commit b7201838467c5dd551ce2fe9f4ccaf5f7c0619b6 Author: PrisonOfMirrors Date: Sat Nov 28 18:24:54 2020 -0600 initial up diff --git a/2018_03_14/DiabDev/DiabDev.cpp b/2018_03_14/DiabDev/DiabDev.cpp new file mode 100644 index 00000000..cc1533b9 --- /dev/null +++ b/2018_03_14/DiabDev/DiabDev.cpp @@ -0,0 +1,222 @@ +// DiabDev.cpp : Defines the entry point for the application. +// + +#include "stdafx.h" +#include "resource.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#pragma warning (disable : 4309) +#pragma warning (disable : 4305) +#pragma warning (disable : 4018) + +#include "diablo.h" +#include "storm.h" +#include "diabloui.h" +#include "pklib/explode.c" +#include "pklib/implode.c" + + +#include "defs.h" +#include "_diab.h" +#include "_data.c" +#include "_diab.c" + +/* +#define MAX_LOADSTRING 100 + +// Global Variables: +HINSTANCE hInst; // current instance +TCHAR szTitle[MAX_LOADSTRING]; // The title bar text +TCHAR szWindowClass[MAX_LOADSTRING]; // The title bar text + +// Foward declarations of functions included in this code module: +ATOM MyRegisterClass(HINSTANCE hInstance); +BOOL InitInstance(HINSTANCE, int); +LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); +LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM); + +int APIENTRY WinMain(HINSTANCE hInstance, + HINSTANCE hPrevInstance, + LPSTR lpCmdLine, + int nCmdShow) +{ + // TODO: Place code here. + MSG msg; + HACCEL hAccelTable; + + // Initialize global strings + LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); + LoadString(hInstance, IDC_DIABDEV, szWindowClass, MAX_LOADSTRING); + MyRegisterClass(hInstance); + + // Perform application initialization: + if (!InitInstance (hInstance, nCmdShow)) + { + return FALSE; + } + + hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_DIABDEV); + + // Main message loop: + while (GetMessage(&msg, NULL, 0, 0)) + { + if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + + return msg.wParam; +} + + + +// +// FUNCTION: MyRegisterClass() +// +// PURPOSE: Registers the window class. +// +// COMMENTS: +// +// This function and its usage is only necessary if you want this code +// to be compatible with Win32 systems prior to the 'RegisterClassEx' +// function that was added to Windows 95. It is important to call this function +// so that the application will get 'well formed' small icons associated +// with it. +// +ATOM MyRegisterClass(HINSTANCE hInstance) +{ + WNDCLASSEX wcex; + + wcex.cbSize = sizeof(WNDCLASSEX); + + wcex.style = CS_HREDRAW | CS_VREDRAW; + wcex.lpfnWndProc = (WNDPROC)WndProc; + wcex.cbClsExtra = 0; + wcex.cbWndExtra = 0; + wcex.hInstance = hInstance; + wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_DIABDEV); + wcex.hCursor = LoadCursor(NULL, IDC_ARROW); + wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); + wcex.lpszMenuName = (LPCSTR)IDC_DIABDEV; + wcex.lpszClassName = szWindowClass; + wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL); + + return RegisterClassEx(&wcex); +} + +// +// FUNCTION: InitInstance(HANDLE, int) +// +// PURPOSE: Saves instance handle and creates main window +// +// COMMENTS: +// +// In this function, we save the instance handle in a global variable and +// create and display the main program window. +// +BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) +{ + HWND hWnd; + + hInst = hInstance; // Store instance handle in our global variable + + hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, + CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL); + + if (!hWnd) + { + return FALSE; + } + + ShowWindow(hWnd, nCmdShow); + UpdateWindow(hWnd); + + return TRUE; +} + +// +// FUNCTION: WndProc(HWND, unsigned, WORD, LONG) +// +// PURPOSE: Processes messages for the main window. +// +// WM_COMMAND - process the application menu +// WM_PAINT - Paint the main window +// WM_DESTROY - post a quit message and return +// +// +LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + int wmId, wmEvent; + PAINTSTRUCT ps; + HDC hdc; + TCHAR szHello[MAX_LOADSTRING]; + LoadString(hInst, IDS_HELLO, szHello, MAX_LOADSTRING); + + switch (message) + { + case WM_COMMAND: + wmId = LOWORD(wParam); + wmEvent = HIWORD(wParam); + // Parse the menu selections: + switch (wmId) + { + case IDM_ABOUT: + DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About); + break; + case IDM_EXIT: + DestroyWindow(hWnd); + break; + default: + return DefWindowProc(hWnd, message, wParam, lParam); + } + break; + case WM_PAINT: + hdc = BeginPaint(hWnd, &ps); + // TODO: Add any drawing code here... + RECT rt; + GetClientRect(hWnd, &rt); + DrawText(hdc, szHello, strlen(szHello), &rt, DT_CENTER); + EndPaint(hWnd, &ps); + break; + case WM_DESTROY: + PostQuitMessage(0); + break; + default: + return DefWindowProc(hWnd, message, wParam, lParam); + } + return 0; +} + +// Mesage handler for about box. +LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) + { + case WM_INITDIALOG: + return TRUE; + + case WM_COMMAND: + if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) + { + EndDialog(hDlg, LOWORD(wParam)); + return TRUE; + } + break; + } + return FALSE; +} +*/ diff --git a/2018_03_14/DiabDev/DiabDev.dsp b/2018_03_14/DiabDev/DiabDev.dsp new file mode 100644 index 00000000..aaf5e7b2 --- /dev/null +++ b/2018_03_14/DiabDev/DiabDev.dsp @@ -0,0 +1,140 @@ +# Microsoft Developer Studio Project File - Name="DiabDev" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=DiabDev - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "DiabDev.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "DiabDev.mak" CFG="DiabDev - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "DiabDev - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "DiabDev - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "DiabDev - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /Yu"stdafx.h" /FD /c +# ADD CPP /nologo /Gd /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /Yu"stdafx.h" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 version.lib shell32.lib advapi32.lib gdi32.lib user32.lib kernel32.lib storm.lib diabloui.lib /nologo /subsystem:windows /machine:I386 + +!ELSEIF "$(CFG)" == "DiabDev - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 version.lib shell32.lib advapi32.lib gdi32.lib user32.lib kernel32.lib storm.lib diabloui.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "DiabDev - Win32 Release" +# Name "DiabDev - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\DiabDev.cpp +# End Source File +# Begin Source File + +SOURCE=.\DiabDev.rc +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.cpp +# ADD CPP /Yc"stdafx.h" +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\DiabDev.h +# End Source File +# Begin Source File + +SOURCE=.\resource.h +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# Begin Source File + +SOURCE=.\DiabDev.ico +# End Source File +# Begin Source File + +SOURCE=.\small.ico +# End Source File +# End Group +# Begin Source File + +SOURCE=.\ReadMe.txt +# End Source File +# End Target +# End Project diff --git a/2018_03_14/DiabDev/DiabDev.dsw b/2018_03_14/DiabDev/DiabDev.dsw new file mode 100644 index 00000000..02539d4a --- /dev/null +++ b/2018_03_14/DiabDev/DiabDev.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "DiabDev"=.\DiabDev.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/2018_03_14/DiabDev/DiabDev.h b/2018_03_14/DiabDev/DiabDev.h new file mode 100644 index 00000000..99210aef --- /dev/null +++ b/2018_03_14/DiabDev/DiabDev.h @@ -0,0 +1,12 @@ + +#if !defined(AFX_DIABDEV_H__0B8B7FA5_C7DA_445A_B381_97DBC871DE77__INCLUDED_) +#define AFX_DIABDEV_H__0B8B7FA5_C7DA_445A_B381_97DBC871DE77__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#include "resource.h" + + +#endif // !defined(AFX_DIABDEV_H__0B8B7FA5_C7DA_445A_B381_97DBC871DE77__INCLUDED_) diff --git a/2018_03_14/DiabDev/DiabDev.ico b/2018_03_14/DiabDev/DiabDev.ico new file mode 100644 index 00000000..e315a262 Binary files /dev/null and b/2018_03_14/DiabDev/DiabDev.ico differ diff --git a/2018_03_14/DiabDev/DiabDev.rc b/2018_03_14/DiabDev/DiabDev.rc new file mode 100644 index 00000000..f65b997a --- /dev/null +++ b/2018_03_14/DiabDev/DiabDev.rc @@ -0,0 +1,135 @@ +//Microsoft Visual C++ generated resource script. +// + +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#define APSTUDIO_HIDDEN_SYMBOLS +#include "windows.h" +#undef APSTUDIO_HIDDEN_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE 9, 1 +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. + +IDI_DIABDEV ICON DISCARDABLE "DiabDev.ICO" +IDI_SMALL ICON DISCARDABLE "SMALL.ICO" + +///////////////////////////////////////////////////////////////////////////// +// +// Menu +// + +IDC_DIABDEV MENU DISCARDABLE +BEGIN + POPUP "&File" + BEGIN + MENUITEM "E&xit", IDM_EXIT + END + POPUP "&Help" + BEGIN + MENUITEM "&About ...", IDM_ABOUT + END +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Accelerator +// + +IDC_DIABDEV ACCELERATORS MOVEABLE PURE +BEGIN + "?", IDM_ABOUT, ASCII, ALT + "/", IDM_ABOUT, ASCII, ALT +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_ABOUTBOX DIALOG DISCARDABLE 22, 17, 230, 75 +STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU +CAPTION "About" +FONT 8, "System" +BEGIN + ICON IDI_DIABDEV,IDC_MYICON,14,9,16,16 + LTEXT "DiabDev Version 1.0",IDC_STATIC,49,10,119,8,SS_NOPREFIX + LTEXT "Copyright (C) 2018",IDC_STATIC,49,20,119,8 + DEFPUSHBUTTON "OK",IDOK,195,6,30,11,WS_GROUP +END + + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "#define APSTUDIO_HIDDEN_SYMBOLS\r\n" + "#include ""windows.h""\r\n" + "#undef APSTUDIO_HIDDEN_SYMBOLS\r\n" + "#include ""resource.h""\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + + + +///////////////////////////////////////////////////////////////////////////// +// +// String Table +// + +STRINGTABLE DISCARDABLE +BEGIN + IDC_DIABDEV "DIABDEV" + IDS_APP_TITLE "DiabDev" + IDS_HELLO "Hello World!" +END + +#endif +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/2018_03_14/DiabDev/DiabloUI.h b/2018_03_14/DiabDev/DiabloUI.h new file mode 100644 index 00000000..77c48854 --- /dev/null +++ b/2018_03_14/DiabDev/DiabloUI.h @@ -0,0 +1,43 @@ + + +/* struct _SNETPROGRAMDATA { + int a1; +}; +struct _SNETPLAYERDATA { + int a1; +}; +struct _SNETUIDATA { + int a1; +}; +struct _SNETVERSIONDATA { + int a1; +}; +struct _uiheroinfo { + int a1; +}; */ +void __cdecl UiDestroy(); // { return; } +void __cdecl UiTitleDialog(int a1); // { return; } +void __cdecl UiInitialize(); // { return; } +void __stdcall UiCopyProtError(int a1); // { return; } +void __stdcall UiAppActivate(int a1); // { return; } +int __stdcall UiValidPlayerName(char *a1); // { return 0; } +int __stdcall UiSelHeroMultDialog(void *fninfo, void *fncreate, void *fnremove, void *fnstats, int *a5, int *a6, char *name); // { return 0; } +int __stdcall UiSelHeroSingDialog(void *fninfo, void *fncreate, void *fnremove, void *fnstats, int *a5, char *name, int *difficulty); // { return 0; } +void __stdcall UiCreditsDialog(int a1); // { return; } +int __stdcall UiMainMenuDialog(char *name, int *a2, void *fnSound, int a4); // { return 0; } +int __stdcall UiProgressDialog(HWND window, char *msg, int a3, void *fnfunc, int a5); // { return 0; } +void __cdecl UiProfileGetString(); // { return; } +void __cdecl UiProfileCallback(); // { return; } +void __cdecl UiProfileDraw(); // { return; } +void __cdecl UiCategoryCallback(); // { return; } +void __cdecl UiGetDataCallback(); // { return; } +void __cdecl UiAuthCallback(); // { return; } +void __cdecl UiSoundCallback(); // { return; } +void __cdecl UiMessageBoxCallback(); // { return; } +void __cdecl UiDrawDescCallback(); // { return; } +void __cdecl UiCreateGameCallback(); // { return; } +void __cdecl UiArtCallback(); // { return; } +int __stdcall UiSelectGame(int a1, _SNETPROGRAMDATA *client_info, _SNETPLAYERDATA *user_info, _SNETUIDATA *ui_info, _SNETVERSIONDATA *file_info, int *a6); // { return 0; } +int __stdcall UiSelectProvider(int a1, _SNETPROGRAMDATA *client_info, _SNETPLAYERDATA *user_info, _SNETUIDATA *ui_info, _SNETVERSIONDATA *file_info, int *type); // { return 0; } +int __stdcall UiCreatePlayerDescription(_uiheroinfo *info, int mode, char *desc); // { return 0; } +int __stdcall UiSetupPlayerInfo(char *str, _uiheroinfo *info, int mode); // { return 0; } diff --git a/2018_03_14/DiabDev/DiabloUI.lib b/2018_03_14/DiabDev/DiabloUI.lib new file mode 100644 index 00000000..d7207ec6 Binary files /dev/null and b/2018_03_14/DiabDev/DiabloUI.lib differ diff --git a/2018_03_14/DiabDev/ReadMe.txt b/2018_03_14/DiabDev/ReadMe.txt new file mode 100644 index 00000000..dd91732e --- /dev/null +++ b/2018_03_14/DiabDev/ReadMe.txt @@ -0,0 +1,56 @@ +======================================================================== + WIN32 APPLICATION : DiabDev +======================================================================== + + +AppWizard has created this DiabDev application for you. + +This file contains a summary of what you will find in each of the files that +make up your DiabDev application. + +DiabDev.cpp + This is the main application source file. + +DiabDev.dsp + This file (the project file) contains information at the project level and + is used to build a single project or subproject. Other users can share the + project (.dsp) file, but they should export the makefiles locally. + + +///////////////////////////////////////////////////////////////////////////// +AppWizard has created the following resources: + +DiabDev.rc + This is a listing of all of the Microsoft Windows resources that the + program uses. It includes the icons, bitmaps, and cursors that are stored + in the RES subdirectory. This file can be directly edited in Microsoft + Visual C++. + +res\DiabDev.ico + This is an icon file, which is used as the application's icon (32x32). + This icon is included by the main resource file DiabDev.rc. + +small.ico + %%This is an icon file, which contains a smaller version (16x16) + of the application's icon. This icon is included by the main resource + file DiabDev.rc. + +///////////////////////////////////////////////////////////////////////////// +Other standard files: + +StdAfx.h, StdAfx.cpp + These files are used to build a precompiled header (PCH) file + named DiabDev.pch and a precompiled types file named StdAfx.obj. + +Resource.h + This is the standard header file, which defines new resource IDs. + Microsoft Visual C++ reads and updates this file. + +///////////////////////////////////////////////////////////////////////////// +Other notes: + +AppWizard uses "TODO:" to indicate parts of the source code you +should add to or customize. + + +///////////////////////////////////////////////////////////////////////////// diff --git a/2018_03_14/DiabDev/Small.ico b/2018_03_14/DiabDev/Small.ico new file mode 100644 index 00000000..0c91f2f3 Binary files /dev/null and b/2018_03_14/DiabDev/Small.ico differ diff --git a/2018_03_14/DiabDev/StdAfx.cpp b/2018_03_14/DiabDev/StdAfx.cpp new file mode 100644 index 00000000..f16bab82 --- /dev/null +++ b/2018_03_14/DiabDev/StdAfx.cpp @@ -0,0 +1,8 @@ +// stdafx.cpp : source file that includes just the standard includes +// DiabDev.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + +// TODO: reference any additional headers you need in STDAFX.H +// and not in this file diff --git a/2018_03_14/DiabDev/StdAfx.h b/2018_03_14/DiabDev/StdAfx.h new file mode 100644 index 00000000..1e47eff2 --- /dev/null +++ b/2018_03_14/DiabDev/StdAfx.h @@ -0,0 +1,32 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#if !defined(AFX_STDAFX_H__A9DB83DB_A9FD_11D0_BFD1_444553540000__INCLUDED_) +#define AFX_STDAFX_H__A9DB83DB_A9FD_11D0_BFD1_444553540000__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers + + +// Windows Header Files: +#include + +// C RunTime Header Files +#include +#include +#include +#include + +// Local Header Files + +// TODO: reference additional headers your program requires here + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_STDAFX_H__A9DB83DB_A9FD_11D0_BFD1_444553540000__INCLUDED_) diff --git a/2018_03_14/DiabDev/_data.c b/2018_03_14/DiabDev/_data.c new file mode 100644 index 00000000..1b0e4227 --- /dev/null +++ b/2018_03_14/DiabDev/_data.c @@ -0,0 +1,27513 @@ + +//------------------------------------------------------------------------- +// Data declarations + +unsigned char fontframe[127] = +{ + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 54u, + 44u, + 57u, + 58u, + 56u, + 55u, + 47u, + 40u, + 41u, + 59u, + 39u, + 50u, + 37u, + 51u, + 52u, + 36u, + 27u, + 28u, + 29u, + 30u, + 31u, + 32u, + 33u, + 34u, + 35u, + 48u, + 49u, + 60u, + 38u, + 61u, + 53u, + 62u, + 1u, + 2u, + 3u, + 4u, + 5u, + 6u, + 7u, + 8u, + 9u, + 10u, + 11u, + 12u, + 13u, + 14u, + 15u, + 16u, + 17u, + 18u, + 19u, + 20u, + 21u, + 22u, + 23u, + 24u, + 25u, + 26u, + 42u, + 63u, + 43u, + 64u, + 65u, + 0u, + 1u, + 2u, + 3u, + 4u, + 5u, + 6u, + 7u, + 8u, + 9u, + 10u, + 11u, + 12u, + 13u, + 14u, + 15u, + 16u, + 17u, + 18u, + 19u, + 20u, + 21u, + 22u, + 23u, + 24u, + 25u, + 26u, + 40u, + 66u, + 41u, + 67u +}; +unsigned char fontkern[68] = +{ + 8u, + 10u, + 7u, + 9u, + 8u, + 7u, + 6u, + 8u, + 8u, + 3u, + 3u, + 8u, + 6u, + 11u, + 9u, + 10u, + 6u, + 9u, + 9u, + 6u, + 9u, + 11u, + 10u, + 13u, + 10u, + 11u, + 7u, + 5u, + 7u, + 7u, + 8u, + 7u, + 7u, + 7u, + 7u, + 7u, + 10u, + 4u, + 5u, + 6u, + 3u, + 3u, + 4u, + 3u, + 6u, + 6u, + 3u, + 3u, + 3u, + 3u, + 3u, + 2u, + 7u, + 6u, + 3u, + 10u, + 10u, + 6u, + 6u, + 7u, + 4u, + 4u, + 9u, + 6u, + 6u, + 12u, + 3u, + 7u +}; +int lineoffset[25] = +{ + 456433, + 24576, + 24576, + 24576, + 24756, + 447217, + 465649, + 24576, + 24576, + 24576, + 442609, + 456433, + 470257, + 24576, + 24576, + 439537, + 451057, + 461809, + 473329, + 24576, + 438001, + 447217, + 456433, + 465649, + 474097 +}; +unsigned char fontidx[256] = +{ + 0u, + 1u, + 1u, + 1u, + 1u, + 1u, + 1u, + 1u, + 1u, + 1u, + 1u, + 1u, + 1u, + 1u, + 1u, + 1u, + 1u, + 1u, + 1u, + 1u, + 1u, + 1u, + 1u, + 1u, + 1u, + 1u, + 1u, + 1u, + 1u, + 1u, + 1u, + 1u, + 32u, + 33u, + 34u, + 35u, + 36u, + 37u, + 38u, + 39u, + 40u, + 41u, + 42u, + 43u, + 44u, + 45u, + 46u, + 47u, + 48u, + 49u, + 50u, + 51u, + 52u, + 53u, + 54u, + 55u, + 56u, + 57u, + 58u, + 59u, + 60u, + 61u, + 62u, + 63u, + 64u, + 65u, + 66u, + 67u, + 68u, + 69u, + 70u, + 71u, + 72u, + 73u, + 74u, + 75u, + 76u, + 77u, + 78u, + 79u, + 80u, + 81u, + 82u, + 83u, + 84u, + 85u, + 86u, + 87u, + 88u, + 89u, + 90u, + 91u, + 92u, + 93u, + 94u, + 95u, + 96u, + 97u, + 98u, + 99u, + 100u, + 101u, + 102u, + 103u, + 104u, + 105u, + 106u, + 107u, + 108u, + 109u, + 110u, + 111u, + 112u, + 113u, + 114u, + 115u, + 116u, + 117u, + 118u, + 119u, + 120u, + 121u, + 122u, + 123u, + 124u, + 125u, + 126u, + 1u, + 67u, + 117u, + 101u, + 97u, + 97u, + 97u, + 97u, + 99u, + 101u, + 101u, + 101u, + 105u, + 105u, + 105u, + 65u, + 65u, + 69u, + 97u, + 65u, + 111u, + 111u, + 111u, + 117u, + 117u, + 121u, + 79u, + 85u, + 99u, + 76u, + 89u, + 80u, + 102u, + 97u, + 105u, + 111u, + 117u, + 110u, + 78u, + 97u, + 111u, + 63u, + 1u, + 1u, + 1u, + 1u, + 33u, + 60u, + 62u, + 111u, + 43u, + 50u, + 51u, + 39u, + 117u, + 80u, + 46u, + 44u, + 49u, + 48u, + 62u, + 1u, + 1u, + 1u, + 63u, + 65u, + 65u, + 65u, + 65u, + 65u, + 65u, + 65u, + 67u, + 69u, + 69u, + 69u, + 69u, + 73u, + 73u, + 73u, + 73u, + 68u, + 78u, + 79u, + 79u, + 79u, + 79u, + 79u, + 88u, + 48u, + 85u, + 85u, + 85u, + 85u, + 89u, + 98u, + 66u, + 97u, + 97u, + 97u, + 97u, + 97u, + 97u, + 97u, + 99u, + 101u, + 101u, + 101u, + 101u, + 105u, + 105u, + 105u, + 105u, + 111u, + 110u, + 111u, + 111u, + 111u, + 111u, + 111u, + 47u, + 48u, + 117u, + 117u, + 117u, + 117u, + 121u, + 98u, + 121u +}; +int InvItemWidth[180] = +{ + 0, + 33, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 23, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56 +}; +int InvItemHeight[180] = +{ + 0, + 29, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 35, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 56, + 56, + 56, + 56, + 56, + 56, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84 +}; +int diablo_inf = 2139095040; // weak +ShadowStruct SPATS[37] = +{ + { 7u, 13u, 0u, 13u, 144u, 0u, 142u }, + { 16u, 13u, 0u, 13u, 144u, 0u, 142u }, + { 15u, 13u, 0u, 13u, 145u, 0u, 142u }, + { 5u, 13u, 13u, 13u, 152u, 140u, 139u }, + { 5u, 13u, 1u, 13u, 143u, 146u, 139u }, + { 5u, 13u, 13u, 2u, 143u, 140u, 148u }, + { 5u, 0u, 1u, 2u, 0u, 146u, 148u }, + { 5u, 13u, 11u, 13u, 143u, 147u, 139u }, + { 5u, 13u, 13u, 12u, 143u, 140u, 149u }, + { 5u, 13u, 11u, 12u, 150u, 147u, 149u }, + { 5u, 13u, 1u, 12u, 143u, 146u, 149u }, + { 5u, 13u, 11u, 2u, 143u, 147u, 148u }, + { 9u, 13u, 13u, 13u, 144u, 140u, 142u }, + { 9u, 13u, 1u, 13u, 144u, 146u, 142u }, + { 9u, 13u, 11u, 13u, 151u, 147u, 142u }, + { 8u, 13u, 0u, 13u, 144u, 0u, 139u }, + { 8u, 13u, 0u, 12u, 143u, 0u, 149u }, + { 8u, 0u, 0u, 2u, 0u, 0u, 148u }, + { 11u, 0u, 0u, 13u, 0u, 0u, 139u }, + { 11u, 13u, 0u, 13u, 139u, 0u, 139u }, + { 11u, 2u, 0u, 13u, 148u, 0u, 139u }, + { 11u, 12u, 0u, 13u, 149u, 0u, 139u }, + { 11u, 13u, 11u, 12u, 139u, 0u, 149u }, + { 14u, 0u, 0u, 13u, 0u, 0u, 139u }, + { 14u, 13u, 0u, 13u, 139u, 0u, 139u }, + { 14u, 2u, 0u, 13u, 148u, 0u, 139u }, + { 14u, 12u, 0u, 13u, 149u, 0u, 139u }, + { 14u, 13u, 11u, 12u, 139u, 0u, 149u }, + { 10u, 0u, 13u, 0u, 0u, 140u, 0u }, + { 10u, 13u, 13u, 0u, 140u, 140u, 0u }, + { 10u, 0u, 1u, 0u, 0u, 146u, 0u }, + { 10u, 13u, 11u, 0u, 140u, 147u, 0u }, + { 12u, 0u, 13u, 0u, 0u, 140u, 0u }, + { 12u, 13u, 13u, 0u, 140u, 140u, 0u }, + { 12u, 0u, 1u, 0u, 0u, 146u, 0u }, + { 12u, 13u, 11u, 0u, 140u, 147u, 0u }, + { 3u, 13u, 11u, 12u, 150u, 0u, 0u } +}; +unsigned char BSTYPES[206] = +{ + 0u, + 1u, + 2u, + 3u, + 4u, + 5u, + 6u, + 7u, + 8u, + 9u, + 10u, + 11u, + 12u, + 13u, + 14u, + 15u, + 16u, + 17u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 1u, + 2u, + 10u, + 4u, + 5u, + 6u, + 7u, + 8u, + 9u, + 10u, + 11u, + 12u, + 14u, + 5u, + 14u, + 10u, + 4u, + 14u, + 4u, + 5u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 1u, + 2u, + 3u, + 4u, + 1u, + 6u, + 7u, + 16u, + 17u, + 2u, + 1u, + 1u, + 2u, + 2u, + 1u, + 1u, + 2u, + 2u, + 2u, + 2u, + 2u, + 1u, + 1u, + 11u, + 1u, + 13u, + 13u, + 13u, + 1u, + 2u, + 1u, + 2u, + 1u, + 2u, + 1u, + 2u, + 2u, + 2u, + 2u, + 12u, + 0u, + 0u, + 11u, + 1u, + 11u, + 1u, + 13u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 13u, + 13u, + 13u, + 13u, + 13u, + 13u, + 13u, + 13u, + 13u, + 13u, + 13u, + 13u, + 13u, + 1u, + 11u, + 2u, + 12u, + 13u, + 13u, + 13u, + 12u, + 2u, + 1u, + 2u, + 2u, + 4u, + 14u, + 4u, + 10u, + 13u, + 13u, + 4u, + 4u, + 1u, + 1u, + 4u, + 2u, + 2u, + 13u, + 13u, + 13u, + 13u, + 25u, + 26u, + 28u, + 30u, + 31u, + 41u, + 43u, + 40u, + 41u, + 42u, + 43u, + 25u, + 41u, + 43u, + 28u, + 28u, + 1u, + 2u, + 25u, + 26u, + 22u, + 22u, + 25u, + 26u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u +}; +unsigned char L5BTYPES[206] = +{ + 0u, + 1u, + 2u, + 3u, + 4u, + 5u, + 6u, + 7u, + 8u, + 9u, + 10u, + 11u, + 12u, + 13u, + 14u, + 15u, + 16u, + 17u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 25u, + 26u, + 0u, + 28u, + 0u, + 30u, + 31u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 40u, + 41u, + 42u, + 43u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 79u, + 80u, + 0u, + 82u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 79u, + 0u, + 80u, + 0u, + 0u, + 79u, + 80u, + 0u, + 2u, + 2u, + 2u, + 1u, + 1u, + 11u, + 25u, + 13u, + 13u, + 13u, + 1u, + 2u, + 1u, + 2u, + 1u, + 2u, + 1u, + 2u, + 2u, + 2u, + 2u, + 12u, + 0u, + 0u, + 11u, + 1u, + 11u, + 1u, + 13u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 13u, + 13u, + 13u, + 13u, + 13u, + 13u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u +}; +unsigned char STAIRSUP[] = +{ + 4u, + 4u, + 13u, + 13u, + 13u, + 13u, + 2u, + 2u, + 2u, + 2u, + 13u, + 13u, + 13u, + 13u, + 13u, + 13u, + 13u, + 13u, + 0u, + 66u, + 6u, + 0u, + 63u, + 64u, + 65u, + 0u, + 0u, + 67u, + 68u, + 0u, + 0u, + 0u, + 0u, + 0u +}; +unsigned char L5STAIRSUP[] = +{ + 4u, + 4u, + 22u, + 22u, + 22u, + 22u, + 2u, + 2u, + 2u, + 2u, + 13u, + 13u, + 13u, + 13u, + 13u, + 13u, + 13u, + 13u, + 0u, + 66u, + 23u, + 0u, + 63u, + 64u, + 65u, + 0u, + 0u, + 67u, + 68u, + 0u, + 0u, + 0u, + 0u, + 0u +}; +unsigned char STAIRSDOWN[] = +{ + 4u, + 3u, + 13u, + 13u, + 13u, + 13u, + 13u, + 13u, + 13u, + 13u, + 13u, + 13u, + 13u, + 13u, + 62u, + 57u, + 58u, + 0u, + 61u, + 59u, + 60u, + 0u, + 0u, + 0u, + 0u, + 0u +}; +unsigned char LAMPS[] = { 2u, 2u, 13u, 0u, 13u, 13u, 129u, 0u, 130u, 128u }; +unsigned char PWATERIN[] = +{ + 6u, + 6u, + 13u, + 13u, + 13u, + 13u, + 13u, + 13u, + 13u, + 13u, + 13u, + 13u, + 13u, + 13u, + 13u, + 13u, + 13u, + 13u, + 13u, + 13u, + 13u, + 13u, + 13u, + 13u, + 13u, + 13u, + 13u, + 13u, + 13u, + 13u, + 13u, + 13u, + 13u, + 13u, + 13u, + 13u, + 13u, + 13u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 202u, + 200u, + 200u, + 84u, + 0u, + 0u, + 199u, + 203u, + 203u, + 83u, + 0u, + 0u, + 85u, + 206u, + 80u, + 81u, + 0u, + 0u, + 0u, + 134u, + 135u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u +}; +unsigned char L3ConvTbl[16] = { 8u, 11u, 3u, 10u, 1u, 9u, 12u, 12u, 6u, 13u, 4u, 13u, 2u, 14u, 5u, 7u }; +unsigned char L3UP[20] = +{ + 3u, + 3u, + 8u, + 8u, + 0u, + 10u, + 10u, + 0u, + 7u, + 7u, + 0u, + 51u, + 50u, + 0u, + 48u, + 49u, + 0u, + 0u, + 0u, + 0u +}; +unsigned char L3DOWN[20] = +{ + 3u, + 3u, + 8u, + 9u, + 7u, + 8u, + 9u, + 7u, + 0u, + 0u, + 0u, + 0u, + 47u, + 0u, + 0u, + 46u, + 0u, + 0u, + 0u, + 0u +}; +unsigned char L3HOLDWARP[20] = +{ + 3u, + 3u, + 8u, + 8u, + 0u, + 10u, + 10u, + 0u, + 7u, + 7u, + 0u, + 125u, + 125u, + 0u, + 125u, + 125u, + 0u, + 0u, + 0u, + 0u +}; +unsigned char L3TITE1[34] = +{ + 4u, + 4u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 0u, + 0u, + 0u, + 0u, + 0u, + 57u, + 58u, + 0u, + 0u, + 56u, + 55u, + 0u, + 0u, + 0u, + 0u, + 0u +}; +unsigned char L3TITE2[34] = +{ + 4u, + 4u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 0u, + 0u, + 0u, + 0u, + 0u, + 61u, + 62u, + 0u, + 0u, + 60u, + 59u, + 0u, + 0u, + 0u, + 0u, + 0u +}; +unsigned char L3TITE3[34] = +{ + 4u, + 4u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 0u, + 0u, + 0u, + 0u, + 0u, + 65u, + 66u, + 0u, + 0u, + 64u, + 63u, + 0u, + 0u, + 0u, + 0u, + 0u +}; +unsigned char L3TITE6[42] = +{ + 5u, + 4u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 0u, + 7u, + 7u, + 7u, + 7u, + 0u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 77u, + 78u, + 0u, + 0u, + 0u, + 76u, + 74u, + 75u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u +}; +unsigned char L3TITE7[42] = +{ + 4u, + 5u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 0u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 0u, + 0u, + 0u, + 0u, + 0u, + 83u, + 0u, + 0u, + 0u, + 82u, + 80u, + 0u, + 0u, + 81u, + 79u, + 0u, + 0u, + 0u, + 0u, + 0u +}; +unsigned char L3TITE8[20] = +{ + 3u, + 3u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 0u, + 0u, + 0u, + 0u, + 52u, + 0u, + 0u, + 0u, + 0u +}; +unsigned char L3TITE9[20] = +{ + 3u, + 3u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 0u, + 0u, + 0u, + 0u, + 53u, + 0u, + 0u, + 0u, + 0u +}; +unsigned char L3TITE10[20] = +{ + 3u, + 3u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 0u, + 0u, + 0u, + 0u, + 54u, + 0u, + 0u, + 0u, + 0u +}; +unsigned char L3TITE11[20] = +{ + 3u, + 3u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 0u, + 0u, + 0u, + 0u, + 67u, + 0u, + 0u, + 0u, + 0u +}; +unsigned char L3TITE12[6] = { 2u, 1u, 9u, 7u, 68u, 0u }; +unsigned char L3TITE13[6] = { 1u, 2u, 10u, 7u, 69u, 0u }; +unsigned char L3CREV1[6] = { 2u, 1u, 8u, 7u, 84u, 85u }; +unsigned char L3CREV2[6] = { 2u, 1u, 8u, 11u, 86u, 87u }; +unsigned char L3CREV3[6] = { 1u, 2u, 8u, 10u, 89u, 88u }; +unsigned char L3CREV4[6] = { 2u, 1u, 8u, 7u, 90u, 91u }; +unsigned char L3CREV5[6] = { 1u, 2u, 8u, 11u, 92u, 93u }; +unsigned char L3CREV6[6] = { 1u, 2u, 8u, 10u, 95u, 94u }; +unsigned char L3CREV7[6] = { 2u, 1u, 8u, 7u, 96u, 101u }; +unsigned char L3CREV8[6] = { 1u, 2u, 2u, 8u, 102u, 97u }; +unsigned char L3CREV9[6] = { 2u, 1u, 3u, 8u, 103u, 98u }; +unsigned char L3CREV10[6] = { 2u, 1u, 4u, 8u, 104u, 99u }; +unsigned char L3CREV11[6] = { 1u, 2u, 6u, 8u, 105u, 100u }; +unsigned char L3ISLE1[14] = { 2u, 3u, 5u, 14u, 4u, 9u, 13u, 12u, 7u, 7u, 7u, 7u, 7u, 7u }; +unsigned char L3ISLE2[14] = { 3u, 2u, 5u, 2u, 14u, 13u, 10u, 12u, 7u, 7u, 7u, 7u, 7u, 7u }; +unsigned char L3ISLE3[14] = { 2u, 3u, 5u, 14u, 4u, 9u, 13u, 12u, 29u, 30u, 25u, 28u, 31u, 32u }; +unsigned char L3ISLE4[14] = { 3u, 2u, 5u, 2u, 14u, 13u, 10u, 12u, 29u, 26u, 30u, 31u, 27u, 32u }; +unsigned char L3ISLE5[10] = { 2u, 2u, 5u, 14u, 13u, 12u, 7u, 7u, 7u, 7u }; +unsigned char L3XTRA1[4] = { 1u, 1u, 7u, 106u }; +unsigned char L3XTRA2[4] = { 1u, 1u, 7u, 107u }; +unsigned char L3XTRA3[4] = { 1u, 1u, 7u, 108u }; +unsigned char L3XTRA4[4] = { 1u, 1u, 9u, 109u }; +unsigned char L3XTRA5[4] = { 1u, 1u, 10u, 110u }; +unsigned char L3ANVIL[244] = +{ + 11u, + 11u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 7u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 29u, + 26u, + 26u, + 26u, + 26u, + 26u, + 30u, + 0u, + 0u, + 0u, + 29u, + 34u, + 33u, + 33u, + 37u, + 36u, + 33u, + 35u, + 30u, + 0u, + 0u, + 25u, + 33u, + 37u, + 27u, + 32u, + 31u, + 36u, + 33u, + 28u, + 0u, + 0u, + 25u, + 37u, + 32u, + 7u, + 7u, + 7u, + 31u, + 27u, + 32u, + 0u, + 0u, + 25u, + 28u, + 7u, + 7u, + 7u, + 7u, + 2u, + 2u, + 2u, + 0u, + 0u, + 25u, + 35u, + 30u, + 7u, + 7u, + 7u, + 29u, + 26u, + 30u, + 0u, + 0u, + 25u, + 33u, + 35u, + 26u, + 30u, + 29u, + 34u, + 33u, + 28u, + 0u, + 0u, + 31u, + 36u, + 33u, + 33u, + 35u, + 34u, + 33u, + 37u, + 32u, + 0u, + 0u, + 0u, + 31u, + 27u, + 27u, + 27u, + 27u, + 27u, + 32u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u +}; +unsigned char L3SpawnTbl1[15] = { 0u, 10u, 67u, 5u, 44u, 6u, 9u, 0u, 0u, 28u, 131u, 6u, 9u, 10u, 5u }; +unsigned char L3SpawnTbl2[15] = { 0u, 10u, 3u, 5u, 12u, 6u, 9u, 0u, 0u, 12u, 3u, 6u, 9u, 10u, 5u }; +unsigned char L3PoolSub[15] = { 0u, 35u, 26u, 36u, 25u, 29u, 34u, 7u, 33u, 28u, 27u, 37u, 32u, 31u, 30u }; +unsigned char L4ConvTbl[16] = { 30u, 6u, 1u, 6u, 2u, 6u, 6u, 6u, 9u, 6u, 1u, 6u, 2u, 6u, 3u, 6u }; +unsigned char L4USTAIRS[42] = +{ + 4u, + 5u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 0u, + 0u, + 0u, + 0u, + 36u, + 38u, + 35u, + 0u, + 37u, + 34u, + 33u, + 32u, + 0u, + 0u, + 31u, + 0u, + 0u, + 0u, + 0u, + 0u +}; +unsigned char L4TWARP[42] = +{ + 4u, + 5u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 0u, + 0u, + 0u, + 0u, + 134u, + 136u, + 133u, + 0u, + 135u, + 132u, + 131u, + 130u, + 0u, + 0u, + 129u, + 0u, + 0u, + 0u, + 0u, + 0u +}; +unsigned char L4DSTAIRS[52] = +{ + 5u, + 5u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 45u, + 41u, + 0u, + 0u, + 44u, + 43u, + 40u, + 0u, + 0u, + 46u, + 42u, + 39u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u +}; +unsigned char L4PENTA[52] = +{ + 5u, + 5u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 98u, + 100u, + 103u, + 0u, + 0u, + 99u, + 102u, + 105u, + 0u, + 0u, + 101u, + 104u, + 106u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u +}; +unsigned char L4PENTA2[52] = +{ + 5u, + 5u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 107u, + 109u, + 112u, + 0u, + 0u, + 108u, + 111u, + 114u, + 0u, + 0u, + 110u, + 113u, + 115u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u +}; +unsigned char L4BTYPES[140] = +{ + 0u, + 1u, + 2u, + 3u, + 4u, + 5u, + 6u, + 7u, + 8u, + 9u, + 10u, + 11u, + 12u, + 13u, + 14u, + 15u, + 16u, + 17u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 6u, + 6u, + 6u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 1u, + 2u, + 1u, + 2u, + 1u, + 2u, + 1u, + 1u, + 2u, + 2u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 15u, + 16u, + 9u, + 12u, + 4u, + 5u, + 7u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u +}; +int dthread_inf = 2139095040; // weak +int dx_inf = 2139095040; // weak +int effects_inf = 2139095040; // weak +char monster_action_sounds[] = { 'a', 'h', 'd', 's' }; // idb +int engine_inf = 2139095040; // weak +unsigned char lfontframe[127] = +{ + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 37u, + 49u, + 38u, + 0u, + 39u, + 40u, + 47u, + 42u, + 43u, + 41u, + 45u, + 52u, + 44u, + 53u, + 55u, + 36u, + 27u, + 28u, + 29u, + 30u, + 31u, + 32u, + 33u, + 34u, + 35u, + 51u, + 50u, + 0u, + 46u, + 0u, + 54u, + 0u, + 1u, + 2u, + 3u, + 4u, + 5u, + 6u, + 7u, + 8u, + 9u, + 10u, + 11u, + 12u, + 13u, + 14u, + 15u, + 16u, + 17u, + 18u, + 19u, + 20u, + 21u, + 22u, + 23u, + 24u, + 25u, + 26u, + 42u, + 0u, + 43u, + 0u, + 0u, + 0u, + 1u, + 2u, + 3u, + 4u, + 5u, + 6u, + 7u, + 8u, + 9u, + 10u, + 11u, + 12u, + 13u, + 14u, + 15u, + 16u, + 17u, + 18u, + 19u, + 20u, + 21u, + 22u, + 23u, + 24u, + 25u, + 26u, + 20u, + 0u, + 21u, + 0u +}; +unsigned char lfontkern[56] = +{ + 18u, + 33u, + 21u, + 26u, + 28u, + 19u, + 19u, + 26u, + 25u, + 11u, + 12u, + 25u, + 19u, + 34u, + 28u, + 32u, + 20u, + 32u, + 28u, + 20u, + 28u, + 36u, + 35u, + 46u, + 33u, + 33u, + 24u, + 11u, + 23u, + 22u, + 22u, + 21u, + 22u, + 21u, + 21u, + 21u, + 32u, + 10u, + 20u, + 36u, + 31u, + 17u, + 13u, + 12u, + 13u, + 18u, + 16u, + 11u, + 20u, + 21u, + 11u, + 10u, + 12u, + 11u, + 21u, + 23u +}; +int init_inf = 2139095040; // weak +int interfac_inf = 2139095040; // weak +unsigned char progress_bar_colours[3] = { 138u, 43u, 254u }; +POINT32 progress_bar_screen_pos[3] = { { 53, 37 }, { 53, 421 }, { 53, 37 } }; +POINT32 inv_screen_pos[73] = +{ + { 452, 31 }, + { 480, 31 }, + { 452, 59 }, + { 480, 59 }, + { 365, 205 }, + { 567, 205 }, + { 524, 59 }, + { 337, 104 }, + { 366, 104 }, + { 337, 132 }, + { 366, 132 }, + { 337, 160 }, + { 366, 160 }, + { 567, 104 }, + { 596, 104 }, + { 567, 132 }, + { 596, 132 }, + { 567, 160 }, + { 596, 160 }, + { 452, 104 }, + { 480, 104 }, + { 452, 132 }, + { 480, 132 }, + { 452, 160 }, + { 480, 160 }, + { 337, 250 }, + { 366, 250 }, + { 394, 250 }, + { 423, 250 }, + { 451, 250 }, + { 480, 250 }, + { 509, 250 }, + { 538, 250 }, + { 567, 250 }, + { 596, 250 }, + { 337, 279 }, + { 366, 279 }, + { 394, 279 }, + { 423, 279 }, + { 451, 279 }, + { 480, 279 }, + { 509, 279 }, + { 538, 279 }, + { 567, 279 }, + { 596, 279 }, + { 337, 308 }, + { 366, 308 }, + { 394, 308 }, + { 423, 308 }, + { 451, 308 }, + { 480, 308 }, + { 509, 308 }, + { 538, 308 }, + { 567, 308 }, + { 596, 308 }, + { 337, 336 }, + { 366, 336 }, + { 394, 336 }, + { 423, 336 }, + { 451, 336 }, + { 480, 336 }, + { 509, 336 }, + { 538, 336 }, + { 567, 336 }, + { 596, 336 }, + { 205, 385 }, + { 234, 385 }, + { 263, 385 }, + { 292, 385 }, + { 321, 385 }, + { 350, 385 }, + { 379, 385 }, + { 408, 385 } +}; +PLStruct PL_Prefix[84] = +{ + { + "Tin", + IPL_TOHIT_CURSE, + 6, + 10, + 3, + PLT_WEAP|PLT_BOW|PLT_MISC, + 0, + 1, + 0, + 0, + 0, + 4294967293 + }, + { + "Brass", + IPL_TOHIT_CURSE, + 1, + 5, + 1, + PLT_WEAP|PLT_BOW|PLT_MISC, + 0, + 1, + 0, + 0, + 0, + 4294967294 + }, + { + "Bronze", + IPL_TOHIT, + 1, + 5, + 1, + PLT_WEAP|PLT_BOW|PLT_MISC, + 0, + 1, + 1, + 100, + 500, + 2 + }, + { + "Iron", + IPL_TOHIT, + 6, + 10, + 4, + PLT_WEAP|PLT_BOW|PLT_MISC, + 0, + 1, + 1, + 600, + 1000, + 3 + }, + { + "Steel", + IPL_TOHIT, + 11, + 15, + 6, + PLT_WEAP|PLT_BOW|PLT_MISC, + 0, + 1, + 1, + 1100, + 1500, + 5 + }, + { + "Silver", + IPL_TOHIT, + 16, + 20, + 9, + PLT_WEAP|PLT_BOW|PLT_MISC, + 16, + 1, + 1, + 1600, + 2000, + 7 + }, + { + "Gold", + IPL_TOHIT, + 21, + 30, + 12, + PLT_WEAP|PLT_BOW|PLT_MISC, + 16, + 1, + 1, + 2100, + 3000, + 9 + }, + { + "Platinum", + IPL_TOHIT, + 31, + 40, + 16, + PLT_WEAP|PLT_BOW, + 16, + 1, + 1, + 3100, + 4000, + 11 + }, + { + "Mithril", + IPL_TOHIT, + 41, + 60, + 20, + PLT_WEAP|PLT_BOW, + 16, + 1, + 1, + 4100, + 6000, + 13 + }, + { + "Meteoric", + IPL_TOHIT, + 61, + 80, + 23, + PLT_WEAP|PLT_BOW, + 0, + 1, + 1, + 6100, + 10000, + 15 + }, + { + "Weird", + IPL_TOHIT, + 81, + 100, + 35, + PLT_WEAP|PLT_BOW, + 0, + 1, + 1, + 10100, + 14000, + 17 + }, + { + "Strange", + IPL_TOHIT, + 101, + 150, + 60, + PLT_WEAP|PLT_BOW, + 0, + 1, + 1, + 14100, + 20000, + 20 + }, + { + "Useless", + IPL_DAMP_CURSE, + 100, + 100, + 5, + PLT_WEAP|PLT_BOW, + 0, + 1, + 0, + 0, + 0, + 4294967288 + }, + { + "Bent", + IPL_DAMP_CURSE, + 50, + 75, + 3, + PLT_WEAP|PLT_BOW, + 0, + 1, + 0, + 0, + 0, + 4294967292 + }, + { + "Weak", + IPL_DAMP_CURSE, + 25, + 45, + 1, + PLT_WEAP|PLT_BOW, + 0, + 1, + 0, + 0, + 0, + 4294967293 + }, + { "Jagged", IPL_DAMP, 20, 35, 4, PLT_WEAP|PLT_BOW, 0, 1, 1, 250, 450, 3 }, + { "Deadly", IPL_DAMP, 36, 50, 6, PLT_WEAP|PLT_BOW, 0, 1, 1, 500, 700, 4 }, + { "Heavy", IPL_DAMP, 51, 65, 9, PLT_WEAP|PLT_BOW, 0, 1, 1, 750, 950, 5 }, + { "Vicious", IPL_DAMP, 66, 80, 12, PLT_WEAP|PLT_BOW, 1, 1, 1, 1000, 1450, 8 }, + { "Brutal", IPL_DAMP, 81, 95, 16, PLT_WEAP|PLT_BOW, 0, 1, 1, 1500, 1950, 10 }, + { + "Massive", + IPL_DAMP, + 96, + 110, + 20, + PLT_WEAP|PLT_BOW, + 0, + 1, + 1, + 2000, + 2450, + 13 + }, + { + "Savage", + IPL_DAMP, + 111, + 125, + 23, + PLT_WEAP|PLT_BOW, + 0, + 1, + 1, + 2500, + 3000, + 15 + }, + { + "Ruthless", + IPL_DAMP, + 126, + 150, + 35, + PLT_WEAP|PLT_BOW, + 0, + 1, + 1, + 10100, + 15000, + 17 + }, + { + "Merciless", + IPL_DAMP, + 151, + 175, + 60, + PLT_WEAP|PLT_BOW, + 0, + 1, + 1, + 15000, + 20000, + 20 + }, + { + "Clumsy", + IPL_TOHIT_DAMP_CURSE, + 50, + 75, + 5, + PLT_WEAP|PLT_STAFF|PLT_BOW, + 0, + 1, + 0, + 0, + 0, + 4294967289 + }, + { + "Dull", + IPL_TOHIT_DAMP_CURSE, + 25, + 45, + 1, + PLT_WEAP|PLT_STAFF|PLT_BOW, + 0, + 1, + 0, + 0, + 0, + 4294967291 + }, + { + "Sharp", + IPL_TOHIT_DAMP, + 20, + 35, + 1, + PLT_WEAP|PLT_STAFF|PLT_BOW, + 0, + 1, + 0, + 350, + 950, + 5 + }, + { + "Fine", + IPL_TOHIT_DAMP, + 36, + 50, + 6, + PLT_WEAP|PLT_STAFF|PLT_BOW, + 0, + 1, + 1, + 1100, + 1700, + 7 + }, + { + "Warrior's", + IPL_TOHIT_DAMP, + 51, + 65, + 10, + PLT_WEAP|PLT_STAFF|PLT_BOW, + 0, + 1, + 1, + 1850, + 2450, + 13 + }, + { + "Soldier's", + IPL_TOHIT_DAMP, + 66, + 80, + 15, + PLT_WEAP|PLT_STAFF, + 0, + 1, + 1, + 2600, + 3950, + 17 + }, + { + "Lord's", + IPL_TOHIT_DAMP, + 81, + 95, + 19, + PLT_WEAP|PLT_STAFF, + 0, + 1, + 1, + 4100, + 5950, + 21 + }, + { + "Knight's", + IPL_TOHIT_DAMP, + 96, + 110, + 23, + PLT_WEAP|PLT_STAFF, + 0, + 1, + 1, + 6100, + 8450, + 26 + }, + { + "Master's", + IPL_TOHIT_DAMP, + 111, + 125, + 28, + PLT_WEAP|PLT_STAFF, + 0, + 1, + 1, + 8600, + 13000, + 30 + }, + { + "Champion's", + IPL_TOHIT_DAMP, + 126, + 150, + 40, + PLT_WEAP|PLT_STAFF, + 0, + 1, + 1, + 15200, + 24000, + 33 + }, + { + "King's", + IPL_TOHIT_DAMP, + 151, + 175, + 28, + PLT_WEAP|PLT_STAFF, + 0, + 1, + 1, + 24100, + 35000, + 38 + }, + { + "Vulnerable", + IPL_ACP_CURSE, + 51, + 100, + 3, + PLT_ARMO|PLT_SHLD, + 0, + 1, + 0, + 0, + 0, + 4294967293 + }, + { + "Rusted", + IPL_ACP_CURSE, + 25, + 50, + 1, + PLT_ARMO|PLT_SHLD, + 0, + 1, + 0, + 0, + 0, + 4294967294 + }, + { "Fine", IPL_ACP, 20, 30, 1, PLT_ARMO|PLT_SHLD, 0, 1, 1, 20, 100, 2 }, + { "Strong", IPL_ACP, 31, 40, 3, PLT_ARMO|PLT_SHLD, 0, 1, 1, 120, 200, 3 }, + { "Grand", IPL_ACP, 41, 55, 6, PLT_ARMO|PLT_SHLD, 0, 1, 1, 220, 300, 5 }, + { "Valiant", IPL_ACP, 56, 70, 10, PLT_ARMO|PLT_SHLD, 0, 1, 1, 320, 400, 7 }, + { "Glorious", IPL_ACP, 71, 90, 14, PLT_ARMO|PLT_SHLD, 16, 1, 1, 420, 600, 9 }, + { "Blessed", IPL_ACP, 91, 110, 19, PLT_ARMO|PLT_SHLD, 16, 1, 1, 620, 800, 11 }, + { + "Saintly", + IPL_ACP, + 111, + 130, + 24, + PLT_ARMO|PLT_SHLD, + 16, + 1, + 1, + 820, + 1200, + 13 + }, + { + "Awesome", + IPL_ACP, + 131, + 150, + 28, + PLT_ARMO|PLT_SHLD, + 16, + 1, + 1, + 1220, + 2000, + 15 + }, + { "Holy", IPL_ACP, 151, 170, 35, PLT_ARMO|PLT_SHLD, 16, 1, 1, 5200, 6000, 17 }, + { + "Godly", + IPL_ACP, + 171, + 200, + 60, + PLT_ARMO|PLT_SHLD, + 16, + 1, + 1, + 6200, + 7000, + 20 + }, + { + "Red", + IPL_FIRERES, + 10, + 20, + 4, + PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_STAFF|PLT_BOW|PLT_MISC, + 0, + 0, + 1, + 500, + 1500, + 2 + }, + { + "Crimson", + IPL_FIRERES, + 21, + 30, + 10, + PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_STAFF|PLT_BOW|PLT_MISC, + 0, + 0, + 1, + 2100, + 3000, + 2 + }, + { + "Crimson", + IPL_FIRERES, + 31, + 40, + 16, + PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_STAFF|PLT_BOW|PLT_MISC, + 0, + 0, + 1, + 3100, + 4000, + 2 + }, + { + "Garnet", + IPL_FIRERES, + 41, + 50, + 20, + PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_STAFF|PLT_BOW|PLT_MISC, + 0, + 0, + 1, + 8200, + 12000, + 3 + }, + { + "Ruby", + IPL_FIRERES, + 51, + 60, + 26, + PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_STAFF|PLT_BOW|PLT_MISC, + 0, + 0, + 1, + 17100, + 20000, + 5 + }, + { + "Blue", + IPL_LIGHTRES, + 10, + 20, + 4, + PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_STAFF|PLT_BOW|PLT_MISC, + 0, + 0, + 1, + 500, + 1500, + 2 + }, + { + "Azure", + IPL_LIGHTRES, + 21, + 30, + 10, + PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_STAFF|PLT_BOW|PLT_MISC, + 0, + 0, + 1, + 2100, + 3000, + 2 + }, + { + "Lapis", + IPL_LIGHTRES, + 31, + 40, + 16, + PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_STAFF|PLT_BOW|PLT_MISC, + 0, + 0, + 1, + 3100, + 4000, + 2 + }, + { + "Cobalt", + IPL_LIGHTRES, + 41, + 50, + 20, + PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_STAFF|PLT_BOW|PLT_MISC, + 0, + 0, + 1, + 8200, + 12000, + 3 + }, + { + "Sapphire", + IPL_LIGHTRES, + 51, + 60, + 26, + PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_STAFF|PLT_BOW|PLT_MISC, + 0, + 0, + 1, + 17100, + 20000, + 5 + }, + { + "White", + IPL_MAGICRES, + 10, + 20, + 4, + PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_STAFF|PLT_BOW|PLT_MISC, + 0, + 0, + 1, + 500, + 1500, + 2 + }, + { + "Pearl", + IPL_MAGICRES, + 21, + 30, + 10, + PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_STAFF|PLT_BOW|PLT_MISC, + 0, + 0, + 1, + 2100, + 3000, + 2 + }, + { + "Ivory", + IPL_MAGICRES, + 31, + 40, + 16, + PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_STAFF|PLT_BOW|PLT_MISC, + 0, + 0, + 1, + 3100, + 4000, + 2 + }, + { + "Crystal", + IPL_MAGICRES, + 41, + 50, + 20, + PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_STAFF|PLT_BOW|PLT_MISC, + 0, + 0, + 1, + 8200, + 12000, + 3 + }, + { + "Diamond", + IPL_MAGICRES, + 51, + 60, + 26, + PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_STAFF|PLT_BOW|PLT_MISC, + 0, + 0, + 1, + 17100, + 20000, + 5 + }, + { + "Topaz", + IPL_ALLRES, + 10, + 15, + 8, + PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_STAFF|PLT_BOW|PLT_MISC, + 0, + 0, + 1, + 2000, + 5000, + 3 + }, + { + "Amber", + IPL_ALLRES, + 16, + 20, + 12, + PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_STAFF|PLT_BOW|PLT_MISC, + 0, + 0, + 1, + 7400, + 10000, + 3 + }, + { + "Jade", + IPL_ALLRES, + 21, + 30, + 18, + PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_STAFF|PLT_BOW|PLT_MISC, + 0, + 0, + 1, + 11000, + 15000, + 3 + }, + { + "Obsidian", + IPL_ALLRES, + 31, + 40, + 24, + PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_STAFF|PLT_BOW|PLT_MISC, + 0, + 0, + 1, + 24000, + 40000, + 4 + }, + { + "Emerald", + IPL_ALLRES, + 41, + 50, + 31, + PLT_SHLD|PLT_WEAP|PLT_STAFF|PLT_BOW, + 0, + 0, + 1, + 61000, + 75000, + 7 + }, + { + "Hyena's", + IPL_MANA_CURSE, + 11, + 25, + 4, + PLT_STAFF|PLT_MISC, + 0, + 0, + 0, + 100, + 1000, + 4294967294 + }, + { + "Frog's", + IPL_MANA_CURSE, + 1, + 10, + 1, + PLT_STAFF|PLT_MISC, + 1, + 0, + 0, + 0, + 0, + 4294967294 + }, + { "Spider's", IPL_MANA, 10, 15, 1, PLT_STAFF|PLT_MISC, 1, 0, 1, 500, 1000, 2 }, + { "Raven's", IPL_MANA, 15, 20, 5, PLT_STAFF|PLT_MISC, 0, 0, 1, 1100, 2000, 3 }, + { "Snake's", IPL_MANA, 21, 30, 9, PLT_STAFF|PLT_MISC, 0, 0, 1, 2100, 4000, 5 }, + { + "Serpent's", + IPL_MANA, + 30, + 40, + 15, + PLT_STAFF|PLT_MISC, + 0, + 0, + 1, + 4100, + 6000, + 7 + }, + { + "Drake's", + IPL_MANA, + 41, + 50, + 21, + PLT_STAFF|PLT_MISC, + 0, + 0, + 1, + 6100, + 10000, + 9 + }, + { + "Dragon's", + IPL_MANA, + 51, + 60, + 27, + PLT_STAFF|PLT_MISC, + 0, + 0, + 1, + 10100, + 15000, + 11 + }, + { "Wyrm's", IPL_MANA, 61, 80, 35, PLT_STAFF, 0, 0, 1, 15100, 19000, 12 }, + { "Hydra's", IPL_MANA, 81, 100, 60, PLT_STAFF, 0, 0, 1, 19100, 30000, 13 }, + { "Angel's", IPL_SPLLVLADD, 1, 1, 15, PLT_STAFF, 16, 0, 1, 25000, 25000, 2 }, + { + "Arch-Angel's", + IPL_SPLLVLADD, + 2, + 2, + 25, + PLT_STAFF, + 16, + 0, + 1, + 50000, + 50000, + 3 + }, + { "Plentiful", IPL_CHARGES, 2, 2, 4, PLT_STAFF, 0, 0, 1, 2000, 2000, 2 }, + { "Bountiful", IPL_CHARGES, 3, 3, 9, PLT_STAFF, 0, 0, 1, 3000, 3000, 3 }, + { + "Flaming", + IPL_FIREDAM, + 1, + 10, + 7, + PLT_WEAP|PLT_STAFF, + 0, + 0, + 1, + 5000, + 5000, + 2 + }, + { + "Lightning", + IPL_LIGHTDAM, + 2, + 20, + 18, + PLT_WEAP|PLT_STAFF, + 0, + 0, + 1, + 10000, + 10000, + 2 + }, + { &empty_string, IPL_INVALID, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } +}; +PLStruct PL_Suffix[96] = +{ + { "quality", IPL_DAMMOD, 1, 2, 2, PLT_WEAP|PLT_BOW, 0, 0, 1, 100, 200, 2 }, + { "maiming", IPL_DAMMOD, 3, 5, 7, PLT_WEAP|PLT_BOW, 0, 0, 1, 1300, 1500, 3 }, + { "slaying", IPL_DAMMOD, 6, 8, 15, PLT_WEAP, 0, 0, 1, 2600, 3000, 5 }, + { "gore", IPL_DAMMOD, 9, 12, 25, PLT_WEAP, 0, 0, 1, 4100, 5000, 8 }, + { "carnage", IPL_DAMMOD, 13, 16, 35, PLT_WEAP, 0, 0, 1, 5100, 10000, 10 }, + { "slaughter", IPL_DAMMOD, 17, 20, 60, PLT_WEAP, 0, 0, 1, 10100, 15000, 13 }, + { + "pain", + IPL_GETHIT, + 2, + 4, + 4, + PLT_ARMO|PLT_SHLD|PLT_MISC, + 1, + 0, + 0, + 0, + 0, + 4294967292 + }, + { + "tears", + IPL_GETHIT, + 1, + 1, + 2, + PLT_ARMO|PLT_SHLD|PLT_MISC, + 1, + 0, + 0, + 0, + 0, + 4294967294 + }, + { + "health", + IPL_GETHIT_CURSE, + 1, + 1, + 2, + PLT_ARMO|PLT_SHLD|PLT_MISC, + 16, + 0, + 1, + 200, + 200, + 2 + }, + { + "protection", + IPL_GETHIT_CURSE, + 2, + 2, + 6, + PLT_ARMO|PLT_SHLD, + 16, + 0, + 1, + 400, + 800, + 4 + }, + { + "absorption", + IPL_GETHIT_CURSE, + 3, + 3, + 12, + PLT_ARMO|PLT_SHLD, + 16, + 0, + 1, + 1001, + 2500, + 10 + }, + { + "deflection", + IPL_GETHIT_CURSE, + 4, + 4, + 20, + PLT_ARMO, + 16, + 0, + 1, + 2500, + 6500, + 15 + }, + { "osmosis", IPL_GETHIT_CURSE, 5, 6, 50, PLT_ARMO, 16, 0, 1, 7500, 10000, 20 }, + { + "frailty", + IPL_STR_CURSE, + 6, + 10, + 3, + PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_BOW|PLT_MISC, + 1, + 0, + 0, + 0, + 0, + 4294967293 + }, + { + "weakness", + IPL_STR_CURSE, + 1, + 5, + 1, + PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_BOW|PLT_MISC, + 1, + 0, + 0, + 0, + 0, + 4294967294 + }, + { + "strength", + IPL_STR, + 1, + 5, + 1, + PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_BOW|PLT_MISC, + 0, + 0, + 1, + 200, + 1000, + 2 + }, + { + "might", + IPL_STR, + 6, + 10, + 5, + PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_BOW|PLT_MISC, + 0, + 0, + 1, + 1200, + 2000, + 3 + }, + { + "power", + IPL_STR, + 11, + 15, + 11, + PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_BOW|PLT_MISC, + 0, + 0, + 1, + 2200, + 3000, + 4 + }, + { + "giants", + IPL_STR, + 16, + 20, + 17, + PLT_ARMO|PLT_WEAP|PLT_BOW|PLT_MISC, + 0, + 0, + 1, + 3200, + 5000, + 7 + }, + { "titans", IPL_STR, 21, 30, 23, PLT_WEAP|PLT_MISC, 0, 0, 1, 5200, 10000, 10 }, + { + "paralysis", + IPL_DEX_CURSE, + 6, + 10, + 3, + PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_BOW|PLT_MISC, + 1, + 0, + 0, + 0, + 0, + 4294967293 + }, + { + "atrophy", + IPL_DEX_CURSE, + 1, + 5, + 1, + PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_BOW|PLT_MISC, + 1, + 0, + 0, + 0, + 0, + 4294967294 + }, + { + "dexterity", + IPL_DEX, + 1, + 5, + 1, + PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_BOW|PLT_MISC, + 0, + 0, + 1, + 200, + 1000, + 2 + }, + { + "skill", + IPL_DEX, + 6, + 10, + 5, + PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_BOW|PLT_MISC, + 0, + 0, + 1, + 1200, + 2000, + 3 + }, + { + "accuracy", + IPL_DEX, + 11, + 15, + 11, + PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_BOW|PLT_MISC, + 0, + 0, + 1, + 2200, + 3000, + 4 + }, + { + "precision", + IPL_DEX, + 16, + 20, + 17, + PLT_ARMO|PLT_WEAP|PLT_BOW|PLT_MISC, + 0, + 0, + 1, + 3200, + 5000, + 7 + }, + { + "perfection", + IPL_DEX, + 21, + 30, + 23, + PLT_BOW|PLT_MISC, + 0, + 0, + 1, + 5200, + 10000, + 10 + }, + { + "the fool", + IPL_MAG_CURSE, + 6, + 10, + 3, + PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_STAFF|PLT_BOW|PLT_MISC, + 1, + 0, + 0, + 0, + 0, + 4294967293 + }, + { + "dyslexia", + IPL_MAG_CURSE, + 1, + 5, + 1, + PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_STAFF|PLT_BOW|PLT_MISC, + 1, + 0, + 0, + 0, + 0, + 4294967294 + }, + { + "magic", + IPL_MAG, + 1, + 5, + 1, + PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_STAFF|PLT_BOW|PLT_MISC, + 0, + 0, + 1, + 200, + 1000, + 2 + }, + { + "the mind", + IPL_MAG, + 6, + 10, + 5, + PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_STAFF|PLT_BOW|PLT_MISC, + 0, + 0, + 1, + 1200, + 2000, + 3 + }, + { + "brilliance", + IPL_MAG, + 11, + 15, + 11, + PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_STAFF|PLT_BOW|PLT_MISC, + 0, + 0, + 1, + 2200, + 3000, + 4 + }, + { + "sorcery", + IPL_MAG, + 16, + 20, + 17, + PLT_ARMO|PLT_WEAP|PLT_STAFF|PLT_BOW|PLT_MISC, + 0, + 0, + 1, + 3200, + 5000, + 7 + }, + { + "wizardry", + IPL_MAG, + 21, + 30, + 23, + PLT_STAFF|PLT_MISC, + 0, + 0, + 1, + 5200, + 10000, + 10 + }, + { + "illness", + IPL_VIT_CURSE, + 6, + 10, + 3, + PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_BOW|PLT_MISC, + 1, + 0, + 0, + 0, + 0, + 4294967293 + }, + { + "disease", + IPL_VIT_CURSE, + 1, + 5, + 1, + PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_BOW|PLT_MISC, + 1, + 0, + 0, + 0, + 0, + 4294967294 + }, + { + "vitality", + IPL_VIT, + 1, + 5, + 1, + PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_BOW|PLT_MISC, + 16, + 0, + 1, + 200, + 1000, + 2 + }, + { + "zest", + IPL_VIT, + 6, + 10, + 5, + PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_BOW|PLT_MISC, + 16, + 0, + 1, + 1200, + 2000, + 3 + }, + { + "vim", + IPL_VIT, + 11, + 15, + 11, + PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_BOW|PLT_MISC, + 16, + 0, + 1, + 2200, + 3000, + 4 + }, + { + "vigor", + IPL_VIT, + 16, + 20, + 17, + PLT_ARMO|PLT_WEAP|PLT_BOW|PLT_MISC, + 16, + 0, + 1, + 3200, + 5000, + 7 + }, + { "life", IPL_VIT, 21, 30, 23, PLT_MISC, 16, 0, 1, 5200, 10000, 10 }, + { + "trouble", + IPL_ATTRIBS_CURSE, + 6, + 10, + 12, + PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_BOW|PLT_MISC, + 1, + 0, + 0, + 0, + 0, + 4294967286 + }, + { + "the pit", + IPL_ATTRIBS_CURSE, + 1, + 5, + 5, + PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_BOW|PLT_MISC, + 1, + 0, + 0, + 0, + 0, + 4294967291 + }, + { + "the sky", + IPL_ATTRIBS, + 1, + 3, + 5, + PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_BOW|PLT_MISC, + 0, + 0, + 1, + 800, + 4000, + 5 + }, + { + "the moon", + IPL_ATTRIBS, + 4, + 7, + 11, + PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_BOW|PLT_MISC, + 0, + 0, + 1, + 4800, + 8000, + 10 + }, + { + "the stars", + IPL_ATTRIBS, + 8, + 11, + 17, + PLT_ARMO|PLT_WEAP|PLT_BOW|PLT_MISC, + 0, + 0, + 1, + 8800, + 12000, + 15 + }, + { + "the heavens", + IPL_ATTRIBS, + 12, + 15, + 25, + PLT_WEAP|PLT_BOW|PLT_MISC, + 0, + 0, + 1, + 12800, + 20000, + 20 + }, + { "the zodiac", IPL_ATTRIBS, 16, 20, 30, PLT_MISC, 0, 0, 1, 20800, 40000, 30 }, + { + "the vulture", + IPL_LIFE_CURSE, + 11, + 25, + 4, + PLT_ARMO|PLT_SHLD|PLT_MISC, + 1, + 0, + 0, + 0, + 0, + 4294967292 + }, + { + "the jackal", + IPL_LIFE_CURSE, + 1, + 10, + 1, + PLT_ARMO|PLT_SHLD|PLT_MISC, + 1, + 0, + 0, + 0, + 0, + 4294967294 + }, + { + "the fox", + IPL_LIFE, + 10, + 15, + 1, + PLT_ARMO|PLT_SHLD|PLT_MISC, + 0, + 0, + 1, + 100, + 1000, + 2 + }, + { + "the jaguar", + IPL_LIFE, + 16, + 20, + 5, + PLT_ARMO|PLT_SHLD|PLT_MISC, + 0, + 0, + 1, + 1100, + 2000, + 3 + }, + { + "the eagle", + IPL_LIFE, + 21, + 30, + 9, + PLT_ARMO|PLT_SHLD|PLT_MISC, + 0, + 0, + 1, + 2100, + 4000, + 5 + }, + { + "the wolf", + IPL_LIFE, + 30, + 40, + 15, + PLT_ARMO|PLT_SHLD|PLT_MISC, + 0, + 0, + 1, + 4100, + 6000, + 7 + }, + { + "the tiger", + IPL_LIFE, + 41, + 50, + 21, + PLT_ARMO|PLT_SHLD|PLT_MISC, + 0, + 0, + 1, + 6100, + 10000, + 9 + }, + { + "the lion", + IPL_LIFE, + 51, + 60, + 27, + PLT_ARMO|PLT_MISC, + 0, + 0, + 1, + 10100, + 15000, + 11 + }, + { "the mammoth", IPL_LIFE, 61, 80, 35, PLT_ARMO, 0, 0, 1, 15100, 19000, 12 }, + { "the whale", IPL_LIFE, 81, 100, 60, PLT_ARMO, 0, 0, 1, 19100, 30000, 13 }, + { + "fragility", + IPL_DUR_CURSE, + 100, + 100, + 3, + PLT_ARMO|PLT_SHLD|PLT_WEAP, + 1, + 0, + 0, + 0, + 0, + 4294967292 + }, + { + "brittleness", + IPL_DUR_CURSE, + 26, + 75, + 1, + PLT_ARMO|PLT_SHLD|PLT_WEAP, + 1, + 0, + 0, + 0, + 0, + 4294967294 + }, + { + "sturdiness", + IPL_DUR, + 26, + 75, + 1, + PLT_ARMO|PLT_SHLD|PLT_WEAP, + 0, + 0, + 1, + 100, + 100, + 2 + }, + { + "craftsmanship", + IPL_DUR, + 51, + 100, + 6, + PLT_ARMO|PLT_SHLD|PLT_WEAP, + 0, + 0, + 1, + 200, + 200, + 2 + }, + { + "structure", + IPL_DUR, + 101, + 200, + 12, + PLT_ARMO|PLT_SHLD|PLT_WEAP, + 0, + 0, + 1, + 300, + 300, + 2 + }, + { + "the ages", + IPL_INDESTRUCTIBLE, + 0, + 0, + 25, + PLT_ARMO|PLT_SHLD|PLT_WEAP, + 0, + 0, + 1, + 600, + 600, + 5 + }, + { + "the dark", + IPL_LIGHT_CURSE, + 4, + 4, + 6, + PLT_ARMO|PLT_WEAP|PLT_MISC, + 1, + 0, + 0, + 0, + 0, + 4294967293 + }, + { + "the night", + IPL_LIGHT_CURSE, + 2, + 2, + 3, + PLT_ARMO|PLT_WEAP|PLT_MISC, + 1, + 0, + 0, + 0, + 0, + 4294967294 + }, + { + "light", + IPL_LIGHT, + 2, + 2, + 4, + PLT_ARMO|PLT_WEAP|PLT_MISC, + 16, + 0, + 1, + 750, + 750, + 2 + }, + { + "radiance", + IPL_LIGHT, + 4, + 4, + 8, + PLT_ARMO|PLT_WEAP|PLT_MISC, + 16, + 0, + 1, + 1500, + 1500, + 3 + }, + { "flame", IPL_FIRE_ARROWS, 1, 3, 1, PLT_BOW, 0, 0, 1, 2000, 2000, 2 }, + { "fire", IPL_FIRE_ARROWS, 1, 6, 11, PLT_BOW, 0, 0, 1, 4000, 4000, 4 }, + { "burning", IPL_FIRE_ARROWS, 1, 16, 35, PLT_BOW, 0, 0, 1, 6000, 6000, 6 }, + { "shock", IPL_LIGHT_ARROWS, 1, 6, 13, PLT_BOW, 0, 0, 1, 6000, 6000, 2 }, + { "lightning", IPL_LIGHT_ARROWS, 1, 10, 21, PLT_BOW, 0, 0, 1, 8000, 8000, 4 }, + { "thunder", IPL_LIGHT_ARROWS, 1, 20, 60, PLT_BOW, 0, 0, 1, 12000, 12000, 6 }, + { "many", IPL_DUR, 100, 100, 3, PLT_BOW, 0, 0, 1, 750, 750, 2 }, + { "plenty", IPL_DUR, 200, 200, 7, PLT_BOW, 0, 0, 1, 1500, 1500, 3 }, + { "thorns", IPL_THORNS, 1, 3, 1, PLT_ARMO|PLT_SHLD, 0, 0, 1, 500, 500, 2 }, + { + "corruption", + IPL_NOMANA, + 0, + 0, + 5, + PLT_ARMO|PLT_SHLD|PLT_WEAP, + 1, + 0, + 0, + 4294966296, + 4294966296, + 2 + }, + { + "thieves", + IPL_ABSHALFTRAP, + 0, + 0, + 11, + PLT_ARMO|PLT_SHLD|PLT_MISC, + 0, + 0, + 1, + 1500, + 1500, + 2 + }, + { + "the bear", + IPL_KNOCKBACK, + 0, + 0, + 5, + PLT_WEAP|PLT_STAFF|PLT_BOW, + 1, + 0, + 1, + 750, + 750, + 2 + }, + { "the bat", IPL_STEALMANA, 3, 3, 8, PLT_WEAP, 0, 0, 1, 7500, 7500, 3 }, + { "vampires", IPL_STEALMANA, 5, 5, 19, PLT_WEAP, 0, 0, 1, 15000, 15000, 3 }, + { "the leech", IPL_STEALLIFE, 3, 3, 8, PLT_WEAP, 0, 0, 1, 7500, 7500, 3 }, + { "blood", IPL_STEALLIFE, 5, 5, 19, PLT_WEAP, 0, 0, 1, 15000, 15000, 3 }, + { "piercing", IPL_TARGAC, 2, 6, 1, PLT_WEAP|PLT_BOW, 0, 0, 1, 1000, 1000, 3 }, + { + "puncturing", + IPL_TARGAC, + 4, + 12, + 9, + PLT_WEAP|PLT_BOW, + 0, + 0, + 1, + 2000, + 2000, + 6 + }, + { "bashing", IPL_TARGAC, 8, 24, 17, PLT_WEAP, 0, 0, 1, 4000, 4000, 12 }, + { + "readiness", + IPL_FASTATTACK, + 1, + 1, + 1, + PLT_WEAP|PLT_STAFF|PLT_BOW, + 0, + 0, + 1, + 2000, + 2000, + 2 + }, + { + "swiftness", + IPL_FASTATTACK, + 2, + 2, + 10, + PLT_WEAP|PLT_STAFF|PLT_BOW, + 0, + 0, + 1, + 4000, + 4000, + 4 + }, + { + "speed", + IPL_FASTATTACK, + 3, + 3, + 19, + PLT_WEAP|PLT_STAFF, + 0, + 0, + 1, + 8000, + 8000, + 8 + }, + { + "haste", + IPL_FASTATTACK, + 4, + 4, + 27, + PLT_WEAP|PLT_STAFF, + 0, + 0, + 1, + 16000, + 16000, + 16 + }, + { + "balance", + IPL_FASTRECOVER, + 1, + 1, + 1, + PLT_ARMO|PLT_MISC, + 0, + 0, + 1, + 2000, + 2000, + 2 + }, + { + "stability", + IPL_FASTRECOVER, + 2, + 2, + 10, + PLT_ARMO|PLT_MISC, + 0, + 0, + 1, + 4000, + 4000, + 4 + }, + { + "harmony", + IPL_FASTRECOVER, + 3, + 3, + 20, + PLT_ARMO|PLT_MISC, + 0, + 0, + 1, + 8000, + 8000, + 8 + }, + { "blocking", IPL_FASTBLOCK, 1, 1, 5, PLT_SHLD, 0, 0, 1, 4000, 4000, 4 }, + { &empty_string, IPL_INVALID, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } +}; +UItemStruct UniqueItemList[91] = +{ + { + "The Butcher's Cleaver", + UITYPE_CLEAVER, + 1u, + 3u, + 3650, + IPL_STR, + 10, + 10, + IPL_SETDAM, + 4, + 24, + IPL_SETDUR, + 10, + 10, + IPL_TOHIT, + 0, + 0, + IPL_TOHIT, + 0, + 0, + IPL_TOHIT, + 0, + 0 + }, + { + "The Undead Crown", + UITYPE_SKCROWN, + 1u, + 3u, + 16650, + IPL_RNDSTEALLIFE, + 0, + 0, + IPL_SETAC, + 8, + 8, + IPL_INVCURS, + 77, + 0, + IPL_TOHIT, + 0, + 0, + IPL_TOHIT, + 0, + 0, + IPL_TOHIT, + 0, + 0 + }, + { + "Empyrean Band", + UITYPE_INFRARING, + 1u, + 4u, + 8000, + IPL_ATTRIBS, + 2, + 2, + IPL_LIGHT, + 2, + 2, + IPL_FASTRECOVER, + 1, + 1, + IPL_ABSHALFTRAP, + 0, + 0, + IPL_TOHIT, + 0, + 0, + IPL_TOHIT, + 0, + 0 + }, + { + "Optic Amulet", + UITYPE_OPTAMULET, + 1u, + 5u, + 9750, + IPL_LIGHT, + 2, + 2, + IPL_LIGHTRES, + 20, + 20, + IPL_GETHIT_CURSE, + 1, + 1, + IPL_MAG, + 5, + 5, + IPL_INVCURS, + 44, + 0, + IPL_TOHIT, + 0, + 0 + }, + { + "Ring of Truth", + UITYPE_TRING, + 1u, + 4u, + 9100, + IPL_LIFE, + 10, + 10, + IPL_GETHIT_CURSE, + 1, + 1, + IPL_ALLRES, + 10, + 10, + IPL_INVCURS, + 10, + 0, + IPL_TOHIT, + 0, + 0, + IPL_TOHIT, + 0, + 0 + }, + { + "Harlequin Crest", + UITYPE_HARCREST, + 1u, + 6u, + 4000, + IPL_AC_CURSE, + 3, + 3, + IPL_GETHIT_CURSE, + 1, + 1, + IPL_ATTRIBS, + 2, + 2, + IPL_LIFE, + 7, + 7, + IPL_MANA, + 7, + 7, + IPL_INVCURS, + 81, + 0 + }, + { + "Veil of Steel", + UITYPE_STEELVEIL, + 1u, + 6u, + 63800, + IPL_ALLRES, + 50, + 50, + IPL_LIGHT_CURSE, + 2, + 2, + IPL_ACP, + 60, + 60, + IPL_MANA_CURSE, + 30, + 30, + IPL_STR, + 15, + 15, + IPL_VIT, + 15, + 15 + }, + { + "Arkaine's Valor", + UITYPE_ARMOFVAL, + 1u, + 4u, + 42000, + IPL_SETAC, + 25, + 25, + IPL_VIT, + 10, + 10, + IPL_GETHIT_CURSE, + 3, + 3, + IPL_FASTRECOVER, + 3, + 3, + IPL_TOHIT, + 0, + 0, + IPL_TOHIT, + 0, + 0 + }, + { + "Griswold's Edge", + UITYPE_GRISWOLD, + 1u, + 6u, + 42000, + IPL_FIREDAM, + 1, + 10, + IPL_TOHIT, + 25, + 25, + IPL_FASTATTACK, + 2, + 2, + IPL_KNOCKBACK, + 0, + 0, + IPL_MANA, + 20, + 20, + IPL_LIFE_CURSE, + 20, + 20 + }, + { + "Lightforge", + UITYPE_MACE, + 1u, + 6u, + 26675, + IPL_LIGHT, + 4, + 4, + IPL_DAMP, + 150, + 150, + IPL_TOHIT, + 25, + 25, + IPL_FIREDAM, + 10, + 20, + IPL_INDESTRUCTIBLE, + 0, + 0, + IPL_ATTRIBS, + 8, + 8 + }, + { + "The Rift Bow", + UITYPE_SHORTBOW, + 1u, + 3u, + 1800, + IPL_RNDARROWVEL, + 0, + 0, + IPL_DAMMOD, + 2, + 2, + IPL_DEX_CURSE, + 3, + 3, + IPL_TOHIT, + 0, + 0, + IPL_TOHIT, + 0, + 0, + IPL_TOHIT, + 0, + 0 + }, + { + "The Needler", + UITYPE_SHORTBOW, + 2u, + 4u, + 8900, + IPL_TOHIT, + 50, + 50, + IPL_SETDAM, + 1, + 3, + IPL_FASTATTACK, + 2, + 2, + IPL_INVCURS, + 158, + 0, + IPL_TOHIT, + 0, + 0, + IPL_TOHIT, + 0, + 0 + }, + { + "The Celestial Bow", + UITYPE_LONGBOW, + 2u, + 4u, + 1200, + IPL_NOMINSTR, + 0, + 0, + IPL_DAMMOD, + 2, + 2, + IPL_SETAC, + 5, + 5, + IPL_INVCURS, + 133, + 0, + IPL_TOHIT, + 0, + 0, + IPL_TOHIT, + 0, + 0 + }, + { + "Deadly Hunter", + UITYPE_COMPBOW, + 3u, + 4u, + 8750, + IPL_3XDAMVDEM, + 10, + 10, + IPL_TOHIT, + 20, + 20, + IPL_MAG_CURSE, + 5, + 5, + IPL_INVCURS, + 108, + 0, + IPL_TOHIT, + 0, + 0, + IPL_TOHIT, + 0, + 0 + }, + { + "Bow of the Dead", + UITYPE_COMPBOW, + 5u, + 6u, + 2500, + IPL_TOHIT, + 10, + 10, + IPL_DEX, + 4, + 4, + IPL_VIT_CURSE, + 3, + 3, + IPL_LIGHT_CURSE, + 2, + 2, + IPL_SETDUR, + 30, + 30, + IPL_INVCURS, + 108, + 0 + }, + { + "The Blackoak Bow", + UITYPE_LONGBOW, + 5u, + 4u, + 2500, + IPL_DEX, + 10, + 10, + IPL_VIT_CURSE, + 10, + 10, + IPL_DAMP, + 50, + 50, + IPL_LIGHT_CURSE, + 1, + 1, + IPL_TOHIT, + 0, + 0, + IPL_TOHIT, + 0, + 0 + }, + { + "Flamedart", + UITYPE_HUNTBOW, + 10u, + 4u, + 14250, + IPL_FIRE_ARROWS, + 0, + 0, + IPL_FIREDAM, + 1, + 6, + IPL_TOHIT, + 20, + 20, + IPL_FIRERES, + 40, + 40, + IPL_TOHIT, + 0, + 0, + IPL_TOHIT, + 0, + 0 + }, + { + "Fleshstinger", + UITYPE_LONGBOW, + 13u, + 4u, + 16500, + IPL_DEX, + 15, + 15, + IPL_TOHIT, + 40, + 40, + IPL_DAMP, + 80, + 80, + IPL_DUR, + 6, + 6, + IPL_TOHIT, + 0, + 0, + IPL_TOHIT, + 0, + 0 + }, + { + "Windforce", + UITYPE_WARBOW, + 17u, + 4u, + 37750, + IPL_STR, + 5, + 5, + IPL_DAMP, + 200, + 200, + IPL_KNOCKBACK, + 0, + 0, + IPL_INVCURS, + 164, + 0, + IPL_TOHIT, + 0, + 0, + IPL_TOHIT, + 0, + 0 + }, + { + "Eaglehorn", + UITYPE_BATTLEBOW, + 26u, + 5u, + 42500, + IPL_DEX, + 20, + 20, + IPL_TOHIT, + 50, + 50, + IPL_DAMP, + 100, + 100, + IPL_INDESTRUCTIBLE, + 0, + 0, + IPL_INVCURS, + 108, + 0, + IPL_TOHIT, + 0, + 0 + }, + { + "Gonnagal's Dirk", + UITYPE_DAGGER, + 1u, + 5u, + 7040, + IPL_DEX_CURSE, + 5, + 5, + IPL_DAMMOD, + 4, + 4, + IPL_FASTATTACK, + 2, + 2, + IPL_FIRERES, + 25, + 25, + IPL_INVCURS, + 54, + 0, + IPL_TOHIT, + 0, + 0 + }, + { + "The Defender", + UITYPE_SABRE, + 1u, + 3u, + 2000, + IPL_SETAC, + 5, + 5, + IPL_VIT, + 5, + 5, + IPL_TOHIT_CURSE, + 5, + 5, + IPL_TOHIT, + 0, + 0, + IPL_TOHIT, + 0, + 0, + IPL_TOHIT, + 0, + 0 + }, + { + "Gryphons Claw", + UITYPE_FALCHION, + 1u, + 4u, + 1000, + IPL_DAMP, + 100, + 100, + IPL_MAG_CURSE, + 2, + 2, + IPL_DEX_CURSE, + 5, + 5, + IPL_INVCURS, + 68, + 0, + IPL_TOHIT, + 0, + 0, + IPL_TOHIT, + 0, + 0 + }, + { + "Black Razor", + UITYPE_DAGGER, + 1u, + 4u, + 2000, + IPL_DAMP, + 150, + 150, + IPL_VIT, + 2, + 2, + IPL_SETDUR, + 5, + 5, + IPL_INVCURS, + 53, + 0, + IPL_TOHIT, + 0, + 0, + IPL_TOHIT, + 0, + 0 + }, + { + "Gibbous Moon", + UITYPE_BROADSWR, + 2u, + 4u, + 6660, + IPL_ATTRIBS, + 2, + 2, + IPL_DAMP, + 25, + 25, + IPL_MANA, + 15, + 15, + IPL_LIGHT_CURSE, + 3, + 3, + IPL_TOHIT, + 0, + 0, + IPL_TOHIT, + 0, + 0 + }, + { + "Ice Shank", + UITYPE_LONGSWR, + 3u, + 3u, + 5250, + IPL_FIRERES, + 40, + 40, + IPL_SETDUR, + 15, + 15, + IPL_STR, + 5, + 10, + IPL_TOHIT, + 0, + 0, + IPL_TOHIT, + 0, + 0, + IPL_TOHIT, + 0, + 0 + }, + { + "The Executioner's Blade", + UITYPE_FALCHION, + 3u, + 5u, + 7080, + IPL_DAMP, + 150, + 150, + IPL_LIFE_CURSE, + 10, + 10, + IPL_LIGHT_CURSE, + 1, + 1, + IPL_DUR, + 200, + 200, + IPL_INVCURS, + 58, + 0, + IPL_TOHIT, + 0, + 0 + }, + { + "The Bonesaw", + UITYPE_CLAYMORE, + 6u, + 6u, + 4400, + IPL_DAMMOD, + 10, + 10, + IPL_STR, + 10, + 10, + IPL_MAG_CURSE, + 5, + 5, + IPL_DEX_CURSE, + 5, + 5, + IPL_LIFE, + 10, + 10, + IPL_MANA_CURSE, + 10, + 10 + }, + { + "Shadowhawk", + UITYPE_BROADSWR, + 8u, + 4u, + 13750, + IPL_LIGHT_CURSE, + 2, + 2, + IPL_STEALLIFE, + 5, + 5, + IPL_TOHIT, + 15, + 15, + IPL_ALLRES, + 5, + 5, + IPL_TOHIT, + 0, + 0, + IPL_TOHIT, + 0, + 0 + }, + { + "Wizardspike", + UITYPE_DAGGER, + 11u, + 5u, + 12920, + IPL_MAG, + 15, + 15, + IPL_MANA, + 35, + 35, + IPL_TOHIT, + 25, + 25, + IPL_ALLRES, + 15, + 15, + IPL_INVCURS, + 50, + 0, + IPL_TOHIT, + 0, + 0 + }, + { + "Lightsabre", + UITYPE_SABRE, + 13u, + 4u, + 19150, + IPL_LIGHT, + 2, + 2, + IPL_LIGHTDAM, + 1, + 10, + IPL_TOHIT, + 20, + 20, + IPL_LIGHTRES, + 50, + 50, + IPL_TOHIT, + 0, + 0, + IPL_TOHIT, + 0, + 0 + }, + { + "The Falcon's Talon", + UITYPE_SCIMITAR, + 15u, + 5u, + 7867, + IPL_FASTATTACK, + 4, + 4, + IPL_TOHIT, + 20, + 20, + IPL_DAMP_CURSE, + 33, + 33, + IPL_DEX, + 10, + 10, + IPL_INVCURS, + 68, + 0, + IPL_TOHIT, + 0, + 0 + }, + { + "Inferno", + UITYPE_LONGSWR, + 17u, + 4u, + 34600, + IPL_FIREDAM, + 2, + 12, + IPL_LIGHT, + 3, + 3, + IPL_MANA, + 20, + 20, + IPL_FIRERES, + 80, + 80, + IPL_TOHIT, + 0, + 0, + IPL_TOHIT, + 0, + 0 + }, + { + "Doombringer", + UITYPE_BASTARDSWR, + 19u, + 5u, + 18250, + IPL_TOHIT, + 25, + 25, + IPL_DAMP, + 250, + 250, + IPL_ATTRIBS_CURSE, + 5, + 5, + IPL_LIFE_CURSE, + 25, + 25, + IPL_LIGHT_CURSE, + 2, + 2, + IPL_TOHIT, + 0, + 0 + }, + { + "The Grizzly", + UITYPE_TWOHANDSWR, + 23u, + 6u, + 50000, + IPL_STR, + 20, + 20, + IPL_VIT_CURSE, + 5, + 5, + IPL_DAMP, + 200, + 200, + IPL_KNOCKBACK, + 0, + 0, + IPL_DUR, + 100, + 100, + IPL_INVCURS, + 160, + 0 + }, + { + "The Grandfather", + UITYPE_GREATSWR, + 27u, + 6u, + 119800, + IPL_ONEHAND, + 0, + 0, + IPL_ATTRIBS, + 5, + 5, + IPL_TOHIT, + 20, + 20, + IPL_DAMP, + 70, + 70, + IPL_LIFE, + 20, + 20, + IPL_INVCURS, + 161, + 0 + }, + { + "The Mangler", + UITYPE_LARGEAXE, + 2u, + 5u, + 2850, + IPL_DAMP, + 200, + 200, + IPL_DEX_CURSE, + 5, + 5, + IPL_MAG_CURSE, + 5, + 5, + IPL_MANA_CURSE, + 10, + 10, + IPL_INVCURS, + 144, + 0, + IPL_TOHIT, + 0, + 0 + }, + { + "Sharp Beak", + UITYPE_LARGEAXE, + 2u, + 4u, + 2850, + IPL_LIFE, + 20, + 20, + IPL_MAG_CURSE, + 10, + 10, + IPL_MANA_CURSE, + 10, + 10, + IPL_INVCURS, + 143, + 0, + IPL_TOHIT, + 0, + 0, + IPL_TOHIT, + 0, + 0 + }, + { + "BloodSlayer", + UITYPE_BROADAXE, + 3u, + 5u, + 2500, + IPL_DAMP, + 100, + 100, + IPL_3XDAMVDEM, + 50, + 50, + IPL_ATTRIBS_CURSE, + 5, + 5, + IPL_SPLLVLADD, + 4294967295, + 4294967295, + IPL_INVCURS, + 144, + 0, + IPL_TOHIT, + 0, + 0 + }, + { + "The Celestial Axe", + UITYPE_BATTLEAXE, + 4u, + 4u, + 14100, + IPL_NOMINSTR, + 0, + 0, + IPL_TOHIT, + 15, + 15, + IPL_LIFE, + 15, + 15, + IPL_STR_CURSE, + 15, + 15, + IPL_TOHIT, + 0, + 0, + IPL_TOHIT, + 0, + 0 + }, + { + "Wicked Axe", + UITYPE_LARGEAXE, + 5u, + 6u, + 31150, + IPL_TOHIT, + 30, + 30, + IPL_DEX, + 10, + 10, + IPL_VIT_CURSE, + 10, + 10, + IPL_GETHIT_CURSE, + 1, + 6, + IPL_INDESTRUCTIBLE, + 0, + 0, + IPL_INVCURS, + 143, + 0 + }, + { + "Stonecleaver", + UITYPE_BROADAXE, + 7u, + 5u, + 23900, + IPL_LIFE, + 30, + 30, + IPL_TOHIT, + 20, + 20, + IPL_DAMP, + 50, + 50, + IPL_LIGHTRES, + 40, + 40, + IPL_INVCURS, + 104, + 0, + IPL_TOHIT, + 0, + 0 + }, + { + "Aguinara's Hatchet", + UITYPE_SMALLAXE, + 12u, + 3u, + 24800, + IPL_SPLLVLADD, + 1, + 1, + IPL_MAG, + 10, + 10, + IPL_MAGICRES, + 80, + 80, + IPL_TOHIT, + 0, + 0, + IPL_TOHIT, + 0, + 0, + IPL_TOHIT, + 0, + 0 + }, + { + "Hellslayer", + UITYPE_BATTLEAXE, + 15u, + 5u, + 26200, + IPL_STR, + 8, + 8, + IPL_VIT, + 8, + 8, + IPL_DAMP, + 100, + 100, + IPL_LIFE, + 25, + 25, + IPL_MANA_CURSE, + 25, + 25, + IPL_TOHIT, + 0, + 0 + }, + { + "Messerschmidt's Reaver", + UITYPE_GREATAXE, + 25u, + 6u, + 58000, + IPL_DAMP, + 200, + 200, + IPL_DAMMOD, + 15, + 15, + IPL_ATTRIBS, + 5, + 5, + IPL_LIFE_CURSE, + 50, + 50, + IPL_FIREDAM, + 2, + 12, + IPL_INVCURS, + 163, + 0 + }, + { + "Crackrust", + UITYPE_MACE, + 1u, + 5u, + 11375, + IPL_ATTRIBS, + 2, + 2, + IPL_INDESTRUCTIBLE, + 0, + 0, + IPL_ALLRES, + 15, + 15, + IPL_DAMP, + 50, + 50, + IPL_SPLLVLADD, + 4294967295, + 4294967295, + IPL_TOHIT, + 0, + 0 + }, + { + "Hammer of Jholm", + UITYPE_MAUL, + 1u, + 4u, + 8700, + IPL_DAMP, + 4, + 10, + IPL_INDESTRUCTIBLE, + 0, + 0, + IPL_STR, + 3, + 3, + IPL_TOHIT, + 15, + 15, + IPL_TOHIT, + 0, + 0, + IPL_TOHIT, + 0, + 0 + }, + { + "Civerb's Cudgel", + UITYPE_MACE, + 1u, + 3u, + 2000, + IPL_3XDAMVDEM, + 35, + 35, + IPL_DEX_CURSE, + 5, + 5, + IPL_MAG_CURSE, + 2, + 2, + IPL_TOHIT, + 0, + 0, + IPL_TOHIT, + 0, + 0, + IPL_TOHIT, + 0, + 0 + }, + { + "The Celestial Star", + UITYPE_FLAIL, + 2u, + 5u, + 7810, + IPL_NOMINSTR, + 0, + 0, + IPL_LIGHT, + 2, + 2, + IPL_DAMMOD, + 10, + 10, + IPL_AC_CURSE, + 8, + 8, + IPL_INVCURS, + 131, + 0, + IPL_TOHIT, + 0, + 0 + }, + { + "Baranar's Star", + UITYPE_MORNSTAR, + 5u, + 6u, + 6850, + IPL_TOHIT, + 12, + 12, + IPL_DAMP, + 80, + 80, + IPL_FASTATTACK, + 1, + 1, + IPL_VIT, + 4, + 4, + IPL_DEX_CURSE, + 4, + 4, + IPL_SETDUR, + 60, + 60 + }, + { + "Gnarled Root", + UITYPE_SPIKCLUB, + 9u, + 6u, + 9820, + IPL_TOHIT, + 20, + 20, + IPL_DAMP, + 300, + 300, + IPL_DEX, + 10, + 10, + IPL_MAG, + 5, + 5, + IPL_ALLRES, + 10, + 10, + IPL_AC_CURSE, + 10, + 10 + }, + { + "The Cranium Basher", + UITYPE_MAUL, + 12u, + 6u, + 36500, + IPL_DAMMOD, + 20, + 20, + IPL_STR, + 15, + 15, + IPL_INDESTRUCTIBLE, + 0, + 0, + IPL_MANA_CURSE, + 150, + 150, + IPL_ALLRES, + 5, + 5, + IPL_INVCURS, + 122, + 0 + }, + { + "Schaefer's Hammer", + UITYPE_WARHAMMER, + 16u, + 6u, + 56125, + IPL_DAMP_CURSE, + 100, + 100, + IPL_LIGHTDAM, + 1, + 50, + IPL_LIFE, + 50, + 50, + IPL_TOHIT, + 30, + 30, + IPL_LIGHTRES, + 80, + 80, + IPL_LIGHT, + 1, + 1 + }, + { + "Dreamflange", + UITYPE_MACE, + 26u, + 5u, + 26450, + IPL_MAG, + 30, + 30, + IPL_MANA, + 50, + 50, + IPL_MAGICRES, + 50, + 50, + IPL_LIGHT, + 2, + 2, + IPL_SPLLVLADD, + 1, + 1, + IPL_TOHIT, + 0, + 0 + }, + { + "Staff of Shadows", + UITYPE_LONGSTAFF, + 2u, + 5u, + 1250, + IPL_MAG_CURSE, + 10, + 10, + IPL_TOHIT, + 10, + 10, + IPL_DAMP, + 60, + 60, + IPL_LIGHT_CURSE, + 2, + 2, + IPL_FASTATTACK, + 1, + 1, + IPL_TOHIT, + 0, + 0 + }, + { + "Immolator", + UITYPE_LONGSTAFF, + 4u, + 4u, + 3900, + IPL_FIRERES, + 20, + 20, + IPL_FIREDAM, + 4, + 4, + IPL_MANA, + 10, + 10, + IPL_VIT_CURSE, + 5, + 5, + IPL_TOHIT, + 0, + 0, + IPL_TOHIT, + 0, + 0 + }, + { + "Storm Spire", + UITYPE_WARSTAFF, + 8u, + 4u, + 22500, + IPL_LIGHTRES, + 50, + 50, + IPL_LIGHTDAM, + 2, + 8, + IPL_STR, + 10, + 10, + IPL_MAG_CURSE, + 10, + 10, + IPL_TOHIT, + 0, + 0, + IPL_TOHIT, + 0, + 0 + }, + { + "Gleamsong", + UITYPE_SHORTSTAFF, + 8u, + 4u, + 6520, + IPL_MANA, + 25, + 25, + IPL_STR_CURSE, + 3, + 3, + IPL_VIT_CURSE, + 3, + 3, + IPL_SPELL, + 10, + 76, + IPL_TOHIT, + 0, + 0, + IPL_TOHIT, + 0, + 0 + }, + { + "Thundercall", + UITYPE_COMPSTAFF, + 14u, + 5u, + 22250, + IPL_TOHIT, + 35, + 35, + IPL_LIGHTDAM, + 1, + 10, + IPL_SPELL, + 3, + 76, + IPL_LIGHTRES, + 30, + 30, + IPL_LIGHT, + 2, + 2, + IPL_TOHIT, + 0, + 0 + }, + { + "The Protector", + UITYPE_SHORTSTAFF, + 16u, + 6u, + 17240, + IPL_VIT, + 5, + 5, + IPL_GETHIT_CURSE, + 5, + 5, + IPL_SETAC, + 40, + 40, + IPL_SPELL, + 2, + 86, + IPL_THORNS, + 1, + 3, + IPL_INVCURS, + 162, + 0 + }, + { + "Naj's Puzzler", + UITYPE_LONGSTAFF, + 18u, + 5u, + 34000, + IPL_MAG, + 20, + 20, + IPL_DEX, + 10, + 10, + IPL_ALLRES, + 20, + 20, + IPL_SPELL, + 23, + 57, + IPL_LIFE_CURSE, + 25, + 25, + IPL_TOHIT, + 0, + 0 + }, + { + "Mindcry", + UITYPE_QUARSTAFF, + 20u, + 4u, + 41500, + IPL_MAG, + 15, + 15, + IPL_SPELL, + 13, + 69, + IPL_ALLRES, + 15, + 15, + IPL_SPLLVLADD, + 1, + 1, + IPL_TOHIT, + 0, + 0, + IPL_TOHIT, + 0, + 0 + }, + { + "Rod of Onan", + UITYPE_WARSTAFF, + 22u, + 3u, + 44167, + IPL_SPELL, + 21, + 50, + IPL_DAMP, + 100, + 100, + IPL_ATTRIBS, + 5, + 5, + IPL_TOHIT, + 0, + 0, + IPL_TOHIT, + 0, + 0, + IPL_TOHIT, + 0, + 0 + }, + { + "Helm of Sprits", + UITYPE_HELM, + 1u, + 2u, + 7525, + IPL_STEALLIFE, + 5, + 5, + IPL_INVCURS, + 77, + 0, + IPL_TOHIT, + 0, + 0, + IPL_TOHIT, + 0, + 0, + IPL_TOHIT, + 0, + 0, + IPL_TOHIT, + 0, + 0 + }, + { + "Thinking Cap", + UITYPE_SKULLCAP, + 6u, + 5u, + 2020, + IPL_MANA, + 30, + 30, + IPL_SPLLVLADD, + 2, + 2, + IPL_ALLRES, + 20, + 20, + IPL_SETDUR, + 1, + 1, + IPL_INVCURS, + 93, + 0, + IPL_TOHIT, + 0, + 0 + }, + { + "OverLord's Helm", + UITYPE_HELM, + 7u, + 6u, + 12500, + IPL_STR, + 20, + 20, + IPL_DEX, + 15, + 15, + IPL_VIT, + 5, + 5, + IPL_MAG_CURSE, + 20, + 20, + IPL_SETDUR, + 15, + 15, + IPL_INVCURS, + 99, + 0 + }, + { + "Fool's Crest", + UITYPE_HELM, + 12u, + 5u, + 10150, + IPL_ATTRIBS_CURSE, + 4, + 4, + IPL_LIFE, + 100, + 100, + IPL_GETHIT, + 1, + 6, + IPL_THORNS, + 1, + 3, + IPL_INVCURS, + 80, + 0, + IPL_TOHIT, + 0, + 0 + }, + { + "Gotterdamerung", + UITYPE_GREATHELM, + 21u, + 6u, + 54900, + IPL_ATTRIBS, + 20, + 20, + IPL_SETAC, + 60, + 60, + IPL_GETHIT_CURSE, + 4, + 4, + IPL_ALLRESZERO, + 0, + 0, + IPL_LIGHT_CURSE, + 4, + 4, + IPL_INVCURS, + 85, + 0 + }, + { + "Royal Circlet", + UITYPE_CROWN, + 27u, + 5u, + 24875, + IPL_ATTRIBS, + 10, + 10, + IPL_MANA, + 40, + 40, + IPL_SETAC, + 40, + 40, + IPL_LIGHT, + 1, + 1, + IPL_INVCURS, + 79, + 0, + IPL_TOHIT, + 0, + 0 + }, + { + "Torn Flesh of Souls", + UITYPE_RAGS, + 2u, + 5u, + 4825, + IPL_SETAC, + 8, + 8, + IPL_VIT, + 10, + 10, + IPL_GETHIT_CURSE, + 1, + 1, + IPL_INDESTRUCTIBLE, + 0, + 0, + IPL_INVCURS, + 92, + 0, + IPL_TOHIT, + 0, + 0 + }, + { + "The Gladiator's Bane", + UITYPE_STUDARMOR, + 6u, + 4u, + 3450, + IPL_SETAC, + 25, + 25, + IPL_GETHIT_CURSE, + 2, + 2, + IPL_DUR, + 200, + 200, + IPL_ATTRIBS_CURSE, + 3, + 3, + IPL_TOHIT, + 0, + 0, + IPL_TOHIT, + 0, + 0 + }, + { + "The Rainbow Cloak", + UITYPE_CLOAK, + 2u, + 6u, + 4900, + IPL_SETAC, + 10, + 10, + IPL_ATTRIBS, + 1, + 1, + IPL_ALLRES, + 10, + 10, + IPL_LIFE, + 5, + 5, + IPL_DUR, + 50, + 50, + IPL_INVCURS, + 138, + 0 + }, + { + "Leather of Aut", + UITYPE_LEATHARMOR, + 4u, + 5u, + 10550, + IPL_SETAC, + 15, + 15, + IPL_STR, + 5, + 5, + IPL_MAG_CURSE, + 5, + 5, + IPL_DEX, + 5, + 5, + IPL_INDESTRUCTIBLE, + 0, + 0, + IPL_TOHIT, + 0, + 0 + }, + { + "Wisdom's Wrap", + UITYPE_ROBE, + 5u, + 6u, + 6200, + IPL_MAG, + 5, + 5, + IPL_MANA, + 10, + 10, + IPL_LIGHTRES, + 25, + 25, + IPL_SETAC, + 15, + 15, + IPL_GETHIT_CURSE, + 1, + 1, + IPL_INVCURS, + 138, + 0 + }, + { + "Sparking Mail", + UITYPE_CHAINMAIL, + 9u, + 2u, + 15750, + IPL_SETAC, + 30, + 30, + IPL_LIGHTDAM, + 1, + 10, + IPL_TOHIT, + 0, + 0, + IPL_TOHIT, + 0, + 0, + IPL_TOHIT, + 0, + 0, + IPL_TOHIT, + 0, + 0 + }, + { + "Scavenger Carapace", + UITYPE_BREASTPLATE, + 13u, + 4u, + 14000, + IPL_GETHIT_CURSE, + 15, + 15, + IPL_AC_CURSE, + 30, + 30, + IPL_DEX, + 5, + 5, + IPL_LIGHTRES, + 40, + 40, + IPL_TOHIT, + 0, + 0, + IPL_TOHIT, + 0, + 0 + }, + { + "Nightscape", + UITYPE_CAPE, + 16u, + 6u, + 11600, + IPL_FASTRECOVER, + 2, + 2, + IPL_LIGHT_CURSE, + 4, + 4, + IPL_SETAC, + 15, + 15, + IPL_DEX, + 3, + 3, + IPL_ALLRES, + 20, + 20, + IPL_INVCURS, + 138, + 0 + }, + { + "Naj's Light Plate", + UITYPE_PLATEMAIL, + 19u, + 6u, + 78700, + IPL_NOMINSTR, + 0, + 0, + IPL_MAG, + 5, + 5, + IPL_MANA, + 20, + 20, + IPL_ALLRES, + 20, + 20, + IPL_SPLLVLADD, + 1, + 1, + IPL_INVCURS, + 159, + 0 + }, + { + "Demonspike Coat", + UITYPE_FULLPLATE, + 25u, + 5u, + 251175, + IPL_SETAC, + 100, + 100, + IPL_GETHIT_CURSE, + 6, + 6, + IPL_STR, + 10, + 10, + IPL_INDESTRUCTIBLE, + 0, + 0, + IPL_FIRERES, + 50, + 50, + IPL_TOHIT, + 0, + 0 + }, + { + "The Deflector", + UITYPE_BUCKLER, + 1u, + 5u, + 1500, + IPL_SETAC, + 7, + 7, + IPL_ALLRES, + 10, + 10, + IPL_DAMP_CURSE, + 20, + 20, + IPL_TOHIT_CURSE, + 5, + 5, + IPL_INVCURS, + 83, + 0, + IPL_TOHIT, + 0, + 0 + }, + { + "Split Skull Shield", + UITYPE_BUCKLER, + 1u, + 6u, + 2025, + IPL_SETAC, + 10, + 10, + IPL_LIFE, + 10, + 10, + IPL_STR, + 2, + 2, + IPL_LIGHT_CURSE, + 1, + 1, + IPL_SETDUR, + 15, + 15, + IPL_INVCURS, + 116, + 0 + }, + { + "Dragon's Breach", + UITYPE_KITESHIELD, + 2u, + 6u, + 19200, + IPL_FIRERES, + 25, + 25, + IPL_STR, + 5, + 5, + IPL_SETAC, + 20, + 20, + IPL_MAG_CURSE, + 5, + 5, + IPL_INDESTRUCTIBLE, + 0, + 0, + IPL_INVCURS, + 117, + 0 + }, + { + "Blackoak Shield", + UITYPE_SMALLSHIELD, + 4u, + 6u, + 5725, + IPL_DEX, + 10, + 10, + IPL_VIT_CURSE, + 10, + 10, + IPL_SETAC, + 18, + 18, + IPL_LIGHT_CURSE, + 1, + 1, + IPL_DUR, + 150, + 150, + IPL_INVCURS, + 146, + 0 + }, + { + "Holy Defender", + UITYPE_LARGESHIELD, + 10u, + 6u, + 13800, + IPL_SETAC, + 15, + 15, + IPL_GETHIT_CURSE, + 2, + 2, + IPL_FIRERES, + 20, + 20, + IPL_DUR, + 200, + 200, + IPL_FASTBLOCK, + 1, + 1, + IPL_INVCURS, + 146, + 0 + }, + { + "Stormshield", + UITYPE_GOTHSHIELD, + 24u, + 6u, + 49000, + IPL_SETAC, + 40, + 40, + IPL_GETHIT, + 4, + 4, + IPL_STR, + 10, + 10, + IPL_INDESTRUCTIBLE, + 0, + 0, + IPL_FASTBLOCK, + 1, + 1, + IPL_INVCURS, + 148, + 0 + }, + { + "Bramble", + UITYPE_RING, + 1u, + 4u, + 1000, + IPL_ATTRIBS_CURSE, + 2, + 2, + IPL_DAMMOD, + 3, + 3, + IPL_MANA, + 10, + 10, + IPL_INVCURS, + 9, + 0, + IPL_TOHIT, + 0, + 0, + IPL_TOHIT, + 0, + 0 + }, + { + "Ring of Regha", + UITYPE_RING, + 1u, + 6u, + 4175, + IPL_MAG, + 10, + 10, + IPL_MAGICRES, + 10, + 10, + IPL_LIGHT, + 1, + 1, + IPL_STR_CURSE, + 3, + 3, + IPL_DEX_CURSE, + 3, + 3, + IPL_INVCURS, + 11, + 0 + }, + { + "The Bleeder", + UITYPE_RING, + 2u, + 4u, + 8500, + IPL_MAGICRES, + 20, + 20, + IPL_MANA, + 30, + 30, + IPL_LIFE_CURSE, + 10, + 10, + IPL_INVCURS, + 8, + 0, + IPL_TOHIT, + 0, + 0, + IPL_TOHIT, + 0, + 0 + }, + { + "Constricting Ring", + UITYPE_RING, + 5u, + 3u, + 62000, + IPL_ALLRES, + 75, + 75, + IPL_DRAINLIFE, + 0, + 0, + IPL_INVCURS, + 14, + 0, + IPL_TOHIT, + 0, + 0, + IPL_TOHIT, + 0, + 0, + IPL_TOHIT, + 0, + 0 + }, + { + "Ring of Engagement", + UITYPE_RING, + 11u, + 5u, + 12476, + IPL_GETHIT_CURSE, + 1, + 2, + IPL_THORNS, + 1, + 3, + IPL_SETAC, + 5, + 5, + IPL_TARGAC, + 4, + 12, + IPL_INVCURS, + 13, + 0, + IPL_TOHIT, + 0, + 0 + }, + { + &empty_string, + UITYPE_INVALID, + 0u, + 0u, + 0, + IPL_TOHIT, + 0, + 0, + IPL_TOHIT, + 0, + 0, + IPL_TOHIT, + 0, + 0, + IPL_TOHIT, + 0, + 0, + IPL_TOHIT, + 0, + 0, + IPL_TOHIT, + 0, + 0 + } +}; +int log_inf = 2139095040; // weak +int mainmenu_inf = 2139095040; // weak +unsigned char mfontframe[127] = +{ + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 37u, + 49u, + 38u, + 0u, + 39u, + 40u, + 47u, + 42u, + 43u, + 41u, + 45u, + 52u, + 44u, + 53u, + 55u, + 36u, + 27u, + 28u, + 29u, + 30u, + 31u, + 32u, + 33u, + 34u, + 35u, + 51u, + 50u, + 48u, + 46u, + 49u, + 54u, + 0u, + 1u, + 2u, + 3u, + 4u, + 5u, + 6u, + 7u, + 8u, + 9u, + 10u, + 11u, + 12u, + 13u, + 14u, + 15u, + 16u, + 17u, + 18u, + 19u, + 20u, + 21u, + 22u, + 23u, + 24u, + 25u, + 26u, + 42u, + 0u, + 43u, + 0u, + 0u, + 0u, + 1u, + 2u, + 3u, + 4u, + 5u, + 6u, + 7u, + 8u, + 9u, + 10u, + 11u, + 12u, + 13u, + 14u, + 15u, + 16u, + 17u, + 18u, + 19u, + 20u, + 21u, + 22u, + 23u, + 24u, + 25u, + 26u, + 48u, + 0u, + 49u, + 0u +}; +unsigned char mfontkern[56] = +{ + 5u, + 15u, + 10u, + 13u, + 14u, + 10u, + 9u, + 13u, + 11u, + 5u, + 5u, + 11u, + 10u, + 16u, + 13u, + 16u, + 10u, + 15u, + 12u, + 10u, + 14u, + 17u, + 17u, + 22u, + 17u, + 16u, + 11u, + 5u, + 11u, + 11u, + 11u, + 10u, + 11u, + 11u, + 11u, + 11u, + 15u, + 5u, + 10u, + 18u, + 15u, + 8u, + 6u, + 6u, + 7u, + 10u, + 9u, + 6u, + 10u, + 10u, + 5u, + 5u, + 5u, + 5u, + 11u, + 12u +}; +int monster_inf = 2139095040; // weak +unsigned char plr2monst[9] = { 0u, 5u, 3u, 7u, 1u, 4u, 6u, 0u, 2u }; +missile_id counsmiss[4] = { MIS_FIREBOLT, MIS_CBOLT, MIS_LIGHTCTRL, MIS_FIREBALL }; +int movie_inf = 2139095040; // weak +int mpqapi_inf = 2139095040; // weak +int msg_inf = 2139095040; // weak +int msgcmd_inf = 2139095040; // weak +int multi_inf = 2139095040; // weak +event_type event_types[3] = +{ + EVENT_TYPE_PLAYER_LEAVE_GAME, + EVENT_TYPE_PLAYER_CREATE_GAME, + EVENT_TYPE_PLAYER_MESSAGE +}; +int nthread_inf = 2139095040; // weak +int hero_inf = 2139095040; // weak +int palette_inf = 2139095040; // weak +unsigned char pathxdir[8] = { 255u, 255u, 1u, 1u, 255u, 0u, 1u, 0u }; +unsigned char pathydir[8] = { 255u, 1u, 255u, 1u, 0u, 255u, 0u, 1u }; +int pfile_inf = 2139095040; // weak +int player_inf = 2139095040; // weak +unsigned char ArmourChar[4] = { 76u, 77u, 72u, 0u }; +unsigned char WepChar[10] = { 78u, 85u, 83u, 68u, 66u, 65u, 77u, 72u, 84u, 0u }; +unsigned char CharChar[4] = { 87u, 82u, 83u, 0u }; +text_color text_color_from_player_num[2] = { COL_WHITE, COL_GOLD }; +int scrollrt_inf = 2139095040; // weak +int sound_inf = 2139095040; // weak +TextDataStruct alltext[259] = +{ + { + " 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... |", + 1, + 5, + TSFX_TAVERN21 + }, + { + "As I told you, good master, the King was entombed three levels below. He's down there, waiting in the putrid darkness for his chance to destroy this land... |", + 1, + 6, + TSFX_TAVERN22 + }, + { + "The curse of our King has passed, but I fear that it was only part of a greater evil at work. However, we may yet be saved from the darkness that consumes our land, for your victory is a good omen. May Light guide you on your way, good master. |", + 1, + 5, + TSFX_TAVERN23 + }, + { + "The loss of his son was too much for King Leoric. I did what I could to ease his madness, but in the end it overcame him. A black curse has hung over this kingdom from that day forward, but perhaps if you were to free his spirit from his earthly prison, the curse would be lifted... |", + 1, + 5, + TSFX_HEALER1 + }, + { + "I don't like to think about how the King died. I like to remember him for the kind and just ruler that he was. His death was so sad and seemed very wrong, somehow. |", + 1, + 6, + TSFX_BMAID1 + }, + { + "I made many of the weapons and most of the armor that King Leoric used to outfit his knights. I even crafted a huge two-handed sword of the finest mithril for him, as well as a field crown to match. I still cannot believe how he died, but it must have been some sinister force that drove him insane! |", + 1, + 5, + TSFX_SMITH1 + }, + { + "I don't care about that. Listen, no skeleton is gonna be MY king. Leoric is King. King, so you hear me? HAIL TO THE KING! |", + 1, + 5, + TSFX_DRUNK1 + }, + { + "The dead who walk among the living follow the cursed King. He holds the power to raise yet more warriors for an ever growing army of the undead. If you do not stop his reign, he will surely march across this land and slay all who still live here. |", + 1, + 5, + TSFX_WITCH1 + }, + { + "Look, I'm running a business here. I don't sell information, and I don't care about some King that's been dead longer than I've been alive. If you need something to use against this King of the undead, then I can help you out... |", + 1, + 5, + TSFX_PEGBOY1 + }, + { + "The warmth of life has entered my tomb. Prepare yourself, mortal, to serve my Master for eternity! |", + 0, + 5, + USFX_SKING1 + }, + { + "I see that this strange behavior puzzles you as well. I would surmise that since many demons fear the light of the sun and believe that it holds great power, it may be that the rising sun depicted on the sign you speak of has led them to believe that it too holds some arcane powers. Hmm, perhaps they are not all as smart as we had feared... |", + 1, + 5, + TSFX_STORY2 + }, + { + "Master, I have a strange experience to relate. I know that you have a great knowledge of those monstrosities that inhabit the labyrinth, and this is something that I cannot understand for the very life of me... I was awakened during the night by a scraping sound just outside of my tavern. When I looked out from my bedroom, I saw the shapes of small demon-like creatures in the inn yard. After a short time, they ran off, but not before stealing the sign to my inn. I don't know why the demons would steal my sign but leave my family in peace... 'tis strange, no? |", + 1, + 5, + TSFX_TAVERN24 + }, + { + "Oh, you didn't have to bring back my sign, but I suppose that it does save me the expense of having another one made. Well, let me see, what could I give you as a fee for finding it? Hmmm, what have we here... ah, yes! This cap was left in one of the rooms by a magician who stayed here some time ago. Perhaps it may be of some value to you. |", + 1, + 5, + TSFX_TAVERN25 + }, + { + "My goodness, demons running about the village at night, pillaging our homes - is nothing sacred? I hope that Ogden and Garda are all right. I suppose that they would come to see me if they were hurt... |", + 1, + 5, + TSFX_HEALER2 + }, + { + "Oh my! Is that where the sign went? My Grandmother and I must have slept right through the whole thing. Thank the Light that those monsters didn't attack the inn. |", + 1, + 6, + TSFX_BMAID2 + }, + { + "Demons stole Ogden's sign, you say? That doesn't sound much like the atrocities I've heard of - or seen. \n \nDemons are concerned with ripping out your heart, not your signpost. |", + 1, + 6, + TSFX_SMITH2 + }, + { + "You know what I think? Somebody took that sign, and they gonna want lots of money for it. If I was Ogden... and I'm not, but if I was... I'd just buy a new sign with some pretty drawing on it. Maybe a nice mug of ale or a piece of cheese... |", + 1, + 5, + TSFX_DRUNK2 + }, + { + "No mortal can truly understand the mind of the demon. \n \nNever let their erratic actions confuse you, as that too may be their plan. |", + 1, + 6, + TSFX_WITCH2 + }, + { + "What - is he saying I took that? I suppose that Griswold is on his side, too. \n \nLook, I got over simple sign stealing months ago. You can't turn a profit on a piece of wood. |", + 1, + 6, + TSFX_PEGBOY2 + }, + { + "Hey - You that one that kill all! You get me Magic Banner or we attack! You no leave with life! You kill big uglies and give back Magic. Go past corner and door, find uglies. You give, you go! |", + 1, + 5, + USFX_SNOT1 + }, + { + "You kill uglies, get banner. You bring to me, or else... |", + 1, + 6, + USFX_SNOT2 + }, + { + "You give! Yes, good! Go now, we strong. We kill all with big Magic! |", + 1, + 6, + USFX_SNOT3 + }, + { + "This does not bode well, for it confirms my darkest fears. While I did not allow myself to believe the ancient legends, I cannot deny them now. Perhaps the time has come to reveal who I am.\n \nMy true name is Deckard Cain the Elder, and I am the last descendant of an ancient Brotherhood that was dedicated to safeguarding the secrets of a timeless evil. An evil that quite obviously has now been released.\n \nThe Archbishop Lazarus, once King Leoric's most trusted advisor, led a party of simple townsfolk into the Labyrinth to find the King's missing son, Albrecht. Quite some time passed before they returned, and only a few of them escaped with their lives.\n \nCurse me for a fool! I should have suspected his veiled treachery then. It must have been Lazarus himself who kidnapped Albrecht and has since hidden him within the Labyrinth. I do not understand why the Archbishop turned to the darkness, or what his interest is in the child. unless he means to sacrifice him to his dark masters!\n \nThat must be what he has planned! The survivors of his 'rescue party' say that Lazarus was last seen running into the deepest bowels of the labyrinth. You must hurry and save the prince from the sacrificial blade of this demented fiend! |", + 1, + 3, + TSFX_STORY36 + }, + { + "You must hurry and rescue Albrecht from the hands of Lazarus. The prince and the people of this kingdom are counting on you! |", + 1, + 5, + TSFX_STORY37 + }, + { + "Your story is quite grim, my friend. Lazarus will surely burn in Hell for his horrific deed. The boy that you describe is not our prince, but I believe that Albrecht may yet be in danger. The symbol of power that you speak of must be a portal in the very heart of the labyrinth.\n \nKnow this, my friend - The evil that you move against is the dark Lord of Terror. He is known to mortal men as Diablo. It was he who was imprisoned within the Labyrinth many centuries ago and I fear that he seeks to once again sow chaos in the realm of mankind. You must venture through the portal and destroy Diablo before it is too late! |", + 1, + 5, + TSFX_STORY38 + }, + { + "Lazarus was the Archbishop who led many of the townspeople into the labyrinth. I lost many good friends that day, and Lazarus never returned. I suppose he was killed along with most of the others. If you would do me a favor, good master - please do not talk to Farnham about that day. |", + 1, + 6, + TSFX_TAVERN1 + }, + { "|", 1, 5, TSFX_STORY38 }, + { "|", 1, 5, TSFX_STORY38 }, + { + "I was shocked when I heard of what the townspeople were planning to do that night. I thought that of all people, Lazarus would have had more sense than that. He was an Archbishop, and always seemed to care so much for the townsfolk of Tristram. So many were injured, I could not save them all... |", + 1, + 5, + TSFX_HEALER3 + }, + { + "I remember Lazarus as being a very kind and giving man. He spoke at my mother's funeral, and was supportive of my grandmother and myself in a very troubled time. I pray every night that somehow, he is still alive and safe. |", + 1, + 5, + TSFX_BMAID3 + }, + { + "I was there when Lazarus led us into the labyrinth. He spoke of holy retribution, but when we started fighting those hellspawn, he did not so much as lift his mace against them. He just ran deeper into the dim, endless chambers that were filled with the servants of darkness! |", + 1, + 5, + TSFX_SMITH3 + }, + { + "They stab, then bite, then they're all around you. Liar! LIAR! They're all dead! Dead! Do you hear me? They just keep falling and falling... their blood spilling out all over the floor... all his fault... |", + 1, + 5, + TSFX_DRUNK3 + }, + { + "I did not know this Lazarus of whom you speak, but I do sense a great conflict within his being. He poses a great danger, and will stop at nothing to serve the powers of darkness which have claimed him as theirs. |", + 1, + 5, + TSFX_WITCH3 + }, + { + "Yes, the righteous Lazarus, who was sooo effective against those monsters down there. Didn't help save my leg, did it? Look, I'll give you a free piece of advice. Ask Farnham, he was there. |", + 1, + 5, + TSFX_PEGBOY3 + }, + { + "Abandon your foolish quest. All that awaits you is the wrath of my Master! You are too late to save the child. Now you will join him in Hell! |", + 0, + 5, + USFX_LAZ1 + }, + { " |", 0, 5, USFX_LAZ1 }, + { + "Hmm, I don't know what I can really tell you about this that will be of any help. The water that fills our wells comes from an underground spring. I have heard of a tunnel that leads to a great lake - perhaps they are one and the same. Unfortunately, I do not know what would cause our water supply to be tainted. |", + 1, + 5, + TSFX_STORY4 + }, + { + "I have always tried to keep a large supply of foodstuffs and drink in our storage cellar, but with the entire town having no source of fresh water, even our stores will soon run dry. \n \nPlease, do what you can or I don't know what we will do. |", + 1, + 6, + TSFX_TAVERN2 + }, + { + "I'm glad I caught up to you in time! Our wells have become brackish and stagnant and some of the townspeople have become ill drinking from them. Our reserves of fresh water are quickly running dry. I believe that there is a passage that leads to the springs that serve our town. Please find what has caused this calamity, or we all will surely perish. |", + 1, + 5, + TSFX_HEALER20 + }, + { + "Please, you must hurry. Every hour that passes brings us closer to having no water to drink. \n \nWe cannot survive for long without your help. |", + 1, + 6, + TSFX_HEALER21 + }, + { + "What's that you say - the mere presence of the demons had caused the water to become tainted? Oh, truly a great evil lurks beneath our town, but your perseverance and courage gives us hope. Please take this ring - perhaps it will aid you in the destruction of such vile creatures. |", + 1, + 5, + TSFX_HEALER22 + }, + { + "My grandmother is very weak, and Garda says that we cannot drink the water from the wells. Please, can you do something to help us? |", + 1, + 6, + TSFX_BMAID4 + }, + { + "Pepin has told you the truth. We will need fresh water badly, and soon. I have tried to clear one of the smaller wells, but it reeks of stagnant filth. It must be getting clogged at the source. |", + 1, + 5, + TSFX_SMITH4 + }, + { "You drink water? |", 1, 8, TSFX_DRUNK4 }, + { + "The people of Tristram will die if you cannot restore fresh water to their wells. \n \nKnow this - demons are at the heart of this matter, but they remain ignorant of what they have spawned. |", + 1, + 6, + TSFX_WITCH4 + }, + { + "For once, I'm with you. My business runs dry - so to speak - if I have no market to sell to. You better find out what is going on, and soon! |", + 1, + 6, + TSFX_PEGBOY4 + }, + { + "A book that speaks of a chamber of human bones? Well, a Chamber of Bone is mentioned in certain archaic writings that I studied in the libraries of the East. These tomes inferred that when the Lords of the underworld desired to protect great treasures, they would create domains where those who died in the attempt to steal that treasure would be forever bound to defend it. A twisted, but strangely fitting, end? |", + 1, + 4, + TSFX_STORY7 + }, + { + "I am afraid that I don't know anything about that, good master. Cain has many books that may be of some help. |", + 1, + 6, + TSFX_TAVERN5 + }, + { + "This sounds like a very dangerous place. If you venture there, please take great care. |", + 1, + 6, + TSFX_HEALER5 + }, + { + "I am afraid that I haven't heard anything about that. Perhaps Cain the Storyteller could be of some help. |", + 1, + 6, + TSFX_BMAID6 + }, + { + "I know nothing of this place, but you may try asking Cain. He talks about many things, and it would not surprise me if he had some answers to your question. |", + 1, + 6, + TSFX_SMITH7 + }, + { + "Okay, so listen. There's this chamber of wood, see. And his wife, you know - her - tells the tree... cause you gotta wait. Then I says, that might work against him, but if you think I'm gonna PAY for this... you... uh... yeah. |", + 1, + 5, + TSFX_DRUNK7 + }, + { + "You will become an eternal servant of the dark lords should you perish within this cursed domain. \n \nEnter the Chamber of Bone at your own peril. |", + 1, + 6, + TSFX_WITCH7 + }, + { + "A vast and mysterious treasure, you say? Maybe I could be interested in picking up a few things from you... or better yet, don't you need some rare and expensive supplies to get you through this ordeal? |", + 1, + 5, + TSFX_PEGBOY7 + }, + { + "It seems that the Archbishop Lazarus goaded many of the townsmen into venturing into the Labyrinth to find the King's missing son. He played upon their fears and whipped them into a frenzied mob. None of them were prepared for what lay within the cold earth... Lazarus abandoned them down there - left in the clutches of unspeakable horrors - to die. |", + 1, + 5, + TSFX_STORY10 + }, + { + "Yes, Farnham has mumbled something about a hulking brute who wielded a fierce weapon. I believe he called him a butcher. |", + 1, + 6, + TSFX_TAVERN8 + }, + { + "By the Light, I know of this vile demon. There were many that bore the scars of his wrath upon their bodies when the few survivors of the charge led by Lazarus crawled from the Cathedral. I don't know what he used to slice open his victims, but it could not have been of this world. It left wounds festering with disease and even I found them almost impossible to treat. Beware if you plan to battle this fiend... |", + 1, + 5, + TSFX_HEALER8 + }, + { + "When Farnham said something about a butcher killing people, I immediately discounted it. But since you brought it up, maybe it is true. |", + 1, + 6, + TSFX_BMAID8 + }, + { + "I saw what Farnham calls the Butcher as it swathed a path through the bodies of my friends. He swung a cleaver as large as an axe, hewing limbs and cutting down brave men where they stood. I was separated from the fray by a host of small screeching demons and somehow found the stairway leading out. I never saw that hideous beast again, but his blood-stained visage haunts me to this day. |", + 1, + 5, + TSFX_SMITH10 + }, + { + "Big! Big cleaver killing all my friends. Couldn't stop him, had to run away, couldn't save them. Trapped in a room with so many bodies... so many friends... NOOOOOOOOOO! |", + 1, + 5, + TSFX_DRUNK10 + }, + { + "The Butcher is a sadistic creature that delights in the torture and pain of others. You have seen his handiwork in the drunkard Farnham. His destruction will do much to ensure the safety of this village. |", + 1, + 5, + TSFX_WITCH10 + }, + { + "I know more than you'd think about that grisly fiend. His little friends got a hold of me and managed to get my leg before Griswold pulled me out of that hole. \n \nI'll put it bluntly - kill him before he kills you and adds your corpse to his collection. |", + 1, + 6, + TSFX_PEGBOY10 + }, + { + "Please, listen to me. The Archbishop Lazarus, he led us down here to find the lost prince. The bastard led us into a trap! Now everyone is dead...killed by a demon he called the Butcher. Avenge us! Find this Butcher and slay him so that our souls may finally rest... |", + 1, + 5, + TSFX_WOUND + }, + { " |", 1, 5, USFX_CLEAVER }, + { + "You recite an interesting rhyme written in a style that reminds me of other works. Let me think now - what was it?\n \n...Darkness shrouds the Hidden. Eyes glowing unseen with only the sounds of razor claws briefly scraping to torment those poor souls who have been made sightless for all eternity. The prison for those so damned is named the Halls of the Blind... |", + 1, + 5, + TSFX_STORY12 + }, + { + "I never much cared for poetry. Occasionally, I had cause to hire minstrels when the inn was doing well, but that seems like such a long time ago now. \n \nWhat? Oh, yes... uh, well, I suppose you could see what someone else knows. |", + 1, + 6, + TSFX_TAVERN10 + }, + { + "This does seem familiar, somehow. I seem to recall reading something very much like that poem while researching the history of demonic afflictions. It spoke of a place of great evil that... wait - you're not going there are you? |", + 1, + 5, + TSFX_HEALER10 + }, + { + "If you have questions about blindness, you should talk to Pepin. I know that he gave my grandmother a potion that helped clear her vision, so maybe he can help you, too. |", + 1, + 6, + TSFX_BMAID10 + }, + { + "I am afraid that I have neither heard nor seen a place that matches your vivid description, my friend. Perhaps Cain the Storyteller could be of some help. |", + 1, + 6, + TSFX_SMITH12 + }, + { + "Look here... that's pretty funny, huh? Get it? Blind - look here? |", + 1, + 6, + TSFX_DRUNK12 + }, + { + "This is a place of great anguish and terror, and so serves its master well. \n \nTread carefully or you may yourself be staying much longer than you had anticipated. |", + 1, + 6, + TSFX_WITCH12 + }, + { + "Lets see, am I selling you something? No. Are you giving me money to tell you about this? No. Are you now leaving and going to talk to the storyteller who lives for this kind of thing? Yes. |", + 1, + 5, + TSFX_PEGBOY11 + }, + { + "You claim to have spoken with Lachdanan? He was a great hero during his life. Lachdanan was an honorable and just man who served his King faithfully for years. But of course, you already know that.\n \nOf those who were caught within the grasp of the King's Curse, Lachdanan would be the least likely to submit to the darkness without a fight, so I suppose that your story could be true. If I were in your place, my friend, I would find a way to release him from his torture. |", + 1, + 5, + TSFX_STORY13 + }, + { + "You speak of a brave warrior long dead! I'll have no such talk of speaking with departed souls in my inn yard, thank you very much. |", + 1, + 6, + TSFX_TAVERN11 + }, + { + "A golden elixir, you say. I have never concocted a potion of that color before, so I can't tell you how it would effect you if you were to try to drink it. As your healer, I strongly advise that should you find such an elixir, do as Lachdanan asks and DO NOT try to use it. |", + 1, + 5, + TSFX_HEALER11 + }, + { + "I've never heard of a Lachdanan before. I'm sorry, but I don't think that I can be of much help to you. |", + 1, + 7, + TSFX_BMAID11 + }, + { + "If it is actually Lachdanan that you have met, then I would advise that you aid him. I dealt with him on several occasions and found him to be honest and loyal in nature. The curse that fell upon the followers of King Leoric would fall especially hard upon him. |", + 1, + 5, + TSFX_SMITH13 + }, + { + " Lachdanan is dead. Everybody knows that, and you can't fool me into thinking any other way. You can't talk to the dead. I know! |", + 1, + 5, + TSFX_DRUNK13 + }, + { + "You may meet people who are trapped within the Labyrinth, such as Lachdanan. \n \nI sense in him honor and great guilt. Aid him, and you aid all of Tristram. |", + 1, + 6, + TSFX_WITCH13 + }, + { + "Wait, let me guess. Cain was swallowed up in a gigantic fissure that opened beneath him. He was incinerated in a ball of hellfire, and can't answer your questions anymore. Oh, that isn't what happened? Then I guess you'll be buying something or you'll be on your way. |", + 1, + 5, + TSFX_PEGBOY12 + }, + { + "Please, don't kill me, just hear me out. I was once Captain of King Leoric's Knights, upholding the laws of this land with justice and honor. Then his dark Curse fell upon us for the role we played in his tragic death. As my fellow Knights succumbed to their twisted fate, I fled from the King's burial chamber, searching for some way to free myself from the Curse. I failed...\n \nI have heard of a Golden Elixir that could lift the Curse and allow my soul to rest, but I have been unable to find it. My strength now wanes, and with it the last of my humanity as well. Please aid me and find the Elixir. I will repay your efforts - I swear upon my honor. |", + 1, + 3, + USFX_LACH1 + }, + { + "You have not found the Golden Elixir. I fear that I am doomed for eternity. Please, keep trying... |", + 1, + 6, + USFX_LACH2 + }, + { + "You have saved my soul from damnation, and for that I am in your debt. If there is ever a way that I can repay you from beyond the grave I will find it, but for now - take my helm. On the journey I am about to take I will have little use for it. May it protect you against the dark powers below. Go with the Light, my friend... |", + 1, + 4, + USFX_LACH3 + }, + { + "Griswold speaks of The Anvil of Fury - a legendary artifact long searched for, but never found. Crafted from the metallic bones of the Razor Pit demons, the Anvil of Fury was smelt around the skulls of the five most powerful magi of the underworld. Carved with runes of power and chaos, any weapon or armor forged upon this Anvil will be immersed into the realm of Chaos, imbedding it with magical properties. It is said that the unpredictable nature of Chaos makes it difficult to know what the outcome of this smithing will be... |", + 1, + 4, + TSFX_STORY14 + }, + { + "Don't you think that Griswold would be a better person to ask about this? He's quite handy, you know. |", + 1, + 7, + TSFX_TAVERN12 + }, + { + "If you had been looking for information on the Pestle of Curing or the Silver Chalice of Purification, I could have assisted you, my friend. However, in this matter, you would be better served to speak to either Griswold or Cain. |", + 1, + 6, + TSFX_HEALER12 + }, + { + "Griswold's father used to tell some of us when we were growing up about a giant anvil that was used to make mighty weapons. He said that when a hammer was struck upon this anvil, the ground would shake with a great fury. Whenever the earth moves, I always remember that story. |", + 1, + 5, + TSFX_BMAID12 + }, + { + "Greetings! It's always a pleasure to see one of my best customers! I know that you have been venturing deeper into the Labyrinth, and there is a story I was told that you may find worth the time to listen to...\n \nOne of the men who returned from the Labyrinth told me about a mystic anvil that he came across during his escape. His description reminded me of legends I had heard in my youth about the burning Hellforge where powerful weapons of magic are crafted. The legend had it that deep within the Hellforge rested the Anvil of Fury! This Anvil contained within it the very essence of the demonic underworld...\n \nIt is said that any weapon crafted upon the burning Anvil is imbued with great power. If this anvil is indeed the Anvil of Fury, I may be able to make you a weapon capable of defeating even the darkest lord of Hell! \n \nFind the Anvil for me, and I'll get to work! |", + 1, + 5, + TSFX_SMITH21 + }, + { + "Nothing yet, eh? Well, keep searching. A weapon forged upon the Anvil could be your best hope, and I am sure that I can make you one of legendary proportions. |", + 1, + 5, + TSFX_SMITH22 + }, + { + "I can hardly believe it! This is the Anvil of Fury - good work, my friend. Now we'll show those bastards that there are no weapons in Hell more deadly than those made by men! Take this and may Light protect you. |", + 1, + 5, + TSFX_SMITH23 + }, + { + "Griswold can't sell his anvil. What will he do then? And I'd be angry too if someone took my anvil! |", + 1, + 6, + TSFX_DRUNK14 + }, + { + "There are many artifacts within the Labyrinth that hold powers beyond the comprehension of mortals. Some of these hold fantastic power that can be used by either the Light or the Darkness. Securing the Anvil from below could shift the course of the Sin War towards the Light. |", + 1, + 5, + TSFX_WITCH14 + }, + { + "If you were to find this artifact for Griswold, it could put a serious damper on my business here. Awwww, you'll never find it. |", + 1, + 6, + TSFX_PEGBOY13 + }, + { + "The Gateway of Blood and the Halls of Fire are landmarks of mystic origin. Wherever this book you read from resides it is surely a place of great power.\n \nLegends speak of a pedestal that is carved from obsidian stone and has a pool of boiling blood atop its bone encrusted surface. There are also allusions to Stones of Blood that will open a door that guards an ancient treasure...\n \nThe nature of this treasure is shrouded in speculation, my friend, but it is said that the ancient hero Arkaine placed the holy armor Valor in a secret vault. Arkaine was the first mortal to turn the tide of the Sin War and chase the legions of darkness back to the Burning Hells.\n \nJust before Arkaine died, his armor was hidden away in a secret vault. It is said that when this holy armor is again needed, a hero will arise to don Valor once more. Perhaps you are that hero... |", + 1, + 3, + TSFX_STORY15 + }, + { + "Every child hears the story of the warrior Arkaine and his mystic armor known as Valor. If you could find its resting place, you would be well protected against the evil in the Labyrinth. |", + 1, + 6, + TSFX_TAVERN13 + }, + { + "Hmm... it sounds like something I should remember, but I've been so busy learning new cures and creating better elixirs that I must have forgotten. Sorry... |", + 1, + 6, + TSFX_HEALER13 + }, + { + "The story of the magic armor called Valor is something I often heard the boys talk about. You had better ask one of the men in the village. |", + 1, + 6, + TSFX_BMAID13 + }, + { + "The armor known as Valor could be what tips the scales in your favor. I will tell you that many have looked for it - including myself. Arkaine hid it well, my friend, and it will take more than a bit of luck to unlock the secrets that have kept it concealed oh, lo these many years. |", + 1, + 5, + TSFX_SMITH14 + }, + { "Zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz... |", 1, 7, TSFX_DRUNK15 }, + { + "Should you find these Stones of Blood, use them carefully. \n \nThe way is fraught with danger and your only hope rests within your self trust. |", + 1, + 6, + TSFX_WITCH15 + }, + { + "You intend to find the armor known as Valor? \n \nNo one has ever figured out where Arkaine stashed the stuff, and if my contacts couldn't find it, I seriously doubt you ever will either. |", + 1, + 6, + TSFX_PEGBOY14 + }, + { + "I know of only one legend that speaks of such a warrior as you describe. His story is found within the ancient chronicles of the Sin War...\n \nStained by a thousand years of war, blood and death, the Warlord of Blood stands upon a mountain of his tattered victims. His dark blade screams a black curse to the living; a tortured invitation to any who would stand before this Executioner of Hell.\n \nIt is also written that although he was once a mortal who fought beside the Legion of Darkness during the Sin War, he lost his humanity to his insatiable hunger for blood. |", + 1, + 5, + TSFX_STORY18 + }, + { + "I am afraid that I haven't heard anything about such a vicious warrior, good master. I hope that you do not have to fight him, for he sounds extremely dangerous. |", + 1, + 6, + TSFX_TAVERN16 + }, + { + "Cain would be able to tell you much more about something like this than I would ever wish to know. |", + 1, + 7, + TSFX_HEALER16 + }, + { + "If you are to battle such a fierce opponent, may Light be your guide and your defender. I will keep you in my thoughts. |", + 1, + 6, + TSFX_BMAID16 + }, + { + "Dark and wicked legends surrounds the one Warlord of Blood. Be well prepared, my friend, for he shows no mercy or quarter. |", + 1, + 6, + TSFX_SMITH17 + }, + { + "Always you gotta talk about Blood? What about flowers, and sunshine, and that pretty girl that brings the drinks. Listen here, friend - you're obsessive, you know that? |", + 1, + 5, + TSFX_DRUNK17 + }, + { + "His prowess with the blade is awesome, and he has lived for thousands of years knowing only warfare. I am sorry... I can not see if you will defeat him. |", + 1, + 5, + TSFX_WITCH18 + }, + { + "I haven't ever dealt with this Warlord you speak of, but he sounds like he's going through a lot of swords. Wouldn't mind supplying his armies... |", + 1, + 6, + TSFX_PEGBOY17 + }, + { + "My blade sings for your blood, mortal, and by my dark masters it shall not be denied. |", + 0, + 6, + USFX_WARLRD1 + }, + { + "Griswold speaks of the Heaven Stone that was destined for the enclave located in the east. It was being taken there for further study. This stone glowed with an energy that somehow granted vision beyond that which a normal man could possess. I do not know what secrets it holds, my friend, but finding this stone would certainly prove most valuable. |", + 1, + 5, + TSFX_STORY20 + }, + { + "The caravan stopped here to take on some supplies for their journey to the east. I sold them quite an array of fresh fruits and some excellent sweetbreads that Garda has just finished baking. Shame what happened to them... |", + 1, + 6, + TSFX_TAVERN18 + }, + { + "I don't know what it is that they thought they could see with that rock, but I will say this. If rocks are falling from the sky, you had better be careful! |", + 1, + 6, + TSFX_HEALER18 + }, + { + "Well, a caravan of some very important people did stop here, but that was quite a while ago. They had strange accents and were starting on a long journey, as I recall. \n \nI don't see how you could hope to find anything that they would have been carrying. |", + 1, + 6, + TSFX_BMAID18 + }, + { + "Stay for a moment - I have a story you might find interesting. A caravan that was bound for the eastern kingdoms passed through here some time ago. It was supposedly carrying a piece of the heavens that had fallen to earth! The caravan was ambushed by cloaked riders just north of here along the roadway. I searched the wreckage for this sky rock, but it was nowhere to be found. If you should find it, I believe that I can fashion something useful from it. |", + 1, + 5, + TSFX_SMITH24 + }, + { + "I am still waiting for you to bring me that stone from the heavens. I know that I can make something powerful out of it. |", + 1, + 6, + TSFX_SMITH25 + }, + { + "Let me see that - aye... aye, it is as I believed. Give me a moment...\n \nAh, Here you are. I arranged pieces of the stone within a silver ring that my father left me. I hope it serves you well. |", + 1, + 5, + TSFX_SMITH26 + }, + { + "I used to have a nice ring; it was a really expensive one, with blue and green and red and silver. Don't remember what happened to it, though. I really miss that ring... |", + 1, + 5, + TSFX_DRUNK19 + }, + { + "The Heaven Stone is very powerful, and were it any but Griswold who bid you find it, I would prevent it. He will harness its powers and its use will be for the good of us all. |", + 1, + 5, + TSFX_WITCH20 + }, + { + "If anyone can make something out of that rock, Griswold can. He knows what he is doing, and as much as I try to steal his customers, I respect the quality of his work. |", + 1, + 6, + TSFX_PEGBOY18 + }, + { + "The witch Adria seeks a black mushroom? I know as much about Black Mushrooms as I do about Red Herrings. Perhaps Pepin the Healer could tell you more, but this is something that cannot be found in any of my stories or books. |", + 1, + 5, + TSFX_STORY21 + }, + { + "Let me just say this. Both Garda and I would never, EVER serve black mushrooms to our honored guests. If Adria wants some mushrooms in her stew, then that is her business, but I can't help you find any. Black mushrooms... disgusting! |", + 1, + 5, + TSFX_TAVERN19 + }, + { + "The witch told me that you were searching for the brain of a demon to assist me in creating my elixir. It should be of great value to the many who are injured by those foul beasts, if I can just unlock the secrets I suspect that its alchemy holds. If you can remove the brain of a demon when you kill it, I would be grateful if you could bring it to me. |", + 1, + 5, + TSFX_HEALER26 + }, + { + "Excellent, this is just what I had in mind. I was able to finish the elixir without this, but it can't hurt to have this to study. Would you please carry this to the witch? I believe that she is expecting it. |", + 1, + 5, + TSFX_HEALER27 + }, + { + "I think Ogden might have some mushrooms in the storage cellar. Why don't you ask him? |", + 1, + 7, + TSFX_BMAID19 + }, + { + "If Adria doesn't have one of these, you can bet that's a rare thing indeed. I can offer you no more help than that, but it sounds like... a huge, gargantuan, swollen, bloated mushroom! Well, good hunting, I suppose. |", + 1, + 5, + TSFX_SMITH19 + }, + { + "Ogden mixes a MEAN black mushroom, but I get sick if I drink that. Listen, listen... here's the secret - moderation is the key! |", + 1, + 5, + TSFX_DRUNK20 + }, + { + "What do we have here? Interesting, it looks like a book of reagents. Keep your eyes open for a black mushroom. It should be fairly large and easy to identify. If you find it, bring it to me, won't you? |", + 1, + 5, + TSFX_WITCH22 + }, + { + "It's a big, black mushroom that I need. Now run off and get it for me so that I can use it for a special concoction that I am working on. |", + 1, + 6, + TSFX_WITCH23 + }, + { + "Yes, this will be perfect for a brew that I am creating. By the way, the healer is looking for the brain of some demon or another so he can treat those who have been afflicted by their poisonous venom. I believe that he intends to make an elixir from it. If you help him find what he needs, please see if you can get a sample of the elixir for me. |", + 1, + 5, + TSFX_WITCH24 + }, + { + "Why have you brought that here? I have no need for a demon's brain at this time. I do need some of the elixir that the Healer is working on. He needs that grotesque organ that you are holding, and then bring me the elixir. Simple when you think about it, isn't it? |", + 1, + 5, + TSFX_WITCH25 + }, + { + "What? Now you bring me that elixir from the healer? I was able to finish my brew without it. Why don't you just keep it... |", + 1, + 6, + TSFX_WITCH26 + }, + { + "I don't have any mushrooms of any size or color for sale. How about something a bit more useful? |", + 1, + 6, + TSFX_PEGBOY19 + }, + { + "So, the legend of the Map is real. Even I never truly believed any of it! I suppose it is time that I told you the truth about who I am, my friend. You see, I am not all that I seem...\n \nMy true name is Deckard Cain the Elder, and I am the last descendant of an ancient Brotherhood that was dedicated to keeping and safeguarding the secrets of a timeless evil. An evil that quite obviously has now been released...\n \nThe evil that you move against is the dark Lord of Terror - known to mortal men as Diablo. It was he who was imprisoned within the Labyrinth many centuries ago. The Map that you hold now was created ages ago to mark the time when Diablo would rise again from his imprisonment. When the two stars on that map align, Diablo will be at the height of his power. He will be all but invincible...\n \nYou are now in a race against time, my friend! Find Diablo and destroy him before the stars align, for we may never have a chance to rid the world of his evil again! |", + 1, + 2, + TSFX_STORY22 + }, + { + "Our time is running short! I sense his dark power building and only you can stop him from attaining his full might. |", + 1, + 6, + TSFX_STORY23 + }, + { + "I am sure that you tried your best, but I fear that even your strength and will may not be enough. Diablo is now at the height of his earthly power, and you will need all your courage and strength to defeat him. May the Light protect and guide you, my friend. I will help in any way that I am able. |", + 1, + 5, + TSFX_STORY24 + }, + { + "If the witch can't help you and suggests you see Cain, what makes you think that I would know anything? It sounds like this is a very serious matter. You should hurry along and see the storyteller as Adria suggests. |", + 1, + 6, + TSFX_TAVERN20 + }, + { + "I can't make much of the writing on this map, but perhaps Adria or Cain could help you decipher what this refers to. \n \nI can see that it is a map of the stars in our sky, but any more than that is beyond my talents. |", + 1, + 6, + TSFX_HEALER19 + }, + { + "The best person to ask about that sort of thing would be our storyteller. \n \nCain is very knowledgeable about ancient writings, and that is easily the oldest looking piece of paper that I have ever seen. |", + 1, + 6, + TSFX_BMAID20 + }, + { + "I have never seen a map of this sort before. Where'd you get it? Although I have no idea how to read this, Cain or Adria may be able to provide the answers that you seek. |", + 1, + 6, + TSFX_SMITH20 + }, + { + "Listen here, come close. I don't know if you know what I know, but you have really got somethin' here. That's a map. |", + 1, + 5, + TSFX_DRUNK21 + }, + { + "Oh, I'm afraid this does not bode well at all. This map of the stars portends great disaster, but its secrets are not mine to tell. The time has come for you to have a very serious conversation with the Storyteller... |", + 1, + 5, + TSFX_WITCH21 + }, + { + "I've been looking for a map, but that certainly isn't it. You should show that to Adria - she can probably tell you what it is. I'll say one thing; it looks old, and old usually means valuable. |", + 1, + 5, + TSFX_PEGBOY20 + }, + { + "Pleeeease, no hurt. No Kill. Keep alive and next time good bring to you. |", + 1, + 6, + USFX_GARBUD1 + }, + { + "Something for you I am making. Again, not kill Gharbad. Live and give good. \n \nYou take this as proof I keep word... |", + 1, + 6, + USFX_GARBUD2 + }, + { + "Nothing yet! Almost done. \n \nVery powerful, very strong. Live! Live! \n \nNo pain and promise I keep! |", + 1, + 6, + USFX_GARBUD3 + }, + { + "This too good for you. Very Powerful! You want - you take! |", + 1, + 6, + USFX_GARBUD4 + }, + { + "What?! Why are you here? All these interruptions are enough to make one insane. Here, take this and leave me to my work. Trouble me no more! |", + 1, + 6, + USFX_ZHAR1 + }, + { "Arrrrgh! Your curiosity will be the death of you!!! |", 1, 7, USFX_ZHAR2 }, + { "Hello, my friend. Stay awhile and listen... |", 0, 5, TSFX_STORY25 }, + { + "While you are venturing deeper into the Labyrinth you may find tomes of great knowledge hidden there. \n \nRead them carefully for they can tell you things that even I cannot. |", + 1, + 6, + TSFX_STORY26 + }, + { + "I know of many myths and legends that may contain answers to questions that may arise in your journeys into the Labyrinth. If you come across challenges and questions to which you seek knowledge, seek me out and I will tell you what I can. |", + 1, + 5, + TSFX_STORY27 + }, + { + "Griswold - a man of great action and great courage. I bet he never told you about the time he went into the Labyrinth to save Wirt, did he? He knows his fair share of the dangers to be found there, but then again - so do you. He is a skilled craftsman, and if he claims to be able to help you in any way, you can count on his honesty and his skill. |", + 1, + 5, + TSFX_STORY28 + }, + { + "Ogden has owned and run the Rising Sun Inn and Tavern for almost four years now. He purchased it just a few short months before everything here went to hell. He and his wife Garda do not have the money to leave as they invested all they had in making a life for themselves here. He is a good man with a deep sense of responsibility. |", + 1, + 5, + TSFX_STORY29 + }, + { + "Poor Farnham. He is a disquieting reminder of the doomed assembly that entered into the Cathedral with Lazarus on that dark day. He escaped with his life, but his courage and much of his sanity were left in some dark pit. He finds comfort only at the bottom of his tankard nowadays, but there are occasional bits of truth buried within his constant ramblings. |", + 1, + 5, + TSFX_STORY30 + }, + { + "The witch, Adria, is an anomaly here in Tristram. She arrived shortly after the Cathedral was desecrated while most everyone else was fleeing. She had a small hut constructed at the edge of town, seemingly overnight, and has access to many strange and arcane artifacts and tomes of knowledge that even I have never seen before. |", + 1, + 5, + TSFX_STORY31 + }, + { + "The story of Wirt is a frightening and tragic one. He was taken from the arms of his mother and dragged into the labyrinth by the small, foul demons that wield wicked spears. There were many other children taken that day, including the son of King Leoric. The Knights of the palace went below, but never returned. The Blacksmith found the boy, but only after the foul beasts had begun to torture him for their sadistic pleasures. |", + 1, + 5, + TSFX_STORY33 + }, + { + "Ah, Pepin. I count him as a true friend - perhaps the closest I have here. He is a bit addled at times, but never a more caring or considerate soul has existed. His knowledge and skills are equaled by few, and his door is always open. |", + 1, + 5, + TSFX_STORY34 + }, + { + "Gillian is a fine woman. Much adored for her high spirits and her quick laugh, she holds a special place in my heart. She stays on at the tavern to support her elderly grandmother who is too sick to travel. I sometimes fear for her safety, but I know that any man in the village would rather die than see her harmed. |", + 1, + 5, + TSFX_STORY35 + }, + { + "Greetings, good master. Welcome to the Tavern of the Rising Sun! |", + 0, + 5, + TSFX_TAVERN36 + }, + { + "Many adventurers have graced the tables of my tavern, and ten times as many stories have been told over as much ale. The only thing that I ever heard any of them agree on was this old axiom. Perhaps it will help you. You can cut the flesh, but you must crush the bone. |", + 1, + 5, + TSFX_TAVERN37 + }, + { + "Griswold the blacksmith is extremely knowledgeable about weapons and armor. If you ever need work done on your gear, he is definitely the man to see. |", + 1, + 6, + TSFX_TAVERN38 + }, + { + "Farnham spends far too much time here, drowning his sorrows in cheap ale. I would make him leave, but he did suffer so during his time in the Labyrinth. |", + 1, + 6, + TSFX_TAVERN39 + }, + { + "Adria is wise beyond her years, but I must admit - she frightens me a little. \n \nWell, no matter. If you ever have need to trade in items of sorcery, she maintains a strangely well-stocked hut just across the river. |", + 1, + 6, + TSFX_TAVERN40 + }, + { + "If you want to know more about the history of our village, the storyteller Cain knows quite a bit about the past. |", + 1, + 6, + TSFX_TAVERN41 + }, + { + "Wirt is a rapscallion and a little scoundrel. He was always getting into trouble, and it's no surprise what happened to him. \n \nHe probably went fooling about someplace that he shouldn't have been. I feel sorry for the boy, but I don't abide the company that he keeps. |", + 1, + 6, + TSFX_TAVERN43 + }, + { + "Pepin is a good man - and certainly the most generous in the village. He is always attending to the needs of others, but trouble of some sort or another does seem to follow him wherever he goes... |", + 1, + 6, + TSFX_TAVERN44 + }, + { + "Gillian, my Barmaid? If it were not for her sense of duty to her grand-dam, she would have fled from here long ago. \n \nGoodness knows I begged her to leave, telling her that I would watch after the old woman, but she is too sweet and caring to have done so. |", + 1, + 6, + TSFX_TAVERN45 + }, + { "What ails you, my friend? |", 0, 5, TSFX_HEALER37 }, + { + "I have made a very interesting discovery. Unlike us, the creatures in the Labyrinth can heal themselves without the aid of potions or magic. If you hurt one of the monsters, make sure it is dead or it very well may regenerate itself. |", + 1, + 5, + TSFX_HEALER38 + }, + { + "Before it was taken over by, well, whatever lurks below, the Cathedral was a place of great learning. There are many books to be found there. If you find any, you should read them all, for some may hold secrets to the workings of the Labyrinth. |", + 1, + 5, + TSFX_HEALER39 + }, + { + "Griswold knows as much about the art of war as I do about the art of healing. He is a shrewd merchant, but his work is second to none. Oh, I suppose that may be because he is the only blacksmith left here. |", + 1, + 5, + TSFX_HEALER40 + }, + { + "Cain is a true friend and a wise sage. He maintains a vast library and has an innate ability to discern the true nature of many things. If you ever have any questions, he is the person to go to. |", + 1, + 5, + TSFX_HEALER41 + }, + { + "Even my skills have been unable to fully heal Farnham. Oh, I have been able to mend his body, but his mind and spirit are beyond anything I can do. |", + 1, + 5, + TSFX_HEALER42 + }, + { + "While I use some limited forms of magic to create the potions and elixirs I store here, Adria is a true sorceress. She never seems to sleep, and she always has access to many mystic tomes and artifacts. I believe her hut may be much more than the hovel it appears to be, but I can never seem to get inside the place. |", + 1, + 5, + TSFX_HEALER43 + }, + { + "Poor Wirt. I did all that was possible for the child, but I know he despises that wooden peg that I was forced to attach to his leg. His wounds were hideous. No one - and especially such a young child - should have to suffer the way he did. |", + 1, + 5, + TSFX_HEALER45 + }, + { + "I really don't understand why Ogden stays here in Tristram. He suffers from a slight nervous condition, but he is an intelligent and industrious man who would do very well wherever he went. I suppose it may be the fear of the many murders that happen in the surrounding countryside, or perhaps the wishes of his wife that keep him and his family where they are. |", + 1, + 5, + TSFX_HEALER46 + }, + { + "Ogden's barmaid is a sweet girl. Her grandmother is quite ill, and suffers from delusions. \n \nShe claims that they are visions, but I have no proof of that one way or the other. |", + 1, + 6, + TSFX_HEALER47 + }, + { "Good day! How may I serve you? |", 0, 5, TSFX_BMAID31 }, + { + "My grandmother had a dream that you would come and talk to me. She has visions, you know and can see into the future. |", + 1, + 6, + TSFX_BMAID32 + }, + { + "The woman at the edge of town is a witch! She seems nice enough, and her name, Adria, is very pleasing to the ear, but I am very afraid of her. \n \nIt would take someone quite brave, like you, to see what she is doing out there. |", + 1, + 6, + TSFX_BMAID33 + }, + { + "Our Blacksmith is a point of pride to the people of Tristram. Not only is he a master craftsman who has won many contests within his guild, but he received praises from our King Leoric himself - may his soul rest in peace. Griswold is also a great hero; just ask Cain. |", + 1, + 5, + TSFX_BMAID34 + }, + { + "Cain has been the storyteller of Tristram for as long as I can remember. He knows so much, and can tell you just about anything about almost everything. |", + 1, + 6, + TSFX_BMAID35 + }, + { + "Farnham is a drunkard who fills his belly with ale and everyone else's ears with nonsense. \n \nI know that both Pepin and Ogden feel sympathy for him, but I get so frustrated watching him slip farther and farther into a befuddled stupor every night. |", + 1, + 6, + TSFX_BMAID36 + }, + { + "Pepin saved my grandmother's life, and I know that I can never repay him for that. His ability to heal any sickness is more powerful than the mightiest sword and more mysterious than any spell you can name. If you ever are in need of healing, Pepin can help you. |", + 1, + 5, + TSFX_BMAID37 + }, + { + "I grew up with Wirt's mother, Canace. Although she was only slightly hurt when those hideous creatures stole him, she never recovered. I think she died of a broken heart. Wirt has become a mean-spirited youngster, looking only to profit from the sweat of others. I know that he suffered and has seen horrors that I cannot even imagine, but some of that darkness hangs over him still. |", + 1, + 5, + TSFX_BMAID39 + }, + { + "Ogden and his wife have taken me and my grandmother into their home and have even let me earn a few gold pieces by working at the inn. I owe so much to them, and hope one day to leave this place and help them start a grand hotel in the east. |", + 1, + 5, + TSFX_BMAID40 + }, + { "Well, what can I do for ya? |", 0, 5, TSFX_SMITH44 }, + { + "If you're looking for a good weapon, let me show this to you. Take your basic blunt weapon, such as a mace. Works like a charm against most of those undying horrors down there, and there's nothing better to shatter skinny little skeletons! |", + 1, + 5, + TSFX_SMITH45 + }, + { + "The axe? Aye, that's a good weapon, balanced against any foe. Look how it cleaves the air, and then imagine a nice fat demon head in its path. Keep in mind, however, that it is slow to swing - but talk about dealing a heavy blow! |", + 1, + 5, + TSFX_SMITH46 + }, + { + "Look at that edge, that balance. A sword in the right hands, and against the right foe, is the master of all weapons. Its keen blade finds little to hack or pierce on the undead, but against a living, breathing enemy, a sword will better slice their flesh! |", + 1, + 5, + TSFX_SMITH47 + }, + { + "Your weapons and armor will show the signs of your struggles against the Darkness. If you bring them to me, with a bit of work and a hot forge, I can restore them to top fighting form. |", + 1, + 6, + TSFX_SMITH48 + }, + { + "While I have to practically smuggle in the metals and tools I need from caravans that skirt the edges of our damned town, that witch, Adria, always seems to get whatever she needs. If I knew even the smallest bit about how to harness magic as she did, I could make some truly incredible things. |", + 1, + 5, + TSFX_SMITH49 + }, + { + "Gillian is a nice lass. Shame that her gammer is in such poor health or I would arrange to get both of them out of here on one of the trading caravans. |", + 1, + 6, + TSFX_SMITH50 + }, + { + "Sometimes I think that Cain talks too much, but I guess that is his calling in life. If I could bend steel as well as he can bend your ear, I could make a suit of court plate good enough for an Emperor! |", + 1, + 5, + TSFX_SMITH51 + }, + { + "I was with Farnham that night that Lazarus led us into Labyrinth. I never saw the Archbishop again, and I may not have survived if Farnham was not at my side. I fear that the attack left his soul as crippled as, well, another did my leg. I cannot fight this battle for him now, but I would if I could. |", + 1, + 5, + TSFX_SMITH52 + }, + { + "A good man who puts the needs of others above his own. You won't find anyone left in Tristram - or anywhere else for that matter - who has a bad thing to say about the healer. |", + 1, + 6, + TSFX_SMITH53 + }, + { + "That lad is going to get himself into serious trouble... or I guess I should say, again. I've tried to interest him in working here and learning an honest trade, but he prefers the high profits of dealing in goods of dubious origin. I cannot hold that against him after what happened to him, but I do wish he would at least be careful. |", + 1, + 5, + TSFX_SMITH55 + }, + { + "The Innkeeper has little business and no real way of turning a profit. He manages to make ends meet by providing food and lodging for those who occasionally drift through the village, but they are as likely to sneak off into the night as they are to pay him. If it weren't for the stores of grains and dried meats he kept in his cellar, why, most of us would have starved during that first year when the entire countryside was overrun by demons. |", + 1, + 5, + TSFX_SMITH56 + }, + { "Can't a fella drink in peace? |", 0, 5, TSFX_DRUNK27 }, + { + "The gal who brings the drinks? Oh, yeah, what a pretty lady. So nice, too. |", + 1, + 6, + TSFX_DRUNK28 + }, + { + "Why don't that old crone do somethin' for a change. Sure, sure, she's got stuff, but you listen to me... she's unnatural. I ain't never seen her eat or drink - and you can't trust somebody who doesn't drink at least a little. |", + 1, + 5, + TSFX_DRUNK29 + }, + { + "Cain isn't what he says he is. Sure, sure, he talks a good story... some of 'em are real scary or funny... but I think he knows more than he knows he knows. |", + 1, + 5, + TSFX_DRUNK30 + }, + { + "Griswold? Good old Griswold. I love him like a brother! We fought together, you know, back when... we... Lazarus... Lazarus... Lazarus!!! |", + 1, + 5, + TSFX_DRUNK31 + }, + { + "Hehehe, I like Pepin. He really tries, you know. Listen here, you should make sure you get to know him. Good fella like that with people always wantin' help. Hey, I guess that would be kinda like you, huh hero? I was a hero too... |", + 1, + 5, + TSFX_DRUNK32 + }, + { + "Wirt is a kid with more problems than even me, and I know all about problems. Listen here - that kid is gotta sweet deal, but he's been there, you know? Lost a leg! Gotta walk around on a piece of wood. So sad, so sad... |", + 1, + 5, + TSFX_DRUNK34 + }, + { + "Ogden is the best man in town. I don't think his wife likes me much, but as long as she keeps tappin' kegs, I'll like her just fine. Seems like I been spendin' more time with Ogden than most, but he's so good to me... |", + 1, + 5, + TSFX_DRUNK35 + }, + { + "I wanna tell ya sumthin', 'cause I know all about this stuff. It's my specialty. This here is the best... theeeee best! That other ale ain't no good since those stupid dogs... |", + 1, + 5, + TSFX_DRUNK23 + }, + { + "No one ever lis... listens to me. Somewhere - I ain't too sure - but somewhere under the church is a whole pile o' gold. Gleamin' and shinin' and just waitin' for someone to get it. |", + 1, + 5, + TSFX_DRUNK24 + }, + { + "I know you gots your own ideas, and I know you're not gonna believe this, but that weapon you got there - it just ain't no good against those big brutes! Oh, I don't care what Griswold says, they can't make anything like they used to in the old days... |", + 1, + 5, + TSFX_DRUNK25 + }, + { + "If I was you... and I ain't... but if I was, I'd sell all that stuff you got and get out of here. That boy out there... He's always got somethin good, but you gotta give him some gold or he won't even show you what he's got. |", + 1, + 5, + TSFX_DRUNK26 + }, + { "I sense a soul in search of answers... |", 0, 5, TSFX_WITCH38 }, + { + "Wisdom is earned, not given. If you discover a tome of knowledge, devour its words. Should you already have knowledge of the arcane mysteries scribed within a book, remember - that level of mastery can always increase. |", + 1, + 5, + TSFX_WITCH39 + }, + { + "The greatest power is often the shortest lived. You may find ancient words of power written upon scrolls of parchment. The strength of these scrolls lies in the ability of either apprentice or adept to cast them with equal ability. Their weakness is that they must first be read aloud and can never be kept at the ready in your mind. Know also that these scrolls can be read but once, so use them with care. |", + 1, + 5, + TSFX_WITCH40 + }, + { + "Though the heat of the sun is beyond measure, the mere flame of a candle is of greater danger. No energies, no matter how great, can be used without the proper focus. For many spells, ensorcelled Staves may be charged with magical energies many times over. I have the ability to restore their power - but know that nothing is done without a price. |", + 1, + 5, + TSFX_WITCH41 + }, + { + "The sum of our knowledge is in the sum of its people. Should you find a book or scroll that you cannot decipher, do not hesitate to bring it to me. If I can make sense of it I will share what I find. |", + 1, + 5, + TSFX_WITCH42 + }, + { + "To a man who only knows Iron, there is no greater magic than Steel. The blacksmith Griswold is more of a sorcerer than he knows. His ability to meld fire and metal is unequaled in this land. |", + 1, + 5, + TSFX_WITCH43 + }, + { + "Corruption has the strength of deceit, but innocence holds the power of purity. The young woman Gillian has a pure heart, placing the needs of her matriarch over her own. She fears me, but it is only because she does not understand me. |", + 1, + 5, + TSFX_WITCH44 + }, + { + "A chest opened in darkness holds no greater treasure than when it is opened in the light. The storyteller Cain is an enigma, but only to those who do not look. His knowledge of what lies beneath the cathedral is far greater than even he allows himself to realize. |", + 1, + 5, + TSFX_WITCH45 + }, + { + "The higher you place your faith in one man, the farther it has to fall. Farnham has lost his soul, but not to any demon. It was lost when he saw his fellow townspeople betrayed by the Archbishop Lazarus. He has knowledge to be gleaned, but you must separate fact from fantasy. |", + 1, + 5, + TSFX_WITCH46 + }, + { + "The hand, the heart and the mind can perform miracles when they are in perfect harmony. The healer Pepin sees into the body in a way that even I cannot. His ability to restore the sick and injured is magnified by his understanding of the creation of elixirs and potions. He is as great an ally as you have in Tristram. |", + 1, + 5, + TSFX_WITCH47 + }, + { + "There is much about the future we cannot see, but when it comes it will be the children who wield it. The boy Wirt has a blackness upon his soul, but he poses no threat to the town or its people. His secretive dealings with the urchins and unspoken guilds of nearby towns gain him access to many devices that cannot be easily found in Tristram. While his methods may be reproachful, Wirt can provide assistance for your battle against the encroaching Darkness. |", + 1, + 4, + TSFX_WITCH49 + }, + { + "Earthen walls and thatched canopy do not a home create. The innkeeper Ogden serves more of a purpose in this town than many understand. He provides shelter for Gillian and her matriarch, maintains what life Farnham has left to him, and provides an anchor for all who are left in the town to what Tristram once was. His tavern, and the simple pleasures that can still be found there, provide a glimpse of a life that the people here remember. It is that memory that continues to feed their hopes for your success. |", + 1, + 4, + TSFX_WITCH50 + }, + { "Pssst... over here... |", 0, 5, TSFX_PEGBOY32 }, + { + "Not everyone in Tristram has a use - or a market - for everything you will find in the labyrinth. Not even me, as hard as that is to believe. \n \nSometimes, only you will be able to find a purpose for some things. |", + 1, + 6, + TSFX_PEGBOY33 + }, + { + "Don't trust everything the drunk says. Too many ales have fogged his vision and his good sense. |", + 1, + 6, + TSFX_PEGBOY34 + }, + { + "In case you haven't noticed, I don't buy anything from Tristram. I am an importer of quality goods. If you want to peddle junk, you'll have to see Griswold, Pepin or that witch, Adria. I'm sure that they will snap up whatever you can bring them... |", + 1, + 5, + TSFX_PEGBOY35 + }, + { + "I guess I owe the blacksmith my life - what there is of it. Sure, Griswold offered me an apprenticeship at the smithy, and he is a nice enough guy, but I'll never get enough money to... well, let's just say that I have definite plans that require a large amount of gold. |", + 1, + 5, + TSFX_PEGBOY36 + }, + { + "If I were a few years older, I would shower her with whatever riches I could muster, and let me assure you I can get my hands on some very nice stuff. Gillian is a beautiful girl who should get out of Tristram as soon as it is safe. Hmmm... maybe I'll take her with me when I go... |", + 1, + 5, + TSFX_PEGBOY37 + }, + { + "Cain knows too much. He scares the life out of me - even more than that woman across the river. He keeps telling me about how lucky I am to be alive, and how my story is foretold in legend. I think he's off his crock. |", + 1, + 5, + TSFX_PEGBOY38 + }, + { + "Farnham - now there is a man with serious problems, and I know all about how serious problems can be. He trusted too much in the integrity of one man, and Lazarus led him into the very jaws of death. Oh, I know what it's like down there, so don't even start telling me about your plans to destroy the evil that dwells in that Labyrinth. Just watch your legs... |", + 1, + 5, + TSFX_PEGBOY39 + }, + { + "As long as you don't need anything reattached, old Pepin is as good as they come. \n \nIf I'd have had some of those potions he brews, I might still have my leg... |", + 1, + 6, + TSFX_PEGBOY40 + }, + { + "Adria truly bothers me. Sure, Cain is creepy in what he can tell you about the past, but that witch can see into your past. She always has some way to get whatever she needs, too. Adria gets her hands on more merchandise than I've seen pass through the gates of the King's Bazaar during High Festival. |", + 1, + 5, + TSFX_PEGBOY42 + }, + { + "Ogden is a fool for staying here. I could get him out of town for a very reasonable price, but he insists on trying to make a go of it with that stupid tavern. I guess at the least he gives Gillian a place to work, and his wife Garda does make a superb Shepherd's pie... |", + 1, + 5, + TSFX_PEGBOY43 + }, + { + "Beyond the Hall of Heroes lies the Chamber of Bone. Eternal death awaits any who would seek to steal the treasures secured within this room. So speaks the Lord of Terror, and so it is written. |", + 1, + 5, + PS_WARR1 + }, + { + "...and so, locked beyond the Gateway of Blood and past the Hall of Fire, Valor awaits for the Hero of Light to awaken... |", + 1, + 6, + PS_WARR10 + }, + { + "I can see what you see not.\nVision milky then eyes rot.\nWhen you turn they will be gone,\nWhispering their hidden song.\nThen you see what cannot be,\nShadows move where light should be.\nOut of darkness, out of mind,\nCast down into the Halls of the Blind. |\n", + 1, + 5, + PS_WARR11 + }, + { + "The armories of Hell are home to the Warlord of Blood. In his wake lay the mutilated bodies of thousands. Angels and man alike have been cut down to fulfill his endless sacrifices to the Dark ones who scream for one thing - blood. |", + 1, + 5, + PS_WARR12 + }, + { + "Beyond the Hall of Heroes lies the Chamber of Bone. Eternal death awaits any who would seek to steal the treasures secured within this room. So speaks the Lord of Terror, and so it is written. |", + 1, + 5, + PS_MAGE1 + }, + { + "...and so, locked beyond the Gateway of Blood and past the Hall of Fire, Valor awaits for the Hero of Light to awaken... |", + 1, + 6, + PS_MAGE10 + }, + { + "I can see what you see not.\nVision milky then eyes rot.\nWhen you turn they will be gone,\nWhispering their hidden song.\nThen you see what cannot be,\nShadows move where light should be.\nOut of darkness, out of mind,\nCast down into the Halls of the Blind. |\n", + 1, + 4, + PS_MAGE11 + }, + { + "The armories of Hell are home to the Warlord of Blood. In his wake lay the mutilated bodies of thousands. Angels and man alike have been cut down to fulfill his endless sacrifices to the Dark ones who scream for one thing - blood. |", + 1, + 5, + PS_MAGE12 + }, + { + "Beyond the Hall of Heroes lies the Chamber of Bone. Eternal death awaits any who would seek to steal the treasures secured within this room. So speaks the Lord of Terror, and so it is written. |", + 1, + 5, + PS_ROGUE1 + }, + { + "...and so, locked beyond the Gateway of Blood and past the Hall of Fire, Valor awaits for the Hero of Light to awaken... |", + 1, + 5, + PS_ROGUE10 + }, + { + "I can see what you see not.\nVision milky then eyes rot.\nWhen you turn they will be gone,\nWhispering their hidden song.\nThen you see what cannot be,\nShadows move where light should be.\nOut of darkness, out of mind,\nCast down into the Halls of the Blind. |\n", + 1, + 5, + PS_ROGUE11 + }, + { + "The armories of Hell are home to the Warlord of Blood. In his wake lay the mutilated bodies of thousands. Angels and man alike have been cut down to fulfill his endless sacrifices to the Dark ones who scream for one thing - blood. |", + 1, + 5, + PS_ROGUE12 + }, + { " |", 0, 5, TSFX_COW1 }, + { " |", 0, 5, TSFX_COW2 }, + { + "Take heed and bear witness to the truths that lie herein, for they are the last legacy of the Horadrim. There is a war that rages on even now, beyond the fields that we know - between the utopian kingdoms of the High Heavens and the chaotic pits of the Burning Hells. This war is known as the Great Conflict, and it has raged and burned longer than any of the stars in the sky. Neither side ever gains sway for long as the forces of Light and Darkness constantly vie for control over all creation. |", + 1, + 5, + PS_NAR1 + }, + { + "Take heed and bear witness to the truths that lie herein, for they are the last legacy of the Horadrim. When the Eternal Conflict between the High Heavens and the Burning Hells falls upon mortal soil, it is called the Sin War. Angels and Demons walk amongst humanity in disguise, fighting in secret, away from the prying eyes of mortals. Some daring, powerful mortals have even allied themselves with either side, and helped to dictate the course of the Sin War. |", + 1, + 4, + PS_NAR2 + }, + { + "Take heed and bear witness to the truths that lie herein, for they are the last legacy of the Horadrim. Nearly three hundred years ago, it came to be known that the Three Prime Evils of the Burning Hells had mysteriously come to our world. The Three Brothers ravaged the lands of the east for decades, while humanity was left trembling in their wake. Our Order - the Horadrim - was founded by a group of secretive magi to hunt down and capture the Three Evils once and for all.\n \nThe original Horadrim captured two of the Three within powerful artifacts known as Soulstones and buried them deep beneath the desolate eastern sands. The third Evil escaped capture and fled to the west with many of the Horadrim in pursuit. The Third Evil - known as Diablo, the Lord of Terror - was eventually captured, his essence set in a Soulstone and buried within this Labyrinth.\n \nBe warned that the soulstone must be kept from discovery by those not of the faith. If Diablo were to be released, he would seek a body that is easily controlled as he would be very weak - perhaps that of an old man or a child. |", + 1, + 3, + PS_NAR3 + }, + { + "So it came to be that there was a great revolution within the Burning Hells known as The Dark Exile. The Lesser Evils overthrew the Three Prime Evils and banished their spirit forms to the mortal realm. The demons Belial (the Lord of Lies) and Azmodan (the Lord of Sin) fought to claim rulership of Hell during the absence of the Three Brothers. All of Hell polarized between the factions of Belial and Azmodan while the forces of the High Heavens continually battered upon the very Gates of Hell. |", + 1, + 4, + PS_NAR4 + }, + { + "Many demons traveled to the mortal realm in search of the Three Brothers. These demons were followed to the mortal plane by Angels who hunted them throughout the vast cities of the East. The Angels allied themselves with a secretive Order of mortal magi named the Horadrim, who quickly became adept at hunting demons. They also made many dark enemies in the underworlds. |", + 1, + 5, + PS_NAR5 + }, + { + "So it came to be that the Three Prime Evils were banished in spirit form to the mortal realm and after sewing chaos across the East for decades, they were hunted down by the cursed Order of the mortal Horadrim. The Horadrim used artifacts called Soulstones to contain the essence of Mephisto, the Lord of Hatred and his brother Baal, the Lord of Destruction. The youngest brother - Diablo, the Lord of Terror - escaped to the west.\n \nEventually the Horadrim captured Diablo within a Soulstone as well, and buried him under an ancient, forgotten Cathedral. There, the Lord of Terror sleeps and awaits the time of his rebirth. Know ye that he will seek a body of youth and power to possess - one that is innocent and easily controlled. He will then arise to free his Brothers and once more fan the flames of the Sin War... |", + 1, + 3, + PS_NAR6 + }, + { + "All praises to Diablo - Lord of Terror and Survivor of The Dark Exile. When he awakened from his long slumber, my Lord and Master spoke to me of secrets that few mortals know. He told me the kingdoms of the High Heavens and the pits of the Burning Hells engage in an eternal war. He revealed the powers that have brought this discord to the realms of man. My lord has named the battle for this world and all who exist here the Sin War. |", + 1, + 4, + PS_NAR7 + }, + { + "Glory and Approbation to Diablo - Lord of Terror and Leader of the Three. My Lord spoke to me of his two Brothers, Mephisto and Baal, who were banished to this world long ago. My Lord wishes to bide his time and harness his awesome power so that he may free his captive brothers from their tombs beneath the sands of the east. Once my Lord releases his Brothers, the Sin War will once again know the fury of the Three. |", + 1, + 4, + PS_NAR8 + }, + { + "Hail and Sacrifice to Diablo - Lord of Terror and Destroyer of Souls. When I awoke my Master from his sleep, he attempted to possess a mortal's form. Diablo attempted to claim the body of King Leoric, but my Master was too weak from his imprisonment. My Lord required a simple and innocent anchor to this world, and so found the boy Albrecht to be perfect for the task. While the good King Leoric was left maddened by Diablo's unsuccessful possession, I kidnapped his son Albrecht and brought him before my Master. I now await Diablo's call and pray that I will be rewarded when he at last emerges as the Lord of this world. |", + 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 + } +}; +_sfx_id snSFX[3][3] = +{ + { PS_WARR52, PS_ROGUE52, PS_MAGE52 }, + { PS_WARR49, PS_ROGUE49, PS_MAGE49 }, + { PS_WARR50, PS_ROGUE50, PS_MAGE50 } +}; +int track_inf = 2139095040; // weak +int wave_inf = 2139095040; // weak +unsigned char SpellITbl[37] = +{ + 1u, + 1u, + 2u, + 3u, + 4u, + 5u, + 6u, + 7u, + 8u, + 9u, + 28u, + 13u, + 12u, + 18u, + 16u, + 14u, + 18u, + 19u, + 11u, + 20u, + 15u, + 21u, + 23u, + 24u, + 25u, + 22u, + 26u, + 29u, + 37u, + 38u, + 39u, + 42u, + 41u, + 40u, + 10u, + 36u, + 30u +}; +int PanBtnPos[8][5] = +{ + { 9, 361, 71, 19, 1 }, + { 9, 387, 71, 19, 0 }, + { 9, 427, 71, 19, 1 }, + { 9, 453, 71, 19, 0 }, + { 560, 361, 71, 19, 1 }, + { 560, 387, 71, 19, 0 }, + { 87, 443, 33, 32, 1 }, + { 527, 443, 33, 32, 1 } +}; +char *PanBtnHotKey[8] = { "'c'", "'q'", "Tab", "Esc", "'i'", "'b'", "Enter", NULL }; +char *PanBtnStr[8] = +{ + "Character Information", + "Quests log", + "Automap", + "Main Menu", + "Inventory", + "Spell book", + "Send Message", + "Player Attack" +}; +RECT32 attribute_inc_rects[4] = +{ + { 137, 138, 41, 22 }, + { 137, 166, 41, 22 }, + { 137, 195, 41, 22 }, + { 137, 223, 41, 22 } +}; +spell_id SpellPages[6][7] = +{ + { + SPL_NULL, + SPL_FIREBOLT, + SPL_CBOLT, + SPL_HBOLT, + SPL_HEAL, + SPL_HEALOTHER, + SPL_FLAME + }, + { + SPL_RESURRECT, + SPL_FIREWALL, + SPL_TELEKINESIS, + SPL_LIGHTNING, + SPL_TOWN, + SPL_FLASH, + SPL_STONE + }, + { + SPL_RNDTELEPORT, + SPL_MANASHIELD, + SPL_ELEMENT, + SPL_FIREBALL, + SPL_WAVE, + SPL_CHAIN, + SPL_GUARDIAN + }, + { + SPL_NOVA, + SPL_GOLEM, + SPL_TELEPORT, + SPL_APOCA, + SPL_BONESPIRIT, + SPL_FLARE, + SPL_ETHEREALIZE + }, + { + SPL_INVALID, + SPL_INVALID, + SPL_INVALID, + SPL_INVALID, + SPL_INVALID, + SPL_INVALID, + SPL_INVALID + }, + { + SPL_INVALID, + SPL_INVALID, + SPL_INVALID, + SPL_INVALID, + SPL_INVALID, + SPL_INVALID, + SPL_INVALID + } +}; +int exclusive = 1; // weak +int FriendlyMode = 1; // weak +char *spszMsgTbl[4] = +{ + "I need help! Come Here!", + "Follow me.", + "Here's something for you.", + "Now you DIE!" +}; // weak +char *spszMsgKeyTbl[4] = { "F9", "F10", "F11", "F12" }; // weak +unsigned char L5ConvTbl[16] = { 22u, 13u, 1u, 13u, 2u, 13u, 13u, 13u, 4u, 13u, 1u, 13u, 2u, 13u, 16u, 13u }; +int Area_Min = 2; // weak +int Room_Max = 10; // weak +int Room_Min = 4; // weak +int Dir_Xadd[5] = { 0, 0, 1, 0, 4294967295 }; +int Dir_Yadd[5] = { 0, 4294967295, 0, 1, 0 }; +ShadowStruct SPATSL2[2] = { { 6u, 3u, 0u, 3u, 48u, 0u, 50u }, { 9u, 3u, 0u, 3u, 48u, 0u, 50u } }; +short word_48489A = 0; // weak +unsigned char BTYPESL2[161] = +{ + 0u, + 1u, + 2u, + 3u, + 4u, + 5u, + 6u, + 7u, + 8u, + 9u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 17u, + 18u, + 1u, + 1u, + 2u, + 2u, + 1u, + 1u, + 1u, + 1u, + 1u, + 1u, + 2u, + 2u, + 2u, + 2u, + 2u, + 0u, + 0u, + 0u, + 0u, + 8u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 1u, + 1u, + 1u, + 0u, + 0u, + 2u, + 2u, + 2u, + 0u, + 0u, + 0u, + 1u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 3u, + 3u, + 3u, + 3u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 3u, + 3u, + 3u, + 0u, + 3u, + 0u, + 3u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u +}; +unsigned char BSTYPESL2[161] = +{ + 0u, + 1u, + 2u, + 3u, + 0u, + 0u, + 6u, + 0u, + 0u, + 9u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 1u, + 1u, + 2u, + 2u, + 1u, + 1u, + 1u, + 1u, + 1u, + 1u, + 2u, + 2u, + 2u, + 2u, + 2u, + 0u, + 0u, + 0u, + 0u, + 0u, + 6u, + 6u, + 6u, + 9u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 1u, + 1u, + 1u, + 0u, + 0u, + 2u, + 2u, + 2u, + 0u, + 0u, + 0u, + 1u, + 1u, + 1u, + 1u, + 6u, + 2u, + 2u, + 2u, + 0u, + 3u, + 3u, + 3u, + 3u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 3u, + 3u, + 3u, + 3u, + 3u, + 3u, + 3u, + 3u, + 3u, + 3u, + 3u, + 3u, + 1u, + 1u, + 2u, + 2u, + 3u, + 3u, + 3u, + 3u, + 1u, + 1u, + 2u, + 2u, + 3u, + 3u, + 3u, + 3u, + 1u, + 1u, + 3u, + 3u, + 2u, + 2u, + 3u, + 3u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u +}; +unsigned char VARCH1[] = { 2u, 4u, 3u, 0u, 3u, 1u, 3u, 4u, 0u, 7u, 48u, 0u, 51u, 39u, 47u, 44u, 0u, 0u }; +unsigned char VARCH2[] = { 2u, 4u, 3u, 0u, 3u, 1u, 3u, 4u, 0u, 8u, 48u, 0u, 51u, 39u, 47u, 44u, 0u, 0u }; +unsigned char VARCH3[] = { 2u, 4u, 3u, 0u, 3u, 1u, 3u, 4u, 0u, 6u, 48u, 0u, 51u, 39u, 47u, 44u, 0u, 0u }; +unsigned char VARCH4[] = { 2u, 4u, 3u, 0u, 3u, 1u, 3u, 4u, 0u, 9u, 48u, 0u, 51u, 39u, 47u, 44u, 0u, 0u }; +unsigned char VARCH5[] = { 2u, 4u, 3u, 0u, 3u, 1u, 3u, 4u, 0u, 14u, 48u, 0u, 51u, 39u, 47u, 44u, 0u, 0u }; +unsigned char VARCH6[] = { 2u, 4u, 3u, 0u, 3u, 1u, 3u, 4u, 0u, 13u, 48u, 0u, 51u, 39u, 47u, 44u, 0u, 0u }; +unsigned char VARCH7[] = { 2u, 4u, 3u, 0u, 3u, 1u, 3u, 4u, 0u, 16u, 48u, 0u, 51u, 39u, 47u, 44u, 0u, 0u }; +unsigned char VARCH8[] = { 2u, 4u, 3u, 0u, 3u, 1u, 3u, 4u, 0u, 15u, 48u, 0u, 51u, 39u, 47u, 44u, 0u, 0u }; +unsigned char VARCH9[] = { 2u, 4u, 3u, 0u, 3u, 8u, 3u, 4u, 0u, 7u, 48u, 0u, 51u, 42u, 47u, 44u, 0u, 0u }; +unsigned char VARCH10[] = { 2u, 4u, 3u, 0u, 3u, 8u, 3u, 4u, 0u, 8u, 48u, 0u, 51u, 42u, 47u, 44u, 0u, 0u }; +unsigned char VARCH11[] = { 2u, 4u, 3u, 0u, 3u, 8u, 3u, 4u, 0u, 6u, 48u, 0u, 51u, 42u, 47u, 44u, 0u, 0u }; +unsigned char VARCH12[] = { 2u, 4u, 3u, 0u, 3u, 8u, 3u, 4u, 0u, 9u, 48u, 0u, 51u, 42u, 47u, 44u, 0u, 0u }; +unsigned char VARCH13[] = { 2u, 4u, 3u, 0u, 3u, 8u, 3u, 4u, 0u, 14u, 48u, 0u, 51u, 42u, 47u, 44u, 0u, 0u }; +unsigned char VARCH14[] = { 2u, 4u, 3u, 0u, 3u, 8u, 3u, 4u, 0u, 13u, 48u, 0u, 51u, 42u, 47u, 44u, 0u, 0u }; +unsigned char VARCH15[] = { 2u, 4u, 3u, 0u, 3u, 8u, 3u, 4u, 0u, 16u, 48u, 0u, 51u, 42u, 47u, 44u, 0u, 0u }; +unsigned char VARCH16[] = { 2u, 4u, 3u, 0u, 3u, 8u, 3u, 4u, 0u, 15u, 48u, 0u, 51u, 42u, 47u, 44u, 0u, 0u }; +unsigned char VARCH17[] = { 2u, 3u, 2u, 7u, 3u, 4u, 0u, 7u, 141u, 39u, 47u, 44u, 0u, 0u }; +unsigned char VARCH18[] = { 2u, 3u, 2u, 7u, 3u, 4u, 0u, 8u, 141u, 39u, 47u, 44u, 0u, 0u }; +unsigned char VARCH19[] = { 2u, 3u, 2u, 7u, 3u, 4u, 0u, 6u, 141u, 39u, 47u, 44u, 0u, 0u }; +unsigned char VARCH20[] = { 2u, 3u, 2u, 7u, 3u, 4u, 0u, 9u, 141u, 39u, 47u, 44u, 0u, 0u }; +unsigned char VARCH21[] = { 2u, 3u, 2u, 7u, 3u, 4u, 0u, 14u, 141u, 39u, 47u, 44u, 0u, 0u }; +unsigned char VARCH22[] = { 2u, 3u, 2u, 7u, 3u, 4u, 0u, 13u, 141u, 39u, 47u, 44u, 0u, 0u }; +unsigned char VARCH23[] = { 2u, 3u, 2u, 7u, 3u, 4u, 0u, 16u, 141u, 39u, 47u, 44u, 0u, 0u }; +unsigned char VARCH24[] = { 2u, 3u, 2u, 7u, 3u, 4u, 0u, 15u, 141u, 39u, 47u, 44u, 0u, 0u }; +unsigned char VARCH25[] = { 2u, 4u, 3u, 0u, 3u, 4u, 3u, 1u, 0u, 7u, 48u, 0u, 51u, 39u, 47u, 44u, 0u, 0u }; +unsigned char VARCH26[] = { 2u, 4u, 3u, 0u, 3u, 4u, 3u, 1u, 0u, 8u, 48u, 0u, 51u, 39u, 47u, 44u, 0u, 0u }; +unsigned char VARCH27[] = { 2u, 4u, 3u, 0u, 3u, 4u, 3u, 1u, 0u, 6u, 48u, 0u, 51u, 39u, 47u, 44u, 0u, 0u }; +unsigned char VARCH28[] = { 2u, 4u, 3u, 0u, 3u, 4u, 3u, 1u, 0u, 9u, 48u, 0u, 51u, 39u, 47u, 44u, 0u, 0u }; +unsigned char VARCH29[] = { 2u, 4u, 3u, 0u, 3u, 4u, 3u, 1u, 0u, 14u, 48u, 0u, 51u, 39u, 47u, 44u, 0u, 0u }; +unsigned char VARCH30[] = { 2u, 4u, 3u, 0u, 3u, 4u, 3u, 1u, 0u, 13u, 48u, 0u, 51u, 39u, 47u, 44u, 0u, 0u }; +unsigned char VARCH31[] = { 2u, 4u, 3u, 0u, 3u, 4u, 3u, 1u, 0u, 16u, 48u, 0u, 51u, 39u, 47u, 44u, 0u, 0u }; +unsigned char VARCH32[] = { 2u, 4u, 3u, 0u, 3u, 4u, 3u, 1u, 0u, 15u, 48u, 0u, 51u, 39u, 47u, 44u, 0u, 0u }; +unsigned char VARCH33[] = { 2u, 4u, 2u, 0u, 3u, 8u, 3u, 4u, 0u, 7u, 142u, 0u, 51u, 42u, 47u, 44u, 0u, 0u }; +unsigned char VARCH34[] = { 2u, 4u, 2u, 0u, 3u, 8u, 3u, 4u, 0u, 8u, 142u, 0u, 51u, 42u, 47u, 44u, 0u, 0u }; +unsigned char VARCH35[] = { 2u, 4u, 2u, 0u, 3u, 8u, 3u, 4u, 0u, 6u, 142u, 0u, 51u, 42u, 47u, 44u, 0u, 0u }; +unsigned char VARCH36[] = { 2u, 4u, 2u, 0u, 3u, 8u, 3u, 4u, 0u, 9u, 142u, 0u, 51u, 42u, 47u, 44u, 0u, 0u }; +unsigned char VARCH37[] = +{ + 2u, + 4u, + 2u, + 0u, + 3u, + 8u, + 3u, + 4u, + 0u, + 14u, + 142u, + 0u, + 51u, + 42u, + 47u, + 44u, + 0u, + 0u +}; +unsigned char VARCH38[] = +{ + 2u, + 4u, + 2u, + 0u, + 3u, + 8u, + 3u, + 4u, + 0u, + 13u, + 142u, + 0u, + 51u, + 42u, + 47u, + 44u, + 0u, + 0u +}; +unsigned char VARCH39[] = +{ + 2u, + 4u, + 2u, + 0u, + 3u, + 8u, + 3u, + 4u, + 0u, + 16u, + 142u, + 0u, + 51u, + 42u, + 47u, + 44u, + 0u, + 0u +}; +unsigned char VARCH40[] = +{ + 2u, + 4u, + 2u, + 0u, + 3u, + 8u, + 3u, + 4u, + 0u, + 15u, + 142u, + 0u, + 51u, + 42u, + 47u, + 44u, + 0u, + 0u +}; +unsigned char HARCH1[] = { 3u, 2u, 3u, 3u, 0u, 2u, 5u, 9u, 49u, 46u, 0u, 40u, 45u, 0u }; +unsigned char HARCH2[] = { 3u, 2u, 3u, 3u, 0u, 2u, 5u, 6u, 49u, 46u, 0u, 40u, 45u, 0u }; +unsigned char HARCH3[] = { 3u, 2u, 3u, 3u, 0u, 2u, 5u, 8u, 49u, 46u, 0u, 40u, 45u, 0u }; +unsigned char HARCH4[] = { 3u, 2u, 3u, 3u, 0u, 2u, 5u, 7u, 49u, 46u, 0u, 40u, 45u, 0u }; +unsigned char HARCH5[] = { 3u, 2u, 3u, 3u, 0u, 2u, 5u, 15u, 49u, 46u, 0u, 40u, 45u, 0u }; +unsigned char HARCH6[] = { 3u, 2u, 3u, 3u, 0u, 2u, 5u, 16u, 49u, 46u, 0u, 40u, 45u, 0u }; +unsigned char HARCH7[] = { 3u, 2u, 3u, 3u, 0u, 2u, 5u, 13u, 49u, 46u, 0u, 40u, 45u, 0u }; +unsigned char HARCH8[] = { 3u, 2u, 3u, 3u, 0u, 2u, 5u, 14u, 49u, 46u, 0u, 40u, 45u, 0u }; +unsigned char HARCH9[] = { 3u, 2u, 3u, 3u, 0u, 8u, 5u, 9u, 49u, 46u, 0u, 43u, 45u, 0u }; +unsigned char HARCH10[] = { 3u, 2u, 3u, 3u, 0u, 8u, 5u, 6u, 49u, 46u, 0u, 43u, 45u, 0u }; +unsigned char HARCH11[] = { 3u, 2u, 3u, 3u, 0u, 8u, 5u, 8u, 49u, 46u, 0u, 43u, 45u, 0u }; +unsigned char HARCH12[] = { 3u, 2u, 3u, 3u, 0u, 8u, 5u, 7u, 49u, 46u, 0u, 43u, 45u, 0u }; +unsigned char HARCH13[] = { 3u, 2u, 3u, 3u, 0u, 8u, 5u, 15u, 49u, 46u, 0u, 43u, 45u, 0u }; +unsigned char HARCH14[] = { 3u, 2u, 3u, 3u, 0u, 8u, 5u, 16u, 49u, 46u, 0u, 43u, 45u, 0u }; +unsigned char HARCH15[] = { 3u, 2u, 3u, 3u, 0u, 8u, 5u, 13u, 49u, 46u, 0u, 43u, 45u, 0u }; +unsigned char HARCH16[] = { 3u, 2u, 3u, 3u, 0u, 8u, 5u, 14u, 49u, 46u, 0u, 43u, 45u, 0u }; +unsigned char HARCH17[] = { 3u, 2u, 1u, 3u, 0u, 8u, 5u, 9u, 140u, 46u, 0u, 43u, 45u, 0u }; +unsigned char HARCH18[] = { 3u, 2u, 1u, 3u, 0u, 8u, 5u, 6u, 140u, 46u, 0u, 43u, 45u, 0u }; +unsigned char HARCH19[] = { 3u, 2u, 1u, 3u, 0u, 8u, 5u, 8u, 140u, 46u, 0u, 43u, 45u, 0u }; +unsigned char HARCH20[] = { 3u, 2u, 1u, 3u, 0u, 8u, 5u, 7u, 140u, 46u, 0u, 43u, 45u, 0u }; +unsigned char HARCH21[] = { 3u, 2u, 1u, 3u, 0u, 8u, 5u, 15u, 140u, 46u, 0u, 43u, 45u, 0u }; +unsigned char HARCH22[] = { 3u, 2u, 1u, 3u, 0u, 8u, 5u, 16u, 140u, 46u, 0u, 43u, 45u, 0u }; +unsigned char HARCH23[] = { 3u, 2u, 1u, 3u, 0u, 8u, 5u, 13u, 140u, 46u, 0u, 43u, 45u, 0u }; +unsigned char HARCH24[] = { 3u, 2u, 1u, 3u, 0u, 8u, 5u, 14u, 140u, 46u, 0u, 43u, 45u, 0u }; +unsigned char HARCH25[] = { 3u, 2u, 3u, 3u, 0u, 5u, 2u, 9u, 49u, 46u, 0u, 40u, 45u, 0u }; +unsigned char HARCH26[] = { 3u, 2u, 3u, 3u, 0u, 5u, 2u, 6u, 49u, 46u, 0u, 40u, 45u, 0u }; +unsigned char HARCH27[] = { 3u, 2u, 3u, 3u, 0u, 5u, 2u, 8u, 49u, 46u, 0u, 40u, 45u, 0u }; +unsigned char HARCH28[] = { 3u, 2u, 3u, 3u, 0u, 5u, 2u, 7u, 49u, 46u, 0u, 40u, 45u, 0u }; +unsigned char HARCH29[] = { 3u, 2u, 3u, 3u, 0u, 5u, 2u, 15u, 49u, 46u, 0u, 40u, 45u, 0u }; +unsigned char HARCH30[] = { 3u, 2u, 3u, 3u, 0u, 5u, 2u, 16u, 49u, 46u, 0u, 40u, 45u, 0u }; +unsigned char HARCH31[] = { 3u, 2u, 3u, 3u, 0u, 5u, 2u, 13u, 49u, 46u, 0u, 40u, 45u, 0u }; +unsigned char HARCH32[] = { 3u, 2u, 3u, 3u, 0u, 5u, 2u, 14u, 49u, 46u, 0u, 40u, 45u, 0u }; +unsigned char HARCH33[] = { 3u, 2u, 1u, 3u, 0u, 9u, 5u, 9u, 140u, 46u, 0u, 40u, 45u, 0u }; +unsigned char HARCH34[] = { 3u, 2u, 1u, 3u, 0u, 9u, 5u, 6u, 140u, 46u, 0u, 40u, 45u, 0u }; +unsigned char HARCH35[] = { 3u, 2u, 1u, 3u, 0u, 9u, 5u, 8u, 140u, 46u, 0u, 40u, 45u, 0u }; +unsigned char HARCH36[] = { 3u, 2u, 1u, 3u, 0u, 9u, 5u, 7u, 140u, 46u, 0u, 40u, 45u, 0u }; +unsigned char HARCH37[] = { 3u, 2u, 1u, 3u, 0u, 9u, 5u, 15u, 140u, 46u, 0u, 40u, 45u, 0u }; +unsigned char HARCH38[] = { 3u, 2u, 1u, 3u, 0u, 9u, 5u, 16u, 140u, 46u, 0u, 40u, 45u, 0u }; +unsigned char HARCH39[] = { 3u, 2u, 1u, 3u, 0u, 9u, 5u, 13u, 140u, 46u, 0u, 40u, 45u, 0u }; +unsigned char HARCH40[] = { 3u, 2u, 1u, 3u, 0u, 9u, 5u, 14u, 140u, 46u, 0u, 40u, 45u, 0u }; +unsigned char USTAIRS[] = +{ + 4u, + 4u, + 3u, + 3u, + 3u, + 3u, + 3u, + 3u, + 3u, + 3u, + 3u, + 3u, + 3u, + 3u, + 3u, + 3u, + 3u, + 3u, + 0u, + 0u, + 0u, + 0u, + 0u, + 72u, + 77u, + 0u, + 0u, + 76u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u +}; +unsigned char DSTAIRS[] = +{ + 4u, + 4u, + 3u, + 3u, + 3u, + 3u, + 3u, + 3u, + 3u, + 3u, + 3u, + 3u, + 3u, + 3u, + 3u, + 3u, + 3u, + 3u, + 0u, + 0u, + 0u, + 0u, + 0u, + 48u, + 71u, + 0u, + 0u, + 50u, + 78u, + 0u, + 0u, + 0u, + 0u, + 0u +}; +unsigned char WARPSTAIRS[] = +{ + 4u, + 4u, + 3u, + 3u, + 3u, + 3u, + 3u, + 3u, + 3u, + 3u, + 3u, + 3u, + 3u, + 3u, + 3u, + 3u, + 3u, + 3u, + 0u, + 0u, + 0u, + 0u, + 0u, + 158u, + 160u, + 0u, + 0u, + 159u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u +}; +unsigned char CRUSHCOL[] = +{ + 3u, + 3u, + 3u, + 1u, + 3u, + 2u, + 6u, + 3u, + 3u, + 3u, + 3u, + 0u, + 0u, + 0u, + 0u, + 83u, + 0u, + 0u, + 0u, + 0u +}; +unsigned char BIG1[] = { 2u, 2u, 3u, 3u, 3u, 3u, 113u, 0u, 112u, 0u }; +unsigned char BIG2[] = { 2u, 2u, 3u, 3u, 3u, 3u, 114u, 115u, 0u, 0u }; +unsigned char BIG3[] = { 1u, 2u, 1u, 1u, 117u, 116u }; +unsigned char BIG4[] = { 2u, 1u, 2u, 2u, 118u, 119u }; +unsigned char BIG5[] = { 2u, 2u, 3u, 3u, 3u, 3u, 120u, 122u, 121u, 123u }; +unsigned char BIG6[] = { 1u, 2u, 1u, 1u, 125u, 124u }; +unsigned char BIG7[] = { 2u, 1u, 2u, 2u, 126u, 127u }; +unsigned char BIG8[] = { 2u, 2u, 3u, 3u, 3u, 3u, 128u, 130u, 129u, 131u }; +unsigned char BIG9[] = { 2u, 2u, 1u, 3u, 1u, 3u, 133u, 135u, 132u, 134u }; +unsigned char BIG10[] = { 2u, 2u, 2u, 2u, 3u, 3u, 136u, 137u, 3u, 3u }; +unsigned char RUINS1[] = { 1u, 1u, 1u, 80u }; +unsigned char RUINS2[] = { 1u, 1u, 1u, 81u }; +unsigned char RUINS3[] = { 1u, 1u, 1u, 82u }; +unsigned char RUINS4[] = { 1u, 1u, 2u, 84u }; +unsigned char RUINS5[] = { 1u, 1u, 2u, 85u }; +unsigned char RUINS6[] = { 1u, 1u, 2u, 86u }; +unsigned char RUINS7[] = { 1u, 1u, 8u, 87u }; +unsigned char PANCREAS1[] = +{ + 5u, + 3u, + 3u, + 3u, + 3u, + 3u, + 3u, + 3u, + 3u, + 3u, + 3u, + 3u, + 3u, + 3u, + 3u, + 3u, + 3u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 108u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u +}; +unsigned char PANCREAS2[] = +{ + 5u, + 3u, + 3u, + 3u, + 3u, + 3u, + 3u, + 3u, + 3u, + 3u, + 3u, + 3u, + 3u, + 3u, + 3u, + 3u, + 3u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 110u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u +}; +unsigned char CTRDOOR1[] = +{ + 3u, + 3u, + 3u, + 1u, + 3u, + 0u, + 4u, + 0u, + 0u, + 9u, + 0u, + 0u, + 4u, + 0u, + 0u, + 1u, + 0u, + 0u, + 0u, + 0u +}; +unsigned char CTRDOOR2[] = +{ + 3u, + 3u, + 3u, + 1u, + 3u, + 0u, + 4u, + 0u, + 0u, + 8u, + 0u, + 0u, + 4u, + 0u, + 0u, + 1u, + 0u, + 0u, + 0u, + 0u +}; +unsigned char CTRDOOR3[] = +{ + 3u, + 3u, + 3u, + 1u, + 3u, + 0u, + 4u, + 0u, + 0u, + 6u, + 0u, + 0u, + 4u, + 0u, + 0u, + 1u, + 0u, + 0u, + 0u, + 0u +}; +unsigned char CTRDOOR4[] = +{ + 3u, + 3u, + 3u, + 1u, + 3u, + 0u, + 4u, + 0u, + 0u, + 7u, + 0u, + 0u, + 4u, + 0u, + 0u, + 1u, + 0u, + 0u, + 0u, + 0u +}; +unsigned char CTRDOOR5[] = +{ + 3u, + 3u, + 3u, + 1u, + 3u, + 0u, + 4u, + 0u, + 0u, + 15u, + 0u, + 0u, + 4u, + 0u, + 0u, + 1u, + 0u, + 0u, + 0u, + 0u +}; +unsigned char CTRDOOR6[] = +{ + 3u, + 3u, + 3u, + 1u, + 3u, + 0u, + 4u, + 0u, + 0u, + 13u, + 0u, + 0u, + 4u, + 0u, + 0u, + 1u, + 0u, + 0u, + 0u, + 0u +}; +unsigned char CTRDOOR7[] = +{ + 3u, + 3u, + 3u, + 1u, + 3u, + 0u, + 4u, + 0u, + 0u, + 16u, + 0u, + 0u, + 4u, + 0u, + 0u, + 1u, + 0u, + 0u, + 0u, + 0u +}; +unsigned char CTRDOOR8[] = +{ + 3u, + 3u, + 3u, + 1u, + 3u, + 0u, + 4u, + 0u, + 0u, + 14u, + 0u, + 0u, + 4u, + 0u, + 0u, + 1u, + 0u, + 0u, + 0u, + 0u +}; +int Patterns[100][10] = +{ + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 3 }, + { 0, 0, 0, 0, 2, 0, 0, 0, 0, 3 }, + { 0, 7, 0, 0, 1, 0, 0, 5, 0, 2 }, + { 0, 5, 0, 0, 1, 0, 0, 7, 0, 2 }, + { 0, 0, 0, 7, 1, 5, 0, 0, 0, 1 }, + { 0, 0, 0, 5, 1, 7, 0, 0, 0, 1 }, + { 0, 1, 0, 0, 3, 0, 0, 1, 0, 4 }, + { 0, 0, 0, 1, 3, 1, 0, 0, 0, 5 }, + { 0, 6, 0, 6, 1, 0, 0, 0, 0, 6 }, + { 0, 6, 0, 0, 1, 6, 0, 0, 0, 9 }, + { 0, 0, 0, 6, 1, 0, 0, 6, 0, 7 }, + { 0, 0, 0, 0, 1, 6, 0, 6, 0, 8 }, + { 0, 6, 0, 6, 6, 0, 8, 6, 0, 7 }, + { 0, 6, 8, 6, 6, 6, 0, 0, 0, 9 }, + { 0, 6, 0, 0, 6, 6, 0, 6, 8, 8 }, + { 6, 6, 6, 6, 6, 6, 0, 6, 0, 8 }, + { 2, 6, 6, 6, 6, 6, 0, 6, 0, 8 }, + { 7, 7, 7, 6, 6, 6, 0, 6, 0, 8 }, + { 6, 6, 2, 6, 6, 6, 0, 6, 0, 8 }, + { 6, 2, 6, 6, 6, 6, 0, 6, 0, 8 }, + { 2, 6, 6, 6, 6, 6, 0, 6, 0, 8 }, + { 6, 7, 7, 6, 6, 6, 0, 6, 0, 8 }, + { 4, 4, 6, 6, 6, 6, 2, 6, 2, 8 }, + { 2, 2, 2, 2, 6, 2, 2, 6, 2, 7 }, + { 2, 2, 2, 2, 6, 2, 6, 6, 6, 7 }, + { 2, 2, 6, 2, 6, 6, 2, 2, 6, 9 }, + { 2, 6, 2, 2, 6, 2, 2, 2, 2, 6 }, + { 2, 2, 2, 2, 6, 6, 2, 2, 2, 9 }, + { 2, 2, 2, 6, 6, 2, 2, 2, 2, 6 }, + { 2, 2, 0, 2, 6, 6, 2, 2, 0, 9 }, + { 0, 0, 0, 0, 4, 0, 0, 0, 0, 12 }, + { 0, 1, 0, 0, 1, 4, 0, 1, 0, 10 }, + { 0, 0, 0, 1, 1, 1, 0, 4, 0, 11 }, + { 0, 0, 0, 6, 1, 4, 0, 1, 0, 14 }, + { 0, 6, 0, 1, 1, 0, 0, 4, 0, 16 }, + { 0, 6, 0, 0, 1, 1, 0, 4, 0, 15 }, + { 0, 0, 0, 0, 1, 1, 0, 1, 4, 13 }, + { 8, 8, 8, 8, 1, 1, 0, 1, 1, 13 }, + { 8, 8, 4, 8, 1, 1, 0, 1, 1, 10 }, + { 0, 0, 0, 1, 1, 1, 1, 1, 1, 11 }, + { 1, 1, 1, 1, 1, 1, 2, 2, 8, 2 }, + { 0, 1, 0, 1, 1, 4, 1, 1, 0, 16 }, + { 0, 0, 0, 1, 1, 1, 1, 1, 4, 11 }, + { 1, 1, 4, 1, 1, 1, 0, 2, 2, 2 }, + { 1, 1, 1, 1, 1, 1, 6, 2, 6, 2 }, + { 4, 1, 1, 1, 1, 1, 6, 2, 6, 2 }, + { 2, 2, 2, 1, 1, 1, 4, 1, 1, 11 }, + { 4, 1, 1, 1, 1, 1, 2, 2, 2, 2 }, + { 1, 1, 4, 1, 1, 1, 2, 2, 1, 2 }, + { 4, 1, 1, 1, 1, 1, 1, 2, 2, 2 }, + { 2, 2, 6, 1, 1, 1, 4, 1, 1, 11 }, + { 4, 1, 1, 1, 1, 1, 2, 2, 6, 2 }, + { 1, 2, 2, 1, 1, 1, 4, 1, 1, 11 }, + { 0, 1, 1, 0, 1, 1, 0, 1, 1, 10 }, + { 2, 1, 1, 3, 1, 1, 2, 1, 1, 14 }, + { 1, 1, 0, 1, 1, 2, 1, 1, 0, 1 }, + { 0, 4, 0, 1, 1, 1, 0, 1, 1, 14 }, + { 4, 1, 0, 1, 1, 0, 1, 1, 0, 1 }, + { 0, 1, 0, 4, 1, 1, 0, 1, 1, 15 }, + { 1, 1, 1, 1, 1, 1, 0, 2, 2, 2 }, + { 0, 1, 1, 2, 1, 1, 2, 1, 4, 10 }, + { 2, 1, 1, 1, 1, 1, 0, 4, 0, 16 }, + { 1, 1, 4, 1, 1, 2, 0, 1, 2, 1 }, + { 2, 1, 1, 2, 1, 1, 1, 1, 4, 10 }, + { 1, 1, 2, 1, 1, 2, 4, 1, 8, 1 }, + { 2, 1, 4, 1, 1, 1, 4, 4, 1, 16 }, + { 2, 1, 1, 1, 1, 1, 1, 1, 1, 16 }, + { 1, 1, 2, 1, 1, 1, 1, 1, 1, 15 }, + { 1, 1, 1, 1, 1, 1, 2, 1, 1, 14 }, + { 4, 1, 1, 1, 1, 1, 2, 1, 1, 14 }, + { 1, 1, 1, 1, 1, 1, 1, 1, 2, 8 }, + { 0, 0, 0, 0, 255, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } +}; +HANDLE sghThread = (HANDLE)0xFFFFFFFF; // idb +TSFX sgSFX[858] = +{ + { 2u, "Sfx\\Misc\\Walk1.wav", 0 }, + { 2u, "Sfx\\Misc\\Walk2.wav", 0 }, + { 2u, "Sfx\\Misc\\Walk3.wav", 0 }, + { 2u, "Sfx\\Misc\\Walk4.wav", 0 }, + { 2u, "Sfx\\Misc\\BFire.wav", 0 }, + { 2u, "Sfx\\Misc\\Fmag.wav", 0 }, + { 2u, "Sfx\\Misc\\Tmag.wav", 0 }, + { 2u, "Sfx\\Misc\\Lghit.wav", 0 }, + { 2u, "Sfx\\Misc\\Lghit1.wav", 0 }, + { 2u, "Sfx\\Misc\\Swing.wav", 0 }, + { 2u, "Sfx\\Misc\\Swing2.wav", 0 }, + { 2u, "Sfx\\Misc\\Dead.wav", 0 }, + { 1u, "Sfx\\Misc\\Questdon.wav", 0 }, + { 2u, "Sfx\\Items\\Armrfkd.wav", 0 }, + { 2u, "Sfx\\Items\\Barlfire.wav", 0 }, + { 2u, "Sfx\\Items\\Barrel.wav", 0 }, + { 2u, "Sfx\\Items\\Bhit.wav", 0 }, + { 2u, "Sfx\\Items\\Bhit1.wav", 0 }, + { 2u, "Sfx\\Items\\Chest.wav", 0 }, + { 2u, "Sfx\\Items\\Doorclos.wav", 0 }, + { 2u, "Sfx\\Items\\Dooropen.wav", 0 }, + { 2u, "Sfx\\Items\\Flipanvl.wav", 0 }, + { 2u, "Sfx\\Items\\Flipaxe.wav", 0 }, + { 2u, "Sfx\\Items\\Flipblst.wav", 0 }, + { 2u, "Sfx\\Items\\Flipbody.wav", 0 }, + { 2u, "Sfx\\Items\\Flipbook.wav", 0 }, + { 2u, "Sfx\\Items\\Flipbow.wav", 0 }, + { 2u, "Sfx\\Items\\Flipcap.wav", 0 }, + { 2u, "Sfx\\Items\\Flipharm.wav", 0 }, + { 2u, "Sfx\\Items\\Fliplarm.wav", 0 }, + { 2u, "Sfx\\Items\\Flipmag.wav", 0 }, + { 2u, "Sfx\\Items\\Flipmag1.wav", 0 }, + { 2u, "Sfx\\Items\\Flipmush.wav", 0 }, + { 2u, "Sfx\\Items\\Flippot.wav", 0 }, + { 2u, "Sfx\\Items\\Flipring.wav", 0 }, + { 2u, "Sfx\\Items\\Fliprock.wav", 0 }, + { 2u, "Sfx\\Items\\Flipscrl.wav", 0 }, + { 2u, "Sfx\\Items\\Flipshld.wav", 0 }, + { 2u, "Sfx\\Items\\Flipsign.wav", 0 }, + { 2u, "Sfx\\Items\\Flipstaf.wav", 0 }, + { 2u, "Sfx\\Items\\Flipswor.wav", 0 }, + { 2u, "Sfx\\Items\\Gold.wav", 0 }, + { 2u, "Sfx\\Items\\Hlmtfkd.wav", 0 }, + { 2u, "Sfx\\Items\\Invanvl.wav", 0 }, + { 2u, "Sfx\\Items\\Invaxe.wav", 0 }, + { 2u, "Sfx\\Items\\Invblst.wav", 0 }, + { 2u, "Sfx\\Items\\Invbody.wav", 0 }, + { 2u, "Sfx\\Items\\Invbook.wav", 0 }, + { 2u, "Sfx\\Items\\Invbow.wav", 0 }, + { 2u, "Sfx\\Items\\Invcap.wav", 0 }, + { 2u, "Sfx\\Items\\Invgrab.wav", 0 }, + { 2u, "Sfx\\Items\\Invharm.wav", 0 }, + { 2u, "Sfx\\Items\\Invlarm.wav", 0 }, + { 2u, "Sfx\\Items\\Invmush.wav", 0 }, + { 2u, "Sfx\\Items\\Invpot.wav", 0 }, + { 2u, "Sfx\\Items\\Invring.wav", 0 }, + { 2u, "Sfx\\Items\\Invrock.wav", 0 }, + { 2u, "Sfx\\Items\\Invscrol.wav", 0 }, + { 2u, "Sfx\\Items\\Invshiel.wav", 0 }, + { 2u, "Sfx\\Items\\Invsign.wav", 0 }, + { 2u, "Sfx\\Items\\Invstaf.wav", 0 }, + { 2u, "Sfx\\Items\\Invsword.wav", 0 }, + { 2u, "Sfx\\Items\\Lever.wav", 0 }, + { 2u, "Sfx\\Items\\Magic.wav", 0 }, + { 2u, "Sfx\\Items\\Magic1.wav", 0 }, + { 2u, "Sfx\\Items\\Readbook.wav", 0 }, + { 2u, "Sfx\\Items\\Sarc.wav", 0 }, + { 2u, "Sfx\\Items\\Shielfkd.wav", 0 }, + { 2u, "Sfx\\Items\\Swrdfkd.wav", 0 }, + { 4u, "Sfx\\Items\\Titlemov.wav", 0 }, + { 4u, "Sfx\\Items\\Titlslct.wav", 0 }, + { 4u, "Sfx\\Misc\\blank.wav", 0 }, + { 2u, "Sfx\\Items\\Trap.wav", 0 }, + { 2u, "Sfx\\Misc\\Cast1.wav", 0 }, + { 2u, "Sfx\\Misc\\Cast10.wav", 0 }, + { 2u, "Sfx\\Misc\\Cast12.wav", 0 }, + { 2u, "Sfx\\Misc\\Cast2.wav", 0 }, + { 2u, "Sfx\\Misc\\Cast3.wav", 0 }, + { 2u, "Sfx\\Misc\\Cast4.wav", 0 }, + { 2u, "Sfx\\Misc\\Cast5.wav", 0 }, + { 2u, "Sfx\\Misc\\Cast6.wav", 0 }, + { 2u, "Sfx\\Misc\\Cast7.wav", 0 }, + { 2u, "Sfx\\Misc\\Cast8.wav", 0 }, + { 2u, "Sfx\\Misc\\Cast9.wav", 0 }, + { 2u, "Sfx\\Misc\\Healing.wav", 0 }, + { 2u, "Sfx\\Misc\\Repair.wav", 0 }, + { 2u, "Sfx\\Misc\\Acids1.wav", 0 }, + { 2u, "Sfx\\Misc\\Acids2.wav", 0 }, + { 2u, "Sfx\\Misc\\Apoc.wav", 0 }, + { 2u, "Sfx\\Misc\\Arrowall.wav", 0 }, + { 2u, "Sfx\\Misc\\Bldboil.wav", 0 }, + { 2u, "Sfx\\Misc\\Blodstar.wav", 0 }, + { 2u, "Sfx\\Misc\\Blsimpt.wav", 0 }, + { 2u, "Sfx\\Misc\\Bonesp.wav", 0 }, + { 2u, "Sfx\\Misc\\Bsimpct.wav", 0 }, + { 2u, "Sfx\\Misc\\Caldron.wav", 0 }, + { 2u, "Sfx\\Misc\\Cbolt.wav", 0 }, + { 2u, "Sfx\\Misc\\Chltning.wav", 0 }, + { 2u, "Sfx\\Misc\\DSerp.wav", 0 }, + { 2u, "Sfx\\Misc\\Elecimp1.wav", 0 }, + { 2u, "Sfx\\Misc\\Elementl.wav", 0 }, + { 2u, "Sfx\\Misc\\Ethereal.wav", 0 }, + { 2u, "Sfx\\Misc\\Fball.wav", 0 }, + { 2u, "Sfx\\Misc\\Fbolt1.wav", 0 }, + { 2u, "Sfx\\Misc\\Fbolt2.wav", 0 }, + { 2u, "Sfx\\Misc\\Firimp1.wav", 0 }, + { 2u, "Sfx\\Misc\\Firimp2.wav", 0 }, + { 2u, "Sfx\\Misc\\Flamwave.wav", 0 }, + { 2u, "Sfx\\Misc\\Flash.wav", 0 }, + { 2u, "Sfx\\Misc\\Fountain.wav", 0 }, + { 2u, "Sfx\\Misc\\Golum.wav", 0 }, + { 2u, "Sfx\\Misc\\Golumded.wav", 0 }, + { 2u, "Sfx\\Misc\\Gshrine.wav", 0 }, + { 2u, "Sfx\\Misc\\Guard.wav", 0 }, + { 2u, "Sfx\\Misc\\Grdlanch.wav", 0 }, + { 2u, "Sfx\\Misc\\Holybolt.wav", 0 }, + { 2u, "Sfx\\Misc\\Hyper.wav", 0 }, + { 2u, "Sfx\\Misc\\Infravis.wav", 0 }, + { 2u, "Sfx\\Misc\\Invisibl.wav", 0 }, + { 2u, "Sfx\\Misc\\Invpot.wav", 0 }, + { 2u, "Sfx\\Misc\\Lning1.wav", 0 }, + { 2u, "Sfx\\Misc\\Ltning.wav", 0 }, + { 2u, "Sfx\\Misc\\Mshield.wav", 0 }, + { 2u, "Sfx\\Misc\\Nova.wav", 0 }, + { 2u, "Sfx\\Misc\\Portal.wav", 0 }, + { 2u, "Sfx\\Misc\\Puddle.wav", 0 }, + { 2u, "Sfx\\Misc\\Resur.wav", 0 }, + { 2u, "Sfx\\Misc\\Scurse.wav", 0 }, + { 2u, "Sfx\\Misc\\Scurimp.wav", 0 }, + { 2u, "Sfx\\Misc\\Sentinel.wav", 0 }, + { 2u, "Sfx\\Misc\\Shatter.wav", 0 }, + { 2u, "Sfx\\Misc\\Soulfire.wav", 0 }, + { 2u, "Sfx\\Misc\\Spoutlop.wav", 0 }, + { 2u, "Sfx\\Misc\\Spoutstr.wav", 0 }, + { 2u, "Sfx\\Misc\\Storm.wav", 0 }, + { 2u, "Sfx\\Misc\\Trapdis.wav", 0 }, + { 2u, "Sfx\\Misc\\Teleport.wav", 0 }, + { 2u, "Sfx\\Misc\\Vtheft.wav", 0 }, + { 2u, "Sfx\\Misc\\Wallloop.wav", 0 }, + { 2u, "Sfx\\Misc\\Wallstrt.wav", 0 }, + { 1u, "Sfx\\Towners\\Bmaid01.wav", 0 }, + { 1u, "Sfx\\Towners\\Bmaid02.wav", 0 }, + { 1u, "Sfx\\Towners\\Bmaid03.wav", 0 }, + { 1u, "Sfx\\Towners\\Bmaid04.wav", 0 }, + { 1u, "Sfx\\Towners\\Bmaid05.wav", 0 }, + { 1u, "Sfx\\Towners\\Bmaid06.wav", 0 }, + { 1u, "Sfx\\Towners\\Bmaid07.wav", 0 }, + { 1u, "Sfx\\Towners\\Bmaid08.wav", 0 }, + { 1u, "Sfx\\Towners\\Bmaid09.wav", 0 }, + { 1u, "Sfx\\Towners\\Bmaid10.wav", 0 }, + { 1u, "Sfx\\Towners\\Bmaid11.wav", 0 }, + { 1u, "Sfx\\Towners\\Bmaid12.wav", 0 }, + { 1u, "Sfx\\Towners\\Bmaid13.wav", 0 }, + { 1u, "Sfx\\Towners\\Bmaid14.wav", 0 }, + { 1u, "Sfx\\Towners\\Bmaid15.wav", 0 }, + { 1u, "Sfx\\Towners\\Bmaid16.wav", 0 }, + { 1u, "Sfx\\Towners\\Bmaid17.wav", 0 }, + { 1u, "Sfx\\Towners\\Bmaid18.wav", 0 }, + { 1u, "Sfx\\Towners\\Bmaid19.wav", 0 }, + { 1u, "Sfx\\Towners\\Bmaid20.wav", 0 }, + { 1u, "Sfx\\Towners\\Bmaid21.wav", 0 }, + { 1u, "Sfx\\Towners\\Bmaid22.wav", 0 }, + { 1u, "Sfx\\Towners\\Bmaid23.wav", 0 }, + { 1u, "Sfx\\Towners\\Bmaid24.wav", 0 }, + { 1u, "Sfx\\Towners\\Bmaid25.wav", 0 }, + { 1u, "Sfx\\Towners\\Bmaid26.wav", 0 }, + { 1u, "Sfx\\Towners\\Bmaid27.wav", 0 }, + { 1u, "Sfx\\Towners\\Bmaid28.wav", 0 }, + { 1u, "Sfx\\Towners\\Bmaid29.wav", 0 }, + { 1u, "Sfx\\Towners\\Bmaid30.wav", 0 }, + { 1u, "Sfx\\Towners\\Bmaid31.wav", 0 }, + { 1u, "Sfx\\Towners\\Bmaid32.wav", 0 }, + { 1u, "Sfx\\Towners\\Bmaid33.wav", 0 }, + { 1u, "Sfx\\Towners\\Bmaid34.wav", 0 }, + { 1u, "Sfx\\Towners\\Bmaid35.wav", 0 }, + { 1u, "Sfx\\Towners\\Bmaid36.wav", 0 }, + { 1u, "Sfx\\Towners\\Bmaid37.wav", 0 }, + { 1u, "Sfx\\Towners\\Bmaid38.wav", 0 }, + { 1u, "Sfx\\Towners\\Bmaid39.wav", 0 }, + { 1u, "Sfx\\Towners\\Bmaid40.wav", 0 }, + { 1u, "Sfx\\Towners\\Bsmith01.wav", 0 }, + { 1u, "Sfx\\Towners\\Bsmith02.wav", 0 }, + { 1u, "Sfx\\Towners\\Bsmith03.wav", 0 }, + { 1u, "Sfx\\Towners\\Bsmith04.wav", 0 }, + { 1u, "Sfx\\Towners\\Bsmith05.wav", 0 }, + { 1u, "Sfx\\Towners\\Bsmith06.wav", 0 }, + { 1u, "Sfx\\Towners\\Bsmith07.wav", 0 }, + { 1u, "Sfx\\Towners\\Bsmith08.wav", 0 }, + { 1u, "Sfx\\Towners\\Bsmith09.wav", 0 }, + { 1u, "Sfx\\Towners\\Bsmith10.wav", 0 }, + { 1u, "Sfx\\Towners\\Bsmith11.wav", 0 }, + { 1u, "Sfx\\Towners\\Bsmith12.wav", 0 }, + { 1u, "Sfx\\Towners\\Bsmith13.wav", 0 }, + { 1u, "Sfx\\Towners\\Bsmith14.wav", 0 }, + { 1u, "Sfx\\Towners\\Bsmith15.wav", 0 }, + { 1u, "Sfx\\Towners\\Bsmith16.wav", 0 }, + { 1u, "Sfx\\Towners\\Bsmith17.wav", 0 }, + { 1u, "Sfx\\Towners\\Bsmith18.wav", 0 }, + { 1u, "Sfx\\Towners\\Bsmith19.wav", 0 }, + { 1u, "Sfx\\Towners\\Bsmith20.wav", 0 }, + { 1u, "Sfx\\Towners\\Bsmith21.wav", 0 }, + { 1u, "Sfx\\Towners\\Bsmith22.wav", 0 }, + { 1u, "Sfx\\Towners\\Bsmith23.wav", 0 }, + { 1u, "Sfx\\Towners\\Bsmith24.wav", 0 }, + { 1u, "Sfx\\Towners\\Bsmith25.wav", 0 }, + { 1u, "Sfx\\Towners\\Bsmith26.wav", 0 }, + { 1u, "Sfx\\Towners\\Bsmith27.wav", 0 }, + { 1u, "Sfx\\Towners\\Bsmith28.wav", 0 }, + { 1u, "Sfx\\Towners\\Bsmith29.wav", 0 }, + { 1u, "Sfx\\Towners\\Bsmith30.wav", 0 }, + { 1u, "Sfx\\Towners\\Bsmith31.wav", 0 }, + { 1u, "Sfx\\Towners\\Bsmith32.wav", 0 }, + { 1u, "Sfx\\Towners\\Bsmith33.wav", 0 }, + { 1u, "Sfx\\Towners\\Bsmith34.wav", 0 }, + { 1u, "Sfx\\Towners\\Bsmith35.wav", 0 }, + { 1u, "Sfx\\Towners\\Bsmith36.wav", 0 }, + { 1u, "Sfx\\Towners\\Bsmith37.wav", 0 }, + { 1u, "Sfx\\Towners\\Bsmith38.wav", 0 }, + { 1u, "Sfx\\Towners\\Bsmith39.wav", 0 }, + { 1u, "Sfx\\Towners\\Bsmith40.wav", 0 }, + { 1u, "Sfx\\Towners\\Bsmith41.wav", 0 }, + { 1u, "Sfx\\Towners\\Bsmith42.wav", 0 }, + { 1u, "Sfx\\Towners\\Bsmith43.wav", 0 }, + { 1u, "Sfx\\Towners\\Bsmith44.wav", 0 }, + { 1u, "Sfx\\Towners\\Bsmith45.wav", 0 }, + { 1u, "Sfx\\Towners\\Bsmith46.wav", 0 }, + { 1u, "Sfx\\Towners\\Bsmith47.wav", 0 }, + { 1u, "Sfx\\Towners\\Bsmith48.wav", 0 }, + { 1u, "Sfx\\Towners\\Bsmith49.wav", 0 }, + { 1u, "Sfx\\Towners\\Bsmith50.wav", 0 }, + { 1u, "Sfx\\Towners\\Bsmith51.wav", 0 }, + { 1u, "Sfx\\Towners\\Bsmith52.wav", 0 }, + { 1u, "Sfx\\Towners\\Bsmith53.wav", 0 }, + { 1u, "Sfx\\Towners\\Bsmith54.wav", 0 }, + { 1u, "Sfx\\Towners\\Bsmith55.wav", 0 }, + { 1u, "Sfx\\Towners\\Bsmith56.wav", 0 }, + { 0u, "Sfx\\Towners\\Cow1.wav", 0 }, + { 0u, "Sfx\\Towners\\Cow2.wav", 0 }, + { 1u, "Sfx\\Towners\\Deadguy2.wav", 0 }, + { 1u, "Sfx\\Towners\\Drunk01.wav", 0 }, + { 1u, "Sfx\\Towners\\Drunk02.wav", 0 }, + { 1u, "Sfx\\Towners\\Drunk03.wav", 0 }, + { 1u, "Sfx\\Towners\\Drunk04.wav", 0 }, + { 1u, "Sfx\\Towners\\Drunk05.wav", 0 }, + { 1u, "Sfx\\Towners\\Drunk06.wav", 0 }, + { 1u, "Sfx\\Towners\\Drunk07.wav", 0 }, + { 1u, "Sfx\\Towners\\Drunk08.wav", 0 }, + { 1u, "Sfx\\Towners\\Drunk09.wav", 0 }, + { 1u, "Sfx\\Towners\\Drunk10.wav", 0 }, + { 1u, "Sfx\\Towners\\Drunk11.wav", 0 }, + { 1u, "Sfx\\Towners\\Drunk12.wav", 0 }, + { 1u, "Sfx\\Towners\\Drunk13.wav", 0 }, + { 1u, "Sfx\\Towners\\Drunk14.wav", 0 }, + { 1u, "Sfx\\Towners\\Drunk15.wav", 0 }, + { 1u, "Sfx\\Towners\\Drunk16.wav", 0 }, + { 1u, "Sfx\\Towners\\Drunk17.wav", 0 }, + { 1u, "Sfx\\Towners\\Drunk18.wav", 0 }, + { 1u, "Sfx\\Towners\\Drunk19.wav", 0 }, + { 1u, "Sfx\\Towners\\Drunk20.wav", 0 }, + { 1u, "Sfx\\Towners\\Drunk21.wav", 0 }, + { 1u, "Sfx\\Towners\\Drunk22.wav", 0 }, + { 1u, "Sfx\\Towners\\Drunk23.wav", 0 }, + { 1u, "Sfx\\Towners\\Drunk24.wav", 0 }, + { 1u, "Sfx\\Towners\\Drunk25.wav", 0 }, + { 1u, "Sfx\\Towners\\Drunk26.wav", 0 }, + { 1u, "Sfx\\Towners\\Drunk27.wav", 0 }, + { 1u, "Sfx\\Towners\\Drunk28.wav", 0 }, + { 1u, "Sfx\\Towners\\Drunk29.wav", 0 }, + { 1u, "Sfx\\Towners\\Drunk30.wav", 0 }, + { 1u, "Sfx\\Towners\\Drunk31.wav", 0 }, + { 1u, "Sfx\\Towners\\Drunk32.wav", 0 }, + { 1u, "Sfx\\Towners\\Drunk33.wav", 0 }, + { 1u, "Sfx\\Towners\\Drunk34.wav", 0 }, + { 1u, "Sfx\\Towners\\Drunk35.wav", 0 }, + { 1u, "Sfx\\Towners\\Healer01.wav", 0 }, + { 1u, "Sfx\\Towners\\Healer02.wav", 0 }, + { 1u, "Sfx\\Towners\\Healer03.wav", 0 }, + { 1u, "Sfx\\Towners\\Healer04.wav", 0 }, + { 1u, "Sfx\\Towners\\Healer05.wav", 0 }, + { 1u, "Sfx\\Towners\\Healer06.wav", 0 }, + { 1u, "Sfx\\Towners\\Healer07.wav", 0 }, + { 1u, "Sfx\\Towners\\Healer08.wav", 0 }, + { 1u, "Sfx\\Towners\\Healer09.wav", 0 }, + { 1u, "Sfx\\Towners\\Healer10.wav", 0 }, + { 1u, "Sfx\\Towners\\Healer11.wav", 0 }, + { 1u, "Sfx\\Towners\\Healer12.wav", 0 }, + { 1u, "Sfx\\Towners\\Healer13.wav", 0 }, + { 1u, "Sfx\\Towners\\Healer14.wav", 0 }, + { 1u, "Sfx\\Towners\\Healer15.wav", 0 }, + { 1u, "Sfx\\Towners\\Healer16.wav", 0 }, + { 1u, "Sfx\\Towners\\Healer17.wav", 0 }, + { 1u, "Sfx\\Towners\\Healer18.wav", 0 }, + { 1u, "Sfx\\Towners\\Healer19.wav", 0 }, + { 1u, "Sfx\\Towners\\Healer20.wav", 0 }, + { 1u, "Sfx\\Towners\\Healer21.wav", 0 }, + { 1u, "Sfx\\Towners\\Healer22.wav", 0 }, + { 1u, "Sfx\\Towners\\Healer23.wav", 0 }, + { 1u, "Sfx\\Towners\\Healer24.wav", 0 }, + { 1u, "Sfx\\Towners\\Healer25.wav", 0 }, + { 1u, "Sfx\\Towners\\Healer26.wav", 0 }, + { 1u, "Sfx\\Towners\\Healer27.wav", 0 }, + { 1u, "Sfx\\Towners\\Healer28.wav", 0 }, + { 1u, "Sfx\\Towners\\Healer29.wav", 0 }, + { 1u, "Sfx\\Towners\\Healer30.wav", 0 }, + { 1u, "Sfx\\Towners\\Healer31.wav", 0 }, + { 1u, "Sfx\\Towners\\Healer32.wav", 0 }, + { 1u, "Sfx\\Towners\\Healer33.wav", 0 }, + { 1u, "Sfx\\Towners\\Healer34.wav", 0 }, + { 1u, "Sfx\\Towners\\Healer35.wav", 0 }, + { 1u, "Sfx\\Towners\\Healer36.wav", 0 }, + { 1u, "Sfx\\Towners\\Healer37.wav", 0 }, + { 1u, "Sfx\\Towners\\Healer38.wav", 0 }, + { 1u, "Sfx\\Towners\\Healer39.wav", 0 }, + { 1u, "Sfx\\Towners\\Healer40.wav", 0 }, + { 1u, "Sfx\\Towners\\Healer41.wav", 0 }, + { 1u, "Sfx\\Towners\\Healer42.wav", 0 }, + { 1u, "Sfx\\Towners\\Healer43.wav", 0 }, + { 1u, "Sfx\\Towners\\Healer44.wav", 0 }, + { 1u, "Sfx\\Towners\\Healer45.wav", 0 }, + { 1u, "Sfx\\Towners\\Healer46.wav", 0 }, + { 1u, "Sfx\\Towners\\Healer47.wav", 0 }, + { 1u, "Sfx\\Towners\\Pegboy01.wav", 0 }, + { 1u, "Sfx\\Towners\\Pegboy02.wav", 0 }, + { 1u, "Sfx\\Towners\\Pegboy03.wav", 0 }, + { 1u, "Sfx\\Towners\\Pegboy04.wav", 0 }, + { 1u, "Sfx\\Towners\\Pegboy05.wav", 0 }, + { 1u, "Sfx\\Towners\\Pegboy06.wav", 0 }, + { 1u, "Sfx\\Towners\\Pegboy07.wav", 0 }, + { 1u, "Sfx\\Towners\\Pegboy08.wav", 0 }, + { 1u, "Sfx\\Towners\\Pegboy09.wav", 0 }, + { 1u, "Sfx\\Towners\\Pegboy10.wav", 0 }, + { 1u, "Sfx\\Towners\\Pegboy11.wav", 0 }, + { 1u, "Sfx\\Towners\\Pegboy12.wav", 0 }, + { 1u, "Sfx\\Towners\\Pegboy13.wav", 0 }, + { 1u, "Sfx\\Towners\\Pegboy14.wav", 0 }, + { 1u, "Sfx\\Towners\\Pegboy15.wav", 0 }, + { 1u, "Sfx\\Towners\\Pegboy16.wav", 0 }, + { 1u, "Sfx\\Towners\\Pegboy17.wav", 0 }, + { 1u, "Sfx\\Towners\\Pegboy18.wav", 0 }, + { 1u, "Sfx\\Towners\\Pegboy19.wav", 0 }, + { 1u, "Sfx\\Towners\\Pegboy20.wav", 0 }, + { 1u, "Sfx\\Towners\\Pegboy21.wav", 0 }, + { 1u, "Sfx\\Towners\\Pegboy22.wav", 0 }, + { 1u, "Sfx\\Towners\\Pegboy23.wav", 0 }, + { 1u, "Sfx\\Towners\\Pegboy24.wav", 0 }, + { 1u, "Sfx\\Towners\\Pegboy25.wav", 0 }, + { 1u, "Sfx\\Towners\\Pegboy26.wav", 0 }, + { 1u, "Sfx\\Towners\\Pegboy27.wav", 0 }, + { 1u, "Sfx\\Towners\\Pegboy28.wav", 0 }, + { 1u, "Sfx\\Towners\\Pegboy29.wav", 0 }, + { 1u, "Sfx\\Towners\\Pegboy30.wav", 0 }, + { 1u, "Sfx\\Towners\\Pegboy31.wav", 0 }, + { 1u, "Sfx\\Towners\\Pegboy32.wav", 0 }, + { 1u, "Sfx\\Towners\\Pegboy33.wav", 0 }, + { 1u, "Sfx\\Towners\\Pegboy34.wav", 0 }, + { 1u, "Sfx\\Towners\\Pegboy35.wav", 0 }, + { 1u, "Sfx\\Towners\\Pegboy36.wav", 0 }, + { 1u, "Sfx\\Towners\\Pegboy37.wav", 0 }, + { 1u, "Sfx\\Towners\\Pegboy38.wav", 0 }, + { 1u, "Sfx\\Towners\\Pegboy39.wav", 0 }, + { 1u, "Sfx\\Towners\\Pegboy40.wav", 0 }, + { 1u, "Sfx\\Towners\\Pegboy41.wav", 0 }, + { 1u, "Sfx\\Towners\\Pegboy42.wav", 0 }, + { 1u, "Sfx\\Towners\\Pegboy43.wav", 0 }, + { 1u, "Sfx\\Towners\\Priest00.wav", 0 }, + { 1u, "Sfx\\Towners\\Priest01.wav", 0 }, + { 1u, "Sfx\\Towners\\Priest02.wav", 0 }, + { 1u, "Sfx\\Towners\\Priest03.wav", 0 }, + { 1u, "Sfx\\Towners\\Priest04.wav", 0 }, + { 1u, "Sfx\\Towners\\Priest05.wav", 0 }, + { 1u, "Sfx\\Towners\\Priest06.wav", 0 }, + { 1u, "Sfx\\Towners\\Priest07.wav", 0 }, + { 1u, "Sfx\\Towners\\Storyt00.wav", 0 }, + { 1u, "Sfx\\Towners\\Storyt01.wav", 0 }, + { 1u, "Sfx\\Towners\\Storyt02.wav", 0 }, + { 1u, "Sfx\\Towners\\Storyt03.wav", 0 }, + { 1u, "Sfx\\Towners\\Storyt04.wav", 0 }, + { 1u, "Sfx\\Towners\\Storyt05.wav", 0 }, + { 1u, "Sfx\\Towners\\Storyt06.wav", 0 }, + { 1u, "Sfx\\Towners\\Storyt07.wav", 0 }, + { 1u, "Sfx\\Towners\\Storyt08.wav", 0 }, + { 1u, "Sfx\\Towners\\Storyt09.wav", 0 }, + { 1u, "Sfx\\Towners\\Storyt10.wav", 0 }, + { 1u, "Sfx\\Towners\\Storyt11.wav", 0 }, + { 1u, "Sfx\\Towners\\Storyt12.wav", 0 }, + { 1u, "Sfx\\Towners\\Storyt13.wav", 0 }, + { 1u, "Sfx\\Towners\\Storyt14.wav", 0 }, + { 1u, "Sfx\\Towners\\Storyt15.wav", 0 }, + { 1u, "Sfx\\Towners\\Storyt16.wav", 0 }, + { 1u, "Sfx\\Towners\\Storyt17.wav", 0 }, + { 1u, "Sfx\\Towners\\Storyt18.wav", 0 }, + { 1u, "Sfx\\Towners\\Storyt19.wav", 0 }, + { 1u, "Sfx\\Towners\\Storyt20.wav", 0 }, + { 1u, "Sfx\\Towners\\Storyt21.wav", 0 }, + { 1u, "Sfx\\Towners\\Storyt22.wav", 0 }, + { 1u, "Sfx\\Towners\\Storyt23.wav", 0 }, + { 1u, "Sfx\\Towners\\Storyt24.wav", 0 }, + { 1u, "Sfx\\Towners\\Storyt25.wav", 0 }, + { 1u, "Sfx\\Towners\\Storyt26.wav", 0 }, + { 1u, "Sfx\\Towners\\Storyt27.wav", 0 }, + { 1u, "Sfx\\Towners\\Storyt28.wav", 0 }, + { 1u, "Sfx\\Towners\\Storyt29.wav", 0 }, + { 1u, "Sfx\\Towners\\Storyt30.wav", 0 }, + { 1u, "Sfx\\Towners\\Storyt31.wav", 0 }, + { 1u, "Sfx\\Towners\\Storyt32.wav", 0 }, + { 1u, "Sfx\\Towners\\Storyt33.wav", 0 }, + { 1u, "Sfx\\Towners\\Storyt34.wav", 0 }, + { 1u, "Sfx\\Towners\\Storyt35.wav", 0 }, + { 1u, "Sfx\\Towners\\Storyt36.wav", 0 }, + { 1u, "Sfx\\Towners\\Storyt37.wav", 0 }, + { 1u, "Sfx\\Towners\\Storyt38.wav", 0 }, + { 1u, "Sfx\\Towners\\Tavown00.wav", 0 }, + { 1u, "Sfx\\Towners\\Tavown01.wav", 0 }, + { 1u, "Sfx\\Towners\\Tavown02.wav", 0 }, + { 1u, "Sfx\\Towners\\Tavown03.wav", 0 }, + { 1u, "Sfx\\Towners\\Tavown04.wav", 0 }, + { 1u, "Sfx\\Towners\\Tavown05.wav", 0 }, + { 1u, "Sfx\\Towners\\Tavown06.wav", 0 }, + { 1u, "Sfx\\Towners\\Tavown07.wav", 0 }, + { 1u, "Sfx\\Towners\\Tavown08.wav", 0 }, + { 1u, "Sfx\\Towners\\Tavown09.wav", 0 }, + { 1u, "Sfx\\Towners\\Tavown10.wav", 0 }, + { 1u, "Sfx\\Towners\\Tavown11.wav", 0 }, + { 1u, "Sfx\\Towners\\Tavown12.wav", 0 }, + { 1u, "Sfx\\Towners\\Tavown13.wav", 0 }, + { 1u, "Sfx\\Towners\\Tavown14.wav", 0 }, + { 1u, "Sfx\\Towners\\Tavown15.wav", 0 }, + { 1u, "Sfx\\Towners\\Tavown16.wav", 0 }, + { 1u, "Sfx\\Towners\\Tavown17.wav", 0 }, + { 1u, "Sfx\\Towners\\Tavown18.wav", 0 }, + { 1u, "Sfx\\Towners\\Tavown19.wav", 0 }, + { 1u, "Sfx\\Towners\\Tavown20.wav", 0 }, + { 1u, "Sfx\\Towners\\Tavown21.wav", 0 }, + { 1u, "Sfx\\Towners\\Tavown22.wav", 0 }, + { 1u, "Sfx\\Towners\\Tavown23.wav", 0 }, + { 1u, "Sfx\\Towners\\Tavown24.wav", 0 }, + { 1u, "Sfx\\Towners\\Tavown25.wav", 0 }, + { 1u, "Sfx\\Towners\\Tavown26.wav", 0 }, + { 1u, "Sfx\\Towners\\Tavown27.wav", 0 }, + { 1u, "Sfx\\Towners\\Tavown28.wav", 0 }, + { 1u, "Sfx\\Towners\\Tavown29.wav", 0 }, + { 1u, "Sfx\\Towners\\Tavown30.wav", 0 }, + { 1u, "Sfx\\Towners\\Tavown31.wav", 0 }, + { 1u, "Sfx\\Towners\\Tavown32.wav", 0 }, + { 1u, "Sfx\\Towners\\Tavown33.wav", 0 }, + { 1u, "Sfx\\Towners\\Tavown34.wav", 0 }, + { 1u, "Sfx\\Towners\\Tavown35.wav", 0 }, + { 1u, "Sfx\\Towners\\Tavown36.wav", 0 }, + { 1u, "Sfx\\Towners\\Tavown37.wav", 0 }, + { 1u, "Sfx\\Towners\\Tavown38.wav", 0 }, + { 1u, "Sfx\\Towners\\Tavown39.wav", 0 }, + { 1u, "Sfx\\Towners\\Tavown40.wav", 0 }, + { 1u, "Sfx\\Towners\\Tavown41.wav", 0 }, + { 1u, "Sfx\\Towners\\Tavown42.wav", 0 }, + { 1u, "Sfx\\Towners\\Tavown43.wav", 0 }, + { 1u, "Sfx\\Towners\\Tavown44.wav", 0 }, + { 1u, "Sfx\\Towners\\Tavown45.wav", 0 }, + { 1u, "Sfx\\Towners\\Witch01.wav", 0 }, + { 1u, "Sfx\\Towners\\Witch02.wav", 0 }, + { 1u, "Sfx\\Towners\\Witch03.wav", 0 }, + { 1u, "Sfx\\Towners\\Witch04.wav", 0 }, + { 1u, "Sfx\\Towners\\Witch05.wav", 0 }, + { 1u, "Sfx\\Towners\\Witch06.wav", 0 }, + { 1u, "Sfx\\Towners\\Witch07.wav", 0 }, + { 1u, "Sfx\\Towners\\Witch08.wav", 0 }, + { 1u, "Sfx\\Towners\\Witch09.wav", 0 }, + { 1u, "Sfx\\Towners\\Witch10.wav", 0 }, + { 1u, "Sfx\\Towners\\Witch11.wav", 0 }, + { 1u, "Sfx\\Towners\\Witch12.wav", 0 }, + { 1u, "Sfx\\Towners\\Witch13.wav", 0 }, + { 1u, "Sfx\\Towners\\Witch14.wav", 0 }, + { 1u, "Sfx\\Towners\\Witch15.wav", 0 }, + { 1u, "Sfx\\Towners\\Witch16.wav", 0 }, + { 1u, "Sfx\\Towners\\Witch17.wav", 0 }, + { 1u, "Sfx\\Towners\\Witch18.wav", 0 }, + { 1u, "Sfx\\Towners\\Witch19.wav", 0 }, + { 1u, "Sfx\\Towners\\Witch20.wav", 0 }, + { 1u, "Sfx\\Towners\\Witch21.wav", 0 }, + { 1u, "Sfx\\Towners\\Witch22.wav", 0 }, + { 1u, "Sfx\\Towners\\Witch23.wav", 0 }, + { 1u, "Sfx\\Towners\\Witch24.wav", 0 }, + { 1u, "Sfx\\Towners\\Witch25.wav", 0 }, + { 1u, "Sfx\\Towners\\Witch26.wav", 0 }, + { 1u, "Sfx\\Towners\\Witch27.wav", 0 }, + { 1u, "Sfx\\Towners\\Witch28.wav", 0 }, + { 1u, "Sfx\\Towners\\Witch29.wav", 0 }, + { 1u, "Sfx\\Towners\\Witch30.wav", 0 }, + { 1u, "Sfx\\Towners\\Witch31.wav", 0 }, + { 1u, "Sfx\\Towners\\Witch32.wav", 0 }, + { 1u, "Sfx\\Towners\\Witch33.wav", 0 }, + { 1u, "Sfx\\Towners\\Witch34.wav", 0 }, + { 1u, "Sfx\\Towners\\Witch35.wav", 0 }, + { 1u, "Sfx\\Towners\\Witch36.wav", 0 }, + { 1u, "Sfx\\Towners\\Witch37.wav", 0 }, + { 1u, "Sfx\\Towners\\Witch38.wav", 0 }, + { 1u, "Sfx\\Towners\\Witch39.wav", 0 }, + { 1u, "Sfx\\Towners\\Witch40.wav", 0 }, + { 1u, "Sfx\\Towners\\Witch41.wav", 0 }, + { 1u, "Sfx\\Towners\\Witch42.wav", 0 }, + { 1u, "Sfx\\Towners\\Witch43.wav", 0 }, + { 1u, "Sfx\\Towners\\Witch44.wav", 0 }, + { 1u, "Sfx\\Towners\\Witch45.wav", 0 }, + { 1u, "Sfx\\Towners\\Witch46.wav", 0 }, + { 1u, "Sfx\\Towners\\Witch47.wav", 0 }, + { 1u, "Sfx\\Towners\\Witch48.wav", 0 }, + { 1u, "Sfx\\Towners\\Witch49.wav", 0 }, + { 1u, "Sfx\\Towners\\Witch50.wav", 0 }, + { 1u, "Sfx\\Towners\\Wound01.wav", 0 }, + { 65u, "Sfx\\Sorceror\\Mage01.wav", 0 }, + { 65u, "Sfx\\Sorceror\\Mage02.wav", 0 }, + { 65u, "Sfx\\Sorceror\\Mage03.wav", 0 }, + { 65u, "Sfx\\Sorceror\\Mage04.wav", 0 }, + { 65u, "Sfx\\Sorceror\\Mage05.wav", 0 }, + { 65u, "Sfx\\Sorceror\\Mage06.wav", 0 }, + { 65u, "Sfx\\Sorceror\\Mage07.wav", 0 }, + { 65u, "Sfx\\Sorceror\\Mage08.wav", 0 }, + { 65u, "Sfx\\Sorceror\\Mage09.wav", 0 }, + { 65u, "Sfx\\Sorceror\\Mage10.wav", 0 }, + { 65u, "Sfx\\Sorceror\\Mage11.wav", 0 }, + { 65u, "Sfx\\Sorceror\\Mage12.wav", 0 }, + { 64u, "Sfx\\Sorceror\\Mage13.wav", 0 }, + { 64u, "Sfx\\Sorceror\\Mage14.wav", 0 }, + { 64u, "Sfx\\Sorceror\\Mage15.wav", 0 }, + { 64u, "Sfx\\Sorceror\\Mage16.wav", 0 }, + { 64u, "Sfx\\Sorceror\\Mage17.wav", 0 }, + { 64u, "Sfx\\Sorceror\\Mage18.wav", 0 }, + { 64u, "Sfx\\Sorceror\\Mage19.wav", 0 }, + { 64u, "Sfx\\Sorceror\\Mage20.wav", 0 }, + { 64u, "Sfx\\Sorceror\\Mage21.wav", 0 }, + { 64u, "Sfx\\Sorceror\\Mage22.wav", 0 }, + { 64u, "Sfx\\Sorceror\\Mage23.wav", 0 }, + { 64u, "Sfx\\Sorceror\\Mage24.wav", 0 }, + { 64u, "Sfx\\Sorceror\\Mage25.wav", 0 }, + { 64u, "Sfx\\Sorceror\\Mage26.wav", 0 }, + { 64u, "Sfx\\Sorceror\\Mage27.wav", 0 }, + { 64u, "Sfx\\Sorceror\\Mage28.wav", 0 }, + { 64u, "Sfx\\Sorceror\\Mage29.wav", 0 }, + { 64u, "Sfx\\Sorceror\\Mage30.wav", 0 }, + { 64u, "Sfx\\Sorceror\\Mage31.wav", 0 }, + { 64u, "Sfx\\Sorceror\\Mage32.wav", 0 }, + { 64u, "Sfx\\Sorceror\\Mage33.wav", 0 }, + { 64u, "Sfx\\Sorceror\\Mage34.wav", 0 }, + { 64u, "Sfx\\Sorceror\\Mage35.wav", 0 }, + { 64u, "Sfx\\Sorceror\\Mage36.wav", 0 }, + { 64u, "Sfx\\Sorceror\\Mage37.wav", 0 }, + { 64u, "Sfx\\Sorceror\\Mage38.wav", 0 }, + { 64u, "Sfx\\Sorceror\\Mage39.wav", 0 }, + { 64u, "Sfx\\Sorceror\\Mage40.wav", 0 }, + { 64u, "Sfx\\Sorceror\\Mage41.wav", 0 }, + { 64u, "Sfx\\Sorceror\\Mage42.wav", 0 }, + { 64u, "Sfx\\Sorceror\\Mage43.wav", 0 }, + { 64u, "Sfx\\Sorceror\\Mage44.wav", 0 }, + { 64u, "Sfx\\Sorceror\\Mage45.wav", 0 }, + { 64u, "Sfx\\Sorceror\\Mage46.wav", 0 }, + { 64u, "Sfx\\Sorceror\\Mage47.wav", 0 }, + { 64u, "Sfx\\Sorceror\\Mage48.wav", 0 }, + { 64u, "Sfx\\Sorceror\\Mage49.wav", 0 }, + { 64u, "Sfx\\Sorceror\\Mage50.wav", 0 }, + { 65u, "Sfx\\Sorceror\\Mage51.wav", 0 }, + { 65u, "Sfx\\Sorceror\\Mage52.wav", 0 }, + { 65u, "Sfx\\Sorceror\\Mage53.wav", 0 }, + { 65u, "Sfx\\Sorceror\\Mage54.wav", 0 }, + { 65u, "Sfx\\Sorceror\\Mage55.wav", 0 }, + { 65u, "Sfx\\Sorceror\\Mage56.wav", 0 }, + { 64u, "Sfx\\Sorceror\\Mage57.wav", 0 }, + { 65u, "Sfx\\Sorceror\\Mage58.wav", 0 }, + { 65u, "Sfx\\Sorceror\\Mage59.wav", 0 }, + { 65u, "Sfx\\Sorceror\\Mage60.wav", 0 }, + { 65u, "Sfx\\Sorceror\\Mage61.wav", 0 }, + { 65u, "Sfx\\Sorceror\\Mage62.wav", 0 }, + { 65u, "Sfx\\Sorceror\\Mage63.wav", 0 }, + { 64u, "Sfx\\Sorceror\\Mage64.wav", 0 }, + { 64u, "Sfx\\Sorceror\\Mage65.wav", 0 }, + { 64u, "Sfx\\Sorceror\\Mage66.wav", 0 }, + { 64u, "Sfx\\Sorceror\\Mage67.wav", 0 }, + { 64u, "Sfx\\Sorceror\\Mage68.wav", 0 }, + { 64u, "Sfx\\Sorceror\\Mage69.wav", 0 }, + { 64u, "Sfx\\Sorceror\\Mage69b.wav", 0 }, + { 64u, "Sfx\\Sorceror\\Mage70.wav", 0 }, + { 64u, "Sfx\\Sorceror\\Mage71.wav", 0 }, + { 64u, "Sfx\\Sorceror\\Mage72.wav", 0 }, + { 64u, "Sfx\\Sorceror\\Mage73.wav", 0 }, + { 64u, "Sfx\\Sorceror\\Mage74.wav", 0 }, + { 64u, "Sfx\\Sorceror\\Mage75.wav", 0 }, + { 64u, "Sfx\\Sorceror\\Mage76.wav", 0 }, + { 64u, "Sfx\\Sorceror\\Mage77.wav", 0 }, + { 64u, "Sfx\\Sorceror\\Mage78.wav", 0 }, + { 64u, "Sfx\\Sorceror\\Mage79.wav", 0 }, + { 65u, "Sfx\\Sorceror\\Mage80.wav", 0 }, + { 65u, "Sfx\\Sorceror\\Mage81.wav", 0 }, + { 65u, "Sfx\\Sorceror\\Mage82.wav", 0 }, + { 65u, "Sfx\\Sorceror\\Mage83.wav", 0 }, + { 65u, "Sfx\\Sorceror\\Mage84.wav", 0 }, + { 65u, "Sfx\\Sorceror\\Mage85.wav", 0 }, + { 65u, "Sfx\\Sorceror\\Mage86.wav", 0 }, + { 65u, "Sfx\\Sorceror\\Mage87.wav", 0 }, + { 65u, "Sfx\\Sorceror\\Mage88.wav", 0 }, + { 65u, "Sfx\\Sorceror\\Mage89.wav", 0 }, + { 65u, "Sfx\\Sorceror\\Mage90.wav", 0 }, + { 65u, "Sfx\\Sorceror\\Mage91.wav", 0 }, + { 65u, "Sfx\\Sorceror\\Mage92.wav", 0 }, + { 65u, "Sfx\\Sorceror\\Mage93.wav", 0 }, + { 65u, "Sfx\\Sorceror\\Mage94.wav", 0 }, + { 65u, "Sfx\\Sorceror\\Mage95.wav", 0 }, + { 65u, "Sfx\\Sorceror\\Mage96.wav", 0 }, + { 65u, "Sfx\\Sorceror\\Mage97.wav", 0 }, + { 65u, "Sfx\\Sorceror\\Mage98.wav", 0 }, + { 65u, "Sfx\\Sorceror\\Mage99.wav", 0 }, + { 65u, "Sfx\\Sorceror\\Mage100.wav", 0 }, + { 65u, "Sfx\\Sorceror\\Mage101.wav", 0 }, + { 65u, "Sfx\\Sorceror\\Mage102.wav", 0 }, + { 17u, "Sfx\\Rogue\\Rogue01.wav", 0 }, + { 17u, "Sfx\\Rogue\\Rogue02.wav", 0 }, + { 17u, "Sfx\\Rogue\\Rogue03.wav", 0 }, + { 17u, "Sfx\\Rogue\\Rogue04.wav", 0 }, + { 17u, "Sfx\\Rogue\\Rogue05.wav", 0 }, + { 17u, "Sfx\\Rogue\\Rogue06.wav", 0 }, + { 17u, "Sfx\\Rogue\\Rogue07.wav", 0 }, + { 17u, "Sfx\\Rogue\\Rogue08.wav", 0 }, + { 17u, "Sfx\\Rogue\\Rogue09.wav", 0 }, + { 17u, "Sfx\\Rogue\\Rogue10.wav", 0 }, + { 17u, "Sfx\\Rogue\\Rogue11.wav", 0 }, + { 17u, "Sfx\\Rogue\\Rogue12.wav", 0 }, + { 16u, "Sfx\\Rogue\\Rogue13.wav", 0 }, + { 16u, "Sfx\\Rogue\\Rogue14.wav", 0 }, + { 16u, "Sfx\\Rogue\\Rogue15.wav", 0 }, + { 16u, "Sfx\\Rogue\\Rogue16.wav", 0 }, + { 16u, "Sfx\\Rogue\\Rogue17.wav", 0 }, + { 16u, "Sfx\\Rogue\\Rogue18.wav", 0 }, + { 16u, "Sfx\\Rogue\\Rogue19.wav", 0 }, + { 16u, "Sfx\\Rogue\\Rogue20.wav", 0 }, + { 16u, "Sfx\\Rogue\\Rogue21.wav", 0 }, + { 16u, "Sfx\\Rogue\\Rogue22.wav", 0 }, + { 16u, "Sfx\\Rogue\\Rogue23.wav", 0 }, + { 16u, "Sfx\\Rogue\\Rogue24.wav", 0 }, + { 16u, "Sfx\\Rogue\\Rogue25.wav", 0 }, + { 16u, "Sfx\\Rogue\\Rogue26.wav", 0 }, + { 16u, "Sfx\\Rogue\\Rogue27.wav", 0 }, + { 16u, "Sfx\\Rogue\\Rogue28.wav", 0 }, + { 16u, "Sfx\\Rogue\\Rogue29.wav", 0 }, + { 16u, "Sfx\\Rogue\\Rogue30.wav", 0 }, + { 16u, "Sfx\\Rogue\\Rogue31.wav", 0 }, + { 16u, "Sfx\\Rogue\\Rogue32.wav", 0 }, + { 16u, "Sfx\\Rogue\\Rogue33.wav", 0 }, + { 16u, "Sfx\\Rogue\\Rogue34.wav", 0 }, + { 16u, "Sfx\\Rogue\\Rogue35.wav", 0 }, + { 16u, "Sfx\\Rogue\\Rogue36.wav", 0 }, + { 16u, "Sfx\\Rogue\\Rogue37.wav", 0 }, + { 16u, "Sfx\\Rogue\\Rogue38.wav", 0 }, + { 16u, "Sfx\\Rogue\\Rogue39.wav", 0 }, + { 16u, "Sfx\\Rogue\\Rogue40.wav", 0 }, + { 16u, "Sfx\\Rogue\\Rogue41.wav", 0 }, + { 16u, "Sfx\\Rogue\\Rogue42.wav", 0 }, + { 16u, "Sfx\\Rogue\\Rogue43.wav", 0 }, + { 16u, "Sfx\\Rogue\\Rogue44.wav", 0 }, + { 16u, "Sfx\\Rogue\\Rogue45.wav", 0 }, + { 16u, "Sfx\\Rogue\\Rogue46.wav", 0 }, + { 16u, "Sfx\\Rogue\\Rogue47.wav", 0 }, + { 16u, "Sfx\\Rogue\\Rogue48.wav", 0 }, + { 16u, "Sfx\\Rogue\\Rogue49.wav", 0 }, + { 16u, "Sfx\\Rogue\\Rogue50.wav", 0 }, + { 17u, "Sfx\\Rogue\\Rogue51.wav", 0 }, + { 17u, "Sfx\\Rogue\\Rogue52.wav", 0 }, + { 17u, "Sfx\\Rogue\\Rogue53.wav", 0 }, + { 17u, "Sfx\\Rogue\\Rogue54.wav", 0 }, + { 17u, "Sfx\\Rogue\\Rogue55.wav", 0 }, + { 17u, "Sfx\\Rogue\\Rogue56.wav", 0 }, + { 16u, "Sfx\\Rogue\\Rogue57.wav", 0 }, + { 17u, "Sfx\\Rogue\\Rogue58.wav", 0 }, + { 17u, "Sfx\\Rogue\\Rogue59.wav", 0 }, + { 17u, "Sfx\\Rogue\\Rogue60.wav", 0 }, + { 17u, "Sfx\\Rogue\\Rogue61.wav", 0 }, + { 17u, "Sfx\\Rogue\\Rogue62.wav", 0 }, + { 17u, "Sfx\\Rogue\\Rogue63.wav", 0 }, + { 16u, "Sfx\\Rogue\\Rogue64.wav", 0 }, + { 16u, "Sfx\\Rogue\\Rogue65.wav", 0 }, + { 16u, "Sfx\\Rogue\\Rogue66.wav", 0 }, + { 16u, "Sfx\\Rogue\\Rogue67.wav", 0 }, + { 16u, "Sfx\\Rogue\\Rogue68.wav", 0 }, + { 16u, "Sfx\\Rogue\\Rogue69.wav", 0 }, + { 16u, "Sfx\\Rogue\\Rogue69b.wav", 0 }, + { 16u, "Sfx\\Rogue\\Rogue70.wav", 0 }, + { 16u, "Sfx\\Rogue\\Rogue71.wav", 0 }, + { 16u, "Sfx\\Rogue\\Rogue72.wav", 0 }, + { 16u, "Sfx\\Rogue\\Rogue73.wav", 0 }, + { 16u, "Sfx\\Rogue\\Rogue74.wav", 0 }, + { 16u, "Sfx\\Rogue\\Rogue75.wav", 0 }, + { 16u, "Sfx\\Rogue\\Rogue76.wav", 0 }, + { 16u, "Sfx\\Rogue\\Rogue77.wav", 0 }, + { 16u, "Sfx\\Rogue\\Rogue78.wav", 0 }, + { 16u, "Sfx\\Rogue\\Rogue79.wav", 0 }, + { 17u, "Sfx\\Rogue\\Rogue80.wav", 0 }, + { 17u, "Sfx\\Rogue\\Rogue81.wav", 0 }, + { 17u, "Sfx\\Rogue\\Rogue82.wav", 0 }, + { 17u, "Sfx\\Rogue\\Rogue83.wav", 0 }, + { 17u, "Sfx\\Rogue\\Rogue84.wav", 0 }, + { 17u, "Sfx\\Rogue\\Rogue85.wav", 0 }, + { 17u, "Sfx\\Rogue\\Rogue86.wav", 0 }, + { 17u, "Sfx\\Rogue\\Rogue87.wav", 0 }, + { 17u, "Sfx\\Rogue\\Rogue88.wav", 0 }, + { 17u, "Sfx\\Rogue\\Rogue89.wav", 0 }, + { 17u, "Sfx\\Rogue\\Rogue90.wav", 0 }, + { 17u, "Sfx\\Rogue\\Rogue91.wav", 0 }, + { 17u, "Sfx\\Rogue\\Rogue92.wav", 0 }, + { 17u, "Sfx\\Rogue\\Rogue93.wav", 0 }, + { 17u, "Sfx\\Rogue\\Rogue94.wav", 0 }, + { 17u, "Sfx\\Rogue\\Rogue95.wav", 0 }, + { 17u, "Sfx\\Rogue\\Rogue96.wav", 0 }, + { 17u, "Sfx\\Rogue\\Rogue97.wav", 0 }, + { 17u, "Sfx\\Rogue\\Rogue98.wav", 0 }, + { 17u, "Sfx\\Rogue\\Rogue99.wav", 0 }, + { 17u, "Sfx\\Rogue\\Rogue100.wav", 0 }, + { 17u, "Sfx\\Rogue\\Rogue101.wav", 0 }, + { 17u, "Sfx\\Rogue\\Rogue102.wav", 0 }, + { 33u, "Sfx\\Warrior\\Warior01.wav", 0 }, + { 33u, "Sfx\\Warrior\\Warior02.wav", 0 }, + { 33u, "Sfx\\Warrior\\Warior03.wav", 0 }, + { 33u, "Sfx\\Warrior\\Warior04.wav", 0 }, + { 33u, "Sfx\\Warrior\\Warior05.wav", 0 }, + { 33u, "Sfx\\Warrior\\Warior06.wav", 0 }, + { 33u, "Sfx\\Warrior\\Warior07.wav", 0 }, + { 33u, "Sfx\\Warrior\\Warior08.wav", 0 }, + { 33u, "Sfx\\Warrior\\Warior09.wav", 0 }, + { 33u, "Sfx\\Warrior\\Warior10.wav", 0 }, + { 33u, "Sfx\\Warrior\\Warior11.wav", 0 }, + { 33u, "Sfx\\Warrior\\Warior12.wav", 0 }, + { 32u, "Sfx\\Warrior\\Warior13.wav", 0 }, + { 32u, "Sfx\\Warrior\\Warior14.wav", 0 }, + { 32u, "Sfx\\Warrior\\Wario14b.wav", 0 }, + { 32u, "Sfx\\Warrior\\Wario14c.wav", 0 }, + { 32u, "Sfx\\Warrior\\Warior15.wav", 0 }, + { 32u, "Sfx\\Warrior\\Wario15b.wav", 0 }, + { 32u, "Sfx\\Warrior\\Wario15c.wav", 0 }, + { 32u, "Sfx\\Warrior\\Warior16.wav", 0 }, + { 32u, "Sfx\\Warrior\\Wario16b.wav", 0 }, + { 32u, "Sfx\\Warrior\\Wario16c.wav", 0 }, + { 32u, "Sfx\\Warrior\\Warior17.wav", 0 }, + { 32u, "Sfx\\Warrior\\Warior18.wav", 0 }, + { 32u, "Sfx\\Warrior\\Warior19.wav", 0 }, + { 32u, "Sfx\\Warrior\\Warior20.wav", 0 }, + { 32u, "Sfx\\Warrior\\Warior21.wav", 0 }, + { 32u, "Sfx\\Warrior\\Warior22.wav", 0 }, + { 32u, "Sfx\\Warrior\\Warior23.wav", 0 }, + { 32u, "Sfx\\Warrior\\Warior24.wav", 0 }, + { 32u, "Sfx\\Warrior\\Warior25.wav", 0 }, + { 32u, "Sfx\\Warrior\\Warior26.wav", 0 }, + { 32u, "Sfx\\Warrior\\Warior27.wav", 0 }, + { 32u, "Sfx\\Warrior\\Warior28.wav", 0 }, + { 32u, "Sfx\\Warrior\\Warior29.wav", 0 }, + { 32u, "Sfx\\Warrior\\Warior30.wav", 0 }, + { 32u, "Sfx\\Warrior\\Warior31.wav", 0 }, + { 32u, "Sfx\\Warrior\\Warior32.wav", 0 }, + { 32u, "Sfx\\Warrior\\Warior33.wav", 0 }, + { 32u, "Sfx\\Warrior\\Warior34.wav", 0 }, + { 32u, "Sfx\\Warrior\\Warior35.wav", 0 }, + { 32u, "Sfx\\Warrior\\Warior36.wav", 0 }, + { 32u, "Sfx\\Warrior\\Warior37.wav", 0 }, + { 32u, "Sfx\\Warrior\\Warior38.wav", 0 }, + { 32u, "Sfx\\Warrior\\Warior39.wav", 0 }, + { 32u, "Sfx\\Warrior\\Warior40.wav", 0 }, + { 32u, "Sfx\\Warrior\\Warior41.wav", 0 }, + { 32u, "Sfx\\Warrior\\Warior42.wav", 0 }, + { 32u, "Sfx\\Warrior\\Warior43.wav", 0 }, + { 32u, "Sfx\\Warrior\\Warior44.wav", 0 }, + { 32u, "Sfx\\Warrior\\Warior45.wav", 0 }, + { 32u, "Sfx\\Warrior\\Warior46.wav", 0 }, + { 32u, "Sfx\\Warrior\\Warior47.wav", 0 }, + { 32u, "Sfx\\Warrior\\Warior48.wav", 0 }, + { 32u, "Sfx\\Warrior\\Warior49.wav", 0 }, + { 32u, "Sfx\\Warrior\\Warior50.wav", 0 }, + { 33u, "Sfx\\Warrior\\Warior51.wav", 0 }, + { 33u, "Sfx\\Warrior\\Warior52.wav", 0 }, + { 33u, "Sfx\\Warrior\\Warior53.wav", 0 }, + { 33u, "Sfx\\Warrior\\Warior54.wav", 0 }, + { 33u, "Sfx\\Warrior\\Warior55.wav", 0 }, + { 33u, "Sfx\\Warrior\\Warior56.wav", 0 }, + { 32u, "Sfx\\Warrior\\Warior57.wav", 0 }, + { 33u, "Sfx\\Warrior\\Warior58.wav", 0 }, + { 33u, "Sfx\\Warrior\\Warior59.wav", 0 }, + { 33u, "Sfx\\Warrior\\Warior60.wav", 0 }, + { 33u, "Sfx\\Warrior\\Warior61.wav", 0 }, + { 33u, "Sfx\\Warrior\\Warior62.wav", 0 }, + { 33u, "Sfx\\Warrior\\Warior63.wav", 0 }, + { 32u, "Sfx\\Warrior\\Warior64.wav", 0 }, + { 32u, "Sfx\\Warrior\\Warior65.wav", 0 }, + { 32u, "Sfx\\Warrior\\Warior66.wav", 0 }, + { 32u, "Sfx\\Warrior\\Warior67.wav", 0 }, + { 32u, "Sfx\\Warrior\\Warior68.wav", 0 }, + { 32u, "Sfx\\Warrior\\Warior69.wav", 0 }, + { 32u, "Sfx\\Warrior\\Wario69b.wav", 0 }, + { 32u, "Sfx\\Warrior\\Warior70.wav", 0 }, + { 32u, "Sfx\\Warrior\\Warior71.wav", 0 }, + { 32u, "Sfx\\Warrior\\Warior72.wav", 0 }, + { 32u, "Sfx\\Warrior\\Warior73.wav", 0 }, + { 32u, "Sfx\\Warrior\\Warior74.wav", 0 }, + { 32u, "Sfx\\Warrior\\Warior75.wav", 0 }, + { 32u, "Sfx\\Warrior\\Warior76.wav", 0 }, + { 32u, "Sfx\\Warrior\\Warior77.wav", 0 }, + { 32u, "Sfx\\Warrior\\Warior78.wav", 0 }, + { 32u, "Sfx\\Warrior\\Warior79.wav", 0 }, + { 33u, "Sfx\\Warrior\\Warior80.wav", 0 }, + { 33u, "Sfx\\Warrior\\Warior81.wav", 0 }, + { 33u, "Sfx\\Warrior\\Warior82.wav", 0 }, + { 33u, "Sfx\\Warrior\\Warior83.wav", 0 }, + { 33u, "Sfx\\Warrior\\Warior84.wav", 0 }, + { 33u, "Sfx\\Warrior\\Warior85.wav", 0 }, + { 33u, "Sfx\\Warrior\\Warior86.wav", 0 }, + { 33u, "Sfx\\Warrior\\Warior87.wav", 0 }, + { 33u, "Sfx\\Warrior\\Warior88.wav", 0 }, + { 33u, "Sfx\\Warrior\\Warior89.wav", 0 }, + { 33u, "Sfx\\Warrior\\Warior90.wav", 0 }, + { 33u, "Sfx\\Warrior\\Warior91.wav", 0 }, + { 33u, "Sfx\\Warrior\\Warior92.wav", 0 }, + { 33u, "Sfx\\Warrior\\Warior93.wav", 0 }, + { 33u, "Sfx\\Warrior\\Warior94.wav", 0 }, + { 33u, "Sfx\\Warrior\\Warior95.wav", 0 }, + { 33u, "Sfx\\Warrior\\Wario95b.wav", 0 }, + { 33u, "Sfx\\Warrior\\Wario95c.wav", 0 }, + { 33u, "Sfx\\Warrior\\Wario95d.wav", 0 }, + { 33u, "Sfx\\Warrior\\Wario95e.wav", 0 }, + { 33u, "Sfx\\Warrior\\Wario95f.wav", 0 }, + { 33u, "Sfx\\Warrior\\Wario96b.wav", 0 }, + { 33u, "Sfx\\Warrior\\Wario97.wav", 0 }, + { 33u, "Sfx\\Warrior\\Wario98.wav", 0 }, + { 33u, "Sfx\\Warrior\\Warior99.wav", 0 }, + { 33u, "Sfx\\Warrior\\Wario100.wav", 0 }, + { 33u, "Sfx\\Warrior\\Wario101.wav", 0 }, + { 33u, "Sfx\\Warrior\\Wario102.wav", 0 }, + { 1u, "Sfx\\Narrator\\Nar01.wav", 0 }, + { 1u, "Sfx\\Narrator\\Nar02.wav", 0 }, + { 1u, "Sfx\\Narrator\\Nar03.wav", 0 }, + { 1u, "Sfx\\Narrator\\Nar04.wav", 0 }, + { 1u, "Sfx\\Narrator\\Nar05.wav", 0 }, + { 1u, "Sfx\\Narrator\\Nar06.wav", 0 }, + { 1u, "Sfx\\Narrator\\Nar07.wav", 0 }, + { 1u, "Sfx\\Narrator\\Nar08.wav", 0 }, + { 1u, "Sfx\\Narrator\\Nar09.wav", 0 }, + { 1u, "Sfx\\Misc\\Lvl16int.wav", 0 }, + { 1u, "Sfx\\Monsters\\Butcher.wav", 0 }, + { 1u, "Sfx\\Monsters\\Garbud01.wav", 0 }, + { 1u, "Sfx\\Monsters\\Garbud02.wav", 0 }, + { 1u, "Sfx\\Monsters\\Garbud03.wav", 0 }, + { 1u, "Sfx\\Monsters\\Garbud04.wav", 0 }, + { 1u, "Sfx\\Monsters\\Izual01.wav", 0 }, + { 1u, "Sfx\\Monsters\\Lach01.wav", 0 }, + { 1u, "Sfx\\Monsters\\Lach02.wav", 0 }, + { 1u, "Sfx\\Monsters\\Lach03.wav", 0 }, + { 1u, "Sfx\\Monsters\\Laz01.wav", 0 }, + { 1u, "Sfx\\Monsters\\Laz02.wav", 0 }, + { 1u, "Sfx\\Monsters\\Sking01.wav", 0 }, + { 1u, "Sfx\\Monsters\\Snot01.wav", 0 }, + { 1u, "Sfx\\Monsters\\Snot02.wav", 0 }, + { 1u, "Sfx\\Monsters\\Snot03.wav", 0 }, + { 1u, "Sfx\\Monsters\\Warlrd01.wav", 0 }, + { 1u, "Sfx\\Monsters\\Wlock01.wav", 0 }, + { 1u, "Sfx\\Monsters\\Zhar01.wav", 0 }, + { 1u, "Sfx\\Monsters\\Zhar02.wav", 0 }, + { 1u, "Sfx\\Monsters\\DiabloD.wav", 0 } +}; +char *MsgStrings[44] = +{ + &empty_string, + "No automap available in town", + "No multiplayer functions in demo", + "Direct Sound Creation Failed", + "Not available in shareware version", + "Not enough space to save", + "No Pause in town", + "Copying to a hard disk is recommended", + "Multiplayer sync problem", + "No pause in multiplayer", + "Loading...", + "Saving...", + "Some are weakened as one grows strong", + "New strength is forged through destruction", + "Those who defend seldom attack", + "The sword of justice is swift and sharp", + "While the spirit is vigilant the body thrives", + "The powers of mana refocused renews", + "Time cannot diminish the power of steel", + "Magic is not always what it seems to be", + "What once was opened now is closed", + "Intensity comes at the cost of wisdom", + "Arcane power brings destruction", + "That which cannot be held cannot be harmed", + "Crimson and Azure become as the sun", + "Knowledge and wisdom at the cost of self", + "Drink and be refreshed", + "Wherever you go, there you are", + "Energy comes at the cost of wisdom", + "Riches abound when least expected", + "Where avarice fails, patience gains reward", + "Blessed by a benevolent companion!", + "The hands of men may be guided by fate", + "Strength is bolstered by heavenly faith", + "The essence of life flows from within", + "The way is made clear when viewed from above", + "Salvation comes at the cost of wisdom", + "Mysteries are revealed in the light of reason", + "Those who are last may yet be first", + "Generosity brings its own rewards", + "You must be at least level 8 to use this.", + "You must be at least level 13 to use this.", + "You must be at least level 17 to use this.", + "Arcane knowledge gained!" +}; +TMenuItem sgSingleMenu[6] = +{ + { 2147483648, "Save Game", &gamemenu_save_game }, + { 2147483648, "Options", &gamemenu_options }, + { 2147483648, "New Game", &gamemenu_new_game }, + { 2147483648, "Load Game", &gamemenu_load_game }, + { 2147483648, "Quit Diablo", &gamemenu_quit_game }, + { 2147483648, NULL, NULL } +}; +TMenuItem sgMultiMenu[5] = +{ + { 2147483648, "Options", &gamemenu_options }, + { 2147483648, "New Game", &gamemenu_new_game }, + { 2147483648, "Restart In Town", &gamemenu_restart_town }, + { 2147483648, "Quit Diablo", &gamemenu_quit_game }, + { 2147483648, NULL, NULL } +}; +TMenuItem sgOptionMenu[6] = +{ + { 3221225472, NULL, &gamemenu_music_volume }, + { 3221225472, NULL, &gamemenu_sound_volume }, + { 3221225472, "Gamma", &gamemenu_gamma }, + { 2147483648, NULL, &gamemenu_color_cycling }, + { 2147483648, "Previous Menu", &gamemenu_previous }, + { 2147483648, NULL, NULL } +}; +char *music_toggle_names[] = { "Music", "Music Disabled" }; +char *sound_toggle_names[] = { "Sound", "Sound Disabled" }; +char *color_cycling_toggle_names[] = { "Color Cycling Off", "Color Cycling On" }; +int AP2x2Tbl[10] = { 8, 28, 6, 26, 4, 24, 2, 22, 0, 20 }; // weak +ItemDataStruct AllItemsList[157] = +{ + { + 1, + 4u, + ILOC_UNEQUIPABLE, + 168, + 11u, + UITYPE_NONE, + "Gold", + NULL, + 1, + 0, + 0, + 0, + 0, + 0, + 0u, + 0u, + 0u, + 0, + 0, + 0, + 1, + 0, + 0 + }, + { + 0, + 1u, + ILOC_ONEHAND, + 64, + 1u, + UITYPE_NONE, + "Short Sword", + NULL, + 2, + 20, + 2, + 6, + 0, + 0, + 18u, + 0u, + 0u, + 0, + 0, + 0, + 0, + 50, + 50 + }, + { + 0, + 2u, + ILOC_ONEHAND, + 83, + 5u, + UITYPE_NONE, + "Buckler", + NULL, + 2, + 10, + 0, + 0, + 3, + 3, + 0u, + 0u, + 0u, + 0, + 0, + 0, + 0, + 50, + 50 + }, + { + 0, + 1u, + ILOC_ONEHAND, + 66, + 4u, + UITYPE_SPIKCLUB, + "Club", + NULL, + 1, + 20, + 1, + 6, + 0, + 0, + 0u, + 0u, + 0u, + 0, + 0, + 0, + 0, + 20, + 20 + }, + { + 0, + 1u, + ILOC_TWOHAND, + 118, + 3u, + UITYPE_NONE, + "Short Bow", + NULL, + 1, + 30, + 1, + 4, + 0, + 0, + 0u, + 0u, + 0u, + 0, + 0, + 0, + 0, + 100, + 100 + }, + { + 0, + 1u, + ILOC_TWOHAND, + 109, + 10u, + UITYPE_NONE, + "Short Staff of Charged Bolt", + NULL, + 1, + 25, + 2, + 4, + 0, + 0, + 0u, + 20u, + 0u, + 0, + 23, + 30, + 0, + 520, + 520 + }, + { + 0, + 1u, + ILOC_TWOHAND, + 106, + 2u, + UITYPE_CLEAVER, + "Cleaver", + NULL, + 10, + 10, + 4, + 24, + 0, + 0, + 0u, + 0u, + 0u, + 0, + 27, + 0, + 0, + 2000, + 2000 + }, + { + 0, + 2u, + ILOC_HELM, + 78, + 7u, + UITYPE_SKCROWN, + "The Undead Crown", + NULL, + 0, + 50, + 0, + 0, + 15, + 15, + 0u, + 0u, + 0u, + 2, + 27, + 0, + 0, + 10000, + 10000 + }, + { + 0, + 3u, + ILOC_RING, + 18, + 12u, + UITYPE_INFRARING, + "Empyrean Band", + NULL, + 0, + 0, + 0, + 0, + 0, + 0, + 0u, + 0u, + 0u, + 0, + 27, + 0, + 0, + 8000, + 8000 + }, + { + 0, + 5u, + ILOC_UNEQUIPABLE, + 76, + 0u, + UITYPE_NONE, + "Magic Rock", + NULL, + 0, + 0, + 0, + 0, + 0, + 0, + 0u, + 0u, + 0u, + 0, + 0, + 0, + 0, + 0, + 0 + }, + { + 0, + 3u, + ILOC_AMULET, + 44, + 13u, + UITYPE_OPTAMULET, + "Optic Amulet", + NULL, + 0, + 0, + 0, + 0, + 0, + 0, + 0u, + 0u, + 0u, + 0, + 27, + 0, + 0, + 5000, + 5000 + }, + { + 0, + 3u, + ILOC_RING, + 10, + 12u, + UITYPE_TRING, + "Ring of Truth", + NULL, + 0, + 0, + 0, + 0, + 0, + 0, + 0u, + 0u, + 0u, + 0, + 27, + 0, + 0, + 1000, + 1000 + }, + { + 0, + 5u, + ILOC_UNEQUIPABLE, + 126, + 0u, + UITYPE_NONE, + "Tavern Sign", + NULL, + 0, + 0, + 0, + 0, + 0, + 0, + 0u, + 0u, + 0u, + 0, + 0, + 0, + 0, + 0, + 0 + }, + { + 0, + 2u, + ILOC_HELM, + 93, + 7u, + UITYPE_HARCREST, + "Harlequin Crest", + NULL, + 0, + 15, + 0, + 0, + 0, + 0, + 0u, + 0u, + 0u, + 0, + 27, + 0, + 0, + 15, + 20 + }, + { + 0, + 2u, + ILOC_HELM, + 85, + 7u, + UITYPE_STEELVEIL, + "Veil of Steel", + NULL, + 0, + 60, + 0, + 0, + 18, + 18, + 0u, + 0u, + 0u, + 0, + 27, + 0, + 0, + 0, + 0 + }, + { + 0, + 3u, + ILOC_UNEQUIPABLE, + 17, + 0u, + UITYPE_ELIXIR, + "Golden Elixir", + NULL, + 15, + 0, + 0, + 0, + 0, + 0, + 0u, + 0u, + 0u, + 0, + 0, + 0, + 0, + 0, + 0 + }, + { + 0, + 5u, + ILOC_UNEQUIPABLE, + 140, + 0u, + UITYPE_NONE, + "Anvil of Fury", + NULL, + 0, + 0, + 0, + 0, + 0, + 0, + 0u, + 0u, + 0u, + 0, + 0, + 0, + 0, + 0, + 0 + }, + { + 0, + 5u, + ILOC_UNEQUIPABLE, + 89, + 0u, + UITYPE_NONE, + "Black Mushroom", + NULL, + 0, + 0, + 0, + 0, + 0, + 0, + 0u, + 0u, + 0u, + 0, + 0, + 0, + 0, + 0, + 0 + }, + { + 0, + 5u, + ILOC_UNEQUIPABLE, + 40, + 0u, + UITYPE_NONE, + "Brain", + NULL, + 0, + 0, + 0, + 0, + 0, + 0, + 0u, + 0u, + 0u, + 0, + 0, + 0, + 0, + 0, + 0 + }, + { + 0, + 5u, + ILOC_UNEQUIPABLE, + 97, + 0u, + UITYPE_NONE, + "Fungal Tome", + NULL, + 0, + 0, + 0, + 0, + 0, + 0, + 0u, + 0u, + 0u, + 0, + 0, + 0, + 0, + 0, + 0 + }, + { + 0, + 3u, + ILOC_UNEQUIPABLE, + 15, + 0u, + UITYPE_ELIXIR, + "Spectral Elixir", + NULL, + 15, + 0, + 0, + 0, + 0, + 0, + 0u, + 0u, + 0u, + 0, + 44, + 0, + 0, + 0, + 0 + }, + { + 0, + 5u, + ILOC_UNEQUIPABLE, + 25, + 0u, + UITYPE_NONE, + "Blood Stone", + NULL, + 0, + 0, + 0, + 0, + 0, + 0, + 0u, + 0u, + 0u, + 0, + 0, + 0, + 0, + 0, + 0 + }, + { + 0, + 5u, + ILOC_UNEQUIPABLE, + 96, + 0u, + UITYPE_MAPOFDOOM, + "Map of the Stars", + NULL, + 0, + 0, + 0, + 0, + 0, + 0, + 0u, + 0u, + 0u, + 0, + 42, + 0, + 1, + 0, + 0 + }, + { + 0, + 5u, + ILOC_UNEQUIPABLE, + 19, + 0u, + UITYPE_NONE, + "Heart", + NULL, + 0, + 0, + 0, + 0, + 0, + 0, + 0u, + 0u, + 0u, + 0, + 43, + 0, + 0, + 0, + 0 + }, + { + 0, + 3u, + ILOC_UNEQUIPABLE, + 32, + 0u, + UITYPE_NONE, + "Potion of Healing", + NULL, + 0, + 0, + 0, + 0, + 0, + 0, + 0u, + 0u, + 0u, + 0, + 3, + 0, + 1, + 50, + 50 + }, + { + 0, + 3u, + ILOC_UNEQUIPABLE, + 39, + 0u, + UITYPE_NONE, + "Potion of Mana", + NULL, + 0, + 0, + 0, + 0, + 0, + 0, + 0u, + 0u, + 0u, + 0, + 6, + 0, + 1, + 50, + 50 + }, + { + 0, + 3u, + ILOC_UNEQUIPABLE, + 1, + 0u, + UITYPE_NONE, + "Scroll of Identify", + NULL, + 1, + 0, + 0, + 0, + 0, + 0, + 0u, + 0u, + 0u, + 0, + 21, + 5, + 1, + 200, + 200 + }, + { + 0, + 3u, + ILOC_UNEQUIPABLE, + 1, + 0u, + UITYPE_NONE, + "Scroll of Town Portal", + NULL, + 4, + 0, + 0, + 0, + 0, + 0, + 0u, + 0u, + 0u, + 0, + 21, + 7, + 1, + 200, + 200 + }, + { + 0, + 2u, + ILOC_ARMOR, + 157, + 8u, + UITYPE_ARMOFVAL, + "Arkaine's Valor", + NULL, + 0, + 40, + 0, + 0, + 0, + 0, + 0u, + 0u, + 0u, + 0, + 27, + 0, + 0, + 0, + 0 + }, + { + 0, + 3u, + ILOC_UNEQUIPABLE, + 35, + 0u, + UITYPE_NONE, + "Potion of Full Healing", + NULL, + 1, + 0, + 0, + 0, + 0, + 0, + 0u, + 0u, + 0u, + 0, + 2, + 0, + 1, + 150, + 150 + }, + { + 0, + 3u, + ILOC_UNEQUIPABLE, + 0, + 0u, + UITYPE_NONE, + "Potion of Full Mana", + NULL, + 1, + 0, + 0, + 0, + 0, + 0, + 0u, + 0u, + 0u, + 0, + 7, + 0, + 1, + 150, + 150 + }, + { + 0, + 1u, + ILOC_ONEHAND, + 61, + 1u, + UITYPE_GRISWOLD, + "Griswold's Edge", + NULL, + 8, + 50, + 4, + 12, + 0, + 0, + 40u, + 0u, + 0u, + 0, + 27, + 0, + 0, + 750, + 750 + }, + { + 0, + 1u, + ILOC_ONEHAND, + 59, + 4u, + UITYPE_LGTFORGE, + "Lightforge", + NULL, + 2, + 32, + 1, + 8, + 0, + 0, + 16u, + 0u, + 0u, + 0, + 27, + 0, + 0, + 200, + 200 + }, + { + 0, + 3u, + ILOC_UNEQUIPABLE, + 155, + 0u, + UITYPE_LAZSTAFF, + "Staff of Lazarus", + NULL, + 0, + 0, + 0, + 0, + 0, + 0, + 0u, + 0u, + 0u, + 0, + 0, + 0, + 0, + 0, + 0 + }, + { + 0, + 3u, + ILOC_UNEQUIPABLE, + 1, + 0u, + UITYPE_NONE, + "Scroll of Resurrect", + NULL, + 1, + 0, + 0, + 0, + 0, + 0, + 0u, + 0u, + 0u, + 0, + 22, + 32, + 1, + 250, + 250 + }, + { + 0, + 0u, + ILOC_NONE, + 0, + 0u, + UITYPE_NONE, + NULL, + NULL, + 0, + 0, + 0, + 0, + 0, + 0, + 0u, + 0u, + 0u, + 0, + 0, + 0, + 0, + 0, + 0 + }, + { + 0, + 0u, + ILOC_NONE, + 0, + 0u, + UITYPE_NONE, + NULL, + NULL, + 0, + 0, + 0, + 0, + 0, + 0, + 0u, + 0u, + 0u, + 0, + 0, + 0, + 0, + 0, + 0 + }, + { + 0, + 0u, + ILOC_NONE, + 0, + 0u, + UITYPE_NONE, + NULL, + NULL, + 0, + 0, + 0, + 0, + 0, + 0, + 0u, + 0u, + 0u, + 0, + 0, + 0, + 0, + 0, + 0 + }, + { + 0, + 0u, + ILOC_NONE, + 0, + 0u, + UITYPE_NONE, + NULL, + NULL, + 0, + 0, + 0, + 0, + 0, + 0, + 0u, + 0u, + 0u, + 0, + 0, + 0, + 0, + 0, + 0 + }, + { + 0, + 0u, + ILOC_NONE, + 0, + 0u, + UITYPE_NONE, + NULL, + NULL, + 0, + 0, + 0, + 0, + 0, + 0, + 0u, + 0u, + 0u, + 0, + 0, + 0, + 0, + 0, + 0 + }, + { + 0, + 0u, + ILOC_NONE, + 0, + 0u, + UITYPE_NONE, + NULL, + NULL, + 0, + 0, + 0, + 0, + 0, + 0, + 0u, + 0u, + 0u, + 0, + 0, + 0, + 0, + 0, + 0 + }, + { + 0, + 0u, + ILOC_NONE, + 0, + 0u, + UITYPE_NONE, + NULL, + NULL, + 0, + 0, + 0, + 0, + 0, + 0, + 0u, + 0u, + 0u, + 0, + 0, + 0, + 0, + 0, + 0 + }, + { + 0, + 0u, + ILOC_NONE, + 0, + 0u, + UITYPE_NONE, + NULL, + NULL, + 0, + 0, + 0, + 0, + 0, + 0, + 0u, + 0u, + 0u, + 0, + 0, + 0, + 0, + 0, + 0 + }, + { + 0, + 0u, + ILOC_NONE, + 0, + 0u, + UITYPE_NONE, + NULL, + NULL, + 0, + 0, + 0, + 0, + 0, + 0, + 0u, + 0u, + 0u, + 0, + 0, + 0, + 0, + 0, + 0 + }, + { + 0, + 0u, + ILOC_NONE, + 0, + 0u, + UITYPE_NONE, + NULL, + NULL, + 0, + 0, + 0, + 0, + 0, + 0, + 0u, + 0u, + 0u, + 0, + 0, + 0, + 0, + 0, + 0 + }, + { + 0, + 0u, + ILOC_NONE, + 0, + 0u, + UITYPE_NONE, + NULL, + NULL, + 0, + 0, + 0, + 0, + 0, + 0, + 0u, + 0u, + 0u, + 0, + 0, + 0, + 0, + 0, + 0 + }, + { + 0, + 0u, + ILOC_NONE, + 0, + 0u, + UITYPE_NONE, + NULL, + NULL, + 0, + 0, + 0, + 0, + 0, + 0, + 0u, + 0u, + 0u, + 0, + 0, + 0, + 0, + 0, + 0 + }, + { + 0, + 0u, + ILOC_NONE, + 0, + 0u, + UITYPE_NONE, + NULL, + NULL, + 0, + 0, + 0, + 0, + 0, + 0, + 0u, + 0u, + 0u, + 0, + 0, + 0, + 0, + 0, + 0 + }, + { + 1, + 2u, + ILOC_HELM, + 91, + 7u, + UITYPE_NONE, + "Cap", + "Cap", + 1, + 15, + 0, + 0, + 1, + 3, + 0u, + 0u, + 0u, + 0, + 0, + 0, + 0, + 15, + 20 + }, + { + 1, + 2u, + ILOC_HELM, + 90, + 7u, + UITYPE_SKULLCAP, + "Skull Cap", + "Cap", + 4, + 20, + 0, + 0, + 2, + 4, + 0u, + 0u, + 0u, + 0, + 0, + 0, + 0, + 25, + 30 + }, + { + 1, + 2u, + ILOC_HELM, + 82, + 7u, + UITYPE_HELM, + "Helm", + "Helm", + 8, + 30, + 0, + 0, + 4, + 6, + 25u, + 0u, + 0u, + 0, + 0, + 0, + 0, + 40, + 70 + }, + { + 1, + 2u, + ILOC_HELM, + 75, + 7u, + UITYPE_NONE, + "Full Helm", + "Helm", + 12, + 35, + 0, + 0, + 6, + 8, + 35u, + 0u, + 0u, + 0, + 0, + 0, + 0, + 90, + 130 + }, + { + 1, + 2u, + ILOC_HELM, + 95, + 7u, + UITYPE_CROWN, + "Crown", + "Crown", + 16, + 40, + 0, + 0, + 8, + 12, + 0u, + 0u, + 0u, + 0, + 0, + 0, + 0, + 200, + 300 + }, + { + 1, + 2u, + ILOC_HELM, + 98, + 7u, + UITYPE_GREATHELM, + "Great Helm", + "Helm", + 20, + 60, + 0, + 0, + 10, + 15, + 50u, + 0u, + 0u, + 0, + 0, + 0, + 0, + 400, + 500 + }, + { + 1, + 2u, + ILOC_ARMOR, + 150, + 6u, + UITYPE_CAPE, + "Cape", + "Cape", + 1, + 12, + 0, + 0, + 1, + 5, + 0u, + 0u, + 0u, + 0, + 0, + 0, + 0, + 10, + 50 + }, + { + 1, + 2u, + ILOC_ARMOR, + 128, + 6u, + UITYPE_RAGS, + "Rags", + "Rags", + 1, + 6, + 0, + 0, + 2, + 6, + 0u, + 0u, + 0u, + 0, + 0, + 0, + 0, + 5, + 25 + }, + { + 1, + 2u, + ILOC_ARMOR, + 149, + 6u, + UITYPE_CLOAK, + "Cloak", + "Cloak", + 2, + 18, + 0, + 0, + 3, + 7, + 0u, + 0u, + 0u, + 0, + 0, + 0, + 0, + 40, + 70 + }, + { + 1, + 2u, + ILOC_ARMOR, + 137, + 6u, + UITYPE_ROBE, + "Robe", + "Robe", + 3, + 24, + 0, + 0, + 4, + 7, + 0u, + 0u, + 0u, + 0, + 0, + 0, + 0, + 75, + 125 + }, + { + 1, + 2u, + ILOC_ARMOR, + 129, + 6u, + UITYPE_NONE, + "Quilted Armor", + "Armor", + 4, + 30, + 0, + 0, + 7, + 10, + 0u, + 0u, + 0u, + 0, + 0, + 0, + 0, + 200, + 300 + }, + { + 1, + 2u, + ILOC_ARMOR, + 135, + 6u, + UITYPE_LEATHARMOR, + "Leather Armor", + "Armor", + 6, + 35, + 0, + 0, + 10, + 13, + 0u, + 0u, + 0u, + 0, + 0, + 0, + 0, + 300, + 400 + }, + { + 1, + 2u, + ILOC_ARMOR, + 127, + 6u, + UITYPE_NONE, + "Hard Leather Armor", + "Armor", + 7, + 40, + 0, + 0, + 11, + 14, + 0u, + 0u, + 0u, + 0, + 0, + 0, + 0, + 450, + 550 + }, + { + 1, + 2u, + ILOC_ARMOR, + 107, + 6u, + UITYPE_STUDARMOR, + "Studded Leather Armor", + "Armor", + 9, + 45, + 0, + 0, + 15, + 17, + 20u, + 0u, + 0u, + 0, + 0, + 0, + 0, + 700, + 800 + }, + { + 1, + 2u, + ILOC_ARMOR, + 154, + 8u, + UITYPE_NONE, + "Ring Mail", + "Mail", + 11, + 50, + 0, + 0, + 17, + 20, + 25u, + 0u, + 0u, + 0, + 0, + 0, + 0, + 900, + 1100 + }, + { + 1, + 2u, + ILOC_ARMOR, + 111, + 8u, + UITYPE_CHAINMAIL, + "Chain Mail", + "Mail", + 13, + 55, + 0, + 0, + 18, + 22, + 30u, + 0u, + 0u, + 0, + 0, + 0, + 0, + 1250, + 1750 + }, + { + 1, + 2u, + ILOC_ARMOR, + 114, + 8u, + UITYPE_NONE, + "Scale Mail", + "Mail", + 15, + 60, + 0, + 0, + 23, + 28, + 35u, + 0u, + 0u, + 0, + 0, + 0, + 0, + 2300, + 2800 + }, + { + 1, + 2u, + ILOC_ARMOR, + 153, + 9u, + UITYPE_BREASTPLATE, + "Breast Plate", + "Plate", + 16, + 80, + 0, + 0, + 20, + 24, + 40u, + 0u, + 0u, + 0, + 0, + 0, + 0, + 2800, + 3200 + }, + { + 1, + 2u, + ILOC_ARMOR, + 136, + 8u, + UITYPE_NONE, + "Splint Mail", + "Mail", + 17, + 65, + 0, + 0, + 30, + 35, + 40u, + 0u, + 0u, + 0, + 0, + 0, + 0, + 3250, + 3750 + }, + { + 1, + 2u, + ILOC_ARMOR, + 103, + 9u, + UITYPE_PLATEMAIL, + "Plate Mail", + "Plate", + 19, + 75, + 0, + 0, + 42, + 50, + 60u, + 0u, + 0u, + 0, + 0, + 0, + 0, + 4600, + 5400 + }, + { + 1, + 2u, + ILOC_ARMOR, + 103, + 9u, + UITYPE_NONE, + "Field Plate", + "Plate", + 21, + 80, + 0, + 0, + 40, + 45, + 65u, + 0u, + 0u, + 0, + 0, + 0, + 0, + 5800, + 6200 + }, + { + 1, + 2u, + ILOC_ARMOR, + 152, + 9u, + UITYPE_NONE, + "Gothic Plate", + "Plate", + 23, + 100, + 0, + 0, + 50, + 60, + 80u, + 0u, + 0u, + 0, + 0, + 0, + 0, + 8000, + 10000 + }, + { + 1, + 2u, + ILOC_ARMOR, + 151, + 9u, + UITYPE_FULLPLATE, + "Full Plate Mail", + "Plate", + 25, + 90, + 0, + 0, + 60, + 75, + 90u, + 0u, + 0u, + 0, + 0, + 0, + 0, + 6500, + 8000 + }, + { + 1, + 2u, + ILOC_ONEHAND, + 83, + 5u, + UITYPE_BUCKLER, + "Buckler", + "Shield", + 1, + 16, + 0, + 0, + 1, + 5, + 0u, + 0u, + 0u, + 0, + 0, + 0, + 0, + 30, + 70 + }, + { + 1, + 2u, + ILOC_ONEHAND, + 105, + 5u, + UITYPE_SMALLSHIELD, + "Small Shield", + "Shield", + 5, + 24, + 0, + 0, + 3, + 8, + 25u, + 0u, + 0u, + 0, + 0, + 0, + 0, + 90, + 130 + }, + { + 1, + 2u, + ILOC_ONEHAND, + 147, + 5u, + UITYPE_LARGESHIELD, + "Large Shield", + "Shield", + 9, + 32, + 0, + 0, + 5, + 10, + 40u, + 0u, + 0u, + 0, + 0, + 0, + 0, + 200, + 300 + }, + { + 1, + 2u, + ILOC_ONEHAND, + 113, + 5u, + UITYPE_KITESHIELD, + "Kite Shield", + "Shield", + 14, + 40, + 0, + 0, + 8, + 15, + 50u, + 0u, + 0u, + 0, + 0, + 0, + 0, + 400, + 700 + }, + { + 1, + 2u, + ILOC_ONEHAND, + 132, + 5u, + UITYPE_GOTHSHIELD, + "Tower Shield", + "Shield", + 20, + 50, + 0, + 0, + 12, + 20, + 60u, + 0u, + 0u, + 0, + 0, + 0, + 0, + 850, + 1200 + }, + { + 1, + 2u, + ILOC_ONEHAND, + 148, + 5u, + UITYPE_GOTHSHIELD, + "Gothic Shield", + "Shield", + 23, + 60, + 0, + 0, + 14, + 18, + 80u, + 0u, + 0u, + 0, + 0, + 0, + 0, + 2300, + 2700 + }, + { + 1, + 3u, + ILOC_UNEQUIPABLE, + 32, + 0u, + UITYPE_NONE, + "Potion of Healing", + NULL, + 1, + 0, + 0, + 0, + 0, + 0, + 0u, + 0u, + 0u, + 0, + 3, + 0, + 1, + 50, + 50 + }, + { + 1, + 3u, + ILOC_UNEQUIPABLE, + 35, + 0u, + UITYPE_NONE, + "Potion of Full Healing", + NULL, + 1, + 0, + 0, + 0, + 0, + 0, + 0u, + 0u, + 0u, + 0, + 2, + 0, + 1, + 150, + 150 + }, + { + 1, + 3u, + ILOC_UNEQUIPABLE, + 39, + 0u, + UITYPE_NONE, + "Potion of Mana", + NULL, + 1, + 0, + 0, + 0, + 0, + 0, + 0u, + 0u, + 0u, + 0, + 6, + 0, + 1, + 50, + 50 + }, + { + 1, + 3u, + ILOC_UNEQUIPABLE, + 0, + 0u, + UITYPE_NONE, + "Potion of Full Mana", + NULL, + 1, + 0, + 0, + 0, + 0, + 0, + 0u, + 0u, + 0u, + 0, + 7, + 0, + 1, + 150, + 150 + }, + { + 1, + 3u, + ILOC_UNEQUIPABLE, + 37, + 0u, + UITYPE_NONE, + "Potion of Rejuvenation", + NULL, + 3, + 0, + 0, + 0, + 0, + 0, + 0u, + 0u, + 0u, + 0, + 18, + 0, + 1, + 120, + 120 + }, + { + 1, + 3u, + ILOC_UNEQUIPABLE, + 33, + 0u, + UITYPE_NONE, + "Potion of Full Rejuvenation", + NULL, + 7, + 0, + 0, + 0, + 0, + 0, + 0u, + 0u, + 0u, + 0, + 19, + 0, + 1, + 600, + 600 + }, + { + 1, + 3u, + ILOC_UNEQUIPABLE, + 38, + 0u, + UITYPE_NONE, + "Elixir of Strength", + NULL, + 15, + 0, + 0, + 0, + 0, + 0, + 0u, + 0u, + 0u, + 0, + 10, + 0, + 1, + 5000, + 5000 + }, + { + 1, + 3u, + ILOC_UNEQUIPABLE, + 34, + 0u, + UITYPE_NONE, + "Elixir of Magic", + NULL, + 15, + 0, + 0, + 0, + 0, + 0, + 0u, + 0u, + 0u, + 0, + 11, + 0, + 1, + 5000, + 5000 + }, + { + 1, + 3u, + ILOC_UNEQUIPABLE, + 36, + 0u, + UITYPE_NONE, + "Elixir of Dexterity", + NULL, + 15, + 0, + 0, + 0, + 0, + 0, + 0u, + 0u, + 0u, + 0, + 12, + 0, + 1, + 5000, + 5000 + }, + { + 1, + 3u, + ILOC_UNEQUIPABLE, + 31, + 0u, + UITYPE_NONE, + "Elixir of Vitality", + NULL, + 20, + 0, + 0, + 0, + 0, + 0, + 0u, + 0u, + 0u, + 0, + 13, + 0, + 1, + 5000, + 5000 + }, + { + 1, + 3u, + ILOC_UNEQUIPABLE, + 1, + 0u, + UITYPE_NONE, + "Scroll of Healing", + NULL, + 1, + 0, + 0, + 0, + 0, + 0, + 0u, + 0u, + 0u, + 0, + 21, + 2, + 1, + 50, + 50 + }, + { + 1, + 3u, + ILOC_UNEQUIPABLE, + 1, + 0u, + UITYPE_NONE, + "Scroll of Lightning", + NULL, + 4, + 0, + 0, + 0, + 0, + 0, + 0u, + 0u, + 0u, + 0, + 22, + 3, + 1, + 150, + 150 + }, + { + 1, + 3u, + ILOC_UNEQUIPABLE, + 1, + 0u, + UITYPE_NONE, + "Scroll of Identify", + NULL, + 1, + 0, + 0, + 0, + 0, + 0, + 0u, + 0u, + 0u, + 0, + 21, + 5, + 1, + 100, + 100 + }, + { + 1, + 3u, + ILOC_UNEQUIPABLE, + 1, + 0u, + UITYPE_NONE, + "Scroll of Resurrect", + NULL, + 1, + 0, + 0, + 0, + 0, + 0, + 0u, + 0u, + 0u, + 0, + 22, + 32, + 1, + 250, + 250 + }, + { + 1, + 3u, + ILOC_UNEQUIPABLE, + 1, + 0u, + UITYPE_NONE, + "Scroll of Fire Wall", + NULL, + 4, + 0, + 0, + 0, + 0, + 0, + 0u, + 17u, + 0u, + 0, + 22, + 6, + 1, + 400, + 400 + }, + { + 1, + 3u, + ILOC_UNEQUIPABLE, + 1, + 0u, + UITYPE_NONE, + "Scroll of Inferno", + NULL, + 1, + 0, + 0, + 0, + 0, + 0, + 0u, + 19u, + 0u, + 0, + 22, + 20, + 1, + 100, + 100 + }, + { + 1, + 3u, + ILOC_UNEQUIPABLE, + 1, + 0u, + UITYPE_NONE, + "Scroll of Town Portal", + NULL, + 4, + 0, + 0, + 0, + 0, + 0, + 0u, + 0u, + 0u, + 0, + 21, + 7, + 1, + 200, + 200 + }, + { + 1, + 3u, + ILOC_UNEQUIPABLE, + 1, + 0u, + UITYPE_NONE, + "Scroll of Flash", + NULL, + 6, + 0, + 0, + 0, + 0, + 0, + 0u, + 21u, + 0u, + 0, + 22, + 4, + 1, + 500, + 500 + }, + { + 1, + 3u, + ILOC_UNEQUIPABLE, + 1, + 0u, + UITYPE_NONE, + "Scroll of Infravision", + NULL, + 8, + 0, + 0, + 0, + 0, + 0, + 0u, + 23u, + 0u, + 0, + 21, + 9, + 1, + 600, + 600 + }, + { + 1, + 3u, + ILOC_UNEQUIPABLE, + 1, + 0u, + UITYPE_NONE, + "Scroll of Phasing", + NULL, + 6, + 0, + 0, + 0, + 0, + 0, + 0u, + 25u, + 0u, + 0, + 21, + 10, + 1, + 200, + 200 + }, + { + 1, + 3u, + ILOC_UNEQUIPABLE, + 1, + 0u, + UITYPE_NONE, + "Scroll of Mana Shield", + NULL, + 8, + 0, + 0, + 0, + 0, + 0, + 0u, + 0u, + 0u, + 0, + 21, + 11, + 1, + 1200, + 1200 + }, + { + 1, + 3u, + ILOC_UNEQUIPABLE, + 1, + 0u, + UITYPE_NONE, + "Scroll of Flame Wave", + NULL, + 10, + 0, + 0, + 0, + 0, + 0, + 0u, + 29u, + 0u, + 0, + 22, + 15, + 1, + 650, + 650 + }, + { + 1, + 3u, + ILOC_UNEQUIPABLE, + 1, + 0u, + UITYPE_NONE, + "Scroll of Fireball", + NULL, + 8, + 0, + 0, + 0, + 0, + 0, + 0u, + 31u, + 0u, + 0, + 22, + 12, + 1, + 300, + 300 + }, + { + 1, + 3u, + ILOC_UNEQUIPABLE, + 1, + 0u, + UITYPE_NONE, + "Scroll of Stone Curse", + NULL, + 6, + 0, + 0, + 0, + 0, + 0, + 0u, + 33u, + 0u, + 0, + 22, + 8, + 1, + 800, + 800 + }, + { + 1, + 3u, + ILOC_UNEQUIPABLE, + 1, + 0u, + UITYPE_NONE, + "Scroll of Chain Lightning", + NULL, + 10, + 0, + 0, + 0, + 0, + 0, + 0u, + 35u, + 0u, + 0, + 22, + 14, + 1, + 750, + 750 + }, + { + 1, + 3u, + ILOC_UNEQUIPABLE, + 1, + 0u, + UITYPE_NONE, + "Scroll of Guardian", + NULL, + 12, + 0, + 0, + 0, + 0, + 0, + 0u, + 47u, + 0u, + 0, + 22, + 13, + 1, + 950, + 950 + }, + { + 0, + 3u, + ILOC_UNEQUIPABLE, + 1, + 0u, + UITYPE_NONE, + "Non Item", + NULL, + 0, + 0, + 0, + 0, + 0, + 0, + 0u, + 0u, + 0u, + 0, + 0, + 0, + 0, + 0, + 0 + }, + { + 1, + 3u, + ILOC_UNEQUIPABLE, + 1, + 0u, + UITYPE_NONE, + "Scroll of Nova", + NULL, + 14, + 0, + 0, + 0, + 0, + 0, + 0u, + 57u, + 0u, + 0, + 21, + 18, + 1, + 1300, + 1300 + }, + { + 1, + 3u, + ILOC_UNEQUIPABLE, + 1, + 0u, + UITYPE_NONE, + "Scroll of Golem", + NULL, + 10, + 0, + 0, + 0, + 0, + 0, + 0u, + 51u, + 0u, + 0, + 22, + 21, + 1, + 1100, + 1100 + }, + { + 0, + 3u, + ILOC_UNEQUIPABLE, + 1, + 0u, + UITYPE_NONE, + "Scroll of None", + NULL, + 99, + 0, + 0, + 0, + 0, + 0, + 0u, + 61u, + 0u, + 0, + 22, + 0, + 1, + 1000, + 1000 + }, + { + 1, + 3u, + ILOC_UNEQUIPABLE, + 1, + 0u, + UITYPE_NONE, + "Scroll of Teleport", + NULL, + 14, + 0, + 0, + 0, + 0, + 0, + 0u, + 81u, + 0u, + 0, + 21, + 23, + 1, + 3000, + 3000 + }, + { + 1, + 3u, + ILOC_UNEQUIPABLE, + 1, + 0u, + UITYPE_NONE, + "Scroll of Apocalypse", + NULL, + 22, + 0, + 0, + 0, + 0, + 0, + 0u, + 117u, + 0u, + 0, + 21, + 24, + 1, + 2000, + 2000 + }, + { + 1, + 3u, + ILOC_UNEQUIPABLE, + 88, + 0u, + UITYPE_NONE, + "Book of ", + NULL, + 2, + 0, + 0, + 0, + 0, + 0, + 0u, + 0u, + 0u, + 0, + 24, + 0, + 1, + 0, + 0 + }, + { + 1, + 3u, + ILOC_UNEQUIPABLE, + 88, + 0u, + UITYPE_NONE, + "Book of ", + NULL, + 8, + 0, + 0, + 0, + 0, + 0, + 0u, + 0u, + 0u, + 0, + 24, + 0, + 1, + 0, + 0 + }, + { + 1, + 3u, + ILOC_UNEQUIPABLE, + 88, + 0u, + UITYPE_NONE, + "Book of ", + NULL, + 14, + 0, + 0, + 0, + 0, + 0, + 0u, + 0u, + 0u, + 0, + 24, + 0, + 1, + 0, + 0 + }, + { + 1, + 3u, + ILOC_UNEQUIPABLE, + 88, + 0u, + UITYPE_NONE, + "Book of ", + NULL, + 20, + 0, + 0, + 0, + 0, + 0, + 0u, + 0u, + 0u, + 0, + 24, + 0, + 1, + 0, + 0 + }, + { + 1, + 1u, + ILOC_ONEHAND, + 51, + 1u, + UITYPE_DAGGER, + "Dagger", + "Dagger", + 1, + 16, + 1, + 4, + 0, + 0, + 0u, + 0u, + 0u, + 0, + 0, + 0, + 0, + 60, + 60 + }, + { + 1, + 1u, + ILOC_ONEHAND, + 64, + 1u, + UITYPE_NONE, + "Short Sword", + "Sword", + 1, + 24, + 2, + 6, + 0, + 0, + 18u, + 0u, + 0u, + 0, + 0, + 0, + 0, + 120, + 120 + }, + { + 1, + 1u, + ILOC_ONEHAND, + 62, + 1u, + UITYPE_FALCHION, + "Falchion", + "Sword", + 2, + 20, + 4, + 8, + 0, + 0, + 30u, + 0u, + 0u, + 0, + 0, + 0, + 0, + 250, + 250 + }, + { + 1, + 1u, + ILOC_ONEHAND, + 72, + 1u, + UITYPE_SCIMITAR, + "Scimitar", + "Sword", + 4, + 28, + 3, + 7, + 0, + 0, + 23u, + 0u, + 23u, + 0, + 0, + 0, + 0, + 200, + 200 + }, + { + 1, + 1u, + ILOC_ONEHAND, + 65, + 1u, + UITYPE_CLAYMORE, + "Claymore", + "Sword", + 5, + 36, + 1, + 12, + 0, + 0, + 35u, + 0u, + 0u, + 0, + 0, + 0, + 0, + 450, + 450 + }, + { + 1, + 1u, + ILOC_ONEHAND, + 56, + 1u, + UITYPE_NONE, + "Blade", + "Blade", + 4, + 30, + 3, + 8, + 0, + 0, + 25u, + 0u, + 30u, + 0, + 0, + 0, + 0, + 280, + 280 + }, + { + 1, + 1u, + ILOC_ONEHAND, + 67, + 1u, + UITYPE_SABRE, + "Sabre", + "Sabre", + 1, + 45, + 1, + 8, + 0, + 0, + 17u, + 0u, + 0u, + 0, + 0, + 0, + 0, + 170, + 170 + }, + { + 1, + 1u, + ILOC_ONEHAND, + 60, + 1u, + UITYPE_LONGSWR, + "Long Sword", + "Sword", + 6, + 40, + 2, + 10, + 0, + 0, + 30u, + 0u, + 30u, + 0, + 0, + 0, + 0, + 350, + 350 + }, + { + 1, + 1u, + ILOC_ONEHAND, + 61, + 1u, + UITYPE_BROADSWR, + "Broad Sword", + "Sword", + 8, + 50, + 4, + 12, + 0, + 0, + 40u, + 0u, + 0u, + 0, + 0, + 0, + 0, + 750, + 750 + }, + { + 1, + 1u, + ILOC_ONEHAND, + 57, + 1u, + UITYPE_BASTARDSWR, + "Bastard Sword", + "Sword", + 10, + 60, + 6, + 15, + 0, + 0, + 50u, + 0u, + 0u, + 0, + 0, + 0, + 0, + 1000, + 1000 + }, + { + 1, + 1u, + ILOC_TWOHAND, + 110, + 1u, + UITYPE_TWOHANDSWR, + "Two-Handed Sword", + "Sword", + 14, + 75, + 8, + 16, + 0, + 0, + 65u, + 0u, + 0u, + 0, + 0, + 0, + 0, + 1800, + 1800 + }, + { + 1, + 1u, + ILOC_TWOHAND, + 134, + 1u, + UITYPE_GREATSWR, + "Great Sword", + "Sword", + 17, + 100, + 10, + 20, + 0, + 0, + 75u, + 0u, + 0u, + 0, + 0, + 0, + 0, + 3000, + 3000 + }, + { + 1, + 1u, + ILOC_TWOHAND, + 112, + 2u, + UITYPE_SMALLAXE, + "Small Axe", + "Axe", + 2, + 24, + 2, + 10, + 0, + 0, + 0u, + 0u, + 0u, + 0, + 0, + 0, + 0, + 150, + 150 + }, + { + 1, + 1u, + ILOC_TWOHAND, + 144, + 2u, + UITYPE_NONE, + "Axe", + "Axe", + 4, + 32, + 4, + 12, + 0, + 0, + 22u, + 0u, + 0u, + 0, + 0, + 0, + 0, + 450, + 450 + }, + { + 1, + 1u, + ILOC_TWOHAND, + 142, + 2u, + UITYPE_LARGEAXE, + "Large Axe", + "Axe", + 6, + 40, + 6, + 16, + 0, + 0, + 30u, + 0u, + 0u, + 0, + 0, + 0, + 0, + 750, + 750 + }, + { + 1, + 1u, + ILOC_TWOHAND, + 141, + 2u, + UITYPE_BROADAXE, + "Broad Axe", + "Axe", + 8, + 50, + 8, + 20, + 0, + 0, + 50u, + 0u, + 0u, + 0, + 0, + 0, + 0, + 1000, + 1000 + }, + { + 1, + 1u, + ILOC_TWOHAND, + 101, + 2u, + UITYPE_BATTLEAXE, + "Battle Axe", + "Axe", + 10, + 60, + 10, + 25, + 0, + 0, + 65u, + 0u, + 0u, + 0, + 0, + 0, + 0, + 1500, + 1500 + }, + { + 1, + 1u, + ILOC_TWOHAND, + 143, + 2u, + UITYPE_GREATAXE, + "Great Axe", + "Axe", + 12, + 75, + 12, + 30, + 0, + 0, + 80u, + 0u, + 0u, + 0, + 0, + 0, + 0, + 2500, + 2500 + }, + { + 1, + 1u, + ILOC_ONEHAND, + 59, + 4u, + UITYPE_MACE, + "Mace", + "Mace", + 2, + 32, + 1, + 8, + 0, + 0, + 16u, + 0u, + 0u, + 0, + 0, + 0, + 0, + 200, + 200 + }, + { + 1, + 1u, + ILOC_ONEHAND, + 63, + 4u, + UITYPE_MORNSTAR, + "Morning Star", + "Mace", + 3, + 40, + 1, + 10, + 0, + 0, + 26u, + 0u, + 0u, + 0, + 0, + 0, + 0, + 300, + 300 + }, + { + 1, + 1u, + ILOC_ONEHAND, + 121, + 4u, + UITYPE_WARHAMMER, + "War Hammer", + "Hammer", + 5, + 50, + 5, + 9, + 0, + 0, + 40u, + 0u, + 0u, + 0, + 0, + 0, + 0, + 600, + 600 + }, + { + 1, + 1u, + ILOC_ONEHAND, + 70, + 4u, + UITYPE_SPIKCLUB, + "Spiked Club", + "Club", + 4, + 20, + 3, + 6, + 0, + 0, + 18u, + 0u, + 0u, + 0, + 0, + 0, + 0, + 225, + 225 + }, + { + 1, + 1u, + ILOC_ONEHAND, + 66, + 4u, + UITYPE_SPIKCLUB, + "Club", + "Club", + 1, + 20, + 1, + 6, + 0, + 0, + 0u, + 0u, + 0u, + 0, + 0, + 0, + 0, + 20, + 20 + }, + { + 1, + 1u, + ILOC_ONEHAND, + 131, + 4u, + UITYPE_FLAIL, + "Flail", + "Flail", + 7, + 36, + 2, + 12, + 0, + 0, + 30u, + 0u, + 0u, + 0, + 0, + 0, + 0, + 500, + 500 + }, + { + 1, + 1u, + ILOC_TWOHAND, + 122, + 4u, + UITYPE_MAUL, + "Maul", + "Maul", + 10, + 50, + 6, + 20, + 0, + 0, + 55u, + 0u, + 0u, + 0, + 0, + 0, + 0, + 900, + 900 + }, + { + 2, + 1u, + ILOC_TWOHAND, + 118, + 3u, + UITYPE_SHORTBOW, + "Short Bow", + "Bow", + 1, + 30, + 1, + 4, + 0, + 0, + 0u, + 0u, + 0u, + 0, + 0, + 0, + 0, + 100, + 100 + }, + { + 2, + 1u, + ILOC_TWOHAND, + 102, + 3u, + UITYPE_HUNTBOW, + "Hunter's Bow", + "Bow", + 3, + 40, + 2, + 5, + 0, + 0, + 20u, + 0u, + 35u, + 0, + 0, + 0, + 0, + 350, + 350 + }, + { + 2, + 1u, + ILOC_TWOHAND, + 102, + 3u, + UITYPE_LONGBOW, + "Long Bow", + "Bow", + 5, + 35, + 1, + 6, + 0, + 0, + 25u, + 0u, + 30u, + 0, + 0, + 0, + 0, + 250, + 250 + }, + { + 2, + 1u, + ILOC_TWOHAND, + 133, + 3u, + UITYPE_COMPBOW, + "Composite Bow", + "Bow", + 7, + 45, + 3, + 6, + 0, + 0, + 25u, + 0u, + 40u, + 0, + 0, + 0, + 0, + 600, + 600 + }, + { + 2, + 1u, + ILOC_TWOHAND, + 167, + 3u, + UITYPE_NONE, + "Short Battle Bow", + "Bow", + 9, + 45, + 3, + 7, + 0, + 0, + 30u, + 0u, + 50u, + 0, + 0, + 0, + 0, + 750, + 750 + }, + { + 2, + 1u, + ILOC_TWOHAND, + 119, + 3u, + UITYPE_BATTLEBOW, + "Long Battle Bow", + "Bow", + 11, + 50, + 1, + 10, + 0, + 0, + 30u, + 0u, + 60u, + 0, + 0, + 0, + 0, + 1000, + 1000 + }, + { + 2, + 1u, + ILOC_TWOHAND, + 165, + 3u, + UITYPE_NONE, + "Short War Bow", + "Bow", + 15, + 55, + 4, + 8, + 0, + 0, + 35u, + 0u, + 70u, + 0, + 0, + 0, + 0, + 1500, + 1500 + }, + { + 2, + 1u, + ILOC_TWOHAND, + 119, + 3u, + UITYPE_WARBOW, + "Long War Bow", + "Bow", + 19, + 60, + 1, + 14, + 0, + 0, + 45u, + 0u, + 80u, + 0, + 0, + 0, + 0, + 2000, + 2000 + }, + { + 1, + 1u, + ILOC_TWOHAND, + 109, + 10u, + UITYPE_SHORTSTAFF, + "Short Staff", + "Staff", + 1, + 25, + 2, + 4, + 0, + 0, + 0u, + 0u, + 0u, + 0, + 23, + 0, + 0, + 30, + 30 + }, + { + 1, + 1u, + ILOC_TWOHAND, + 123, + 10u, + UITYPE_LONGSTAFF, + "Long Staff", + "Staff", + 4, + 35, + 4, + 8, + 0, + 0, + 0u, + 0u, + 0u, + 0, + 23, + 0, + 0, + 100, + 100 + }, + { + 1, + 1u, + ILOC_TWOHAND, + 166, + 10u, + UITYPE_COMPSTAFF, + "Composite Staff", + "Staff", + 6, + 45, + 5, + 10, + 0, + 0, + 0u, + 0u, + 0u, + 0, + 23, + 0, + 0, + 500, + 500 + }, + { + 1, + 1u, + ILOC_TWOHAND, + 109, + 10u, + UITYPE_QUARSTAFF, + "Quarter Staff", + "Staff", + 9, + 55, + 6, + 12, + 0, + 0, + 20u, + 0u, + 0u, + 0, + 23, + 0, + 0, + 1000, + 1000 + }, + { + 1, + 1u, + ILOC_TWOHAND, + 124, + 10u, + UITYPE_WARSTAFF, + "War Staff", + "Staff", + 12, + 75, + 8, + 16, + 0, + 0, + 30u, + 0u, + 0u, + 0, + 23, + 0, + 0, + 1500, + 1500 + }, + { + 1, + 3u, + ILOC_RING, + 12, + 12u, + UITYPE_RING, + "Ring", + "Ring", + 5, + 0, + 0, + 0, + 0, + 0, + 0u, + 0u, + 0u, + 0, + 25, + 0, + 0, + 1000, + 1000 + }, + { + 1, + 3u, + ILOC_RING, + 12, + 12u, + UITYPE_RING, + "Ring", + "Ring", + 10, + 0, + 0, + 0, + 0, + 0, + 0u, + 0u, + 0u, + 0, + 25, + 0, + 0, + 1000, + 1000 + }, + { + 1, + 3u, + ILOC_RING, + 12, + 12u, + UITYPE_RING, + "Ring", + "Ring", + 15, + 0, + 0, + 0, + 0, + 0, + 0u, + 0u, + 0u, + 0, + 25, + 0, + 0, + 1000, + 1000 + }, + { + 1, + 3u, + ILOC_AMULET, + 45, + 13u, + UITYPE_AMULET, + "Amulet", + "Amulet", + 8, + 0, + 0, + 0, + 0, + 0, + 0u, + 0u, + 0u, + 0, + 26, + 0, + 0, + 1200, + 1200 + }, + { + 1, + 3u, + ILOC_AMULET, + 45, + 13u, + UITYPE_AMULET, + "Amulet", + "Amulet", + 16, + 0, + 0, + 0, + 0, + 0, + 0u, + 0u, + 0u, + 0, + 26, + 0, + 0, + 1200, + 1200 + }, + { + 0, + 0u, + ILOC_INVALID, + 0, + 0u, + UITYPE_NONE, + NULL, + NULL, + 0, + 0, + 0, + 0, + 0, + 0, + 0u, + 0u, + 0u, + 0, + 0, + 0, + 0, + 0, + 0 + } +}; +unsigned char ItemCAnimTbl[169] = +{ + 20u, + 16u, + 16u, + 16u, + 4u, + 4u, + 4u, + 12u, + 12u, + 12u, + 12u, + 12u, + 12u, + 12u, + 12u, + 21u, + 21u, + 25u, + 12u, + 28u, + 28u, + 28u, + 0u, + 0u, + 0u, + 32u, + 0u, + 0u, + 0u, + 24u, + 24u, + 26u, + 2u, + 25u, + 22u, + 23u, + 24u, + 25u, + 27u, + 27u, + 29u, + 0u, + 0u, + 0u, + 12u, + 12u, + 12u, + 12u, + 12u, + 0u, + 8u, + 8u, + 0u, + 8u, + 8u, + 8u, + 8u, + 8u, + 8u, + 6u, + 8u, + 8u, + 8u, + 6u, + 8u, + 8u, + 6u, + 8u, + 8u, + 6u, + 6u, + 6u, + 8u, + 8u, + 8u, + 5u, + 9u, + 13u, + 13u, + 13u, + 5u, + 5u, + 5u, + 15u, + 5u, + 5u, + 18u, + 18u, + 18u, + 30u, + 5u, + 5u, + 14u, + 5u, + 14u, + 13u, + 16u, + 18u, + 5u, + 5u, + 7u, + 1u, + 3u, + 17u, + 1u, + 15u, + 10u, + 14u, + 3u, + 11u, + 8u, + 0u, + 1u, + 7u, + 0u, + 7u, + 15u, + 7u, + 3u, + 3u, + 3u, + 6u, + 6u, + 11u, + 11u, + 11u, + 31u, + 14u, + 14u, + 14u, + 6u, + 6u, + 7u, + 3u, + 8u, + 14u, + 0u, + 14u, + 14u, + 0u, + 33u, + 1u, + 1u, + 1u, + 1u, + 1u, + 7u, + 7u, + 7u, + 14u, + 14u, + 17u, + 17u, + 17u, + 0u, + 34u, + 1u, + 0u, + 3u, + 17u, + 8u, + 8u, + 6u, + 1u, + 3u, + 3u, + 11u, + 3u, + 4u +}; +char *ItemDropStrs[35] = +{ + "Armor2", + "Axe", + "FBttle", + "Bow", + "GoldFlip", + "Helmut", + "Mace", + "Shield", + "SwrdFlip", + "Rock", + "Cleaver", + "Staff", + "Ring", + "CrownF", + "LArmor", + "WShield", + "Scroll", + "FPlateAr", + "FBook", + "Food", + "FBttleBB", + "FBttleDY", + "FBttleOR", + "FBttleBR", + "FBttleBL", + "FBttleBY", + "FBttleWH", + "FBttleDB", + "FEar", + "FBrain", + "FMush", + "Innsign", + "Bldstn", + "Fanvil", + "FLazStaf" +}; +unsigned char ItemAnimLs[35] = +{ + 15u, + 13u, + 16u, + 13u, + 10u, + 13u, + 13u, + 13u, + 13u, + 10u, + 13u, + 13u, + 13u, + 13u, + 13u, + 13u, + 13u, + 13u, + 13u, + 1u, + 16u, + 16u, + 16u, + 16u, + 16u, + 16u, + 16u, + 16u, + 13u, + 12u, + 12u, + 13u, + 13u, + 13u, + 8u +}; +_sfx_id ItemDropSnds[35] = +{ + IS_FHARM, + IS_FAXE, + IS_FPOT, + IS_FBOW, + IS_GOLD, + IS_FCAP, + IS_FSWOR, + IS_FSHLD, + IS_FSWOR, + IS_FROCK, + IS_FAXE, + IS_FSTAF, + IS_FRING, + IS_FCAP, + IS_FLARM, + IS_FSHLD, + IS_FSCRL, + IS_FHARM, + IS_FBOOK, + IS_FLARM, + IS_FPOT, + IS_FPOT, + IS_FPOT, + IS_FPOT, + IS_FPOT, + IS_FPOT, + IS_FPOT, + IS_FPOT, + IS_FBODY, + IS_FBODY, + IS_FMUSH, + IS_ISIGN, + IS_FBLST, + IS_FANVL, + IS_FSTAF +}; +_sfx_id ItemInvSnds[35] = +{ + IS_IHARM, + IS_IAXE, + IS_IPOT, + IS_IBOW, + IS_GOLD, + IS_ICAP, + IS_ISWORD, + IS_ISHIEL, + IS_ISWORD, + IS_IROCK, + IS_IAXE, + IS_ISTAF, + IS_IRING, + IS_ICAP, + IS_ILARM, + IS_ISHIEL, + IS_ISCROL, + IS_IHARM, + IS_IBOOK, + IS_IHARM, + IS_IPOT, + IS_IPOT, + IS_IPOT, + IS_IPOT, + IS_IPOT, + IS_IPOT, + IS_IPOT, + IS_IPOT, + IS_IBODY, + IS_IBODY, + IS_IMUSH, + IS_ISIGN, + IS_IBLST, + IS_IANVL, + IS_ISTAF +}; +int idoppely = 16; // weak +int premiumlvladd[6] = { 4294967295, 4294967295, 0, 0, 1, 2 }; +CircleCoord CrawlTable = +{ + 1u, + { { 0u, 0u } }, + 4u, + { { 0u, 1u }, { 0u, 255u }, { 255u, 0u }, { 1u, 0u } }, + 16u, + { + { 0u, 2u }, + { 0u, 254u }, + { 255u, 2u }, + { 1u, 2u }, + { 255u, 254u }, + { 1u, 254u }, + { 255u, 1u }, + { 1u, 1u }, + { 255u, 255u }, + { 1u, 255u }, + { 254u, 1u }, + { 2u, 1u }, + { 254u, 255u }, + { 2u, 255u }, + { 254u, 0u }, + { 2u, 0u } + }, + 24u, + { + { 0u, 3u }, + { 0u, 253u }, + { 255u, 3u }, + { 1u, 3u }, + { 255u, 253u }, + { 1u, 253u }, + { 254u, 3u }, + { 2u, 3u }, + { 254u, 253u }, + { 2u, 253u }, + { 254u, 2u }, + { 2u, 2u }, + { 254u, 254u }, + { 2u, 254u }, + { 253u, 2u }, + { 3u, 2u }, + { 253u, 254u }, + { 3u, 254u }, + { 253u, 1u }, + { 3u, 1u }, + { 253u, 255u }, + { 3u, 255u }, + { 253u, 0u }, + { 3u, 0u } + }, + 32u, + { + { 0u, 4u }, + { 0u, 252u }, + { 255u, 4u }, + { 1u, 4u }, + { 255u, 252u }, + { 1u, 252u }, + { 254u, 4u }, + { 2u, 4u }, + { 254u, 252u }, + { 2u, 252u }, + { 253u, 4u }, + { 3u, 4u }, + { 253u, 252u }, + { 3u, 252u }, + { 253u, 3u }, + { 3u, 3u }, + { 253u, 253u }, + { 3u, 253u }, + { 252u, 3u }, + { 4u, 3u }, + { 252u, 253u }, + { 4u, 253u }, + { 252u, 2u }, + { 4u, 2u }, + { 252u, 254u }, + { 4u, 254u }, + { 252u, 1u }, + { 4u, 1u }, + { 252u, 255u }, + { 4u, 255u }, + { 252u, 0u }, + { 4u, 0u } + }, + 40u, + { + { 0u, 5u }, + { 0u, 251u }, + { 255u, 5u }, + { 1u, 5u }, + { 255u, 251u }, + { 1u, 251u }, + { 254u, 5u }, + { 2u, 5u }, + { 254u, 251u }, + { 2u, 251u }, + { 253u, 5u }, + { 3u, 5u }, + { 253u, 251u }, + { 3u, 251u }, + { 252u, 5u }, + { 4u, 5u }, + { 252u, 251u }, + { 4u, 251u }, + { 252u, 4u }, + { 4u, 4u }, + { 252u, 252u }, + { 4u, 252u }, + { 251u, 4u }, + { 5u, 4u }, + { 251u, 252u }, + { 5u, 252u }, + { 251u, 3u }, + { 5u, 3u }, + { 251u, 253u }, + { 5u, 253u }, + { 251u, 2u }, + { 5u, 2u }, + { 251u, 254u }, + { 5u, 254u }, + { 251u, 1u }, + { 5u, 1u }, + { 251u, 255u }, + { 5u, 255u }, + { 251u, 0u }, + { 5u, 0u } + }, + 48u, + { + { 0u, 6u }, + { 0u, 250u }, + { 255u, 6u }, + { 1u, 6u }, + { 255u, 250u }, + { 1u, 250u }, + { 254u, 6u }, + { 2u, 6u }, + { 254u, 250u }, + { 2u, 250u }, + { 253u, 6u }, + { 3u, 6u }, + { 253u, 250u }, + { 3u, 250u }, + { 252u, 6u }, + { 4u, 6u }, + { 252u, 250u }, + { 4u, 250u }, + { 251u, 6u }, + { 5u, 6u }, + { 251u, 250u }, + { 5u, 250u }, + { 251u, 5u }, + { 5u, 5u }, + { 251u, 251u }, + { 5u, 251u }, + { 250u, 5u }, + { 6u, 5u }, + { 250u, 251u }, + { 6u, 251u }, + { 250u, 4u }, + { 6u, 4u }, + { 250u, 252u }, + { 6u, 252u }, + { 250u, 3u }, + { 6u, 3u }, + { 250u, 253u }, + { 6u, 253u }, + { 250u, 2u }, + { 6u, 2u }, + { 250u, 254u }, + { 6u, 254u }, + { 250u, 1u }, + { 6u, 1u }, + { 250u, 255u }, + { 6u, 255u }, + { 250u, 0u }, + { 6u, 0u } + }, + 56u, + { + { 0u, 7u }, + { 0u, 249u }, + { 255u, 7u }, + { 1u, 7u }, + { 255u, 249u }, + { 1u, 249u }, + { 254u, 7u }, + { 2u, 7u }, + { 254u, 249u }, + { 2u, 249u }, + { 253u, 7u }, + { 3u, 7u }, + { 253u, 249u }, + { 3u, 249u }, + { 252u, 7u }, + { 4u, 7u }, + { 252u, 249u }, + { 4u, 249u }, + { 251u, 7u }, + { 5u, 7u }, + { 251u, 249u }, + { 5u, 249u }, + { 250u, 7u }, + { 6u, 7u }, + { 250u, 249u }, + { 6u, 249u }, + { 250u, 6u }, + { 6u, 6u }, + { 250u, 250u }, + { 6u, 250u }, + { 249u, 6u }, + { 7u, 6u }, + { 249u, 250u }, + { 7u, 250u }, + { 249u, 5u }, + { 7u, 5u }, + { 249u, 251u }, + { 7u, 251u }, + { 249u, 4u }, + { 7u, 4u }, + { 249u, 252u }, + { 7u, 252u }, + { 249u, 3u }, + { 7u, 3u }, + { 249u, 253u }, + { 7u, 253u }, + { 249u, 2u }, + { 7u, 2u }, + { 249u, 254u }, + { 7u, 254u }, + { 249u, 1u }, + { 7u, 1u }, + { 249u, 255u }, + { 7u, 255u }, + { 249u, 0u }, + { 7u, 0u } + }, + 64u, + { + { 0u, 8u }, + { 0u, 248u }, + { 255u, 8u }, + { 1u, 8u }, + { 255u, 248u }, + { 1u, 248u }, + { 254u, 8u }, + { 2u, 8u }, + { 254u, 248u }, + { 2u, 248u }, + { 253u, 8u }, + { 3u, 8u }, + { 253u, 248u }, + { 3u, 248u }, + { 252u, 8u }, + { 4u, 8u }, + { 252u, 248u }, + { 4u, 248u }, + { 251u, 8u }, + { 5u, 8u }, + { 251u, 248u }, + { 5u, 248u }, + { 250u, 8u }, + { 6u, 8u }, + { 250u, 248u }, + { 6u, 248u }, + { 249u, 8u }, + { 7u, 8u }, + { 249u, 248u }, + { 7u, 248u }, + { 249u, 7u }, + { 7u, 7u }, + { 249u, 249u }, + { 7u, 249u }, + { 248u, 7u }, + { 8u, 7u }, + { 248u, 249u }, + { 8u, 249u }, + { 248u, 6u }, + { 8u, 6u }, + { 248u, 250u }, + { 8u, 250u }, + { 248u, 5u }, + { 8u, 5u }, + { 248u, 251u }, + { 8u, 251u }, + { 248u, 4u }, + { 8u, 4u }, + { 248u, 252u }, + { 8u, 252u }, + { 248u, 3u }, + { 8u, 3u }, + { 248u, 253u }, + { 8u, 253u }, + { 248u, 2u }, + { 8u, 2u }, + { 248u, 254u }, + { 8u, 254u }, + { 248u, 1u }, + { 8u, 1u }, + { 248u, 255u }, + { 8u, 255u }, + { 248u, 0u }, + { 8u, 0u } + }, + 72u, + { + { 0u, 9u }, + { 0u, 247u }, + { 255u, 9u }, + { 1u, 9u }, + { 255u, 247u }, + { 1u, 247u }, + { 254u, 9u }, + { 2u, 9u }, + { 254u, 247u }, + { 2u, 247u }, + { 253u, 9u }, + { 3u, 9u }, + { 253u, 247u }, + { 3u, 247u }, + { 252u, 9u }, + { 4u, 9u }, + { 252u, 247u }, + { 4u, 247u }, + { 251u, 9u }, + { 5u, 9u }, + { 251u, 247u }, + { 5u, 247u }, + { 250u, 9u }, + { 6u, 9u }, + { 250u, 247u }, + { 6u, 247u }, + { 249u, 9u }, + { 7u, 9u }, + { 249u, 247u }, + { 7u, 247u }, + { 248u, 9u }, + { 8u, 9u }, + { 248u, 247u }, + { 8u, 247u }, + { 248u, 8u }, + { 8u, 8u }, + { 248u, 248u }, + { 8u, 248u }, + { 247u, 8u }, + { 9u, 8u }, + { 247u, 248u }, + { 9u, 248u }, + { 247u, 7u }, + { 9u, 7u }, + { 247u, 249u }, + { 9u, 249u }, + { 247u, 6u }, + { 9u, 6u }, + { 247u, 250u }, + { 9u, 250u }, + { 247u, 5u }, + { 9u, 5u }, + { 247u, 251u }, + { 9u, 251u }, + { 247u, 4u }, + { 9u, 4u }, + { 247u, 252u }, + { 9u, 252u }, + { 247u, 3u }, + { 9u, 3u }, + { 247u, 253u }, + { 9u, 253u }, + { 247u, 2u }, + { 9u, 2u }, + { 247u, 254u }, + { 9u, 254u }, + { 247u, 1u }, + { 9u, 1u }, + { 247u, 255u }, + { 9u, 255u }, + { 247u, 0u }, + { 9u, 0u } + }, + 80u, + { + { 0u, 10u }, + { 0u, 246u }, + { 255u, 10u }, + { 1u, 10u }, + { 255u, 246u }, + { 1u, 246u }, + { 254u, 10u }, + { 2u, 10u }, + { 254u, 246u }, + { 2u, 246u }, + { 253u, 10u }, + { 3u, 10u }, + { 253u, 246u }, + { 3u, 246u }, + { 252u, 10u }, + { 4u, 10u }, + { 252u, 246u }, + { 4u, 246u }, + { 251u, 10u }, + { 5u, 10u }, + { 251u, 246u }, + { 5u, 246u }, + { 250u, 10u }, + { 6u, 10u }, + { 250u, 246u }, + { 6u, 246u }, + { 249u, 10u }, + { 7u, 10u }, + { 249u, 246u }, + { 7u, 246u }, + { 248u, 10u }, + { 8u, 10u }, + { 248u, 246u }, + { 8u, 246u }, + { 247u, 10u }, + { 9u, 10u }, + { 247u, 246u }, + { 9u, 246u }, + { 247u, 9u }, + { 9u, 9u }, + { 247u, 247u }, + { 9u, 247u }, + { 246u, 9u }, + { 10u, 9u }, + { 246u, 247u }, + { 10u, 247u }, + { 246u, 8u }, + { 10u, 8u }, + { 246u, 248u }, + { 10u, 248u }, + { 246u, 7u }, + { 10u, 7u }, + { 246u, 249u }, + { 10u, 249u }, + { 246u, 6u }, + { 10u, 6u }, + { 246u, 250u }, + { 10u, 250u }, + { 246u, 5u }, + { 10u, 5u }, + { 246u, 251u }, + { 10u, 251u }, + { 246u, 4u }, + { 10u, 4u }, + { 246u, 252u }, + { 10u, 252u }, + { 246u, 3u }, + { 10u, 3u }, + { 246u, 253u }, + { 10u, 253u }, + { 246u, 2u }, + { 10u, 2u }, + { 246u, 254u }, + { 10u, 254u }, + { 246u, 1u }, + { 10u, 1u }, + { 246u, 255u }, + { 10u, 255u }, + { 246u, 0u }, + { 10u, 0u } + }, + 88u, + { + { 0u, 11u }, + { 0u, 245u }, + { 255u, 11u }, + { 1u, 11u }, + { 255u, 245u }, + { 1u, 245u }, + { 254u, 11u }, + { 2u, 11u }, + { 254u, 245u }, + { 2u, 245u }, + { 253u, 11u }, + { 3u, 11u }, + { 253u, 245u }, + { 3u, 245u }, + { 252u, 11u }, + { 4u, 11u }, + { 252u, 245u }, + { 4u, 245u }, + { 251u, 11u }, + { 5u, 11u }, + { 251u, 245u }, + { 5u, 245u }, + { 250u, 11u }, + { 6u, 11u }, + { 250u, 245u }, + { 6u, 245u }, + { 249u, 11u }, + { 7u, 11u }, + { 249u, 245u }, + { 7u, 245u }, + { 248u, 11u }, + { 8u, 11u }, + { 248u, 245u }, + { 8u, 245u }, + { 247u, 11u }, + { 9u, 11u }, + { 247u, 245u }, + { 9u, 245u }, + { 246u, 11u }, + { 10u, 11u }, + { 246u, 245u }, + { 10u, 245u }, + { 246u, 10u }, + { 10u, 10u }, + { 246u, 246u }, + { 10u, 246u }, + { 245u, 10u }, + { 11u, 10u }, + { 245u, 246u }, + { 11u, 246u }, + { 245u, 9u }, + { 11u, 9u }, + { 245u, 247u }, + { 11u, 247u }, + { 245u, 8u }, + { 11u, 8u }, + { 245u, 248u }, + { 11u, 248u }, + { 245u, 7u }, + { 11u, 7u }, + { 245u, 249u }, + { 11u, 249u }, + { 245u, 6u }, + { 11u, 6u }, + { 245u, 250u }, + { 11u, 250u }, + { 245u, 5u }, + { 11u, 5u }, + { 245u, 251u }, + { 11u, 251u }, + { 245u, 4u }, + { 11u, 4u }, + { 245u, 252u }, + { 11u, 252u }, + { 245u, 3u }, + { 11u, 3u }, + { 245u, 253u }, + { 11u, 253u }, + { 245u, 2u }, + { 11u, 2u }, + { 245u, 254u }, + { 11u, 254u }, + { 245u, 1u }, + { 11u, 1u }, + { 245u, 255u }, + { 11u, 255u }, + { 245u, 0u }, + { 11u, 0u } + }, + 96u, + { + { 0u, 12u }, + { 0u, 244u }, + { 255u, 12u }, + { 1u, 12u }, + { 255u, 244u }, + { 1u, 244u }, + { 254u, 12u }, + { 2u, 12u }, + { 254u, 244u }, + { 2u, 244u }, + { 253u, 12u }, + { 3u, 12u }, + { 253u, 244u }, + { 3u, 244u }, + { 252u, 12u }, + { 4u, 12u }, + { 252u, 244u }, + { 4u, 244u }, + { 251u, 12u }, + { 5u, 12u }, + { 251u, 244u }, + { 5u, 244u }, + { 250u, 12u }, + { 6u, 12u }, + { 250u, 244u }, + { 6u, 244u }, + { 249u, 12u }, + { 7u, 12u }, + { 249u, 244u }, + { 7u, 244u }, + { 248u, 12u }, + { 8u, 12u }, + { 248u, 244u }, + { 8u, 244u }, + { 247u, 12u }, + { 9u, 12u }, + { 247u, 244u }, + { 9u, 244u }, + { 246u, 12u }, + { 10u, 12u }, + { 246u, 244u }, + { 10u, 244u }, + { 245u, 12u }, + { 11u, 12u }, + { 245u, 244u }, + { 11u, 244u }, + { 245u, 11u }, + { 11u, 11u }, + { 245u, 245u }, + { 11u, 245u }, + { 244u, 11u }, + { 12u, 11u }, + { 244u, 245u }, + { 12u, 245u }, + { 244u, 10u }, + { 12u, 10u }, + { 244u, 246u }, + { 12u, 246u }, + { 244u, 9u }, + { 12u, 9u }, + { 244u, 247u }, + { 12u, 247u }, + { 244u, 8u }, + { 12u, 8u }, + { 244u, 248u }, + { 12u, 248u }, + { 244u, 7u }, + { 12u, 7u }, + { 244u, 249u }, + { 12u, 249u }, + { 244u, 6u }, + { 12u, 6u }, + { 244u, 250u }, + { 12u, 250u }, + { 244u, 5u }, + { 12u, 5u }, + { 244u, 251u }, + { 12u, 251u }, + { 244u, 4u }, + { 12u, 4u }, + { 244u, 252u }, + { 12u, 252u }, + { 244u, 3u }, + { 12u, 3u }, + { 244u, 253u }, + { 12u, 253u }, + { 244u, 2u }, + { 12u, 2u }, + { 244u, 254u }, + { 12u, 254u }, + { 244u, 1u }, + { 12u, 1u }, + { 244u, 255u }, + { 12u, 255u }, + { 244u, 0u }, + { 12u, 0u } + }, + 104u, + { + { 0u, 13u }, + { 0u, 243u }, + { 255u, 13u }, + { 1u, 13u }, + { 255u, 243u }, + { 1u, 243u }, + { 254u, 13u }, + { 2u, 13u }, + { 254u, 243u }, + { 2u, 243u }, + { 253u, 13u }, + { 3u, 13u }, + { 253u, 243u }, + { 3u, 243u }, + { 252u, 13u }, + { 4u, 13u }, + { 252u, 243u }, + { 4u, 243u }, + { 251u, 13u }, + { 5u, 13u }, + { 251u, 243u }, + { 5u, 243u }, + { 250u, 13u }, + { 6u, 13u }, + { 250u, 243u }, + { 6u, 243u }, + { 249u, 13u }, + { 7u, 13u }, + { 249u, 243u }, + { 7u, 243u }, + { 248u, 13u }, + { 8u, 13u }, + { 248u, 243u }, + { 8u, 243u }, + { 247u, 13u }, + { 9u, 13u }, + { 247u, 243u }, + { 9u, 243u }, + { 246u, 13u }, + { 10u, 13u }, + { 246u, 243u }, + { 10u, 243u }, + { 245u, 13u }, + { 11u, 13u }, + { 245u, 243u }, + { 11u, 243u }, + { 244u, 13u }, + { 12u, 13u }, + { 244u, 243u }, + { 12u, 243u }, + { 244u, 12u }, + { 12u, 12u }, + { 244u, 244u }, + { 12u, 244u }, + { 243u, 12u }, + { 13u, 12u }, + { 243u, 244u }, + { 13u, 244u }, + { 243u, 11u }, + { 13u, 11u }, + { 243u, 245u }, + { 13u, 245u }, + { 243u, 10u }, + { 13u, 10u }, + { 243u, 246u }, + { 13u, 246u }, + { 243u, 9u }, + { 13u, 9u }, + { 243u, 247u }, + { 13u, 247u }, + { 243u, 8u }, + { 13u, 8u }, + { 243u, 248u }, + { 13u, 248u }, + { 243u, 7u }, + { 13u, 7u }, + { 243u, 249u }, + { 13u, 249u }, + { 243u, 6u }, + { 13u, 6u }, + { 243u, 250u }, + { 13u, 250u }, + { 243u, 5u }, + { 13u, 5u }, + { 243u, 251u }, + { 13u, 251u }, + { 243u, 4u }, + { 13u, 4u }, + { 243u, 252u }, + { 13u, 252u }, + { 243u, 3u }, + { 13u, 3u }, + { 243u, 253u }, + { 13u, 253u }, + { 243u, 2u }, + { 13u, 2u }, + { 243u, 254u }, + { 13u, 254u }, + { 243u, 1u }, + { 13u, 1u }, + { 243u, 255u }, + { 13u, 255u }, + { 243u, 0u }, + { 13u, 0u } + }, + 112u, + { + { 0u, 14u }, + { 0u, 242u }, + { 255u, 14u }, + { 1u, 14u }, + { 255u, 242u }, + { 1u, 242u }, + { 254u, 14u }, + { 2u, 14u }, + { 254u, 242u }, + { 2u, 242u }, + { 253u, 14u }, + { 3u, 14u }, + { 253u, 242u }, + { 3u, 242u }, + { 252u, 14u }, + { 4u, 14u }, + { 252u, 242u }, + { 4u, 242u }, + { 251u, 14u }, + { 5u, 14u }, + { 251u, 242u }, + { 5u, 242u }, + { 250u, 14u }, + { 6u, 14u }, + { 250u, 242u }, + { 6u, 242u }, + { 249u, 14u }, + { 7u, 14u }, + { 249u, 242u }, + { 7u, 242u }, + { 248u, 14u }, + { 8u, 14u }, + { 248u, 242u }, + { 8u, 242u }, + { 247u, 14u }, + { 9u, 14u }, + { 247u, 242u }, + { 9u, 242u }, + { 246u, 14u }, + { 10u, 14u }, + { 246u, 242u }, + { 10u, 242u }, + { 245u, 14u }, + { 11u, 14u }, + { 245u, 242u }, + { 11u, 242u }, + { 244u, 14u }, + { 12u, 14u }, + { 244u, 242u }, + { 12u, 242u }, + { 243u, 14u }, + { 13u, 14u }, + { 243u, 242u }, + { 13u, 242u }, + { 243u, 13u }, + { 13u, 13u }, + { 243u, 243u }, + { 13u, 243u }, + { 242u, 13u }, + { 14u, 13u }, + { 242u, 243u }, + { 14u, 243u }, + { 242u, 12u }, + { 14u, 12u }, + { 242u, 244u }, + { 14u, 244u }, + { 242u, 11u }, + { 14u, 11u }, + { 242u, 245u }, + { 14u, 245u }, + { 242u, 10u }, + { 14u, 10u }, + { 242u, 246u }, + { 14u, 246u }, + { 242u, 9u }, + { 14u, 9u }, + { 242u, 247u }, + { 14u, 247u }, + { 242u, 8u }, + { 14u, 8u }, + { 242u, 248u }, + { 14u, 248u }, + { 242u, 7u }, + { 14u, 7u }, + { 242u, 249u }, + { 14u, 249u }, + { 242u, 6u }, + { 14u, 6u }, + { 242u, 250u }, + { 14u, 250u }, + { 242u, 5u }, + { 14u, 5u }, + { 242u, 251u }, + { 14u, 251u }, + { 242u, 4u }, + { 14u, 4u }, + { 242u, 252u }, + { 14u, 252u }, + { 242u, 3u }, + { 14u, 3u }, + { 242u, 253u }, + { 14u, 253u }, + { 242u, 2u }, + { 14u, 2u }, + { 242u, 254u }, + { 14u, 254u }, + { 242u, 1u }, + { 14u, 1u }, + { 242u, 255u }, + { 14u, 255u }, + { 242u, 0u }, + { 14u, 0u } + }, + 120u, + { + { 0u, 15u }, + { 0u, 241u }, + { 255u, 15u }, + { 1u, 15u }, + { 255u, 241u }, + { 1u, 241u }, + { 254u, 15u }, + { 2u, 15u }, + { 254u, 241u }, + { 2u, 241u }, + { 253u, 15u }, + { 3u, 15u }, + { 253u, 241u }, + { 3u, 241u }, + { 252u, 15u }, + { 4u, 15u }, + { 252u, 241u }, + { 4u, 241u }, + { 251u, 15u }, + { 5u, 15u }, + { 251u, 241u }, + { 5u, 241u }, + { 250u, 15u }, + { 6u, 15u }, + { 250u, 241u }, + { 6u, 241u }, + { 249u, 15u }, + { 7u, 15u }, + { 249u, 241u }, + { 7u, 241u }, + { 248u, 15u }, + { 8u, 15u }, + { 248u, 241u }, + { 8u, 241u }, + { 247u, 15u }, + { 9u, 15u }, + { 247u, 241u }, + { 9u, 241u }, + { 246u, 15u }, + { 10u, 15u }, + { 246u, 241u }, + { 10u, 241u }, + { 245u, 15u }, + { 11u, 15u }, + { 245u, 241u }, + { 11u, 241u }, + { 244u, 15u }, + { 12u, 15u }, + { 244u, 241u }, + { 12u, 241u }, + { 243u, 15u }, + { 13u, 15u }, + { 243u, 241u }, + { 13u, 241u }, + { 242u, 15u }, + { 14u, 15u }, + { 242u, 241u }, + { 14u, 241u }, + { 242u, 14u }, + { 14u, 14u }, + { 242u, 242u }, + { 14u, 242u }, + { 241u, 14u }, + { 15u, 14u }, + { 241u, 242u }, + { 15u, 242u }, + { 241u, 13u }, + { 15u, 13u }, + { 241u, 243u }, + { 15u, 243u }, + { 241u, 12u }, + { 15u, 12u }, + { 241u, 244u }, + { 15u, 244u }, + { 241u, 11u }, + { 15u, 11u }, + { 241u, 245u }, + { 15u, 245u }, + { 241u, 10u }, + { 15u, 10u }, + { 241u, 246u }, + { 15u, 246u }, + { 241u, 9u }, + { 15u, 9u }, + { 241u, 247u }, + { 15u, 247u }, + { 241u, 8u }, + { 15u, 8u }, + { 241u, 248u }, + { 15u, 248u }, + { 241u, 7u }, + { 15u, 7u }, + { 241u, 249u }, + { 15u, 249u }, + { 241u, 6u }, + { 15u, 6u }, + { 241u, 250u }, + { 15u, 250u }, + { 241u, 5u }, + { 15u, 5u }, + { 241u, 251u }, + { 15u, 251u }, + { 241u, 4u }, + { 15u, 4u }, + { 241u, 252u }, + { 15u, 252u }, + { 241u, 3u }, + { 15u, 3u }, + { 241u, 253u }, + { 15u, 253u }, + { 241u, 2u }, + { 15u, 2u }, + { 241u, 254u }, + { 15u, 254u }, + { 241u, 1u }, + { 15u, 1u }, + { 241u, 255u }, + { 15u, 255u }, + { 241u, 0u }, + { 15u, 0u } + }, + 128u, + { + { 0u, 16u }, + { 0u, 240u }, + { 255u, 16u }, + { 1u, 16u }, + { 255u, 240u }, + { 1u, 240u }, + { 254u, 16u }, + { 2u, 16u }, + { 254u, 240u }, + { 2u, 240u }, + { 253u, 16u }, + { 3u, 16u }, + { 253u, 240u }, + { 3u, 240u }, + { 252u, 16u }, + { 4u, 16u }, + { 252u, 240u }, + { 4u, 240u }, + { 251u, 16u }, + { 5u, 16u }, + { 251u, 240u }, + { 5u, 240u }, + { 250u, 16u }, + { 6u, 16u }, + { 250u, 240u }, + { 6u, 240u }, + { 249u, 16u }, + { 7u, 16u }, + { 249u, 240u }, + { 7u, 240u }, + { 248u, 16u }, + { 8u, 16u }, + { 248u, 240u }, + { 8u, 240u }, + { 247u, 16u }, + { 9u, 16u }, + { 247u, 240u }, + { 9u, 240u }, + { 246u, 16u }, + { 10u, 16u }, + { 246u, 240u }, + { 10u, 240u }, + { 245u, 16u }, + { 11u, 16u }, + { 245u, 240u }, + { 11u, 240u }, + { 244u, 16u }, + { 12u, 16u }, + { 244u, 240u }, + { 12u, 240u }, + { 243u, 16u }, + { 13u, 16u }, + { 243u, 240u }, + { 13u, 240u }, + { 242u, 16u }, + { 14u, 16u }, + { 242u, 240u }, + { 14u, 240u }, + { 241u, 16u }, + { 15u, 16u }, + { 241u, 240u }, + { 15u, 240u }, + { 241u, 15u }, + { 15u, 15u }, + { 241u, 241u }, + { 15u, 241u }, + { 240u, 15u }, + { 16u, 15u }, + { 240u, 241u }, + { 16u, 241u }, + { 240u, 14u }, + { 16u, 14u }, + { 240u, 242u }, + { 16u, 242u }, + { 240u, 13u }, + { 16u, 13u }, + { 240u, 243u }, + { 16u, 243u }, + { 240u, 12u }, + { 16u, 12u }, + { 240u, 244u }, + { 16u, 244u }, + { 240u, 11u }, + { 16u, 11u }, + { 240u, 245u }, + { 16u, 245u }, + { 240u, 10u }, + { 16u, 10u }, + { 240u, 246u }, + { 16u, 246u }, + { 240u, 9u }, + { 16u, 9u }, + { 240u, 247u }, + { 16u, 247u }, + { 240u, 8u }, + { 16u, 8u }, + { 240u, 248u }, + { 16u, 248u }, + { 240u, 7u }, + { 16u, 7u }, + { 240u, 249u }, + { 16u, 249u }, + { 240u, 6u }, + { 16u, 6u }, + { 240u, 250u }, + { 16u, 250u }, + { 240u, 5u }, + { 16u, 5u }, + { 240u, 251u }, + { 16u, 251u }, + { 240u, 4u }, + { 16u, 4u }, + { 240u, 252u }, + { 16u, 252u }, + { 240u, 3u }, + { 16u, 3u }, + { 240u, 253u }, + { 16u, 253u }, + { 240u, 2u }, + { 16u, 2u }, + { 240u, 254u }, + { 16u, 254u }, + { 240u, 1u }, + { 16u, 1u }, + { 240u, 255u }, + { 16u, 255u }, + { 240u, 0u }, + { 16u, 0u } + }, + 136u, + { + { 0u, 17u }, + { 0u, 239u }, + { 255u, 17u }, + { 1u, 17u }, + { 255u, 239u }, + { 1u, 239u }, + { 254u, 17u }, + { 2u, 17u }, + { 254u, 239u }, + { 2u, 239u }, + { 253u, 17u }, + { 3u, 17u }, + { 253u, 239u }, + { 3u, 239u }, + { 252u, 17u }, + { 4u, 17u }, + { 252u, 239u }, + { 4u, 239u }, + { 251u, 17u }, + { 5u, 17u }, + { 251u, 239u }, + { 5u, 239u }, + { 250u, 17u }, + { 6u, 17u }, + { 250u, 239u }, + { 6u, 239u }, + { 249u, 17u }, + { 7u, 17u }, + { 249u, 239u }, + { 7u, 239u }, + { 248u, 17u }, + { 8u, 17u }, + { 248u, 239u }, + { 8u, 239u }, + { 247u, 17u }, + { 9u, 17u }, + { 247u, 239u }, + { 9u, 239u }, + { 246u, 17u }, + { 10u, 17u }, + { 246u, 239u }, + { 10u, 239u }, + { 245u, 17u }, + { 11u, 17u }, + { 245u, 239u }, + { 11u, 239u }, + { 244u, 17u }, + { 12u, 17u }, + { 244u, 239u }, + { 12u, 239u }, + { 243u, 17u }, + { 13u, 17u }, + { 243u, 239u }, + { 13u, 239u }, + { 242u, 17u }, + { 14u, 17u }, + { 242u, 239u }, + { 14u, 239u }, + { 241u, 17u }, + { 15u, 17u }, + { 241u, 239u }, + { 15u, 239u }, + { 240u, 17u }, + { 16u, 17u }, + { 240u, 239u }, + { 16u, 239u }, + { 240u, 16u }, + { 16u, 16u }, + { 240u, 240u }, + { 16u, 240u }, + { 239u, 16u }, + { 17u, 16u }, + { 239u, 240u }, + { 17u, 240u }, + { 239u, 15u }, + { 17u, 15u }, + { 239u, 241u }, + { 17u, 241u }, + { 239u, 14u }, + { 17u, 14u }, + { 239u, 242u }, + { 17u, 242u }, + { 239u, 13u }, + { 17u, 13u }, + { 239u, 243u }, + { 17u, 243u }, + { 239u, 12u }, + { 17u, 12u }, + { 239u, 244u }, + { 17u, 244u }, + { 239u, 11u }, + { 17u, 11u }, + { 239u, 245u }, + { 17u, 245u }, + { 239u, 10u }, + { 17u, 10u }, + { 239u, 246u }, + { 17u, 246u }, + { 239u, 9u }, + { 17u, 9u }, + { 239u, 247u }, + { 17u, 247u }, + { 239u, 8u }, + { 17u, 8u }, + { 239u, 248u }, + { 17u, 248u }, + { 239u, 7u }, + { 17u, 7u }, + { 239u, 249u }, + { 17u, 249u }, + { 239u, 6u }, + { 17u, 6u }, + { 239u, 250u }, + { 17u, 250u }, + { 239u, 5u }, + { 17u, 5u }, + { 239u, 251u }, + { 17u, 251u }, + { 239u, 4u }, + { 17u, 4u }, + { 239u, 252u }, + { 17u, 252u }, + { 239u, 3u }, + { 17u, 3u }, + { 239u, 253u }, + { 17u, 253u }, + { 239u, 2u }, + { 17u, 2u }, + { 239u, 254u }, + { 17u, 254u }, + { 239u, 1u }, + { 17u, 1u }, + { 239u, 255u }, + { 17u, 255u }, + { 239u, 0u }, + { 17u, 0u } + }, + 144u, + { + { 0u, 18u }, + { 0u, 238u }, + { 255u, 18u }, + { 1u, 18u }, + { 255u, 238u }, + { 1u, 238u }, + { 254u, 18u }, + { 2u, 18u }, + { 254u, 238u }, + { 2u, 238u }, + { 253u, 18u }, + { 3u, 18u }, + { 253u, 238u }, + { 3u, 238u }, + { 252u, 18u }, + { 4u, 18u }, + { 252u, 238u }, + { 4u, 238u }, + { 251u, 18u }, + { 5u, 18u }, + { 251u, 238u }, + { 5u, 238u }, + { 250u, 18u }, + { 6u, 18u }, + { 250u, 238u }, + { 6u, 238u }, + { 249u, 18u }, + { 7u, 18u }, + { 249u, 238u }, + { 7u, 238u }, + { 248u, 18u }, + { 8u, 18u }, + { 248u, 238u }, + { 8u, 238u }, + { 247u, 18u }, + { 9u, 18u }, + { 247u, 238u }, + { 9u, 238u }, + { 246u, 18u }, + { 10u, 18u }, + { 246u, 238u }, + { 10u, 238u }, + { 245u, 18u }, + { 11u, 18u }, + { 245u, 238u }, + { 11u, 238u }, + { 244u, 18u }, + { 12u, 18u }, + { 244u, 238u }, + { 12u, 238u }, + { 243u, 18u }, + { 13u, 18u }, + { 243u, 238u }, + { 13u, 238u }, + { 242u, 18u }, + { 14u, 18u }, + { 242u, 238u }, + { 14u, 238u }, + { 241u, 18u }, + { 15u, 18u }, + { 241u, 238u }, + { 15u, 238u }, + { 240u, 18u }, + { 16u, 18u }, + { 240u, 238u }, + { 16u, 238u }, + { 239u, 18u }, + { 17u, 18u }, + { 239u, 238u }, + { 17u, 238u }, + { 239u, 17u }, + { 17u, 17u }, + { 239u, 239u }, + { 17u, 239u }, + { 238u, 17u }, + { 18u, 17u }, + { 238u, 239u }, + { 18u, 239u }, + { 238u, 16u }, + { 18u, 16u }, + { 238u, 240u }, + { 18u, 240u }, + { 238u, 15u }, + { 18u, 15u }, + { 238u, 241u }, + { 18u, 241u }, + { 238u, 14u }, + { 18u, 14u }, + { 238u, 242u }, + { 18u, 242u }, + { 238u, 13u }, + { 18u, 13u }, + { 238u, 243u }, + { 18u, 243u }, + { 238u, 12u }, + { 18u, 12u }, + { 238u, 244u }, + { 18u, 244u }, + { 238u, 11u }, + { 18u, 11u }, + { 238u, 245u }, + { 18u, 245u }, + { 238u, 10u }, + { 18u, 10u }, + { 238u, 246u }, + { 18u, 246u }, + { 238u, 9u }, + { 18u, 9u }, + { 238u, 247u }, + { 18u, 247u }, + { 238u, 8u }, + { 18u, 8u }, + { 238u, 248u }, + { 18u, 248u }, + { 238u, 7u }, + { 18u, 7u }, + { 238u, 249u }, + { 18u, 249u }, + { 238u, 6u }, + { 18u, 6u }, + { 238u, 250u }, + { 18u, 250u }, + { 238u, 5u }, + { 18u, 5u }, + { 238u, 251u }, + { 18u, 251u }, + { 238u, 4u }, + { 18u, 4u }, + { 238u, 252u }, + { 18u, 252u }, + { 238u, 3u }, + { 18u, 3u }, + { 238u, 253u }, + { 18u, 253u }, + { 238u, 2u }, + { 18u, 2u }, + { 238u, 254u }, + { 18u, 254u }, + { 238u, 1u }, + { 18u, 1u }, + { 238u, 255u }, + { 18u, 255u }, + { 238u, 0u }, + { 18u, 0u } + } +}; +unsigned char vCrawlTable[23][30] = +{ + { + 1u, + 0u, + 2u, + 0u, + 3u, + 0u, + 4u, + 0u, + 5u, + 0u, + 6u, + 0u, + 7u, + 0u, + 8u, + 0u, + 9u, + 0u, + 10u, + 0u, + 11u, + 0u, + 12u, + 0u, + 13u, + 0u, + 14u, + 0u, + 15u, + 0u + }, + { + 1u, + 0u, + 2u, + 0u, + 3u, + 0u, + 4u, + 0u, + 5u, + 0u, + 6u, + 0u, + 7u, + 0u, + 8u, + 1u, + 9u, + 1u, + 10u, + 1u, + 11u, + 1u, + 12u, + 1u, + 13u, + 1u, + 14u, + 1u, + 15u, + 1u + }, + { + 1u, + 0u, + 2u, + 0u, + 3u, + 0u, + 4u, + 1u, + 5u, + 1u, + 6u, + 1u, + 7u, + 1u, + 8u, + 1u, + 9u, + 1u, + 10u, + 1u, + 11u, + 1u, + 12u, + 2u, + 13u, + 2u, + 14u, + 2u, + 15u, + 2u + }, + { + 1u, + 0u, + 2u, + 0u, + 3u, + 1u, + 4u, + 1u, + 5u, + 1u, + 6u, + 1u, + 7u, + 1u, + 8u, + 2u, + 9u, + 2u, + 10u, + 2u, + 11u, + 2u, + 12u, + 2u, + 13u, + 3u, + 14u, + 3u, + 15u, + 3u + }, + { + 1u, + 0u, + 2u, + 1u, + 3u, + 1u, + 4u, + 1u, + 5u, + 1u, + 6u, + 2u, + 7u, + 2u, + 8u, + 2u, + 9u, + 3u, + 10u, + 3u, + 11u, + 3u, + 12u, + 3u, + 13u, + 4u, + 14u, + 4u, + 0u, + 0u + }, + { + 1u, + 0u, + 2u, + 1u, + 3u, + 1u, + 4u, + 1u, + 5u, + 2u, + 6u, + 2u, + 7u, + 3u, + 8u, + 3u, + 9u, + 3u, + 10u, + 4u, + 11u, + 4u, + 12u, + 4u, + 13u, + 5u, + 14u, + 5u, + 0u, + 0u + }, + { + 1u, + 0u, + 2u, + 1u, + 3u, + 1u, + 4u, + 2u, + 5u, + 2u, + 6u, + 3u, + 7u, + 3u, + 8u, + 3u, + 9u, + 4u, + 10u, + 4u, + 11u, + 5u, + 12u, + 5u, + 13u, + 6u, + 14u, + 6u, + 0u, + 0u + }, + { + 1u, + 1u, + 2u, + 1u, + 3u, + 2u, + 4u, + 2u, + 5u, + 3u, + 6u, + 3u, + 7u, + 4u, + 8u, + 4u, + 9u, + 5u, + 10u, + 5u, + 11u, + 6u, + 12u, + 6u, + 13u, + 7u, + 0u, + 0u, + 0u, + 0u + }, + { + 1u, + 1u, + 2u, + 1u, + 3u, + 2u, + 4u, + 2u, + 5u, + 3u, + 6u, + 4u, + 7u, + 4u, + 8u, + 5u, + 9u, + 6u, + 10u, + 6u, + 11u, + 7u, + 12u, + 7u, + 12u, + 8u, + 13u, + 8u, + 0u, + 0u + }, + { + 1u, + 1u, + 2u, + 2u, + 3u, + 2u, + 4u, + 3u, + 5u, + 4u, + 6u, + 5u, + 7u, + 5u, + 8u, + 6u, + 9u, + 7u, + 10u, + 7u, + 10u, + 8u, + 11u, + 8u, + 12u, + 9u, + 0u, + 0u, + 0u, + 0u + }, + { + 1u, + 1u, + 2u, + 2u, + 3u, + 3u, + 4u, + 4u, + 5u, + 5u, + 6u, + 5u, + 7u, + 6u, + 8u, + 7u, + 9u, + 8u, + 10u, + 9u, + 11u, + 9u, + 11u, + 10u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u + }, + { + 1u, + 1u, + 2u, + 2u, + 3u, + 3u, + 4u, + 4u, + 5u, + 5u, + 6u, + 6u, + 7u, + 7u, + 8u, + 8u, + 9u, + 9u, + 10u, + 10u, + 11u, + 11u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u + }, + { + 1u, + 1u, + 2u, + 2u, + 3u, + 3u, + 4u, + 4u, + 5u, + 5u, + 5u, + 6u, + 6u, + 7u, + 7u, + 8u, + 8u, + 9u, + 9u, + 10u, + 9u, + 11u, + 10u, + 11u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u + }, + { + 1u, + 1u, + 2u, + 2u, + 2u, + 3u, + 3u, + 4u, + 4u, + 5u, + 5u, + 6u, + 5u, + 7u, + 6u, + 8u, + 7u, + 9u, + 7u, + 10u, + 8u, + 10u, + 8u, + 11u, + 9u, + 12u, + 0u, + 0u, + 0u, + 0u + }, + { + 1u, + 1u, + 1u, + 2u, + 2u, + 3u, + 2u, + 4u, + 3u, + 5u, + 4u, + 6u, + 4u, + 7u, + 5u, + 8u, + 6u, + 9u, + 6u, + 10u, + 7u, + 11u, + 7u, + 12u, + 8u, + 12u, + 8u, + 13u, + 0u, + 0u + }, + { + 1u, + 1u, + 1u, + 2u, + 2u, + 3u, + 2u, + 4u, + 3u, + 5u, + 3u, + 6u, + 4u, + 7u, + 4u, + 8u, + 5u, + 9u, + 5u, + 10u, + 6u, + 11u, + 6u, + 12u, + 7u, + 13u, + 0u, + 0u, + 0u, + 0u + }, + { + 0u, + 1u, + 1u, + 2u, + 1u, + 3u, + 2u, + 4u, + 2u, + 5u, + 3u, + 6u, + 3u, + 7u, + 3u, + 8u, + 4u, + 9u, + 4u, + 10u, + 5u, + 11u, + 5u, + 12u, + 6u, + 13u, + 6u, + 14u, + 0u, + 0u + }, + { + 0u, + 1u, + 1u, + 2u, + 1u, + 3u, + 1u, + 4u, + 2u, + 5u, + 2u, + 6u, + 3u, + 7u, + 3u, + 8u, + 3u, + 9u, + 4u, + 10u, + 4u, + 11u, + 4u, + 12u, + 5u, + 13u, + 5u, + 14u, + 0u, + 0u + }, + { + 0u, + 1u, + 1u, + 2u, + 1u, + 3u, + 1u, + 4u, + 1u, + 5u, + 2u, + 6u, + 2u, + 7u, + 2u, + 8u, + 3u, + 9u, + 3u, + 10u, + 3u, + 11u, + 3u, + 12u, + 4u, + 13u, + 4u, + 14u, + 0u, + 0u + }, + { + 0u, + 1u, + 0u, + 2u, + 1u, + 3u, + 1u, + 4u, + 1u, + 5u, + 1u, + 6u, + 1u, + 7u, + 2u, + 8u, + 2u, + 9u, + 2u, + 10u, + 2u, + 11u, + 2u, + 12u, + 3u, + 13u, + 3u, + 14u, + 3u, + 15u + }, + { + 0u, + 1u, + 0u, + 2u, + 0u, + 3u, + 1u, + 4u, + 1u, + 5u, + 1u, + 6u, + 1u, + 7u, + 1u, + 8u, + 1u, + 9u, + 1u, + 10u, + 1u, + 11u, + 2u, + 12u, + 2u, + 13u, + 2u, + 14u, + 2u, + 15u + }, + { + 0u, + 1u, + 0u, + 2u, + 0u, + 3u, + 0u, + 4u, + 0u, + 5u, + 0u, + 6u, + 0u, + 7u, + 1u, + 8u, + 1u, + 9u, + 1u, + 10u, + 1u, + 11u, + 1u, + 12u, + 1u, + 13u, + 1u, + 14u, + 1u, + 15u + }, + { + 0u, + 1u, + 0u, + 2u, + 0u, + 3u, + 0u, + 4u, + 0u, + 5u, + 0u, + 6u, + 0u, + 7u, + 0u, + 8u, + 0u, + 9u, + 0u, + 10u, + 0u, + 11u, + 0u, + 12u, + 0u, + 13u, + 0u, + 14u, + 0u, + 15u + } +}; +unsigned char RadiusAdj[23][15] = +{ + { 0u, 0u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u }, + { 3u, 3u, 3u, 3u, 0u, 1u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u }, + { 3u, 3u, 3u, 3u, 3u, 3u, 3u, 0u, 1u, 2u, 3u, 3u, 3u, 3u, 3u }, + { 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 0u, 0u, 1u, 2u, 3u }, + { 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 0u, 0u }, + { 1u, 1u, 2u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u }, + { 3u, 0u, 0u, 1u, 1u, 2u, 2u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u }, + { 3u, 3u, 3u, 3u, 0u, 0u, 0u, 1u, 1u, 2u, 2u, 3u, 3u, 3u, 3u }, + { 3u, 3u, 3u, 3u, 3u, 3u, 3u, 0u, 0u, 0u, 1u, 1u, 1u, 2u, 2u }, + { 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 0u, 0u, 0u, 0u, 1u }, + { 1u, 2u, 2u, 2u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 0u, 0u }, + { 0u, 0u, 1u, 1u, 1u, 2u, 2u, 2u, 3u, 3u, 3u, 3u, 3u, 3u, 3u }, + { 3u, 0u, 0u, 0u, 0u, 0u, 1u, 1u, 1u, 2u, 2u, 2u, 3u, 3u, 3u }, + { 3u, 3u, 3u, 3u, 0u, 0u, 0u, 0u, 0u, 1u, 1u, 1u, 2u, 2u, 2u }, + { 2u, 3u, 3u, 3u, 3u, 3u, 3u, 0u, 0u, 0u, 0u, 0u, 1u, 1u, 1u }, + { 1u, 2u, 2u, 2u, 2u, 3u, 3u, 3u, 3u, 3u, 0u, 0u, 0u, 0u, 0u }, + { 0u, 1u, 1u, 1u, 1u, 1u, 2u, 2u, 2u, 2u, 3u, 3u, 3u, 0u, 0u }, + { 0u, 0u, 0u, 0u, 1u, 1u, 1u, 1u, 1u, 2u, 2u, 2u, 2u, 2u, 3u }, + { 3u, 0u, 0u, 0u, 0u, 0u, 0u, 1u, 1u, 1u, 1u, 1u, 2u, 2u, 2u }, + { 2u, 2u, 3u, 3u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 1u, 1u, 1u, 1u }, + { 1u, 2u, 2u, 2u, 2u, 2u, 3u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 1u, 1u, 1u, 1u, 1u, 2u, 2u, 2u, 2u, 2u, 0u, 0u, 0u, 0u, 1u }, + { 1u, 1u, 2u, 2u, 2u, 3u, 4u, 3u, 2u, 2u, 2u, 1u, 1u, 1u, 0u } +}; +int log_not_created = 1; // weak +HANDLE log_file = (HANDLE)0xFFFFFFFF; // idb +int menu_music_track_id = 5; // idb +CHAR aUnableToDisp_0[] = "Unable to display mainmenu"; // idb +MissileData missiledata[68] = +{ + { + MIS_ARROW, + &AddArrow, + &MI_Arrow, + 1, + 0u, + 0u, + MFILE_ARROWS, + 4294967295, + 4294967295 + }, + { + MIS_FIREBOLT, + &AddFirebolt, + &MI_Firebolt, + 1, + 1u, + 1u, + MFILE_FIREBA, + LS_FBOLT1, + LS_FIRIMP2 + }, + { + MIS_GUARDIAN, + &AddGuardian, + &MI_Guardian, + 1, + 1u, + 0u, + MFILE_GUARD, + LS_GUARD, + LS_GUARDLAN + }, + { + MIS_RNDTELEPORT, + &AddRndTeleport, + &MI_Teleport, + 0, + 1u, + 0u, + MFILE_NONE, + LS_TELEPORT, + 4294967295 + }, + { + MIS_LIGHTBALL, + &AddLightball, + &MI_Lightball, + 1, + 1u, + 2u, + MFILE_LGHNING, + 4294967295, + 4294967295 + }, + { + MIS_FIREWALL, + &AddFirewall, + &MI_Firewall, + 1, + 1u, + 1u, + MFILE_FIREWAL, + LS_WALLLOOP, + LS_FIRIMP2 + }, + { + MIS_FIREBALL, + &AddFireball, + &MI_Fireball, + 1, + 1u, + 1u, + MFILE_FIREBA, + LS_FBOLT1, + LS_FIRIMP2 + }, + { + MIS_LIGHTCTRL, + &AddLightctrl, + &MI_Lightctrl, + 0, + 1u, + 2u, + MFILE_LGHNING, + 4294967295, + 4294967295 + }, + { + MIS_LIGHTNING, + &AddLightning, + &MI_Lightning, + 1, + 1u, + 2u, + MFILE_LGHNING, + LS_LNING1, + LS_ELECIMP1 + }, + { + MIS_MISEXP, + &AddMisexp, + &MI_Misexp, + 1, + 2u, + 0u, + MFILE_MAGBLOS, + 4294967295, + 4294967295 + }, + { + MIS_TOWN, + &AddTown, + &MI_Town, + 1, + 1u, + 3u, + MFILE_PORTAL, + LS_SENTINEL, + LS_ELEMENTL + }, + { + MIS_FLASH, + &AddFlash, + &MI_Flash, + 1, + 1u, + 3u, + MFILE_BLUEXFR, + LS_NOVA, + LS_ELECIMP1 + }, + { + MIS_FLASH2, + &AddFlash2, + &MI_Flash2, + 1, + 1u, + 3u, + MFILE_BLUEXBK, + 4294967295, + 4294967295 + }, + { + MIS_MANASHIELD, + &AddManashield, + &MI_SetManashield, + 0, + 1u, + 3u, + MFILE_MANASHLD, + LS_MSHIELD, + 4294967295 + }, + { + MIS_FIREMOVE, + &AddFiremove, + &MI_Firemove, + 1, + 1u, + 1u, + MFILE_FIREWAL, + 4294967295, + 4294967295 + }, + { + MIS_CHAIN, + &AddChain, + &MI_Chain, + 1, + 1u, + 2u, + MFILE_LGHNING, + LS_LNING1, + LS_ELECIMP1 + }, + { MIS_NULL_10, NULL, NULL, 1, 1u, 2u, MFILE_LGHNING, 4294967295, 4294967295 }, + { + MIS_NULL_11, + &miss_null_11, + &mi_null_11, + 1, + 2u, + 0u, + MFILE_BLOOD, + LS_BLODSTAR, + LS_BLSIMPT + }, + { + MIS_NULL_12, + &miss_null_12, + &mi_null_11, + 1, + 2u, + 0u, + MFILE_BONE, + 4294967295, + 4294967295 + }, + { + MIS_NULL_13, + &miss_null_13, + &mi_null_11, + 1, + 2u, + 0u, + MFILE_METLHIT, + 4294967295, + 4294967295 + }, + { + MIS_RHINO, + &AddRhino, + &MI_Rhino, + 1, + 2u, + 0u, + MFILE_NONE, + 4294967295, + 4294967295 + }, + { + MIS_MAGMABALL, + &AddMagmaball, + &MI_Firebolt, + 1, + 1u, + 1u, + MFILE_MAGBALL, + 4294967295, + 4294967295 + }, + { + MIS_LIGHTCTRL2, + &AddLightctrl, + &MI_Lightctrl, + 0, + 1u, + 2u, + MFILE_THINLGHT, + 4294967295, + 4294967295 + }, + { + MIS_LIGHTNING2, + &AddLightning, + &MI_Lightning, + 1, + 1u, + 2u, + MFILE_THINLGHT, + 4294967295, + 4294967295 + }, + { + MIS_FLARE, + &AddFlare, + &MI_Firebolt, + 1, + 1u, + 3u, + MFILE_FLARE, + 4294967295, + 4294967295 + }, + { + MIS_MISEXP2, + &AddMisexp, + &MI_Misexp, + 1, + 2u, + 3u, + MFILE_FLAREEXP, + 4294967295, + 4294967295 + }, + { + MIS_TELEPORT, + &AddTeleport, + &MI_Teleport, + 0, + 1u, + 0u, + MFILE_NONE, + LS_ELEMENTL, + 4294967295 + }, + { + MIS_LARROW, + &AddLArrow, + &MI_LArrow, + 1, + 0u, + 1u, + MFILE_FARROW, + 4294967295, + 4294967295 + }, + { MIS_DOOMSERP, NULL, NULL, 0, 1u, 3u, MFILE_DOOM, LS_DSERP, 4294967295 }, + { + MIS_NULL_1D, + &miss_null_1D, + &MI_Firewall, + 1, + 2u, + 1u, + MFILE_FIREWAL, + 4294967295, + 4294967295 + }, + { + MIS_STONE, + &AddStone, + &MI_Stone, + 0, + 1u, + 3u, + MFILE_NONE, + LS_SCURIMP, + 4294967295 + }, + { + MIS_NULL_1F, + &miss_null_1F, + &MI_Dummy, + 1, + 1u, + 0u, + MFILE_NONE, + 4294967295, + 4294967295 + }, + { MIS_INVISIBL, NULL, NULL, 0, 1u, 0u, MFILE_NONE, LS_INVISIBL, 4294967295 }, + { + MIS_GOLEM, + &AddGolem, + &MI_Golem, + 0, + 1u, + 0u, + MFILE_NONE, + LS_GOLUM, + 4294967295 + }, + { + MIS_ETHEREALIZE, + &AddEtherealize, + &MI_Etherealize, + 1, + 1u, + 0u, + MFILE_ETHRSHLD, + LS_ETHEREAL, + 4294967295 + }, + { + MIS_NULL_23, + &miss_null_23, + &mi_null_11, + 1, + 2u, + 0u, + MFILE_BLODBUR, + 4294967295, + 4294967295 + }, + { + MIS_BOOM, + &AddBoom, + &MI_Boom, + 1, + 2u, + 0u, + MFILE_NEWEXP, + 4294967295, + 4294967295 + }, + { + MIS_HEAL, + &AddHeal, + &MI_Dummy, + 0, + 1u, + 0u, + MFILE_NONE, + 4294967295, + 4294967295 + }, + { + MIS_FIREWALLC, + &AddFirewallC, + &MI_FirewallC, + 0, + 1u, + 1u, + MFILE_FIREWAL, + 4294967295, + 4294967295 + }, + { + MIS_INFRA, + &AddInfra, + &MI_Infra, + 0, + 1u, + 0u, + MFILE_NONE, + LS_INFRAVIS, + 4294967295 + }, + { + MIS_IDENTIFY, + &AddIdentify, + &MI_Dummy, + 0, + 1u, + 0u, + MFILE_NONE, + 4294967295, + 4294967295 + }, + { + MIS_WAVE, + &AddWave, + &MI_Wave, + 1, + 1u, + 1u, + MFILE_FIREWAL, + LS_FLAMWAVE, + 4294967295 + }, + { + MIS_NOVA, + &AddNova, + &MI_Nova, + 1, + 1u, + 2u, + MFILE_LGHNING, + LS_NOVA, + 4294967295 + }, + { + MIS_BLODBOIL, + &miss_null_1F, + &MI_Blodboil, + 1, + 1u, + 0u, + MFILE_NONE, + 4294967295, + LS_BLODBOIL + }, + { + MIS_APOCA, + &AddApoca, + &MI_Apoca, + 1, + 1u, + 3u, + MFILE_NEWEXP, + LS_APOC, + 4294967295 + }, + { + MIS_REPAIR, + &AddRepair, + &MI_Dummy, + 0, + 2u, + 0u, + MFILE_NONE, + 4294967295, + 4294967295 + }, + { + MIS_RECHARGE, + &AddRecharge, + &MI_Dummy, + 0, + 2u, + 0u, + MFILE_NONE, + 4294967295, + 4294967295 + }, + { + MIS_DISARM, + &AddDisarm, + &MI_Dummy, + 0, + 2u, + 0u, + MFILE_NONE, + LS_TRAPDIS, + 4294967295 + }, + { + MIS_FLAME, + &AddFlame, + &MI_Flame, + 1, + 1u, + 1u, + MFILE_INFERNO, + LS_SPOUTSTR, + 4294967295 + }, + { + MIS_FLAMEC, + &AddFlamec, + &MI_Flamec, + 0, + 1u, + 1u, + MFILE_NONE, + 4294967295, + 4294967295 + }, + { + MIS_NULL_32, + &miss_null_32, + &mi_null_32, + 1, + 2u, + 0u, + MFILE_NONE, + 4294967295, + 4294967295 + }, + { + MIS_NULL_33, + &miss_null_33, + &mi_null_33, + 1, + 0u, + 1u, + MFILE_KRULL, + 4294967295, + 4294967295 + }, + { + MIS_CBOLT, + &AddCbolt, + &MI_Cbolt, + 1, + 1u, + 2u, + MFILE_MINILTNG, + LS_CBOLT, + 4294967295 + }, + { + MIS_HBOLT, + &AddHbolt, + &MI_Hbolt, + 1, + 1u, + 0u, + MFILE_HOLY, + LS_HOLYBOLT, + LS_ELECIMP1 + }, + { + MIS_RESURRECT, + &AddResurrect, + &MI_Dummy, + 0, + 1u, + 3u, + MFILE_NONE, + 4294967295, + LS_RESUR + }, + { + MIS_TELEKINESIS, + &AddTelekinesis, + &MI_Dummy, + 0, + 1u, + 0u, + MFILE_NONE, + LS_ETHEREAL, + 4294967295 + }, + { + MIS_LARROW2, + &AddLArrow, + &MI_LArrow, + 1, + 0u, + 2u, + MFILE_LARROW, + 4294967295, + 4294967295 + }, + { + MIS_ACID, + &AddAcid, + &MI_Firebolt, + 1, + 1u, + 4u, + MFILE_ACIDBF, + LS_ACID, + 4294967295 + }, + { + MIS_MISEXP3, + &AddMisexp, + &MI_Acidsplat, + 1, + 2u, + 4u, + MFILE_ACIDSPLA, + 4294967295, + 4294967295 + }, + { + MIS_ACIDPUD, + &AddAcidpud, + &MI_Acidpud, + 1, + 2u, + 4u, + MFILE_ACIDPUD, + LS_PUDDLE, + 4294967295 + }, + { + MIS_HEALOTHER, + &AddHealOther, + &MI_Dummy, + 0, + 1u, + 0u, + MFILE_NONE, + 4294967295, + 4294967295 + }, + { + MIS_ELEMENT, + &AddElement, + &MI_Element, + 1, + 1u, + 1u, + MFILE_FIRERUN, + LS_ELEMENTL, + 4294967295 + }, + { + MIS_RESURRECTBEAM, + &AddResurrectBeam, + &MI_ResurrectBeam, + 1, + 1u, + 0u, + MFILE_RESSUR1, + 4294967295, + 4294967295 + }, + { + MIS_BONESPIRIT, + &AddBoneSpirit, + &MI_Bonespirit, + 1, + 1u, + 3u, + MFILE_SKLBALL, + LS_BONESP, + LS_BSIMPCT + }, + { + MIS_WEAPEXP, + &AddWeapexp, + &MI_Weapexp, + 1, + 2u, + 0u, + MFILE_NONE, + 4294967295, + 4294967295 + }, + { + MIS_RPORTAL, + &AddRportal, + &MI_Rportal, + 1, + 2u, + 0u, + MFILE_RPORTAL, + LS_SENTINEL, + LS_ELEMENTL + }, + { + MIS_BOOM2, + &AddBoom, + &MI_Boom, + 1, + 2u, + 0u, + MFILE_FIREPLAR, + 4294967295, + 4294967295 + }, + { + MIS_DIABAPOCA, + &AddDiabApoca, + &MI_Dummy, + 0, + 2u, + 0u, + MFILE_NONE, + 4294967295, + 4294967295 + } +}; +MisFileData misfiledata[47] = +{ + { + MFILE_ARROWS, + 1u, + "Arrows", + 2, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 16u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } + }, + { + MFILE_FIREBA, + 16u, + "Fireba", + 0, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { + 14u, + 14u, + 14u, + 14u, + 14u, + 14u, + 14u, + 14u, + 14u, + 14u, + 14u, + 14u, + 14u, + 14u, + 14u, + 14u + }, + { 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96 }, + { 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 } + }, + { + MFILE_GUARD, + 3u, + "Guard", + 0, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 1u, 1u, 1u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 15u, 14u, 3u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 96, 96, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } + }, + { + MFILE_LGHNING, + 1u, + "Lghning", + 0, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 8u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } + }, + { + MFILE_FIREWAL, + 2u, + "Firewal", + 0, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 13u, 11u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 128, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 32, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } + }, + { + MFILE_MAGBLOS, + 1u, + "MagBlos", + 0, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 1u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 10u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } + }, + { + MFILE_PORTAL, + 2u, + "Portal", + 0, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0u, 1u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 16u, 16u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 96, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } + }, + { + MFILE_BLUEXFR, + 1u, + "Bluexfr", + 0, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 19u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } + }, + { + MFILE_BLUEXBK, + 1u, + "Bluexbk", + 0, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 19u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } + }, + { + MFILE_MANASHLD, + 1u, + "Manashld", + 2, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 1u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } + }, + { + MFILE_BLOOD, + 4u, + "Blood", + 0, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 15u, 8u, 8u, 8u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 96, 128, 128, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 16, 32, 32, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } + }, + { + MFILE_BONE, + 3u, + "Bone", + 0, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 2u, 2u, 2u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 8u, 8u, 8u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 128, 128, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 32, 32, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } + }, + { + MFILE_METLHIT, + 3u, + "Metlhit", + 0, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 2u, 2u, 2u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 10u, 10u, 10u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 96, 96, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } + }, + { + MFILE_FARROW, + 16u, + "Farrow", + 0, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 4u, 4u, 4u, 4u, 4u, 4u, 4u, 4u, 4u, 4u, 4u, 4u, 4u, 4u, 4u, 4u }, + { 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96 }, + { 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 } + }, + { + MFILE_DOOM, + 9u, + "Doom", + 1, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 15u, 15u, 15u, 15u, 15u, 15u, 15u, 15u, 15u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 96, 96, 96, 96, 96, 96, 96, 96, 96, 0, 0, 0, 0, 0, 0, 0 }, + { 16, 16, 16, 16, 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0 } + }, + { + MFILE_0F, + 1u, + " ", + 1, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } + }, + { + MFILE_BLODBUR, + 2u, + "Blodbur", + 0, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 2u, 2u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 8u, 8u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 128, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 32, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } + }, + { + MFILE_NEWEXP, + 1u, + "Newexp", + 0, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 1u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 15u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } + }, + { + MFILE_SHATTER1, + 1u, + "Shatter1", + 0, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 1u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 12u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } + }, + { + MFILE_BIGEXP, + 1u, + "Bigexp", + 0, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 15u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } + }, + { + MFILE_INFERNO, + 1u, + "Inferno", + 0, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 20u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } + }, + { + MFILE_THINLGHT, + 1u, + "Thinlght", + 1, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 8u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } + }, + { + MFILE_FLARE, + 1u, + "Flare", + 0, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 16u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } + }, + { + MFILE_FLAREEXP, + 1u, + "Flareexp", + 0, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 7u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } + }, + { + MFILE_MAGBALL, + 8u, + "Magball", + 1, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 16u, 16u, 16u, 16u, 16u, 16u, 16u, 16u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 128, 128, 128, 128, 128, 128, 128, 128, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 32, 32, 32, 32, 32, 32, 32, 32, 0, 0, 0, 0, 0, 0, 0, 0 } + }, + { + MFILE_KRULL, + 1u, + "Krull", + 1, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 14u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } + }, + { + MFILE_MINILTNG, + 1u, + "Miniltng", + 0, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 1u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 8u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } + }, + { + MFILE_HOLY, + 16u, + "Holy", + 0, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 1u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { + 14u, + 14u, + 14u, + 14u, + 14u, + 14u, + 14u, + 14u, + 14u, + 14u, + 14u, + 14u, + 14u, + 14u, + 14u, + 14u + }, + { 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96 }, + { 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 } + }, + { + MFILE_HOLYEXPL, + 1u, + "Holyexpl", + 0, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 8u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } + }, + { + MFILE_LARROW, + 16u, + "Larrow", + 0, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 4u, 4u, 4u, 4u, 4u, 4u, 4u, 4u, 4u, 4u, 4u, 4u, 4u, 4u, 4u, 4u }, + { 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96 }, + { 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 } + }, + { + MFILE_FIRARWEX, + 1u, + "Firarwex", + 0, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 6u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } + }, + { + MFILE_ACIDBF, + 16u, + "Acidbf", + 1, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 8u, 8u, 8u, 8u, 8u, 8u, 8u, 8u, 8u, 8u, 8u, 8u, 8u, 8u, 8u, 8u }, + { 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96 }, + { 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 } + }, + { + MFILE_ACIDSPLA, + 1u, + "Acidspla", + 1, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 8u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } + }, + { + MFILE_ACIDPUD, + 2u, + "Acidpud", + 1, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 9u, 4u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 96, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } + }, + { + MFILE_ETHRSHLD, + 1u, + "Ethrshld", + 0, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 1u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } + }, + { + MFILE_FIRERUN, + 8u, + "Firerun", + 0, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 12u, 12u, 12u, 12u, 12u, 12u, 12u, 12u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 96, 96, 96, 96, 96, 96, 96, 96, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 16, 16, 16, 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0 } + }, + { + MFILE_RESSUR1, + 1u, + "Ressur1", + 0, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 16u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } + }, + { + MFILE_SKLBALL, + 9u, + "Sklball", + 0, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 16u, 16u, 16u, 16u, 16u, 16u, 16u, 16u, 8u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 96, 96, 96, 96, 96, 96, 96, 96, 96, 0, 0, 0, 0, 0, 0, 0 }, + { 16, 16, 16, 16, 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0 } + }, + { + MFILE_RPORTAL, + 2u, + "Rportal", + 0, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 16u, 16u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 96, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } + }, + { + MFILE_FIREPLAR, + 1u, + "Fireplar", + 1, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 1u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 17u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } + }, + { + MFILE_SCUBMISB, + 1u, + "Scubmisb", + 1, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 16u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } + }, + { + MFILE_SCBSEXPB, + 1u, + "Scbsexpb", + 1, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 6u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } + }, + { + MFILE_SCUBMISC, + 1u, + "Scubmisc", + 1, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 16u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } + }, + { + MFILE_SCBSEXPC, + 1u, + "Scbsexpc", + 1, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 6u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } + }, + { + MFILE_SCUBMISD, + 1u, + "Scubmisd", + 1, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 16u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } + }, + { + MFILE_SCBSEXPD, + 1u, + "Scbsexpd", + 1, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 6u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } + }, + { + MFILE_NONE, + 0u, + &empty_string, + 0, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } + } +}; +int XDirAdd[8] = { 1, 0, 4294967295, 4294967295, 4294967295, 0, 1, 1 }; +int YDirAdd[8] = { 1, 1, 1, 0, 4294967295, 4294967295, 4294967295, 0 }; +MonsterData monsterdata[112] = +{ + { + 128, + 799, + "Monsters\\Zombie\\Zombie%c.CL2", + 0, + "Monsters\\Zombie\\Zombie%c%i.WAV", + 0, + 0, + NULL, + { 11, 24, 12, 6, 16, 0 }, + { 4, 0, 0, 0, 0, 0 }, + "Zombie", + 1u, + 3u, + 1u, + 4, + 7, + MG_ZOMBIE, + 0, + 0u, + 10u, + 8u, + 2u, + 5u, + 0u, + 0u, + 0u, + 0u, + 5u, + MC_UNDEAD, + 72, + 72, + 0, + 3u, + 54 + }, + { + 128, + 799, + "Monsters\\Zombie\\Zombie%c.CL2", + 0, + "Monsters\\Zombie\\Zombie%c%i.WAV", + 0, + 1, + "Monsters\\Zombie\\Bluered.TRN", + { 11, 24, 12, 6, 16, 0 }, + { 4, 0, 0, 0, 0, 0 }, + "Ghoul", + 2u, + 4u, + 2u, + 7, + 11, + MG_ZOMBIE, + 0, + 1u, + 10u, + 8u, + 3u, + 10u, + 0u, + 0u, + 0u, + 0u, + 10u, + MC_UNDEAD, + 72, + 72, + 0, + 3u, + 58 + }, + { + 128, + 799, + "Monsters\\Zombie\\Zombie%c.CL2", + 0, + "Monsters\\Zombie\\Zombie%c%i.WAV", + 0, + 1, + "Monsters\\Zombie\\Grey.TRN", + { 11, 24, 12, 6, 16, 0 }, + { 4, 0, 0, 0, 0, 0 }, + "Rotting Carcass", + 2u, + 6u, + 4u, + 15, + 25, + MG_ZOMBIE, + 0, + 2u, + 25u, + 8u, + 5u, + 15u, + 0u, + 0u, + 0u, + 0u, + 15u, + MC_UNDEAD, + 72, + 74, + 0, + 3u, + 136 + }, + { + 128, + 799, + "Monsters\\Zombie\\Zombie%c.CL2", + 0, + "Monsters\\Zombie\\Zombie%c%i.WAV", + 0, + 1, + "Monsters\\Zombie\\Yellow.TRN", + { 11, 24, 12, 6, 16, 0 }, + { 4, 0, 0, 0, 0, 0 }, + "Black Death", + 4u, + 8u, + 6u, + 25, + 40, + MG_ZOMBIE, + 0, + 3u, + 30u, + 8u, + 6u, + 22u, + 0u, + 0u, + 0u, + 0u, + 20u, + MC_UNDEAD, + 72, + 76, + 0, + 3u, + 240 + }, + { + 128, + 543, + "Monsters\\FalSpear\\Phall%c.CL2", + 1, + "Monsters\\FalSpear\\Phall%c%i.WAV", + 1, + 1, + "Monsters\\FalSpear\\FallenT.TRN", + { 11, 11, 13, 11, 18, 13 }, + { 3, 0, 0, 0, 0, 0 }, + "Fallen One", + 1u, + 3u, + 1u, + 1, + 4, + MG_FALLEN, + 0, + 0u, + 15u, + 7u, + 1u, + 3u, + 0u, + 5u, + 0u, + 0u, + 0u, + MC_ANIMAL, + 0, + 0, + 0, + 3u, + 46 + }, + { + 128, + 543, + "Monsters\\FalSpear\\Phall%c.CL2", + 1, + "Monsters\\FalSpear\\Phall%c%i.WAV", + 1, + 1, + "Monsters\\FalSpear\\Dark.TRN", + { 11, 11, 13, 11, 18, 13 }, + { 3, 0, 0, 0, 0, 0 }, + "Carver", + 2u, + 5u, + 3u, + 4, + 8, + MG_FALLEN, + 0, + 2u, + 20u, + 7u, + 2u, + 5u, + 0u, + 5u, + 0u, + 0u, + 5u, + MC_ANIMAL, + 0, + 0, + 0, + 3u, + 80 + }, + { + 128, + 543, + "Monsters\\FalSpear\\Phall%c.CL2", + 1, + "Monsters\\FalSpear\\Phall%c%i.WAV", + 1, + 0, + NULL, + { 11, 11, 13, 11, 18, 13 }, + { 3, 0, 0, 0, 0, 0 }, + "Devil Kin", + 3u, + 7u, + 5u, + 12, + 24, + MG_FALLEN, + 0, + 2u, + 25u, + 7u, + 3u, + 7u, + 0u, + 5u, + 0u, + 0u, + 10u, + MC_ANIMAL, + 0, + 2, + 0, + 3u, + 155 + }, + { + 128, + 543, + "Monsters\\FalSpear\\Phall%c.CL2", + 1, + "Monsters\\FalSpear\\Phall%c%i.WAV", + 1, + 1, + "Monsters\\FalSpear\\Blue.TRN", + { 11, 11, 13, 11, 18, 13 }, + { 3, 0, 0, 0, 0, 0 }, + "Dark One", + 5u, + 9u, + 7u, + 20, + 36, + MG_FALLEN, + 0, + 3u, + 30u, + 7u, + 4u, + 8u, + 0u, + 5u, + 0u, + 0u, + 15u, + MC_ANIMAL, + 64, + 68, + 0, + 3u, + 255 + }, + { + 128, + 553, + "Monsters\\SkelAxe\\SklAx%c.CL2", + 1, + "Monsters\\SkelAxe\\SklAx%c%i.WAV", + 0, + 1, + "Monsters\\SkelAxe\\White.TRN", + { 12, 8, 13, 6, 17, 16 }, + { 5, 0, 0, 0, 0, 0 }, + "Skeleton", + 1u, + 3u, + 1u, + 2, + 4, + MG_SKELSD, + 0, + 0u, + 20u, + 8u, + 1u, + 4u, + 0u, + 0u, + 0u, + 0u, + 0u, + MC_UNDEAD, + 72, + 72, + 0, + 3u, + 64 + }, + { + 128, + 553, + "Monsters\\SkelAxe\\SklAx%c.CL2", + 1, + "Monsters\\SkelAxe\\SklAx%c%i.WAV", + 0, + 1, + "Monsters\\SkelAxe\\Skelt.TRN", + { 12, 8, 13, 6, 17, 16 }, + { 4, 0, 0, 0, 0, 0 }, + "Corpse Axe", + 2u, + 5u, + 2u, + 4, + 7, + MG_SKELSD, + 0, + 1u, + 25u, + 8u, + 3u, + 5u, + 0u, + 0u, + 0u, + 0u, + 0u, + MC_UNDEAD, + 72, + 72, + 0, + 3u, + 68 + }, + { + 128, + 553, + "Monsters\\SkelAxe\\SklAx%c.CL2", + 1, + "Monsters\\SkelAxe\\SklAx%c%i.WAV", + 0, + 0, + NULL, + { 12, 8, 13, 6, 17, 16 }, + { 2, 0, 0, 0, 0, 0 }, + "Burning Dead", + 2u, + 6u, + 4u, + 8, + 12, + MG_SKELSD, + 0, + 2u, + 30u, + 8u, + 3u, + 7u, + 0u, + 0u, + 0u, + 0u, + 5u, + MC_UNDEAD, + 74, + 88, + 0, + 3u, + 154 + }, + { + 128, + 553, + "Monsters\\SkelAxe\\SklAx%c.CL2", + 1, + "Monsters\\SkelAxe\\SklAx%c%i.WAV", + 0, + 1, + "Monsters\\SkelAxe\\Black.TRN", + { 12, 8, 13, 6, 17, 16 }, + { 3, 0, 0, 0, 0, 0 }, + "Horror", + 4u, + 8u, + 6u, + 12, + 20, + MG_SKELSD, + 0, + 3u, + 35u, + 8u, + 4u, + 9u, + 0u, + 0u, + 0u, + 0u, + 15u, + MC_UNDEAD, + 76, + 76, + 0, + 3u, + 264 + }, + { + 128, + 623, + "Monsters\\FalSword\\Fall%c.CL2", + 1, + "Monsters\\FalSword\\Fall%c%i.WAV", + 1, + 1, + "Monsters\\FalSword\\FallenT.TRN", + { 12, 12, 13, 11, 14, 15 }, + { 3, 0, 0, 0, 0, 0 }, + "Fallen One", + 1u, + 3u, + 1u, + 2, + 5, + MG_FALLEN, + 0, + 0u, + 15u, + 8u, + 1u, + 4u, + 0u, + 5u, + 0u, + 0u, + 10u, + MC_ANIMAL, + 0, + 0, + 0, + 3u, + 52 + }, + { + 128, + 623, + "Monsters\\FalSword\\Fall%c.CL2", + 1, + "Monsters\\FalSword\\Fall%c%i.WAV", + 1, + 1, + "Monsters\\FalSword\\Dark.TRN", + { 12, 12, 13, 11, 14, 15 }, + { 3, 0, 0, 0, 0, 0 }, + "Carver", + 2u, + 5u, + 3u, + 5, + 9, + MG_FALLEN, + 0, + 1u, + 20u, + 8u, + 2u, + 7u, + 0u, + 5u, + 0u, + 0u, + 15u, + MC_ANIMAL, + 0, + 0, + 0, + 3u, + 90 + }, + { + 128, + 623, + "Monsters\\FalSword\\Fall%c.CL2", + 1, + "Monsters\\FalSword\\Fall%c%i.WAV", + 1, + 0, + NULL, + { 12, 12, 13, 11, 14, 15 }, + { 3, 0, 0, 0, 0, 0 }, + "Devil Kin", + 3u, + 7u, + 5u, + 16, + 24, + MG_FALLEN, + 0, + 2u, + 25u, + 8u, + 4u, + 10u, + 0u, + 5u, + 0u, + 0u, + 20u, + MC_ANIMAL, + 0, + 2, + 0, + 3u, + 180 + }, + { + 128, + 623, + "Monsters\\FalSword\\Fall%c.CL2", + 1, + "Monsters\\FalSword\\Fall%c%i.WAV", + 1, + 1, + "Monsters\\FalSword\\Blue.TRN", + { 12, 12, 13, 11, 14, 15 }, + { 3, 0, 0, 0, 0, 0 }, + "Dark One", + 5u, + 9u, + 7u, + 24, + 36, + MG_FALLEN, + 0, + 3u, + 30u, + 8u, + 4u, + 12u, + 0u, + 5u, + 0u, + 0u, + 25u, + MC_ANIMAL, + 64, + 68, + 0, + 3u, + 280 + }, + { + 128, + 410, + "Monsters\\Scav\\Scav%c.CL2", + 1, + "Monsters\\Scav\\Scav%c%i.WAV", + 0, + 0, + NULL, + { 12, 8, 12, 6, 20, 11 }, + { 2, 0, 0, 0, 0, 0 }, + "Scavenger", + 1u, + 4u, + 2u, + 3, + 6, + MG_SCAV, + 0, + 0u, + 20u, + 7u, + 1u, + 5u, + 0u, + 0u, + 0u, + 0u, + 10u, + MC_ANIMAL, + 0, + 2, + 0, + 3u, + 80 + }, + { + 128, + 410, + "Monsters\\Scav\\Scav%c.CL2", + 1, + "Monsters\\Scav\\Scav%c%i.WAV", + 0, + 1, + "Monsters\\Scav\\ScavBr.TRN", + { 12, 8, 12, 6, 20, 11 }, + { 2, 0, 0, 0, 0, 0 }, + "Plague Eater", + 3u, + 6u, + 4u, + 12, + 24, + MG_SCAV, + 0, + 1u, + 30u, + 7u, + 1u, + 8u, + 0u, + 0u, + 0u, + 0u, + 20u, + MC_ANIMAL, + 0, + 4, + 0, + 3u, + 188 + }, + { + 128, + 410, + "Monsters\\Scav\\Scav%c.CL2", + 1, + "Monsters\\Scav\\Scav%c%i.WAV", + 0, + 1, + "Monsters\\Scav\\ScavBe.TRN", + { 12, 8, 12, 6, 20, 11 }, + { 2, 0, 0, 0, 0, 0 }, + "Shadow Beast", + 4u, + 8u, + 6u, + 24, + 36, + MG_SCAV, + 0, + 2u, + 35u, + 7u, + 3u, + 12u, + 0u, + 0u, + 0u, + 0u, + 25u, + MC_ANIMAL, + 64, + 66, + 0, + 3u, + 375 + }, + { + 128, + 410, + "Monsters\\Scav\\Scav%c.CL2", + 1, + "Monsters\\Scav\\Scav%c%i.WAV", + 0, + 1, + "Monsters\\Scav\\ScavW.TRN", + { 12, 8, 12, 6, 20, 11 }, + { 2, 0, 0, 0, 0, 0 }, + "Bone Gasher", + 6u, + 10u, + 8u, + 28, + 40, + MG_SCAV, + 0, + 3u, + 35u, + 7u, + 5u, + 15u, + 0u, + 0u, + 0u, + 0u, + 30u, + MC_ANIMAL, + 65, + 68, + 0, + 3u, + 552 + }, + { + 128, + 567, + "Monsters\\SkelBow\\SklBw%c.CL2", + 1, + "Monsters\\SkelBow\\SklBw%c%i.WAV", + 0, + 1, + "Monsters\\SkelBow\\White.TRN", + { 9, 8, 16, 5, 16, 16 }, + { 4, 0, 0, 0, 0, 0 }, + "Skeleton", + 2u, + 5u, + 3u, + 2, + 4, + MG_SKELBOW, + 0, + 0u, + 15u, + 12u, + 1u, + 2u, + 0u, + 0u, + 0u, + 0u, + 0u, + MC_UNDEAD, + 72, + 72, + 0, + 3u, + 110 + }, + { + 128, + 567, + "Monsters\\SkelBow\\SklBw%c.CL2", + 1, + "Monsters\\SkelBow\\SklBw%c%i.WAV", + 0, + 1, + "Monsters\\SkelBow\\Skelt.TRN", + { 9, 8, 16, 5, 16, 16 }, + { 4, 0, 0, 0, 0, 0 }, + "Corpse Bow", + 3u, + 7u, + 5u, + 8, + 16, + MG_SKELBOW, + 0, + 1u, + 25u, + 12u, + 1u, + 4u, + 0u, + 0u, + 0u, + 0u, + 0u, + MC_UNDEAD, + 72, + 72, + 0, + 3u, + 210 + }, + { + 128, + 567, + "Monsters\\SkelBow\\SklBw%c.CL2", + 1, + "Monsters\\SkelBow\\SklBw%c%i.WAV", + 0, + 0, + NULL, + { 9, 8, 16, 5, 16, 16 }, + { 2, 0, 0, 0, 0, 0 }, + "Burning Dead", + 5u, + 9u, + 7u, + 10, + 24, + MG_SKELBOW, + 0, + 2u, + 30u, + 12u, + 1u, + 6u, + 0u, + 0u, + 0u, + 0u, + 5u, + MC_UNDEAD, + 74, + 88, + 0, + 3u, + 364 + }, + { + 128, + 567, + "Monsters\\SkelBow\\SklBw%c.CL2", + 1, + "Monsters\\SkelBow\\SklBw%c%i.WAV", + 0, + 1, + "Monsters\\SkelBow\\Black.TRN", + { 9, 8, 16, 5, 16, 16 }, + { 3, 0, 0, 0, 0, 0 }, + "Horror", + 7u, + 11u, + 9u, + 15, + 45, + MG_SKELBOW, + 0, + 3u, + 35u, + 12u, + 2u, + 9u, + 0u, + 0u, + 0u, + 0u, + 15u, + MC_UNDEAD, + 76, + 76, + 0, + 3u, + 594 + }, + { + 128, + 575, + "Monsters\\SkelSd\\SklSr%c.CL2", + 1, + "Monsters\\SkelSd\\SklSr%c%i.WAV", + 1, + 1, + "Monsters\\SkelSd\\White.TRN", + { 13, 8, 12, 7, 15, 16 }, + { 4, 0, 0, 0, 0, 0 }, + "Skeleton Captain", + 1u, + 4u, + 2u, + 3, + 6, + MG_SKELSD, + 0, + 0u, + 20u, + 8u, + 2u, + 7u, + 0u, + 0u, + 0u, + 0u, + 10u, + MC_UNDEAD, + 72, + 72, + 0, + 3u, + 90 + }, + { + 128, + 575, + "Monsters\\SkelSd\\SklSr%c.CL2", + 1, + "Monsters\\SkelSd\\SklSr%c%i.WAV", + 0, + 1, + "Monsters\\SkelSd\\Skelt.TRN", + { 13, 8, 12, 7, 15, 16 }, + { 4, 0, 0, 0, 0, 0 }, + "Corpse Captain", + 2u, + 6u, + 4u, + 12, + 20, + MG_SKELSD, + 0, + 1u, + 30u, + 8u, + 3u, + 9u, + 0u, + 0u, + 0u, + 0u, + 5u, + MC_UNDEAD, + 72, + 72, + 0, + 3u, + 200 + }, + { + 128, + 575, + "Monsters\\SkelSd\\SklSr%c.CL2", + 1, + "Monsters\\SkelSd\\SklSr%c%i.WAV", + 0, + 0, + NULL, + { 13, 8, 12, 7, 15, 16 }, + { 4, 0, 0, 0, 0, 0 }, + "Burning Dead Captain", + 4u, + 8u, + 6u, + 16, + 30, + MG_SKELSD, + 0, + 2u, + 35u, + 8u, + 4u, + 10u, + 0u, + 0u, + 0u, + 0u, + 15u, + MC_UNDEAD, + 74, + 88, + 0, + 3u, + 393 + }, + { + 128, + 575, + "Monsters\\SkelSd\\SklSr%c.CL2", + 1, + "Monsters\\SkelSd\\SklSr%c%i.WAV", + 0, + 1, + "Monsters\\SkelSd\\Black.TRN", + { 13, 8, 12, 7, 15, 16 }, + { 4, 0, 0, 0, 0, 0 }, + "Horror Captain", + 6u, + 10u, + 8u, + 35, + 50, + MG_SKELSD, + 256, + 3u, + 40u, + 8u, + 5u, + 14u, + 0u, + 0u, + 0u, + 0u, + 30u, + MC_UNDEAD, + 76, + 76, + 0, + 3u, + 604 + }, + { + 128, + 2000, + "Monsters\\TSneak\\TSneak%c.CL2", + 0, + "Monsters\\TSneak\\Sneakl%c%i.WAV", + 0, + 0, + NULL, + { 13, 13, 15, 11, 16, 0 }, + { 2, 0, 0, 0, 0, 0 }, + "Invisible Lord", + 14u, + 14u, + 14u, + 278, + 278, + MG_SKELSD, + 256, + 3u, + 65u, + 8u, + 16u, + 30u, + 0u, + 0u, + 0u, + 0u, + 60u, + MC_DEMON, + 71, + 71, + 0, + 3u, + 2000 + }, + { + 128, + 992, + "Monsters\\Sneak\\Sneak%c.CL2", + 1, + "Monsters\\Sneak\\Sneak%c%i.WAV", + 0, + 0, + NULL, + { 16, 8, 12, 8, 24, 15 }, + { 2, 0, 0, 0, 0, 0 }, + "Hidden", + 3u, + 8u, + 5u, + 8, + 24, + MG_SNEAK, + 1, + 0u, + 35u, + 8u, + 3u, + 6u, + 0u, + 0u, + 0u, + 0u, + 25u, + MC_DEMON, + 0, + 64, + 0, + 3u, + 278 + }, + { + 128, + 992, + "Monsters\\Sneak\\Sneak%c.CL2", + 1, + "Monsters\\Sneak\\Sneak%c%i.WAV", + 0, + 1, + "Monsters\\Sneak\\Sneakv2.TRN", + { 16, 8, 12, 8, 24, 15 }, + { 2, 0, 0, 0, 0, 0 }, + "Stalker", + 8u, + 12u, + 9u, + 30, + 45, + MG_SNEAK, + 257, + 1u, + 40u, + 8u, + 8u, + 16u, + 0u, + 0u, + 0u, + 0u, + 30u, + MC_DEMON, + 0, + 64, + 0, + 3u, + 630 + }, + { + 128, + 992, + "Monsters\\Sneak\\Sneak%c.CL2", + 1, + "Monsters\\Sneak\\Sneak%c%i.WAV", + 0, + 1, + "Monsters\\Sneak\\Sneakv3.TRN", + { 16, 8, 12, 8, 24, 15 }, + { 2, 0, 0, 0, 0, 0 }, + "Unseen", + 10u, + 14u, + 11u, + 35, + 50, + MG_SNEAK, + 257, + 2u, + 45u, + 8u, + 12u, + 20u, + 0u, + 0u, + 0u, + 0u, + 30u, + MC_DEMON, + 65, + 72, + 0, + 3u, + 935 + }, + { + 128, + 992, + "Monsters\\Sneak\\Sneak%c.CL2", + 1, + "Monsters\\Sneak\\Sneak%c%i.WAV", + 0, + 1, + "Monsters\\Sneak\\Sneakv1.TRN", + { 16, 8, 12, 8, 24, 15 }, + { 2, 0, 0, 0, 0, 0 }, + "Illusion Weaver", + 14u, + 18u, + 13u, + 40, + 60, + MG_SNEAK, + 257, + 3u, + 60u, + 8u, + 16u, + 24u, + 0u, + 0u, + 0u, + 0u, + 30u, + MC_DEMON, + 3, + 74, + 0, + 3u, + 1500 + }, + { + 160, + 2000, + "Monsters\\GoatLord\\GoatL%c.CL2", + 0, + "Monsters\\GoatLord\\Goatl%c%i.WAV", + 0, + 0, + NULL, + { 13, 13, 14, 9, 16, 0 }, + { 2, 0, 0, 0, 0, 0 }, + "Lord Sayter", + 13u, + 13u, + 12u, + 351, + 351, + MG_SKELSD, + 256, + 3u, + 80u, + 8u, + 14u, + 24u, + 0u, + 0u, + 0u, + 0u, + 60u, + MC_DEMON, + 67, + 67, + 0, + 3u, + 1500 + }, + { + 128, + 1030, + "Monsters\\GoatMace\\Goat%c.CL2", + 1, + "Monsters\\GoatMace\\Goat%c%i.WAV", + 0, + 0, + NULL, + { 12, 8, 12, 6, 20, 12 }, + { 2, 0, 0, 0, 1, 0 }, + "Flesh Clan", + 6u, + 10u, + 8u, + 30, + 45, + MG_GOATMC, + 768, + 0u, + 50u, + 8u, + 4u, + 10u, + 0u, + 0u, + 0u, + 0u, + 40u, + MC_DEMON, + 0, + 0, + 0, + 3u, + 460 + }, + { + 128, + 1030, + "Monsters\\GoatMace\\Goat%c.CL2", + 1, + "Monsters\\GoatMace\\Goat%c%i.WAV", + 0, + 1, + "Monsters\\GoatMace\\Beige.TRN", + { 12, 8, 12, 6, 20, 12 }, + { 2, 0, 0, 0, 1, 0 }, + "Stone Clan", + 8u, + 12u, + 10u, + 40, + 55, + MG_GOATMC, + 768, + 1u, + 60u, + 8u, + 6u, + 12u, + 0u, + 0u, + 0u, + 0u, + 40u, + MC_DEMON, + 65, + 72, + 0, + 3u, + 685 + }, + { + 128, + 1030, + "Monsters\\GoatMace\\Goat%c.CL2", + 1, + "Monsters\\GoatMace\\Goat%c%i.WAV", + 0, + 1, + "Monsters\\GoatMace\\Red.TRN", + { 12, 8, 12, 6, 20, 12 }, + { 2, 0, 0, 0, 1, 0 }, + "Fire Clan", + 10u, + 14u, + 12u, + 50, + 65, + MG_GOATMC, + 768, + 2u, + 70u, + 8u, + 8u, + 16u, + 0u, + 0u, + 0u, + 0u, + 45u, + MC_DEMON, + 2, + 16, + 0, + 3u, + 906 + }, + { + 128, + 1030, + "Monsters\\GoatMace\\Goat%c.CL2", + 1, + "Monsters\\GoatMace\\Goat%c%i.WAV", + 0, + 1, + "Monsters\\GoatMace\\Gray.TRN", + { 12, 8, 12, 6, 20, 12 }, + { 2, 0, 0, 0, 1, 0 }, + "Night Clan", + 12u, + 16u, + 14u, + 55, + 70, + MG_GOATMC, + 768, + 3u, + 80u, + 8u, + 10u, + 20u, + 15u, + 0u, + 30u, + 30u, + 50u, + MC_DEMON, + 65, + 72, + 0, + 3u, + 1190 + }, + { + 96, + 364, + "Monsters\\Bat\\Bat%c.CL2", + 0, + "Monsters\\Bat\\Bat%c%i.WAV", + 0, + 1, + "Monsters\\Bat\\red.trn", + { 9, 13, 10, 9, 13, 0 }, + { 0, 0, 0, 0, 0, 0 }, + "Fiend", + 2u, + 5u, + 3u, + 3, + 6, + MG_BAT, + 0, + 0u, + 35u, + 5u, + 1u, + 6u, + 0u, + 0u, + 0u, + 0u, + 0u, + MC_ANIMAL, + 0, + 0, + 16384, + 6u, + 102 + }, + { + 96, + 364, + "Monsters\\Bat\\Bat%c.CL2", + 0, + "Monsters\\Bat\\Bat%c%i.WAV", + 0, + 0, + NULL, + { 9, 13, 10, 9, 13, 0 }, + { 0, 0, 0, 0, 0, 0 }, + "Blink", + 5u, + 9u, + 7u, + 12, + 28, + MG_BAT, + 0, + 1u, + 45u, + 5u, + 1u, + 8u, + 0u, + 0u, + 0u, + 0u, + 15u, + MC_ANIMAL, + 0, + 0, + 16384, + 6u, + 340 + }, + { + 96, + 364, + "Monsters\\Bat\\Bat%c.CL2", + 0, + "Monsters\\Bat\\Bat%c%i.WAV", + 0, + 1, + "Monsters\\Bat\\grey.trn", + { 9, 13, 10, 9, 13, 0 }, + { 0, 0, 0, 0, 0, 0 }, + "Gloom", + 7u, + 11u, + 9u, + 28, + 36, + MG_BAT, + 256, + 2u, + 70u, + 5u, + 4u, + 12u, + 0u, + 0u, + 0u, + 0u, + 35u, + MC_ANIMAL, + 1, + 65, + 16384, + 6u, + 509 + }, + { + 96, + 364, + "Monsters\\Bat\\Bat%c.CL2", + 0, + "Monsters\\Bat\\Bat%c%i.WAV", + 0, + 1, + "Monsters\\Bat\\orange.trn", + { 9, 13, 10, 9, 13, 0 }, + { 0, 0, 0, 0, 0, 0 }, + "Familiar", + 11u, + 15u, + 13u, + 20, + 35, + MG_BAT, + 256, + 3u, + 50u, + 5u, + 4u, + 16u, + 0u, + 0u, + 0u, + 0u, + 35u, + MC_DEMON, + 33, + 97, + 16384, + 6u, + 448 + }, + { + 128, + 1040, + "Monsters\\GoatBow\\GoatB%c.CL2", + 0, + "Monsters\\GoatBow\\GoatB%c%i.WAV", + 0, + 0, + NULL, + { 12, 8, 16, 6, 20, 0 }, + { 3, 0, 0, 0, 0, 0 }, + "Flesh Clan", + 6u, + 10u, + 8u, + 20, + 35, + MG_GOATBOW, + 512, + 0u, + 35u, + 13u, + 1u, + 7u, + 0u, + 0u, + 0u, + 0u, + 35u, + MC_DEMON, + 0, + 0, + 0, + 3u, + 448 + }, + { + 128, + 1040, + "Monsters\\GoatBow\\GoatB%c.CL2", + 0, + "Monsters\\GoatBow\\GoatB%c%i.WAV", + 0, + 1, + "Monsters\\GoatBow\\Beige.TRN", + { 12, 8, 16, 6, 20, 0 }, + { 3, 0, 0, 0, 0, 0 }, + "Stone Clan", + 8u, + 12u, + 10u, + 30, + 40, + MG_GOATBOW, + 512, + 1u, + 40u, + 13u, + 2u, + 9u, + 0u, + 0u, + 0u, + 0u, + 35u, + MC_DEMON, + 65, + 72, + 0, + 3u, + 645 + }, + { + 128, + 1040, + "Monsters\\GoatBow\\GoatB%c.CL2", + 0, + "Monsters\\GoatBow\\GoatB%c%i.WAV", + 0, + 1, + "Monsters\\GoatBow\\Red.TRN", + { 12, 8, 16, 6, 20, 0 }, + { 3, 0, 0, 0, 0, 0 }, + "Fire Clan", + 10u, + 14u, + 12u, + 40, + 50, + MG_GOATBOW, + 768, + 2u, + 45u, + 13u, + 3u, + 11u, + 0u, + 0u, + 0u, + 0u, + 35u, + MC_DEMON, + 2, + 16, + 0, + 3u, + 822 + }, + { + 128, + 1040, + "Monsters\\GoatBow\\GoatB%c.CL2", + 0, + "Monsters\\GoatBow\\GoatB%c%i.WAV", + 0, + 1, + "Monsters\\GoatBow\\Gray.TRN", + { 12, 8, 16, 6, 20, 0 }, + { 3, 0, 0, 0, 0, 0 }, + "Night Clan", + 12u, + 16u, + 14u, + 50, + 65, + MG_GOATBOW, + 768, + 3u, + 50u, + 13u, + 4u, + 13u, + 15u, + 0u, + 0u, + 0u, + 40u, + MC_DEMON, + 65, + 72, + 0, + 3u, + 1092 + }, + { + 128, + 716, + "Monsters\\Acid\\Acid%c.CL2", + 1, + "Monsters\\Acid\\Acid%c%i.WAV", + 1, + 0, + NULL, + { 13, 8, 12, 8, 16, 12 }, + { 0, 0, 0, 0, 0, 0 }, + "Acid Beast", + 10u, + 14u, + 11u, + 40, + 66, + MG_ACID, + 0, + 0u, + 40u, + 8u, + 4u, + 12u, + 25u, + 8u, + 0u, + 0u, + 30u, + MC_ANIMAL, + 128, + 136, + 0, + 3u, + 846 + }, + { + 128, + 716, + "Monsters\\Acid\\Acid%c.CL2", + 1, + "Monsters\\Acid\\Acid%c%i.WAV", + 1, + 1, + "Monsters\\Acid\\AcidBlk.TRN", + { 13, 8, 12, 8, 16, 12 }, + { 0, 0, 0, 0, 0, 0 }, + "Poison Spitter", + 14u, + 18u, + 15u, + 60, + 85, + MG_ACID, + 0, + 1u, + 45u, + 8u, + 4u, + 16u, + 25u, + 8u, + 0u, + 0u, + 30u, + MC_ANIMAL, + 128, + 136, + 0, + 3u, + 1248 + }, + { + 128, + 716, + "Monsters\\Acid\\Acid%c.CL2", + 1, + "Monsters\\Acid\\Acid%c%i.WAV", + 1, + 1, + "Monsters\\Acid\\AcidB.TRN", + { 13, 8, 12, 8, 16, 12 }, + { 0, 0, 0, 0, 0, 0 }, + "Pit Beast", + 18u, + 22u, + 21u, + 80, + 110, + MG_ACID, + 0, + 2u, + 55u, + 8u, + 8u, + 18u, + 35u, + 8u, + 0u, + 0u, + 35u, + MC_ANIMAL, + 129, + 140, + 0, + 3u, + 2060 + }, + { + 128, + 716, + "Monsters\\Acid\\Acid%c.CL2", + 1, + "Monsters\\Acid\\Acid%c%i.WAV", + 1, + 1, + "Monsters\\Acid\\AcidR.TRN", + { 13, 8, 12, 8, 16, 12 }, + { 0, 0, 0, 0, 0, 0 }, + "Lava Maw", + 22u, + 27u, + 25u, + 100, + 150, + MG_ACID, + 0, + 3u, + 65u, + 8u, + 10u, + 20u, + 40u, + 8u, + 0u, + 0u, + 35u, + MC_ANIMAL, + 145, + 152, + 0, + 3u, + 2940 + }, + { + 160, + 1010, + "Monsters\\SKing\\SKing%c.CL2", + 1, + "Monsters\\SKing\\SKing%c%i.WAV", + 1, + 1, + "Monsters\\SkelAxe\\White.TRN", + { 8, 6, 16, 6, 16, 6 }, + { 2, 0, 0, 0, 0, 2 }, + "Skeleton King", + 6u, + 6u, + 9u, + 140, + 140, + MG_SKELKING, + 768, + 3u, + 60u, + 8u, + 6u, + 16u, + 0u, + 0u, + 0u, + 0u, + 70u, + MC_UNDEAD, + 78, + 120, + 32769, + 7u, + 570 + }, + { + 128, + 980, + "Monsters\\FatC\\FatC%c.CL2", + 0, + "Monsters\\FatC\\FatC%c%i.WAV", + 0, + 0, + NULL, + { 10, 8, 12, 6, 16, 0 }, + { 1, 0, 0, 0, 0, 0 }, + "The Butcher", + 0u, + 0u, + 1u, + 320, + 320, + MG_CLEAVER, + 0, + 3u, + 50u, + 8u, + 6u, + 12u, + 0u, + 0u, + 0u, + 0u, + 50u, + MC_DEMON, + 6, + 49, + 32768, + 3u, + 710 + }, + { + 128, + 1130, + "Monsters\\Fat\\Fat%c.CL2", + 1, + "Monsters\\Fat\\Fat%c%i.WAV", + 0, + 0, + NULL, + { 8, 10, 15, 6, 16, 10 }, + { 4, 0, 0, 0, 0, 0 }, + "Overlord", + 8u, + 12u, + 10u, + 60, + 80, + MG_FAT, + 0, + 0u, + 55u, + 8u, + 6u, + 12u, + 0u, + 0u, + 0u, + 0u, + 55u, + MC_DEMON, + 0, + 2, + 0, + 3u, + 635 + }, + { + 128, + 1130, + "Monsters\\Fat\\Fat%c.CL2", + 1, + "Monsters\\Fat\\Fat%c%i.WAV", + 0, + 1, + "Monsters\\Fat\\Blue.TRN", + { 8, 10, 15, 6, 16, 10 }, + { 4, 0, 0, 0, 0, 0 }, + "Mud Man", + 13u, + 17u, + 14u, + 100, + 125, + MG_FAT, + 256, + 1u, + 60u, + 8u, + 8u, + 16u, + 0u, + 0u, + 0u, + 0u, + 60u, + MC_DEMON, + 0, + 32, + 0, + 3u, + 1165 + }, + { + 128, + 1130, + "Monsters\\Fat\\Fat%c.CL2", + 1, + "Monsters\\Fat\\Fat%c%i.WAV", + 0, + 1, + "Monsters\\Fat\\FatB.TRN", + { 8, 10, 15, 6, 16, 10 }, + { 4, 0, 0, 0, 0, 0 }, + "Toad Demon", + 15u, + 19u, + 16u, + 135, + 160, + MG_FAT, + 256, + 2u, + 70u, + 8u, + 8u, + 16u, + 40u, + 0u, + 8u, + 20u, + 65u, + MC_DEMON, + 8, + 12, + 0, + 3u, + 1380 + }, + { + 128, + 1130, + "Monsters\\Fat\\Fat%c.CL2", + 1, + "Monsters\\Fat\\Fat%c%i.WAV", + 0, + 1, + "Monsters\\Fat\\FatF.TRN", + { 8, 10, 15, 6, 16, 10 }, + { 4, 0, 0, 0, 0, 0 }, + "Flayed One", + 19u, + 23u, + 20u, + 160, + 200, + MG_FAT, + 256, + 3u, + 85u, + 8u, + 10u, + 20u, + 0u, + 0u, + 0u, + 0u, + 70u, + MC_DEMON, + 17, + 24, + 0, + 3u, + 2058 + }, + { + 160, + 2420, + "Monsters\\Worm\\Worm%c.CL2", + 0, + "Monsters\\Fat\\Fat%c%i.WAV", + 0, + 0, + NULL, + { 13, 13, 13, 11, 19, 0 }, + { 0, 0, 0, 0, 0, 0 }, + "Wyrm", + 9u, + 13u, + 11u, + 60, + 90, + MG_SKELSD, + 0, + 0u, + 40u, + 8u, + 4u, + 10u, + 0u, + 0u, + 0u, + 0u, + 25u, + MC_ANIMAL, + 1, + 1, + 0, + 3u, + 660 + }, + { + 160, + 2420, + "Monsters\\Worm\\Worm%c.CL2", + 0, + "Monsters\\Fat\\Fat%c%i.WAV", + 0, + 0, + NULL, + { 13, 13, 13, 11, 19, 0 }, + { 0, 0, 0, 0, 0, 0 }, + "Cave Slug", + 11u, + 15u, + 13u, + 75, + 110, + MG_SKELSD, + 0, + 1u, + 50u, + 8u, + 6u, + 13u, + 0u, + 0u, + 0u, + 0u, + 30u, + MC_ANIMAL, + 1, + 1, + 0, + 3u, + 994 + }, + { + 160, + 2420, + "Monsters\\Worm\\Worm%c.CL2", + 0, + "Monsters\\Fat\\Fat%c%i.WAV", + 0, + 0, + NULL, + { 13, 13, 13, 11, 19, 0 }, + { 0, 0, 0, 0, 0, 0 }, + "Devil Wyrm", + 13u, + 17u, + 15u, + 100, + 140, + MG_SKELSD, + 0, + 2u, + 55u, + 8u, + 8u, + 16u, + 0u, + 0u, + 0u, + 0u, + 30u, + MC_ANIMAL, + 3, + 3, + 0, + 3u, + 1320 + }, + { + 160, + 2420, + "Monsters\\Worm\\Worm%c.CL2", + 0, + "Monsters\\Fat\\Fat%c%i.WAV", + 0, + 0, + NULL, + { 13, 13, 13, 11, 19, 0 }, + { 0, 0, 0, 0, 0, 0 }, + "Devourer", + 15u, + 19u, + 17u, + 125, + 200, + MG_SKELSD, + 0, + 3u, + 60u, + 8u, + 10u, + 20u, + 0u, + 0u, + 0u, + 0u, + 35u, + MC_ANIMAL, + 67, + 67, + 0, + 3u, + 1827 + }, + { + 128, + 1680, + "Monsters\\Magma\\Magma%c.CL2", + 1, + "Monsters\\Magma\\Magma%c%i.WAV", + 1, + 0, + NULL, + { 8, 10, 14, 7, 18, 18 }, + { 2, 0, 0, 0, 1, 0 }, + "Magma Demon", + 14u, + 17u, + 13u, + 50, + 70, + MG_MAGMA, + 768, + 0u, + 45u, + 4u, + 2u, + 10u, + 50u, + 13u, + 0u, + 0u, + 45u, + MC_DEMON, + 10, + 24, + 0, + 7u, + 1076 + }, + { + 128, + 1680, + "Monsters\\Magma\\Magma%c.CL2", + 1, + "Monsters\\Magma\\Magma%c%i.WAV", + 1, + 1, + "Monsters\\Magma\\Yellow.TRN", + { 8, 10, 14, 7, 18, 18 }, + { 2, 0, 0, 0, 1, 0 }, + "Blood Stone", + 15u, + 19u, + 14u, + 55, + 75, + MG_MAGMA, + 768, + 1u, + 50u, + 4u, + 2u, + 12u, + 50u, + 14u, + 0u, + 0u, + 45u, + MC_DEMON, + 24, + 24, + 0, + 7u, + 1309 + }, + { + 128, + 1680, + "Monsters\\Magma\\Magma%c.CL2", + 1, + "Monsters\\Magma\\Magma%c%i.WAV", + 1, + 1, + "Monsters\\Magma\\Blue.TRN", + { 8, 10, 14, 7, 18, 18 }, + { 2, 0, 0, 0, 1, 0 }, + "Hell Stone", + 16u, + 20u, + 16u, + 60, + 80, + MG_MAGMA, + 768, + 2u, + 60u, + 4u, + 2u, + 20u, + 60u, + 14u, + 0u, + 0u, + 50u, + MC_DEMON, + 24, + 24, + 0, + 7u, + 1680 + }, + { + 128, + 1680, + "Monsters\\Magma\\Magma%c.CL2", + 1, + "Monsters\\Magma\\Magma%c%i.WAV", + 1, + 1, + "Monsters\\Magma\\Wierd.TRN", + { 8, 10, 14, 7, 18, 18 }, + { 2, 0, 0, 0, 1, 0 }, + "Lava Lord", + 17u, + 21u, + 18u, + 70, + 85, + MG_MAGMA, + 768, + 3u, + 75u, + 4u, + 4u, + 24u, + 60u, + 14u, + 0u, + 0u, + 60u, + MC_DEMON, + 24, + 24, + 0, + 7u, + 2124 + }, + { + 160, + 1630, + "Monsters\\Rhino\\Rhino%c.CL2", + 1, + "Monsters\\Rhino\\Rhino%c%i.WAV", + 1, + 0, + NULL, + { 8, 8, 14, 6, 16, 6 }, + { 2, 0, 0, 0, 0, 0 }, + "Horned Demon", + 12u, + 16u, + 13u, + 40, + 80, + MG_RHINO, + 768, + 0u, + 60u, + 7u, + 2u, + 16u, + 100u, + 0u, + 5u, + 32u, + 40u, + MC_ANIMAL, + 0, + 2, + 0, + 7u, + 1172 + }, + { + 160, + 1630, + "Monsters\\Rhino\\Rhino%c.CL2", + 1, + "Monsters\\Rhino\\Rhino%c%i.WAV", + 1, + 1, + "Monsters\\Rhino\\Orange.TRN", + { 8, 8, 14, 6, 16, 6 }, + { 2, 0, 0, 0, 0, 0 }, + "Mud Runner", + 14u, + 18u, + 15u, + 50, + 90, + MG_RHINO, + 768, + 1u, + 70u, + 7u, + 6u, + 18u, + 100u, + 0u, + 12u, + 36u, + 45u, + MC_ANIMAL, + 0, + 2, + 0, + 7u, + 1404 + }, + { + 160, + 1630, + "Monsters\\Rhino\\Rhino%c.CL2", + 1, + "Monsters\\Rhino\\Rhino%c%i.WAV", + 1, + 1, + "Monsters\\Rhino\\Blue.TRN", + { 8, 8, 14, 6, 16, 6 }, + { 2, 0, 0, 0, 0, 0 }, + "Frost Charger", + 16u, + 20u, + 17u, + 60, + 100, + MG_RHINO, + 768, + 2u, + 80u, + 7u, + 8u, + 20u, + 100u, + 0u, + 20u, + 40u, + 50u, + MC_ANIMAL, + 12, + 12, + 0, + 7u, + 1720 + }, + { + 160, + 1630, + "Monsters\\Rhino\\Rhino%c.CL2", + 1, + "Monsters\\Rhino\\Rhino%c%i.WAV", + 1, + 1, + "Monsters\\Rhino\\RhinoB.TRN", + { 8, 8, 14, 6, 16, 6 }, + { 2, 0, 0, 0, 0, 0 }, + "Obsidian Lord", + 18u, + 22u, + 19u, + 70, + 110, + MG_RHINO, + 768, + 3u, + 90u, + 7u, + 10u, + 22u, + 100u, + 0u, + 20u, + 50u, + 55u, + MC_ANIMAL, + 12, + 56, + 0, + 7u, + 1809 + }, + { + 128, + 1740, + "Monsters\\Demskel\\Demskl%c.CL2", + 1, + "Monsters\\Thin\\Thin%c%i.WAV", + 1, + 0, + "Monsters\\Thin\\Thinv3.TRN", + { 10, 8, 20, 6, 24, 16 }, + { 3, 0, 0, 0, 0, 0 }, + "Bone Demon", + 10u, + 14u, + 12u, + 70, + 70, + MG_STORM, + 0, + 0u, + 60u, + 8u, + 6u, + 14u, + 12u, + 0u, + 0u, + 0u, + 50u, + MC_DEMON, + 72, + 72, + 0, + 7u, + 1344 + }, + { + 160, + 1740, + "Monsters\\Thin\\Thin%c.CL2", + 1, + "Monsters\\Thin\\Thin%c%i.WAV", + 1, + 1, + "Monsters\\Thin\\Thinv3.TRN", + { 8, 8, 18, 4, 17, 14 }, + { 3, 0, 0, 0, 0, 0 }, + "Red Death", + 14u, + 18u, + 16u, + 96, + 96, + MG_STORM, + 0, + 1u, + 75u, + 5u, + 10u, + 20u, + 0u, + 0u, + 0u, + 0u, + 60u, + MC_DEMON, + 24, + 24, + 0, + 7u, + 2168 + }, + { + 160, + 1740, + "Monsters\\Thin\\Thin%c.CL2", + 1, + "Monsters\\Thin\\Thin%c%i.WAV", + 1, + 1, + "Monsters\\Thin\\Thinv3.TRN", + { 8, 8, 18, 4, 17, 14 }, + { 3, 0, 0, 0, 0, 0 }, + "Litch Demon", + 16u, + 20u, + 18u, + 110, + 110, + MG_STORM, + 0, + 2u, + 80u, + 5u, + 10u, + 24u, + 0u, + 0u, + 0u, + 0u, + 45u, + MC_DEMON, + 104, + 104, + 0, + 7u, + 2736 + }, + { + 160, + 1740, + "Monsters\\Thin\\Thin%c.CL2", + 1, + "Monsters\\Thin\\Thin%c%i.WAV", + 1, + 1, + "Monsters\\Thin\\Thinv3.TRN", + { 8, 8, 18, 4, 17, 14 }, + { 3, 0, 0, 0, 0, 0 }, + "Undead Balrog", + 20u, + 24u, + 22u, + 130, + 130, + MG_STORM, + 0, + 3u, + 85u, + 5u, + 12u, + 30u, + 0u, + 0u, + 0u, + 0u, + 65u, + MC_DEMON, + 78, + 78, + 0, + 7u, + 3575 + }, + { + 128, + 1460, + "Monsters\\Fireman\\FireM%c.CL2", + 1, + "Monsters\\Acid\\Acid%c%i.WAV", + 0, + 0, + NULL, + { 14, 19, 20, 8, 14, 23 }, + { 0, 0, 0, 0, 0, 0 }, + "Incinerator", + 14u, + 18u, + 16u, + 30, + 45, + MG_FIREMAN, + 0, + 0u, + 75u, + 8u, + 8u, + 16u, + 0u, + 0u, + 0u, + 0u, + 25u, + MC_DEMON, + 24, + 24, + 0, + 3u, + 1888 + }, + { + 128, + 1460, + "Monsters\\Fireman\\FireM%c.CL2", + 1, + "Monsters\\Acid\\Acid%c%i.WAV", + 0, + 0, + NULL, + { 14, 19, 20, 8, 14, 23 }, + { 0, 0, 0, 0, 0, 0 }, + "Flame Lord", + 16u, + 20u, + 18u, + 40, + 55, + MG_FIREMAN, + 0, + 1u, + 75u, + 8u, + 10u, + 20u, + 0u, + 0u, + 0u, + 0u, + 25u, + MC_DEMON, + 24, + 24, + 0, + 3u, + 2250 + }, + { + 128, + 1460, + "Monsters\\Fireman\\FireM%c.CL2", + 1, + "Monsters\\Acid\\Acid%c%i.WAV", + 0, + 0, + NULL, + { 14, 19, 20, 8, 14, 23 }, + { 0, 0, 0, 0, 0, 0 }, + "Doom Fire", + 18u, + 22u, + 20u, + 50, + 65, + MG_FIREMAN, + 0, + 2u, + 80u, + 8u, + 12u, + 24u, + 0u, + 0u, + 0u, + 0u, + 30u, + MC_DEMON, + 28, + 28, + 0, + 3u, + 2740 + }, + { + 128, + 1460, + "Monsters\\Fireman\\FireM%c.CL2", + 1, + "Monsters\\Acid\\Acid%c%i.WAV", + 0, + 0, + NULL, + { 14, 19, 20, 8, 14, 23 }, + { 0, 0, 0, 0, 0, 0 }, + "Hell Burner", + 20u, + 24u, + 22u, + 60, + 80, + MG_FIREMAN, + 0, + 3u, + 85u, + 8u, + 15u, + 30u, + 0u, + 0u, + 0u, + 0u, + 30u, + MC_DEMON, + 28, + 28, + 0, + 3u, + 3355 + }, + { + 160, + 1740, + "Monsters\\Thin\\Thin%c.CL2", + 1, + "Monsters\\Thin\\Thin%c%i.WAV", + 1, + 1, + "Monsters\\Thin\\Thinv3.TRN", + { 8, 8, 18, 4, 17, 14 }, + { 3, 0, 0, 0, 0, 0 }, + "Red Storm", + 17u, + 21u, + 18u, + 55, + 110, + MG_STORM, + 768, + 0u, + 80u, + 5u, + 8u, + 18u, + 75u, + 8u, + 4u, + 16u, + 30u, + MC_DEMON, + 12, + 40, + 0, + 7u, + 2160 + }, + { + 160, + 1740, + "Monsters\\Thin\\Thin%c.CL2", + 1, + "Monsters\\Thin\\Thin%c%i.WAV", + 1, + 0, + NULL, + { 8, 8, 18, 4, 17, 14 }, + { 3, 0, 0, 0, 0, 0 }, + "Storm Rider", + 19u, + 23u, + 20u, + 60, + 120, + MG_STORM, + 768, + 1u, + 80u, + 5u, + 8u, + 18u, + 80u, + 8u, + 4u, + 16u, + 30u, + MC_DEMON, + 33, + 40, + 0, + 7u, + 2391 + }, + { + 160, + 1740, + "Monsters\\Thin\\Thin%c.CL2", + 1, + "Monsters\\Thin\\Thin%c%i.WAV", + 1, + 1, + "Monsters\\Thin\\Thinv2.TRN", + { 8, 8, 18, 4, 17, 14 }, + { 3, 0, 0, 0, 0, 0 }, + "Storm Lord", + 21u, + 25u, + 22u, + 75, + 135, + MG_STORM, + 768, + 2u, + 85u, + 5u, + 12u, + 24u, + 75u, + 8u, + 4u, + 16u, + 35u, + MC_DEMON, + 33, + 40, + 0, + 7u, + 2775 + }, + { + 160, + 1740, + "Monsters\\Thin\\Thin%c.CL2", + 1, + "Monsters\\Thin\\Thin%c%i.WAV", + 1, + 1, + "Monsters\\Thin\\Thinv1.TRN", + { 8, 8, 18, 4, 17, 14 }, + { 3, 0, 0, 0, 0, 0 }, + "Maelstorm", + 23u, + 27u, + 24u, + 90, + 150, + MG_STORM, + 768, + 3u, + 90u, + 5u, + 12u, + 28u, + 75u, + 8u, + 4u, + 16u, + 40u, + MC_DEMON, + 97, + 104, + 0, + 7u, + 3177 + }, + { + 128, + 1650, + "Monsters\\BigFall\\Fallg%c.CL2", + 1, + "Monsters\\BigFall\\Bfal%c%i.WAV", + 0, + 0, + NULL, + { 10, 8, 11, 8, 17, 0 }, + { 0, 0, 0, 0, 2, 2 }, + "Devil Kin Brute", + 20u, + 20u, + 24u, + 160, + 220, + MG_SKELSD, + 768, + 3u, + 100u, + 6u, + 18u, + 24u, + 0u, + 0u, + 0u, + 0u, + 75u, + MC_ANIMAL, + 0, + 0, + 0, + 6u, + 2000 + }, + { + 160, + 1650, + "Monsters\\Gargoyle\\Gargo%c.CL2", + 1, + "Monsters\\Gargoyle\\Gargo%c%i.WAV", + 0, + 0, + NULL, + { 14, 14, 14, 10, 18, 14 }, + { 0, 0, 0, 0, 0, 2 }, + "Winged-Demon", + 8u, + 12u, + 9u, + 45, + 60, + MG_GARG, + 512, + 0u, + 50u, + 7u, + 10u, + 16u, + 0u, + 0u, + 0u, + 0u, + 45u, + MC_DEMON, + 74, + 88, + 0, + 6u, + 662 + }, + { + 160, + 1650, + "Monsters\\Gargoyle\\Gargo%c.CL2", + 1, + "Monsters\\Gargoyle\\Gargo%c%i.WAV", + 0, + 1, + "Monsters\\Gargoyle\\GarE.TRN", + { 14, 14, 14, 10, 18, 14 }, + { 0, 0, 0, 0, 0, 2 }, + "Gargoyle", + 12u, + 16u, + 13u, + 60, + 90, + MG_GARG, + 512, + 1u, + 65u, + 7u, + 10u, + 16u, + 0u, + 0u, + 0u, + 0u, + 45u, + MC_DEMON, + 76, + 104, + 0, + 6u, + 1205 + }, + { + 160, + 1650, + "Monsters\\Gargoyle\\Gargo%c.CL2", + 1, + "Monsters\\Gargoyle\\Gargo%c%i.WAV", + 0, + 1, + "Monsters\\Gargoyle\\GargBr.TRN", + { 14, 14, 14, 10, 18, 14 }, + { 0, 0, 0, 0, 0, 0 }, + "Blood Claw", + 16u, + 20u, + 19u, + 75, + 125, + MG_GARG, + 512, + 2u, + 80u, + 7u, + 14u, + 22u, + 0u, + 0u, + 0u, + 0u, + 50u, + MC_DEMON, + 88, + 92, + 0, + 6u, + 1873 + }, + { + 160, + 1650, + "Monsters\\Gargoyle\\Gargo%c.CL2", + 1, + "Monsters\\Gargoyle\\Gargo%c%i.WAV", + 0, + 1, + "Monsters\\Gargoyle\\GargB.TRN", + { 14, 14, 14, 10, 18, 14 }, + { 0, 0, 0, 0, 0, 0 }, + "Death Wing", + 18u, + 22u, + 23u, + 90, + 150, + MG_GARG, + 512, + 3u, + 95u, + 7u, + 16u, + 28u, + 0u, + 0u, + 0u, + 0u, + 60u, + MC_DEMON, + 104, + 106, + 0, + 6u, + 2278 + }, + { + 160, + 2220, + "Monsters\\Mega\\Mega%c.CL2", + 1, + "Monsters\\Mega\\Mega%c%i.WAV", + 1, + 0, + NULL, + { 6, 7, 14, 1, 24, 5 }, + { 3, 0, 0, 0, 2, 0 }, + "Slayer", + 19u, + 23u, + 20u, + 120, + 140, + MG_MEGA, + 768, + 0u, + 100u, + 8u, + 12u, + 20u, + 0u, + 3u, + 0u, + 0u, + 60u, + MC_DEMON, + 17, + 17, + 0, + 7u, + 2300 + }, + { + 160, + 2220, + "Monsters\\Mega\\Mega%c.CL2", + 1, + "Monsters\\Mega\\Mega%c%i.WAV", + 1, + 1, + "Monsters\\Mega\\Guard.TRN", + { 6, 7, 14, 1, 24, 5 }, + { 3, 0, 0, 0, 2, 0 }, + "Guardian", + 21u, + 25u, + 22u, + 140, + 160, + MG_MEGA, + 768, + 1u, + 110u, + 8u, + 14u, + 22u, + 0u, + 3u, + 0u, + 0u, + 65u, + MC_DEMON, + 17, + 17, + 0, + 7u, + 2714 + }, + { + 160, + 2220, + "Monsters\\Mega\\Mega%c.CL2", + 1, + "Monsters\\Mega\\Mega%c%i.WAV", + 1, + 1, + "Monsters\\Mega\\Vtexl.TRN", + { 6, 7, 14, 1, 24, 5 }, + { 3, 0, 0, 0, 2, 0 }, + "Vortex Lord", + 23u, + 26u, + 24u, + 160, + 180, + MG_MEGA, + 768, + 2u, + 120u, + 8u, + 18u, + 24u, + 0u, + 3u, + 0u, + 0u, + 70u, + MC_DEMON, + 81, + 85, + 0, + 7u, + 3252 + }, + { + 160, + 2220, + "Monsters\\Mega\\Mega%c.CL2", + 1, + "Monsters\\Mega\\Mega%c%i.WAV", + 1, + 1, + "Monsters\\Mega\\Balr.TRN", + { 6, 7, 14, 1, 24, 5 }, + { 3, 0, 0, 0, 2, 0 }, + "Balrog", + 25u, + 29u, + 26u, + 180, + 200, + MG_MEGA, + 768, + 3u, + 130u, + 8u, + 22u, + 30u, + 0u, + 3u, + 0u, + 0u, + 75u, + MC_DEMON, + 81, + 85, + 0, + 7u, + 3643 + }, + { + 160, + 1270, + "Monsters\\Snake\\Snake%c.CL2", + 0, + "Monsters\\Snake\\Snake%c%i.WAV", + 0, + 0, + NULL, + { 12, 11, 13, 5, 18, 0 }, + { 2, 0, 0, 0, 1, 0 }, + "Cave Viper", + 20u, + 24u, + 21u, + 100, + 150, + MG_SNAKE, + 256, + 0u, + 90u, + 8u, + 8u, + 20u, + 0u, + 0u, + 0u, + 0u, + 60u, + MC_DEMON, + 8, + 8, + 0, + 7u, + 2725 + }, + { + 160, + 1270, + "Monsters\\Snake\\Snake%c.CL2", + 0, + "Monsters\\Snake\\Snake%c%i.WAV", + 0, + 1, + "Monsters\\Snake\\SnakR.TRN", + { 12, 11, 13, 5, 18, 0 }, + { 2, 0, 0, 0, 1, 0 }, + "Fire Drake", + 22u, + 26u, + 23u, + 120, + 170, + MG_SNAKE, + 256, + 1u, + 105u, + 8u, + 12u, + 24u, + 0u, + 0u, + 0u, + 0u, + 65u, + MC_DEMON, + 10, + 24, + 0, + 7u, + 3139 + }, + { + 160, + 1270, + "Monsters\\Snake\\Snake%c.CL2", + 0, + "Monsters\\Snake\\Snake%c%i.WAV", + 0, + 1, + "Monsters\\Snake\\Snakg.TRN", + { 12, 11, 13, 5, 18, 0 }, + { 2, 0, 0, 0, 1, 0 }, + "Gold Viper", + 24u, + 27u, + 25u, + 140, + 180, + MG_SNAKE, + 256, + 2u, + 120u, + 8u, + 15u, + 26u, + 0u, + 0u, + 0u, + 0u, + 70u, + MC_DEMON, + 12, + 12, + 0, + 7u, + 3540 + }, + { + 160, + 1270, + "Monsters\\Snake\\Snake%c.CL2", + 0, + "Monsters\\Snake\\Snake%c%i.WAV", + 0, + 1, + "Monsters\\Snake\\Snakb.TRN", + { 12, 11, 13, 5, 18, 0 }, + { 2, 0, 0, 0, 1, 0 }, + "Azure Drake", + 28u, + 30u, + 27u, + 160, + 200, + MG_SNAKE, + 256, + 3u, + 130u, + 8u, + 18u, + 30u, + 0u, + 0u, + 0u, + 0u, + 75u, + MC_DEMON, + 6, + 42, + 0, + 7u, + 3791 + }, + { + 160, + 2120, + "Monsters\\Black\\Black%c.CL2", + 0, + "Monsters\\Black\\Black%c%i.WAV", + 0, + 0, + NULL, + { 8, 8, 16, 4, 24, 0 }, + { 2, 0, 0, 0, 0, 0 }, + "Black Knight", + 23u, + 27u, + 24u, + 150, + 150, + MG_SKELSD, + 256, + 0u, + 110u, + 8u, + 15u, + 20u, + 0u, + 0u, + 0u, + 0u, + 75u, + MC_DEMON, + 69, + 97, + 0, + 7u, + 3360 + }, + { + 160, + 2120, + "Monsters\\Black\\Black%c.CL2", + 0, + "Monsters\\Black\\Black%c%i.WAV", + 0, + 1, + "Monsters\\Black\\BlkKntRT.TRN", + { 8, 8, 16, 4, 24, 0 }, + { 2, 0, 0, 0, 0, 0 }, + "Doom Guard", + 25u, + 29u, + 26u, + 165, + 165, + MG_SKELSD, + 256, + 0u, + 130u, + 8u, + 18u, + 25u, + 0u, + 0u, + 0u, + 0u, + 75u, + MC_DEMON, + 67, + 81, + 0, + 7u, + 3650 + }, + { + 160, + 2120, + "Monsters\\Black\\Black%c.CL2", + 0, + "Monsters\\Black\\Black%c%i.WAV", + 0, + 1, + "Monsters\\Black\\BlkKntBT.TRN", + { 8, 8, 16, 4, 24, 0 }, + { 2, 0, 0, 0, 0, 0 }, + "Steel Lord", + 27u, + 30u, + 28u, + 180, + 180, + MG_SKELSD, + 256, + 1u, + 120u, + 8u, + 20u, + 30u, + 0u, + 0u, + 0u, + 0u, + 80u, + MC_DEMON, + 85, + 92, + 0, + 7u, + 4252 + }, + { + 160, + 2120, + "Monsters\\Black\\Black%c.CL2", + 0, + "Monsters\\Black\\Black%c%i.WAV", + 0, + 1, + "Monsters\\Black\\BlkKntBe.TRN", + { 8, 8, 16, 4, 24, 0 }, + { 2, 0, 0, 0, 0, 0 }, + "Blood Knight", + 24u, + 26u, + 30u, + 200, + 200, + MG_SKELSD, + 256, + 1u, + 130u, + 8u, + 25u, + 35u, + 0u, + 0u, + 0u, + 0u, + 85u, + MC_DEMON, + 106, + 106, + 0, + 7u, + 5130 + }, + { + 96, + 484, + "Monsters\\Unrav\\Unrav%c.CL2", + 0, + "Monsters\\Acid\\Acid%c%i.WAV", + 0, + 0, + NULL, + { 10, 10, 12, 5, 16, 0 }, + { 0, 0, 0, 0, 0, 0 }, + "Unraveler", + 26u, + 28u, + 25u, + 70, + 150, + MG_SKELSD, + 0, + 0u, + 75u, + 7u, + 10u, + 20u, + 0u, + 0u, + 0u, + 0u, + 70u, + MC_UNDEAD, + 106, + 106, + 0, + 3u, + 3812 + }, + { + 96, + 484, + "Monsters\\Unrav\\Unrav%c.CL2", + 0, + "Monsters\\Acid\\Acid%c%i.WAV", + 0, + 0, + NULL, + { 10, 10, 12, 5, 16, 0 }, + { 0, 0, 0, 0, 0, 0 }, + "Hollow One", + 28u, + 30u, + 27u, + 135, + 240, + MG_SKELSD, + 0, + 1u, + 75u, + 7u, + 12u, + 24u, + 0u, + 0u, + 0u, + 0u, + 75u, + MC_UNDEAD, + 92, + 92, + 0, + 3u, + 4374 + }, + { + 96, + 484, + "Monsters\\Unrav\\Unrav%c.CL2", + 0, + "Monsters\\Acid\\Acid%c%i.WAV", + 0, + 0, + NULL, + { 10, 10, 12, 5, 16, 0 }, + { 0, 0, 0, 0, 0, 0 }, + "Pain Master", + 27u, + 30u, + 29u, + 110, + 200, + MG_SKELSD, + 0, + 2u, + 80u, + 7u, + 16u, + 30u, + 0u, + 0u, + 0u, + 0u, + 80u, + MC_UNDEAD, + 92, + 92, + 0, + 3u, + 5147 + }, + { + 96, + 484, + "Monsters\\Unrav\\Unrav%c.CL2", + 0, + "Monsters\\Acid\\Acid%c%i.WAV", + 0, + 0, + NULL, + { 10, 10, 12, 5, 16, 0 }, + { 0, 0, 0, 0, 0, 0 }, + "Reality Weaver", + 28u, + 30u, + 30u, + 135, + 240, + MG_SKELSD, + 0, + 3u, + 85u, + 7u, + 20u, + 35u, + 0u, + 0u, + 0u, + 0u, + 85u, + MC_UNDEAD, + 113, + 113, + 0, + 3u, + 5925 + }, + { + 128, + 980, + "Monsters\\Succ\\Scbs%c.CL2", + 0, + "Monsters\\Succ\\Scbs%c%i.WAV", + 0, + 0, + NULL, + { 14, 8, 16, 7, 24, 0 }, + { 0, 0, 0, 0, 0, 0 }, + "Succubus", + 22u, + 26u, + 24u, + 120, + 150, + MG_SUCC, + 512, + 0u, + 100u, + 10u, + 1u, + 20u, + 0u, + 0u, + 0u, + 0u, + 60u, + MC_DEMON, + 1, + 10, + 0, + 3u, + 3696 + }, + { + 128, + 980, + "Monsters\\Succ\\Scbs%c.CL2", + 0, + "Monsters\\Succ\\Scbs%c%i.WAV", + 0, + 1, + "Monsters\\Succ\\Succb.TRN", + { 14, 8, 16, 7, 24, 0 }, + { 0, 0, 0, 0, 0, 0 }, + "Snow Witch", + 25u, + 28u, + 26u, + 135, + 175, + MG_SUCC, + 512, + 1u, + 110u, + 10u, + 1u, + 24u, + 0u, + 0u, + 0u, + 0u, + 65u, + MC_DEMON, + 68, + 76, + 0, + 3u, + 4084 + }, + { + 128, + 980, + "Monsters\\Succ\\Scbs%c.CL2", + 0, + "Monsters\\Succ\\Scbs%c%i.WAV", + 0, + 1, + "Monsters\\Succ\\Succrw.TRN", + { 14, 8, 16, 7, 24, 0 }, + { 0, 0, 0, 0, 0, 0 }, + "Hell Spawn", + 27u, + 30u, + 28u, + 150, + 200, + MG_SUCC, + 768, + 2u, + 115u, + 10u, + 1u, + 30u, + 0u, + 0u, + 0u, + 0u, + 75u, + MC_DEMON, + 33, + 28, + 0, + 3u, + 4480 + }, + { + 128, + 980, + "Monsters\\Succ\\Scbs%c.CL2", + 0, + "Monsters\\Succ\\Scbs%c%i.WAV", + 0, + 1, + "Monsters\\Succ\\Succbw.TRN", + { 14, 8, 16, 7, 24, 0 }, + { 0, 0, 0, 0, 0, 0 }, + "Soul Burner", + 28u, + 30u, + 30u, + 140, + 225, + MG_SUCC, + 768, + 3u, + 120u, + 10u, + 1u, + 35u, + 0u, + 0u, + 0u, + 0u, + 85u, + MC_DEMON, + 21, + 56, + 0, + 3u, + 4644 + }, + { + 128, + 2000, + "Monsters\\Mage\\Mage%c.CL2", + 1, + "Monsters\\Mage\\Mage%c%i.WAV", + 0, + 0, + NULL, + { 12, 1, 20, 8, 28, 20 }, + { 0, 0, 0, 0, 0, 0 }, + "Counselor", + 24u, + 26u, + 25u, + 70, + 70, + MG_COUNSELOR, + 512, + 0u, + 90u, + 8u, + 8u, + 20u, + 0u, + 0u, + 0u, + 0u, + 0u, + MC_DEMON, + 7, + 7, + 0, + 7u, + 4070 + }, + { + 128, + 2000, + "Monsters\\Mage\\Mage%c.CL2", + 1, + "Monsters\\Mage\\Mage%c%i.WAV", + 0, + 1, + "Monsters\\Mage\\Cnselg.TRN", + { 12, 1, 20, 8, 28, 20 }, + { 0, 0, 0, 0, 0, 0 }, + "Magistrate", + 26u, + 28u, + 27u, + 85, + 85, + MG_COUNSELOR, + 512, + 1u, + 100u, + 8u, + 10u, + 24u, + 0u, + 0u, + 0u, + 0u, + 0u, + MC_DEMON, + 85, + 92, + 0, + 7u, + 4478 + }, + { + 128, + 2000, + "Monsters\\Mage\\Mage%c.CL2", + 1, + "Monsters\\Mage\\Mage%c%i.WAV", + 0, + 1, + "Monsters\\Mage\\Cnselgd.TRN", + { 12, 1, 20, 8, 28, 20 }, + { 0, 0, 0, 0, 0, 0 }, + "Cabalist", + 28u, + 30u, + 29u, + 120, + 120, + MG_COUNSELOR, + 512, + 2u, + 110u, + 8u, + 14u, + 30u, + 0u, + 0u, + 0u, + 0u, + 0u, + MC_DEMON, + 99, + 106, + 0, + 7u, + 4929 + }, + { + 128, + 2000, + "Monsters\\Mage\\Mage%c.CL2", + 1, + "Monsters\\Mage\\Mage%c%i.WAV", + 0, + 1, + "Monsters\\Mage\\Cnselbk.TRN", + { 12, 1, 20, 8, 28, 20 }, + { 0, 0, 0, 0, 0, 0 }, + "Advocate", + 30u, + 30u, + 30u, + 145, + 145, + MG_COUNSELOR, + 512, + 3u, + 120u, + 8u, + 15u, + 25u, + 0u, + 0u, + 0u, + 0u, + 0u, + MC_DEMON, + 106, + 120, + 0, + 7u, + 4968 + }, + { + 96, + 386, + "Monsters\\Golem\\Golem%c.CL2", + 1, + "Monsters\\Golem\\Golm%c%i.WAV", + 0, + 0, + NULL, + { 0, 16, 12, 0, 12, 20 }, + { 0, 0, 0, 0, 0, 0 }, + "Golem", + 0u, + 0u, + 12u, + 1, + 1, + MG_GOLUM, + 512, + 0u, + 0u, + 7u, + 1u, + 1u, + 0u, + 0u, + 0u, + 0u, + 1u, + MC_DEMON, + 0, + 0, + 0, + 0u, + 0 + }, + { + 160, + 2000, + "Monsters\\Diablo\\Diablo%c.CL2", + 1, + "Monsters\\Diablo\\Diablo%c%i.WAV", + 1, + 0, + NULL, + { 16, 6, 16, 6, 16, 16 }, + { 0, 0, 0, 0, 0, 0 }, + "The Dark Lord", + 50u, + 50u, + 30u, + 1666, + 1666, + MG_DIABLO, + 896, + 3u, + 220u, + 4u, + 30u, + 60u, + 0u, + 11u, + 0u, + 0u, + 70u, + MC_DEMON, + 78, + 78, + 0, + 7u, + 31666 + }, + { + 128, + 1060, + "Monsters\\DarkMage\\Dmage%c.CL2", + 1, + "Monsters\\DarkMage\\Dmag%c%i.WAV", + 0, + 0, + NULL, + { 6, 1, 21, 6, 23, 18 }, + { 0, 0, 0, 0, 0, 0 }, + "The Arch-Litch Malignus", + 30u, + 30u, + 30u, + 160, + 160, + MG_COUNSELOR, + 512, + 3u, + 120u, + 8u, + 20u, + 40u, + 0u, + 0u, + 0u, + 0u, + 70u, + MC_DEMON, + 71, + 120, + 0, + 7u, + 4968 + } +}; +unsigned char MonstAvailTbl[112] = +{ + 1u, + 1u, + 1u, + 1u, + 1u, + 1u, + 1u, + 1u, + 1u, + 1u, + 1u, + 1u, + 1u, + 1u, + 1u, + 1u, + 1u, + 1u, + 1u, + 1u, + 1u, + 1u, + 1u, + 1u, + 1u, + 1u, + 1u, + 1u, + 0u, + 2u, + 2u, + 2u, + 2u, + 0u, + 2u, + 2u, + 2u, + 2u, + 1u, + 1u, + 1u, + 1u, + 2u, + 2u, + 2u, + 2u, + 2u, + 2u, + 2u, + 2u, + 0u, + 0u, + 2u, + 2u, + 2u, + 2u, + 0u, + 0u, + 0u, + 0u, + 2u, + 2u, + 2u, + 2u, + 2u, + 2u, + 2u, + 2u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 2u, + 2u, + 2u, + 2u, + 0u, + 2u, + 2u, + 2u, + 2u, + 2u, + 2u, + 2u, + 2u, + 2u, + 2u, + 2u, + 2u, + 2u, + 2u, + 2u, + 2u, + 0u, + 0u, + 0u, + 0u, + 2u, + 2u, + 2u, + 2u, + 2u, + 2u, + 2u, + 2u, + 0u, + 0u, + 0u +}; +UniqMonstStruct UniqMonst[98] = +{ + { + MON_GOATMACEA, + "Gharbad the Weak", + "BSDB", + 4u, + 120u, + MG_GARBUD, + 3u, + 8u, + 16u, + 96, + 0, + 0u, + 0u, + TEXT_GARBUD1 + }, + { + MON_SKING, + "Skeleton King", + "GENRL", + 0u, + 240u, + MG_SKELKING, + 3u, + 6u, + 16u, + 78, + 1, + 0u, + 0u, + TEXT_STORY1 + }, + { + MON_MAGEA, + "Zhar the Mad", + "GENERAL", + 8u, + 360u, + MG_ZHAR, + 3u, + 16u, + 40u, + 14, + 0, + 0u, + 0u, + TEXT_ZHAR1 + }, + { + MON_FALSPEARD, + "Snotspill", + "BNG", + 4u, + 220u, + MG_SNOTSPIL, + 3u, + 10u, + 18u, + 4, + 0, + 0u, + 0u, + TEXT_SNOT1 + }, + { + MON_MAGED, + "Arch-Bishop Lazarus", + "GENERAL", + 0u, + 600u, + MG_LAZURUS, + 3u, + 30u, + 50u, + 78, + 0, + 0u, + 0u, + TEXT_LAZ1_1 + }, + { + MON_SUCCC, + "Red Vex", + "REDV", + 0u, + 400u, + MG_LAZHELP, + 3u, + 30u, + 50u, + 74, + 0, + 0u, + 0u, + TEXT_LAZ1_1 + }, + { + MON_SUCCC, + "BlackJade", + "BLKJD", + 0u, + 400u, + MG_LAZHELP, + 3u, + 30u, + 50u, + 76, + 0, + 0u, + 0u, + TEXT_LAZ1_1 + }, + { + MON_BLACKD, + "Lachdanan", + "BHKA", + 14u, + 500u, + MG_LACHDANAN, + 3u, + 0u, + 0u, + 0, + 0, + 0u, + 0u, + TEXT_LACH1 + }, + { + MON_BLACKC, + "Warlord of Blood", + "GENERAL", + 13u, + 850u, + MG_WARLORD, + 3u, + 35u, + 50u, + 120, + 0, + 0u, + 0u, + TEXT_WARLRD1 + }, + { + MON_BUTCH, + "The Butcher", + "GENRL", + 0u, + 220u, + MG_CLEAVER, + 3u, + 6u, + 12u, + 70, + 0, + 0u, + 0u, + TEXT_STORY1 + }, + { + MON_SKELAXEB, + "Bonehead Keenaxe", + "BHKA", + 2u, + 91u, + MG_SKELSD, + 2u, + 4u, + 10u, + 72, + 7, + 100u, + 0u, + TEXT_STORY1 + }, + { + MON_FALSWORDA, + "Bladeskin the Slasher", + "BSTS", + 2u, + 51u, + MG_FALLEN, + 0u, + 6u, + 18u, + 2, + 11, + 45u, + 0u, + TEXT_STORY1 + }, + { + MON_ZOMBIEA, + "Soulpus", + "GENERAL", + 2u, + 133u, + MG_ZOMBIE, + 0u, + 4u, + 8u, + 6, + 0, + 0u, + 0u, + TEXT_STORY1 + }, + { + MON_FALSPEARA, + "Pukerat the Unclean", + "PTU", + 2u, + 77u, + MG_FALLEN, + 3u, + 1u, + 5u, + 2, + 0, + 0u, + 0u, + TEXT_STORY1 + }, + { + MON_SKELAXEA, + "Boneripper", + "BR", + 2u, + 54u, + MG_BAT, + 0u, + 6u, + 15u, + 88, + 3, + 0u, + 0u, + TEXT_STORY1 + }, + { + MON_ZOMBIEA, + "Rotfeast the Hungry", + "ETH", + 2u, + 85u, + MG_SKELSD, + 3u, + 4u, + 12u, + 72, + 3, + 0u, + 0u, + TEXT_STORY1 + }, + { + MON_FALSWORDB, + "Gutshank the Quick", + "GTQ", + 3u, + 66u, + MG_BAT, + 2u, + 6u, + 16u, + 2, + 3, + 0u, + 0u, + TEXT_STORY1 + }, + { + MON_SKELSDB, + "Brokenhead Bangshield", + "BHBS", + 3u, + 108u, + MG_SKELSD, + 3u, + 12u, + 20u, + 76, + 3, + 0u, + 0u, + TEXT_STORY1 + }, + { + MON_FALSPEARC, + "Bongo", + "BNG", + 3u, + 178u, + MG_FALLEN, + 3u, + 9u, + 21u, + 0, + 3, + 0u, + 0u, + TEXT_STORY1 + }, + { + MON_ZOMBIEB, + "Rotcarnage", + "RCRN", + 3u, + 102u, + MG_ZOMBIE, + 3u, + 9u, + 24u, + 76, + 11, + 45u, + 0u, + TEXT_STORY1 + }, + { + MON_SCAVA, + "Shadowbite", + "SHBT", + 2u, + 60u, + MG_SKELSD, + 3u, + 3u, + 20u, + 16, + 3, + 0u, + 0u, + TEXT_STORY1 + }, + { + MON_SKELBOWA, + "Deadeye", + "DE", + 2u, + 49u, + MG_GOATBOW, + 0u, + 6u, + 9u, + 74, + 0, + 0u, + 0u, + TEXT_STORY1 + }, + { + MON_SKELAXEC, + "Madeye the Dead", + "MTD", + 4u, + 75u, + MG_BAT, + 0u, + 9u, + 21u, + 24, + 11, + 30u, + 0u, + TEXT_STORY1 + }, + { + MON_SCAVB, + "El Chupacabras", + "GENERAL", + 3u, + 120u, + MG_GOATMC, + 0u, + 10u, + 18u, + 2, + 3, + 30u, + 0u, + TEXT_STORY1 + }, + { + MON_SKELBOWB, + "Skullfire", + "SKFR", + 3u, + 125u, + MG_GOATBOW, + 1u, + 6u, + 10u, + 16, + 0, + 100u, + 0u, + TEXT_STORY1 + }, + { + MON_SNEAKA, + "Warpskull", + "TSPO", + 3u, + 117u, + MG_SNEAK, + 2u, + 6u, + 18u, + 6, + 3, + 0u, + 0u, + TEXT_STORY1 + }, + { + MON_ZOMBIEC, + "Goretongue", + "PMR", + 3u, + 156u, + MG_SKELSD, + 1u, + 15u, + 30u, + 72, + 0, + 0u, + 0u, + TEXT_STORY1 + }, + { + MON_SCAVC, + "Pulsecrawler", + "BHKA", + 4u, + 150u, + MG_SCAV, + 0u, + 16u, + 20u, + 20, + 11, + 45u, + 0u, + TEXT_STORY1 + }, + { + MON_BATB, + "Moonbender", + "GENERAL", + 4u, + 135u, + MG_BAT, + 0u, + 9u, + 27u, + 16, + 3, + 0u, + 0u, + TEXT_STORY1 + }, + { + MON_BATB, + "Wrathraven", + "GENERAL", + 5u, + 135u, + MG_BAT, + 2u, + 9u, + 22u, + 16, + 3, + 0u, + 0u, + TEXT_STORY1 + }, + { + MON_SCAVD, + "Spineeater", + "GENERAL", + 4u, + 180u, + MG_SCAV, + 1u, + 18u, + 25u, + 96, + 3, + 0u, + 0u, + TEXT_STORY1 + }, + { + MON_SKELBOWC, + "Blackash the Burning", + "BASHTB", + 4u, + 120u, + MG_GOATBOW, + 0u, + 6u, + 16u, + 24, + 3, + 0u, + 0u, + TEXT_STORY1 + }, + { + MON_FALSWORDD, + "Shadowcrow", + "GENERAL", + 5u, + 270u, + MG_SNEAK, + 2u, + 12u, + 25u, + 0, + 3, + 0u, + 0u, + TEXT_STORY1 + }, + { + MON_GOATLORD, + "Blightstone the Weak", + "BHKA", + 4u, + 360u, + MG_SKELSD, + 0u, + 4u, + 12u, + 12, + 7, + 70u, + 0u, + TEXT_STORY1 + }, + { + MON_FATA, + "Bilefroth the Pit Master", + "BFTP", + 6u, + 210u, + MG_BAT, + 1u, + 16u, + 23u, + 28, + 3, + 0u, + 0u, + TEXT_STORY1 + }, + { + MON_GOATBOWA, + "Bloodskin Darkbow", + "BSDB", + 5u, + 207u, + MG_GOATBOW, + 0u, + 3u, + 16u, + 6, + 11, + 55u, + 0u, + TEXT_STORY1 + }, + { + MON_BATC, + "Foulwing", + "DB", + 5u, + 246u, + MG_RHINO, + 3u, + 12u, + 28u, + 2, + 3, + 0u, + 0u, + TEXT_STORY1 + }, + { + MON_SKELSDD, + "Shadowdrinker", + "SHDR", + 5u, + 300u, + MG_SNEAK, + 1u, + 18u, + 26u, + 78, + 8, + 45u, + 0u, + TEXT_STORY1 + }, + { + MON_SNEAKC, + "Hazeshifter", + "BHKA", + 5u, + 285u, + MG_SNEAK, + 3u, + 18u, + 30u, + 96, + 3, + 0u, + 0u, + TEXT_STORY1 + }, + { + MON_ACIDA, + "Deathspit", + "BFDS", + 6u, + 303u, + MG_ACIDUNIQ, + 0u, + 12u, + 32u, + 6, + 3, + 0u, + 0u, + TEXT_STORY1 + }, + { + MON_GOATMACEC, + "Bloodgutter", + "BGBL", + 6u, + 315u, + MG_BAT, + 1u, + 24u, + 34u, + 16, + 3, + 0u, + 0u, + TEXT_STORY1 + }, + { + MON_GOATMACEB, + "Deathshade Fleshmaul", + "DSFM", + 6u, + 276u, + MG_RHINO, + 0u, + 12u, + 24u, + 10, + 8, + 65u, + 0u, + TEXT_STORY1 + }, + { + MON_WORMA, + "Warmaggot the Mad", + "GENERAL", + 6u, + 246u, + MG_BAT, + 3u, + 15u, + 30u, + 4, + 3, + 0u, + 0u, + TEXT_STORY1 + }, + { + MON_THINA, + "Glasskull the Jagged", + "BHKA", + 7u, + 354u, + MG_STORM, + 0u, + 18u, + 30u, + 88, + 3, + 0u, + 0u, + TEXT_STORY1 + }, + { + MON_GOATBOWC, + "Blightfire", + "BLF", + 7u, + 321u, + MG_SUCC, + 2u, + 13u, + 21u, + 16, + 3, + 0u, + 0u, + TEXT_STORY1 + }, + { + MON_GARGOYLEB, + "Nightwing the Cold", + "GENERAL", + 7u, + 342u, + MG_BAT, + 1u, + 18u, + 26u, + 76, + 3, + 0u, + 0u, + TEXT_STORY1 + }, + { + MON_GOATBOWD, + "Gorestone", + "GENERAL", + 7u, + 303u, + MG_GOATBOW, + 1u, + 15u, + 28u, + 68, + 7, + 70u, + 0u, + TEXT_STORY1 + }, + { + MON_MAGMAC, + "Bronzefist Firestone", + "GENERAL", + 8u, + 360u, + MG_MAGMA, + 0u, + 30u, + 36u, + 10, + 3, + 0u, + 0u, + TEXT_STORY1 + }, + { + MON_FIREMANA, + "Wrathfire the Doomed", + "WFTD", + 8u, + 270u, + MG_SKELSD, + 2u, + 20u, + 30u, + 14, + 3, + 0u, + 0u, + TEXT_STORY1 + }, + { + MON_MAGMAA, + "Firewound the Grim", + "BHKA", + 8u, + 303u, + MG_MAGMA, + 0u, + 18u, + 22u, + 10, + 3, + 0u, + 0u, + TEXT_STORY1 + }, + { + MON_FATB, + "Baron Sludge", + "BSM", + 8u, + 315u, + MG_SNEAK, + 3u, + 25u, + 34u, + 78, + 11, + 75u, + 0u, + TEXT_STORY1 + }, + { + MON_GOATMACED, + "Blighthorn Steelmace", + "BHSM", + 7u, + 250u, + MG_RHINO, + 0u, + 20u, + 28u, + 4, + 11, + 45u, + 0u, + TEXT_STORY1 + }, + { + MON_ACIDB, + "Chaoshowler", + "GENERAL", + 8u, + 240u, + MG_ACIDUNIQ, + 0u, + 12u, + 20u, + 0, + 3, + 0u, + 0u, + TEXT_STORY1 + }, + { + MON_THINE, + "Doomgrin the Rotting", + "GENERAL", + 8u, + 405u, + MG_STORM, + 3u, + 25u, + 50u, + 78, + 3, + 0u, + 0u, + TEXT_STORY1 + }, + { + MON_FIREMANB, + "Madburner", + "GENERAL", + 9u, + 270u, + MG_STORM, + 0u, + 20u, + 40u, + 56, + 3, + 0u, + 0u, + TEXT_STORY1 + }, + { + MON_THINF, + "Bonesaw the Litch", + "GENERAL", + 9u, + 495u, + MG_STORM, + 2u, + 30u, + 55u, + 78, + 3, + 0u, + 0u, + TEXT_STORY1 + }, + { + MON_RHINOB, + "Breakspine", + "GENERAL", + 9u, + 351u, + MG_RHINO, + 0u, + 25u, + 34u, + 2, + 3, + 0u, + 0u, + TEXT_STORY1 + }, + { + MON_THINE, + "Devilskull Sharpbone", + "GENERAL", + 9u, + 444u, + MG_STORM, + 1u, + 25u, + 40u, + 16, + 3, + 0u, + 0u, + TEXT_STORY1 + }, + { + MON_THINA, + "Brokenstorm", + "GENERAL", + 9u, + 411u, + MG_STORM, + 2u, + 25u, + 36u, + 32, + 3, + 0u, + 0u, + TEXT_STORY1 + }, + { + MON_THINB, + "Stormbane", + "GENERAL", + 9u, + 555u, + MG_STORM, + 3u, + 30u, + 30u, + 32, + 3, + 0u, + 0u, + TEXT_STORY1 + }, + { + MON_FATC, + "Oozedrool", + "GENERAL", + 9u, + 483u, + MG_FAT, + 3u, + 25u, + 30u, + 4, + 3, + 0u, + 0u, + TEXT_STORY1 + }, + { + MON_GARGOYLEC, + "Goldblight of the Flame", + "GENERAL", + 10u, + 405u, + MG_GARG, + 0u, + 15u, + 35u, + 24, + 11, + 80u, + 0u, + TEXT_STORY1 + }, + { + MON_RHINOD, + "Blackstorm", + "GENERAL", + 10u, + 525u, + MG_RHINO, + 3u, + 20u, + 40u, + 40, + 11, + 90u, + 0u, + TEXT_STORY1 + }, + { + MON_ACIDB, + "Plaguewrath", + "GENERAL", + 10u, + 450u, + MG_ACIDUNIQ, + 2u, + 20u, + 30u, + 74, + 3, + 0u, + 0u, + TEXT_STORY1 + }, + { + MON_THINB, + "The Flayer", + "GENERAL", + 10u, + 501u, + MG_STORM, + 1u, + 20u, + 35u, + 99, + 3, + 0u, + 0u, + TEXT_STORY1 + }, + { + MON_RHINOC, + "Bluehorn", + "GENERAL", + 11u, + 477u, + MG_RHINO, + 1u, + 25u, + 30u, + 10, + 11, + 90u, + 0u, + TEXT_STORY1 + }, + { + MON_FIREMAND, + "Warpfire Hellspawn", + "GENERAL", + 11u, + 525u, + MG_FIREMAN, + 3u, + 10u, + 40u, + 17, + 3, + 0u, + 0u, + TEXT_STORY1 + }, + { + MON_SNAKEA, + "Fangspeir", + "GENERAL", + 11u, + 444u, + MG_SKELSD, + 1u, + 15u, + 32u, + 80, + 3, + 0u, + 0u, + TEXT_STORY1 + }, + { + MON_THING, + "Festerskull", + "GENERAL", + 11u, + 600u, + MG_STORM, + 2u, + 15u, + 30u, + 72, + 3, + 0u, + 0u, + TEXT_STORY1 + }, + { + MON_BLACKA, + "Lionskull the Bent", + "GENERAL", + 12u, + 525u, + MG_SKELSD, + 2u, + 25u, + 25u, + 120, + 3, + 0u, + 0u, + TEXT_STORY1 + }, + { + MON_MAGEA, + "Blacktongue", + "GENERAL", + 12u, + 360u, + MG_COUNSELOR, + 3u, + 15u, + 30u, + 66, + 3, + 0u, + 0u, + TEXT_STORY1 + }, + { + MON_GARGOYLED, + "Viletouch", + "GENERAL", + 12u, + 525u, + MG_GARG, + 3u, + 20u, + 40u, + 96, + 3, + 0u, + 0u, + TEXT_STORY1 + }, + { + MON_SNAKEB, + "Viperflame", + "GENERAL", + 12u, + 570u, + MG_SKELSD, + 1u, + 25u, + 35u, + 20, + 3, + 0u, + 0u, + TEXT_STORY1 + }, + { + MON_SNAKEC, + "Fangskin", + "BHKA", + 14u, + 681u, + MG_SKELSD, + 2u, + 15u, + 50u, + 12, + 3, + 0u, + 0u, + TEXT_STORY1 + }, + { + MON_SUCCA, + "Witchfire the Unholy", + "GENERAL", + 12u, + 444u, + MG_SUCC, + 3u, + 10u, + 20u, + 28, + 3, + 0u, + 0u, + TEXT_STORY1 + }, + { + MON_MEGAD, + "Blackskull", + "BHKA", + 13u, + 750u, + MG_SKELSD, + 3u, + 25u, + 40u, + 12, + 3, + 0u, + 0u, + TEXT_STORY1 + }, + { + MON_UNRAVA, + "Soulslash", + "GENERAL", + 12u, + 450u, + MG_SKELSD, + 0u, + 25u, + 25u, + 72, + 3, + 0u, + 0u, + TEXT_STORY1 + }, + { + MON_MEGAC, + "Windspawn", + "GENERAL", + 12u, + 711u, + MG_SKELSD, + 1u, + 35u, + 40u, + 24, + 3, + 0u, + 0u, + TEXT_STORY1 + }, + { + MON_SNAKED, + "Lord of the Pit", + "GENERAL", + 13u, + 762u, + MG_SKELSD, + 2u, + 25u, + 42u, + 66, + 3, + 0u, + 0u, + TEXT_STORY1 + }, + { + MON_BLACKB, + "Rustweaver", + "GENERAL", + 13u, + 400u, + MG_SKELSD, + 3u, + 1u, + 60u, + 120, + 0, + 0u, + 0u, + TEXT_STORY1 + }, + { + MON_UNRAVB, + "Howlingire the Shade", + "GENERAL", + 13u, + 450u, + MG_SKELSD, + 2u, + 40u, + 75u, + 6, + 3, + 0u, + 0u, + TEXT_STORY1 + }, + { + MON_THIND, + "Doomcloud", + "GENERAL", + 13u, + 612u, + MG_STORM, + 1u, + 1u, + 60u, + 34, + 0, + 0u, + 0u, + TEXT_STORY1 + }, + { + MON_UNRAVC, + "Bloodmoon Soulfire", + "GENERAL", + 13u, + 684u, + MG_SKELSD, + 1u, + 15u, + 40u, + 14, + 3, + 0u, + 0u, + TEXT_STORY1 + }, + { + MON_SUCCB, + "Witchmoon", + "GENERAL", + 13u, + 310u, + MG_SUCC, + 3u, + 30u, + 40u, + 4, + 0, + 0u, + 0u, + TEXT_STORY1 + }, + { + MON_MEGAC, + "Gorefeast", + "GENERAL", + 13u, + 771u, + MG_SKELSD, + 3u, + 20u, + 55u, + 66, + 0, + 0u, + 0u, + TEXT_STORY1 + }, + { + MON_BLACKB, + "Graywar the Slayer", + "GENERAL", + 14u, + 672u, + MG_SKELSD, + 1u, + 30u, + 50u, + 68, + 0, + 0u, + 0u, + TEXT_STORY1 + }, + { + MON_MAGEB, + "Dreadjudge", + "GENERAL", + 14u, + 540u, + MG_COUNSELOR, + 1u, + 30u, + 40u, + 14, + 3, + 0u, + 0u, + TEXT_STORY1 + }, + { + MON_SUCCC, + "Stareye the Witch", + "GENERAL", + 14u, + 726u, + MG_SUCC, + 2u, + 30u, + 50u, + 16, + 0, + 0u, + 0u, + TEXT_STORY1 + }, + { + MON_BLACKC, + "Steelskull the Hunter", + "GENERAL", + 14u, + 831u, + MG_SKELSD, + 3u, + 40u, + 50u, + 68, + 0, + 0u, + 0u, + TEXT_STORY1 + }, + { + MON_BLACKD, + "Sir Gorash", + "GENERAL", + 16u, + 1050u, + MG_SKELSD, + 1u, + 20u, + 60u, + 64, + 0, + 0u, + 0u, + TEXT_STORY1 + }, + { + MON_MAGEC, + "The Vizier", + "GENERAL", + 15u, + 850u, + MG_COUNSELOR, + 2u, + 25u, + 40u, + 16, + 3, + 0u, + 0u, + TEXT_STORY1 + }, + { + MON_UNRAVD, + "Zamphir", + "GENERAL", + 15u, + 891u, + MG_SKELSD, + 2u, + 30u, + 50u, + 78, + 3, + 0u, + 0u, + TEXT_STORY1 + }, + { + MON_SUCCC, + "Bloodlust", + "GENERAL", + 15u, + 825u, + MG_SUCC, + 1u, + 20u, + 55u, + 104, + 0, + 0u, + 0u, + TEXT_STORY1 + }, + { + MON_SUCCC, + "Webwidow", + "GENERAL", + 16u, + 774u, + MG_SUCC, + 1u, + 20u, + 50u, + 88, + 0, + 0u, + 0u, + TEXT_STORY1 + }, + { + MON_SUCCD, + "Fleshdancer", + "GENERAL", + 16u, + 999u, + MG_SUCC, + 3u, + 30u, + 50u, + 74, + 0, + 0u, + 0u, + TEXT_STORY1 + }, + { + MON_RHINOD, + "Grimspike", + "GENERAL", + 19u, + 534u, + MG_SNEAK, + 1u, + 25u, + 40u, + 74, + 3, + 0u, + 0u, + TEXT_STORY1 + }, + { + MON_THINC, + "Doomlock", + "GENERAL", + 28u, + 534u, + MG_SNEAK, + 1u, + 35u, + 55u, + 78, + 3, + 0u, + 0u, + TEXT_STORY1 + }, + { + MON_NONE, + NULL, + NULL, + 0u, + 0u, + MG_ZOMBIE, + 0u, + 0u, + 0u, + 0, + 0, + 0u, + 0u, + TEXT_STORY1 + } +}; +int MWVel[24][3] = +{ + { 256, 512, 1024 }, + { 128, 256, 512 }, + { 85, 170, 341 }, + { 64, 128, 256 }, + { 51, 102, 204 }, + { 42, 85, 170 }, + { 36, 73, 146 }, + { 32, 64, 128 }, + { 28, 56, 113 }, + { 26, 51, 102 }, + { 23, 46, 93 }, + { 21, 42, 85 }, + { 19, 39, 78 }, + { 18, 36, 73 }, + { 17, 34, 68 }, + { 16, 32, 64 }, + { 15, 30, 60 }, + { 14, 28, 57 }, + { 13, 26, 54 }, + { 12, 25, 51 }, + { 12, 24, 48 }, + { 11, 23, 46 }, + { 11, 22, 44 }, + { 10, 21, 42 } +}; +char animletter[7] = "nwahds"; +int left[8] = { 7, 0, 1, 2, 3, 4, 5, 6 }; +int right[8] = { 1, 2, 3, 4, 5, 6, 7, 0 }; +int opposite[8] = { 4, 5, 6, 7, 0, 1, 2, 3 }; +int offset_x[8] = { 1, 0, 4294967295, 4294967295, 4294967295, 0, 1, 1 }; +int offset_y[8] = { 1, 1, 1, 0, 4294967295, 4294967295, 4294967295, 0 }; +void (__fastcall *AiProc[])(int i) = +{ + &MAI_Zombie, + &MAI_Fat, + &MAI_SkelSd, + &MAI_SkelBow, + &MAI_Scav, + &MAI_Rhino, + &MAI_GoatMc, + &MAI_GoatBow, + &MAI_Fallen, + &MAI_Magma, + &MAI_SkelKing, + &MAI_Bat, + &MAI_Garg, + &MAI_Cleaver, + &MAI_Succ, + &MAI_Sneak, + &MAI_Storm, + &MAI_Fireman, + &MAI_Garbud, + &MAI_Acid, + &MAI_AcidUniq, + &MAI_Golum, + &MAI_Zhar, + &MAI_SnotSpil, + &MAI_Snake, + &MAI_Counselor, + &MAI_Mega, + &MAI_Diablo, + &MAI_Lazurus, + &MAI_Lazhelp, + &MAI_Lachdanan, + &MAI_Warlord +}; +HANDLE sghArchive = (HANDLE)0xFFFFFFFF; // idb +HANDLE hObject = (HANDLE)0xFFFFFFFF; // idb +int ObjTypeConv[113] = +{ + 0, + 4, + 20, + 21, + 22, + 24, + 11, + 12, + 13, + 0, + 0, + 0, + 0, + 0, + 25, + 41, + 26, + 0, + 8, + 9, + 10, + 80, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 49, + 0, + 0, + 0, + 0, + 0, + 84, + 85, + 3, + 14, + 15, + 16, + 17, + 18, + 19, + 0, + 0, + 0, + 0, + 0, + 0, + 28, + 0, + 53, + 54, + 36, + 37, + 38, + 39, + 40, + 0, + 0, + 0, + 0, + 0, + 27, + 0, + 0, + 0, + 0, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 5, + 5, + 5, + 6, + 6, + 6, + 7, + 7, + 7, + 0, + 0, + 0, + 0, + 0, + 73, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 83, + 0, + 0, + 89, + 90, + 47, + 46, + 94 +}; +ObjDataStruct AllObjects[99] = +{ + { 1u, OFILE_L1BRAZ, 1u, 4u, 1u, 255u, 255u, 1, 1, 26, 64, 1, 1, 0, 0u, 0u, 0 }, + { 1u, OFILE_L1DOORS, 1u, 4u, 1u, 255u, 255u, 0, 1, 0, 64, 0, 0, 1, 0u, 3u, 1 }, + { 1u, OFILE_L1DOORS, 1u, 4u, 1u, 255u, 255u, 0, 2, 0, 64, 0, 0, 1, 0u, 3u, 1 }, + { 3u, OFILE_SKULFIRE, 0u, 0u, 0u, 3u, 255u, 1, 2, 11, 96, 1, 1, 0, 0u, 0u, 0 }, + { 1u, OFILE_LEVER, 1u, 4u, 1u, 255u, 255u, 0, 1, 1, 96, 1, 1, 1, 0u, 1u, 1 }, + { 1u, OFILE_CHEST1, 1u, 16u, 0u, 255u, 255u, 0, 1, 0, 96, 1, 1, 1, 0u, 1u, 1 }, + { 1u, OFILE_CHEST2, 1u, 16u, 0u, 255u, 255u, 0, 1, 0, 96, 1, 1, 1, 0u, 1u, 1 }, + { 1u, OFILE_CHEST3, 1u, 16u, 0u, 255u, 255u, 0, 1, 0, 96, 1, 1, 1, 0u, 1u, 1 }, + { 2u, OFILE_L1BRAZ, 0u, 0u, 0u, 255u, 255u, 0, 0, 0, 0, 0, 0, 0, 0u, 0u, 0 }, + { 3u, OFILE_CANDLE2, 0u, 0u, 0u, 1u, 255u, 1, 2, 4, 96, 1, 1, 1, 0u, 0u, 0 }, + { 2u, OFILE_L1BRAZ, 0u, 0u, 0u, 255u, 255u, 0, 0, 0, 0, 0, 0, 0, 0u, 0u, 0 }, + { 3u, OFILE_BANNER, 0u, 0u, 0u, 3u, 255u, 0, 2, 0, 96, 1, 1, 1, 0u, 0u, 0 }, + { 3u, OFILE_BANNER, 0u, 0u, 0u, 3u, 255u, 0, 1, 0, 96, 1, 1, 1, 0u, 0u, 0 }, + { 3u, OFILE_BANNER, 0u, 0u, 0u, 3u, 255u, 0, 3, 0, 96, 1, 1, 1, 0u, 0u, 0 }, + { + 2u, + OFILE_SKULPILE, + 1u, + 4u, + 0u, + 255u, + 255u, + 0, + 0, + 1, + 96, + 1, + 1, + 1, + 0u, + 0u, + 0 + }, + { 2u, OFILE_L1BRAZ, 0u, 0u, 0u, 255u, 255u, 0, 0, 0, 0, 0, 0, 0, 0u, 0u, 0 }, + { 2u, OFILE_L1BRAZ, 0u, 0u, 0u, 255u, 255u, 0, 0, 0, 0, 0, 0, 0, 0u, 0u, 0 }, + { 2u, OFILE_L1BRAZ, 0u, 0u, 0u, 255u, 255u, 0, 0, 0, 0, 0, 0, 0, 0u, 0u, 0 }, + { 2u, OFILE_L1BRAZ, 0u, 0u, 0u, 255u, 255u, 0, 0, 0, 0, 0, 0, 0, 0u, 0u, 0 }, + { 2u, OFILE_L1BRAZ, 0u, 0u, 0u, 255u, 255u, 0, 0, 0, 0, 0, 0, 0, 0u, 0u, 0 }, + { + 2u, + OFILE_CRUXSK1, + 0u, + 0u, + 0u, + 255u, + 255u, + 0, + 1, + 15, + 96, + 1, + 0, + 1, + 1u, + 3u, + 0 + }, + { + 2u, + OFILE_CRUXSK2, + 0u, + 0u, + 0u, + 255u, + 255u, + 0, + 1, + 15, + 96, + 1, + 0, + 1, + 1u, + 3u, + 0 + }, + { + 2u, + OFILE_CRUXSK3, + 0u, + 0u, + 0u, + 255u, + 255u, + 0, + 1, + 15, + 96, + 1, + 0, + 1, + 1u, + 3u, + 0 + }, + { + 1u, + OFILE_ROCKSTAN, + 5u, + 5u, + 0u, + 255u, + 255u, + 0, + 1, + 0, + 96, + 1, + 1, + 1, + 0u, + 0u, + 0 + }, + { 2u, OFILE_ANGEL, 0u, 0u, 0u, 255u, 255u, 0, 1, 0, 96, 1, 0, 1, 0u, 0u, 0 }, + { 2u, OFILE_BOOK2, 0u, 0u, 0u, 255u, 255u, 0, 1, 0, 96, 1, 1, 1, 0u, 3u, 0 }, + { + 2u, + OFILE_BURNCROS, + 0u, + 0u, + 0u, + 255u, + 255u, + 1, + 0, + 10, + 160, + 1, + 0, + 0, + 0u, + 0u, + 0 + }, + { 2u, OFILE_NUDE2, 0u, 0u, 0u, 255u, 255u, 1, 3, 6, 128, 1, 0, 1, 0u, 0u, 0 }, + { + 1u, + OFILE_SWITCH4, + 16u, + 16u, + 0u, + 255u, + 255u, + 0, + 1, + 0, + 96, + 1, + 1, + 1, + 0u, + 1u, + 1 + }, + { 1u, OFILE_TNUDEM, 13u, 16u, 0u, 255u, 6u, 0, 1, 0, 128, 1, 0, 1, 0u, 0u, 0 }, + { 1u, OFILE_TNUDEM, 13u, 16u, 0u, 6u, 6u, 0, 2, 0, 128, 1, 0, 1, 0u, 0u, 0 }, + { 1u, OFILE_TNUDEM, 13u, 16u, 0u, 6u, 6u, 0, 3, 0, 128, 1, 0, 1, 0u, 0u, 0 }, + { 1u, OFILE_TNUDEM, 13u, 16u, 0u, 6u, 6u, 0, 4, 0, 128, 1, 0, 1, 0u, 0u, 0 }, + { 1u, OFILE_TNUDEW, 13u, 16u, 0u, 6u, 6u, 0, 1, 0, 128, 1, 0, 1, 0u, 0u, 0 }, + { 1u, OFILE_TNUDEW, 13u, 16u, 0u, 6u, 6u, 0, 2, 0, 128, 1, 0, 1, 0u, 0u, 0 }, + { 1u, OFILE_TNUDEW, 13u, 16u, 0u, 6u, 6u, 0, 3, 0, 128, 1, 0, 1, 0u, 0u, 0 }, + { 1u, OFILE_TSOUL, 13u, 16u, 0u, 255u, 6u, 0, 1, 0, 128, 1, 0, 1, 0u, 0u, 0 }, + { 1u, OFILE_TSOUL, 13u, 16u, 0u, 255u, 6u, 0, 2, 0, 128, 1, 0, 1, 0u, 0u, 0 }, + { 1u, OFILE_TSOUL, 13u, 16u, 0u, 255u, 6u, 0, 3, 0, 128, 1, 0, 1, 0u, 0u, 0 }, + { 1u, OFILE_TSOUL, 13u, 16u, 0u, 255u, 6u, 0, 4, 0, 128, 1, 0, 1, 0u, 0u, 0 }, + { 1u, OFILE_TSOUL, 13u, 16u, 0u, 255u, 6u, 0, 5, 0, 128, 1, 0, 1, 0u, 0u, 0 }, + { 1u, OFILE_BOOK2, 6u, 6u, 0u, 255u, 255u, 0, 4, 0, 96, 1, 1, 1, 0u, 3u, 0 }, + { 1u, OFILE_L2DOORS, 5u, 8u, 2u, 255u, 255u, 0, 1, 0, 64, 0, 0, 1, 0u, 3u, 1 }, + { 1u, OFILE_L2DOORS, 5u, 8u, 2u, 255u, 255u, 0, 2, 0, 64, 0, 0, 1, 0u, 3u, 1 }, + { 1u, OFILE_WTORCH4, 5u, 8u, 2u, 255u, 255u, 1, 1, 9, 96, 0, 1, 0, 0u, 0u, 0 }, + { 1u, OFILE_WTORCH3, 5u, 8u, 2u, 255u, 255u, 1, 1, 9, 96, 0, 1, 0, 0u, 0u, 0 }, + { 1u, OFILE_WTORCH1, 5u, 8u, 2u, 255u, 255u, 1, 1, 9, 96, 0, 1, 0, 0u, 0u, 0 }, + { 1u, OFILE_WTORCH2, 5u, 8u, 2u, 255u, 255u, 1, 1, 9, 96, 0, 1, 0, 0u, 0u, 0 }, + { 1u, OFILE_SARC, 1u, 4u, 1u, 255u, 255u, 0, 1, 5, 128, 1, 1, 1, 0u, 3u, 1 }, + { 2u, OFILE_FLAME1, 1u, 4u, 1u, 255u, 255u, 0, 1, 20, 96, 0, 1, 1, 0u, 0u, 0 }, + { 2u, OFILE_LEVER, 1u, 4u, 1u, 255u, 255u, 0, 1, 2, 96, 1, 1, 1, 0u, 1u, 1 }, + { + 2u, + OFILE_MINIWATR, + 1u, + 4u, + 1u, + 255u, + 255u, + 1, + 1, + 10, + 64, + 1, + 0, + 1, + 0u, + 0u, + 0 + }, + { 1u, OFILE_BOOK1, 3u, 4u, 1u, 255u, 255u, 0, 1, 0, 96, 1, 1, 1, 0u, 3u, 0 }, + { + 1u, + OFILE_TRAPHOLE, + 1u, + 16u, + 0u, + 255u, + 255u, + 0, + 1, + 0, + 64, + 0, + 1, + 1, + 0u, + 0u, + 0 + }, + { + 1u, + OFILE_TRAPHOLE, + 1u, + 16u, + 0u, + 255u, + 255u, + 0, + 2, + 0, + 64, + 0, + 1, + 1, + 0u, + 0u, + 0 + }, + { 2u, OFILE_BCASE, 0u, 0u, 0u, 255u, 255u, 0, 1, 0, 96, 1, 0, 1, 0u, 0u, 0 }, + { + 2u, + OFILE_WEAPSTND, + 0u, + 0u, + 0u, + 255u, + 255u, + 0, + 1, + 0, + 96, + 1, + 0, + 1, + 0u, + 0u, + 0 + }, + { 1u, OFILE_BARREL, 1u, 16u, 0u, 255u, 255u, 0, 1, 9, 96, 1, 1, 1, 1u, 3u, 0 }, + { + 1u, + OFILE_BARRELEX, + 1u, + 16u, + 0u, + 255u, + 255u, + 0, + 1, + 10, + 96, + 1, + 1, + 1, + 1u, + 3u, + 0 + }, + { + 3u, + OFILE_LSHRINEG, + 0u, + 0u, + 0u, + 1u, + 255u, + 0, + 1, + 11, + 128, + 0, + 0, + 1, + 0u, + 3u, + 0 + }, + { + 3u, + OFILE_RSHRINEG, + 0u, + 0u, + 0u, + 1u, + 255u, + 0, + 1, + 11, + 128, + 0, + 0, + 1, + 0u, + 3u, + 0 + }, + { 3u, OFILE_BOOK2, 0u, 0u, 0u, 3u, 255u, 0, 4, 0, 96, 1, 1, 1, 0u, 3u, 0 }, + { 3u, OFILE_BCASE, 0u, 0u, 0u, 5u, 255u, 0, 3, 0, 96, 0, 0, 1, 0u, 3u, 0 }, + { 3u, OFILE_BCASE, 0u, 0u, 0u, 5u, 255u, 0, 4, 0, 96, 0, 0, 1, 0u, 3u, 0 }, + { 3u, OFILE_BOOK2, 0u, 0u, 0u, 5u, 255u, 0, 1, 0, 96, 1, 1, 1, 0u, 3u, 0 }, + { 3u, OFILE_CANDLE2, 0u, 0u, 0u, 5u, 255u, 1, 2, 4, 96, 1, 1, 1, 0u, 0u, 0 }, + { 3u, OFILE_BLOODFNT, 0u, 0u, 0u, 7u, 255u, 1, 2, 10, 96, 1, 1, 1, 0u, 3u, 0 }, + { 1u, OFILE_DECAP, 13u, 16u, 0u, 8u, 255u, 0, 1, 0, 96, 1, 1, 1, 0u, 1u, 0 }, + { 1u, OFILE_CHEST1, 1u, 16u, 0u, 255u, 255u, 0, 1, 0, 96, 1, 1, 1, 0u, 1u, 1 }, + { 1u, OFILE_CHEST2, 1u, 16u, 0u, 255u, 255u, 0, 1, 0, 96, 1, 1, 1, 0u, 1u, 1 }, + { 1u, OFILE_CHEST3, 1u, 16u, 0u, 255u, 255u, 0, 1, 0, 96, 1, 1, 1, 0u, 1u, 1 }, + { 1u, OFILE_BOOK1, 7u, 7u, 2u, 255u, 8u, 0, 1, 0, 96, 1, 1, 1, 0u, 3u, 0 }, + { 1u, OFILE_BOOK1, 5u, 5u, 2u, 255u, 9u, 0, 4, 0, 96, 1, 1, 1, 0u, 3u, 0 }, + { 1u, OFILE_PEDISTL, 5u, 5u, 2u, 255u, 9u, 0, 1, 0, 96, 1, 1, 1, 0u, 3u, 0 }, + { + 1u, + OFILE_L3DOORS, + 9u, + 12u, + 3u, + 255u, + 255u, + 0, + 1, + 0, + 64, + 0, + 0, + 1, + 0u, + 3u, + 1 + }, + { + 1u, + OFILE_L3DOORS, + 9u, + 12u, + 3u, + 255u, + 255u, + 0, + 2, + 0, + 64, + 0, + 0, + 1, + 0u, + 3u, + 1 + }, + { 3u, OFILE_PFOUNTN, 0u, 0u, 0u, 9u, 255u, 1, 2, 10, 128, 1, 1, 1, 0u, 3u, 0 }, + { 3u, OFILE_ARMSTAND, 0u, 0u, 0u, 10u, 255u, 0, 1, 0, 96, 1, 0, 1, 0u, 3u, 0 }, + { 3u, OFILE_ARMSTAND, 0u, 0u, 0u, 10u, 255u, 0, 2, 0, 96, 1, 0, 1, 0u, 0u, 0 }, + { + 3u, + OFILE_GOATSHRN, + 0u, + 0u, + 0u, + 11u, + 255u, + 1, + 2, + 10, + 96, + 1, + 1, + 1, + 0u, + 3u, + 0 + }, + { + 1u, + OFILE_CAULDREN, + 13u, + 16u, + 0u, + 255u, + 255u, + 0, + 1, + 0, + 96, + 1, + 0, + 1, + 0u, + 3u, + 0 + }, + { + 3u, + OFILE_MFOUNTN, + 0u, + 0u, + 0u, + 13u, + 255u, + 1, + 2, + 10, + 128, + 1, + 1, + 1, + 0u, + 3u, + 0 + }, + { 3u, OFILE_TFOUNTN, 0u, 0u, 0u, 14u, 255u, 1, 2, 4, 128, 1, 1, 1, 0u, 3u, 0 }, + { 1u, OFILE_ALTBOY, 0u, 0u, 1u, 255u, 15u, 0, 1, 0, 128, 1, 1, 1, 0u, 0u, 0 }, + { 1u, OFILE_MCIRL, 0u, 0u, 1u, 255u, 15u, 0, 1, 0, 96, 0, 1, 1, 0u, 0u, 0 }, + { 1u, OFILE_MCIRL, 0u, 0u, 1u, 255u, 15u, 0, 1, 0, 96, 0, 1, 1, 0u, 0u, 0 }, + { + 1u, + OFILE_BKSLBRNT, + 4u, + 12u, + 0u, + 255u, + 255u, + 0, + 1, + 0, + 96, + 1, + 1, + 1, + 0u, + 3u, + 0 + }, + { 1u, OFILE_CANDLE2, 2u, 12u, 0u, 255u, 15u, 1, 2, 4, 96, 1, 1, 1, 0u, 0u, 0 }, + { 1u, OFILE_BOOK1, 13u, 13u, 4u, 255u, 11u, 0, 4, 0, 96, 1, 1, 1, 0u, 3u, 0 }, + { + 1u, + OFILE_ARMSTAND, + 13u, + 13u, + 0u, + 255u, + 11u, + 0, + 1, + 0, + 96, + 1, + 0, + 1, + 0u, + 3u, + 0 + }, + { + 2u, + OFILE_WEAPSTND, + 13u, + 13u, + 0u, + 255u, + 11u, + 0, + 1, + 0, + 96, + 1, + 0, + 1, + 0u, + 3u, + 0 + }, + { + 2u, + OFILE_BURNCROS, + 0u, + 0u, + 0u, + 15u, + 255u, + 1, + 0, + 10, + 160, + 1, + 0, + 0, + 0u, + 0u, + 0 + }, + { 2u, OFILE_WEAPSTND, 0u, 0u, 0u, 16u, 255u, 0, 1, 0, 96, 1, 0, 1, 0u, 3u, 0 }, + { 2u, OFILE_WEAPSTND, 0u, 0u, 0u, 16u, 255u, 0, 2, 0, 96, 1, 0, 1, 0u, 0u, 0 }, + { 2u, OFILE_MUSHPTCH, 0u, 0u, 0u, 255u, 1u, 0, 1, 0, 96, 1, 1, 1, 0u, 3u, 1 }, + { 2u, OFILE_LZSTAND, 0u, 0u, 0u, 255u, 15u, 0, 1, 0, 128, 1, 0, 1, 0u, 3u, 0 }, + { 1u, OFILE_DECAP, 9u, 9u, 3u, 255u, 255u, 0, 2, 0, 96, 1, 1, 1, 0u, 1u, 0 }, + { 2u, OFILE_CHEST3, 0u, 0u, 0u, 255u, 255u, 0, 1, 0, 96, 1, 1, 1, 0u, 1u, 1 }, + { + 255u, + OFILE_L1BRAZ, + 0u, + 0u, + 255u, + 255u, + 255u, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0u, + 0u, + 0 + } +}; +char *ObjMasterLoadList[56] = +{ + "L1Braz", + "L1Doors", + "Lever", + "Chest1", + "Chest2", + "Banner", + "SkulPile", + "SkulFire", + "SkulStik", + "CruxSk1", + "CruxSk2", + "CruxSk3", + "Book1", + "Book2", + "Rockstan", + "Angel", + "Chest3", + "Burncros", + "Candle2", + "Nude2", + "Switch4", + "TNudeM", + "TNudeW", + "TSoul", + "L2Doors", + "WTorch4", + "WTorch3", + "Sarc", + "Flame1", + "Prsrplt1", + "Traphole", + "MiniWatr", + "WTorch2", + "WTorch1", + "BCase", + "BShelf", + "WeapStnd", + "Barrel", + "Barrelex", + "LShrineG", + "RShrineG", + "Bloodfnt", + "Decap", + "Pedistl", + "L3Doors", + "PFountn", + "Armstand", + "Goatshrn", + "Cauldren", + "MFountn", + "TFountn", + "Altboy", + "Mcirl", + "Bkslbrnt", + "Mushptch", + "LzStand" +}; +int bxadd[8] = { 4294967295, 0, 1, 4294967295, 1, 4294967295, 0, 1 }; +int byadd[8] = { 4294967295, 4294967295, 4294967295, 0, 0, 1, 1, 1 }; +char *shrinestrs[26] = +{ + "Mysterious", + "Hidden", + "Gloomy", + "Weird", + "Magical", + "Stone", + "Religious", + "Enchanted", + "Thaumaturgic", + "Fascinating", + "Cryptic", + "Magical", + "Eldritch", + "Eerie", + "Divine", + "Holy", + "Sacred", + "Spiritual", + "Spooky", + "Abandoned", + "Creepy", + "Quiet", + "Secluded", + "Ornate", + "Glimmering", + "Tainted" +}; +unsigned char shrinemin[26] = +{ + 1u, + 1u, + 1u, + 1u, + 1u, + 1u, + 1u, + 1u, + 1u, + 1u, + 1u, + 1u, + 1u, + 1u, + 1u, + 1u, + 1u, + 1u, + 1u, + 1u, + 1u, + 1u, + 1u, + 1u, + 1u, + 1u +}; +unsigned char shrinemax[26] = +{ + 16u, + 16u, + 16u, + 16u, + 16u, + 16u, + 16u, + 8u, + 16u, + 16u, + 16u, + 16u, + 16u, + 16u, + 16u, + 16u, + 16u, + 16u, + 16u, + 16u, + 16u, + 16u, + 16u, + 16u, + 16u, + 16u +}; +unsigned char shrineavail[26] = +{ + 0u, + 0u, + 1u, + 1u, + 0u, + 0u, + 0u, + 0u, + 1u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 2u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 2u +}; +char *StoryBookName[9] = +{ + "The Great Conflict", + "The Wages of Sin are War", + "The Tale of the Horadrim", + "The Dark Exile", + "The Sin War", + "The Binding of the Three", + "The Realms Beyond", + "Tale of the Three", + "The Black King" +}; +_speech_id StoryText[3][3] = +{ + { TEXT_NAR1, TEXT_NAR2, TEXT_NAR3 }, + { TEXT_NAR4, TEXT_NAR5, TEXT_NAR6 }, + { TEXT_NAR7, TEXT_NAR8, TEXT_NAR9 } +}; +int gamma_correction = 100; // idb +int color_cycling_enabled = 1; // idb +unsigned char palette_bright = 1u; +unsigned char path_directions[9] = { 5u, 1u, 6u, 2u, 0u, 3u, 8u, 4u, 7u }; +int plrxoff[9] = { 0, 2, 0, 2, 1, 0, 1, 2, 1 }; +int plryoff[9] = { 0, 2, 2, 0, 1, 1, 0, 1, 2 }; +int plrxoff2[9] = { 0, 1, 0, 1, 2, 0, 1, 2, 2 }; +int plryoff2[9] = { 0, 0, 1, 1, 0, 2, 2, 1, 2 }; +ActionFrame PlrGFXAnimLens[3] = +{ + { 10u, 16u, 8u, 2u, 20u, 20u, 6u, 20u, 8u, 9u, 14u }, + { 8u, 18u, 8u, 4u, 20u, 16u, 7u, 20u, 8u, 10u, 12u }, + { 8u, 16u, 8u, 6u, 20u, 12u, 8u, 20u, 8u, 12u, 8u } +}; +int PWVel[4][3] = { { 2048, 1024, 512 }, { 2048, 1024, 512 }, { 2048, 1024, 512 }, { 8, 8, 8 } }; +int StrengthTbl[3] = { 30, 20, 15 }; +int MagicTbl[3] = { 10, 15, 35 }; +int DexterityTbl[3] = { 20, 30, 15 }; +int VitalityTbl[3] = { 25, 20, 20 }; +int ToBlkTbl[3] = { 30, 20, 10 }; +int MaxStats[3][4] = { { 250, 50, 60, 100 }, { 55, 70, 250, 80 }, { 45, 250, 85, 80 } }; +int ExpLvlsTbl[51] = +{ + 0, + 2000, + 4620, + 8040, + 12489, + 18258, + 25712, + 35309, + 47622, + 63364, + 83419, + 108879, + 141086, + 181683, + 231075, + 313656, + 424067, + 571190, + 766569, + 1025154, + 1366227, + 1814568, + 2401895, + 3168651, + 4166200, + 5459523, + 7130496, + 9281874, + 12042092, + 15571031, + 20066900, + 25774405, + 32994399, + 42095202, + 53525811, + 67831218, + 85670061, + 107834823, + 135274799, + 169122009, + 210720231, + 261657253, + 323800420, + 399335440, + 490808349, + 601170414, + 733825617, + 892680222, + 1082908612, + 1310707109, + 1583495809 +}; +char *ClassNameTbl[3] = { "Warrior", "Rogue", "Sorceror" }; +int WarpDropX[4] = { 57, 59, 61, 63 }; +int WarpDropY[4] = { 40, 40, 40, 40 }; +QuestData questlist[16] = +{ + { 5u, 255u, DTYPE_NONE, 0u, 100u, 0u, 0u, TEXT_SMITH24, "The Magic Rock" }, + { 9u, 255u, DTYPE_NONE, 1u, 100u, 0u, 0u, TEXT_WITCH22, "Black Mushroom" }, + { 4u, 255u, DTYPE_NONE, 2u, 100u, 0u, 0u, TEXT_GARBUD1, "Gharbad The Weak" }, + { 8u, 255u, DTYPE_NONE, 3u, 100u, 0u, 0u, TEXT_ZHAR1, "Zhar the Mad" }, + { 14u, 255u, DTYPE_NONE, 4u, 100u, 0u, 0u, TEXT_LACH1, "Lachdanan" }, + { 15u, 255u, DTYPE_NONE, 5u, 100u, 0u, 1u, TEXT_STORY38_1, "Diablo" }, + { 2u, 2u, DTYPE_NONE, 6u, 100u, 0u, 1u, TEXT_WOUND, "The Butcher" }, + { 4u, 255u, DTYPE_NONE, 7u, 100u, 0u, 0u, TEXT_TAVERN24, "Ogden's Sign" }, + { 7u, 255u, DTYPE_NONE, 8u, 100u, 0u, 0u, TEXT_WARR11, "Halls of the Blind" }, + { 5u, 255u, DTYPE_NONE, 9u, 100u, 0u, 0u, TEXT_WARR10, "Valor" }, + { 10u, 255u, DTYPE_NONE, 10u, 100u, 0u, 0u, TEXT_SMITH21, "Anvil of Fury" }, + { 13u, 255u, DTYPE_NONE, 11u, 100u, 0u, 0u, TEXT_WARR12, "Warlord of Blood" }, + { + 3u, + 3u, + DTYPE_CATHEDRAL, + 12u, + 100u, + 1u, + 1u, + TEXT_TAVERN21, + "The Curse of King Leoric" + }, + { + 2u, + 255u, + DTYPE_CAVES, + 13u, + 100u, + 4u, + 0u, + TEXT_HEALER20, + "Poisoned Water Supply" + }, + { + 6u, + 255u, + DTYPE_CATACOMBS, + 14u, + 100u, + 2u, + 0u, + TEXT_WARR1, + "The Chamber of Bone" + }, + { + 15u, + 15u, + DTYPE_CATHEDRAL, + 15u, + 100u, + 5u, + 1u, + TEXT_STORY36, + "Archbishop Lazarus" + } +}; +unsigned char questxoff[7] = { 0u, 255u, 0u, 255u, 254u, 255u, 254u }; +unsigned char questyoff[7] = { 0u, 0u, 255u, 255u, 255u, 254u, 254u }; +char *questtrigstr[5] = +{ + "King Leoric's Tomb", + "The Chamber of Bone", + "Maze", + "A Dark Passage", + "Unholy Altar" +}; +quest_id QuestGroup1[3] = { QTYPE_BUTCH, QTYPE_BOL, QTYPE_GARB }; +quest_id QuestGroup2[3] = { QTYPE_BLIND, QTYPE_INFRA, QTYPE_BLOOD }; +quest_id QuestGroup3[3] = { QTYPE_BLKM, QTYPE_ZHAR, QTYPE_ANVIL }; +quest_id QuestGroup4[2] = { QTYPE_VEIL, QTYPE_WARLRD }; +RECT8 QSRects[32] = +{ + { { 19u, 47u }, { 26u, 55u } }, + { { 26u, 49u }, { 30u, 53u } }, + { { 33u, 19u }, { 47u, 29u } }, + { { 37u, 29u }, { 43u, 39u } }, + { { 27u, 53u }, { 35u, 61u } }, + { { 27u, 35u }, { 34u, 42u } }, + { { 45u, 35u }, { 53u, 43u } }, + { { 45u, 53u }, { 53u, 61u } }, + { { 31u, 39u }, { 49u, 57u } }, + { { 49u, 45u }, { 58u, 51u } }, + { { 57u, 31u }, { 62u, 37u } }, + { { 63u, 31u }, { 69u, 40u } }, + { { 59u, 41u }, { 73u, 55u } }, + { { 63u, 55u }, { 69u, 65u } }, + { { 73u, 45u }, { 78u, 51u } }, + { { 79u, 43u }, { 89u, 53u } }, + { { 43u, 19u }, { 50u, 26u } }, + { { 51u, 19u }, { 59u, 26u } }, + { { 35u, 27u }, { 42u, 34u } }, + { { 43u, 27u }, { 49u, 34u } }, + { { 50u, 27u }, { 59u, 34u } }, + { { 19u, 31u }, { 34u, 47u } }, + { { 34u, 35u }, { 42u, 42u } }, + { { 43u, 35u }, { 50u, 42u } }, + { { 51u, 35u }, { 62u, 42u } }, + { { 63u, 31u }, { 66u, 46u } }, + { { 67u, 31u }, { 78u, 34u } }, + { { 67u, 35u }, { 78u, 42u } }, + { { 67u, 43u }, { 78u, 46u } }, + { { 35u, 43u }, { 42u, 51u } }, + { { 43u, 43u }, { 49u, 51u } }, + { { 50u, 43u }, { 59u, 51u } } +}; +char *quest_level_names[] = +{ + &empty_string, + "Skeleton King's Lair", + "Bone Chamber", + "Maze", + "Poisoned Water Supply", + "Archbishop Lazarus' Lair" +}; +char gbMusicOn = '\x01'; // weak +char gbSoundOn = '\x01'; // weak +char gbDupSounds = '\x01'; // weak +int sgnMusicTrack = 6; +char *sgszMusicTracks[6] = +{ + "Music\\DTowne.wav", + "Music\\DLvlA.wav", + "Music\\DLvlB.wav", + "Music\\DLvlC.wav", + "Music\\DLvlD.wav", + "Music\\Dintro.wav" +}; +SpellData spelldata[37] = +{ + { + REM4X_SPL_NULL, + 0u, + STYPE_FIRE, + NULL, + NULL, + 0, + 0, + 0, + 0u, + 0, + 0, + { MIS_ARROW, MIS_ARROW, MIS_ARROW }, + 0u, + 0u, + 40, + 80, + 0, + 0 + }, + { + REM4X_SPL_FIREBOLT, + 6u, + STYPE_FIRE, + "Firebolt", + "Firebolt", + 1, + 1, + 1, + 0u, + 15, + REM4X_IS_CAST2, + { MIS_FIREBOLT, MIS_ARROW, MIS_ARROW }, + 1u, + 3u, + 40, + 80, + 1000, + 50 + }, + { + REM4X_SPL_HEAL, + 5u, + STYPE_MAGIC, + "Healing", + NULL, + 1, + 1, + 0, + 1u, + 17, + REM4X_IS_CAST8, + { MIS_HEAL, MIS_ARROW, MIS_ARROW }, + 3u, + 1u, + 20, + 40, + 1000, + 50 + }, + { + REM4X_SPL_LIGHTNING, + 10u, + STYPE_LIGHTNING, + "Lightning", + NULL, + 4, + 3, + 1, + 0u, + 20, + REM4X_IS_CAST4, + { MIS_LIGHTCTRL, MIS_ARROW, MIS_ARROW }, + 1u, + 6u, + 20, + 60, + 3000, + 150 + }, + { + REM4X_SPL_FLASH, + 30u, + STYPE_LIGHTNING, + "Flash", + NULL, + 5, + 4, + 0, + 0u, + 33, + REM4X_IS_CAST4, + { MIS_FLASH, MIS_FLASH2, MIS_ARROW }, + 2u, + 16u, + 20, + 40, + 7500, + 500 + }, + { + REM4X_SPL_IDENTIFY, + 13u, + STYPE_MAGIC, + "Identify", + "Identify", + 4294967295, + 4294967295, + 0, + 1u, + 23, + REM4X_IS_CAST6, + { MIS_IDENTIFY, MIS_ARROW, MIS_ARROW }, + 2u, + 1u, + 8, + 12, + 0, + 100 + }, + { + REM4X_SPL_FIREWALL, + 28u, + STYPE_FIRE, + "Fire Wall", + NULL, + 3, + 2, + 1, + 0u, + 27, + REM4X_IS_CAST2, + { MIS_FIREWALLC, MIS_ARROW, MIS_ARROW }, + 2u, + 16u, + 8, + 16, + 6000, + 400 + }, + { + REM4X_SPL_TOWN, + 35u, + STYPE_MAGIC, + "Town Portal", + NULL, + 3, + 3, + 1, + 0u, + 20, + REM4X_IS_CAST6, + { MIS_TOWN, MIS_ARROW, MIS_ARROW }, + 3u, + 18u, + 8, + 12, + 3000, + 200 + }, + { + REM4X_SPL_STONE, + 60u, + STYPE_MAGIC, + "Stone Curse", + NULL, + 6, + 5, + 1, + 0u, + 51, + REM4X_IS_CAST2, + { MIS_STONE, MIS_ARROW, MIS_ARROW }, + 3u, + 40u, + 8, + 16, + 12000, + 800 + }, + { + REM4X_SPL_INFRA, + 40u, + STYPE_MAGIC, + "Infravision", + NULL, + 4294967295, + 4294967295, + 0, + 0u, + 36, + REM4X_IS_CAST8, + { MIS_INFRA, MIS_ARROW, MIS_ARROW }, + 5u, + 20u, + 0, + 0, + 0, + 600 + }, + { + REM4X_SPL_RNDTELEPORT, + 12u, + STYPE_MAGIC, + "Phasing", + NULL, + 7, + 6, + 0, + 0u, + 39, + REM4X_IS_CAST2, + { MIS_RNDTELEPORT, MIS_ARROW, MIS_ARROW }, + 2u, + 4u, + 40, + 80, + 3500, + 200 + }, + { + REM4X_SPL_MANASHIELD, + 33u, + STYPE_MAGIC, + "Mana Shield", + NULL, + 6, + 5, + 0, + 0u, + 25, + REM4X_IS_CAST2, + { MIS_MANASHIELD, MIS_ARROW, MIS_ARROW }, + 0u, + 33u, + 4, + 10, + 16000, + 1200 + }, + { + REM4X_SPL_FIREBALL, + 16u, + STYPE_FIRE, + "Fireball", + NULL, + 8, + 7, + 1, + 0u, + 48, + REM4X_IS_CAST2, + { MIS_FIREBALL, MIS_ARROW, MIS_ARROW }, + 1u, + 10u, + 40, + 80, + 8000, + 300 + }, + { + REM4X_SPL_GUARDIAN, + 50u, + STYPE_FIRE, + "Guardian", + NULL, + 9, + 8, + 1, + 0u, + 61, + REM4X_IS_CAST2, + { MIS_GUARDIAN, MIS_ARROW, MIS_ARROW }, + 2u, + 30u, + 16, + 32, + 14000, + 950 + }, + { + REM4X_SPL_CHAIN, + 30u, + STYPE_LIGHTNING, + "Chain Lightning", + NULL, + 8, + 7, + 0, + 0u, + 54, + REM4X_IS_CAST2, + { MIS_CHAIN, MIS_ARROW, MIS_ARROW }, + 1u, + 18u, + 20, + 60, + 11000, + 750 + }, + { + REM4X_SPL_WAVE, + 35u, + STYPE_FIRE, + "Flame Wave", + NULL, + 9, + 8, + 1, + 0u, + 54, + REM4X_IS_CAST2, + { MIS_WAVE, MIS_ARROW, MIS_ARROW }, + 3u, + 20u, + 20, + 40, + 10000, + 650 + }, + { + REM4X_SPL_DOOMSERP, + 0u, + STYPE_LIGHTNING, + "Doom Serpents", + NULL, + 4294967295, + 4294967295, + 0, + 0u, + 0, + REM4X_IS_CAST2, + { MIS_ARROW, MIS_ARROW, MIS_ARROW }, + 0u, + 0u, + 40, + 80, + 0, + 0 + }, + { + REM4X_SPL_BLODRIT, + 0u, + STYPE_MAGIC, + "Blood Ritual", + NULL, + 4294967295, + 4294967295, + 0, + 0u, + 0, + REM4X_IS_CAST2, + { MIS_ARROW, MIS_ARROW, MIS_ARROW }, + 0u, + 0u, + 40, + 80, + 0, + 0 + }, + { + REM4X_SPL_NOVA, + 60u, + STYPE_MAGIC, + "Nova", + NULL, + 4294967295, + 10, + 0, + 0u, + 87, + REM4X_IS_CAST4, + { MIS_NOVA, MIS_ARROW, MIS_ARROW }, + 3u, + 35u, + 16, + 32, + 21000, + 1300 + }, + { + REM4X_SPL_INVISIBIL, + 0u, + STYPE_MAGIC, + "Invisibility", + NULL, + 4294967295, + 4294967295, + 0, + 0u, + 0, + REM4X_IS_CAST2, + { MIS_ARROW, MIS_ARROW, MIS_ARROW }, + 0u, + 0u, + 40, + 80, + 0, + 0 + }, + { + REM4X_SPL_FLAME, + 11u, + STYPE_FIRE, + "Inferno", + NULL, + 3, + 2, + 1, + 0u, + 20, + REM4X_IS_CAST2, + { MIS_FLAMEC, MIS_ARROW, MIS_ARROW }, + 1u, + 6u, + 20, + 40, + 2000, + 100 + }, + { + REM4X_SPL_GOLEM, + 100u, + STYPE_FIRE, + "Golem", + NULL, + 11, + 9, + 0, + 0u, + 81, + REM4X_IS_CAST2, + { MIS_GOLEM, MIS_ARROW, MIS_ARROW }, + 6u, + 60u, + 16, + 32, + 18000, + 1100 + }, + { + REM4X_SPL_BLODBOIL, + 0u, + STYPE_LIGHTNING, + "Blood Boil", + NULL, + 4294967295, + 4294967295, + 1, + 0u, + 0, + REM4X_IS_CAST8, + { MIS_ARROW, MIS_ARROW, MIS_ARROW }, + 0u, + 0u, + 0, + 0, + 0, + 0 + }, + { + REM4X_SPL_TELEPORT, + 35u, + STYPE_MAGIC, + "Teleport", + NULL, + 14, + 12, + 1, + 0u, + 105, + REM4X_IS_CAST6, + { MIS_TELEPORT, MIS_ARROW, MIS_ARROW }, + 3u, + 15u, + 16, + 32, + 20000, + 1250 + }, + { + REM4X_SPL_APOCA, + 150u, + STYPE_FIRE, + "Apocalypse", + NULL, + 4294967295, + 15, + 0, + 0u, + 149, + REM4X_IS_CAST2, + { MIS_APOCA, MIS_ARROW, MIS_ARROW }, + 6u, + 90u, + 8, + 12, + 30000, + 2000 + }, + { + REM4X_SPL_ETHEREALIZE, + 100u, + STYPE_MAGIC, + "Etherealize", + NULL, + 4294967295, + 4294967295, + 0, + 0u, + 93, + REM4X_IS_CAST2, + { MIS_ETHEREALIZE, MIS_ARROW, MIS_ARROW }, + 0u, + 100u, + 2, + 6, + 26000, + 1600 + }, + { + REM4X_SPL_REPAIR, + 0u, + STYPE_MAGIC, + "Item Repair", + "Item Repair", + 4294967295, + 4294967295, + 0, + 1u, + 4294967295, + REM4X_IS_CAST6, + { MIS_REPAIR, MIS_ARROW, MIS_ARROW }, + 0u, + 0u, + 40, + 80, + 0, + 0 + }, + { + REM4X_SPL_RECHARGE, + 0u, + STYPE_MAGIC, + "Staff Recharge", + "Staff Recharge", + 4294967295, + 4294967295, + 0, + 1u, + 4294967295, + REM4X_IS_CAST6, + { MIS_RECHARGE, MIS_ARROW, MIS_ARROW }, + 0u, + 0u, + 40, + 80, + 0, + 0 + }, + { + REM4X_SPL_DISARM, + 0u, + STYPE_MAGIC, + "Trap Disarm", + "Trap Disarm", + 4294967295, + 4294967295, + 0, + 0u, + 4294967295, + REM4X_IS_CAST6, + { MIS_DISARM, MIS_ARROW, MIS_ARROW }, + 0u, + 0u, + 40, + 80, + 0, + 0 + }, + { + REM4X_SPL_ELEMENT, + 35u, + STYPE_FIRE, + "Elemental", + NULL, + 8, + 6, + 0, + 0u, + 68, + REM4X_IS_CAST2, + { MIS_ELEMENT, MIS_ARROW, MIS_ARROW }, + 2u, + 20u, + 20, + 60, + 10500, + 700 + }, + { + REM4X_SPL_CBOLT, + 6u, + STYPE_LIGHTNING, + "Charged Bolt", + NULL, + 1, + 1, + 1, + 0u, + 25, + REM4X_IS_CAST2, + { MIS_CBOLT, MIS_ARROW, MIS_ARROW }, + 1u, + 6u, + 40, + 80, + 1000, + 50 + }, + { + REM4X_SPL_HBOLT, + 7u, + STYPE_MAGIC, + "Holy Bolt", + NULL, + 1, + 1, + 1, + 0u, + 20, + REM4X_IS_CAST2, + { MIS_HBOLT, MIS_ARROW, MIS_ARROW }, + 1u, + 3u, + 40, + 80, + 1000, + 50 + }, + { + REM4X_SPL_RESURRECT, + 20u, + STYPE_MAGIC, + "Resurrect", + NULL, + 4294967295, + 5, + 0, + 1u, + 30, + REM4X_IS_CAST8, + { MIS_RESURRECT, MIS_ARROW, MIS_ARROW }, + 0u, + 20u, + 4, + 10, + 4000, + 250 + }, + { + REM4X_SPL_TELEKINESIS, + 15u, + STYPE_MAGIC, + "Telekinesis", + NULL, + 2, + 2, + 0, + 0u, + 33, + REM4X_IS_CAST2, + { MIS_TELEKINESIS, MIS_ARROW, MIS_ARROW }, + 2u, + 8u, + 20, + 40, + 2500, + 200 + }, + { + REM4X_SPL_HEALOTHER, + 5u, + STYPE_MAGIC, + "Heal Other", + NULL, + 1, + 1, + 0, + 1u, + 17, + REM4X_IS_CAST8, + { MIS_HEALOTHER, MIS_ARROW, MIS_ARROW }, + 3u, + 1u, + 20, + 40, + 1000, + 50 + }, + { + REM4X_SPL_FLARE, + 25u, + STYPE_MAGIC, + "Blood Star", + NULL, + 14, + 13, + 0, + 0u, + 70, + REM4X_IS_CAST2, + { MIS_FLARE, MIS_ARROW, MIS_ARROW }, + 2u, + 14u, + 20, + 60, + 27500, + 1800 + }, + { + REM4X_SPL_BONESPIRIT, + 24u, + STYPE_MAGIC, + "Bone Spirit", + NULL, + 9, + 7, + 0, + 0u, + 34, + REM4X_IS_CAST2, + { MIS_BONESPIRIT, MIS_ARROW, MIS_ARROW }, + 1u, + 12u, + 20, + 60, + 11500, + 800 + } +}; +int SStringY[24] = +{ + 0, + 12, + 24, + 36, + 48, + 60, + 72, + 84, + 96, + 108, + 120, + 132, + 144, + 156, + 168, + 180, + 192, + 204, + 216, + 228, + 240, + 252, + 264, + 276 +}; +char *talkname[9] = +{ + "Griswold", + "Pepin", + &empty_string, + "Ogden", + "Cain", + "Farnham", + "Adria", + "Gillian", + "Wirt" +}; +theme_id ThemeGood[4] = { THEME_GOATSHRINE, THEME_SHRINE, THEME_SKELROOM, THEME_LIBRARY }; +int trm5x[25] = +{ + 4294967294, + 4294967295, + 0, + 1, + 2, + 4294967294, + 4294967295, + 0, + 1, + 2, + 4294967294, + 4294967295, + 0, + 1, + 2, + 4294967294, + 4294967295, + 0, + 1, + 2, + 4294967294, + 4294967295, + 0, + 1, + 2 +}; +int trm5y[25] = +{ + 4294967294, + 4294967294, + 4294967294, + 4294967294, + 4294967294, + 4294967295, + 4294967295, + 4294967295, + 4294967295, + 4294967295, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 2, + 2, + 2, + 2, + 2 +}; +int trm3x[9] = { 4294967295, 0, 1, 4294967295, 0, 1, 4294967295, 0, 1 }; +int trm3y[9] = { 4294967295, 4294967295, 4294967295, 0, 0, 0, 1, 1, 1 }; +unsigned char AnimOrder[6][148] = +{ + { + 5u, + 6u, + 7u, + 8u, + 9u, + 10u, + 11u, + 12u, + 13u, + 14u, + 14u, + 13u, + 12u, + 11u, + 10u, + 9u, + 8u, + 7u, + 6u, + 5u, + 5u, + 6u, + 7u, + 8u, + 9u, + 10u, + 11u, + 12u, + 13u, + 14u, + 14u, + 13u, + 12u, + 11u, + 10u, + 9u, + 8u, + 7u, + 6u, + 5u, + 5u, + 6u, + 7u, + 8u, + 9u, + 10u, + 11u, + 12u, + 13u, + 14u, + 14u, + 13u, + 12u, + 11u, + 10u, + 9u, + 8u, + 7u, + 6u, + 5u, + 5u, + 6u, + 7u, + 8u, + 9u, + 10u, + 11u, + 12u, + 13u, + 14u, + 14u, + 13u, + 12u, + 11u, + 10u, + 9u, + 8u, + 7u, + 6u, + 5u, + 5u, + 6u, + 7u, + 8u, + 9u, + 10u, + 11u, + 12u, + 13u, + 14u, + 14u, + 13u, + 12u, + 11u, + 10u, + 9u, + 8u, + 7u, + 6u, + 5u, + 5u, + 6u, + 7u, + 8u, + 9u, + 10u, + 11u, + 12u, + 13u, + 14u, + 15u, + 5u, + 1u, + 1u, + 1u, + 1u, + 1u, + 1u, + 1u, + 1u, + 1u, + 1u, + 1u, + 1u, + 1u, + 1u, + 1u, + 2u, + 3u, + 4u, + 255u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u + }, + { + 1u, + 2u, + 3u, + 3u, + 2u, + 1u, + 20u, + 19u, + 19u, + 20u, + 1u, + 2u, + 3u, + 3u, + 2u, + 1u, + 20u, + 19u, + 19u, + 20u, + 1u, + 2u, + 3u, + 3u, + 2u, + 1u, + 20u, + 19u, + 19u, + 20u, + 1u, + 2u, + 3u, + 3u, + 2u, + 1u, + 20u, + 19u, + 19u, + 20u, + 1u, + 2u, + 3u, + 4u, + 5u, + 6u, + 7u, + 8u, + 9u, + 10u, + 11u, + 12u, + 13u, + 14u, + 15u, + 16u, + 15u, + 14u, + 13u, + 12u, + 11u, + 10u, + 9u, + 8u, + 7u, + 6u, + 5u, + 4u, + 5u, + 6u, + 7u, + 8u, + 9u, + 10u, + 11u, + 12u, + 13u, + 14u, + 15u, + 16u, + 15u, + 14u, + 13u, + 12u, + 11u, + 10u, + 9u, + 8u, + 7u, + 6u, + 5u, + 4u, + 5u, + 6u, + 7u, + 8u, + 9u, + 10u, + 11u, + 12u, + 13u, + 14u, + 15u, + 16u, + 17u, + 18u, + 19u, + 20u, + 255u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u + }, + { + 1u, + 1u, + 25u, + 25u, + 24u, + 23u, + 22u, + 21u, + 20u, + 19u, + 18u, + 17u, + 16u, + 15u, + 16u, + 17u, + 18u, + 19u, + 20u, + 21u, + 22u, + 23u, + 24u, + 25u, + 25u, + 25u, + 1u, + 1u, + 1u, + 25u, + 1u, + 2u, + 3u, + 4u, + 5u, + 6u, + 7u, + 8u, + 9u, + 10u, + 11u, + 12u, + 13u, + 14u, + 15u, + 14u, + 13u, + 12u, + 11u, + 10u, + 9u, + 8u, + 7u, + 6u, + 5u, + 4u, + 3u, + 2u, + 1u, + 255u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u + }, + { + 1u, + 2u, + 3u, + 3u, + 2u, + 1u, + 16u, + 15u, + 14u, + 14u, + 16u, + 1u, + 2u, + 3u, + 3u, + 2u, + 1u, + 16u, + 15u, + 14u, + 14u, + 15u, + 16u, + 1u, + 2u, + 3u, + 3u, + 2u, + 1u, + 16u, + 15u, + 14u, + 14u, + 15u, + 16u, + 1u, + 2u, + 3u, + 3u, + 2u, + 1u, + 16u, + 15u, + 14u, + 14u, + 15u, + 16u, + 1u, + 2u, + 3u, + 3u, + 2u, + 1u, + 16u, + 15u, + 14u, + 14u, + 15u, + 16u, + 1u, + 2u, + 3u, + 3u, + 2u, + 1u, + 16u, + 15u, + 14u, + 14u, + 15u, + 16u, + 1u, + 2u, + 3u, + 3u, + 2u, + 1u, + 16u, + 15u, + 14u, + 14u, + 15u, + 16u, + 1u, + 2u, + 3u, + 2u, + 1u, + 16u, + 15u, + 14u, + 14u, + 15u, + 16u, + 1u, + 2u, + 3u, + 4u, + 5u, + 6u, + 7u, + 8u, + 9u, + 10u, + 11u, + 12u, + 13u, + 14u, + 15u, + 16u, + 255u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u + }, + { + 1u, + 1u, + 1u, + 2u, + 3u, + 4u, + 5u, + 6u, + 7u, + 8u, + 9u, + 10u, + 11u, + 11u, + 11u, + 11u, + 12u, + 13u, + 14u, + 15u, + 16u, + 17u, + 18u, + 18u, + 1u, + 1u, + 1u, + 18u, + 17u, + 16u, + 15u, + 14u, + 13u, + 12u, + 11u, + 10u, + 11u, + 12u, + 13u, + 14u, + 15u, + 16u, + 17u, + 18u, + 1u, + 2u, + 3u, + 4u, + 5u, + 5u, + 5u, + 4u, + 3u, + 2u, + 255u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u + }, + { + 4u, + 4u, + 4u, + 5u, + 6u, + 6u, + 6u, + 5u, + 4u, + 15u, + 14u, + 13u, + 13u, + 13u, + 14u, + 15u, + 4u, + 5u, + 6u, + 6u, + 6u, + 5u, + 4u, + 4u, + 4u, + 5u, + 6u, + 6u, + 6u, + 5u, + 4u, + 15u, + 14u, + 13u, + 13u, + 13u, + 14u, + 15u, + 4u, + 5u, + 6u, + 6u, + 6u, + 5u, + 4u, + 4u, + 4u, + 5u, + 6u, + 6u, + 6u, + 5u, + 4u, + 15u, + 14u, + 13u, + 13u, + 13u, + 14u, + 15u, + 4u, + 5u, + 6u, + 6u, + 6u, + 5u, + 4u, + 3u, + 2u, + 1u, + 19u, + 18u, + 19u, + 1u, + 2u, + 1u, + 19u, + 18u, + 19u, + 1u, + 2u, + 1u, + 2u, + 3u, + 4u, + 5u, + 6u, + 7u, + 8u, + 9u, + 10u, + 11u, + 12u, + 13u, + 14u, + 15u, + 15u, + 15u, + 14u, + 13u, + 13u, + 13u, + 13u, + 14u, + 15u, + 15u, + 15u, + 14u, + 13u, + 12u, + 12u, + 12u, + 11u, + 10u, + 10u, + 10u, + 9u, + 8u, + 9u, + 10u, + 10u, + 11u, + 12u, + 13u, + 14u, + 15u, + 16u, + 17u, + 18u, + 19u, + 1u, + 2u, + 1u, + 19u, + 18u, + 19u, + 1u, + 2u, + 1u, + 2u, + 3u, + 255u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u + } +}; +int TownCowX[3] = { 58, 56, 59 }; +int TownCowY[3] = { 16, 14, 20 }; +int TownCowDir[3] = { 1, 3, 4 }; +int cowoffx[8] = { 4294967295, 0, 4294967295, 4294967295, 4294967295, 0, 4294967295, 4294967295 }; +int cowoffy[8] = { 4294967295, 4294967295, 4294967295, 0, 4294967295, 4294967295, 4294967295, 0 }; +QuestTalkData Qtalklist[11] = +{ + { + TEXT_SMITH25, + TEXT_SMITH19, + TEXT_INVALID, + TEXT_INVALID, + TEXT_SMITH13, + TEXT_INVALID, + TEXT_SMITH10, + TEXT_SMITH2, + TEXT_SMITH12, + TEXT_SMITH14, + TEXT_SMITH22, + TEXT_SMITH17, + TEXT_SMITH1, + TEXT_SMITH4, + TEXT_SMITH7, + TEXT_SMITH3 + }, + { + TEXT_HEALER18, + TEXT_INVALID, + TEXT_INVALID, + TEXT_INVALID, + TEXT_HEALER11, + TEXT_INVALID, + TEXT_HEALER8, + TEXT_HEALER2, + TEXT_HEALER10, + TEXT_HEALER13, + TEXT_HEALER12, + TEXT_HEALER16, + TEXT_HEALER1, + TEXT_HEALER21, + TEXT_HEALER5, + TEXT_HEALER3 + }, + { + TEXT_INVALID, + TEXT_INVALID, + TEXT_INVALID, + TEXT_INVALID, + TEXT_INVALID, + TEXT_INVALID, + TEXT_INVALID, + TEXT_INVALID, + TEXT_INVALID, + TEXT_INVALID, + TEXT_INVALID, + TEXT_INVALID, + TEXT_INVALID, + TEXT_INVALID, + TEXT_INVALID, + TEXT_INVALID + }, + { + TEXT_TAVERN18, + TEXT_TAVERN19, + TEXT_INVALID, + TEXT_INVALID, + TEXT_TAVERN11, + TEXT_INVALID, + TEXT_TAVERN8, + TEXT_INVALID, + TEXT_TAVERN10, + TEXT_TAVERN13, + TEXT_TAVERN12, + TEXT_TAVERN16, + TEXT_TAVERN22, + TEXT_TAVERN2, + TEXT_TAVERN5, + TEXT_TAVERN1 + }, + { + TEXT_STORY20, + TEXT_STORY21, + TEXT_INVALID, + TEXT_INVALID, + TEXT_STORY13, + TEXT_STORY38_1, + TEXT_STORY10, + TEXT_STORY2, + TEXT_STORY12, + TEXT_STORY15, + TEXT_STORY14, + TEXT_STORY18, + TEXT_STORY1, + TEXT_STORY4, + TEXT_STORY7, + TEXT_STORY37 + }, + { + TEXT_DRUNK19, + TEXT_DRUNK20, + TEXT_INVALID, + TEXT_INVALID, + TEXT_DRUNK13, + TEXT_INVALID, + TEXT_DRUNK10, + TEXT_DRUNK2, + TEXT_DRUNK12, + TEXT_DRUNK15, + TEXT_DRUNK14, + TEXT_DRUNK17, + TEXT_DRUNK1, + TEXT_DRUNK4, + TEXT_DRUNK7, + TEXT_DRUNK3 + }, + { + TEXT_WITCH20, + TEXT_WITCH23, + TEXT_INVALID, + TEXT_INVALID, + TEXT_WITCH13, + TEXT_INVALID, + TEXT_WITCH10, + TEXT_WITCH2, + TEXT_WITCH12, + TEXT_WITCH15, + TEXT_WITCH14, + TEXT_WITCH18, + TEXT_WITCH1, + TEXT_WITCH4, + TEXT_WITCH7, + TEXT_WITCH3 + }, + { + TEXT_BMAID18, + TEXT_BMAID19, + TEXT_INVALID, + TEXT_INVALID, + TEXT_BMAID11, + TEXT_INVALID, + TEXT_BMAID8, + TEXT_BMAID2, + TEXT_BMAID10, + TEXT_BMAID13, + TEXT_BMAID12, + TEXT_BMAID16, + TEXT_BMAID1, + TEXT_BMAID4, + TEXT_BMAID6, + TEXT_BMAID3 + }, + { + TEXT_PEGBOY18, + TEXT_PEGBOY19, + TEXT_INVALID, + TEXT_INVALID, + TEXT_PEGBOY12, + TEXT_INVALID, + TEXT_PEGBOY10, + TEXT_PEGBOY2, + TEXT_PEGBOY11, + TEXT_PEGBOY14, + TEXT_PEGBOY13, + TEXT_PEGBOY17, + TEXT_PEGBOY1, + TEXT_PEGBOY4, + TEXT_PEGBOY7, + TEXT_PEGBOY3 + }, + { + TEXT_INVALID, + TEXT_INVALID, + TEXT_INVALID, + TEXT_INVALID, + TEXT_INVALID, + TEXT_INVALID, + TEXT_INVALID, + TEXT_INVALID, + TEXT_INVALID, + TEXT_INVALID, + TEXT_INVALID, + TEXT_INVALID, + TEXT_INVALID, + TEXT_INVALID, + TEXT_INVALID, + TEXT_INVALID + }, + { + TEXT_STORY1, + TEXT_STORY1, + TEXT_STORY1, + TEXT_STORY1, + TEXT_STORY1, + TEXT_STORY1, + TEXT_STORY1, + TEXT_STORY1, + TEXT_STORY1, + TEXT_STORY1, + TEXT_STORY1, + TEXT_STORY1, + TEXT_STORY1, + TEXT_STORY1, + TEXT_STORY1, + TEXT_STORY1 + } +}; +int CowPlaying = 4294967295; +int TownDownList[11] = { 716, 715, 719, 720, 721, 723, 724, 725, 726, 727, 4294967295 }; +int TownWarp1List[13] = +{ + 1171, + 1172, + 1173, + 1174, + 1175, + 1176, + 1177, + 1178, + 1179, + 1181, + 1183, + 1185, + 4294967295 +}; +int L1UpList[12] = { 127, 129, 130, 131, 132, 133, 135, 137, 138, 139, 140, 4294967295 }; +int L1DownList[10] = { 106, 107, 108, 109, 110, 112, 114, 115, 118, 4294967295 }; +int L2UpList[3] = { 266, 267, 4294967295 }; +int L2DownList[5] = { 269, 270, 271, 272, 4294967295 }; +int L2TWarpUpList[3] = { 558, 559, 4294967295 }; +int L3UpList[15] = +{ + 170, + 171, + 172, + 173, + 174, + 175, + 176, + 177, + 178, + 179, + 180, + 181, + 182, + 183, + 4294967295 +}; +int L3DownList[9] = { 162, 163, 164, 165, 166, 167, 168, 169, 4294967295 }; +int L3TWarpUpList[14] = { 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 4294967295 }; +int L4UpList[4] = { 82, 83, 90, 4294967295 }; +int L4DownList[6] = { 120, 130, 131, 132, 133, 4294967295 }; +int L4TWarpUpList[4] = { 421, 422, 429, 4294967295 }; +int L4PentaList[33] = +{ + 353, + 354, + 355, + 356, + 357, + 358, + 359, + 360, + 361, + 362, + 363, + 364, + 365, + 366, + 367, + 368, + 369, + 370, + 371, + 372, + 373, + 374, + 375, + 376, + 377, + 378, + 379, + 380, + 381, + 382, + 383, + 384, + 4294967295 +}; +int world_4B325C = 0; +unsigned char world_4B3260[5] = { 0u, 0u, 0u, 0u, 0u }; +int world_4B3265 = 0; +int world_4B3269[5] = { 0, 0, 0, 0, 0 }; +int tile_draw_masks[96] = +{ + 3937053354, + 4116010325, + 4272597674, + 4283782485, + 4293569194, + 4294268245, + 4294879914, + 4294923605, + 4294961834, + 4294964565, + 4294966954, + 4294967125, + 4294967274, + 4294967285, + 4294967294, + 4294967295, + 4294967295, + 4294967295, + 4294967295, + 4294967295, + 4294967295, + 4294967295, + 4294967295, + 4294967295, + 4294967295, + 4294967295, + 4294967295, + 4294967295, + 4294967295, + 4294967295, + 4294967295, + 4294967295, + 2863311531, + 1431655775, + 2863311551, + 1431655935, + 2863311871, + 1431658495, + 2863316991, + 1431699455, + 2863398911, + 1432354815, + 2864709631, + 1442840575, + 2885681151, + 1610612735, + 3221225471, + 4294967295, + 4294967295, + 4294967295, + 4294967295, + 4294967295, + 4294967295, + 4294967295, + 4294967295, + 4294967295, + 4294967295, + 4294967295, + 4294967295, + 4294967295, + 4294967295, + 4294967295, + 4294967295, + 4294967295, + 2863311530, + 1431655765, + 2863311530, + 1431655765, + 2863311530, + 1431655765, + 2863311530, + 1431655765, + 2863311530, + 1431655765, + 2863311530, + 1431655765, + 2863311530, + 1431655765, + 2863311530, + 1431655765, + 2863311530, + 1431655765, + 2863311530, + 1431655765, + 2863311530, + 1431655765, + 2863311530, + 1431655765, + 2863311530, + 1431655765, + 2863311530, + 1431655765, + 2863311530, + 1431655765, + 2863311530, + 1431655765 +}; +int world_4B33FD[48] = +{ + 0, + 0, + 0, + 4, + 4, + 4, + 8, + 8, + 8, + 12, + 12, + 12, + 16, + 16, + 16, + 20, + 20, + 20, + 24, + 24, + 24, + 28, + 28, + 28, + 32, + 32, + 32, + 36, + 36, + 36, + 40, + 40, + 40, + 44, + 44, + 44, + 48, + 48, + 48, + 52, + 52, + 52, + 56, + 56, + 56, + 60, + 60, + 60 +}; +int world_4B34BD[17] = { 0, 4, 8, 16, 24, 36, 48, 64, 80, 100, 120, 144, 168, 196, 224, 256, 288 }; +int world_4B3501[17] = +{ + 0, + 32, + 60, + 88, + 112, + 136, + 156, + 176, + 192, + 208, + 220, + 232, + 240, + 248, + 252, + 256, + 288 +}; diff --git a/2018_03_14/DiabDev/_diab.c b/2018_03_14/DiabDev/_diab.c new file mode 100644 index 00000000..276b0110 --- /dev/null +++ b/2018_03_14/DiabDev/_diab.c @@ -0,0 +1,108579 @@ + +//----- (0040102A) -------------------------------------------------------- +char *__fastcall GetErr(int error_code) +{ + int v1; // edi + unsigned int v2; // eax + int v3; // eax + signed int v4; // eax + _BYTE *i; // ecx + + v1 = error_code; + v2 = ((unsigned int)error_code >> 16) & 0x1FFF; + if ( v2 == 2168 ) + { + GetDSErr(error_code, (char *)error_buf, 256); + } + else if ( v2 == 2166 ) + { + GetDDErr(error_code, (char *)error_buf, 256); + } + else + { + _LOBYTE(v3) = SErrGetErrorStr(error_code, (char *)error_buf, 256); + if ( !v3 && !FormatMessageA(0x1000u, 0, v1, 0x400u, (LPSTR)error_buf, 0x100u, 0) ) + wsprintfA((LPSTR)error_buf, "unknown error 0x%08x", v1); + } + v4 = strlen((const char *)error_buf); + for ( i = (unsigned char *)&appfat_terminated + v4 + 3; v4 > 0; *i = 0 ) + { + --v4; + if ( *--i != 13 && *i != 10 ) + break; + } + return (char *)error_buf; +} +// 4B7930: using guessed type int appfat_terminated; + +//----- (004010CE) -------------------------------------------------------- +void __fastcall GetDDErr(int error_code, char *error_buf, int error_buf_len) +{ + const char *v3; // eax + char v4[4]; // [esp+0h] [ebp-14h] + + if ( error_code > (signed int)0x887601AE ) + { + if ( error_code > (signed int)0x8876023D ) + { + if ( error_code > (signed int)0x88760280 ) + { + switch ( error_code ) + { + case (int)0x88760294: + v3 = "DDERR_CANTPAGEUNLOCK"; + goto LABEL_182; + case (int)0x887602A8: + v3 = "DDERR_NOTPAGELOCKED"; + goto LABEL_182; + case 0: + v3 = "DD_OK"; + goto LABEL_182; + } + } + else + { + if ( error_code == 0x88760280 ) + { + v3 = "DDERR_CANTPAGELOCK"; + goto LABEL_182; + } + switch ( error_code ) + { + case (int)0x8876023E: + v3 = "DDERR_BLTFASTCANTCLIP"; + goto LABEL_182; + case (int)0x8876023F: + v3 = "DDERR_NOBLTHW"; + goto LABEL_182; + case (int)0x88760240: + v3 = "DDERR_NODDROPSHW"; + goto LABEL_182; + case (int)0x88760241: + v3 = "DDERR_OVERLAYNOTVISIBLE"; + goto LABEL_182; + case (int)0x88760242: + v3 = "DDERR_NOOVERLAYDEST"; + goto LABEL_182; + case (int)0x88760243: + v3 = "DDERR_INVALIDPOSITION"; + goto LABEL_182; + case (int)0x88760244: + v3 = "DDERR_NOTAOVERLAYSURFACE"; + goto LABEL_182; + case (int)0x88760245: + v3 = "DDERR_EXCLUSIVEMODEALREADYSET"; + goto LABEL_182; + case (int)0x88760246: + v3 = "DDERR_NOTFLIPPABLE"; + goto LABEL_182; + case (int)0x88760247: + v3 = "DDERR_CANTDUPLICATE"; + goto LABEL_182; + case (int)0x88760248: + v3 = "DDERR_NOTLOCKED"; + goto LABEL_182; + case (int)0x88760249: + v3 = "DDERR_CANTCREATEDC"; + goto LABEL_182; + case (int)0x8876024A: + v3 = "DDERR_NODC"; + goto LABEL_182; + case (int)0x8876024B: + v3 = "DDERR_WRONGMODE"; + goto LABEL_182; + case (int)0x8876024C: + v3 = "DDERR_IMPLICITLYCREATED"; + goto LABEL_182; + case (int)0x8876024D: + v3 = "DDERR_NOTPALETTIZED"; + goto LABEL_182; + case (int)0x8876024F: + v3 = "DDERR_NOMIPMAPHW"; + goto LABEL_182; + case (int)0x88760250: + v3 = "DDERR_INVALIDSURFACETYPE"; + goto LABEL_182; + case (int)0x8876026C: + v3 = "DDERR_DCALREADYCREATED"; + goto LABEL_182; + default: + goto LABEL_178; + } + } + } + else + { + if ( error_code == 0x8876023D ) + { + v3 = "DDERR_NOPALETTEHW"; + goto LABEL_182; + } + if ( error_code > (signed int)0x88760231 ) + { + switch ( error_code ) + { + case (int)0x88760232: + v3 = "DDERR_DIRECTDRAWALREADYCREATED"; + goto LABEL_182; + case (int)0x88760233: + v3 = "DDERR_NODIRECTDRAWHW"; + goto LABEL_182; + case (int)0x88760234: + v3 = "DDERR_PRIMARYSURFACEALREADYEXISTS"; + goto LABEL_182; + case (int)0x88760235: + v3 = "DDERR_NOEMULATION"; + goto LABEL_182; + case (int)0x88760236: + v3 = "DDERR_REGIONTOOSMALL"; + goto LABEL_182; + case (int)0x88760237: + v3 = "DDERR_CLIPPERISUSINGHWND"; + goto LABEL_182; + case (int)0x88760238: + v3 = "DDERR_NOCLIPPERATTACHED"; + goto LABEL_182; + case (int)0x88760239: + v3 = "DDERR_NOHWND"; + goto LABEL_182; + case (int)0x8876023A: + v3 = "DDERR_HWNDSUBCLASSED"; + goto LABEL_182; + case (int)0x8876023B: + v3 = "DDERR_HWNDALREADYSET"; + goto LABEL_182; + case (int)0x8876023C: + v3 = "DDERR_NOPALETTEATTACHED"; + goto LABEL_182; + default: + goto LABEL_178; + } + } + else + { + if ( error_code == 0x88760231 ) + { + v3 = "DDERR_INVALIDDIRECTDRAWGUID"; + goto LABEL_182; + } + if ( error_code > (signed int)0x887601EA ) + { + switch ( error_code ) + { + case (int)0x887601FE: + v3 = "DDERR_UNSUPPORTEDFORMAT"; + goto LABEL_182; + case (int)0x88760208: + v3 = "DDERR_UNSUPPORTEDMASK"; + goto LABEL_182; + case (int)0x88760219: + v3 = "DDERR_VERTICALBLANKINPROGRESS"; + goto LABEL_182; + case (int)0x8876021C: + v3 = "DDERR_WASSTILLDRAWING"; + goto LABEL_182; + case (int)0x88760230: + v3 = "DDERR_XALIGN"; + goto LABEL_182; + } + } + else + { + switch ( error_code ) + { + case (int)0x887601EA: + v3 = "DDERR_TOOBIGWIDTH"; + goto LABEL_182; + case (int)0x887601B3: + v3 = "DDERR_CANTLOCKSURFACE"; + goto LABEL_182; + case (int)0x887601B8: + v3 = "DDERR_SURFACEISOBSCURED"; + goto LABEL_182; + case (int)0x887601C2: + v3 = "DDERR_SURFACELOST"; + goto LABEL_182; + case (int)0x887601CC: + v3 = "DDERR_SURFACENOTATTACHED"; + goto LABEL_182; + case (int)0x887601D6: + v3 = "DDERR_TOOBIGHEIGHT"; + goto LABEL_182; + case (int)0x887601E0: + v3 = "DDERR_TOOBIGSIZE"; + goto LABEL_182; + } + } + } + } + goto LABEL_178; + } + if ( error_code == 0x887601AE ) + { + v3 = "DDERR_SURFACEBUSY"; + goto LABEL_182; + } + if ( error_code > (signed int)0x887600DC ) + { + if ( error_code > (signed int)0x8876014A ) + { + if ( error_code > (signed int)0x8876017E ) + { + switch ( error_code ) + { + case (int)0x88760180: + v3 = "DDERR_OVERLAYCOLORKEYONLYONEACTIVE"; + goto LABEL_182; + case (int)0x88760183: + v3 = "DDERR_PALETTEBUSY"; + goto LABEL_182; + case (int)0x88760190: + v3 = "DDERR_COLORKEYNOTSET"; + goto LABEL_182; + case (int)0x8876019A: + v3 = "DDERR_SURFACEALREADYATTACHED"; + goto LABEL_182; + case (int)0x887601A4: + v3 = "DDERR_SURFACEALREADYDEPENDENT"; + goto LABEL_182; + } + } + else + { + switch ( error_code ) + { + case (int)0x8876017E: + v3 = "DDERR_OVERLAYCANTCLIP"; + goto LABEL_182; + case (int)0x8876014F: + v3 = "DDERR_NOVSYNCHW"; + goto LABEL_182; + case (int)0x88760154: + v3 = "DDERR_NOZBUFFERHW"; + goto LABEL_182; + case (int)0x8876015E: + v3 = "DDERR_NOZOVERLAYHW"; + goto LABEL_182; + case (int)0x88760168: + v3 = "DDERR_OUTOFCAPS"; + goto LABEL_182; + case (int)0x8876017C: + v3 = "DDERR_OUTOFVIDEOMEMORY"; + goto LABEL_182; + } + } + } + else + { + if ( error_code == 0x8876014A ) + { + v3 = "DDERR_NOTEXTUREHW"; + goto LABEL_182; + } + if ( error_code > (signed int)0x88760118 ) + { + switch ( error_code ) + { + case (int)0x88760122: + v3 = "DDERR_NOROTATIONHW"; + goto LABEL_182; + case (int)0x88760136: + v3 = "DDERR_NOSTRETCHHW"; + goto LABEL_182; + case (int)0x8876013C: + v3 = "DDERR_NOT4BITCOLOR"; + goto LABEL_182; + case (int)0x8876013D: + v3 = "DDERR_NOT4BITCOLORINDEX"; + goto LABEL_182; + case (int)0x88760140: + v3 = "DDERR_NOT8BITCOLOR"; + goto LABEL_182; + } + } + else + { + switch ( error_code ) + { + case (int)0x88760118: + v3 = "DDERR_NORASTEROPHW"; + goto LABEL_182; + case (int)0x887600E1: + v3 = "DDERR_NOEXCLUSIVEMODE"; + goto LABEL_182; + case (int)0x887600E6: + v3 = "DDERR_NOFLIPHW"; + goto LABEL_182; + case (int)0x887600F0: + v3 = "DDERR_NOGDI"; + goto LABEL_182; + case (int)0x887600FA: + v3 = "DDERR_NOMIRRORHW"; + goto LABEL_182; + case (int)0x887600FF: + v3 = "DDERR_NOTFOUND"; + goto LABEL_182; + case (int)0x88760104: + v3 = "DDERR_NOOVERLAYHW"; + goto LABEL_182; + } + } + } + goto LABEL_178; + } + if ( error_code == 0x887600DC ) + { + v3 = "DDERR_NOCOLORKEYHW"; + goto LABEL_182; + } + if ( error_code > (signed int)0x8876006E ) + { + if ( error_code > (signed int)0x887600AA ) + { + switch ( error_code ) + { + case (int)0x887600B4: + v3 = "DDERR_NOALPHAHW"; + goto LABEL_182; + case (int)0x887600CD: + v3 = "DDERR_NOCLIPLIST"; + goto LABEL_182; + case (int)0x887600D2: + v3 = "DDERR_NOCOLORCONVHW"; + goto LABEL_182; + case (int)0x887600D4: + v3 = "DDERR_NOCOOPERATIVELEVELSET"; + goto LABEL_182; + case (int)0x887600D7: + v3 = "DDERR_NOCOLORKEY"; + goto LABEL_182; + } + } + else + { + switch ( error_code ) + { + case (int)0x887600AA: + v3 = "DDERR_NO3D"; + goto LABEL_182; + case (int)0x88760078: + v3 = "DDERR_INVALIDMODE"; + goto LABEL_182; + case (int)0x88760082: + v3 = "DDERR_INVALIDOBJECT"; + goto LABEL_182; + case (int)0x88760091: + v3 = "DDERR_INVALIDPIXELFORMAT"; + goto LABEL_182; + case (int)0x88760096: + v3 = "DDERR_INVALIDRECT"; + goto LABEL_182; + case (int)0x887600A0: + v3 = "DDERR_LOCKEDSURFACES"; + goto LABEL_182; + } + } + goto LABEL_178; + } + if ( error_code == 0x8876006E ) + { + v3 = "DDERR_INVALIDCLIPLIST"; + goto LABEL_182; + } + if ( error_code > (signed int)0x88760014 ) + { + switch ( error_code ) + { + case (int)0x88760028: + v3 = "DDERR_CURRENTLYNOTAVAIL"; + goto LABEL_182; + case (int)0x88760037: + v3 = "DDERR_EXCEPTION"; + goto LABEL_182; + case (int)0x8876005A: + v3 = "DDERR_HEIGHTALIGN"; + goto LABEL_182; + case (int)0x8876005F: + v3 = "DDERR_INCOMPATIBLEPRIMARY"; + goto LABEL_182; + case (int)0x88760064: + v3 = "DDERR_INVALIDCAPS"; + goto LABEL_182; + } + goto LABEL_178; + } + switch ( error_code ) + { + case (int)0x88760014: + v3 = "DDERR_CANNOTDETACHSURFACE"; + goto LABEL_182; + case (int)0x80004001: + v3 = "DDERR_UNSUPPORTED"; + goto LABEL_182; + case (int)0x80004005: + v3 = "DDERR_GENERIC"; + goto LABEL_182; + case (int)0x8007000E: + v3 = "DDERR_OUTOFMEMORY"; + goto LABEL_182; + case (int)0x80070057: + v3 = "DDERR_INVALIDPARAMS"; + goto LABEL_182; + case (int)0x88760005: + v3 = "DDERR_ALREADYINITIALIZED"; + goto LABEL_182; + } + if ( error_code != 0x8876000A ) + { +LABEL_178: + strcpy(v4, "DDERR unknown 0x%x"); + sprintf(error_buf, v4, error_code); + return; + } + v3 = "DDERR_CANNOTATTACHSURFACE"; +LABEL_182: + strncpy(error_buf, v3, error_buf_len); +} + +//----- (00401831) -------------------------------------------------------- +void __fastcall GetDSErr(int error_code, char *error_buf, int error_buf_len) +{ + const char *v3; // eax + char v4[4]; // [esp+0h] [ebp-14h] + + if ( error_code > (signed int)0x88780032 ) + { + switch ( error_code ) + { + case (int)0x88780046: + v3 = "DSERR_PRIOLEVELNEEDED"; + goto LABEL_29; + case (int)0x88780064: + v3 = "DSERR_BADFORMAT"; + goto LABEL_29; + case (int)0x88780078: + v3 = "DSERR_NODRIVER"; + goto LABEL_29; + case (int)0x88780082: + v3 = "DSERR_ALREADYINITIALIZED"; + goto LABEL_29; + case (int)0x88780096: + v3 = "DSERR_BUFFERLOST"; + goto LABEL_29; + case 0: + v3 = "DS_OK"; + goto LABEL_29; + } + goto LABEL_22; + } + switch ( error_code ) + { + case (int)0x88780032: + v3 = "DSERR_INVALIDCALL"; + goto LABEL_29; + case (int)0x80004002: + v3 = "E_NOINTERFACE"; + goto LABEL_29; + case (int)0x80040110: + v3 = "DSERR_NOAGGREGATION"; + goto LABEL_29; + case (int)0x8007000E: + v3 = "DSERR_OUTOFMEMORY"; + goto LABEL_29; + case (int)0x80070057: + v3 = "DSERR_INVALIDPARAM"; + goto LABEL_29; + case (int)0x8878000A: + v3 = "DSERR_ALLOCATED"; + goto LABEL_29; + } + if ( error_code != 0x8878001E ) + { +LABEL_22: + strcpy(v4, "DSERR unknown 0x%x"); + sprintf(error_buf, v4, error_code); + return; + } + v3 = "DSERR_CONTROLUNAVAIL"; +LABEL_29: + strncpy(error_buf, v3, error_buf_len); +} + +//----- (0040193A) -------------------------------------------------------- +char *__cdecl GetLastErr() +{ + int v0; // eax + + v0 = GetLastError(); + return GetErr(v0); +} + +//----- (00401947) -------------------------------------------------------- +void TermMsg(char *format, ...) +{ + va_list arglist; // [esp+8h] [ebp+8h] + + va_start(arglist, format); + FreeDlg(); + if ( format ) + MsgBox(format, arglist); + init_cleanup(0); + exit(1); +} + +//----- (00401975) -------------------------------------------------------- +void __fastcall MsgBox(char *format, va_list va) +{ + char Text[256]; // [esp+0h] [ebp-100h] + + wvsprintfA(Text, format, va); + if ( ghMainWnd ) + SetWindowPos(ghMainWnd, (HWND)0xFFFFFFFE, 0, 0, 0, 0, 0x13u); + MessageBoxA(ghMainWnd, Text, "ERROR", 0x2010u); +} + +//----- (004019C7) -------------------------------------------------------- +void __cdecl FreeDlg() +{ + int v0; // eax + + if ( terminating && cleanup_thread_id != GetCurrentThreadId() ) + Sleep(20000u); + terminating = 1; + cleanup_thread_id = GetCurrentThreadId(); + dx_cleanup(); + if ( (unsigned char)gbMaxPlayers > 1u ) + { + _LOBYTE(v0) = SNetLeaveGame(3); + if ( v0 ) + Sleep(2000u); + } + SNetDestroy(); + ShowCursor(1); +} +// 4B7A34: using guessed type int terminating; +// 4B7A38: using guessed type int cleanup_thread_id; +// 679660: using guessed type char gbMaxPlayers; + +//----- (00401A30) -------------------------------------------------------- +void DrawDlg(char *format, ...) +{ + char text[256]; // [esp+0h] [ebp-100h] + va_list arglist; // [esp+10Ch] [ebp+Ch] + + va_start(arglist, format); + wvsprintfA(text, format, arglist); + SDrawMessageBox(text, "Diablo", 8240); +} + +//----- (00401A65) -------------------------------------------------------- +void __fastcall DDErrDlg(int error_code, int log_line_nr, char *log_file_path) +{ + int v3; // esi + char *v4; // eax + + v3 = log_line_nr; + if ( error_code ) + { + v4 = GetErr(error_code); + TermMsg("Direct draw error (%s:%d)\n%s", log_file_path, v3, v4); + } +} + +//----- (00401A88) -------------------------------------------------------- +void __fastcall DSErrDlg(int error_code, int log_line_nr, char *log_file_path) +{ + int v3; // esi + char *v4; // eax + + v3 = log_line_nr; + if ( error_code ) + { + v4 = GetErr(error_code); + TermMsg("Direct sound error (%s:%d)\n%s", log_file_path, v3, v4); + } +} + +//----- (00401AAB) -------------------------------------------------------- +void __fastcall CenterDlg(HWND hDlg) +{ + LONG v1; // esi + LONG v2; // edi + int v3; // ebx + char *v4; // eax + struct tagRECT Rect; // [esp+Ch] [ebp-1Ch] + int v6; // [esp+1Ch] [ebp-Ch] + HDC hdc; // [esp+20h] [ebp-8h] + HWND hWnd; // [esp+24h] [ebp-4h] + + hWnd = hDlg; + GetWindowRect(hDlg, &Rect); + v1 = Rect.right - Rect.left; + v2 = Rect.bottom - Rect.top; + hdc = GetDC(hWnd); + v6 = GetDeviceCaps(hdc, 8); + v3 = GetDeviceCaps(hdc, 10); + ReleaseDC(hWnd, hdc); + if ( !SetWindowPos(hWnd, 0, (v6 - v1) / 2, (v3 - v2) / 2, 0, 0, 5u) ) + { + v4 = GetLastErr(); + TermMsg("center_window: %s", v4); + } +} + +//----- (00401B3D) -------------------------------------------------------- +void __fastcall TermDlg(int template_id, int error_code, char *log_file_path, int log_line_nr) +{ + int v4; // ebx + int v5; // edi + char *v6; // esi + char *v7; // eax + char *v8; // eax + LPARAM dwInitParam[128]; // [esp+Ch] [ebp-200h] + + v4 = error_code; + v5 = template_id; + FreeDlg(); + v6 = log_file_path; + v7 = strrchr(log_file_path, 92); + if ( v7 ) + v6 = v7 + 1; + v8 = GetErr(v4); + wsprintfA((LPSTR)dwInitParam, "%s\nat: %s line %d", v8, v6, log_line_nr); + if ( DialogBoxParamA(hInstance, (LPCSTR)(unsigned short)v5, ghMainWnd, (DLGPROC)FuncDlg, (LPARAM)dwInitParam) == -1 ) + TermMsg("ErrDlg: %d", v5); + TermMsg(0); +} + +//----- (00401BCA) -------------------------------------------------------- +bool __stdcall FuncDlg(HWND hDlg, UINT uMsg, WPARAM wParam, char *text) +{ + if ( uMsg == 272 ) + { + TextDlg(hDlg, text); + } + else + { + if ( uMsg != 273 ) + return 0; + if ( (_WORD)wParam == 1 ) + { + EndDialog(hDlg, 1); + } + else if ( (_WORD)wParam == 2 ) + { + EndDialog(hDlg, 0); + } + } + return 1; +} + +//----- (00401C0F) -------------------------------------------------------- +void __fastcall TextDlg(HWND hDlg, char *text) +{ + char *v2; // esi + HWND v3; // edi + + v2 = text; + v3 = hDlg; + CenterDlg(hDlg); + if ( v2 ) + SetDlgItemTextA(v3, 1000, v2); +} + +//----- (00401C2E) -------------------------------------------------------- +void __fastcall ErrDlg(template_id template_id, int error_code, char *log_file_path, int log_line_nr) +{ + char *v4; // esi + int v5; // edi + unsigned short v6; // bx + char *v7; // eax + char *v8; // eax + LPARAM dwInitParam[128]; // [esp+Ch] [ebp-200h] + + v4 = log_file_path; + v5 = error_code; + v6 = template_id; + v7 = strrchr(log_file_path, 92); + if ( v7 ) + v4 = v7 + 1; + v8 = GetErr(v5); + wsprintfA((LPSTR)dwInitParam, "%s\nat: %s line %d", v8, v4, log_line_nr); + DialogBoxParamA(hInstance, (LPCSTR)v6, ghMainWnd, (DLGPROC)FuncDlg, (LPARAM)dwInitParam); +} + +//----- (00401C9C) -------------------------------------------------------- +void __fastcall FileErrDlg(char *error) +{ + char *v1; // esi + + v1 = error; + FreeDlg(); + if ( !v1 ) + v1 = &empty_string; + if ( DialogBoxParamA(hInstance, (LPCSTR)0x6A, ghMainWnd, (DLGPROC)FuncDlg, (LPARAM)v1) == -1 ) + TermMsg("FileErrDlg"); + TermMsg(0); +} + +//----- (00401CE1) -------------------------------------------------------- +void __fastcall DiskFreeDlg(char *error) +{ + char *v1; // esi + + v1 = error; + FreeDlg(); + if ( DialogBoxParamA(hInstance, (LPCSTR)0x6E, ghMainWnd, (DLGPROC)FuncDlg, (LPARAM)v1) == -1 ) + TermMsg("DiskFreeDlg"); + TermMsg(0); +} + +//----- (00401D1D) -------------------------------------------------------- +bool __cdecl InsertCDDlg() +{ + INT_PTR v0; // edi + + ShowCursor(1); + v0 = DialogBoxParamA(hInstance, (LPCSTR)0x70, ghMainWnd, (DLGPROC)FuncDlg, (LPARAM)&empty_string); + if ( v0 == -1 ) + TermMsg("InsertCDDlg"); + ShowCursor(0); + return v0 == 1; +} + +//----- (00401D68) -------------------------------------------------------- +void __fastcall DirErrDlg(char *error) +{ + char *v1; // esi + + v1 = error; + FreeDlg(); + if ( DialogBoxParamA(hInstance, (LPCSTR)0x72, ghMainWnd, (DLGPROC)FuncDlg, (LPARAM)v1) == -1 ) + TermMsg("DirErrorDlg"); + TermMsg(0); +} + +//----- (00401DA4) -------------------------------------------------------- +void __cdecl InitAutomapOnce() +{ + *(_DWORD *)&automapflag = 0; + AutoMapScale = 50; + CT_4B84B8 = 32; + CT_4B84BC = 16; + CT_4B84C0 = 8; + CT_4B84C4 = 4; + CT_4B84C8 = 2; +} +// 4B84B8: using guessed type int CT_4B84B8; +// 4B84BC: using guessed type int CT_4B84BC; +// 4B84C0: using guessed type int CT_4B84C0; +// 4B84C4: using guessed type int CT_4B84C4; +// 4B84C8: using guessed type int CT_4B84C8; + +//----- (00401DE8) -------------------------------------------------------- +void __cdecl InitAutomap() +{ + signed int v0; // edi + signed int v1; // ecx + int v2; // esi + char v3; // al + int v4; // esi + char v5; // al + char *v6; // ecx + unsigned char *v7; // eax + int v8; // ecx + unsigned char *v9; // edx + unsigned int i; // esi + unsigned char v11; // bl + _BYTE *v12; // edx + signed int v13; // ecx + _BYTE *v14; // eax + signed int v15; // edx + int size; // [esp+Ch] [ebp-4h] + + v0 = 50; + v1 = 0; + do + { + v2 = (v0 << 6) / 100; + v3 = 2 * (320 / v2); + v4 = 320 % v2; + v5 = v3 + 1; + AMbyte_4B7E4C[v1] = v5; + if ( v4 ) + AMbyte_4B7E4C[v1] = v5 + 1; + if ( v4 >= 32 * v0 / 100 ) + ++AMbyte_4B7E4C[v1]; + v0 += 5; + ++v1; + } + while ( v1 < 31 ); + memset(automaptype, 0, 0x400u); + switch ( leveltype ) + { + case DTYPE_CATHEDRAL: + v6 = "Levels\\L1Data\\L1.AMP"; + break; + case DTYPE_CATACOMBS: + v6 = "Levels\\L2Data\\L2.AMP"; + break; + case DTYPE_CAVES: + v6 = "Levels\\L3Data\\L3.AMP"; + break; + case DTYPE_HELL: + v6 = "Levels\\L4Data\\L4.AMP"; + break; + default: + return; + } + v7 = LoadFileInMem(v6, &size); + size = (unsigned int)size >> 1; + v9 = v7; + for ( i = 1; i <= size; ++i ) + { + v11 = *v9; + v12 = v9 + 1; + _LOWORD(v0) = v11; + _LOBYTE(v8) = *v12; + v9 = v12 + 1; + _LOWORD(v8) = (unsigned char)v8; + v8 = v0 + (v8 << 8); + automaptype[i] = v8; + } + mem_free_dbg(v7); + memset(automapview, 0, 0x640u); + v13 = 0; + do + { + v14 = (unsigned char *)dFlags + v13; + v15 = 112; + do + { + *v14 &= 0x7Fu; + v14 += 112; + --v15; + } + while ( v15 ); + ++v13; + } + while ( v13 < 112 ); +} +// 5BB1ED: using guessed type char leveltype; + +//----- (00401EF4) -------------------------------------------------------- +void __cdecl StartAutomap() +{ + AutoMapXOfs = 0; + AutoMapYOfs = 0; + *(_DWORD *)&automapflag = 1; +} +// 4B84B0: using guessed type int AutoMapXOfs; +// 4B84B4: using guessed type int AutoMapYOfs; + +//----- (00401F0D) -------------------------------------------------------- +void __cdecl AutomapUp() +{ + --AutoMapXOfs; + --AutoMapYOfs; +} +// 4B84B0: using guessed type int AutoMapXOfs; +// 4B84B4: using guessed type int AutoMapYOfs; + +//----- (00401F1A) -------------------------------------------------------- +void __cdecl AutomapDown() +{ + ++AutoMapXOfs; + ++AutoMapYOfs; +} +// 4B84B0: using guessed type int AutoMapXOfs; +// 4B84B4: using guessed type int AutoMapYOfs; + +//----- (00401F27) -------------------------------------------------------- +void __cdecl AutomapLeft() +{ + --AutoMapXOfs; + ++AutoMapYOfs; +} +// 4B84B0: using guessed type int AutoMapXOfs; +// 4B84B4: using guessed type int AutoMapYOfs; + +//----- (00401F34) -------------------------------------------------------- +void __cdecl AutomapRight() +{ + ++AutoMapXOfs; + --AutoMapYOfs; +} +// 4B84B0: using guessed type int AutoMapXOfs; +// 4B84B4: using guessed type int AutoMapYOfs; + +//----- (00401F41) -------------------------------------------------------- +void __cdecl AutomapZoomIn() +{ + if ( AutoMapScale < 200 ) + { + AutoMapScale += 5; + CT_4B84B8 = (AutoMapScale << 6) / 100; + CT_4B84BC = CT_4B84B8 >> 1; + CT_4B84C0 = CT_4B84B8 >> 2; + CT_4B84C4 = CT_4B84B8 >> 3; + CT_4B84C8 = CT_4B84B8 >> 4; + } +} +// 4B84B8: using guessed type int CT_4B84B8; +// 4B84BC: using guessed type int CT_4B84BC; +// 4B84C0: using guessed type int CT_4B84C0; +// 4B84C4: using guessed type int CT_4B84C4; +// 4B84C8: using guessed type int CT_4B84C8; + +//----- (00401F80) -------------------------------------------------------- +void __cdecl AutomapZoomOut() +{ + if ( AutoMapScale > 50 ) + { + AutoMapScale -= 5; + CT_4B84B8 = (AutoMapScale << 6) / 100; + CT_4B84BC = CT_4B84B8 >> 1; + CT_4B84C0 = CT_4B84B8 >> 2; + CT_4B84C4 = CT_4B84B8 >> 3; + CT_4B84C8 = CT_4B84B8 >> 4; + } +} +// 4B84B8: using guessed type int CT_4B84B8; +// 4B84BC: using guessed type int CT_4B84BC; +// 4B84C0: using guessed type int CT_4B84C0; +// 4B84C4: using guessed type int CT_4B84C4; +// 4B84C8: using guessed type int CT_4B84C8; + +//----- (00401FBD) -------------------------------------------------------- +void __cdecl DrawAutomap() +{ + int v0; // eax + int v1; // ecx + int v2; // edx + int v3; // edx + int v4; // ecx + int v5; // eax + int v6; // esi + int v7; // edx + int v8; // edx + int v9; // esi + int v10; // ebx + int v11; // edi + int v12; // esi + int v13; // edi + int v14; // esi + int v15; // ebp + short v16; // ax + int v17; // ebp + short v18; // ax + int v19; // [esp+0h] [ebp-18h] + int screen_x; // [esp+4h] [ebp-14h] + int screen_xa; // [esp+4h] [ebp-14h] + int v22; // [esp+8h] [ebp-10h] + int ty; // [esp+Ch] [ebp-Ch] + int tya; // [esp+Ch] [ebp-Ch] + int v25; // [esp+10h] [ebp-8h] + int screen_y; // [esp+14h] [ebp-4h] + + if ( leveltype ) + { + screen_buf_end = (int)gpBuffer->row[352].col_unused_1; + v0 = AutoMapXOfs; + v1 = (ViewX - 16) >> 1; + v2 = AutoMapXOfs + v1; + if ( AutoMapXOfs + v1 < 0 ) + { + do + { + ++v0; + ++v2; + } + while ( v2 < 0 ); + AutoMapXOfs = v0; + } + v3 = v0 + v1; + if ( v0 + v1 >= 40 ) + { + do + { + --v0; + --v3; + } + while ( v3 >= 40 ); + AutoMapXOfs = v0; + } + v4 = v0 + v1; + AMdword_4B7E40 = v4; + v5 = AutoMapYOfs; + v6 = (ViewY - 16) >> 1; + v7 = AutoMapYOfs + v6; + if ( AutoMapYOfs + v6 < 0 ) + { + do + { + ++v5; + ++v7; + } + while ( v7 < 0 ); + AutoMapYOfs = v5; + } + v8 = v5 + v6; + if ( v5 + v6 >= 40 ) + { + do + { + --v5; + --v8; + } + while ( v8 >= 40 ); + AutoMapYOfs = v5; + } + v9 = v5 + v6; + AMdword_4B7E44 = v9; + v10 = AMbyte_4B7E4C[(AutoMapScale - 50) / 5]; + if ( ScrollInfo._sxoff + ScrollInfo._syoff ) + ++v10; + v22 = v4 - v10; + v19 = v9 - 1; + if ( v10 & 1 ) + { + v11 = 384 - CT_4B84B8 * ((v10 - 1) >> 1); + v12 = 336 - CT_4B84BC * ((v10 + 1) >> 1); + } + else + { + v11 = CT_4B84BC - CT_4B84B8 * (v10 >> 1) + 384; + v12 = 336 - CT_4B84BC * (v10 >> 1) - CT_4B84C0; + } + if ( ViewX & 1 ) + { + v11 -= CT_4B84C0; + v12 -= CT_4B84C4; + } + if ( ViewY & 1 ) + { + v11 += CT_4B84C0; + v12 -= CT_4B84C4; + } + v13 = (AutoMapScale * ScrollInfo._sxoff / 100 >> 1) + v11; + v14 = (AutoMapScale * ScrollInfo._syoff / 100 >> 1) + v12; + if ( invflag || sbookflag ) + v13 -= 160; + if ( chrflag || questlog ) + v13 += 160; + if ( v10 + 1 >= 0 ) + { + v25 = v10 + 2; + do + { + v15 = 0; + screen_x = v13; + if ( v10 > 0 ) + { + ty = v19; + do + { + v16 = GetAutomapType(v22 + v15, ty, 1); + if ( v16 ) + DrawAutomapType(screen_x, v14, v16); + screen_x += CT_4B84B8; + ++v15; + --ty; + } + while ( v15 < v10 ); + } + ++v19; + screen_xa = 0; + v17 = v13 - CT_4B84BC; + screen_y = v14 + CT_4B84C0; + if ( v10 >= 0 ) + { + tya = v19; + do + { + v18 = GetAutomapType(v22 + screen_xa, tya, 1); + if ( v18 ) + DrawAutomapType(v17, screen_y, v18); + v17 += CT_4B84B8; + ++screen_xa; + --tya; + } + while ( screen_xa <= v10 ); + } + ++v22; + v14 += CT_4B84BC; + --v25; + } + while ( v25 ); + } + DrawAutomapPlr(); + DrawAutomapGame(); + } + else + { + DrawAutomapGame(); + } +} +// 4B7E40: using guessed type int AMdword_4B7E40; +// 4B7E44: using guessed type int AMdword_4B7E44; +// 4B84B0: using guessed type int AutoMapXOfs; +// 4B84B4: using guessed type int AutoMapYOfs; +// 4B84B8: using guessed type int CT_4B84B8; +// 4B84BC: using guessed type int CT_4B84BC; +// 4B84C0: using guessed type int CT_4B84C0; +// 4B84C4: using guessed type int CT_4B84C4; +// 4B8968: using guessed type int sbookflag; +// 5BB1ED: using guessed type char leveltype; +// 69BD04: using guessed type int questlog; +// 69CF0C: using guessed type int screen_buf_end; + +//----- (00402233) -------------------------------------------------------- +void __fastcall DrawAutomapType(int screen_x, int screen_y, short automap_type) +{ + char v3; // al + int v4; // ebx + int v5; // edi + int a3; // ST2C_4 + int a1; // ST28_4 + int a2; // ST24_4 + int v9; // edx + int v10; // ST28_4 + int v11; // ST2C_4 + int v12; // ST24_4 + int v13; // ST2C_4 + int v14; // ST28_4 + int v15; // ST24_4 + int v16; // ST28_4 + int v17; // ST24_4 + int v18; // ST2C_4 + int v19; // ST2C_4 + int v20; // ST28_4 + int v21; // ST24_4 + int v22; // ST28_4 + int v23; // ST2C_4 + int v24; // ST24_4 + int v25; // ST28_4 + int v26; // ST24_4 + int v27; // ST2C_4 + int v28; // [esp-Ch] [ebp-34h] + int v29; // [esp-8h] [ebp-30h] + signed int v30; // [esp+Ch] [ebp-1Ch] + signed int v31; // [esp+10h] [ebp-18h] + signed int v32; // [esp+14h] [ebp-14h] + char v33; // [esp+27h] [ebp-1h] + int automap_typea; // [esp+30h] [ebp+8h] + int automap_typeb; // [esp+30h] [ebp+8h] + int automap_typec; // [esp+30h] [ebp+8h] + int automap_typed; // [esp+30h] [ebp+8h] + int automap_typee; // [esp+30h] [ebp+8h] + int automap_typef; // [esp+30h] [ebp+8h] + int automap_typeg; // [esp+30h] [ebp+8h] + + v3 = automap_type; + v4 = screen_x; + v5 = screen_y; + v33 = _HIBYTE(automap_type); + if ( automap_type & 0x4000 ) + { + ENG_set_pixel(screen_x, screen_y, 200); + ENG_set_pixel(v4 - CT_4B84C4, v5 - CT_4B84C8, 200); + ENG_set_pixel(v4 - CT_4B84C4, CT_4B84C8 + v5, 200); + ENG_set_pixel(CT_4B84C4 + v4, v5 - CT_4B84C8, 200); + ENG_set_pixel(CT_4B84C4 + v4, CT_4B84C8 + v5, 200); + ENG_set_pixel(v4 - CT_4B84C0, v5, 200); + ENG_set_pixel(CT_4B84C0 + v4, v5, 200); + ENG_set_pixel(v4, v5 - CT_4B84C4, 200); + ENG_set_pixel(v4, CT_4B84C4 + v5, 200); + ENG_set_pixel(v4 + CT_4B84C4 - CT_4B84BC, CT_4B84C8 + v5, 200); + ENG_set_pixel(v4 + CT_4B84BC - CT_4B84C4, CT_4B84C8 + v5, 200); + ENG_set_pixel(v4 - CT_4B84C0, CT_4B84C4 + v5, 200); + ENG_set_pixel(CT_4B84C0 + v4, CT_4B84C4 + v5, 200); + ENG_set_pixel(v4 - CT_4B84C4, v5 + CT_4B84C0 - CT_4B84C8, 200); + ENG_set_pixel(CT_4B84C4 + v4, v5 + CT_4B84C0 - CT_4B84C8, 200); + ENG_set_pixel(v4, CT_4B84C0 + v5, 200); + v3 = automap_type; + } + if ( automap_type < 0 ) + { + engine_4170BD(v4 - CT_4B84C4, v5 - CT_4B84C4 - CT_4B84C8, v4 + CT_4B84C4 + CT_4B84C0, CT_4B84C8 + v5, 144); + engine_4170BD(v4 - CT_4B84C0, v5 - CT_4B84C4, CT_4B84C0 + v4, CT_4B84C4 + v5, 144); + engine_4170BD(v4 - CT_4B84C0 - CT_4B84C4, v5 - CT_4B84C8, CT_4B84C4 + v4, v5 + CT_4B84C4 + CT_4B84C8, 144); + engine_4170BD(v4 - CT_4B84BC, v5, v4, v5 + CT_4B84C0, 144); + v3 = automap_type; + } + v31 = 0; + v30 = 0; + v32 = 0; + switch ( v3 & 0xF ) + { + case 1: + a3 = v4 - CT_4B84C0 + CT_4B84BC; + a1 = v4 - CT_4B84C0; + a2 = v5 - CT_4B84C0; + automap_typea = v5 - CT_4B84C4; + engine_4170BD(v4, v5 - CT_4B84C0, v4 - CT_4B84C0, v5 - CT_4B84C4, 200); + engine_4170BD(v4, a2, a3, automap_typea, 200); + engine_4170BD(v4, v5, a1, automap_typea, 200); + v9 = v5; + v29 = automap_typea; + v28 = a3; + goto LABEL_36; + case 2: + case 5: + goto LABEL_8; + case 3: + case 6: + goto LABEL_17; + case 4: + v31 = 1; + goto LABEL_8; + case 7: + goto LABEL_25; + case 8: + v30 = 1; +LABEL_8: + if ( automap_type & 0x100 ) + { + v10 = v4 - CT_4B84BC; + v11 = v4 - CT_4B84C0; + v12 = v5 - CT_4B84C0; + automap_typeb = v5 - CT_4B84C4; + engine_4170BD(v4, v5 - CT_4B84C0, v4 - CT_4B84C4, v5 - CT_4B84C0 + CT_4B84C8, 200); + engine_4170BD(v10, v5, v10 + CT_4B84C4, v5 - CT_4B84C8, 200); + engine_4170BD(v11, v12, v10, automap_typeb, 144); + engine_4170BD(v11, v12, v4, automap_typeb, 144); + engine_4170BD(v11, v5, v10, automap_typeb, 144); + engine_4170BD(v11, v5, v4, automap_typeb, 144); + } + if ( v33 & 0x10 ) + { + engine_4170BD(v4 - CT_4B84C0, v5 - CT_4B84C4, v4 - CT_4B84BC, v5, 200); + v33 |= 4u; + } + if ( v33 & 4 ) + { + v13 = v4 - CT_4B84C0 + CT_4B84BC; + v14 = v4 - CT_4B84C0; + v15 = v5 - CT_4B84C0; + automap_typec = v5 - CT_4B84C4; + engine_4170BD(v4, v5 - CT_4B84C0, v4 - CT_4B84C0, v5 - CT_4B84C4, 200); + engine_4170BD(v4, v15, v13, automap_typec, 200); + engine_4170BD(v4, v5, v14, automap_typec, 200); + engine_4170BD(v4, v5, v13, automap_typec, 200); + } + if ( !(v33 & 0x15) ) + engine_4170BD(v4, v5 - CT_4B84C0, v4 - CT_4B84BC, v5, 200); + if ( v31 ) + goto LABEL_17; + goto LABEL_25; + case 9: + v32 = 1; +LABEL_17: + if ( v33 & 2 ) + { + v16 = CT_4B84C0 + v4; + v17 = v5 - CT_4B84C0; + v18 = v4 + CT_4B84BC; + automap_typed = v5 - CT_4B84C4; + engine_4170BD(v4, v5 - CT_4B84C0, v4 + CT_4B84C4, v5 - CT_4B84C0 + CT_4B84C8, 200); + engine_4170BD(v18, v5, v18 - CT_4B84C4, v5 - CT_4B84C8, 200); + engine_4170BD(v16, v17, v4, automap_typed, 144); + engine_4170BD(v16, v17, v18, automap_typed, 144); + engine_4170BD(v16, v5, v4, automap_typed, 144); + engine_4170BD(v16, v5, v18, automap_typed, 144); + } + if ( v33 & 0x20 ) + { + engine_4170BD(CT_4B84C0 + v4, v5 - CT_4B84C4, v4 + CT_4B84BC, v5, 200); + v33 |= 8u; + } + if ( v33 & 8 ) + { + v19 = v4 - CT_4B84C0 + CT_4B84BC; + v20 = v4 - CT_4B84C0; + v21 = v5 - CT_4B84C0; + automap_typee = v5 - CT_4B84C4; + engine_4170BD(v4, v5 - CT_4B84C0, v4 - CT_4B84C0, v5 - CT_4B84C4, 200); + engine_4170BD(v4, v21, v19, automap_typee, 200); + engine_4170BD(v4, v5, v20, automap_typee, 200); + engine_4170BD(v4, v5, v19, automap_typee, 200); + } + if ( !(v33 & 0x2A) ) + engine_4170BD(v4, v5 - CT_4B84C0, v4 + CT_4B84BC, v5, 200); +LABEL_25: + if ( v30 ) + goto LABEL_26; + goto LABEL_32; + case 0xA: + goto LABEL_26; + case 0xB: + goto LABEL_33; + case 0xC: + v32 = 1; +LABEL_26: + if ( v33 & 1 ) + { + v22 = v4 - CT_4B84BC; + v23 = v4 - CT_4B84C0; + v24 = CT_4B84C0 + v5; + automap_typef = CT_4B84C4 + v5; + engine_4170BD(v4, CT_4B84C0 + v5, v4 - CT_4B84C4, CT_4B84C0 + v5 - CT_4B84C8, 200); + engine_4170BD(v22, v5, v22 + CT_4B84C4, v5 + CT_4B84C8, 200); + engine_4170BD(v23, v24, v22, automap_typef, 144); + engine_4170BD(v23, v24, v4, automap_typef, 144); + engine_4170BD(v23, v5, v22, automap_typef, 144); + engine_4170BD(v23, v5, v4, automap_typef, 144); + } + else + { + engine_4170BD(v4, CT_4B84C0 + v5, v4 - CT_4B84BC, v5, 200); + } +LABEL_32: + if ( v32 ) + { +LABEL_33: + if ( v33 & 2 ) + { + v25 = CT_4B84C0 + v4; + v26 = CT_4B84C0 + v5; + v27 = v4 + CT_4B84BC; + automap_typeg = CT_4B84C4 + v5; + engine_4170BD(v4, CT_4B84C0 + v5, v4 + CT_4B84C4, CT_4B84C0 + v5 - CT_4B84C8, 200); + engine_4170BD(v27, v5, v27 - CT_4B84C4, v5 + CT_4B84C8, 200); + engine_4170BD(v25, v26, v4, automap_typeg, 144); + engine_4170BD(v25, v26, v27, automap_typeg, 144); + engine_4170BD(v25, v5, v4, automap_typeg, 144); + engine_4170BD(v25, v5, v27, automap_typeg, 144); + } + else + { + v29 = v5; + v28 = v4 + CT_4B84BC; + v9 = CT_4B84C0 + v5; +LABEL_36: + engine_4170BD(v4, v9, v28, v29, 200); + } + } + break; + default: + return; + } +} +// 4B84BC: using guessed type int CT_4B84BC; +// 4B84C0: using guessed type int CT_4B84C0; +// 4B84C4: using guessed type int CT_4B84C4; +// 4B84C8: using guessed type int CT_4B84C8; + +//----- (004029A8) -------------------------------------------------------- +void __cdecl DrawAutomapPlr() +{ + int v0; // ebx + int v1; // eax + int v2; // ecx + int v3; // esi + int v4; // edi + int v5; // edx + int v6; // ecx + int v7; // eax + int v8; // ecx + int v9; // [esp-Ch] [ebp-20h] + int v10; // [esp-8h] [ebp-1Ch] + int v11; // [esp+Ch] [ebp-8h] + int v12; // [esp+10h] [ebp-4h] + + v0 = myplr; + if ( plr[myplr]._pmode == PM_WALK3 ) + { + v1 = plr[v0]._px; + v2 = plr[v0]._py; + if ( plr[v0]._pdir == 2 ) + ++v1; + else + ++v2; + } + else + { + v1 = plr[v0].WorldX; + v2 = plr[v0].WorldY; + } + v11 = v1 - 2 * AutoMapXOfs - ViewX; + v12 = v2 - 2 * AutoMapYOfs - ViewY; + v3 = (AutoMapScale * ScrollInfo._sxoff / 100 >> 1) + + (AutoMapScale * plr[v0]._pxoff / 100 >> 1) + + CT_4B84C0 * (v11 - v12) + + 384; + if ( invflag || sbookflag ) + v3 = (AutoMapScale * ScrollInfo._sxoff / 100 >> 1) + + (AutoMapScale * plr[v0]._pxoff / 100 >> 1) + + CT_4B84C0 * (v11 - v12) + + 224; + if ( chrflag || questlog ) + v3 += 160; + v4 = CT_4B84C4 * (v12 + v11) + + (AutoMapScale * ScrollInfo._syoff / 100 >> 1) + + (AutoMapScale * plr[v0]._pyoff / 100 >> 1) + + 336 + - CT_4B84C4; + switch ( plr[v0]._pdir ) + { + case DIR_S: + engine_4170BD(v3, v4, v3, v4 + CT_4B84C0, 153); + engine_4170BD(v3, CT_4B84C0 + v4, v3 + CT_4B84C8, v4 + CT_4B84C4, 153); + v10 = v4 + CT_4B84C4; + v9 = v3 - CT_4B84C8; + v5 = CT_4B84C0 + v4; + goto LABEL_19; + case DIR_SW: + engine_4170BD( + v3, + CT_4B84C4 * (v12 + v11) + + (AutoMapScale * ScrollInfo._syoff / 100 >> 1) + + (AutoMapScale * plr[v0]._pyoff / 100 >> 1) + + 336 + - CT_4B84C4, + v3 - CT_4B84C0, + CT_4B84C4 * (v12 + v11) + + (AutoMapScale * ScrollInfo._syoff / 100 >> 1) + + (AutoMapScale * plr[v0]._pyoff / 100 >> 1) + + 336, + 153); + engine_4170BD(v3 - CT_4B84C0, CT_4B84C4 + v4, v3 - CT_4B84C8 - CT_4B84C4, v4, 153); + v7 = CT_4B84C4; + v8 = v3; + v5 = CT_4B84C4 + v4; + v10 = CT_4B84C4 + v4; + goto LABEL_23; + case DIR_W: + engine_4170BD(v3, v4, v3 - CT_4B84C0, v4, 153); + engine_4170BD(v3 - CT_4B84C0, v4, v3 - CT_4B84C4, v4 - CT_4B84C8, 153); + v5 = v4; + v10 = v4 + CT_4B84C8; + v9 = v3 - CT_4B84C4; + goto LABEL_24; + case DIR_NW: + engine_4170BD(v3, v4, v3 - CT_4B84C0, v4 - CT_4B84C4, 153); + engine_4170BD(v3 - CT_4B84C0, v4 - CT_4B84C4, v3 - CT_4B84C4, v4 - CT_4B84C4, 153); + v7 = CT_4B84C4; + v8 = v3 - CT_4B84C8; + v10 = v4; + v5 = v4 - CT_4B84C4; +LABEL_23: + v9 = v8 - v7; +LABEL_24: + v6 = v3 - CT_4B84C0; + goto LABEL_25; + case DIR_N: + engine_4170BD(v3, v4, v3, v4 - CT_4B84C0, 153); + engine_4170BD(v3, v4 - CT_4B84C0, v3 - CT_4B84C8, v4 - CT_4B84C4, 153); + v10 = v4 - CT_4B84C4; + v5 = v4 - CT_4B84C0; + v9 = v3 + CT_4B84C8; +LABEL_19: + v6 = v3; + goto LABEL_25; + case DIR_NE: + engine_4170BD(v3, v4, v3 + CT_4B84C0, v4 - CT_4B84C4, 153); + engine_4170BD(CT_4B84C0 + v3, v4 - CT_4B84C4, v3 + CT_4B84C4, v4 - CT_4B84C4, 153); + v10 = v4; + v9 = v3 + CT_4B84C4 + CT_4B84C8; + v5 = v4 - CT_4B84C4; + goto LABEL_17; + case DIR_E: + engine_4170BD(v3, v4, v3 + CT_4B84C0, v4, 153); + engine_4170BD(CT_4B84C0 + v3, v4, v3 + CT_4B84C4, v4 - CT_4B84C8, 153); + engine_4170BD(CT_4B84C0 + v3, v4, v3 + CT_4B84C4, v4 + CT_4B84C8, 153); + break; + case DIR_SE: + engine_4170BD( + v3, + CT_4B84C4 * (v12 + v11) + + (AutoMapScale * ScrollInfo._syoff / 100 >> 1) + + (AutoMapScale * plr[v0]._pyoff / 100 >> 1) + + 336 + - CT_4B84C4, + v3 + CT_4B84C0, + CT_4B84C4 * (v12 + v11) + + (AutoMapScale * ScrollInfo._syoff / 100 >> 1) + + (AutoMapScale * plr[v0]._pyoff / 100 >> 1) + + 336, + 153); + engine_4170BD(CT_4B84C0 + v3, CT_4B84C4 + v4, v3 + CT_4B84C4 + CT_4B84C8, v4, 153); + v5 = CT_4B84C4 + v4; + v10 = CT_4B84C4 + v4; + v9 = v3 + CT_4B84C4; +LABEL_17: + v6 = CT_4B84C0 + v3; +LABEL_25: + engine_4170BD(v6, v5, v9, v10, 153); + break; + default: + return; + } +} +// 4B84B0: using guessed type int AutoMapXOfs; +// 4B84B4: using guessed type int AutoMapYOfs; +// 4B84C0: using guessed type int CT_4B84C0; +// 4B84C4: using guessed type int CT_4B84C4; +// 4B84C8: using guessed type int CT_4B84C8; +// 4B8968: using guessed type int sbookflag; +// 69BD04: using guessed type int questlog; + +//----- (00402D83) -------------------------------------------------------- +short __fastcall GetAutomapType(int tx, int ty, bool view) +{ + int v3; // edi + int v4; // esi + int v6; // eax + short v7; // bp + + v3 = ty; + v4 = tx; + if ( view ) + { + if ( tx == -1 && ty >= 0 && ty < 40 && automapview[0][ty] ) + { + tx = 0; + return ~GetAutomapType(tx, ty, 0) & 0x4000; + } + if ( ty == -1 ) + { + if ( tx < 0 ) + return 0; + if ( tx < 40 && automapview[tx][0] ) + { + ty = 0; + return ~GetAutomapType(tx, ty, 0) & 0x4000; + } + } + } + if ( tx < 0 ) + return 0; + if ( tx >= 40 ) + return 0; + if ( ty < 0 ) + return 0; + if ( ty >= 40 ) + return 0; + v6 = ty + 40 * tx; + if ( !automapview[0][v6] && view ) + return 0; + v7 = automaptype[(unsigned char)dungeon[0][v6]]; + if ( v7 == 7 && ((unsigned short)GetAutomapType(tx - 1, ty, 0) >> 8) & 8 ) + { + if ( ((unsigned short)GetAutomapType(v4, v3 - 1, 0) >> 8) & 4 ) + v7 = 1; + } + return v7; +} + +//----- (00402E4A) -------------------------------------------------------- +void __cdecl DrawAutomapGame() +{ + int v0; // esi + char *v1; // eax + char *v2; // eax + char v3[256]; // [esp+4h] [ebp-100h] + + v0 = 20; + if ( (unsigned char)gbMaxPlayers > 1u ) + { + v1 = strcpy(v3, "game: "); + strcat(v1, szPlayerName); + PrintGameStr(8, 20, v3, 3); + v0 = 35; + if ( szPlayerDescript[0] ) + { + v2 = strcpy(v3, "password: "); + strcat(v2, szPlayerDescript); + PrintGameStr(8, 35, v3, 3); + v0 = 50; + } + } + if ( setlevel ) + { + PrintGameStr(8, v0, quest_level_names[(unsigned char)setlvlnum], 3); + } + else if ( currlevel ) + { + sprintf(v3, "Level: %i", currlevel); + PrintGameStr(8, v0, v3, 3); + } +} +// 5CCB10: using guessed type char setlvlnum; +// 5CF31D: using guessed type char setlevel; +// 679660: using guessed type char gbMaxPlayers; + +//----- (00402F27) -------------------------------------------------------- +void __fastcall SetAutomapView(int x, int y) +{ + signed int v2; // esi + signed int v3; // edi + int v4; // ebx + short v5; // ax + short v6; // cx + int v7; // eax + int v8; // eax + int v9; // eax + int v10; // eax + short v11; // ax + int v12; // edi + + v2 = (x - 16) >> 1; + v3 = (y - 16) >> 1; + if ( v2 < 0 || v2 >= 40 || v3 < 0 || v3 >= 40 ) + return; + v4 = v3 + 40 * v2; + automapview[0][v4] = 1; + v5 = GetAutomapType((x - 16) >> 1, (y - 16) >> 1, 0); + v6 = v5 & 0x4000; + v7 = (v5 & 0xF) - 2; + if ( !v7 ) + { + if ( v6 ) + { +LABEL_19: + if ( GetAutomapType(v2, v3 + 1, 0) == 16391 ) + automapview[0][v4 + 1] = 1; + return; + } + goto LABEL_35; + } + v8 = v7 - 1; + if ( !v8 ) + { + if ( v6 ) + { + v11 = GetAutomapType(v2 + 1, v3, 0); +LABEL_32: + if ( v11 == 16391 ) + automapview[1][v4] = 1; + return; + } +LABEL_14: + if ( GetAutomapType(v2, v3 - 1, 0) & 0x4000 ) + AMbyte_4B7E4C[v4 + 31] = 1; + return; + } + v9 = v8 - 1; + if ( v9 ) + { + v10 = v9 - 1; + if ( v10 ) + { + if ( v10 != 1 ) + return; + if ( v6 ) + { + if ( GetAutomapType(v2 - 1, v3, 0) & 0x4000 ) + *((_BYTE *)&AMdword_4B7E44 + v4) = 1; +LABEL_13: + v11 = GetAutomapType(v2 + 1, v3, 0); + goto LABEL_32; + } + goto LABEL_14; + } + if ( v6 ) + { + if ( GetAutomapType(v2, v3 - 1, 0) & 0x4000 ) + AMbyte_4B7E4C[v4 + 31] = 1; + goto LABEL_19; + } +LABEL_35: + if ( GetAutomapType(v2 - 1, v3, 0) & 0x4000 ) + *((_BYTE *)&AMdword_4B7E44 + v4) = 1; + return; + } + if ( v6 ) + { + if ( GetAutomapType(v2, v3 + 1, 0) == 16391 ) + automapview[0][v4 + 1] = 1; + goto LABEL_13; + } + if ( GetAutomapType(v2 - 1, v3, 0) & 0x4000 ) + *((_BYTE *)&AMdword_4B7E44 + v4) = 1; + v12 = v3 - 1; + if ( GetAutomapType(v2, v12, 0) & 0x4000 ) + AMbyte_4B7E4C[v4 + 31] = 1; + if ( GetAutomapType(v2 - 1, v12, 0) & 0x4000 ) + *((_BYTE *)&AMdword_4B7E40 + v4 + 3) = 1; +} +// 4B7E40: using guessed type int AMdword_4B7E40; +// 4B7E44: using guessed type int AMdword_4B7E44; + +//----- (004030DD) -------------------------------------------------------- +void __cdecl AutomapZoomReset() +{ + AutoMapXOfs = 0; + AutoMapYOfs = 0; + CT_4B84B8 = (AutoMapScale << 6) / 100; + CT_4B84BC = CT_4B84B8 >> 1; + CT_4B84C0 = CT_4B84B8 >> 2; + CT_4B84C4 = CT_4B84B8 >> 3; + CT_4B84C8 = CT_4B84B8 >> 4; +} +// 4B84B0: using guessed type int AutoMapXOfs; +// 4B84B4: using guessed type int AutoMapYOfs; +// 4B84B8: using guessed type int CT_4B84B8; +// 4B84BC: using guessed type int CT_4B84BC; +// 4B84C0: using guessed type int CT_4B84C0; +// 4B84C4: using guessed type int CT_4B84C4; +// 4B84C8: using guessed type int CT_4B84C8; + +//----- (0040311B) -------------------------------------------------------- +void __cdecl CaptureScreen() +{ + int v0; // ebx + int v1; // edi + int v2; // esi + int v3; // eax + int v4; // edi + int v5; // eax + int v6; // eax + PALETTEENTRY palette; // [esp+0h] [ebp-508h] + char FileName[260]; // [esp+400h] [ebp-108h] + HANDLE hObject; // [esp+504h] [ebp-4h] + + hObject = CaptureFile(FileName); + if ( hObject != (HANDLE)-1 ) + { + DrawAndBlit(); + IDirectDrawPalette_GetEntries( + (IDirectDrawPalette *)lpDDPRed, + 0, + 0, + 256, + &palette); + CaptureRedPal(&palette); + dx_lock_mutex(); + _LOBYTE(v3) = CaptureHdr(hObject, 640, 480); + v4 = v3; + if ( v3 ) + { + _LOBYTE(v5) = CapturePix(hObject, 640, 480, 768, gpBuffer->row[0].pixels); + v4 = v5; + if ( v5 ) + { + _LOBYTE(v6) = CapturePal(hObject, &palette); + v4 = v6; + } + } + dx_unlock_mutex(); + CloseHandle(hObject); + if ( !v4 ) + DeleteFileA(FileName); + Sleep(0x12Cu); + IDirectDrawPalette_SetEntries((IDirectDrawPalette *)lpDDPRed, 0, 0, 0, &palette); + } +} +// 40311B: could not find valid save-restore pair for ebx +// 40311B: could not find valid save-restore pair for edi +// 40311B: could not find valid save-restore pair for esi + +//----- (00403204) -------------------------------------------------------- +bool __fastcall CaptureHdr(HANDLE hFile, short width, int height) +{ + short v3; // si + HANDLE v4; // ebx + char Buffer[128]; // [esp+Ch] [ebp-84h] + DWORD NumberOfBytesWritten; // [esp+8Ch] [ebp-4h] + + v3 = width; + v4 = hFile; + memset(Buffer, 0, 0x80u); + *(_WORD *)&Buffer[8] = v3 - 1; + *(_WORD *)&Buffer[14] = height; + Buffer[0] = 10; + Buffer[1] = 5; + Buffer[2] = 1; + Buffer[3] = 8; + *(_WORD *)&Buffer[10] = height - 1; + *(_WORD *)&Buffer[12] = v3; + Buffer[65] = 1; + *(_WORD *)&Buffer[66] = v3; + return WriteFile(v4, Buffer, 0x80u, &NumberOfBytesWritten, 0) && NumberOfBytesWritten == 128; +} + +//----- (00403294) -------------------------------------------------------- +bool __fastcall CapturePal(HANDLE hFile, PALETTEENTRY *palette) +{ + BYTE *v2; // eax + char *v3; // esi + signed int v4; // edx + char Buffer[772]; // [esp+8h] [ebp-308h] + DWORD NumberOfBytesWritten; // [esp+30Ch] [ebp-4h] + + v2 = &palette->peBlue; + Buffer[0] = 12; + v3 = &Buffer[2]; + v4 = 256; + do + { + *(v3 - 1) = *(v2 - 2); + *v3 = *(v2 - 1); + v3[1] = *v2; + v2 += 4; + v3 += 3; + --v4; + } + while ( v4 ); + return WriteFile(hFile, Buffer, 0x301u, &NumberOfBytesWritten, 0) && NumberOfBytesWritten == 769; +} + +//----- (004032FD) -------------------------------------------------------- +bool __fastcall CapturePix(HANDLE hFile, short width, short height, short stride, char *pixels) +{ + int v5; // esi + void *v6; // edi + char *v7; // eax + int v8; // ebx + DWORD NumberOfBytesWritten; // [esp+Ch] [ebp-8h] + HANDLE hFilea; // [esp+10h] [ebp-4h] + + v5 = (unsigned short)width; + hFilea = hFile; + v6 = DiabloAllocPtr(2 * (unsigned short)width); + do + { + if ( !height ) + { + mem_free_dbg(v6); + return 1; + } + *(_DWORD *)&height = height + 0xFFFF; + v7 = CaptureEnc(pixels, v6, v5); + pixels += (unsigned short)stride; + v8 = v7 - v6; + } + while ( WriteFile(hFilea, v6, v7 - v6, &NumberOfBytesWritten, 0) && NumberOfBytesWritten == v8 ); + return 0; +} + +//----- (0040336A) -------------------------------------------------------- +char *__fastcall CaptureEnc(char *src, void *dst, int width) +{ + int v3; // esi + unsigned char v4; // bl + signed int v5; // eax + + v3 = width; + do + { + v4 = *src++; + v5 = 1; + --v3; + if ( v4 == *src ) + { + do + { + if ( v5 >= 63 ) + break; + if ( !v3 ) + break; + ++v5; + --v3; + ++src; + } + while ( v4 == *src ); + if ( v5 > 1 ) + goto LABEL_13; + } + if ( v4 > 0xBFu ) + { +LABEL_13: + *(_BYTE *)dst = v5 | 0xC0; + dst = (char *)dst + 1; + } + *(_BYTE *)dst = v4; + dst = (char *)dst + 1; + } + while ( v3 ); + return (char *)dst; +} + +//----- (004033A8) -------------------------------------------------------- +HANDLE __fastcall CaptureFile(char *dst_path) +{ + char *v1; // edi + __int32 v2; // esi + int v3; // eax + int v5; // [esp-4h] [ebp-18Ch] + struct _finddata_t v6; // [esp+Ch] [ebp-17Ch] + char v7[100]; // [esp+124h] [ebp-64h] + + v1 = dst_path; + memset(v7, 0, 0x64u); + v2 = _findfirst("screen??.PCX", &v6); + if ( v2 != -1 ) + { + do + { + if ( isdigit(v6.name[6]) ) + { + if ( isdigit(v6.name[7]) ) + v7[10 * v6.name[6] - 528 + v6.name[7]] = 1; + } + } + while ( !_findnext(v2, &v6) ); + } + v3 = 0; + while ( v7[v3] ) + { + if ( ++v3 >= 100 ) + return (HANDLE)-1; + } + v5 = v3; + sprintf(v1, "screen%02d.PCX", v3); + return CreateFileA(v1, 0x40000000u, 0, 0, 2u, 0x80u, 0); +} +// 4033A8: using guessed type char var_64[100]; + +//----- (00403470) -------------------------------------------------------- +void __fastcall CaptureRedPal(PALETTEENTRY *palette_orig) +{ + signed int v1; // esi + int v2; // eax + char v3; // bl + char v4[1024]; // [esp+Ch] [ebp-400h] + + v1 = 0; + do + { + v2 = 4 * v1++; + v4[v2 + 1] = 0; + v4[v2 + 2] = 0; + v3 = v4[(char *)palette_orig - v4 + v2]; + v4[v2 + 3] = 0; + v4[v2] = v3; + } + while ( v1 < 256 ); + IDirectDrawPalette_SetEntries((IDirectDrawPalette *)lpDDPRed, 0, 0, 256, (LPPALETTEENTRY)v4); +} + +//----- (004034D9) -------------------------------------------------------- +int __fastcall codec_decode(void *src_dst, int size, char *password) +{ + unsigned int v3; // ebx + char *v4; // esi + int v5; // ebx + signed int v7; // ecx + int v8; // esi + char v9[128]; // [esp+8h] [ebp-98h] + char dst[20]; // [esp+88h] [ebp-18h] + int v11; // [esp+9Ch] [ebp-4h] + char *passworda; // [esp+A8h] [ebp+8h] + + v3 = size; + v4 = (char *)src_dst; + codec_init_key(0, password); + if ( v3 <= 8 ) + return 0; + v5 = v3 - 8; + v11 = v5; + if ( v5 & 0x3F ) + return 0; + passworda = (char *)v5; + if ( v5 ) + { + do + { + memcpy(v9, v4, 0x40u); + sha1_final(0, (char (*)[20])dst); + v7 = 0; + do + { + v9[v7] ^= dst[v7 % 20]; + ++v7; + } + while ( v7 < 64 ); + sha1(0, v9, 0); + memset(dst, 0, 0x14u); + memcpy(v4, v9, 0x40u); + v4 += 64; + passworda -= 64; + } + while ( passworda ); + v5 = v11; + } + memset(v9, 0, 0x80u); + if ( !v4[4] ) + { + sha1_final(0, (char (*)[20])dst); + if ( *(_DWORD *)v4 == *(_DWORD *)dst ) + { + v8 = v5 + (unsigned char)v4[5] - 64; + goto LABEL_14; + } + memset(dst, 0, 0x14u); + } + v8 = 0; +LABEL_14: + sha1_reset(); + return v8; +} +// 4034D9: using guessed type char var_98[128]; + +//----- (004035DB) -------------------------------------------------------- +void __fastcall codec_init_key(int unused, char *password) +{ + char *v2; // edi + char *v3; // esi + int v4; // eax + signed int v5; // ecx + char v6; // dl + unsigned int v7; // ecx + signed int v8; // esi + char v9[72]; // [esp+Ch] [ebp-E0h] + char data[64]; // [esp+54h] [ebp-98h] + char v11[64]; // [esp+94h] [ebp-58h] + char dst[20]; // [esp+D4h] [ebp-18h] + int v13; // [esp+E8h] [ebp-4h] + + v2 = password; + srand(0x7058u); + v3 = v9; + v13 = 136; + do + { + *v3++ = rand(); + --v13; + } + while ( v13 ); + v4 = 0; + v5 = 0; + do + { + if ( !v2[v4] ) + v4 = 0; + v6 = v2[v4++]; + v11[v5++] = v6; + } + while ( v5 < 64 ); + sha1_init(0); + sha1(0, v11, (char (*)[20])dst); + sha1_reset(); + v7 = 0; + do + { + v9[v7] ^= dst[(signed int)v7 % 20]; + ++v7; + } + while ( v7 < 0x88 ); + memset(v11, 0, 0x40u); + memset(dst, 0, 0x14u); + v8 = 0; + do + { + sha1_init(v8); + sha1(v8++, data, 0); + } + while ( v8 < 3 ); + memset(v9, 0, 0x88u); +} +// 4035DB: using guessed type char var_E0[72]; +// 4035DB: using guessed type char var_58[64]; +// 4035DB: using guessed type char dst[20]; + +//----- (004036AC) -------------------------------------------------------- +int __fastcall codec_get_encoded_len(int n) +{ + if ( n & 0x3F ) + n += 64 - (n & 0x3F); + return n + 8; +} + +//----- (004036BE) -------------------------------------------------------- +void __fastcall codec_encode(void *src_dst, int size, int size_64, char *password) +{ + char *v4; // esi + char v5; // bl + size_t v6; // edi + signed int v7; // ecx + int v8; // eax + char v9[128]; // [esp+8h] [ebp-ACh] + char v10[20]; // [esp+88h] [ebp-2Ch] + char dst[20]; // [esp+9Ch] [ebp-18h] + size_t v12; // [esp+B0h] [ebp-4h] + + v4 = (char *)src_dst; + v12 = size; + if ( size_64 != codec_get_encoded_len(size) ) + TermMsg("Invalid encode parameters"); + codec_init_key(1, password); + v5 = 0; + if ( v12 ) + { + do + { + v6 = v12; + if ( v12 >= 0x40 ) + v6 = 64; + memcpy(v9, v4, v6); + if ( v6 < 0x40 ) + memset(&v9[v6], 0, 64 - v6); + sha1_final(0, (char (*)[20])dst); + sha1(0, v9, 0); + v7 = 0; + do + { + v9[v7] ^= dst[v7 % 20]; + ++v7; + } + while ( v7 < 64 ); + memset(dst, 0, 0x14u); + memcpy(v4, v9, 0x40u); + v4 += 16; + v12 -= v6; + } + while ( v12 ); + v5 = v6; + } + memset(v9, 0, 0x80u); + sha1_final(0, (char (*)[20])v10); + v8 = *(_DWORD *)v10; + *((_BYTE *)v4 + 4) = 0; + *((_WORD *)v4 + 3) = 0; + *v4 = v8; + *((_BYTE *)v4 + 5) = v5; + sha1_reset(); +} +// 4036BE: using guessed type char var_AC[128]; +// 4036BE: using guessed type char dst[20]; + +//----- (004037D4) -------------------------------------------------------- +void __fastcall DrawSpellCel(int xp, int yp, char *Trans, int nCel, int w) +{ +/* char *v5; // ebx + char *v6; // esi + char *v7; // edi + int v9; // edx + unsigned int v10; // eax + unsigned int v11; // ecx + char v14; // cf + unsigned int v15; // ecx + int v18; // [esp+Ch] [ebp-Ch] + + v5 = &Trans[4 * nCel]; + v6 = &Trans[*(_DWORD *)v5]; + v7 = (char *)gpBuffer + screen_y_times_768[yp] + xp; + v18 = (int)&v6[*((_DWORD *)v5 + 1) - *(_DWORD *)v5]; + _EBX = byte_4B8B88; + do + { + v9 = w; + do + { + while ( 1 ) + { + v10 = (unsigned char)*v6++; + if ( (v10 & 0x80u) == 0 ) + break; + _LOBYTE(v10) = -(char)v10; + v7 += v10; + v9 -= v10; + if ( !v9 ) + goto LABEL_12; + } + v9 -= v10; + v11 = v10 >> 1; + if ( v10 & 1 ) + { + _AL = *v6++; + __asm { xlat } + *v7++ = _AL; + if ( !v11 ) + continue; + } + v14 = v11 & 1; + v15 = v11 >> 1; + if ( !v14 ) + goto LABEL_15; + _AX = *(_WORD *)v6; + v6 += 2; + __asm { xlat } + _AX = __ROR2__(_AX, 8); + __asm { xlat } + *(_WORD *)v7 = __ROR2__(_AX, 8); + v7 += 2; + if ( v15 ) + { +LABEL_15: + do + { + _EAX = *(_DWORD *)v6; + v6 += 4; + __asm { xlat } + _EAX = __ROR4__(_EAX, 8); + __asm { xlat } + _EAX = __ROR4__(_EAX, 8); + __asm { xlat } + _EAX = __ROR4__(_EAX, 8); + __asm { xlat } + *(_DWORD *)v7 = __ROR4__(_EAX, 8); + v7 += 4; + --v15; + } + while ( v15 ); + } + } + while ( v9 ); +LABEL_12: + v7 = &v7[-w - 768]; + } + while ( v6 != (char *)v18 ); +*/ +} + +//----- (0040387E) -------------------------------------------------------- +void __fastcall SetSpellTrans(char t) +{ + signed int v1; // eax + signed int v2; // eax + signed int v3; // eax + char *v4; // ecx + signed int v5; // eax + char *v6; // ecx + signed int v7; // eax + char *v8; // ecx + signed int v9; // eax + char *v10; // ecx + + if ( !t ) + { + v1 = 0; + do + { + byte_4B8B88[v1] = v1; + ++v1; + } + while ( v1 < 128 ); + } + v2 = 128; + do + { + byte_4B8B88[v2] = v2; + ++v2; + } + while ( v2 < 256 ); + byte_4B8B88[255] = 0; + switch ( t ) + { + case 1: + byte_4B8B88[144] = -79; + byte_4B8B88[145] = -77; + byte_4B8B88[146] = -75; + v9 = 176; + do + { + v10 = &byte_4B8B88[v9 + 32]; + byte_4B8B88[v9 - 16] = v9; + *(v10 - 16) = v9; + *v10 = v9++; + } + while ( v9 < 192 ); + break; + case 2: + byte_4B8B88[144] = -95; + byte_4B8B88[145] = -93; + byte_4B8B88[146] = -91; + v7 = 160; + do + { + v8 = &byte_4B8B88[v7 + 48]; + *(v8 - 16) = v7; + *v8 = v7++; + } + while ( v7 < 176 ); + break; + case 3: + byte_4B8B88[144] = -47; + byte_4B8B88[145] = -45; + byte_4B8B88[146] = -43; + v5 = 208; + do + { + v6 = &byte_4B8B88[v5 - 16]; + *(v6 - 32) = v5; + *v6 = v5++; + } + while ( v5 < 224 ); + break; + case 4: + byte_4B8B88[144] = -15; + byte_4B8B88[145] = -13; + byte_4B8B88[146] = -11; + v3 = 240; + do + { + v4 = &byte_4B8B88[v3 - 48]; + *(v4 - 32) = v3; + *v4 = v3; + v4[16] = v3++; + } + while ( v3 < 255 ); + byte_4B8B88[175] = 0; + byte_4B8B88[207] = 0; + byte_4B8B88[223] = 0; + break; + } +} + +//----- (004039C7) -------------------------------------------------------- +void __cdecl DrawSpell() +{ + int v0; // ebp + char v1; // cl + char v2; // bl + int v3; // edi + int v4; // esi + int v5; // eax + char v6; // [esp+Fh] [ebp-5h] + + v0 = myplr; + v1 = plr[myplr]._pRSpell; + v2 = plr[myplr]._pRSplType; + v3 = v1; + v6 = plr[myplr]._pRSpell; + v4 = plr[myplr]._pISplLvlAdd + plr[myplr]._pSplLvl[v1]; + if ( v2 == 1 && v1 != -1 ) + { + _LOBYTE(v5) = CheckSpell(myplr, v1, 1, 1); + if ( !v5 ) + v2 = 4; + v0 = myplr; + if ( v4 <= 0 ) + v2 = 4; + } + if ( !currlevel && v2 != 4 && !*(_DWORD *)&spelldata[v3].sTownSpell ) + v2 = 4; + if ( plr[v0]._pRSpell < 0 ) + v2 = 4; + SetSpellTrans(v2); + if ( v6 == -1 ) + DrawSpellCel(629, 631, (char *)pSpellCels, 27, 56); + else + DrawSpellCel(629, 631, (char *)pSpellCels, (char)SpellITbl[v3], 56); +} + +//----- (00403A8E) -------------------------------------------------------- +void __cdecl DrawSpellList() +{ + int v0; // esi + signed int v1; // edi + int v2; // ecx + int v3; // eax + signed int v4; // ebp + int v5; // eax + int v6; // esi + int v7; // eax + bool v8; // sf + int v9; // esi + int v10; // eax + int v11; // ebp + int v12; // edx + int *v13; // ecx + int *v14; // eax + signed int v15; // edx + signed int v16; // edi + int v17; // [esp+Ch] [ebp-34h] + __int32 xp; // [esp+10h] [ebp-30h] + __int32 yp; // [esp+14h] [ebp-2Ch] + unsigned char *v20; // [esp+18h] [ebp-28h] + __int32 nCel; // [esp+1Ch] [ebp-24h] + int v22; // [esp+20h] [ebp-20h] + __int32 v23; // [esp+24h] [ebp-1Ch] + signed int v24; // [esp+28h] [ebp-18h] + unsigned __int64 v25; // [esp+2Ch] [ebp-14h] + signed __int64 v26; // [esp+34h] [ebp-Ch] + + pSpell = -1; + infostr[0] = 0; + v17 = 636; + xp = 495; + ClearPanel(); + v0 = myplr; + v1 = 0; + v24 = 0; + do + { + switch ( v1 ) + { + case RSPLTYPE_SKILL: + SetSpellTrans(0); + yp = 46; + v2 = plr[v0]._pAblSpells[0]; + v3 = plr[v0]._pAblSpells[1]; + goto LABEL_10; + case RSPLTYPE_SPELL: + yp = 47; + v2 = plr[v0]._pMemSpells[0]; + v3 = plr[v0]._pMemSpells[1]; + goto LABEL_10; + case RSPLTYPE_SCROLL: + SetSpellTrans(2); + yp = 44; + v2 = plr[v0]._pScrlSpells[0]; + v3 = plr[v0]._pScrlSpells[1]; + goto LABEL_10; + case RSPLTYPE_CHARGES: + SetSpellTrans(3); + yp = 45; + v2 = plr[v0]._pISpells[0]; + v3 = plr[v0]._pISpells[1]; +LABEL_10: + v25 = __PAIR__(v3, v2); + break; + } + v20 = &spelldata[1].sTownSpell; + v4 = 1; + v26 = 1i64; + v23 = 1; + v22 = xp - 216; + do + { + if ( !(v25 & v26) ) + goto LABEL_68; + if ( v1 == RSPLTYPE_SPELL ) + { + v5 = v0; + v6 = plr[v0]._pSplLvl[v4]; + v7 = plr[v5]._pISplLvlAdd; + v8 = v7 + v6 < 0; + v9 = v7 + v6; + nCel = v9; + if ( v8 ) + { + nCel = 0; + v9 = 0; + } + SetSpellTrans(v9 <= 0 ? 4 : 1); + } + else + { + v9 = nCel; + } + if ( !currlevel && !*(_DWORD *)v20 ) + SetSpellTrans(4); + DrawSpellCel(v17, xp, (char *)pSpellCels, (char)SpellITbl[v4], 56); + if ( MouseX >= v17 - 64 && MouseX < v17 - 64 + 56 && MouseY >= v22 && MouseY < v22 + 56 ) + { + pSpell = v4; + pSplType = v1; + DrawSpellCel(v17, xp, (char *)pSpellCels, yp, 56); + if ( v1 ) + { + switch ( v1 ) + { + case RSPLTYPE_SPELL: + sprintf(infostr, "%s Spell", spelldata[pSpell].sNameText); + if ( pSpell == 31 ) + { + sprintf(tempstr, "Damages undead only"); + AddPanelString(tempstr, 1); + } + if ( v9 ) + sprintf(tempstr, "Spell Level %i", v9); + else + sprintf(tempstr, "Spell Level 0 - Unusable"); +LABEL_32: + AddPanelString(tempstr, 1); + break; + case RSPLTYPE_SCROLL: + sprintf(infostr, "Scroll of %s", spelldata[pSpell].sNameText); + v10 = myplr; + v11 = 0; + v12 = plr[myplr]._pNumInv; + if ( v12 > 0 ) + { + v13 = &plr[v10].InvList[0]._iMiscId; + do + { + if ( *(v13 - 53) != -1 + && (*v13 == IMISC_SCROLL || *v13 == IMISC_SCROLLT) + && v13[1] == pSpell ) + { + ++v11; + } + v13 += 92; + --v12; + } + while ( v12 ); + } + v14 = &plr[v10].SpdList[0]._iMiscId; + v15 = 8; + do + { + if ( *(v14 - 53) != -1 + && (*v14 == IMISC_SCROLL || *v14 == IMISC_SCROLLT) + && v14[1] == pSpell ) + { + ++v11; + } + v14 += 92; + --v15; + } + while ( v15 ); + if ( v11 == 1 ) + strcpy(tempstr, "1 Scroll"); + else + sprintf(tempstr, "%i Scrolls", v11); + AddPanelString(tempstr, 1); + v4 = v23; + break; + case RSPLTYPE_CHARGES: + sprintf(infostr, "Staff of %s", spelldata[pSpell].sNameText); + if ( plr[myplr].InvBody[4]._iCharges == 1 ) + strcpy(tempstr, "1 Charge"); + else + sprintf(tempstr, "%i Charges", plr[myplr].InvBody[4]._iCharges); + goto LABEL_32; + } + } + else + { + sprintf(infostr, "%s Skill", spelldata[pSpell].sSkillText); + } + v0 = myplr; + v16 = 0; + do + { + if ( plr[0]._pSplHotKey[v16 + 5430 * v0] == pSpell && plr[v0]._pSplTHotKey[v16] == pSplType ) + { + DrawSpellCel(v17, xp, (char *)pSpellCels, v16 + 48, 56); + sprintf(tempstr, "Spell Hot Key #F%i", v16 + 5); + AddPanelString(tempstr, 1); + v0 = myplr; + } + ++v16; + } + while ( v16 < 4 ); + v1 = v24; + goto LABEL_66; + } + v0 = myplr; +LABEL_66: + v17 -= 56; + if ( v17 == 20 ) + { + xp -= 56; + v22 -= 56; + v17 = 636; + } +LABEL_68: + v20 += 56; + ++v4; + v26 *= 2i64; + v23 = v4; + } + while ( (signed int)v20 < (signed int)"Heal Other" ); + if ( v25 && v17 != 636 ) + v17 -= 56; + if ( v17 == 20 ) + { + xp -= 56; + v17 = 636; + } + v24 = ++v1; + } + while ( v1 < 4 ); +} +// 4B8834: using guessed type int pSpell; +// 4B8954: using guessed type int pSplType; + +//----- (00403F69) -------------------------------------------------------- +void __cdecl SetSpell() +{ + int v0; // eax + + spselflag = 0; + if ( pSpell != -1 ) + { + ClearPanel(); + v0 = myplr; + force_redraw = 255; + plr[v0]._pRSpell = pSpell; + _LOBYTE(plr[v0]._pRSplType) = pSplType; + } +} +// 4B8834: using guessed type int pSpell; +// 4B8954: using guessed type int pSplType; +// 4B8C98: using guessed type int spselflag; +// 52571C: using guessed type int force_redraw; + +//----- (00403FAC) -------------------------------------------------------- +void __fastcall SetSpeedSpell(int slot) +{ + int v1; // esi + int v2; // eax + signed int v3; // ebp + int v4; // edx + int v5; // ebx + int *v6; // edi + + v1 = pSpell; + if ( pSpell != -1 ) + { + v2 = myplr; + v3 = 0; + v4 = myplr; + v5 = pSplType; + v6 = plr[myplr]._pSplHotKey; + do + { + if ( *v6 == v1 && plr[v4]._pSplTHotKey[v3] == v5 ) + *v6 = -1; + ++v3; + ++v6; + } + while ( v3 < 4 ); + plr[0]._pSplHotKey[slot + 5430 * v2] = v1; + plr[v4]._pSplTHotKey[slot] = v5; + } +} +// 4B8834: using guessed type int pSpell; +// 4B8954: using guessed type int pSplType; + +//----- (00404017) -------------------------------------------------------- +void __fastcall ToggleSpell(int slot) +{ + int v1; // eax + int v2; // edx + int v3; // esi + char *v4; // eax + int v5; // eax + int v6; // eax + int v7; // eax + int v8; // ebx + int v9; // edi + int v10; // [esp+4h] [ebp-Ch] + char *v11; // [esp+8h] [ebp-8h] + int v12; // [esp+Ch] [ebp-4h] + + v1 = slot + 5430 * myplr; + v2 = plr[0]._pSplHotKey[v1]; + v12 = plr[0]._pSplHotKey[v1]; + if ( v2 != -1 ) + { + v3 = myplr; + v4 = &plr[myplr]._pSplTHotKey[slot]; + v11 = v4; + v5 = *v4; + if ( v5 ) + { + v6 = v5 - 1; + if ( v6 ) + { + v7 = v6 - 1; + if ( v7 ) + { + if ( v7 == 1 ) + { + v8 = plr[v3]._pISpells[0]; + v9 = plr[v3]._pISpells[1]; + } + else + { + v9 = (int)v11; + v8 = v10; + } + } + else + { + v8 = plr[v3]._pScrlSpells[0]; + v9 = plr[v3]._pScrlSpells[1]; + } + } + else + { + v8 = plr[v3]._pMemSpells[0]; + v9 = plr[v3]._pMemSpells[1]; + } + } + else + { + v8 = plr[v3]._pAblSpells[0]; + v9 = plr[v3]._pAblSpells[1]; + } + if ( v9 & ((unsigned __int64)(1i64 << ((unsigned char)v2 - 1)) >> 32) | v8 & (unsigned int)(1i64 << ((unsigned char)v2 - 1)) ) + { + force_redraw = 255; + plr[v3]._pRSpell = v12; + _LOBYTE(plr[v3]._pRSplType) = *v11; + } + } +} +// 52571C: using guessed type int force_redraw; + +//----- (004040DA) -------------------------------------------------------- +int __fastcall CPrintString(int No, char *pszStr, int Just) +{ + _DWORD *v3; // ebx + char *v4; // esi + char *v5; // edi + int v6; // ebx + signed int v7; // edx + int result; // eax + unsigned int v9; // ecx + char v10; // cf + unsigned int v11; // ecx + signed int v12; // edx + int v13; // ecx + signed int v14; // edx + int v15; // ecx + signed int v16; // edx + int v17; // ecx + + v3 = (unsigned int *)pPanelText + 4 * (_DWORD)pszStr; + v4 = (char *)pPanelText + *v3; + v5 = (char *)gpBuffer + No; + v6 = (int)&v4[v3[1] - *v3]; + if ( (_BYTE)Just ) + { + if ( (unsigned char)Just == 1 ) + { + do + { + v12 = 13; + do + { + while ( 1 ) + { + result = (unsigned char)*v4++; + if ( (result & 0x80u) == 0 ) + break; + _LOBYTE(result) = -(char)result; + v5 += result; + v12 -= result; + if ( !v12 ) + goto LABEL_28; + } + v12 -= result; + v13 = result; + do + { + _LOBYTE(result) = *v4++; + if ( (unsigned char)result > 0xFDu ) + { + _LOBYTE(result) = -65; + } + else if ( (unsigned char)result >= 0xF0u ) + { + _LOBYTE(result) = result - 62; + } + *v5++ = result; + --v13; + } + while ( v13 ); + } + while ( v12 ); +LABEL_28: + v5 -= 781; + } + while ( (char *)v6 != v4 ); + } + else if ( (unsigned char)Just == 2 ) + { + do + { + v14 = 13; + do + { + while ( 1 ) + { + result = (unsigned char)*v4++; + if ( (result & 0x80u) == 0 ) + break; + _LOBYTE(result) = -(char)result; + v5 += result; + v14 -= result; + if ( !v14 ) + goto LABEL_39; + } + v14 -= result; + v15 = result; + do + { + _LOBYTE(result) = *v4++; + if ( (unsigned char)result >= 0xF0u ) + _LOBYTE(result) = result - 16; + *v5++ = result; + --v15; + } + while ( v15 ); + } + while ( v14 ); +LABEL_39: + v5 -= 781; + } + while ( (char *)v6 != v4 ); + } + else + { + do + { + v16 = 13; + do + { + while ( 1 ) + { + result = (unsigned char)*v4++; + if ( (result & 0x80u) == 0 ) + break; + _LOBYTE(result) = -(char)result; + v5 += result; + v16 -= result; + if ( !v16 ) + goto LABEL_52; + } + v16 -= result; + v17 = result; + do + { + _LOBYTE(result) = *v4++; + if ( (unsigned char)result >= 0xF0u ) + { + if ( (unsigned char)result >= 0xFEu ) + _LOBYTE(result) = -49; + else + _LOBYTE(result) = result - 46; + } + *v5++ = result; + --v17; + } + while ( v17 ); + } + while ( v16 ); +LABEL_52: + v5 -= 781; + } + while ( (char *)v6 != v4 ); + } + } + else + { + do + { + v7 = 13; + do + { + while ( 1 ) + { + result = (unsigned char)*v4++; + if ( (result & 0x80u) == 0 ) + break; + _LOBYTE(result) = -(char)result; + v5 += result; + v7 -= result; + if ( !v7 ) + goto LABEL_15; + } + v7 -= result; + v9 = (unsigned int)result >> 1; + if ( result & 1 ) + { + *v5++ = *v4++; + if ( !v9 ) + continue; + } + v10 = v9 & 1; + v11 = (unsigned int)result >> 2; + if ( v10 ) + { + *(_WORD *)v5 = *(_WORD *)v4; + v4 += 2; + v5 += 2; + if ( !v11 ) + continue; + } + qmemcpy(v5, v4, 4 * v11); + v4 += 4 * v11; + v5 += 4 * v11; + } + while ( v7 ); +LABEL_15: + v5 -= 781; + } + while ( (char *)v6 != v4 ); + } + return result; +} + +//----- (00404218) -------------------------------------------------------- +void __fastcall AddPanelString(char *str, int just) +{ + int v2; // esi + int v3; // eax + bool v4; // sf + unsigned char v5; // of + + v2 = just; + strcpy(&panelstr[64 * pnumlines], str); + v3 = pnumlines; + v5 = __OFSUB__(pnumlines, 4); + v4 = pnumlines - 4 < 0; + pstrjust[pnumlines] = v2; + if ( v4 ^ v5 ) + pnumlines = v3 + 1; +} + +//----- (0040424A) -------------------------------------------------------- +void __cdecl ClearPanel() +{ + pnumlines = 0; + pinfoflag = 0; +} +// 4B8824: using guessed type int pinfoflag; + +//----- (00404259) -------------------------------------------------------- +void __fastcall DrawPanelBox(int x, int y, unsigned short a3, unsigned short a4, int sx, int sy) +{ + _WORD *v6; // esi + char *v7; // edi + int v8; // edx + unsigned int v9; // ecx + char v10; // cf + unsigned int v11; // ecx + + v6 = (unsigned short *)pBtmBuff + 640 * y + x; + v7 = &gpBuffer->row_unused_1[sy].col_unused_1[sx]; + v8 = a4; + do + { + v9 = (unsigned int)a3 >> 1; + if ( !(a3 & 1) || (*v7 = *(_BYTE *)v6, v6 = (_WORD *)((char *)v6 + 1), ++v7, v9) ) + { + v10 = v9 & 1; + v11 = (unsigned int)a3 >> 2; + if ( !v10 || (*(_WORD *)v7 = *v6, ++v6, v7 += 2, v11) ) + { + qmemcpy(v7, v6, 4 * v11); + v6 += 2 * v11; + v7 += 4 * v11; + } + } + v6 = (_WORD *)((char *)v6 - a3 + 640); + v7 = &v7[-a3 + 768]; + --v8; + } + while ( v8 ); +} + +//----- (004042CA) -------------------------------------------------------- +void __fastcall SetFlaskHeight(char *buf, int min, int max, int c, int r) +{ + char *v5; // esi + char *v6; // edi + int v7; // edx + + v5 = &buf[88 * min]; + v6 = &gpBuffer->row_unused_1[r].col_unused_1[c]; + v7 = max - min; + do + { + qmemcpy(v6, v5, 0x58u); + v5 += 88; + v6 += 768; + --v7; + } + while ( v7 ); +} + +//----- (0040431B) -------------------------------------------------------- +void __fastcall DrawFlask(void *a1, int a2, int a3, void *a4, int a5, int a6) +{ + char *v6; // esi + _BYTE *v7; // edi + int v8; // edx + signed int v9; // ecx + char v10; // al + int v11; // [esp+Ch] [ebp-4h] + + v11 = a2; + v6 = (char *)a1 + a3; + v7 = (unsigned char *)a4 + a5; + v8 = a6; + do + { + v9 = 59; + do + { + v10 = *v6++; + if ( v10 ) + *v7 = v10; + ++v7; + --v9; + } + while ( v9 ); + v6 = &v6[v11 - 59]; + v7 += 709; + --v8; + } + while ( v8 ); +} + +//----- (0040435B) -------------------------------------------------------- +void __cdecl DrawLifeFlask() +{ + signed __int64 v0; // rax + signed int v1; // esi + int v2; // esi + + v0 = (signed __int64)((double)plr[myplr]._pHitPoints / (double)plr[myplr]._pMaxHP * 80.0); + plr[myplr]._pHPPer = v0; + if ( (signed int)v0 > 80 ) + LODWORD(v0) = 80; + v1 = 80 - v0; + if ( 80 - (signed int)v0 > 11 ) + v1 = 11; + v2 = v1 + 2; + DrawFlask(pLifeBuff, 88, 277, gpBuffer, 383405, v2); + if ( v2 != 13 ) + DrawFlask(pBtmBuff, 640, 640 * v2 + 2029, gpBuffer, 768 * v2 + 383405, 13 - v2); +} + +//----- (004043F4) -------------------------------------------------------- +void __cdecl UpdateLifeFlask() +{ + signed __int64 v0; // rax + signed int v1; // edi + + v0 = (signed __int64)((double)plr[myplr]._pHitPoints / (double)plr[myplr]._pMaxHP * 80.0); + v1 = v0; + plr[myplr]._pHPPer = v0; + if ( (signed int)v0 > 69 ) + { + v1 = 69; +LABEL_8: + DrawPanelBox(96, 85 - v1, 0x58u, v1, 160, 581 - v1); + return; + } + if ( (signed int)v0 < 0 ) + v1 = 0; + if ( v1 != 69 ) + SetFlaskHeight((char *)pLifeBuff, 16, 85 - v1, 160, 512); + if ( v1 ) + goto LABEL_8; +} + +//----- (00404475) -------------------------------------------------------- +void __cdecl DrawManaFlask() +{ + int v0; // eax + int v1; // esi + int v2; // esi + + v0 = plr[myplr]._pManaPer; + if ( v0 > 80 ) + v0 = 80; + v1 = 80 - v0; + if ( 80 - v0 > 11 ) + v1 = 11; + v2 = v1 + 2; + DrawFlask(pManaBuff, 88, 277, gpBuffer, 383771, v2); + if ( v2 != 13 ) + DrawFlask(pBtmBuff, 640, 640 * v2 + 2395, gpBuffer, 768 * v2 + 383771, 13 - v2); +} + +//----- (004044F6) -------------------------------------------------------- +void __cdecl control_update_life_mana() +{ + int v0; // esi + signed __int64 v1; // rax + int v2; // [esp+4h] [ebp-8h] + int v3; // [esp+8h] [ebp-4h] + + v0 = myplr; + v3 = plr[myplr]._pMaxMana; + v2 = plr[myplr]._pMana; + if ( plr[myplr]._pMaxMana < 0 ) + v3 = 0; + if ( plr[myplr]._pMana < 0 ) + v2 = 0; + if ( v3 ) + v1 = (signed __int64)((double)v2 / (double)v3 * 80.0); + else + LODWORD(v1) = 0; + plr[v0]._pManaPer = v1; + plr[v0]._pHPPer = (signed __int64)((double)plr[v0]._pHitPoints / (double)plr[v0]._pMaxHP * 80.0); +} + +//----- (0040456A) -------------------------------------------------------- +void __cdecl UpdateManaFlask() +{ + signed int v0; // edi + int v1; // [esp+8h] [ebp-8h] + int v2; // [esp+Ch] [ebp-4h] + + v2 = plr[myplr]._pMaxMana; + v1 = plr[myplr]._pMana; + if ( plr[myplr]._pMaxMana < 0 ) + v2 = 0; + if ( plr[myplr]._pMana < 0 ) + v1 = 0; + if ( v2 ) + v0 = (signed __int64)((double)v1 / (double)v2 * 80.0); + else + v0 = 0; + plr[myplr]._pManaPer = v0; + if ( v0 > 69 ) + v0 = 69; + if ( v0 != 69 ) + SetFlaskHeight((char *)pManaBuff, 16, 85 - v0, 528, 512); + if ( v0 ) + DrawPanelBox(464, 85 - v0, 0x58u, v0, 528, 581 - v0); + DrawSpell(); +} + +//----- (00404616) -------------------------------------------------------- +void __cdecl InitControlPan() +{ + size_t v0; // esi + void *v1; // ecx + void *v2; // ecx + void *v3; // ecx + char v4; // al + unsigned char *v5; // eax + + v0 = 0x16800; + if ( gbMaxPlayers != 1 ) + v0 = 0x2D000; + pBtmBuff = DiabloAllocPtr(v0); + memset(pBtmBuff, 0, v0); + pManaBuff = DiabloAllocPtr(0x1E40); + memset(pManaBuff, 0, 0x1E40u); + pLifeBuff = DiabloAllocPtr(0x1E40); + memset(pLifeBuff, 0, 0x1E40u); + pPanelText = LoadFileInMem("CtrlPan\\SmalText.CEL", 0); + pChrPanel = LoadFileInMem("Data\\Char.CEL", 0); + pSpellCels = LoadFileInMem("CtrlPan\\SpelIcon.CEL", 0); + SetSpellTrans(0); + pStatusPanel = LoadFileInMem("CtrlPan\\Panel8.CEL", 0); + Cel_into_rect_of_buf((char *)pBtmBuff, 0, 143, 640, (char *)pStatusPanel, 1, 640); + v1 = pStatusPanel; + pStatusPanel = 0; + mem_free_dbg(v1); + pStatusPanel = LoadFileInMem("CtrlPan\\P8Bulbs.CEL", 0); + Cel_into_rect_of_buf((char *)pLifeBuff, 0, 87, 88, (char *)pStatusPanel, 1, 88); + Cel_into_rect_of_buf((char *)pManaBuff, 0, 87, 88, (char *)pStatusPanel, 2, 88); + v2 = pStatusPanel; + pStatusPanel = 0; + mem_free_dbg(v2); + talkflag = 0; + if ( gbMaxPlayers != 1 ) + { + pTalkPanel = LoadFileInMem("CtrlPan\\TalkPanl.CEL", 0); + Cel_into_rect_of_buf((char *)pBtmBuff, 0, 287, 640, (char *)pTalkPanel, 1, 640); + v3 = pTalkPanel; + pTalkPanel = 0; + mem_free_dbg(v3); + pMultiBtns = LoadFileInMem("CtrlPan\\P8But2.CEL", 0); + pTalkBtns = LoadFileInMem("CtrlPan\\TalkButt.CEL", 0); + sgbPlrTalkTbl = 0; + *(_DWORD *)&tempstr[256] = 0x1010101; + talkbtndown[0] = 0; + talkbtndown[1] = 0; + sgszTalkMsg[0] = 0; + talkbtndown[2] = 0; + } + panelflag = 0; + lvlbtndown = 0; + pPanelButtons = LoadFileInMem("CtrlPan\\Panel8bu.CEL", 0); + memset(panbtn, 0, sizeof(panbtn)); + panbtndown = 0; + numpanbtns = 2 * (gbMaxPlayers != 1) + 6; + pChrButtons = LoadFileInMem("Data\\CharBut.CEL", 0); + chrbtn[0] = 0; + chrbtn[1] = 0; + chrbtn[2] = 0; + chrbtnactive = 0; + chrbtn[3] = 0; + pDurIcons = LoadFileInMem("Items\\DurIcons.CEL", 0); + strcpy(infostr, &empty_string); + ClearPanel(); + drawhpflag = 1; + drawmanaflag = 1; + chrflag = 0; + spselflag = 0; + pSpellBkCel = LoadFileInMem("Data\\SpellBk.CEL", 0); + pSBkBtnCel = LoadFileInMem("Data\\SpellBkB.CEL", 0); + pSBkIconCels = LoadFileInMem("Data\\SpellI2.CEL", 0); + sbooktab = 0; + sbookflag = 0; + v4 = plr[myplr]._pClass; + if ( v4 ) + { + if ( v4 == UI_ROGUE ) + { + SpellPages[0][0] = SPL_DISARM; + } + else if ( v4 == UI_SORCERER ) + { + SpellPages[0][0] = SPL_RECHARGE; + } + } + else + { + SpellPages[0][0] = SPL_REPAIR; + } + pQLogCel = LoadFileInMem("Data\\Quest.CEL", 0); + v5 = LoadFileInMem("CtrlPan\\Golddrop.cel", 0); + frame_4B8800 = 1; + dropGoldFlag = 0; + dropGoldValue = 0; + initialDropGoldValue = 0; + initialDropGoldIndex = 0; + pGBoxBuff = v5; +} +// 4B84DC: using guessed type int dropGoldFlag; +// 4B851C: using guessed type int lvlbtndown; +// 4B87A8: using guessed type int chrbtnactive; +// 4B8840: using guessed type int sgbPlrTalkTbl; +// 4B8950: using guessed type int sbooktab; +// 4B8960: using guessed type int talkflag; +// 4B8968: using guessed type int sbookflag; +// 4B8A7C: using guessed type int numpanbtns; +// 4B8B84: using guessed type int panelflag; +// 4B8C90: using guessed type int panbtndown; +// 4B8C98: using guessed type int spselflag; +// 679660: using guessed type char gbMaxPlayers; + +//----- (00404934) -------------------------------------------------------- +void __cdecl ClearCtrlPan() +{ + DrawPanelBox(0, sgbPlrTalkTbl + 16, 0x280u, 0x80u, 64, 512); + DrawInfoBox(); +} +// 4B8840: using guessed type int sgbPlrTalkTbl; + +//----- (00404959) -------------------------------------------------------- +void __cdecl DrawCtrlPan() +{ + signed int v0; // edi + int *v1; // esi + int v2; // ecx + int v3; // eax + + v0 = 0; + v1 = (int *)PanBtnPos; + do + { + v2 = *v1; + if ( panbtn[v0] ) + Cel_decode(v2 + 64, v1[1] + 178, pPanelButtons, v0 + 1, 71); + else + DrawPanelBox(v2, v1[1] - 336, 0x47u, 0x14u, v2 + 64, v1[1] + 160); + ++v0; + v1 += 5; + } + while ( v0 < 6 ); + if ( numpanbtns == 8 ) + { + Cel_decode(151, 634, pMultiBtns, panbtn[6] + 1, 33); + if ( FriendlyMode ) + v3 = panbtn[7] + 3; + else + v3 = panbtn[7] + 5; + Cel_decode(591, 634, pMultiBtns, v3, 33); + } +} +// 484368: using guessed type int FriendlyMode; +// 4B8A7C: using guessed type int numpanbtns; + +//----- (00404A0A) -------------------------------------------------------- +void __cdecl DoSpeedBook() +{ + int v0; // eax + signed int v1; // ebx + bool v2; // zf + unsigned __int64 v3; // rdi + unsigned int v4; // ecx + unsigned int v5; // [esp+4h] [ebp-20h] + unsigned int v6; // [esp+8h] [ebp-1Ch] + unsigned int v7; // [esp+8h] [ebp-1Ch] + int X; // [esp+Ch] [ebp-18h] + int Y; // [esp+10h] [ebp-14h] + signed int v10; // [esp+14h] [ebp-10h] + int v11; // [esp+18h] [ebp-Ch] + signed int v12; // [esp+1Ch] [ebp-8h] + signed int v13; // [esp+20h] [ebp-4h] + + v0 = myplr; + v13 = 636; + v1 = 1; + v2 = plr[myplr]._pRSpell == -1; + spselflag = 1; + v12 = 495; + X = 600; + Y = 307; + if ( !v2 ) + { + v11 = 0; + v3 = __PAIR__(v5, v6); + while ( 1 ) + { + if ( v11 ) + { + switch ( v11 ) + { + case RSPLTYPE_SPELL: + HIDWORD(v3) = plr[v0]._pMemSpells[0]; + LODWORD(v3) = plr[v0]._pMemSpells[1]; + break; + case RSPLTYPE_SCROLL: + HIDWORD(v3) = plr[v0]._pScrlSpells[0]; + LODWORD(v3) = plr[v0]._pScrlSpells[1]; + break; + case RSPLTYPE_CHARGES: + HIDWORD(v3) = plr[v0]._pISpells[0]; + LODWORD(v3) = plr[v0]._pISpells[1]; + break; + } + } + else + { + HIDWORD(v3) = plr[v0]._pAblSpells[0]; + LODWORD(v3) = plr[v0]._pAblSpells[1]; + } + v7 = 0; + v10 = 1; + do + { + if ( (unsigned int)v3 & v7 | HIDWORD(v3) & v1 ) + { + if ( v10 == plr[v0]._pRSpell && v11 == SLOBYTE(plr[v0]._pRSplType) ) + { + X = v13 - 36; + Y = v12 - 188; + } + v13 -= 56; + if ( v13 == 20 ) + { + v12 -= 56; + v13 = 636; + } + } + v4 = __PAIR__(v7, v1) >> 31; + v1 *= 2; + ++v10; + v7 = v4; + } + while ( v10 < 37 ); + if ( v3 && v13 != 636 ) + v13 -= 56; + if ( v13 == 20 ) + { + v12 -= 56; + v13 = 636; + } + if ( ++v11 >= 4 ) + break; + v1 = 1; + } + } + SetCursorPos(X, Y); +} +// 4B8C98: using guessed type int spselflag; + +//----- (00404B52) -------------------------------------------------------- +void __cdecl DoPanBtn() +{ + int v0; // edx + int v1; // ebx + int v2; // edi + int v3; // esi + int (*v4)[5]; // eax + int v5; // ecx + + v0 = MouseX; + v1 = MouseY; + v2 = numpanbtns; + v3 = 0; + if ( numpanbtns > 0 ) + { + v4 = PanBtnPos; + do + { + if ( v0 >= (*v4)[0] && v0 <= (*v4)[0] + (*v4)[2] ) + { + v5 = (*v4)[1]; + if ( v1 >= v5 && v1 <= v5 + (*v4)[3] ) + { + panbtn[v3] = 1; + drawbtnflag = 1; + panbtndown = 1; + } + } + ++v3; + ++v4; + } + while ( v3 < v2 ); + } + if ( !spselflag && v0 >= 565 && v0 < 621 && v1 >= 416 && v1 < 472 ) + { + DoSpeedBook(); + gamemenu_off(); + } +} +// 4B8A7C: using guessed type int numpanbtns; +// 4B8C90: using guessed type int panbtndown; +// 4B8C98: using guessed type int spselflag; + +//----- (00404BEB) -------------------------------------------------------- +void __fastcall control_set_button_down(int btn_id) +{ + panbtn[btn_id] = 1; + drawbtnflag = 1; + panbtndown = 1; +} +// 4B8C90: using guessed type int panbtndown; + +//----- (00404C00) -------------------------------------------------------- +void __cdecl control_check_btn_press() +{ + int v0; // edx + int v1; // esi + + v0 = MouseX; + v1 = MouseY; + if ( MouseX >= PanBtnPos[3][0] + && MouseX <= PanBtnPos[3][0] + PanBtnPos[3][2] + && MouseY >= PanBtnPos[3][1] + && MouseY <= PanBtnPos[3][1] + PanBtnPos[3][3] ) + { + control_set_button_down(3); + } + if ( v0 >= PanBtnPos[6][0] + && v0 <= PanBtnPos[6][0] + PanBtnPos[6][2] + && v1 >= PanBtnPos[6][1] + && v1 <= PanBtnPos[6][1] + PanBtnPos[6][3] ) + { + control_set_button_down(6); + } +} + +//----- (00404C74) -------------------------------------------------------- +void __cdecl DoAutoMap() +{ + if ( currlevel || gbMaxPlayers != 1 ) + { + if ( *(_DWORD *)&automapflag ) + *(_DWORD *)&automapflag = 0; + else + StartAutomap(); + } + else + { + InitDiabloMsg(1); + } +} +// 679660: using guessed type char gbMaxPlayers; + +//----- (00404CA0) -------------------------------------------------------- +void __cdecl CheckPanelInfo() +{ + int v0; // edi + int v1; // eax + int v2; // ecx + int v3; // ecx + int v4; // edi + int v5; // eax + int *v6; // edx + int v7; // ebx + int v8; // ebx + int *v9; // eax + signed int v10; // edx + int v11; // ecx + int v12; // [esp+10h] [ebp-4h] + + v0 = 0; + panelflag = 0; + ClearPanel(); + if ( numpanbtns > 0 ) + { + do + { + v1 = v0; + v2 = PanBtnPos[v0][0]; + if ( MouseX >= v2 && MouseX <= v2 + PanBtnPos[v1][2] ) + { + v3 = PanBtnPos[v1][1]; + if ( MouseY >= v3 && MouseY <= v3 + PanBtnPos[v1][3] ) + { + if ( v0 == 7 ) + { + if ( FriendlyMode ) + strcpy(infostr, "Player friendly"); + else + strcpy(infostr, "Player attack"); + } + else + { + strcpy(infostr, PanBtnStr[v0]); + } + if ( PanBtnHotKey[v0] ) + { + sprintf(tempstr, "Hotkey : %s", PanBtnHotKey[v0]); + AddPanelString(tempstr, 1); + } + _LOBYTE(infoclr) = 0; + panelflag = 1; + pinfoflag = 1; + } + } + ++v0; + } + while ( v0 < numpanbtns ); + } + if ( !spselflag && MouseX >= 565 && MouseX < 621 && MouseY >= 416 && MouseY < 472 ) + { + strcpy(infostr, "Select current spell button"); + _LOBYTE(infoclr) = 0; + panelflag = 1; + pinfoflag = 1; + strcpy(tempstr, "Hotkey : 's'"); + AddPanelString(tempstr, 1); + v4 = plr[myplr]._pRSpell; + if ( v4 != -1 ) + { + switch ( _LOBYTE(plr[myplr]._pRSplType) ) + { + case RSPLTYPE_SKILL: + sprintf(tempstr, "%s Skill", spelldata[v4].sSkillText); +LABEL_54: + AddPanelString(tempstr, 1); + break; + case RSPLTYPE_SPELL: + sprintf(tempstr, "%s Spell", spelldata[v4].sNameText); + AddPanelString(tempstr, 1); + v11 = plr[myplr]._pISplLvlAdd + plr[myplr]._pSplLvl[v4]; + if ( v11 < 0 ) + v11 = 0; + if ( v11 ) + sprintf(tempstr, "Spell Level %i", v11); + else + sprintf(tempstr, "Spell Level 0 - Unusable"); + goto LABEL_54; + case RSPLTYPE_SCROLL: + sprintf(tempstr, "Scroll of %s", spelldata[v4].sNameText); + AddPanelString(tempstr, 1); + v12 = 0; + v5 = myplr; + if ( plr[myplr]._pNumInv > 0 ) + { + v6 = &plr[v5].InvList[0]._iMiscId; + v7 = plr[myplr]._pNumInv; + do + { + if ( *(v6 - 53) != -1 && (*v6 == IMISC_SCROLL || *v6 == IMISC_SCROLLT) && v6[1] == v4 ) + ++v12; + v6 += 92; + --v7; + } + while ( v7 ); + } + v8 = v12; + v9 = &plr[v5].SpdList[0]._iMiscId; + v10 = 8; + do + { + if ( *(v9 - 53) != -1 && (*v9 == IMISC_SCROLL || *v9 == IMISC_SCROLLT) && v9[1] == v4 ) + ++v8; + v9 += 92; + --v10; + } + while ( v10 ); + if ( v8 == 1 ) + strcpy(tempstr, "1 Scroll"); + else + sprintf(tempstr, "%i Scrolls", v8); + goto LABEL_54; + case RSPLTYPE_CHARGES: + sprintf(tempstr, "Staff of %s", spelldata[v4].sNameText); + AddPanelString(tempstr, 1); + if ( plr[myplr].InvBody[4]._iCharges == 1 ) + strcpy(tempstr, "1 Charge"); + else + sprintf(tempstr, "%i Charges", plr[myplr].InvBody[4]._iCharges); + goto LABEL_54; + } + } + } + if ( MouseX > 190 && MouseX < 437 && MouseY > 356 && MouseY < 385 ) + pcursinvitem = CheckInvHLight(); +} +// 484368: using guessed type int FriendlyMode; +// 4B8824: using guessed type int pinfoflag; +// 4B883C: using guessed type int infoclr; +// 4B8A7C: using guessed type int numpanbtns; +// 4B8B84: using guessed type int panelflag; +// 4B8C98: using guessed type int spselflag; +// 4B8CB8: using guessed type char pcursinvitem; + +//----- (00404FE4) -------------------------------------------------------- +void __cdecl CheckBtnUp() +{ + signed int v0; // esi + int *v1; // eax + int v2; // edx + signed int v3; // eax + int v4; // ecx + int v5; // ecx + char v6; // [esp+Fh] [ebp-1h] + + v6 = 1; + drawbtnflag = 1; + panbtndown = 0; + v0 = 0; + do + { + v1 = &panbtn[v0]; + if ( *v1 ) + { + v2 = MouseX; + *v1 = 0; + v3 = v0; + v4 = PanBtnPos[v0][0]; + if ( v2 >= v4 && v2 <= v4 + PanBtnPos[v3][2] ) + { + v5 = PanBtnPos[v3][1]; + if ( MouseY >= v5 && MouseY <= v5 + PanBtnPos[v3][3] ) + { + switch ( v0 ) + { + case PANBTN_CHARINFO: + questlog = 0; + chrflag = chrflag == 0; + break; + case PANBTN_QLOG: + chrflag = 0; + if ( questlog ) + questlog = 0; + else + StartQuestlog(); + break; + case PANBTN_AUTOMAP: + DoAutoMap(); + break; + case PANBTN_MAINMENU: + qtextflag = 0; + gamemenu_handle_previous(); + v6 = 0; + break; + case PANBTN_INVENTORY: + sbookflag = 0; + invflag = invflag == 0; + if ( dropGoldFlag ) + { + dropGoldFlag = 0; + dropGoldValue = 0; + } + break; + case PANBTN_SPELLBOOK: + invflag = 0; + if ( dropGoldFlag ) + { + dropGoldFlag = 0; + dropGoldValue = 0; + } + sbookflag = sbookflag == 0; + break; + case PANBTN_SENDMSG: + if ( talkflag ) + control_reset_talk(); + else + control_type_message(); + break; + case PANBTN_FRIENDLY: + FriendlyMode = FriendlyMode == 0; + break; + default: + break; + } + } + } + } + ++v0; + } + while ( v0 < 8 ); + if ( v6 ) + gamemenu_off(); +} +// 484368: using guessed type int FriendlyMode; +// 4B84DC: using guessed type int dropGoldFlag; +// 4B8960: using guessed type int talkflag; +// 4B8968: using guessed type int sbookflag; +// 4B8C90: using guessed type int panbtndown; +// 646D00: using guessed type char qtextflag; +// 69BD04: using guessed type int questlog; + +//----- (00405181) -------------------------------------------------------- +void __cdecl FreeControlPan() +{ + void *v0; // ecx + void *v1; // ecx + void *v2; // ecx + void *v3; // ecx + void *v4; // ecx + void *v5; // ecx + void *v6; // ecx + void *v7; // ecx + void *v8; // ecx + void *v9; // ecx + void *v10; // ecx + void *v11; // ecx + void *v12; // ecx + void *v13; // ecx + void *v14; // ecx + void *v15; // ecx + + v0 = pBtmBuff; + pBtmBuff = 0; + mem_free_dbg(v0); + v1 = pManaBuff; + pManaBuff = 0; + mem_free_dbg(v1); + v2 = pLifeBuff; + pLifeBuff = 0; + mem_free_dbg(v2); + v3 = pPanelText; + pPanelText = 0; + mem_free_dbg(v3); + v4 = pChrPanel; + pChrPanel = 0; + mem_free_dbg(v4); + v5 = pSpellCels; + pSpellCels = 0; + mem_free_dbg(v5); + v6 = pPanelButtons; + pPanelButtons = 0; + mem_free_dbg(v6); + v7 = pMultiBtns; + pMultiBtns = 0; + mem_free_dbg(v7); + v8 = pTalkBtns; + pTalkBtns = 0; + mem_free_dbg(v8); + v9 = pChrButtons; + pChrButtons = 0; + mem_free_dbg(v9); + v10 = pDurIcons; + pDurIcons = 0; + mem_free_dbg(v10); + v11 = pQLogCel; + pQLogCel = 0; + mem_free_dbg(v11); + v12 = pSpellBkCel; + pSpellBkCel = 0; + mem_free_dbg(v12); + v13 = pSBkBtnCel; + pSBkBtnCel = 0; + mem_free_dbg(v13); + v14 = pSBkIconCels; + pSBkIconCels = 0; + mem_free_dbg(v14); + v15 = pGBoxBuff; + pGBoxBuff = 0; + mem_free_dbg(v15); +} + +//----- (00405295) -------------------------------------------------------- +int __fastcall control_WriteStringToBuffer(char *str) +{ + signed int v1; // edx + unsigned char v2; // al + + v1 = 0; + do + { + v2 = *str; + if ( !*str ) + return 1; + ++str; + v1 += fontkern[fontframe[fontidx[v2]]]; + } + while ( v1 < 125 ); + return 0; +} + +//----- (004052C8) -------------------------------------------------------- +void __cdecl DrawInfoBox() +{ + int v0; // ecx + int v1; // eax + int v2; // eax + int v3; // esi + char *v4; // eax + const char *v5; // eax + char v6; // al + signed int v7; // edi + signed int v8; // ebp + int v9; // esi + char *v10; // ebx + + DrawPanelBox(177, 62, 0x120u, 0x3Cu, 241, 558); + v0 = trigflag[3]; + v1 = spselflag; + if ( !panelflag && !trigflag[3] && pcursinvitem == -1 ) + { + if ( spselflag ) + { +LABEL_32: + _LOBYTE(infoclr) = 0; + goto LABEL_33; + } + infostr[0] = 0; + _LOBYTE(infoclr) = 0; + ClearPanel(); + } + if ( v1 || v0 ) + goto LABEL_32; + if ( pcurs < CURSOR_FIRSTITEM ) + { + if ( pcursitem != -1 ) + GetItemStr(pcursitem); + if ( pcursobj != -1 ) + GetObjectStr(pcursobj); + if ( *(_DWORD *)&pcursmonst != -1 ) + { + if ( leveltype ) + { + _LOBYTE(infoclr) = 0; + strcpy(infostr, monster[*(_DWORD *)&pcursmonst].mName); + ClearPanel(); + if ( monster[*(_DWORD *)&pcursmonst]._uniqtype ) + { + _LOBYTE(infoclr) = 3; + PrintUniqueHistory(); + } + else + { + PrintMonstHistory(monster[*(_DWORD *)&pcursmonst].MType->mtype); + } + } + else + { + strcpy(infostr, towner[*(_DWORD *)&pcursmonst]._tName); + } + } + if ( pcursplr != -1 ) + { + _LOBYTE(infoclr) = 3; + strcpy(infostr, plr[pcursplr]._pName); + ClearPanel(); + sprintf(tempstr, "Level : %i", plr[pcursplr]._pLevel); + AddPanelString(tempstr, 1); + sprintf(tempstr, "Hit Points %i of %i", plr[pcursplr]._pHitPoints >> 6, plr[pcursplr]._pMaxHP >> 6); + AddPanelString(tempstr, 1); + } + } + else + { + v2 = myplr; + if ( plr[myplr].HoldItem._itype == ITYPE_GOLD ) + { + v3 = plr[v2].HoldItem._ivalue; + v4 = get_pieces_str(plr[v2].HoldItem._ivalue); + sprintf(infostr, "%i gold %s", v3, v4); + } + else if ( plr[v2].HoldItem._iStatFlag ) + { + if ( plr[v2].HoldItem._iIdentified ) + v5 = plr[v2].HoldItem._iIName; + else + v5 = plr[v2].HoldItem._iName; + strcpy(infostr, v5); + v6 = plr[myplr].HoldItem._iMagical; + if ( v6 == 1 ) + _LOBYTE(infoclr) = 1; + if ( v6 == 2 ) + _LOBYTE(infoclr) = 3; + } + else + { + ClearPanel(); + AddPanelString("Requirements not met", 1); + pinfoflag = 1; + } + } +LABEL_33: + if ( (infostr[0] || pnumlines) && !talkflag ) + { + v7 = 0; + v8 = 1; + if ( infostr[0] ) + { + control_print_info_str(0, infostr, 1, pnumlines); + v7 = 1; + v8 = 0; + } + v9 = 0; + if ( pnumlines > 0 ) + { + v10 = panelstr; + do + { + control_print_info_str(v9 + v7, v10, pstrjust[v9], pnumlines - v8); + ++v9; + v10 += 64; + } + while ( v9 < pnumlines ); + } + } +} +// 4B8824: using guessed type int pinfoflag; +// 4B883C: using guessed type int infoclr; +// 4B8960: using guessed type int talkflag; +// 4B8B84: using guessed type int panelflag; +// 4B8C98: using guessed type int spselflag; +// 4B8CB8: using guessed type char pcursinvitem; +// 4B8CC0: using guessed type char pcursitem; +// 4B8CC1: using guessed type char pcursobj; +// 4B8CC2: using guessed type char pcursplr; +// 5BB1ED: using guessed type char leveltype; + +//----- (004055BC) -------------------------------------------------------- +void __fastcall control_print_info_str(int y, char *str, int a3, int lines) +{ + int v4; // edi + char *v5; // ebx + unsigned char v6; // cl + signed int v7; // eax + char *v8; // esi + int v9; // eax + char *v10; // esi + unsigned char v11; // al + int width; // [esp+18h] [ebp+Ch] + + v4 = 0; + v5 = str; + width = lineoffset[y + 4 * lines + lines]; + if ( a3 == 1 ) + { + v6 = *str; + v7 = 0; + v8 = str; + if ( !*str ) + goto LABEL_14; + do + { + ++v8; + v7 += fontkern[fontframe[fontidx[v6]]] + 2; + v6 = *v8; + } + while ( *v8 ); + if ( v7 < 288 ) +LABEL_14: + v4 = (288 - v7) >> 1; + width += v4; + } + while ( 1 ) + { + v11 = *v5; + if ( !*v5 ) + break; + ++v5; + v9 = fontidx[v11]; + _LOBYTE(v9) = fontframe[v9]; + v10 = (char *)(unsigned char)v9; + v4 += fontkern[(unsigned char)v9] + 2; + if ( (_BYTE)v9 ) + { + if ( v4 < 288 ) + { + _LOBYTE(v9) = infoclr; + CPrintString(width, v10, v9); + } + } + width += fontkern[(_DWORD)v10] + 2; + } +} +// 4B883C: using guessed type int infoclr; + +//----- (00405681) -------------------------------------------------------- +void __fastcall PrintGameStr(int x, int y, char *str, int color) +{ + char *v4; // edi + int v5; // esi + unsigned char i; // al + unsigned char v7; // bl + + v4 = str; + v5 = screen_y_times_768[y + 160] + x + 64; + for ( i = *str; *v4; i = *v4 ) + { + ++v4; + v7 = fontframe[fontidx[i]]; + if ( v7 ) + CPrintString(v5, (char *)v7, color); + v5 += fontkern[v7] + 1; + } +} + +//----- (004056D8) -------------------------------------------------------- +void __cdecl DrawChr() +{ + char v0; // al + int v1; // ecx + int v2; // ecx + int v3; // eax + int v4; // eax + bool v5; // zf + int v6; // eax + int v7; // edi + int v8; // edi + char v9; // al + char v10; // al + char v11; // al + int v12; // ecx + int v13; // eax + int v14; // ecx + int v15; // eax + int v16; // ecx + int v17; // eax + int v18; // ecx + int v19; // eax + int *v20; // edi + int v21; // edi + int v22; // edi + int v23; // ecx + int v24; // eax + int v25; // ecx + int v26; // ecx + char a4[64]; // [esp+Ch] [ebp-50h] + int v28; // [esp+4Ch] [ebp-10h] + int v29; // [esp+50h] [ebp-Ch] + int v30; // [esp+54h] [ebp-8h] + char a5[4]; // [esp+58h] [ebp-4h] + + Cel_decode(64, 511, pChrPanel, 1, 320); + ADD_PlrStringXY(20, 32, 151, plr[myplr]._pName, 0); + v0 = plr[myplr]._pClass; + if ( v0 ) + { + if ( v0 == 1 ) + { + ADD_PlrStringXY(168, 32, 299, "Rogue", 0); + } + else if ( v0 == 2 ) + { + ADD_PlrStringXY(168, 32, 299, "Sorceror", 0); + } + } + else + { + ADD_PlrStringXY(168, 32, 299, "Warrior", 0); + } + sprintf(a4, "%i", plr[myplr]._pLevel); + ADD_PlrStringXY(66, 69, 109, a4, 0); + sprintf(a4, "%li", plr[myplr]._pExperience); + ADD_PlrStringXY(216, 69, 300, a4, 0); + if ( plr[myplr]._pLevel == 50 ) + { + strcpy(a4, "None"); + a5[0] = 3; + } + else + { + sprintf(a4, "%li", plr[myplr]._pNextExper); + a5[0] = 0; + } + ADD_PlrStringXY(216, 97, 300, a4, a5[0]); + sprintf(a4, "%i", plr[myplr]._pGold); + ADD_PlrStringXY(216, 146, 300, a4, 0); + a5[0] = 0; + v29 = plr[myplr]._pIBonusAC; + if ( v29 > 0 ) + a5[0] = 1; + if ( v29 < 0 ) + a5[0] = 2; + sprintf(a4, "%i", v29 + plr[myplr]._pIAC + plr[myplr]._pDexterity / 5); + ADD_PlrStringXY(258, 183, 301, a4, a5[0]); + a5[0] = 0; + v1 = plr[myplr]._pIBonusToHit; + if ( v1 > 0 ) + a5[0] = 1; + if ( v1 < 0 ) + a5[0] = 2; + sprintf(a4, "%i%%", (plr[myplr]._pDexterity >> 1) + v1 + 50); + ADD_PlrStringXY(258, 211, 301, a4, a5[0]); + a5[0] = 0; + v2 = myplr; + v3 = plr[myplr]._pIBonusDam; + if ( v3 > 0 ) + a5[0] = 1; + if ( v3 < 0 ) + a5[0] = 2; + v30 = plr[v2]._pIMinDam; + v30 += plr[v2]._pIBonusDamMod + v30 * v3 / 100; + v4 = plr[v2]._pDamageMod; + v5 = plr[v2].InvBody[4]._itype == ITYPE_BOW; + v29 = plr[v2]._pDamageMod; + if ( v5 && _LOBYTE(plr[v2]._pClass) != 1 ) + v4 >>= 1; + v30 += v4; + v6 = plr[v2]._pIBonusDam; + v28 = plr[v2]._pIMaxDam; + v7 = plr[v2]._pIBonusDamMod + v28 * v6 / 100 + v28; + if ( plr[v2].InvBody[4]._itype != ITYPE_BOW || _LOBYTE(plr[v2]._pClass) == 1 ) + v8 = v29 + v7; + else + v8 = (v29 >> 1) + v7; + sprintf(a4, "%i-%i", v30, v8); + if ( v30 >= 100 || v8 >= 100 ) + MY_PlrStringXY(254, 239, 305, a4, a5[0], -1); + else + MY_PlrStringXY(258, 239, 301, a4, a5[0], 0); + v9 = plr[myplr]._pMagResist; + a5[0] = v9 != 0; + if ( v9 >= 75 ) + { + a5[0] = 3; + sprintf(a4, "MAX"); + } + else + { + sprintf(a4, "%i%%", v9); + } + ADD_PlrStringXY(257, 276, 300, a4, a5[0]); + v10 = plr[myplr]._pFireResist; + a5[0] = v10 != 0; + if ( v10 >= 75 ) + { + a5[0] = 3; + sprintf(a4, "MAX"); + } + else + { + sprintf(a4, "%i%%", v10); + } + ADD_PlrStringXY(257, 304, 300, a4, a5[0]); + v11 = plr[myplr]._pLghtResist; + a5[0] = v11 != 0; + if ( v11 >= 75 ) + { + a5[0] = 3; + sprintf(a4, "MAX"); + } + else + { + sprintf(a4, "%i%%", v11); + } + ADD_PlrStringXY(257, 332, 300, a4, a5[0]); + a5[0] = 0; + sprintf(a4, "%i", plr[myplr]._pBaseStr); + if ( MaxStats[SLOBYTE(plr[myplr]._pClass)][0] == plr[myplr]._pBaseStr ) + a5[0] = 3; + ADD_PlrStringXY(95, 155, 126, a4, a5[0]); + a5[0] = 0; + sprintf(a4, "%i", plr[myplr]._pBaseMag); + if ( MaxStats[SLOBYTE(plr[myplr]._pClass)][1] == plr[myplr]._pBaseMag ) + a5[0] = 3; + ADD_PlrStringXY(95, 183, 126, a4, a5[0]); + a5[0] = 0; + sprintf(a4, "%i", plr[myplr]._pBaseDex); + if ( MaxStats[SLOBYTE(plr[myplr]._pClass)][2] == plr[myplr]._pBaseDex ) + a5[0] = 3; + ADD_PlrStringXY(95, 211, 126, a4, a5[0]); + a5[0] = 0; + sprintf(a4, "%i", plr[myplr]._pBaseVit); + if ( MaxStats[SLOBYTE(plr[myplr]._pClass)][3] == plr[myplr]._pBaseVit ) + a5[0] = 3; + ADD_PlrStringXY(95, 239, 126, a4, a5[0]); + a5[0] = 0; + v12 = plr[myplr]._pStrength; + v13 = plr[myplr]._pBaseStr; + if ( v12 > v13 ) + a5[0] = 1; + if ( v12 < v13 ) + a5[0] = 2; + sprintf(a4, "%i", v12); + ADD_PlrStringXY(143, 155, 173, a4, a5[0]); + a5[0] = 0; + v14 = plr[myplr]._pMagic; + v15 = plr[myplr]._pBaseMag; + if ( v14 > v15 ) + a5[0] = 1; + if ( v14 < v15 ) + a5[0] = 2; + sprintf(a4, "%i", v14); + ADD_PlrStringXY(143, 183, 173, a4, a5[0]); + a5[0] = 0; + v16 = plr[myplr]._pDexterity; + v17 = plr[myplr]._pBaseDex; + if ( v16 > v17 ) + a5[0] = 1; + if ( v16 < v17 ) + a5[0] = 2; + sprintf(a4, "%i", v16); + ADD_PlrStringXY(143, 211, 173, a4, a5[0]); + a5[0] = 0; + v18 = plr[myplr]._pVitality; + v19 = plr[myplr]._pBaseVit; + if ( v18 > v19 ) + a5[0] = 1; + if ( v18 < v19 ) + a5[0] = 2; + sprintf(a4, "%i", v18); + ADD_PlrStringXY(143, 239, 173, a4, a5[0]); + v20 = &plr[myplr]._pStatPts; + if ( *v20 > 0 ) + { + v20 = &plr[myplr]._pStatPts; + if ( CalcStatDiff(myplr) < *v20 ) + { + v20 = &plr[myplr]._pStatPts; + *v20 = CalcStatDiff(myplr); + } + } + v21 = *v20; + if ( v21 > 0 ) + { + sprintf(a4, "%i", v21); + ADD_PlrStringXY(95, 266, 126, a4, 2); + v22 = SLOBYTE(plr[myplr]._pClass); + if ( plr[myplr]._pBaseStr < MaxStats[v22][0] ) + Cel_decode(201, 319, pChrButtons, chrbtn[0] + 2, 41); + if ( plr[myplr]._pBaseMag < MaxStats[v22][1] ) + Cel_decode(201, 347, pChrButtons, chrbtn[1] + 4, 41); + if ( plr[myplr]._pBaseDex < MaxStats[v22][2] ) + Cel_decode(201, 376, pChrButtons, chrbtn[2] + 6, 41); + if ( plr[myplr]._pBaseVit < MaxStats[v22][3] ) + Cel_decode(201, 404, pChrButtons, chrbtn[3] + 8, 41); + } + v23 = plr[myplr]._pMaxHP; + a5[0] = v23 > plr[myplr]._pMaxHPBase; + sprintf(a4, "%i", v23 >> 6); + ADD_PlrStringXY(95, 304, 126, a4, a5[0]); + v24 = plr[myplr]._pHitPoints; + if ( v24 != plr[myplr]._pMaxHP ) + a5[0] = 2; + sprintf(a4, "%i", v24 >> 6); + ADD_PlrStringXY(143, 304, 174, a4, a5[0]); + v25 = plr[myplr]._pMaxMana; + a5[0] = v25 > plr[myplr]._pMaxManaBase; + sprintf(a4, "%i", v25 >> 6); + ADD_PlrStringXY(95, 332, 126, a4, a5[0]); + v26 = plr[myplr]._pMana; + if ( v26 != plr[myplr]._pMaxMana ) + a5[0] = 2; + sprintf(a4, "%i", v26 >> 6); + ADD_PlrStringXY(143, 332, 174, a4, a5[0]); +} + +//----- (00406058) -------------------------------------------------------- +void __fastcall ADD_PlrStringXY(int x, int y, int width, char *pszStr, char col) +{ + int v5; // eax + char *v6; // edx + unsigned char v7; // al + int v8; // esi + int v9; // edi + int v10; // ecx + unsigned char v11; // bl + unsigned char v12; // al + int v13; // ebx + int widtha; // [esp+Ch] [ebp-4h] + int widthb; // [esp+Ch] [ebp-4h] + + v5 = screen_y_times_768[y + 160]; + v6 = pszStr; + widtha = v5 + x + 64; + v7 = *pszStr; + v8 = width - x + 1; + v9 = 0; + v10 = 0; + if ( *pszStr ) + { + v11 = *pszStr; + do + { + ++v6; + v10 += fontkern[fontframe[fontidx[v11]]] + 1; + v11 = *v6; + } + while ( *v6 ); + } + if ( v10 < v8 ) + v9 = (v8 - v10) >> 1; + widthb = v9 + widtha; + while ( v7 ) + { + ++pszStr; + v12 = fontframe[fontidx[v7]]; + v13 = v12; + v9 += fontkern[v12] + 1; + if ( v12 ) + { + if ( v9 < v8 ) + CPrintString(widthb, (char *)v12, col); + } + widthb += fontkern[v13] + 1; + v7 = *pszStr; + } +} + +//----- (0040610F) -------------------------------------------------------- +void __fastcall MY_PlrStringXY(int x, int y, int width, char *pszStr, char col, int base) +{ + char *v6; // ebx + unsigned char v7; // al + int v8; // edx + int v9; // esi + char *v10; // edi + unsigned char v11; // cl + unsigned char v12; // al + int v13; // edi + int widtha; // [esp+Ch] [ebp-4h] + int widthb; // [esp+Ch] [ebp-4h] + int v16; // [esp+18h] [ebp+8h] + + v6 = pszStr; + widtha = screen_y_times_768[y + 160] + x + 64; + v7 = *pszStr; + v8 = 0; + v9 = width - x + 1; + v16 = 0; + v10 = pszStr; + if ( *pszStr ) + { + v11 = *pszStr; + do + { + ++v10; + v8 += base + fontkern[fontframe[fontidx[v11]]]; + v11 = *v10; + } + while ( *v10 ); + } + if ( v8 < v9 ) + v16 = (v9 - v8) >> 1; + widthb = v16 + widtha; + while ( v7 ) + { + ++v6; + v12 = fontframe[fontidx[v7]]; + v13 = v12; + v16 += base + fontkern[v12]; + if ( v12 ) + { + if ( v16 < v9 ) + CPrintString(widthb, (char *)v12, col); + } + widthb += base + fontkern[v13]; + v7 = *v6; + } +} + +//----- (004061CA) -------------------------------------------------------- +void __cdecl CheckLvlBtn() +{ + if ( !lvlbtndown && MouseX >= 40 && MouseX <= 81 && MouseY >= 313 && MouseY <= 335 ) + lvlbtndown = 1; +} +// 4B851C: using guessed type int lvlbtndown; + +//----- (00406200) -------------------------------------------------------- +void __cdecl ReleaseLvlBtn() +{ + if ( MouseX >= 40 && MouseX <= 81 && MouseY >= 313 && MouseY <= 335 ) + chrflag = 1; + lvlbtndown = 0; +} +// 4B851C: using guessed type int lvlbtndown; + +//----- (00406234) -------------------------------------------------------- +void __cdecl DrawLevelUpIcon() +{ + int v0; // esi + + if ( !stextflag ) + { + v0 = (lvlbtndown != 0) + 2; + ADD_PlrStringXY(0, 303, 120, "Level Up", 0); + Cel_decode(104, 495, pChrButtons, v0, 41); + } +} +// 4B851C: using guessed type int lvlbtndown; +// 6AA705: using guessed type char stextflag; + +//----- (0040627A) -------------------------------------------------------- +void __cdecl CheckChrBtns() +{ + int v0; // esi + int v1; // ecx + int v2; // ebx + int v3; // edi + int v4; // edx + bool v5; // sf + unsigned char v6; // of + int v7; // edx + int v8; // edx + int v9; // edx + int v10; // eax + int v11; // edx + int v12; // edx + + v0 = 0; + if ( !chrbtnactive ) + { + v1 = myplr; + if ( plr[myplr]._pStatPts ) + { + v2 = MouseX; + v3 = SLOBYTE(plr[v1]._pClass); + while ( 1 ) + { + if ( !v0 ) + { + v9 = plr[v1]._pBaseStr; + v6 = __OFSUB__(v9, MaxStats[v3][0]); + v5 = v9 - MaxStats[v3][0] < 0; + goto LABEL_12; + } + if ( v0 == 1 ) + { + v8 = plr[v1]._pBaseMag; + v6 = __OFSUB__(v8, MaxStats[v3][1]); + v5 = v8 - MaxStats[v3][1] < 0; + goto LABEL_12; + } + if ( v0 == 2 ) + break; + if ( v0 == 3 ) + { + v4 = plr[v1]._pBaseVit; + v6 = __OFSUB__(v4, MaxStats[v3][3]); + v5 = v4 - MaxStats[v3][3] < 0; +LABEL_12: + if ( v5 ^ v6 ) + { + v10 = v0; + v11 = attribute_inc_rects[v0].x; + if ( v2 >= v11 && v2 <= v11 + attribute_inc_rects[v10].w ) + { + v12 = attribute_inc_rects[v10].y; + if ( MouseY >= v12 && MouseY <= v12 + attribute_inc_rects[v10].h ) + { + chrbtn[v0] = 1; + chrbtnactive = 1; + } + } + } + } + if ( ++v0 >= 4 ) + return; + } + v7 = plr[v1]._pBaseDex; + v6 = __OFSUB__(v7, MaxStats[v3][2]); + v5 = v7 - MaxStats[v3][2] < 0; + goto LABEL_12; + } + } +} +// 4B87A8: using guessed type int chrbtnactive; + +//----- (00406366) -------------------------------------------------------- +void __cdecl ReleaseChrBtns() +{ + signed int v0; // esi + int *v1; // eax + signed int v2; // eax + int v3; // ecx + int v4; // ecx + unsigned char v5; // dl + + chrbtnactive = 0; + v0 = 0; + do + { + v1 = &chrbtn[v0]; + if ( *v1 ) + { + *v1 = 0; + v2 = v0; + v3 = attribute_inc_rects[v0].x; + if ( MouseX >= v3 && MouseX <= v3 + attribute_inc_rects[v2].w ) + { + v4 = attribute_inc_rects[v2].y; + if ( MouseY >= v4 && MouseY <= v4 + attribute_inc_rects[v2].h ) + { + if ( v0 ) + { + switch ( v0 ) + { + case ATTRIB_MAG: + v5 = CMD_ADDMAG; + break; + case ATTRIB_DEX: + v5 = CMD_ADDDEX; + break; + case ATTRIB_VIT: + v5 = CMD_ADDVIT; + break; + default: + goto LABEL_16; + } + } + else + { + v5 = CMD_ADDSTR; + } + NetSendCmdParam1(1u, v5, 1u); + --plr[myplr]._pStatPts; + } + } + } +LABEL_16: + ++v0; + } + while ( v0 < 4 ); +} +// 4B87A8: using guessed type int chrbtnactive; + +//----- (00406408) -------------------------------------------------------- +void __cdecl DrawDurIcon() +{ + int v0; // edx + PlayerStruct *v1; // esi + int v2; // eax + int v3; // eax + int v4; // eax + + if ( !chrflag && !questlog || !invflag && !sbookflag ) + { + v0 = 656; + if ( invflag || sbookflag ) + v0 = 336; + v1 = &plr[myplr]; + v2 = DrawDurIcon4Item(v1->InvBody, v0, 4); + v3 = DrawDurIcon4Item(&v1->InvBody[6], v2, 3); + v4 = DrawDurIcon4Item(&v1->InvBody[4], v3, 0); + DrawDurIcon4Item(&v1->InvBody[5], v4, 0); + } +} +// 4B8968: using guessed type int sbookflag; +// 69BD04: using guessed type int questlog; + +//----- (0040648E) -------------------------------------------------------- +int __fastcall DrawDurIcon4Item(ItemStruct *pItem, int x, int c) +{ + int v3; // eax + int v4; // edi + int v5; // esi + signed int v7; // edx + int v8; // eax + int v9; // eax + int v10; // eax + int v11; // eax + signed int v12; // [esp-4h] [ebp-Ch] + + v3 = pItem->_itype; + v4 = x; + if ( v3 == -1 ) + return x; + v5 = pItem->_iDurability; + if ( v5 > 5 ) + return x; + v7 = c; + if ( !c ) + { + if ( pItem->_iClass != 1 ) + { + v7 = 1; + goto LABEL_18; + } + v8 = v3 - 1; + if ( !v8 ) + { + v12 = 2; + goto LABEL_15; + } + v9 = v8 - 1; + if ( !v9 ) + { + v12 = 6; + goto LABEL_15; + } + v10 = v9 - 1; + if ( !v10 ) + { + v12 = 7; + goto LABEL_15; + } + v11 = v10 - 1; + if ( !v11 ) + { + v12 = 5; + goto LABEL_15; + } + if ( v11 == 6 ) + { + v12 = 8; +LABEL_15: + v7 = v12; + goto LABEL_18; + } + } +LABEL_18: + if ( v5 > 2 ) + v7 += 8; + Cel_decode(v4, 495, pDurIcons, v7, 32); + return v4 - 40; +} + +//----- (00406508) -------------------------------------------------------- +void __cdecl RedBack() +{ +/* int v0; // eax + char *v1; // edi + signed int v3; // edx + signed int v4; // ecx + char *v7; // edi + signed int v9; // edx + signed int v10; // ecx + int v12; // [esp+8h] [ebp-4h] + + v0 = -(light4flag != 0); + _LOWORD(v0) = v0 & 0xF400; + v12 = v0 + 0x1200; + if ( leveltype == 4 ) + { + v7 = gpBuffer->row[0].pixels; + _EBX = v12 + dword_646A20; + v9 = 352; + do + { + v10 = 640; + do + { + _AL = *v7; + if ( (unsigned char)*v7 >= 0x20u ) + __asm { xlat } + *v7++ = _AL; + --v10; + } + while ( v10 ); + v7 += 128; + --v9; + } + while ( v9 ); + } + else + { + v1 = gpBuffer->row[0].pixels; + _EBX = v12 + dword_646A20; + v3 = 352; + do + { + v4 = 640; + do + { + _AL = *v1; + __asm { xlat } + *v1++ = _AL; + --v4; + } + while ( v4 ); + v1 += 128; + --v3; + } + while ( v3 ); + } +*/ +} +// 525728: using guessed type int light4flag; +// 5BB1ED: using guessed type char leveltype; + +//----- (00406592) -------------------------------------------------------- +int __fastcall GetSBookTrans(int ii, unsigned char townok) +{ + int v2; // edi + int v3; // esi + int result; // eax + int v5; // eax + char v6; // [esp+13h] [ebp-5h] + int v7; // [esp+14h] [ebp-4h] + + v2 = ii; + v7 = townok; + v6 = 1; + v3 = myplr; + if ( ((unsigned __int64)(1i64 << ((unsigned char)ii - 1)) >> 32) & plr[v3]._pISpells[1] | (unsigned int)(1i64 << ((unsigned char)ii - 1)) & plr[v3]._pISpells[0] ) + v6 = 3; + result = plr[v3]._pAblSpells[1] & (1 << (ii - 1) >> 31) | plr[v3]._pAblSpells[0] & (1 << (ii - 1)); + if ( result ) + v6 = 0; + if ( v6 == 1 ) + { + _LOBYTE(v5) = CheckSpell(myplr, ii, 1, 1); + if ( !v5 ) + v6 = 4; + result = 21720 * myplr; + if ( (char)(plr[myplr]._pISplLvlAdd + plr[myplr]._pSplLvl[v2]) <= 0 ) + v6 = 4; + } + if ( v7 && !currlevel && v6 != 4 && !*(_DWORD *)&spelldata[v2].sTownSpell ) + v6 = 4; + _LOBYTE(result) = v6; + return result; +} + +//----- (00406667) -------------------------------------------------------- +void __cdecl DrawSpellBook() +{ + int v0; // edi + int v1; // ebp + int v2; // esi + char v3; // al + int v4; // eax + int v5; // ebx + int v6; // ecx + char v7; // [esp+Bh] [ebp-1Dh] + int v8; // [esp+Ch] [ebp-1Ch] + signed int v9; // [esp+10h] [ebp-18h] + int sel; // [esp+14h] [ebp-14h] + int v11; // [esp+18h] [ebp-10h] + int v12; // [esp+1Ch] [ebp-Ch] + + Cel_decode(384, 511, pSpellBkCel, 1, 320); + Cel_decode(76 * sbooktab + 391, 508, pSBkBtnCel, sbooktab + 1, 76); + v9 = 1; + v8 = 214; + v0 = plr[myplr]._pISpells[0] | plr[myplr]._pMemSpells[0] | plr[myplr]._pAblSpells[0]; + v1 = plr[myplr]._pISpells[1] | plr[myplr]._pMemSpells[1] | plr[myplr]._pAblSpells[1]; + do + { + v2 = *(&attribute_inc_rects[3].h + v9 + 7 * sbooktab); + if ( v2 != -1 + && v1 & ((unsigned __int64)(1i64 << ((unsigned char)v2 - 1)) >> 32) | v0 & (unsigned int)(1i64 << ((unsigned char)v2 - 1)) ) + { + v7 = GetSBookTrans(v2, 1u); + SetSpellTrans(v7); + DrawSpellCel(395, v8 + 1, (char *)pSBkIconCels, (char)SpellITbl[v2], 37); + if ( v2 == plr[myplr]._pRSpell && v7 == _LOBYTE(plr[myplr]._pRSplType) ) + { + SetSpellTrans(0); + DrawSpellCel(395, v8 + 1, (char *)pSBkIconCels, 43, 37); + } + PrintSBookStr(10, v8 - 22, 0, spelldata[v2].sNameText, 0); + v3 = GetSBookTrans(v2, 0); + if ( v3 ) + { + if ( v3 == 3 ) + { + sprintf(tempstr, "Staff (%i charges)", plr[myplr].InvBody[4]._iCharges); + } + else + { + v4 = GetManaAmount(myplr, v2); + v5 = v4 >> 6; + v12 = v4 >> 6; + GetDamageAmt(v2, &sel, &v11); + if ( sel == -1 ) + sprintf(tempstr, "Mana: %i Dam: n/a", v5); + else + sprintf(tempstr, "Mana: %i Dam: %i - %i", v5, sel, v11); + if ( v2 == SPL_BONESPIRIT ) + sprintf(tempstr, "Mana: %i Dam: 1/3 tgt hp", v12); + PrintSBookStr(10, v8, 0, tempstr, 0); + v6 = plr[myplr]._pISplLvlAdd + plr[myplr]._pSplLvl[v2]; + if ( v6 < 0 ) + v6 = 0; + if ( v6 ) + sprintf(tempstr, "Spell Level %i", v6); + else + sprintf(tempstr, "Spell Level 0 - Unusable"); + } + } + else + { + strcpy(tempstr, "Skill"); + } + PrintSBookStr(10, v8 - 11, 0, tempstr, 0); + } + v8 += 43; + ++v9; + } + while ( v9 < 8 ); +} +// 4B8950: using guessed type int sbooktab; + +//----- (004068F4) -------------------------------------------------------- +void __fastcall PrintSBookStr(int x, int y, bool cjustflag, char *pszStr, int bright) +{ + char *v5; // ebx + signed int v6; // eax + int v7; // edi + unsigned char v8; // cl + char *v9; // esi + unsigned char v10; // al + int v11; // esi + unsigned char v12; // al + int width; // [esp+Ch] [ebp-4h] + + v5 = pszStr; + width = screen_y_times_768[y] + x + 440; + v6 = 0; + v7 = 0; + if ( cjustflag ) + { + v8 = *pszStr; + v9 = pszStr; + if ( !*pszStr ) + goto LABEL_14; + do + { + ++v9; + v6 += fontkern[fontframe[fontidx[v8]]] + 1; + v8 = *v9; + } + while ( *v9 ); + if ( v6 < 222 ) +LABEL_14: + v7 = (222 - v6) >> 1; + width += v7; + } + while ( 1 ) + { + v12 = *v5; + if ( !*v5 ) + break; + ++v5; + v10 = fontframe[fontidx[v12]]; + v11 = v10; + v7 += fontkern[v10] + 1; + if ( v10 ) + { + if ( v7 <= 222 ) + CPrintString(width, (char *)v10, bright); + } + width += fontkern[v11] + 1; + } +} + +//----- (004069B6) -------------------------------------------------------- +void __cdecl CheckSBook() +{ + signed int v0; // ecx + signed int v1; // esi + spell_id v2; // eax + int v3; // esi + signed __int64 v4; // rax + char v5; // cl + __int64 v6; // [esp+8h] [ebp-10h] + int v7; // [esp+10h] [ebp-8h] + + v0 = MouseY; + v1 = MouseX; + if ( MouseX >= 331 && MouseX < 368 && MouseY >= 18 && MouseY < 314 ) + { + v2 = SpellPages[0][7 * sbooktab + (MouseY - 18) / 43]; + v7 = SpellPages[0][7 * sbooktab + (MouseY - 18) / 43]; + if ( v2 != -1 ) + { + v3 = myplr; + LODWORD(v6) = plr[myplr]._pAblSpells[0]; + HIDWORD(v6) = plr[myplr]._pAblSpells[1]; + v4 = 1i64 << ((unsigned char)v2 - 1); + if ( HIDWORD(v4) & (HIDWORD(v6) | plr[myplr]._pISpells[1] | plr[myplr]._pMemSpells[1]) | (unsigned int)v4 & ((unsigned int)v6 | plr[myplr]._pISpells[0] | plr[myplr]._pMemSpells[0]) ) + { + v5 = 3; + if ( !(plr[v3]._pISpells[1] & HIDWORD(v4) | plr[v3]._pISpells[0] & (unsigned int)v4) ) + v5 = 1; + if ( v6 & v4 ) + v5 = 0; + force_redraw = 255; + plr[v3]._pRSpell = v7; + _LOBYTE(plr[v3]._pRSplType) = v5; + } + v1 = MouseX; + v0 = MouseY; + } + } + if ( v1 >= 327 && v1 < 633 && v0 >= 320 && v0 < 349 ) + sbooktab = (v1 - 327) / 76; +} +// 4B8950: using guessed type int sbooktab; +// 52571C: using guessed type int force_redraw; + +//----- (00406AF8) -------------------------------------------------------- +char *__fastcall get_pieces_str(int nGold) +{ + char *result; // eax + + result = "piece"; + if ( nGold != 1 ) + result = "pieces"; + return result; +} + +//----- (00406B08) -------------------------------------------------------- +void __fastcall DrawGoldSplit(int amount) +{ + int v1; // ebp + char *v2; // eax + char v3; // cl + signed int i; // eax + int screen_x; // [esp+10h] [ebp-4h] + int screen_xa; // [esp+10h] [ebp-4h] + + screen_x = 0; + v1 = amount; + Cel_decode(415, 338, pGBoxBuff, 1, 261); + sprintf(tempstr, "You have %u gold", initialDropGoldValue); + ADD_PlrStringXY(366, 87, 600, tempstr, 3); + v2 = get_pieces_str(initialDropGoldValue); + sprintf(tempstr, "%s. How many do", v2); + ADD_PlrStringXY(366, 103, 600, tempstr, 3); + ADD_PlrStringXY(366, 121, 600, "you want to remove?", 3); + if ( v1 <= 0 ) + { + screen_xa = 450; + } + else + { + sprintf(tempstr, "%u", v1); + PrintGameStr(388, 140, tempstr, 0); + v3 = tempstr[0]; + for ( i = 0; i < v3; v3 = tempstr[i] ) + { + ++i; + screen_x += fontkern[fontframe[fontidx[(unsigned char)v3]]] + 1; + } + screen_xa = screen_x + 452; + } + Cel_decode(screen_xa, 300, pCelBuff, frame_4B8800, 12); + frame_4B8800 = (frame_4B8800 & 7) + 1; +} + +//----- (00406C40) -------------------------------------------------------- +void __fastcall control_drop_gold(int a1) +{ + char v1; // bl + int v2; // eax + int v3; // eax + size_t v4; // esi + char v5; // [esp+7h] [ebp-9h] + char v6[8]; // [esp+8h] [ebp-8h] + + v1 = a1; + if ( (signed int)(plr[myplr]._pHitPoints & 0xFFFFFFC0) <= 0 ) + { + dropGoldFlag = 0; + dropGoldValue = 0; + return; + } + memset(v6, 0, 6u); + _itoa(dropGoldValue, v6, 10); + if ( v1 != 13 ) + { + if ( v1 == 27 ) + { + dropGoldFlag = 0; + dropGoldValue = 0; + return; + } + if ( v1 == 8 ) + { + *(&v5 + strlen(v6)) = 0; + v2 = atoi(v6); + } + else + { + v3 = v1 - 48; + if ( v3 < 0 || v3 > 9 ) + return; + if ( dropGoldValue || atoi(v6) <= initialDropGoldValue ) + { + v6[strlen(v6)] = v1; + if ( atoi(v6) > initialDropGoldValue ) + return; + v4 = strlen(v6); + if ( v4 > strlen(v6) ) + return; + } + else + { + v6[0] = v1; + } + v2 = atoi(v6); + } + dropGoldValue = v2; + return; + } + if ( dropGoldValue > 0 ) + control_remove_gold(myplr, initialDropGoldIndex); + dropGoldFlag = 0; +} +// 4B84DC: using guessed type int dropGoldFlag; +// 406C40: using guessed type char var_8[8]; + +//----- (00406D6E) -------------------------------------------------------- +void __fastcall control_remove_gold(int pnum, int gold_index) +{ + int v2; // edi + int v3; // esi + int v4; // edx + _DWORD *v5; // eax + int v6; // edx + _DWORD *v7; // eax + int v8; // eax + + v2 = pnum; + v3 = pnum; + if ( gold_index > 46 ) + { + v6 = gold_index - 47; + v7 = (unsigned int *)((char *)&plr[0].SpdList[v6]._ivalue + v3 * 21720); + *v7 -= dropGoldValue; + if ( *v7 <= 0 ) + RemoveSpdBarItem(pnum, v6); + else + SetSpdbarGoldCurs(pnum, v6); + } + else + { + v4 = gold_index - 7; + v5 = (unsigned int *)((char *)&plr[0].InvList[v4]._ivalue + v3 * 21720); + *v5 -= dropGoldValue; + if ( *v5 <= 0 ) + RemoveInvItem(pnum, v4); + else + SetGoldCurs(pnum, v4); + } + SetPlrHandItem(&plr[v3].HoldItem, 0); + GetGoldSeed(v2, &plr[v3].HoldItem._iSeed); + plr[v3].HoldItem._ivalue = dropGoldValue; + plr[v3].HoldItem._iStatFlag = 1; + control_set_gold_curs(v2); + v8 = CalculateGold(v2); + dropGoldValue = 0; + plr[v3]._pGold = v8; +} + +//----- (00406E24) -------------------------------------------------------- +void __fastcall control_set_gold_curs(int pnum) +{ + int v1; // ecx + int v2; // eax + int *v3; // eax + bool v4; // zf + bool v5; // sf + unsigned char v6; // of + + v1 = pnum; + v2 = plr[v1].HoldItem._ivalue; + if ( v2 < 2500 ) + { + v6 = __OFSUB__(v2, 1000); + v4 = v2 == 1000; + v5 = v2 - 1000 < 0; + v3 = &plr[v1].HoldItem._iCurs; + if ( (unsigned char)(v5 ^ v6) | v4 ) + *v3 = 4; + else + *v3 = 5; + } + else + { + v3 = &plr[v1].HoldItem._iCurs; + plr[v1].HoldItem._iCurs = 6; + } + SetCursor(*v3 + 12); +} + +//----- (00406E6A) -------------------------------------------------------- +void __cdecl DrawTalkPan() +{ + int v0; // esi + signed int v1; // edi + signed int v2; // esi + char *v3; // eax + int v4; // esi + int v5; // esi + int v6; // ebx + int v7; // eax + int a4; // [esp+4h] [ebp-Ch] + char *a1; // [esp+8h] [ebp-8h] + int v10; // [esp+Ch] [ebp-4h] + + v0 = 0; + if ( talkflag ) + { + DrawPanelBox(175, sgbPlrTalkTbl + 20, 0x126u, 5u, 239, 516); + v1 = 293; + do + { + DrawPanelBox((v0 >> 1) + 175, sgbPlrTalkTbl + v0 + 25, v1, 1u, (v0 >> 1) + 239, v0 + 521); + ++v0; + --v1; + } + while ( v1 > 283 ); + DrawPanelBox(185, sgbPlrTalkTbl + 35, 0x112u, 0x1Eu, 249, 531); + DrawPanelBox(180, sgbPlrTalkTbl + 65, 0x11Cu, 5u, 244, 561); + v2 = 0; + do + { + DrawPanelBox(180, sgbPlrTalkTbl + v2 + 70, v2 + 284, 1u, 244, v2 + 566); + ++v2; + } + while ( v2 < 10 ); + DrawPanelBox(170, sgbPlrTalkTbl + 80, 0x136u, 0x37u, 234, 576); + v3 = sgszTalkMsg; + v4 = 0; + do + { + control_print_talk_msg(v3, 0, v4, &a4, 0); + if ( !v3 ) + goto LABEL_10; + v4 += 13; + } + while ( v4 < 39 ); + *v3 = 0; +LABEL_10: + Cel_into_buf((char *)gpBuffer + a4, (char *)pCelBuff, frame, 12); + v5 = 0; + a1 = plr[0]._pName; + v10 = 0; + frame = (frame & 7) + 1; + while ( v10 == myplr ) + { +LABEL_21: + a1 += 21720; + ++v10; + if ( (signed int)a1 >= (signed int)&plr_msgs[1].msg[115] ) + return; + } + if ( tempstr[v10 + 256] ) + { + v6 = 3; + if ( !talkbtndown[v5] ) + { +LABEL_18: + if ( *(a1 - 291) ) + control_print_talk_msg(a1, 46, 18 * v5 + 60, &a4, v6); + ++v5; + goto LABEL_21; + } + v7 = (v5 != 0) + 3; + } + else + { + v7 = (v5 != 0) + 1; + v6 = 2; + if ( talkbtndown[v5] ) + v7 = (v5 != 0) + 5; + } + Cel_decode(236, 18 * v5 + 596, pTalkBtns, v7, 61); + goto LABEL_18; + } +} +// 4B8840: using guessed type int sgbPlrTalkTbl; +// 4B8960: using guessed type int talkflag; + +//----- (00407071) -------------------------------------------------------- +void __fastcall control_print_talk_msg(char *msg, int x, int y, int *a4, int just) +{ + int v5; // edx + char *v6; // ebx + unsigned char v7; // al + int v8; // ecx + unsigned char v9; // dl + int v10; // edi + int a3; // [esp+14h] [ebp+8h] + + v5 = x + 264; + v6 = msg; + *a4 = v5 + screen_y_times_768[y + 534]; + v7 = *msg; + v8 = v5; + if ( v7 ) + { + while ( 1 ) + { + v9 = fontframe[fontidx[v7]]; + v10 = v9; + a3 = v8 + fontkern[v9] + 1; + if ( a3 > 514 ) + break; + ++v6; + if ( v9 ) + CPrintString(*a4, (char *)v9, just); + *a4 += fontkern[v10] + 1; + v7 = *v6; + if ( !*v6 ) + break; + v8 = a3; + } + } +} + +//----- (004070F3) -------------------------------------------------------- +int __cdecl control_check_talk_btn() +{ + int v0; // ecx + int result; // eax + + if ( !talkflag ) + return 0; + if ( MouseX < 172 ) + return 0; + v0 = MouseY; + if ( MouseY < 421 || MouseX > 233 ) + return 0; + result = 0; + if ( MouseY <= 475 ) + { + talkbtndown[0] = 0; + talkbtndown[1] = 0; + talkbtndown[2] = 0; + talkbtndown[(v0 - 421) / 18] = 1; + result = 1; + } + return result; +} +// 4B8960: using guessed type int talkflag; + +//----- (0040714D) -------------------------------------------------------- +void __cdecl control_release_talk_btn() +{ + signed int v0; // ecx + int v1; // eax + signed int v2; // ecx + + if ( talkflag ) + { + v0 = MouseX; + talkbtndown[0] = 0; + talkbtndown[1] = 0; + talkbtndown[2] = 0; + if ( v0 >= 172 && MouseY >= 421 && v0 <= 233 && MouseY <= 475 ) + { + v1 = (MouseY - 421) / 18; + v2 = 0; + do + { + if ( v1 == -1 ) + break; + if ( v2 != myplr ) + --v1; + ++v2; + } + while ( v2 < 4 ); + if ( v2 <= 4 ) + tempstr[v2 + 255] = tempstr[v2 + 255] == 0; + } + } +} +// 4B8960: using guessed type int talkflag; + +//----- (004071C0) -------------------------------------------------------- +void __cdecl control_reset_talk_msg() +{ + int v0; // edi + signed int v1; // ecx + + v0 = 0; + v1 = 0; + do + { + if ( tempstr[v1 + 256] ) + v0 |= 1 << v1; + ++v1; + } + while ( v1 < 4 ); + if ( !msgcmd_check_set_event((int)sgszTalkMsg) ) + msg_init_msg(v0, sgszTalkMsg); +} + +//----- (004071FA) -------------------------------------------------------- +void __cdecl control_type_message() +{ + if ( gbMaxPlayers != 1 ) + { + sgszTalkMsg[0] = 0; + talkflag = 1; + frame = 1; + talkbtndown[0] = 0; + talkbtndown[1] = 0; + talkbtndown[2] = 0; + sgbPlrTalkTbl = 144; + force_redraw = 255; + sgbTalkSavePos = sgbNextTalkSave; + } +} +// 4B84CC: using guessed type char sgbNextTalkSave; +// 4B84CD: using guessed type char sgbTalkSavePos; +// 4B8840: using guessed type int sgbPlrTalkTbl; +// 4B8960: using guessed type int talkflag; +// 52571C: using guessed type int force_redraw; +// 679660: using guessed type char gbMaxPlayers; + +//----- (00407241) -------------------------------------------------------- +void __cdecl control_reset_talk() +{ + talkflag = 0; + sgbPlrTalkTbl = 0; + force_redraw = 255; +} +// 4B8840: using guessed type int sgbPlrTalkTbl; +// 4B8960: using guessed type int talkflag; +// 52571C: using guessed type int force_redraw; + +//----- (0040725A) -------------------------------------------------------- +int __fastcall control_talk_last_key(int a1) +{ + char v1; // bl + signed int v3; // eax + + v1 = a1; + if ( gbMaxPlayers == 1 || !talkflag || (unsigned int)a1 < 0x20 ) + return 0; + v3 = strlen(sgszTalkMsg); + if ( v3 < 78 ) + { + sgszTalkMsg[v3 + 1] = 0; + sgszTalkMsg[v3] = v1; + } + return 1; +} +// 4B8960: using guessed type int talkflag; +// 679660: using guessed type char gbMaxPlayers; + +//----- (0040729A) -------------------------------------------------------- +int __fastcall control_presskeys(int a1) +{ + signed int v1; // eax + char v2; // cl + + if ( gbMaxPlayers != 1 && talkflag ) + { + switch ( a1 ) + { + case VK_SPACE: + return 1; + case VK_ESCAPE: + control_reset_talk(); + return 1; + case VK_RETURN: + control_press_enter(); + return 1; + case VK_BACK: + v1 = strlen(sgszTalkMsg); + if ( v1 > 0 ) + *((_BYTE *)&chrbtnactive + v1 + 3) = 0; + return 1; + case VK_DOWN: + v2 = 1; +LABEL_15: + control_up_down(v2); + return 1; + case VK_UP: + v2 = -1; + goto LABEL_15; + } + } + return 0; +} +// 4B87A8: using guessed type int chrbtnactive; +// 4B8960: using guessed type int talkflag; +// 679660: using guessed type char gbMaxPlayers; + +//----- (00407304) -------------------------------------------------------- +void __cdecl control_press_enter() +{ + signed int v0; // esi + char (*v1)[80]; // ebp + char v2; // al + int v3; // ecx + char *v4; // ebp + + if ( sgszTalkMsg[0] ) + { + control_reset_talk_msg(); + v0 = 0; + v1 = sgszTalkSave; + do + { + if ( !strcmp((const char *)v1, sgszTalkMsg) ) + break; + ++v1; + ++v0; + } + while ( (signed int)v1 < (signed int)&dropGoldValue ); + if ( v0 < 8 ) + { + v2 = sgbNextTalkSave; + v3 = (sgbNextTalkSave - 1) & 7; + if ( v0 != v3 ) + { + v4 = sgszTalkSave[v3]; + strcpy(sgszTalkSave[v0], sgszTalkSave[v3]); + strcpy(v4, sgszTalkMsg); + v2 = sgbNextTalkSave; + } + } + else + { + strcpy(sgszTalkSave[(unsigned char)sgbNextTalkSave], sgszTalkMsg); + v2 = (sgbNextTalkSave + 1) & 7; + sgbNextTalkSave = (sgbNextTalkSave + 1) & 7; + } + sgszTalkMsg[0] = 0; + sgbTalkSavePos = v2; + } + control_reset_talk(); +} +// 4B84CC: using guessed type char sgbNextTalkSave; +// 4B84CD: using guessed type char sgbTalkSavePos; + +//----- (004073C2) -------------------------------------------------------- +void __fastcall control_up_down(char a1) +{ + unsigned char v1; // al + int v2; // esi + + v1 = sgbTalkSavePos; + v2 = 0; + while ( 1 ) + { + v1 = (a1 + v1) & 7; + sgbTalkSavePos = v1; + if ( sgszTalkSave[v1][0] ) + break; + if ( ++v2 >= 8 ) + return; + } + strcpy(sgszTalkMsg, sgszTalkSave[v1]); +} +// 4B84CD: using guessed type char sgbTalkSavePos; + +//----- (0040740A) -------------------------------------------------------- +void __cdecl InitCursor() +{ + pCursCels = LoadFileInMem("Data\\Inv\\Objcurs.CEL", 0); + ClearCursor(); +} + +//----- (00407420) -------------------------------------------------------- +void __cdecl FreeCursor() +{ + void *v0; // ecx + + v0 = pCursCels; + pCursCels = 0; + mem_free_dbg(v0); + ClearCursor(); +} + +//----- (00407437) -------------------------------------------------------- +void __fastcall SetICursor(int i) +{ + int v1; // ecx + + v1 = i; + icursW = InvItemWidth[v1]; + icursH = InvItemHeight[v1]; + icursW28 = icursW / 28; + icursH28 = icursH / 28; +} +// 4B8CB4: using guessed type int icursH; +// 4B8CBC: using guessed type int icursW; + +//----- (0040746B) -------------------------------------------------------- +void __fastcall SetCursor(int i) +{ + int v1; // eax + + v1 = InvItemWidth[i]; + pcurs = i; + cursW = v1; + cursH = InvItemHeight[i]; + SetICursor(i); +} +// 4B8C9C: using guessed type int cursH; + +//----- (00407493) -------------------------------------------------------- +void __cdecl InitLevelCursor() +{ + SetCursor(1); + cursmx = ViewX; + cursmy = ViewY; + dword_4B8CCC = -1; + *(_DWORD *)&pcursmonst = -1; + pcursobj = -1; + pcursitem = -1; + pcursplr = -1; + ClearCursor(); +} +// 4B8CC0: using guessed type char pcursitem; +// 4B8CC1: using guessed type char pcursobj; +// 4B8CC2: using guessed type char pcursplr; +// 4B8CCC: using guessed type int dword_4B8CCC; + +//----- (004074D0) -------------------------------------------------------- +void __cdecl CheckTown() +{ + int v0; // ecx + int v1; // eax + int v2; // esi + int v3; // edx + int v4; // ebx + int v5; // [esp+0h] [ebp-4h] + + v5 = 0; + if ( nummissiles > 0 ) + { + v0 = cursmx; + v1 = cursmy; + do + { + v2 = missileactive[v5]; + if ( missile[v2]._mitype == 10 ) + { + if ( (v3 = missile[v2]._mix, v4 = v3 - 1, v0 == v3 - 1) && v1 == missile[v2]._miy + || v0 == v3 && v1 == missile[v2]._miy - 1 + || v0 == v4 && v1 == missile[v2]._miy - 1 + || v0 == v3 - 2 && (v1 == missile[v2]._miy - 1 || v0 == v3 - 2 && v1 == missile[v2]._miy - 2) + || v0 == v4 && v1 == missile[v2]._miy - 2 + || v0 == v3 && v1 == missile[v2]._miy ) + { + trigflag[3] = 1; + ClearPanel(); + strcpy(infostr, "Town Portal"); + sprintf(tempstr, "from %s", plr[missile[v2]._misource]._pName); + AddPanelString(tempstr, 1); + v0 = missile[v2]._mix; + v1 = missile[v2]._miy; + cursmx = missile[v2]._mix; + cursmy = v1; + } + } + ++v5; + } + while ( v5 < nummissiles ); + } +} + +//----- (004075FD) -------------------------------------------------------- +void __cdecl CheckRportal() +{ + int v0; // ecx + int v1; // eax + int v2; // esi + int v3; // edx + int v4; // ebx + int v5; // [esp+0h] [ebp-4h] + + v5 = 0; + if ( nummissiles > 0 ) + { + v0 = cursmx; + v1 = cursmy; + do + { + v2 = missileactive[v5]; + if ( missile[v2]._mitype == 65 ) + { + if ( (v3 = missile[v2]._mix, v4 = v3 - 1, v0 == v3 - 1) && v1 == missile[v2]._miy + || v0 == v3 && v1 == missile[v2]._miy - 1 + || v0 == v4 && v1 == missile[v2]._miy - 1 + || v0 == v3 - 2 && (v1 == missile[v2]._miy - 1 || v0 == v3 - 2 && v1 == missile[v2]._miy - 2) + || v0 == v4 && v1 == missile[v2]._miy - 2 + || v0 == v3 && v1 == missile[v2]._miy ) + { + trigflag[3] = 1; + ClearPanel(); + strcpy(infostr, "Portal to"); + if ( setlevel ) + strcpy(tempstr, "level 15"); + else + strcpy(tempstr, "The Unholy Altar"); + AddPanelString(tempstr, 1); + v0 = missile[v2]._mix; + v1 = missile[v2]._miy; + cursmx = missile[v2]._mix; + cursmy = v1; + } + } + ++v5; + } + while ( v5 < nummissiles ); + } +} +// 5CF31D: using guessed type char setlevel; + +//----- (00407729) -------------------------------------------------------- +void __cdecl CheckCursMove() +{ + int v0; // esi + signed int v1; // edi + int v2; // esi + int v3; // edi + int v4; // edx + int v5; // ebx + int v6; // edi + int v7; // eax + int v8; // esi + BOOL v9; // eax + int v10; // ecx + int v11; // edx + int v12; // ecx + int v13; // ebx + int v14; // ebx + int v15; // eax + bool v16; // zf + int v17; // ecx + int v18; // eax + int v19; // ecx + int v20; // eax + int v21; // ecx + int v22; // eax + int v23; // eax + int v24; // ecx + int v25; // eax + int v26; // ecx + int v27; // ebx + int v28; // edx + int v29; // eax + int v30; // ecx + int v31; // eax + int v32; // eax + int v33; // eax + int v34; // ecx + int v35; // eax + int v36; // ecx + int v37; // eax + int v38; // eax + int v39; // ecx + int v40; // eax + int v41; // ecx + signed int v42; // eax + int v43; // ecx + int v44; // eax + int v45; // eax + int v46; // eax + int v47; // eax + char v48; // al + char v49; // cl + char v50; // al + char v51; // al + char v52; // cl + int v53; // ecx + int *v54; // eax + int v55; // edx + int *v56; // ecx + char v57; // al + char v58; // cl + signed int v59; // edx + char v60; // al + char v61; // cl + char v62; // al + char v63; // al + char v64; // cl + char v65; // al + char v66; // al + char v67; // cl + char v68; // al + char v69; // al + char v70; // al + char v71; // al + char v72; // al + char v73; // cl + char v74; // al + char v75; // al + int v76; // [esp+Ch] [ebp-18h] + char *v77; // [esp+Ch] [ebp-18h] + int v78; // [esp+10h] [ebp-14h] + signed int v79; // [esp+14h] [ebp-10h] + signed int v80; // [esp+18h] [ebp-Ch] + int v81; // [esp+1Ch] [ebp-8h] + int v82; // [esp+1Ch] [ebp-8h] + signed int v83; // [esp+20h] [ebp-4h] + + v0 = MouseX; + v1 = MouseY; + if ( chrflag || questlog ) + { + if ( MouseX >= 160 ) + { + v0 = MouseX - 160; + goto LABEL_10; + } + goto LABEL_9; + } + if ( invflag || sbookflag ) + { + if ( MouseX <= 320 ) + { + v0 = MouseX + 160; + goto LABEL_10; + } +LABEL_9: + v0 = 0; + } +LABEL_10: + if ( MouseY > 351 && track_isscrolling() ) + v1 = 351; + if ( !zoomflag ) + { + v0 >>= 1; + v1 >>= 1; + } + v2 = v0 - ScrollInfo._sxoff; + v3 = v1 - ScrollInfo._syoff; + if ( ScrollInfo._sdir ) + { + v2 += ((plr[myplr]._pVar6 + plr[myplr]._pxvel) >> 8) - (plr[myplr]._pVar6 >> 8); + v3 += ((plr[myplr]._pVar7 + plr[myplr]._pyvel) >> 8) - (plr[myplr]._pVar7 >> 8); + } + if ( v2 < 0 ) + v2 = 0; + if ( v2 >= 640 ) + v2 = 640; + if ( v3 < 0 ) + v3 = 0; + if ( v3 >= 480 ) + v3 = 480; + v4 = v3 >> 5; + v5 = v3 & 0x1F; + v76 = v2 & 0x3F; + v6 = (v2 >> 6) + (v3 >> 5) + ViewX - (zoomflag != 0 ? 10 : 5); + v7 = v76 >> 1; + v8 = v4 + ViewY - (v2 >> 6); + if ( v5 < v76 >> 1 ) + --v8; + v9 = v5 >= 32 - v7; + if ( v9 ) + ++v6; + if ( v6 < 0 ) + v6 = 0; + if ( v6 >= 112 ) + v6 = 111; + if ( v8 < 0 ) + v8 = 0; + if ( v8 >= 112 ) + v8 = 111; + if ( v5 >= v76 >> 1 ) + { + if ( !v9 ) + goto LABEL_49; + goto LABEL_48; + } + if ( !v9 ) + { +LABEL_48: + if ( v76 < 32 ) + goto LABEL_39; +LABEL_49: + v83 = 0; + goto LABEL_40; + } +LABEL_39: + v83 = 1; +LABEL_40: + v10 = *(_DWORD *)&pcursmonst; + pcursobj = -1; + pcursitem = -1; + v11 = -1; + dword_4B8CCC = *(_DWORD *)&pcursmonst; + *(_DWORD *)&pcursmonst = -1; + if ( pcursinvitem != -1 ) + drawsbarflag = 1; + pcursinvitem = -1; + pcursplr = -1; + v16 = plr[myplr]._pInvincible == 0; + uitemflag = 0; + panelflag = 0; + trigflag[3] = 0; + if ( !v16 ) + return; + if ( pcurs >= CURSOR_FIRSTITEM || spselflag ) + { + cursmx = v6; + cursmy = v8; + return; + } + if ( MouseY > 352 ) + { + CheckPanelInfo(); + return; + } + if ( doomflag ) + return; + if ( invflag && MouseX > 320 ) + { + pcursinvitem = CheckInvHLight(); + return; + } + if ( sbookflag && MouseX > 320 || (chrflag || questlog) && MouseX < 320 ) + return; + if ( !leveltype ) + { + if ( v83 ) + { + v27 = 112 * v6; + v78 = 112 * v6; + v43 = 112 * v6 + v8; + v45 = dMonster[0][v43 + 1]; + if ( v45 <= 0 ) + goto LABEL_200; + v11 = v45 - 1; + cursmx = v6; + cursmy = v8 + 1; + } + else + { + v27 = 112 * v6; + v78 = 112 * v6; + v43 = 112 * v6 + v8; + v44 = dMonster[1][v43]; + if ( v44 <= 0 ) + goto LABEL_200; + v11 = v44 - 1; + cursmx = v6 + 1; + cursmy = v8; + } + *(_DWORD *)&pcursmonst = v11; +LABEL_200: + v46 = dMonster[0][v43]; + if ( v46 > 0 ) + { + v11 = v46 - 1; + cursmx = v6; + *(_DWORD *)&pcursmonst = v46 - 1; + cursmy = v8; + } + v47 = dMonster[1][v43 + 1]; + if ( v47 > 0 ) + { + v11 = v47 - 1; + cursmx = v6 + 1; + *(_DWORD *)&pcursmonst = v47 - 1; + cursmy = v8 + 1; + } + if ( !towner[v11]._tSelFlag ) +LABEL_205: + *(_DWORD *)&pcursmonst = -1; +LABEL_206: + if ( *(_DWORD *)&pcursmonst != -1 ) + { +LABEL_305: + v59 = *(_DWORD *)&pcursmonst; + goto LABEL_306; + } +LABEL_207: + if ( v83 ) + { + v50 = dPlayer[0][v27 + 1 + v8]; + if ( v50 ) + { + v49 = v50 <= 0 ? -1 - v50 : v50 - 1; + if ( v49 != myplr && plr[v49]._pHitPoints ) + { + cursmx = v6; + cursmy = v8 + 1; + goto LABEL_222; + } + } + } + else + { + v48 = dPlayer[1][v27 + v8]; + if ( v48 ) + { + v49 = v48 <= 0 ? -1 - v48 : v48 - 1; + if ( v49 != myplr && plr[v49]._pHitPoints ) + { + cursmy = v8; + cursmx = v6 + 1; +LABEL_222: + pcursplr = v49; + goto LABEL_223; + } + } + } +LABEL_223: + v51 = dPlayer[0][v27 + v8]; + if ( v51 ) + { + v52 = v51 <= 0 ? -1 - v51 : v51 - 1; + if ( v52 != myplr ) + { + cursmx = v6; + cursmy = v8; + pcursplr = v52; + } + } + if ( dFlags[0][v27 + v8] & 4 ) + { + v53 = 0; + v54 = &plr[0].WorldY; + do + { + if ( *(v54 - 1) == v6 && *v54 == v8 && v53 != myplr ) + { + cursmx = v6; + cursmy = v8; + pcursplr = v53; + } + v54 += 5430; + ++v53; + } + while ( (signed int)v54 < (signed int)&plr_msgs[0].msg[7] ); + } + if ( pcurs == CURSOR_RESURRECT ) + { + v79 = -1; + v77 = &nBlockTable[v27 + 1944 + v8]; + do + { + v80 = -1; + v55 = v8 - 1; + do + { + if ( v77[v80] & 4 ) + { + v82 = 0; + v56 = &plr[0].WorldY; + do + { + if ( *(v56 - 1) == v6 + v79 && *v56 == v55 && v82 != myplr ) + { + cursmx = v6 + v79; + cursmy = v55; + pcursplr = v82; + } + ++v82; + v56 += 5430; + } + while ( (signed int)v56 < (signed int)&plr_msgs[0].msg[7] ); + } + ++v80; + ++v55; + } + while ( v80 < 2 ); + ++v79; + v77 += 112; + } + while ( v79 < 2 ); + v27 = v78; + } + v57 = dPlayer[1][v27 + 1 + v8]; + if ( v57 ) + { + v58 = v57 <= 0 ? -1 - v57 : v57 - 1; + if ( v58 != myplr && plr[v58]._pHitPoints ) + { + pcursplr = v58; + cursmx = v6 + 1; + cursmy = v8 + 1; + } + } + v59 = *(_DWORD *)&pcursmonst; + if ( *(_DWORD *)&pcursmonst != -1 ) + { +LABEL_285: + if ( pcursplr == -1 ) + goto LABEL_286; +LABEL_306: + if ( pcurs == CURSOR_IDENTIFY ) + { + pcursobj = -1; + v59 = -1; + pcursitem = -1; + *(_DWORD *)&pcursmonst = -1; + cursmx = v6; + cursmy = v8; + } + if ( v59 != -1 ) + { + if ( monster[v59]._mFlags & 0x20 ) + *(_DWORD *)&pcursmonst = -1; + } + return; + } + if ( pcursplr != (_BYTE)pcursmonst ) + goto LABEL_306; + if ( v83 ) + { + v62 = dObject[0][v27 + 1 + v8]; + if ( !v62 ) + goto LABEL_272; + v61 = v62 <= 0 ? -1 - v62 : v62 - 1; + if ( SLOBYTE(object[v61]._oSelFlag) < 2 ) + goto LABEL_272; + cursmx = v6; + cursmy = v8 + 1; + } + else + { + v60 = dObject[1][v27 + v8]; + if ( !v60 ) + goto LABEL_272; + v61 = v60 <= 0 ? -1 - v60 : v60 - 1; + if ( SLOBYTE(object[v61]._oSelFlag) < 2 ) + goto LABEL_272; + cursmy = v8; + cursmx = v6 + 1; + } + pcursobj = v61; +LABEL_272: + v63 = dObject[0][v27 + v8]; + if ( v63 ) + { + v64 = v63 <= 0 ? -1 - v63 : v63 - 1; + v65 = object[v64]._oSelFlag; + if ( v65 == 1 || v65 == 3 ) + { + cursmx = v6; + cursmy = v8; + pcursobj = v64; + } + } + v66 = dObject[1][v27 + 1 + v8]; + if ( !v66 || (v66 <= 0 ? (v67 = -1 - v66) : (v67 = v66 - 1), SLOBYTE(object[v67]._oSelFlag) < 2) ) + { +LABEL_286: + if ( pcursobj != -1 || *(_DWORD *)&pcursmonst != -1 ) + goto LABEL_306; + if ( v83 ) + { + v70 = dItem[0][v27 + 1 + v8]; + if ( v70 <= 0 ) + goto LABEL_296; + v69 = v70 - 1; + if ( items[v69]._iSelFlag < 2 ) + goto LABEL_296; + cursmx = v6; + cursmy = v8 + 1; + } + else + { + v68 = dItem[1][v27 + v8]; + if ( v68 <= 0 ) + goto LABEL_296; + v69 = v68 - 1; + if ( items[v69]._iSelFlag < 2 ) + goto LABEL_296; + cursmy = v8; + cursmx = v6 + 1; + } + pcursitem = v69; +LABEL_296: + v71 = dItem[0][v27 + v8]; + if ( v71 > 0 ) + { + v72 = v71 - 1; + v73 = items[v72]._iSelFlag; + if ( v73 == 1 || v73 == 3 ) + { + cursmx = v6; + cursmy = v8; + pcursitem = v72; + } + } + v74 = dItem[1][v27 + 1 + v8]; + if ( v74 > 0 ) + { + v75 = v74 - 1; + if ( items[v75]._iSelFlag >= 2 ) + { + pcursitem = v75; + cursmx = v6 + 1; + cursmy = v8 + 1; + } + } + if ( pcursitem != -1 ) + goto LABEL_306; + cursmx = v6; + cursmy = v8; + CheckTrigForce(); + CheckTown(); + CheckRportal(); + goto LABEL_305; + } + pcursobj = v67; + cursmx = v6 + 1; + cursmy = v8 + 1; + goto LABEL_285; + } + if ( v10 == -1 ) + goto LABEL_128; + v12 = 112 * v6 + v8; + v81 = 112 * v6 + v8; + v13 = 112 * v6 + v8; + if ( v83 ) + { + v14 = v13; + v15 = dMonster[1][v14 + 2]; + if ( !v15 ) + goto LABEL_74; + v16 = (dFlags[1][v12 + 2] & 0x40) == 0; + } + else + { + v14 = v13; + v15 = dMonster[2][v14 + 1]; + if ( !v15 ) + goto LABEL_74; + v16 = (dFlags[2][v12 + 1] & 0x40) == 0; + } + if ( !v16 ) + { + v17 = v15 <= 0 ? -1 - v15 : v15 - 1; + if ( v17 == dword_4B8CCC + && (signed int)(monster[v17]._mhitpoints & 0xFFFFFFC0) > 0 + && monster[v17].MData->mSelFlag & 4 ) + { + v11 = v17; + cursmx = v6 + 1; + cursmy = v8 + 2; + *(_DWORD *)&pcursmonst = v17; + } + } +LABEL_74: + v18 = dMonster[2][v14 + 2]; + if ( v18 && dFlags[2][v81 + 2] & 0x40 ) + { + v19 = v18 <= 0 ? -1 - v18 : v18 - 1; + if ( v19 == dword_4B8CCC + && (signed int)(monster[v19]._mhitpoints & 0xFFFFFFC0) > 0 + && monster[v19].MData->mSelFlag & 4 ) + { + v11 = v19; + cursmx = v6 + 2; + cursmy = v8 + 2; + *(_DWORD *)&pcursmonst = v19; + } + } + if ( v83 ) + { + v22 = dMonster[0][v14 + 1]; + if ( v22 && dFlags[0][v81 + 1] & 0x40 ) + { + v21 = v22 <= 0 ? -1 - v22 : v22 - 1; + if ( v21 == dword_4B8CCC + && (signed int)(monster[v21]._mhitpoints & 0xFFFFFFC0) > 0 + && monster[v21].MData->mSelFlag & 2 ) + { + cursmx = v6; + cursmy = v8 + 1; + goto LABEL_102; + } + } + } + else + { + v20 = dMonster[1][v14]; + if ( v20 && dFlags[1][v81] & 0x40 ) + { + v21 = v20 <= 0 ? -1 - v20 : v20 - 1; + if ( v21 == dword_4B8CCC + && (signed int)(monster[v21]._mhitpoints & 0xFFFFFFC0) > 0 + && monster[v21].MData->mSelFlag & 2 ) + { + cursmy = v8; + cursmx = v6 + 1; +LABEL_102: + v11 = v21; + *(_DWORD *)&pcursmonst = v21; + goto LABEL_103; + } + } + } +LABEL_103: + v23 = dMonster[0][v14]; + if ( v23 && dFlags[0][v81] & 0x40 ) + { + v24 = v23 <= 0 ? -1 - v23 : v23 - 1; + if ( v24 == dword_4B8CCC + && (signed int)(monster[v24]._mhitpoints & 0xFFFFFFC0) > 0 + && monster[v24].MData->mSelFlag & 1 ) + { + v11 = v24; + cursmx = v6; + cursmy = v8; + *(_DWORD *)&pcursmonst = v24; + } + } + v25 = dMonster[1][v14 + 1]; + if ( v25 && dFlags[1][v81 + 1] & 0x40 ) + { + v26 = v25 <= 0 ? -1 - v25 : v25 - 1; + if ( v26 == dword_4B8CCC + && (signed int)(monster[v26]._mhitpoints & 0xFFFFFFC0) > 0 + && monster[v26].MData->mSelFlag & 2 ) + { + v11 = v26; + cursmx = v6 + 1; + cursmy = v8 + 1; + *(_DWORD *)&pcursmonst = v26; + } + } + if ( v11 == -1 ) + goto LABEL_128; + if ( monster[v11]._mFlags & 1 ) + { + v11 = -1; + cursmx = v6; + *(_DWORD *)&pcursmonst = -1; + cursmy = v8; + } + if ( v11 == -1 ) + goto LABEL_128; + if ( monster[v11]._mFlags & 0x20 ) + { + v11 = -1; + *(_DWORD *)&pcursmonst = -1; + } + if ( v11 == -1 ) + { +LABEL_128: + v27 = 112 * v6; + v78 = 112 * v6; + if ( v83 ) + { + v28 = v27 + v8; + v32 = dMonster[1][v28 + 2]; + if ( v32 && dFlags[1][v27 + 2 + v8] & 0x40 ) + { + v30 = v32 <= 0 ? -1 - v32 : v32 - 1; + if ( (signed int)(monster[v30]._mhitpoints & 0xFFFFFFC0) > 0 && monster[v30].MData->mSelFlag & 4 ) + { + cursmx = v6 + 1; + v31 = v8 + 2; + goto LABEL_145; + } + } + } + else + { + v28 = v27 + v8; + v29 = dMonster[2][v28 + 1]; + if ( v29 && dFlags[2][v27 + 1 + v8] & 0x40 ) + { + v30 = v29 <= 0 ? -1 - v29 : v29 - 1; + if ( (signed int)(monster[v30]._mhitpoints & 0xFFFFFFC0) > 0 && monster[v30].MData->mSelFlag & 4 ) + { + cursmx = v6 + 2; + v31 = v8 + 1; +LABEL_145: + cursmy = v31; + *(_DWORD *)&pcursmonst = v30; + goto LABEL_146; + } + } + } +LABEL_146: + v33 = dMonster[2][v28 + 2]; + if ( v33 && dFlags[2][v27 + 2 + v8] & 0x40 ) + { + v34 = v33 <= 0 ? -1 - v33 : v33 - 1; + if ( (signed int)(monster[v34]._mhitpoints & 0xFFFFFFC0) > 0 && monster[v34].MData->mSelFlag & 4 ) + { + *(_DWORD *)&pcursmonst = v34; + cursmx = v6 + 2; + cursmy = v8 + 2; + } + } + if ( v83 ) + { + v37 = dMonster[0][v28 + 1]; + if ( v37 && dFlags[0][v27 + 1 + v8] & 0x40 ) + { + v36 = v37 <= 0 ? -1 - v37 : v37 - 1; + if ( (signed int)(monster[v36]._mhitpoints & 0xFFFFFFC0) > 0 && monster[v36].MData->mSelFlag & 2 ) + { + cursmx = v6; + cursmy = v8 + 1; + goto LABEL_171; + } + } + } + else + { + v35 = dMonster[1][v28]; + if ( v35 && dFlags[1][v27 + v8] & 0x40 ) + { + v36 = v35 <= 0 ? -1 - v35 : v35 - 1; + if ( (signed int)(monster[v36]._mhitpoints & 0xFFFFFFC0) > 0 && monster[v36].MData->mSelFlag & 2 ) + { + cursmy = v8; + cursmx = v6 + 1; +LABEL_171: + *(_DWORD *)&pcursmonst = v36; + goto LABEL_172; + } + } + } +LABEL_172: + v38 = dMonster[0][v28]; + if ( v38 && dFlags[0][v27 + v8] & 0x40 ) + { + v39 = v38 <= 0 ? -1 - v38 : v38 - 1; + if ( (signed int)(monster[v39]._mhitpoints & 0xFFFFFFC0) > 0 && monster[v39].MData->mSelFlag & 1 ) + { + cursmx = v6; + cursmy = v8; + *(_DWORD *)&pcursmonst = v39; + } + } + v40 = dMonster[1][v28 + 1]; + if ( v40 && dFlags[1][v27 + 1 + v8] & 0x40 ) + { + v41 = v40 <= 0 ? -1 - v40 : v40 - 1; + if ( (signed int)(monster[v41]._mhitpoints & 0xFFFFFFC0) > 0 && monster[v41].MData->mSelFlag & 2 ) + { + *(_DWORD *)&pcursmonst = v41; + cursmx = v6 + 1; + cursmy = v8 + 1; + } + } + v42 = *(_DWORD *)&pcursmonst; + if ( *(_DWORD *)&pcursmonst == -1 ) + goto LABEL_207; + if ( monster[*(_DWORD *)&pcursmonst]._mFlags & 1 ) + { + v42 = -1; + cursmx = v6; + *(_DWORD *)&pcursmonst = -1; + cursmy = v8; + } + if ( v42 == -1 ) + goto LABEL_207; + if ( monster[v42]._mFlags & 0x20 ) + goto LABEL_205; + goto LABEL_206; + } +} +// 4B8968: using guessed type int sbookflag; +// 4B8B84: using guessed type int panelflag; +// 4B8C98: using guessed type int spselflag; +// 4B8CB8: using guessed type char pcursinvitem; +// 4B8CC0: using guessed type char pcursitem; +// 4B8CC1: using guessed type char pcursobj; +// 4B8CC2: using guessed type char pcursplr; +// 4B8CCC: using guessed type int dword_4B8CCC; +// 52569C: using guessed type int zoomflag; +// 52575C: using guessed type int doomflag; +// 5BB1ED: using guessed type char leveltype; +// 69BD04: using guessed type int questlog; + +//----- (004084A6) -------------------------------------------------------- +void __cdecl InitDead() +{ + int v0; // ebx + int *v1; // edx + int *v2; // eax + int v3; // ecx + int v4; // edx + int v5; // eax + int v6; // edx + int v7; // esi + int *v8; // eax + int v9; // edx + CMonster *v10; // ecx + char *v11; // edi + int *v12; // ebx + int mtypes[200]; // [esp+Ch] [ebp-330h] + int *v14; // [esp+32Ch] [ebp-10h] + int *v15; // [esp+330h] [ebp-Ch] + int v16; // [esp+334h] [ebp-8h] + int v17; // [esp+338h] [ebp-4h] + + memset(mtypes, 0, sizeof(mtypes)); + v0 = 0; + if ( nummtypes > 0 ) + { + v1 = &dead[0]._deadFrame; + v2 = &Monsters[0].Anims[4].Rate; + v17 = nummtypes; + do + { + v15 = &mtypes[*((unsigned char *)v2 - 216)]; + if ( !*v15 ) + { + qmemcpy(v1 - 8, v2 - 8, 0x20u); + v3 = *v2; + *((_BYTE *)v1 + 12) = 0; + *v1 = v3; + v1[1] = v2[21]; + v1[2] = v2[22]; + *((_BYTE *)v2 + 101) = ++v0; + v1 += 12; + *v15 = v0; + } + v2 += 82; + --v17; + } + while ( v17 ); + } + v16 = 0; + v4 = v0; + memset(&dead[v0], misfiledata[16].mAnimCel[0], 8u); + _LOBYTE(dead[v4]._deadtrans) = 0; + dead[v4]._deadFrame = 8; + v5 = misfiledata[18].mAnimCel[0]; + dead[v4].field_24 = 128; + dead[v4].field_28 = 32; + v6 = v0 + 1; + spurtndx = v0 + 1; + memset(&dead[v6], v5, 8u); + _LOBYTE(dead[v6]._deadtrans) = 0; + stonendx = v0 + 2; + v7 = nummonsters; + dead[v6]._deadFrame = 12; + dead[v6].field_24 = 128; + dead[v6].field_28 = 32; + v17 = v0 + 2; + if ( v7 > 0 ) + { + v8 = &dead[v0 + 2]._deadFrame; + do + { + v9 = monstactive[v16]; + if ( monster[v9]._uniqtype ) + { + v10 = monster[v9].MType; + v11 = (char *)(v8 - 8); + v15 = (int *)8; + v14 = &v10->Anims[4].Frames[1]; + do + { + v12 = v14; + ++v14; + *(_DWORD *)v11 = *v12; + v11 += 4; + v15 = (int *)((char *)v15 - 1); + } + while ( v15 ); + *v8 = v10->Anims[4].Rate; + v8[1] = v10->flags_1; + v8[2] = v10->flags_2; + *((_BYTE *)v8 + 12) = monster[v9]._uniqtrans + 4; + monster[v9]._udeadval = ++v17; + v8 += 12; + } + ++v16; + } + while ( v16 < v7 ); + } +} +// 4B8CD8: using guessed type int spurtndx; + +//----- (0040865C) -------------------------------------------------------- +void __fastcall AddDead(int dx, int dy, char dv, direction ddir) +{ + dDead[dx][dy] = (dv & 0x1F) + 32 * ddir; +} + +//----- (0040867D) -------------------------------------------------------- +void __cdecl SetDead() +{ + int v0; // eax + int v1; // esi + int v2; // ebp + char (*v3)[112]; // ebx + int v4; // edi + int i; // [esp+0h] [ebp-4h] + + v0 = 0; + for ( i = 0; i < nummonsters; ++i ) + { + v1 = monstactive[v0]; + if ( monster[v1]._uniqtype ) + { + v2 = 0; + v3 = dDead; + do + { + v4 = 0; + do + { + if ( ((*v3)[v4] & 0x1F) == monster[v1]._udeadval ) + ChangeLightXY((unsigned char)monster[v1].mlid, v2, v4); + ++v4; + } + while ( v4 < 112 ); + ++v3; + ++v2; + } + while ( (signed int)v3 < (signed int)dpiece_defs_map_1 ); + } + v0 = i + 1; + } +} + +//----- (004086F4) -------------------------------------------------------- +void __cdecl LoadDebugGFX() +{ + if ( visiondebug ) + pSquareCel = LoadFileInMem("Data\\Square.CEL", 0); +} +// 525720: using guessed type int visiondebug; + +//----- (0040870F) -------------------------------------------------------- +void __cdecl FreeDebug() +{ + void *v0; // ecx + + v0 = pSquareCel; + pSquareCel = 0; + mem_free_dbg(v0); +} + +//----- (00408721) -------------------------------------------------------- +void __cdecl CheckClearDbg() +{ + int v0; // esi + signed int v1; // ebx + int v2; // edi + char v3; // cl + int v4; // eax + int (*v5)[112]; // [esp+Ch] [ebp-8h] + int (*v6)[112]; // [esp+10h] [ebp-4h] + + v0 = 0; + v6 = dMonster; + do + { + v1 = 0; + v5 = v6; + v2 = v0; + do + { + if ( (*v5)[0] ) + TermMsg("Monsters not cleared"); + if ( dPlayer[0][v2] ) + TermMsg("Players not cleared"); + v3 = dFlags[0][v2]; + v4 = v1 + 112 * currlevel; + ++v5; + ++v1; + v2 += 112; + debug_dMonster[0][v4][v0] = v3 & 2; + debug_dflags[0][v4][v0] = v3 & 8; + } + while ( v1 < 112 ); + v6 = (int (*)[112])((char *)v6 + 4); + ++v0; + } + while ( (signed int)v6 < (signed int)dMonster[1] ); +} + +//----- (004087B6) -------------------------------------------------------- +void __cdecl diablo_cpp_init() +{ + diablo_cpp_init_value = diablo_inf; +} +// 479BF8: using guessed type int diablo_inf; +// 525514: using guessed type int diablo_cpp_init_value; + +//----- (004087C1) -------------------------------------------------------- +void __cdecl FreeGameMem() +{ + void *v0; // ecx + void *v1; // ecx + void *v2; // ecx + void *v3; // ecx + void *v4; // ecx + + music_stop(); + v0 = pDungeonCels; + pDungeonCels = 0; + mem_free_dbg(v0); + v1 = pMegaTiles; + pMegaTiles = 0; + mem_free_dbg(v1); + v2 = *(void **)&dpiece_defs[0].blocks; + *(_DWORD *)&dpiece_defs[0].blocks = 0; + mem_free_dbg(v2); + v3 = level_special_cel; + level_special_cel = 0; + mem_free_dbg(v3); + v4 = pSpeedCels; + pSpeedCels = 0; + mem_free_dbg(v4); + FreeMissiles(); + FreeMonsters(); + FreeObjectGFX(); + FreeEffects(); + FreeTownerGFX(); +} + +//----- (00408838) -------------------------------------------------------- +int __fastcall diablo_init_menu(int a1, int bSinglePlayer) +{ + int v2; // esi + int v3; // edi + interface_mode v4; // ecx + unsigned char pfExitProgram[4]; // [esp+Ch] [ebp-4h] + + v2 = bSinglePlayer; + v3 = a1; + byte_678640 = 1; + while ( 1 ) + { + *(_DWORD *)pfExitProgram = 0; + dword_5256E8 = 0; + if ( !NetInit(v2, (int *)pfExitProgram) ) + break; + byte_678640 = 0; + if ( (v3 || !*(_DWORD *)&gbValidSaveFile) + && (InitLevels(), InitQuests(), InitPortals(), InitDungMsgs(myplr), !*(_DWORD *)&gbValidSaveFile) + || (v4 = WM_DIABLOADGAME, !dword_5256E8) ) + { + v4 = WM_DIABNEWGAME; + } + run_game_loop(v4); + NetClose(); + pfile_create_player_description(0, 0); + if ( !gbRunGameResult ) + goto LABEL_11; + } + gbRunGameResult = *(_DWORD *)pfExitProgram == 0; +LABEL_11: + SNetDestroy(); + return gbRunGameResult; +} +// 525698: using guessed type int gbRunGameResult; +// 5256E8: using guessed type int dword_5256E8; +// 678640: using guessed type char byte_678640; + +//----- (004088E2) -------------------------------------------------------- +void __fastcall run_game_loop(int interface_mode) +{ + int v1; // esi + HANDLE v2; // eax + int v3; // eax + HANDLE v4; // eax + bool v5; // zf + int v6; // eax + signed int v7; // [esp+8h] [ebp-24h] + LRESULT (__stdcall *func)(HWND, UINT, WPARAM, LPARAM); // [esp+Ch] [ebp-20h] + struct tagMSG Msg; // [esp+10h] [ebp-1Ch] + + v1 = interface_mode; + nthread_ignore_mutex(1); + start_game(v1); + func = SetWindowProc(GM_Game); + control_update_life_mana(); + msg_process_net_packets(); + gbRunGame = 1; + gbProcessPlayers = 1; + gbRunGameResult = 1; + force_redraw = 255; + DrawAndBlit(); + PaletteFadeIn(8); + force_redraw = 255; + *(_DWORD *)&gbGameLoopStartup = 1; + nthread_ignore_mutex(0); + while ( gbRunGame ) + { + diablo_color_cyc_logic(); + if ( PeekMessageA(&Msg, 0, 0, 0, 0) ) + { + v2 = GetCurrentThread(); + SetThreadPriority(v2, 1); + while ( PeekMessageA(&Msg, 0, 0, 0, 1u) ) + { + if ( Msg.message == 18 ) + { + gbRunGameResult = 0; + gbRunGame = 0; + break; + } + TranslateMessage(&Msg); + DispatchMessageA(&Msg); + } + if ( !gbRunGame || (_LOBYTE(v3) = nthread_has_500ms_passed(), v7 = 1, !v3) ) + v7 = 0; + v4 = GetCurrentThread(); + SetThreadPriority(v4, 0); + v5 = v7 == 0; + } + else + { + _LOBYTE(v6) = nthread_has_500ms_passed(); + v5 = v6 == 0; + } + if ( !v5 ) + { + multi_process_network_packets(); + game_loop(gbGameLoopStartup); + msgcmd_send_chat(); + *(_DWORD *)&gbGameLoopStartup = 0; + DrawAndBlit(); + } + } + if ( (unsigned char)gbMaxPlayers > 1u ) + pfile_write_hero(); + pfile_flush_W(); + PaletteFadeOut(8); + SetCursor(0); + ClearScreenBuffer(); + force_redraw = 255; + scrollrt_455E65(1); + SetWindowProc(func); + free_game(); + if ( cineflag ) + { + cineflag = 0; + DoEnding(); + } +} +// 525650: using guessed type int gbRunGame; +// 525698: using guessed type int gbRunGameResult; +// 5256A0: using guessed type int gbProcessPlayers; +// 525718: using guessed type char cineflag; +// 52571C: using guessed type int force_redraw; +// 679660: using guessed type char gbMaxPlayers; + +//----- (00408A8C) -------------------------------------------------------- +void __fastcall start_game(int interface_mode) +{ + int v1; // esi + + cineflag = 0; + v1 = interface_mode; + zoomflag = 1; + InitCursor(); + InitLightTable(); + LoadDebugGFX(); + music_stop(); + ShowProgress(v1); + gmenu_init_menu(); + InitLevelCursor(); + sgnTimeoutCurs = 0; + sgbMouseDown = 0; + track_mouse_stance(0); +} +// 52569C: using guessed type int zoomflag; +// 525718: using guessed type char cineflag; +// 525748: using guessed type char sgbMouseDown; + +//----- (00408ADB) -------------------------------------------------------- +void __cdecl free_game() +{ + int v0; // esi + + FreeControlPan(); + FreeInvGFX(); + FreeGMenu(); + FreeQuestText(); + FreeStoreMem(); + v0 = 0; + do + FreePlayerGFX(v0++); + while ( v0 < 4 ); + FreeItemGFX(); + FreeCursor(); + FreeLightTable(); + FreeDebug(); + FreeGameMem(); +} + +//----- (00408B1E) -------------------------------------------------------- +bool __cdecl diablo_get_not_running() +{ + SetLastError(0); + CreateEventA(0, 0, 0, "DiabloEvent"); + return GetLastError() != ERROR_ALREADY_EXISTS; +} + +//----- (00408B4A) -------------------------------------------------------- +int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) +{ + HINSTANCE v4; // esi + int v5; // eax + int v6; // eax + unsigned int v7; // eax + int v8; // eax + int v9; // esi + int v10; // eax + int v11; // ecx + char Filename[260]; // [esp+8h] [ebp-10Ch] + char value_name[8]; // [esp+10Ch] [ebp-8h] + + v4 = hInstance; + diablo_reload_process(hInstance); + ::hInstance = v4; + _LOBYTE(v5) = RestrictedTest(); + if ( v5 ) + ErrDlg(TEMPLATE_ERR_RESTRICTED, 0, "C:\\Src\\Diablo\\Source\\DIABLO.CPP", 877); + _LOBYTE(v6) = ReadOnlyTest(); + if ( v6 ) + { + if ( !GetModuleFileNameA(::hInstance, Filename, 0x104u) ) + Filename[0] = 0; + DirErrDlg(Filename); + } + ShowCursor(0); + v7 = GetTickCount(); + srand(v7); + encrypt_init_lookup_table(); + exception_get_filter(); + _LOBYTE(v8) = diablo_get_not_running(); + v9 = v8; + if ( !diablo_find_window("DIABLO") && v9 ) + { + diablo_init_screen(); + diablo_parse_flags(lpCmdLine); + init_create_window(); + sound_init(); + UiInitialize(); + play_movie("gendata\\logo.smk", 1); + strcpy(value_name, "Intro"); + _LOBYTE(v10) = SRegLoadValue("Diablo", value_name, 0, (int *)&hInstance); + if ( !v10 ) + hInstance = (HINSTANCE)1; + if ( hInstance ) + play_movie("gendata\\diablo1.smk", 1); + SRegSaveValue("Diablo", value_name, 0, 0); + UiTitleDialog(7); + BlackPalette(); + mainmenu_action(v11); + UiDestroy(); + palette_save_gamme(); + if ( ghMainWnd ) + { + Sleep(0x12Cu); + DestroyWindow(ghMainWnd); + } + } + return 0; +} + +//----- (00408CB1) -------------------------------------------------------- +void __fastcall diablo_parse_flags(char *args) +{ + char *v1; // esi + int i; // eax + size_t v3; // eax + size_t v4; // eax + size_t v5; // eax + size_t v6; // eax + + v1 = args; + for ( _LOBYTE(i) = *args; *v1; _LOBYTE(i) = *v1 ) + { + for ( i = (char)i; isspace(i); i = *v1 ) + ++v1; + v3 = strlen("dd_emulate"); + if ( !_strnicmp("dd_emulate", v1, v3) ) + { + gbEmulate = 1; + v4 = strlen("dd_emulate"); + } + else + { + v5 = strlen("dd_backbuf"); + if ( !_strnicmp("dd_backbuf", v1, v5) ) + { + gbBackBuf = 1; + v4 = strlen("dd_backbuf"); + } + else + { + v6 = strlen("ds_noduplicates"); + if ( _strnicmp("ds_noduplicates", v1, v6) ) + { + tolower(*v1++); + continue; + } + gbDupSounds = 0; + v4 = strlen("ds_noduplicates"); + } + } + v1 += v4; + } +} +// 4A22D6: using guessed type char gbDupSounds; +// 52A548: using guessed type char gbBackBuf; +// 52A549: using guessed type char gbEmulate; + +//----- (00408D61) -------------------------------------------------------- +void __cdecl diablo_init_screen() +{ + int v0; // ecx + int *v1; // eax + + v0 = 0; + MouseX = 320; + MouseY = 240; + ScrollInfo._sdx = 0; + ScrollInfo._sdy = 0; + ScrollInfo._sxoff = 0; + ScrollInfo._syoff = 0; + ScrollInfo._sdir = 0; + v1 = screen_y_times_768; + do + { + *v1 = v0; + ++v1; + v0 += 768; + } + while ( (signed int)v1 < (signed int)&scrollrt_cpp_init_value ); + ClrDiabloMsg(); +} +// 69CEFC: using guessed type int scrollrt_cpp_init_value; + +//----- (00408DB1) -------------------------------------------------------- +HWND __fastcall diablo_find_window(LPCSTR lpClassName) +{ + HWND result; // eax + HWND v2; // esi + HWND v3; // eax + HWND v4; // edi + + result = FindWindowA(lpClassName, 0); + v2 = result; + if ( result ) + { + v3 = GetLastActivePopup(result); + if ( v3 ) + v2 = v3; + v4 = GetTopWindow(v2); + if ( !v4 ) + v4 = v2; + SetForegroundWindow(v2); + SetFocus(v4); + result = (HWND)1; + } + return result; +} + +//----- (00408DF4) -------------------------------------------------------- +void __fastcall diablo_reload_process(HMODULE hModule) +{ + char *i; // eax + DWORD v2; // esi + BOOL v3; // edi + _DWORD *v4; // eax + _DWORD *v5; // esi + HWND v6; // eax + char Name[276]; // [esp+Ch] [ebp-29Ch] + char Filename[260]; // [esp+120h] [ebp-188h] + struct _STARTUPINFOA StartupInfo; // [esp+224h] [ebp-84h] + struct _SYSTEM_INFO SystemInfo; // [esp+268h] [ebp-40h] + struct _PROCESS_INFORMATION ProcessInformation; // [esp+28Ch] [ebp-1Ch] + DWORD dwProcessId; // [esp+29Ch] [ebp-Ch] + HANDLE hFileMappingObject; // [esp+2A0h] [ebp-8h] + HWND hWnd; // [esp+2A4h] [ebp-4h] + + Filename[0] = empty_string; + memset(&Filename[1], 0, 0x100u); + *(_WORD *)&Filename[257] = 0; + Filename[259] = 0; + GetModuleFileNameA(hModule, Filename, 0x104u); + wsprintfA(Name, "Reload-%s", Filename); + for ( i = Name; *i; ++i ) + { + if ( *i == '\\' ) + *i = '/'; + } + GetSystemInfo(&SystemInfo); + v2 = SystemInfo.dwPageSize; + if ( SystemInfo.dwPageSize < 0x1000 ) + v2 = 4096; + hFileMappingObject = CreateFileMappingA((HANDLE)0xFFFFFFFF, 0, 0x8000004u, 0, v2, Name); + v3 = GetLastError() != ERROR_ALREADY_EXISTS; + if ( hFileMappingObject ) + { + v4 = (unsigned int *)MapViewOfFile(hFileMappingObject, 0xF001Fu, 0, 0, v2); + v5 = v4; + if ( v4 ) + { + if ( v3 ) + { + *v4 = -1; + v4[1] = 0; + memset(&StartupInfo, 0, 0x44u); + StartupInfo.cb = 68; + CreateProcessA(Filename, 0, 0, 0, 0, 0x200u, 0, 0, &StartupInfo, &ProcessInformation); + WaitForInputIdle(ProcessInformation.hProcess, 0xFFFFFFFF); + CloseHandle(ProcessInformation.hThread); + CloseHandle(ProcessInformation.hProcess); + while ( *v5 < 0 ) + Sleep(0x3E8u); + UnmapViewOfFile(v5); + CloseHandle(hFileMappingObject); + ExitProcess(0); + } + if ( InterlockedIncrement((long *)v4) ) + { + v6 = GetForegroundWindow(); + do + { + hWnd = v6; + v6 = GetWindow(v6, 3u); + } + while ( v6 ); + while ( 1 ) + { + GetWindowThreadProcessId(hWnd, &dwProcessId); + if ( dwProcessId == v5[1] ) + break; + hWnd = GetWindow(hWnd, 2u); + if ( !hWnd ) + goto LABEL_23; + } + SetForegroundWindow(hWnd); +LABEL_23: + UnmapViewOfFile(v5); + CloseHandle(hFileMappingObject); + ExitProcess(0); + } + v5[1] = GetCurrentProcessId(); + } + } +} + +//----- (00408FCF) -------------------------------------------------------- +int __cdecl PressEscKey() +{ + int result; // eax + + result = 0; + if ( doomflag ) + { + doom_close(); + result = 1; + } + if ( helpflag ) + { + helpflag = 0; + result = 1; + } + if ( qtextflag ) + { + qtextflag = 0; + sfx_stop(); + } + else + { + if ( !stextflag ) + goto LABEL_10; + STextESC(); + } + result = 1; +LABEL_10: + if ( msgflag ) + { + msgdelay = 0; + result = 1; + } + if ( talkflag ) + { + control_reset_talk(); + result = 1; + } + if ( dropGoldFlag ) + { + control_drop_gold(27); + result = 1; + } + if ( spselflag ) + { + spselflag = 0; + result = 1; + } + return result; +} +// 4B84DC: using guessed type int dropGoldFlag; +// 4B8960: using guessed type int talkflag; +// 4B8C98: using guessed type int spselflag; +// 52575C: using guessed type int doomflag; +// 52B9F0: using guessed type char msgdelay; +// 52B9F1: using guessed type char msgflag; +// 646D00: using guessed type char qtextflag; +// 6AA705: using guessed type char stextflag; + +//----- (0040905E) -------------------------------------------------------- +LRESULT __stdcall DisableInputWndProc(HWND hWnd, int uMsg, int wParam, int lParam) +{ + bool v5; // zf + + if ( uMsg <= (unsigned int)WM_LBUTTONDOWN ) + { + if ( uMsg != WM_LBUTTONDOWN ) + { + if ( uMsg >= (unsigned int)WM_KEYFIRST + && (uMsg <= (unsigned int)WM_CHAR + || uMsg == WM_SYSKEYDOWN + || uMsg == WM_SYSCOMMAND + || uMsg == WM_MOUSEFIRST) ) + { + return 0; + } + return init_palette(hWnd, uMsg, wParam, lParam); + } + if ( !sgbMouseDown ) + { + sgbMouseDown = 1; +LABEL_21: + SetCapture(hWnd); + return 0; + } + return 0; + } + if ( uMsg == WM_LBUTTONUP ) + { + v5 = sgbMouseDown == 1; + goto LABEL_23; + } + if ( uMsg != WM_RBUTTONDOWN ) + { + if ( uMsg != WM_RBUTTONUP ) + { + if ( uMsg == WM_CAPTURECHANGED ) + { + if ( hWnd != (HWND)lParam ) + sgbMouseDown = 0; + return 0; + } + return init_palette(hWnd, uMsg, wParam, lParam); + } + v5 = sgbMouseDown == 2; +LABEL_23: + if ( v5 ) + { + sgbMouseDown = 0; + ReleaseCapture(); + } + return 0; + } + if ( !sgbMouseDown ) + { + sgbMouseDown = 2; + goto LABEL_21; + } + return 0; +} +// 525748: using guessed type char sgbMouseDown; + +//----- (00409131) -------------------------------------------------------- +int __stdcall GM_Game(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + int v4; // eax + + if ( uMsg > WM_LBUTTONDOWN ) + { + if ( uMsg == WM_LBUTTONUP ) + { + MouseX = (unsigned short)lParam; + MouseY = (unsigned int)lParam >> 16; + if ( sgbMouseDown != 1 ) + return 0; + sgbMouseDown = 0; + LeftMouseUp(); + track_mouse_stance(0); + } + else + { + if ( uMsg == WM_RBUTTONDOWN ) + { + MouseX = (unsigned short)lParam; + MouseY = (unsigned int)lParam >> 16; + if ( !sgbMouseDown ) + { + sgbMouseDown = 2; + SetCapture(hWnd); + RightMouseDown(); + } + return 0; + } + if ( uMsg != WM_RBUTTONUP ) + { + if ( uMsg == WM_CAPTURECHANGED ) + { + if ( hWnd != (HWND)lParam ) + { + sgbMouseDown = 0; + track_mouse_stance(0); + } + } + else if ( uMsg > 0x401 && uMsg <= WM_DIABRETOWN ) + { + if ( (unsigned char)gbMaxPlayers > 1u ) + pfile_write_hero(); + nthread_ignore_mutex(1); + PaletteFadeOut(8); + FreeMonsterSnd(); + music_stop(); + track_mouse_stance(0); + sgbMouseDown = 0; + ReleaseCapture(); + ShowProgress(uMsg); + force_redraw = 255; + DrawAndBlit(); + if ( gbRunGame ) + PaletteFadeIn(8); + nthread_ignore_mutex(0); + *(_DWORD *)&gbGameLoopStartup = 1; + return 0; + } + return init_palette(hWnd, uMsg, wParam, lParam); + } + MouseX = (unsigned short)lParam; + MouseY = (unsigned int)lParam >> 16; + if ( sgbMouseDown != 2 ) + return 0; + sgbMouseDown = 0; + } + ReleaseCapture(); + return 0; + } + switch ( uMsg ) + { + case WM_LBUTTONDOWN: + MouseX = (unsigned short)lParam; + MouseY = (unsigned int)lParam >> 16; + if ( !sgbMouseDown ) + { + sgbMouseDown = 1; + SetCapture(hWnd); + LeftMouseDown(); + track_mouse_stance(v4); + } + return 0; + case WM_KEYFIRST: + PressKey(wParam); + return 0; + case WM_KEYUP: + ReleaseKey(wParam); + return 0; + case WM_CHAR: + PressChar(wParam); + return 0; + case WM_SYSKEYDOWN: + if ( PressSysKey(wParam) ) + return 0; + return init_palette(hWnd, uMsg, wParam, lParam); + case WM_SYSCOMMAND: + if ( wParam == SC_CLOSE ) + { + gbRunGame = 0; + gbRunGameResult = 0; + return 0; + } + return init_palette(hWnd, uMsg, wParam, lParam); + } + if ( uMsg != WM_MOUSEFIRST ) + return init_palette(hWnd, uMsg, wParam, lParam); + MouseX = (unsigned short)lParam; + MouseY = (unsigned int)lParam >> 16; + gmenu_run_item((unsigned short)lParam); + return 0; +} +// 525650: using guessed type int gbRunGame; +// 525698: using guessed type int gbRunGameResult; +// 52571C: using guessed type int force_redraw; +// 525748: using guessed type char sgbMouseDown; +// 679660: using guessed type char gbMaxPlayers; + +//----- (004093B2) -------------------------------------------------------- +void __cdecl LeftMouseDown() +{ + int v0; // ecx + int v1; // edi + int v2; // eax + int v3; // eax + int v4; // eax + int v5; // ecx + int v6; // eax + unsigned char v7; // dl + int v8; // eax + unsigned char v9; // dl + unsigned short v10; // ax + unsigned char v11; // dl + int v12; // eax + unsigned short v13; // [esp-8h] [ebp-10h] + + v1 = v0; + if ( !gmenu_left_mouse(1) && !control_check_talk_btn() && sgnTimeoutCurs == CURSOR_NONE ) + { + if ( *(_DWORD *)&deathflag ) + { + control_check_btn_press(); + return; + } + if ( PauseMode != 2 ) + { + if ( doomflag ) + { + doom_close(); + return; + } + if ( spselflag ) + { + SetSpell(); + return; + } + if ( stextflag ) + { + CheckStoreBtn(); + return; + } + if ( MouseY >= 352 ) + { + if ( !talkflag && !dropGoldFlag ) + { + _LOBYTE(v4) = gmenu_exception(); + if ( !v4 ) + CheckInvScrn(); + } + DoPanBtn(); + if ( pcurs > 1 && pcurs < 12 ) + { +LABEL_48: + SetCursor(1); + return; + } + } + else + { + _LOBYTE(v2) = gmenu_exception(); + if ( !v2 && !TryIconCurs() ) + { + if ( questlog && MouseX > 32 && MouseX < 288 && MouseY > 32 && MouseY < 308 ) + { + QuestlogESC(); + return; + } + if ( qtextflag ) + { + qtextflag = 0; + sfx_stop(); + return; + } + if ( chrflag && MouseX < 320 ) + { + CheckChrBtns(); + return; + } + if ( invflag && MouseX > 320 ) + { + if ( !dropGoldFlag ) + CheckInvItem(); + return; + } + if ( sbookflag && MouseX > 320 ) + { + CheckSBook(); + return; + } + if ( pcurs >= CURSOR_FIRSTITEM ) + { + if ( !TryInvPut() ) + return; + NetSendCmdPItem(1u, CMD_PUTITEM, cursmx, cursmy); + goto LABEL_48; + } + v3 = 21720 * myplr; + if ( plr[myplr]._pStatPts && !spselflag ) + CheckLvlBtn(); + if ( !lvlbtndown ) + { + if ( !leveltype ) + { + if ( pcursitem != -1 && pcurs == 1 ) + { + _LOWORD(v3) = pcursitem; + NetSendCmdLocParam1(1u, (invflag == 0) + CMD_GOTOGETITEM, cursmx, cursmy, v3); + } + if ( *(_DWORD *)&pcursmonst != -1 ) + NetSendCmdLocParam1(1u, CMD_TALKXY, cursmx, cursmy, *(int *)&pcursmonst); + return; + } + v5 = abs(plr[myplr].WorldX - cursmx) < 2 && abs(plr[myplr].WorldY - cursmy) < 2; + _HIWORD(v6) = _HIWORD(pcurs); + if ( pcursitem != -1 && pcurs == 1 && v1 != 5 ) + { + _LOWORD(v6) = pcursitem; + NetSendCmdLocParam1(1u, (invflag == 0) + CMD_GOTOGETITEM, cursmx, cursmy, v6); + return; + } + if ( pcursobj != -1 ) + { + if ( v1 != 5 || v5 && (v5 = 120 * pcursobj, *((_BYTE *)&object[0]._oBreak + v5) == 1) ) + { + _LOWORD(v5) = pcursobj; + NetSendCmdLocParam1(1u, (pcurs == 5) + CMD_OPOBJXY, cursmx, cursmy, v5); + return; + } + } + if ( plr[myplr]._pwtype == 1 ) + { + if ( v1 == 5 ) + { + v7 = CMD_RATTACKXY; +LABEL_84: + NetSendCmdLoc(1u, v7, cursmx, cursmy); + return; + } + if ( *(_DWORD *)&pcursmonst != -1 ) + { + _LOBYTE(v8) = CanTalkToMonst(*(int *)&pcursmonst); + v13 = pcursmonst; + if ( !v8 ) + { + v9 = CMD_RATTACKID; +LABEL_89: + NetSendCmdParam1(1u, v9, v13); + return; + } +LABEL_88: + v9 = CMD_ATTACKID; + goto LABEL_89; + } + _LOBYTE(v10) = pcursplr; + if ( pcursplr == -1 || FriendlyMode ) + return; + v11 = CMD_RATTACKPID; + } + else + { + if ( v1 == 5 ) + { + if ( *(_DWORD *)&pcursmonst == -1 + || (_LOBYTE(v12) = CanTalkToMonst(*(int *)&pcursmonst), !v12) ) + { + v7 = CMD_SATTACKXY; + goto LABEL_84; + } + v10 = pcursmonst; + v11 = CMD_ATTACKID; +LABEL_94: + NetSendCmdParam1(1u, v11, v10); + return; + } + if ( *(_DWORD *)&pcursmonst != -1 ) + { + v13 = pcursmonst; + goto LABEL_88; + } + _LOBYTE(v10) = pcursplr; + if ( pcursplr == -1 || FriendlyMode ) + return; + v11 = CMD_ATTACKPID; + } + v10 = (char)v10; + goto LABEL_94; + } + } + } + } + } +} +// 484368: using guessed type int FriendlyMode; +// 4B84DC: using guessed type int dropGoldFlag; +// 4B851C: using guessed type int lvlbtndown; +// 4B8960: using guessed type int talkflag; +// 4B8968: using guessed type int sbookflag; +// 4B8C98: using guessed type int spselflag; +// 4B8CC0: using guessed type char pcursitem; +// 4B8CC1: using guessed type char pcursobj; +// 4B8CC2: using guessed type char pcursplr; +// 525740: using guessed type int PauseMode; +// 52575C: using guessed type int doomflag; +// 5BB1ED: using guessed type char leveltype; +// 646D00: using guessed type char qtextflag; +// 69BD04: using guessed type int questlog; +// 6AA705: using guessed type char stextflag; + +//----- (004097EC) -------------------------------------------------------- +int __cdecl TryIconCurs() +{ + unsigned char v0; // dl + int v1; // edx + int v2; // eax + int v3; // eax + int v4; // ST0C_4 + int v5; // eax + + switch ( pcurs ) + { + case CURSOR_RESURRECT: + v0 = CMD_RESURRECT; +LABEL_3: + NetSendCmdParam1(1u, v0, pcursplr); + return 1; + case CURSOR_HEALOTHER: + v0 = CMD_HEALOTHER; + goto LABEL_3; + case CURSOR_TELEKINESIS: + DoTelekinesis(); + return 1; + case CURSOR_IDENTIFY: + if ( pcursinvitem != -1 ) + { + CheckIdentify(myplr, pcursinvitem); + return 1; + } +LABEL_26: + SetCursor(1); + return 1; + case CURSOR_REPAIR: + if ( pcursinvitem != -1 ) + { + DoRepair(myplr, pcursinvitem); + return 1; + } + goto LABEL_26; + case CURSOR_RECHARGE: + if ( pcursinvitem != -1 ) + { + DoRecharge(myplr, pcursinvitem); + return 1; + } + goto LABEL_26; + case CURSOR_TELEPORT: + v1 = plr[myplr]._pTSpell; + if ( *(_DWORD *)&pcursmonst == -1 ) + { + if ( pcursplr == -1 ) + { + v4 = GetSpellLevel(myplr, v1); + v5 = 21720 * myplr; + _LOWORD(v5) = plr[myplr]._pTSpell; + NetSendCmdLocParam2(1u, CMD_TSPELLXY, cursmx, cursmy, v5, v4); + } + else + { + v3 = GetSpellLevel(myplr, v1); + NetSendCmdParam3(1u, CMD_TSPELLPID, pcursplr, plr[myplr]._pTSpell, v3); + } + } + else + { + v2 = GetSpellLevel(myplr, v1); + NetSendCmdParam3(1u, CMD_TSPELLID, pcursmonst, plr[myplr]._pTSpell, v2); + } + goto LABEL_26; + } + if ( pcurs == CURSOR_DISARM && pcursobj == -1 ) + goto LABEL_26; + return 0; +} +// 4B8CB8: using guessed type char pcursinvitem; +// 4B8CC1: using guessed type char pcursobj; +// 4B8CC2: using guessed type char pcursplr; + +//----- (00409963) -------------------------------------------------------- +void __cdecl LeftMouseUp() +{ + gmenu_left_mouse(0); + control_release_talk_btn(); + if ( panbtndown ) + CheckBtnUp(); + if ( chrbtnactive ) + ReleaseChrBtns(); + if ( lvlbtndown ) + ReleaseLvlBtn(); + if ( stextflag ) + ReleaseStoreBtn(); +} +// 4B851C: using guessed type int lvlbtndown; +// 4B87A8: using guessed type int chrbtnactive; +// 4B8C90: using guessed type int panbtndown; +// 6AA705: using guessed type char stextflag; + +//----- (004099A8) -------------------------------------------------------- +void __cdecl RightMouseDown() +{ + int v0; // eax + + _LOBYTE(v0) = gmenu_exception(); + if ( !v0 && sgnTimeoutCurs == CURSOR_NONE && PauseMode != 2 && !plr[myplr]._pInvincible ) + { + if ( doomflag ) + { + doom_close(); + } + else if ( !stextflag ) + { + if ( spselflag ) + { + SetSpell(); + } + else if ( MouseY >= 352 + || (!sbookflag || MouseX <= 320) + && !TryIconCurs() + && (pcursinvitem == -1 || !UseInvItem(myplr, pcursinvitem)) ) + { + if ( pcurs == 1 ) + { + if ( pcursinvitem == -1 || !UseInvItem(myplr, pcursinvitem) ) + CheckPlrSpell(); + } + else if ( pcurs > 1 && pcurs < 12 ) + { + SetCursor(1); + } + } + } + } +} +// 4B8968: using guessed type int sbookflag; +// 4B8C98: using guessed type int spselflag; +// 4B8CB8: using guessed type char pcursinvitem; +// 525740: using guessed type int PauseMode; +// 52575C: using guessed type int doomflag; +// 6AA705: using guessed type char stextflag; + +//----- (00409A8E) -------------------------------------------------------- +int __fastcall PressSysKey(int wParam) +{ + int v1; // esi + int v2; // eax + + v1 = wParam; + _LOBYTE(v2) = gmenu_exception(); + if ( v2 || v1 != VK_F10 ) + return 0; + diablo_hotkey_msg(1); + return 1; +} + +//----- (00409AB0) -------------------------------------------------------- +void __fastcall diablo_hotkey_msg(int dwMsg) +{ + int v1; // esi + char *v2; // eax + char Filename[260]; // [esp+4h] [ebp-154h] + char ReturnedString[80]; // [esp+108h] [ebp-50h] + + v1 = dwMsg; + if ( gbMaxPlayers != 1 ) + { + if ( !GetModuleFileNameA(hInstance, Filename, 0x104u) ) + TermMsg("Can't get program name"); + v2 = strrchr(Filename, 92); + if ( v2 ) + *v2 = 0; + strcat(Filename, "\\Diablo.ini"); + GetPrivateProfileStringA("NetMsg", spszMsgKeyTbl[v1], spszMsgTbl[v1], ReturnedString, 0x50u, Filename); + msg_init_msg(-1, ReturnedString); + } +} +// 48436C: using guessed type char *spszMsgTbl[4]; +// 48437C: using guessed type char *spszMsgKeyTbl[4]; +// 679660: using guessed type char gbMaxPlayers; + +//----- (00409B51) -------------------------------------------------------- +void __fastcall ReleaseKey(int vkey) +{ + if ( vkey == VK_SNAPSHOT ) + CaptureScreen(); +} + +//----- (00409B5C) -------------------------------------------------------- +void __fastcall PressKey(int vkey) +{ + int v1; // esi + int v2; // ecx + int v3; // ecx + signed int v4; // eax + + v1 = vkey; + if ( !gmenu_presskeys(vkey) && !control_presskeys(v1) ) + { + if ( !*(_DWORD *)&deathflag ) + goto LABEL_113; + if ( sgnTimeoutCurs == CURSOR_NONE ) + { + if ( v1 == VK_F9 ) + diablo_hotkey_msg(0); + if ( v1 == VK_F10 ) + diablo_hotkey_msg(1); + if ( v1 == VK_F11 ) + diablo_hotkey_msg(2); + if ( v1 == VK_F12 ) + diablo_hotkey_msg(3); + if ( v1 == VK_RETURN ) + control_type_message(); + if ( v1 == VK_ESCAPE ) + { +LABEL_113: + if ( v1 == VK_ESCAPE ) + { + if ( !PressEscKey() ) + { + track_mouse_stance(0); + gamemenu_previous(); + } + return; + } + if ( sgnTimeoutCurs == CURSOR_NONE && !dropGoldFlag ) + { + if ( v1 == VK_PAUSE ) + { + diablo_pause_game(); + return; + } + if ( PauseMode != 2 ) + { + switch ( v1 ) + { + case VK_RETURN: + if ( stextflag ) + { + STextEnter(); + } + else if ( questlog ) + { + QuestlogEnter(); + } + else + { + control_type_message(); + } + return; + case VK_F1: + if ( helpflag ) + { + helpflag = 0; + return; + } + if ( stextflag ) + { + ClearPanel(); + AddPanelString("No help available", 1); + AddPanelString("while in stores", 1); + track_mouse_stance(0); + return; + } + invflag = 0; + chrflag = 0; + sbookflag = 0; + spselflag = 0; + if ( qtextflag && !leveltype ) + { + qtextflag = 0; + sfx_stop(); + } + questlog = 0; + *(_DWORD *)&automapflag = 0; + msgdelay = 0; + gamemenu_off(); + DisplayHelp(); +LABEL_110: + doom_close(); + return; + case VK_F5: + v2 = 0; + goto LABEL_48; + case VK_F6: + v2 = 1; + goto LABEL_48; + case VK_F7: + v2 = 2; + goto LABEL_48; + case VK_F8: + v2 = 3; +LABEL_48: + if ( spselflag ) + SetSpeedSpell(v2); + else + ToggleSpell(v2); + return; + case VK_F9: + v3 = 0; +LABEL_59: + diablo_hotkey_msg(v3); + return; + case VK_F10: + v3 = 1; + goto LABEL_59; + case VK_F11: + v3 = 2; + goto LABEL_59; + case VK_F12: + v3 = 3; + goto LABEL_59; + case VK_UP: + if ( stextflag ) + { + STextUp(); + } + else if ( questlog ) + { + QuestlogUp(); + } + else if ( helpflag ) + { + HelpScrollUp(); + } + else if ( *(_DWORD *)&automapflag ) + { + AutomapUp(); + } + return; + case VK_DOWN: + if ( stextflag ) + { + STextDown(); + } + else if ( questlog ) + { + QuestlogDown(); + } + else if ( helpflag ) + { + HelpScrollDown(); + } + else if ( *(_DWORD *)&automapflag ) + { + AutomapDown(); + } + return; + case VK_PRIOR: + if ( stextflag ) + STextPrior(); + return; + case VK_NEXT: + if ( stextflag ) + STextNext(); + return; + case VK_LEFT: + if ( *(_DWORD *)&automapflag && !talkflag ) + AutomapLeft(); + return; + case VK_RIGHT: + if ( *(_DWORD *)&automapflag && !talkflag ) + AutomapRight(); + return; + case VK_TAB: + DoAutoMap(); + return; + case VK_SPACE: + if ( !chrflag ) + { + if ( !invflag ) + { +LABEL_106: + helpflag = 0; + invflag = 0; + chrflag = 0; + sbookflag = 0; + spselflag = 0; + if ( qtextflag && !leveltype ) + { + qtextflag = 0; + sfx_stop(); + } + questlog = 0; + *(_DWORD *)&automapflag = 0; + msgdelay = 0; + gamemenu_off(); + goto LABEL_110; + } + v4 = MouseX; + if ( MouseX >= 480 || MouseY >= 352 ) + { +LABEL_101: + if ( !invflag && chrflag && v4 > 160 && MouseY < 352 ) + SetCursorPos(v4 - 160, MouseY); + goto LABEL_106; + } + SetCursorPos(MouseX + 160, MouseY); + } + v4 = MouseX; + goto LABEL_101; + } + } + } + } + } + } +} +// 4B84DC: using guessed type int dropGoldFlag; +// 4B8960: using guessed type int talkflag; +// 4B8968: using guessed type int sbookflag; +// 4B8C98: using guessed type int spselflag; +// 525740: using guessed type int PauseMode; +// 52B9F0: using guessed type char msgdelay; +// 5BB1ED: using guessed type char leveltype; +// 646D00: using guessed type char qtextflag; +// 69BD04: using guessed type int questlog; +// 6AA705: using guessed type char stextflag; + +//----- (00409F43) -------------------------------------------------------- +void __cdecl diablo_pause_game() +{ + if ( (unsigned char)gbMaxPlayers <= 1u ) + { + if ( PauseMode ) + { + PauseMode = 0; + } + else + { + PauseMode = 2; + FreeMonsterSnd(); + track_mouse_stance(0); + } + force_redraw = 255; + } +} +// 52571C: using guessed type int force_redraw; +// 525740: using guessed type int PauseMode; +// 679660: using guessed type char gbMaxPlayers; + +//----- (00409F7F) -------------------------------------------------------- +void __fastcall PressChar(int vkey) +{ + int v1; // ebx + int v2; // eax + int v3; // ecx + BOOL v4; // ecx + int v5; // ecx + int v6; // eax + BOOL v7; // ecx + const char *v8; // edx + int v9; // ecx + int v10; // eax + int v11; // eax + int v12; // eax + int v13; // eax + int v14; // eax + int v15; // eax + int v16; // eax + int v17; // eax + int v18; // [esp-4h] [ebp-8h] + + v1 = vkey; + _LOBYTE(v2) = gmenu_exception(); + if ( !v2 && !control_talk_last_key(v1) && sgnTimeoutCurs == CURSOR_NONE && !*(_DWORD *)&deathflag ) + { + if ( (_BYTE)v1 == 'p' || (_BYTE)v1 == 'P' ) + { + diablo_pause_game(); + } + else if ( PauseMode != 2 ) + { + if ( doomflag ) + { + doom_close(); + return; + } + if ( dropGoldFlag ) + { + _LOBYTE(v3) = v1; + control_drop_gold(v3); + return; + } + switch ( v1 ) + { + case '!': + case '1': + v9 = myplr; + v10 = plr[myplr].SpdList[0]._itype; + if ( v10 != -1 && v10 != 11 ) + { + v18 = 47; + goto LABEL_72; + } + return; + case '#': + case '3': + v9 = myplr; + v12 = plr[myplr].SpdList[2]._itype; + if ( v12 != -1 && v12 != 11 ) + { + v18 = 49; + goto LABEL_72; + } + return; + case '$': + case '4': + v9 = myplr; + v13 = plr[myplr].SpdList[3]._itype; + if ( v13 != -1 && v13 != 11 ) + { + v18 = 50; + goto LABEL_72; + } + return; + case '%': + case '5': + v9 = myplr; + v14 = plr[myplr].SpdList[4]._itype; + if ( v14 != -1 && v14 != 11 ) + { + v18 = 51; + goto LABEL_72; + } + return; + case '&': + case '7': + v9 = myplr; + v16 = plr[myplr].SpdList[6]._itype; + if ( v16 != -1 && v16 != 11 ) + { + v18 = 53; + goto LABEL_72; + } + return; + case '*': + case '8': + v9 = myplr; + v17 = plr[myplr].SpdList[7]._itype; + if ( v17 != -1 && v17 != 11 ) + { + v18 = 54; + goto LABEL_72; + } + return; + case '+': + case '=': + if ( *(_DWORD *)&automapflag ) + AutomapZoomIn(); + return; + case '-': + case '_': + if ( *(_DWORD *)&automapflag ) + AutomapZoomOut(); + return; + case '2': + case '@': + v9 = myplr; + v11 = plr[myplr].SpdList[1]._itype; + if ( v11 != -1 && v11 != 11 ) + { + v18 = 48; + goto LABEL_72; + } + return; + case '6': + case '^': + v9 = myplr; + v15 = plr[myplr].SpdList[5]._itype; + if ( v15 != -1 && v15 != 11 ) + { + v18 = 52; +LABEL_72: + UseInvItem(v9, v18); + } + return; + case 'B': + case 'b': + if ( !stextflag ) + { + invflag = 0; + sbookflag = sbookflag == 0; + } + return; + case 'C': + case 'c': + if ( !stextflag ) + { + questlog = 0; + v7 = chrflag == 0; + chrflag = chrflag == 0; + if ( !v7 || invflag ) + goto LABEL_18; + goto LABEL_24; + } + return; + case 'F': + case 'f': + palette_inc_gamma(); + return; + case 'G': + case 'g': + palette_dec_gamma(); + return; + case 'I': + case 'i': + if ( stextflag ) + return; + sbookflag = 0; + v4 = invflag == 0; + invflag = invflag == 0; + if ( !v4 || chrflag ) + { +LABEL_24: + if ( MouseX < 480 ) + { + v5 = MouseY; + if ( MouseY < 352 ) + { + v6 = MouseX + 160; + goto LABEL_27; + } + } + } + else + { +LABEL_18: + if ( MouseX > 160 ) + { + v5 = MouseY; + if ( MouseY < 352 ) + { + v6 = MouseX - 160; +LABEL_27: + SetCursorPos(v6, v5); + return; + } + } + } + break; + case 'Q': + case 'q': + if ( !stextflag ) + { + chrflag = 0; + if ( questlog ) + questlog = 0; + else + StartQuestlog(); + } + return; + case 'S': + case 's': + if ( !stextflag ) + { + invflag = 0; + if ( spselflag ) + spselflag = 0; + else + DoSpeedBook(); + track_mouse_stance(0); + } + return; + case 'V': + v8 = "internal version unknown"; + goto LABEL_47; + case 'Z': + case 'z': + zoomflag = zoomflag == 0; + return; + case 'v': + v8 = "Diablo v1.09"; +LABEL_47: + msg_init_msg(1 << myplr, v8); + return; + default: + return; + } + } + } +} +// 4B84DC: using guessed type int dropGoldFlag; +// 4B8968: using guessed type int sbookflag; +// 4B8C98: using guessed type int spselflag; +// 52569C: using guessed type int zoomflag; +// 525740: using guessed type int PauseMode; +// 52575C: using guessed type int doomflag; +// 69BD04: using guessed type int questlog; +// 6AA705: using guessed type char stextflag; + +//----- (0040A391) -------------------------------------------------------- +void __cdecl LoadLvlGFX() +{ + unsigned char *v0; // eax + char *v1; // ecx + unsigned char *v2; // eax + char *v3; // ecx + unsigned char *v4; // eax + char *v5; // ecx + + if ( !leveltype ) + { + pDungeonCels = LoadFileInMem("Levels\\TownData\\Town.CEL", 0); + pMegaTiles = LoadFileInMem("Levels\\TownData\\Town.TIL", 0); + v4 = LoadFileInMem("Levels\\TownData\\Town.MIN", 0); + v5 = "Levels\\TownData\\TownS.CEL"; + goto LABEL_14; + } + if ( leveltype == 1 ) + { + pDungeonCels = LoadFileInMem("Levels\\L1Data\\L1.CEL", 0); + v2 = LoadFileInMem("Levels\\L1Data\\L1.TIL", 0); + v3 = "Levels\\L1Data\\L1.MIN"; + goto LABEL_12; + } + if ( leveltype != 2 ) + { + if ( leveltype != 3 ) + { + if ( leveltype != 4 ) + { + TermMsg("LoadLvlGFX"); + return; + } + pDungeonCels = LoadFileInMem("Levels\\L4Data\\L4.CEL", 0); + v0 = LoadFileInMem("Levels\\L4Data\\L4.TIL", 0); + v1 = "Levels\\L4Data\\L4.MIN"; + goto LABEL_10; + } + pDungeonCels = LoadFileInMem("Levels\\L3Data\\L3.CEL", 0); + v2 = LoadFileInMem("Levels\\L3Data\\L3.TIL", 0); + v3 = "Levels\\L3Data\\L3.MIN"; +LABEL_12: + pMegaTiles = v2; + v4 = LoadFileInMem(v3, 0); + v5 = "Levels\\L1Data\\L1S.CEL"; + goto LABEL_14; + } + pDungeonCels = LoadFileInMem("Levels\\L2Data\\L2.CEL", 0); + v0 = LoadFileInMem("Levels\\L2Data\\L2.TIL", 0); + v1 = "Levels\\L2Data\\L2.MIN"; +LABEL_10: + pMegaTiles = v0; + v4 = LoadFileInMem(v1, 0); + v5 = "Levels\\L2Data\\L2S.CEL"; +LABEL_14: + *(_DWORD *)&dpiece_defs[0].blocks = (unsigned int)v4; + level_special_cel = LoadFileInMem(v5, 0); +} +// 5BB1ED: using guessed type char leveltype; + +//----- (0040A4B4) -------------------------------------------------------- +void __cdecl LoadAllGFX() +{ + pSpeedCels = DiabloAllocPtr(0x100000); + IncProgress(); + IncProgress(); + InitObjectGFX(); + IncProgress(); + InitMissileGFX(); + IncProgress(); +} + +//----- (0040A4E1) -------------------------------------------------------- +void __fastcall CreateLevel(int entry) +{ + char v1; // cl + char v2; // [esp-4h] [ebp-4h] + + if ( leveltype ) + { + if ( leveltype == 1 ) + { + CreateL5Dungeon(glSeedTbl[currlevel], entry); + InitL1Triggers(); + Freeupstairs(); + v1 = 1; + } + else + { + switch ( leveltype ) + { + case 2: + CreateL2Dungeon(glSeedTbl[currlevel], entry); + InitL2Triggers(); + Freeupstairs(); + v2 = 2; + break; + case 3: + CreateL3Dungeon(glSeedTbl[currlevel], entry); + InitL3Triggers(); + Freeupstairs(); + v2 = 3; + break; + case 4: + CreateL4Dungeon(glSeedTbl[currlevel], entry); + InitL4Triggers(); + Freeupstairs(); + v2 = 4; + break; + default: + TermMsg("CreateLevel"); + return; + } + v1 = v2; + } + } + else + { + CreateTown(entry); + InitTownTriggers(); + v1 = 0; + } + LoadRndLvlPal(v1); +} +// 5BB1ED: using guessed type char leveltype; + +//----- (0040A5A4) -------------------------------------------------------- +void __fastcall LoadGameLevel(bool from_save, int entry) +{ + int v2; // ebp + int v3; // ebx + int v4; // esi + int *v5; // edi + int v6; // eax + BOOL v7; // edx + int v8; // ecx + int v9; // eax + int v10; // ecx + int v11; // eax + bool v12; // zf + char (*v13)[112]; // ecx + signed int v14; // eax + int *v15; // edi + int v16; // ebx + int *v17; // esi + char *v18; // eax + int v19; // eax + BOOL FirstTime; // [esp+0h] [ebp-8h] + int v21; // [esp+4h] [ebp-4h] + + v2 = 0; + v3 = entry; + v21 = entry; + FirstTime = from_save; + if ( setseed ) + glSeedTbl[currlevel] = setseed; + music_stop(); + SetCursor(1); + SetRndSeed(glSeedTbl[currlevel]); + IncProgress(); + MakeLightTable(); + LoadLvlGFX(); + IncProgress(); + if ( FirstTime ) + { + InitInv(); + InitItemGFX(); + InitQuestText(); + v4 = 0; + if ( gbMaxPlayers ) + { + do + InitPlrGFXMem(v4++); + while ( v4 < (unsigned char)gbMaxPlayers ); + } + InitStores(); + InitAutomapOnce(); + InitHelp(); + } + SetRndSeed(glSeedTbl[currlevel]); + if ( !leveltype ) + SetupTownStores(); + IncProgress(); + InitAutomap(); + if ( leveltype && v3 != 4 ) + { + InitLighting(); + InitVision(); + } + InitLevelMonsters(); + IncProgress(); + if ( !setlevel ) + { + CreateLevel(v3); + IncProgress(); + FillSolidBlockTbls(); + SetRndSeed(glSeedTbl[currlevel]); + if ( leveltype ) + { + GetLevelMTypes(); + InitThemes(); + LoadAllGFX(); + } + else + { + InitMissileGFX(); + } + IncProgress(); + if ( v3 == 3 ) + GetReturnLvlPos(); + if ( v3 == 5 ) + GetPortalLvlPos(); + IncProgress(); + v5 = &plr[0].plrlevel; + do + { + if ( *((_BYTE *)v5 - 23) ) + { + if ( currlevel == *v5 ) + { + InitPlayerGFX(v2); + if ( v3 != 4 ) + InitPlayer(v2, FirstTime); + } + } + v5 += 5430; + ++v2; + } + while ( (signed int)v5 < (signed int)&plr_msgs[0].player ); + PlayDungMsgs(); + InitMultiView(); + IncProgress(); + v6 = (unsigned char)gbMaxPlayers; + v7 = 0; + if ( (signed int)(unsigned char)gbMaxPlayers > 0 ) + { + v8 = 0; + do + { + if ( plr[v8].plractive[0] ) + v7 = v7 || plr[0]._pLvlVisited[currlevel + v8 * 21720]; + ++v8; + --v6; + } + while ( v6 ); + } + SetRndSeed(glSeedTbl[currlevel]); + if ( leveltype ) + { + if ( FirstTime || v21 == 4 || !plr[myplr]._pLvlVisited[currlevel] || gbMaxPlayers != 1 ) + { + HoldThemeRooms(); + glMid1Seed[currlevel] = GetRndSeed(); + InitMonsters(); + v9 = GetRndSeed(); + v10 = currlevel; + glMid2Seed[v10] = v9; + InitObjects(v10); + InitItems(); + CreateThemeRooms(); + glMid3Seed[currlevel] = GetRndSeed(); + InitMissiles(); + InitDead(); + v11 = GetRndSeed(); + v12 = gbMaxPlayers == 1; + glEndSeed[currlevel] = v11; + if ( !v12 ) + DeltaLoadLevel(); + IncProgress(); + SavePreLighting(); + goto LABEL_55; + } + InitMonsters(); + InitMissiles(); + InitDead(); + IncProgress(); + LoadLevel(); +LABEL_54: + IncProgress(); +LABEL_55: + if ( gbMaxPlayers == 1 ) + ResyncQuests(); + else + ResyncMPQuests(); + goto LABEL_72; + } + v13 = dFlags; + do + { + v14 = 0; + do + (*v13)[v14++] |= 0x40u; + while ( v14 < 112 ); + ++v13; + } + while ( (signed int)v13 < (signed int)dItem ); + InitTowners(); + InitItems(); + InitMissiles(); + IncProgress(); + if ( !FirstTime && v21 != 4 && plr[myplr]._pLvlVisited[currlevel] ) + { + if ( gbMaxPlayers != 1 ) + goto LABEL_53; + LoadLevel(); + } + if ( gbMaxPlayers == 1 ) + goto LABEL_54; +LABEL_53: + DeltaLoadLevel(); + goto LABEL_54; + } + pSpeedCels = DiabloAllocPtr(0x100000); + LoadSetMap(); + IncProgress(); + GetLevelMTypes(); + InitMonsters(); + InitMissileGFX(); + InitDead(); + FillSolidBlockTbls(); + IncProgress(); + if ( v3 == 5 ) + GetPortalLvlPos(); + v15 = &plr[0].plrlevel; + do + { + if ( *((_BYTE *)v15 - 23) ) + { + if ( currlevel == *v15 ) + { + InitPlayerGFX(v2); + if ( v3 != 4 ) + InitPlayer(v2, FirstTime); + } + } + v15 += 5430; + ++v2; + } + while ( (signed int)v15 < (signed int)&plr_msgs[0].player ); + InitMultiView(); + IncProgress(); + if ( FirstTime || v3 == 4 || !plr[myplr]._pSLvlVisited[(unsigned char)setlvlnum] ) + { + InitItems(); + SavePreLighting(); + } + else + { + LoadLevel(); + } + InitMissiles(); + IncProgress(); +LABEL_72: + SyncPortals(); + v16 = 0; + v17 = &plr[0].plrlevel; + do + { + if ( *((_BYTE *)v17 - 23) && *v17 == currlevel && (!*((_BYTE *)v17 + 267) || v16 == myplr) ) + { + if ( v17[89] <= 0 ) + { + v18 = &dFlags[v17[1]][v17[2]]; + *v18 |= 4u; + } + else if ( gbMaxPlayers == 1 ) + { + dPlayer[v17[1]][v17[2]] = v16 + 1; + } + else + { + SyncInitPlrPos(v16); + } + } + v17 += 5430; + ++v16; + } + while ( (signed int)v17 < (signed int)&plr_msgs[0].player ); + if ( leveltype ) + SetDungeonMicros(); + InitLightMax(); + IncProgress(); + IncProgress(); + if ( FirstTime ) + { + InitControlPan(); + IncProgress(); + } + if ( leveltype ) + { + ProcessLightList(); + ProcessVisionList(); + } + music_start((unsigned char)leveltype); + do + _LOBYTE(v19) = IncProgress(); + while ( !v19 ); + if ( setlevel && setlvlnum == SL_SKELKING && quests[12]._qactive == 2 ) + PlaySFX(USFX_SKING1); +} +// 525738: using guessed type int setseed; +// 5BB1ED: using guessed type char leveltype; +// 5CCB10: using guessed type char setlvlnum; +// 5CF31D: using guessed type char setlevel; +// 679660: using guessed type char gbMaxPlayers; + +//----- (0040AAE3) -------------------------------------------------------- +void __fastcall game_loop(bool startup) +{ + int v1; // ecx + int v2; // esi + int v3; // eax + + v1 = startup != 0 ? 0x39 : 0; + v2 = v1 + 3; + if ( v1 != -3 ) + { + while ( 1 ) + { + --v2; + if ( !multi_handle_delta() ) + break; + timeout_cursor(0); + game_logic(); + if ( gbRunGame ) + { + if ( gbMaxPlayers != 1 ) + { + _LOBYTE(v3) = nthread_has_500ms_passed(); + if ( v3 ) + { + if ( v2 ) + continue; + } + } + } + return; + } + timeout_cursor(1); + } +} +// 525650: using guessed type int gbRunGame; +// 679660: using guessed type char gbMaxPlayers; + +//----- (0040AB33) -------------------------------------------------------- +void __cdecl game_logic() +{ + int v0; // eax + int v1; // eax + + if ( PauseMode != 2 ) + { + if ( PauseMode == 1 ) + PauseMode = 2; + if ( gbMaxPlayers == 1 && (_LOBYTE(v0) = gmenu_exception(), v0) ) + { + force_redraw |= 1u; + } + else + { + _LOBYTE(v1) = gmenu_exception(); + if ( !v1 && sgnTimeoutCurs == CURSOR_NONE ) + { + CheckCursMove(); + track_repeat_walk(); + } + if ( gbProcessPlayers ) + ProcessPlayers(); + if ( leveltype ) + { + ProcessMonsters(); + ProcessObjects(); + ProcessMissiles(); + ProcessItems(); + ProcessLightList(); + ProcessVisionList(); + } + else + { + ProcessTowners(); + ProcessItems(); + ProcessMissiles(); + } + sound_update(); + ClearPlrMsg(); + CheckTriggers(); + CheckQuests(); + force_redraw |= 1u; + pfile_update(0); + } + } +} +// 5256A0: using guessed type int gbProcessPlayers; +// 525718: using guessed type char cineflag; +// 52571C: using guessed type int force_redraw; +// 525740: using guessed type int PauseMode; +// 5BB1ED: using guessed type char leveltype; +// 679660: using guessed type char gbMaxPlayers; + +//----- (0040ABE7) -------------------------------------------------------- +void __fastcall timeout_cursor(bool timeout) +{ + if ( timeout ) + { + if ( sgnTimeoutCurs == CURSOR_NONE && !sgbMouseDown ) + { + sgnTimeoutCurs = pcurs; + multi_net_ping(); + ClearPanel(); + AddPanelString("-- Network timeout --", 1); + AddPanelString("-- Waiting for players --", 1); + SetCursor(11); + force_redraw = 255; + } + scrollrt_455E65(1); + } + else if ( sgnTimeoutCurs ) + { + SetCursor(sgnTimeoutCurs); + sgnTimeoutCurs = 0; + ClearPanel(); + force_redraw = 255; + } +} +// 52571C: using guessed type int force_redraw; +// 525748: using guessed type char sgbMouseDown; + +//----- (0040AC6B) -------------------------------------------------------- +void __cdecl diablo_color_cyc_logic() +{ + DWORD v0; // eax + int v1; // eax + + v0 = GetTickCount(); + if ( v0 - dword_52574C >= 0x32 ) + { + dword_52574C = v0; + _LOBYTE(v1) = palette_get_colour_cycling(); + if ( v1 ) + { + if ( leveltype == 4 ) + { + lighting_color_cycling(); + } + else if ( leveltype == 3 ) + { + if ( exclusive ) + palette_update_caves(); + } + } + } +} +// 484364: using guessed type int exclusive; +// 52574C: using guessed type int dword_52574C; +// 5BB1ED: using guessed type char leveltype; + +//----- (0040ACAD) -------------------------------------------------------- +int __cdecl doom_get_frame_from_time() +{ + int result; // eax + + if ( dword_525760 == 36001 ) + result = 31; + else + result = dword_525760 / 1200; + return result; +} + +//----- (0040ACC6) -------------------------------------------------------- +void __cdecl doom_alloc_cel() +{ + pDoomCel = DiabloAllocPtr(229376); +} + +//----- (0040ACD6) -------------------------------------------------------- +void __cdecl doom_cleanup() +{ + void *v0; // ecx + + v0 = pDoomCel; + pDoomCel = 0; + mem_free_dbg(v0); +} + +//----- (0040ACE8) -------------------------------------------------------- +void __cdecl doom_load_graphics() +{ + if ( dword_525750 == 31 ) + { + strcpy(tempstr, "Items\\Map\\MapZDoom.CEL"); + } + else if ( dword_525750 >= 10 ) + { + sprintf(tempstr, "Items\\Map\\MapZ00%i.CEL", dword_525750); + } + else + { + sprintf(tempstr, "Items\\Map\\MapZ000%i.CEL", dword_525750); + } + LoadFileWithMem(tempstr, pDoomCel); +} +// 525750: using guessed type int dword_525750; + +//----- (0040AD34) -------------------------------------------------------- +void __cdecl doom_init() +{ + int v0; // eax + + doomflag = 1; + doom_alloc_cel(); + v0 = -(doom_get_frame_from_time() != 31); + _LOBYTE(v0) = v0 & 0xE1; + dword_525750 = v0 + 31; + doom_load_graphics(); +} +// 525750: using guessed type int dword_525750; +// 52575C: using guessed type int doomflag; + +//----- (0040AD5E) -------------------------------------------------------- +void __cdecl doom_close() +{ + if ( doomflag ) + { + doomflag = 0; + doom_cleanup(); + } +} +// 52575C: using guessed type int doomflag; + +//----- (0040AD74) -------------------------------------------------------- +void __cdecl doom_draw() +{ + if ( doomflag ) + { + if ( dword_525750 != 31 && ++dword_525754 >= 5 ) + { + dword_525754 = 0; + if ( ++dword_525750 > doom_get_frame_from_time() ) + dword_525750 = 0; + doom_load_graphics(); + } + Cel_decode(64, 511, pDoomCel, 1, 640); + } +} +// 525750: using guessed type int dword_525750; +// 525754: using guessed type int dword_525754; +// 52575C: using guessed type int doomflag; + +//----- (0040ADD6) -------------------------------------------------------- +void __cdecl DRLG_Init_Globals() +{ + char v0; // al + + memset(dFlags, 0, 0x3100u); + memset(dPlayer, 0, 0x3100u); + memset(dMonster, 0, 0xC400u); + memset(dDead, 0, 0x3100u); + memset(dObject, 0, 0x3100u); + memset(dItem, 0, 0x3100u); + memset(dMissile, 0, 0x3100u); + memset(dArch, 0, 0x3100u); + if ( lightflag ) + v0 = 0; + else + v0 = light4flag == 0 ? 15 : 3; + memset(dTransVal, v0, 0x3100u); +} +// 525728: using guessed type int light4flag; +// 646A28: using guessed type int lightflag; + +//----- (0040AE79) -------------------------------------------------------- +void __fastcall LoadL1Dungeon(char *dun_path, int view_x, int view_y) +{ + char *v3; // esi + unsigned char *v4; // esi + signed int v5; // ecx + signed int v6; // eax + signed int v7; // edx + int v8; // edi + int v9; // ebx + char *v10; // eax + int v11; // ecx + char v12; // dl + int v13; // [esp+Ch] [ebp-Ch] + int v14; // [esp+10h] [ebp-8h] + int v15; // [esp+14h] [ebp-4h] + + v13 = view_x; + dminx = 16; + dminy = 16; + v3 = dun_path; + dmaxx = 96; + dmaxy = 96; + DRLG_InitTrans(); + v4 = LoadFileInMem(v3, 0); + v5 = 0; + do + { + v6 = v5; + v7 = 40; + do + { + mydflags[0][v6] = 0; + dungeon[0][v6] = 22; + v6 += 40; + --v7; + } + while ( v7 ); + ++v5; + } + while ( v5 < 40 ); + v15 = 0; + v8 = *v4; + v9 = v4[2]; + v10 = (char *)(v4 + 4); + if ( v9 > 0 ) + { + do + { + if ( v8 > 0 ) + { + v11 = v15; + v14 = v8; + do + { + v12 = *v10; + if ( *v10 ) + { + mydflags[0][v11] |= 0x80u; + dungeon[0][v11] = v12; + } + else + { + dungeon[0][v11] = 13; + } + v11 += 40; + v10 += 2; + --v14; + } + while ( v14 ); + } + ++v15; + } + while ( v15 < v9 ); + } + DRLG_L1Floor(); + ViewX = v13; + ViewY = view_y; + DRLG_L1Pass3(); + DRLG_Init_Globals(); + DRLG_InitL1Vals(); + SetMapMonsters((char *)v4, 0, 0); + SetMapObjects((char *)v4, 0, 0); + mem_free_dbg(v4); +} +// 5CF328: using guessed type int dmaxx; +// 5CF32C: using guessed type int dmaxy; +// 5D2458: using guessed type int dminx; +// 5D245C: using guessed type int dminy; + +//----- (0040AF65) -------------------------------------------------------- +void __cdecl DRLG_L1Floor() +{ + signed int v0; // edi + signed int v1; // esi + signed int v2; // ebx + int v3; // eax + + v0 = 0; + do + { + v1 = v0; + v2 = 40; + do + { + if ( !mydflags[0][v1] && dungeon[0][v1] == 13 ) + { + v3 = random(0, 3); + if ( v3 == 1 ) + dungeon[0][v1] = -94; + if ( v3 == 2 ) + dungeon[0][v1] = -93; + } + v1 += 40; + --v2; + } + while ( v2 ); + ++v0; + } + while ( v0 < 40 ); +} + +//----- (0040AFB3) -------------------------------------------------------- +void __cdecl DRLG_L1Pass3() +{ + int v0; // eax + int *v1; // edx + int *v2; // eax + signed int v3; // ecx + signed int v4; // ebx + int *v5; // ecx + unsigned char *v6; // edx + unsigned short *v7; // esi + unsigned short v8; // ax + int v9; // eax + int v10; // ST24_4 + int v11; // ST20_4 + int v12; // ST1C_4 + signed int v13; // [esp+Ch] [ebp-1Ch] + int *v14; // [esp+10h] [ebp-18h] + int v15; // [esp+14h] [ebp-14h] + int v16; // [esp+18h] [ebp-10h] + int v17; // [esp+1Ch] [ebp-Ch] + int v18; // [esp+20h] [ebp-8h] + + v0 = *((unsigned short *)pMegaTiles + 84) + 1; + v18 = *((unsigned short *)pMegaTiles + 84) + 1; + _LOWORD(v0) = *((_WORD *)pMegaTiles + 85); + v17 = ++v0; + _LOWORD(v0) = *((_WORD *)pMegaTiles + 86); + v16 = ++v0; + _LOWORD(v0) = *((_WORD *)pMegaTiles + 87); + v15 = v0 + 1; + v1 = dPiece[1]; + do + { + v2 = v1; + v3 = 56; + do + { + *(v2 - 112) = v18; + *v2 = v17; + *(v2 - 111) = v16; + v2[1] = v15; + v2 += 224; + --v3; + } + while ( v3 ); + v1 += 2; + } + while ( (signed int)v1 < (signed int)dPiece[2] ); + v4 = 0; + v14 = &dPiece[17][16]; + do + { + v5 = v14; + v6 = (unsigned char *)dungeon + v4; + v13 = 40; + do + { + v7 = (unsigned short *)((char *)pMegaTiles + 8 * (*v6 - 1)); + v8 = *v7; + ++v7; + v9 = v8 + 1; + v10 = v9; + _LOWORD(v9) = *v7; + ++v7; + v11 = ++v9; + _LOWORD(v9) = *v7; + v12 = ++v9; + _LOWORD(v9) = v7[1]; + v6 += 40; + *(v5 - 112) = v10; + *v5 = v11; + *(v5 - 111) = v12; + v5[1] = v9 + 1; + v5 += 224; + --v13; + } + while ( v13 ); + v14 += 2; + ++v4; + } + while ( v4 < 40 ); +} + +//----- (0040B0A5) -------------------------------------------------------- +void __cdecl DRLG_InitL1Vals() +{ + int v0; // esi + int (*v1)[112]; // edx + char *v2; // ecx + int v3; // eax + char v4; // al + char v5; // [esp-4h] [ebp-18h] + signed int v6; // [esp+Ch] [ebp-8h] + int (*v7)[112]; // [esp+10h] [ebp-4h] + + v0 = 0; + v7 = dPiece; + do + { + v1 = v7; + v2 = (char *)dArch + v0; + v6 = 112; + do + { + v3 = (*v1)[0]; + if ( (*v1)[0] != 12 ) + { + if ( v3 == 11 ) + goto LABEL_21; + if ( v3 != 71 ) + { + if ( v3 == 259 ) + { + v5 = 5; +LABEL_9: + v4 = v5; + goto LABEL_22; + } + if ( v3 == 249 || v3 == 325 ) + goto LABEL_21; + if ( v3 != 321 ) + { + if ( v3 == 255 ) + { + v5 = 4; + goto LABEL_9; + } + if ( v3 != 211 ) + { + if ( v3 == 344 ) + goto LABEL_21; + if ( v3 != 341 ) + { + if ( v3 == 331 ) + goto LABEL_21; + if ( v3 != 418 ) + { + if ( v3 != 421 ) + goto LABEL_23; +LABEL_21: + v4 = 2; + goto LABEL_22; + } + } + } + } + } + } + v4 = 1; +LABEL_22: + *v2 = v4; +LABEL_23: + ++v1; + v2 += 112; + --v6; + } + while ( v6 ); + v7 = (int (*)[112])((char *)v7 + 4); + ++v0; + } + while ( (signed int)v7 < (signed int)dPiece[1] ); +} + +//----- (0040B160) -------------------------------------------------------- +void __fastcall LoadPreL1Dungeon(char *dun_path, int view_x, int view_y) +{ + unsigned char *v3; // ebx + signed int v4; // ecx + signed int v5; // eax + signed int v6; // edx + int v7; // esi + int v8; // edi + char *v9; // eax + int v10; // ecx + char v11; // dl + signed int v12; // esi + signed int v13; // eax + signed int v14; // edi + int v15; // [esp+Ch] [ebp-8h] + int v16; // [esp+10h] [ebp-4h] + + dminx = 16; + dminy = 16; + dmaxx = 96; + dmaxy = 96; + v3 = LoadFileInMem(dun_path, 0); + v4 = 0; + do + { + v5 = v4; + v6 = 40; + do + { + mydflags[0][v5] = 0; + dungeon[0][v5] = 22; + v5 += 40; + --v6; + } + while ( v6 ); + ++v4; + } + while ( v4 < 40 ); + v16 = 0; + v7 = *v3; + v8 = v3[2]; + v9 = (char *)(v3 + 4); + if ( v8 > 0 ) + { + do + { + if ( v7 > 0 ) + { + v10 = v16; + v15 = v7; + do + { + v11 = *v9; + if ( *v9 ) + { + mydflags[0][v10] |= 0x80u; + dungeon[0][v10] = v11; + } + else + { + dungeon[0][v10] = 13; + } + v10 += 40; + v9 += 2; + --v15; + } + while ( v15 ); + } + ++v16; + } + while ( v16 < v8 ); + } + DRLG_L1Floor(); + v12 = 0; + do + { + v13 = v12; + v14 = 40; + do + { + pdungeon[0][v13] = dungeon[0][v13]; + v13 += 40; + --v14; + } + while ( v14 ); + ++v12; + } + while ( v12 < 40 ); + mem_free_dbg(v3); +} +// 5CF328: using guessed type int dmaxx; +// 5CF32C: using guessed type int dmaxy; +// 5D2458: using guessed type int dminx; +// 5D245C: using guessed type int dminy; + +//----- (0040B229) -------------------------------------------------------- +void __fastcall CreateL5Dungeon(int seed, int entry) +{ + int v2; // esi + + v2 = entry; + SetRndSeed(seed); + dminx = 16; + dminy = 16; + dmaxx = 96; + dmaxy = 96; + DRLG_InitTrans(); + DRLG_InitSetPC(); + DRLG_LoadL1SP(); + DRLG_L5(v2); + DRLG_L1Pass3(); + DRLG_FreeL1SP(); + DRLG_InitL1Vals(); + DRLG_SetPC(); +} +// 5CF328: using guessed type int dmaxx; +// 5CF32C: using guessed type int dmaxy; +// 5D2458: using guessed type int dminx; +// 5D245C: using guessed type int dminy; + +//----- (0040B276) -------------------------------------------------------- +void __cdecl DRLG_LoadL1SP() +{ + int v0; // eax + int v1; // eax + int v2; // eax + + setloadflag = 0; + _LOBYTE(v0) = QuestStatus(6); + if ( v0 ) + { + pSetPiece = LoadFileInMem("Levels\\L1Data\\rnd6.DUN", 0); + setloadflag = 1; + } + _LOBYTE(v1) = QuestStatus(12); + if ( v1 && gbMaxPlayers == 1 ) + { + pSetPiece = LoadFileInMem("Levels\\L1Data\\SKngDO.DUN", 0); + setloadflag = 1; + } + _LOBYTE(v2) = QuestStatus(7); + if ( v2 ) + { + pSetPiece = LoadFileInMem("Levels\\L1Data\\Banner2.DUN", 0); + setloadflag = 1; + } +} +// 5276A4: using guessed type int setloadflag; +// 679660: using guessed type char gbMaxPlayers; + +//----- (0040B2F4) -------------------------------------------------------- +void __cdecl DRLG_FreeL1SP() +{ + void *v0; // ecx + + v0 = pSetPiece; + pSetPiece = 0; + mem_free_dbg(v0); +} + +//----- (0040B306) -------------------------------------------------------- +void __fastcall DRLG_L5(int entry) +{ + signed int v1; // esi + signed int v2; // edi + int v3; // eax + int v4; // eax + int v5; // eax + int v6; // ebx + int v7; // edi + int v8; // edi + int v9; // ebp + _BYTE *v10; // ebx + signed int v11; // eax + signed int v12; // ecx + int v13; // [esp+10h] [ebp-8h] + int v14; // [esp+10h] [ebp-8h] + int v15; // [esp+14h] [ebp-4h] + _BYTE *v16; // [esp+14h] [ebp-4h] + + v13 = entry; + if ( currlevel == 1 ) + { + v15 = 533; + } + else if ( currlevel == 2 ) + { + v15 = 693; + } + else if ( currlevel > 2u && currlevel <= 4u ) + { + v15 = 761; + } + v1 = 0; + while ( 1 ) + { + DRLG_InitTrans(); + do + { + InitL5Dungeon(); + L5firstRoom(); + } + while ( L5GetArea() < v15 ); + L5makeDungeon(); + L5makeDmt(); + L5FillChambers(); + L5tileFix(); + L5AddWall(); + L5ClearFlags(); + DRLG_L5FloodTVal(); + v2 = 1; + _LOBYTE(v3) = QuestStatus(13); + if ( v3 ) + { + if ( v13 ) + { + if ( DRLG_PlaceMiniSet((char *)PWATERIN, 1, 1, 0, 0, 0, -1, 0) < 0 ) + v2 = 0; + --ViewY; + } + else if ( DRLG_PlaceMiniSet((char *)PWATERIN, 1, 1, 0, 0, 1, -1, 0) < 0 ) + { + v2 = 0; + } + } + _LOBYTE(v4) = QuestStatus(7); + if ( v4 ) + { + if ( !v13 ) + { + v5 = DRLG_PlaceMiniSet((char *)STAIRSUP, 1, 1, 0, 0, 1, -1, 0); + goto LABEL_21; + } + if ( DRLG_PlaceMiniSet((char *)STAIRSUP, 1, 1, 0, 0, 0, -1, 0) < 0 ) + v2 = 0; + if ( v13 == 1 ) + { + ViewX = 2 * setpc_x + 20; + ViewY = 2 * setpc_y + 28; + goto LABEL_34; + } +LABEL_33: + --ViewY; + goto LABEL_34; + } + if ( v13 ) + { + if ( DRLG_PlaceMiniSet((char *)L5STAIRSUP, 1, 1, 0, 0, 0, -1, 0) < 0 + || DRLG_PlaceMiniSet((char *)STAIRSDOWN, 1, 1, 0, 0, 1, -1, 1) < 0 ) + { + v2 = 0; + } + goto LABEL_33; + } + if ( DRLG_PlaceMiniSet((char *)L5STAIRSUP, 1, 1, 0, 0, 1, -1, 0) >= 0 ) + { + v5 = DRLG_PlaceMiniSet((char *)STAIRSDOWN, 1, 1, 0, 0, 0, -1, 1); +LABEL_21: + if ( v5 < 0 ) + v2 = 0; +LABEL_34: + if ( v2 ) + break; + } + } + v14 = 0; + v6 = 16; + do + { + v7 = 16; + v16 = (unsigned char *)dungeon + v14; + do + { + if ( *v16 == 64 ) + { + DRLG_CopyTrans(v7, v6 + 1, v7, v6); + DRLG_CopyTrans(v7 + 1, v6 + 1, v7 + 1, v6); + } + v16 += 40; + v7 += 2; + } + while ( v7 < 96 ); + ++v14; + v6 += 2; + } + while ( v6 < 96 ); + DRLG_L5TransFix(); + DRLG_L5DirtFix(); + DRLG_L5CornerFix(); + v8 = 0; + do + { + v9 = 0; + v10 = (unsigned char *)mydflags + v8; + do + { + if ( *v10 & 0x7F ) + DRLG_PlaceDoor(v9, v8); + ++v9; + v10 += 40; + } + while ( v9 < 40 ); + ++v8; + } + while ( v8 < 40 ); + DRLG_L5Subs(); + DRLG_L1Shadows(); + DRLG_PlaceMiniSet((char *)LAMPS, 5, 10, 0, 0, 0, -1, 4); + DRLG_L1Floor(); + do + { + v11 = v1; + v12 = 40; + do + { + pdungeon[0][v11] = dungeon[0][v11]; + v11 += 40; + --v12; + } + while ( v12 ); + ++v1; + } + while ( v1 < 40 ); + DRLG_Init_Globals(); + DRLG_CheckQuests(setpc_x, setpc_y); +} + +//----- (0040B56F) -------------------------------------------------------- +void __fastcall DRLG_PlaceDoor(int tx, int ty) +{ + int v2; // edi + char *v3; // eax + char v4; // al + char v5; // dl + char *v6; // eax + char v7; // bl + char *v8; // [esp+Ch] [ebp-8h] + + v2 = ty; + v3 = &mydflags[tx][ty]; + v8 = v3; + v4 = *v3; + if ( v4 < 0 ) + goto LABEL_57; + v5 = v4 & 0x7F; + v6 = &dungeon[tx][v2]; + v7 = *v6; + if ( v5 == 1 ) + { + if ( v2 != 1 ) + { + if ( v7 == 2 ) + *v6 = 26; + if ( v7 == 7 ) + *v6 = 31; + if ( v7 == 14 ) + *v6 = 42; + if ( v7 == 4 ) + *v6 = 43; + } + if ( tx == 1 ) + goto LABEL_57; + if ( v7 == 1 ) + *v6 = 25; + if ( v7 == 10 ) + *v6 = 40; + if ( v7 != 6 ) + goto LABEL_57; + *v6 = 30; + } + if ( v5 != 2 ) + goto LABEL_36; + if ( tx != 1 ) + { + if ( v7 == 1 ) + *v6 = 25; + if ( v7 == 6 ) + *v6 = 30; + if ( v7 == 10 ) + *v6 = 40; + if ( v7 == 4 ) + *v6 = 41; + } + if ( v2 != 1 ) + { + if ( v7 == 2 ) + *v6 = 26; + if ( v7 == 14 ) + *v6 = 42; + if ( v7 == 7 ) + { + *v6 = 31; +LABEL_36: + if ( v5 == 3 ) + { + if ( tx != 1 ) + { + if ( v2 != 1 && v7 == 4 ) + *v6 = 28; + if ( v7 == 10 ) + *v6 = 40; + } + if ( v2 != 1 ) + { + if ( v7 == 14 ) + *v6 = 42; + if ( v7 == 2 ) + *v6 = 26; + } + if ( tx != 1 && v7 == 1 ) + *v6 = 25; + if ( v2 != 1 && v7 == 7 ) + *v6 = 31; + if ( tx != 1 && v7 == 6 ) + *v6 = 30; + } + goto LABEL_57; + } + } +LABEL_57: + *v8 = -128; +} + +//----- (0040B699) -------------------------------------------------------- +void __cdecl DRLG_L1Shadows() +{ + signed int v0; // ebx + char *v1; // eax + signed int v2; // edx + unsigned char *v3; // esi + signed int v4; // edi + char v5; // cl + char v6; // cl + char v7; // cl + char v8; // cl + char v9; // cl + signed int v10; // edi + signed int v11; // eax + signed int v12; // esi + char v13; // cl + char v14; // dl + char v15; // cl + char v16; // dl + char v17; // cl + char v18; // dl + unsigned char v19; // [esp+Ch] [ebp-4h] + unsigned char v20; // [esp+Dh] [ebp-3h] + unsigned char v21; // [esp+Eh] [ebp-2h] + unsigned char v22; // [esp+Fh] [ebp-1h] + + v0 = 1; + do + { + v1 = &dungeon[0][v0 + 39]; + v2 = 40; + do + { + v3 = &SPATS[0].s1; + v19 = BSTYPES[(unsigned char)v1[1]]; + v21 = BSTYPES[(unsigned char)*(v1 - 39)]; + v20 = BSTYPES[(unsigned char)*v1]; + v22 = BSTYPES[(unsigned char)*(v1 - 40)]; + do + { + if ( *(v3 - 1) == v19 ) + { + v4 = 1; + if ( *v3 && *v3 != v22 ) + v4 = 0; + v5 = v3[1]; + if ( v5 && v5 != v20 ) + v4 = 0; + v6 = v3[2]; + if ( v6 && v6 != v21 ) + v4 = 0; + if ( v4 == 1 ) + { + v7 = v3[3]; + if ( v7 && !L5dungeon[79][v2 + 39 + v0] ) + *(v1 - 40) = v7; + v8 = v3[4]; + if ( v8 && !L5dungeon[79][v2 + 79 + v0] ) + *v1 = v8; + v9 = v3[5]; + if ( v9 && !L5dungeon[79][v2 + 40 + v0] ) + *(v1 - 39) = v9; + } + } + v3 += 7; + } + while ( (signed int)v3 < (signed int)BSTYPES ); + v2 += 40; + v1 += 40; + } + while ( v2 < 1600 ); + ++v0; + } + while ( v0 < 40 ); + v10 = 1; + do + { + v11 = v10; + v12 = 39; + do + { + if ( dungeon[0][v11] == -117 && !mydflags[0][v11] ) + { + v13 = dungeon[1][v11]; + v14 = -117; + if ( v13 == 29 ) + v14 = -115; + if ( v13 == 32 ) + v14 = -115; + if ( v13 == 35 ) + v14 = -115; + if ( v13 == 37 ) + v14 = -115; + if ( v13 == 38 ) + v14 = -115; + if ( v13 == 39 ) + v14 = -115; + dungeon[0][v11] = v14; + } + if ( dungeon[0][v11] == -107 && !mydflags[0][v11] ) + { + v15 = dungeon[1][v11]; + v16 = -107; + if ( v15 == 29 ) + v16 = -103; + if ( v15 == 32 ) + v16 = -103; + if ( v15 == 35 ) + v16 = -103; + if ( v15 == 37 ) + v16 = -103; + if ( v15 == 38 ) + v16 = -103; + if ( v15 == 39 ) + v16 = -103; + dungeon[0][v11] = v16; + } + if ( dungeon[0][v11] == -108 && !mydflags[0][v11] ) + { + v17 = dungeon[1][v11]; + v18 = -108; + if ( v17 == 29 ) + v18 = -102; + if ( v17 == 32 ) + v18 = -102; + if ( v17 == 35 ) + v18 = -102; + if ( v17 == 37 ) + v18 = -102; + if ( v17 == 38 ) + v18 = -102; + if ( v17 == 39 ) + v18 = -102; + dungeon[0][v11] = v18; + } + v11 += 40; + --v12; + } + while ( v12 ); + ++v10; + } + while ( v10 < 40 ); +} + +//----- (0040B881) -------------------------------------------------------- +int __fastcall DRLG_PlaceMiniSet(char *miniset, int tmin, int tmax, int cx, int cy, bool set_view, int noquad, int ldir) +{ + unsigned char *v8; // ebx + int v9; // edi + int v10; // esi + int v11; // edx + int v12; // eax + int v13; // ecx + int v14; // esi + int v15; // edi + int v16; // ebx + signed int v17; // edx + int v18; // eax + char v19; // cl + int v20; // ebx + int result; // eax + int v22; // eax + char v23; // dl + char v24; // bl + bool v25; // zf + bool v26; // sf + unsigned char v27; // of + int v28; // [esp-4h] [ebp-34h] + int v29; // [esp+Ch] [ebp-24h] + char *v30; // [esp+10h] [ebp-20h] + int v31; // [esp+14h] [ebp-1Ch] + int v32; // [esp+18h] [ebp-18h] + int v33; // [esp+1Ch] [ebp-14h] + signed int v34; // [esp+20h] [ebp-10h] + int max; // [esp+24h] [ebp-Ch] + int v36; // [esp+28h] [ebp-8h] + int v37; // [esp+2Ch] [ebp-4h] + int tmaxa; // [esp+38h] [ebp+8h] + int tmaxb; // [esp+38h] [ebp+8h] + + v8 = (unsigned char *)miniset; + v9 = (unsigned char)*miniset; + v10 = tmin; + v11 = tmax - tmin; + v30 = miniset; + v36 = (unsigned char)*miniset; + v37 = (unsigned char)miniset[1]; + if ( v11 ) + { + _LOBYTE(miniset) = 0; + v31 = v10 + random((int)miniset, v11); + } + else + { + v31 = 1; + } + v32 = 0; + if ( v31 > 0 ) + { + max = 40 - v9; + v29 = 40 - v37; + while ( 1 ) + { + _LOBYTE(miniset) = 0; + v12 = random((int)miniset, max); + _LOBYTE(v13) = 0; + v14 = v12; + v33 = 0; + v15 = random(v13, v29); + while ( 1 ) + { + tmaxa = 1; + if ( cx != -1 && v14 >= cx - v36 && v14 <= cx + 12 ) + { + ++v14; + tmaxa = 0; + } + miniset = (char *)cy; + if ( cy != -1 && v15 >= cy - v37 && v15 <= cy + 12 ) + { + ++v15; + tmaxa = 0; + } + v16 = 0; + switch ( noquad ) + { + case 0: + if ( v14 >= cx ) + goto LABEL_29; + goto LABEL_27; + case 1: + if ( v14 <= cx ) + goto LABEL_29; +LABEL_27: + if ( v15 >= cy ) + goto LABEL_29; +LABEL_28: + tmaxa = 0; + goto LABEL_29; + case 2: + if ( v14 >= cx ) + goto LABEL_29; +LABEL_22: + if ( v15 <= cy ) + goto LABEL_29; + goto LABEL_28; + } + if ( noquad == 3 && v14 > cx ) + goto LABEL_22; +LABEL_29: + v17 = 2; + if ( v37 > 0 ) + { + do + { + if ( tmaxa != 1 ) + break; + v34 = 0; + if ( v36 > 0 ) + { + v18 = v15 + v16 + 40 * v14; + do + { + if ( tmaxa != 1 ) + break; + v19 = v30[v17]; + if ( v19 && dungeon[0][v18] != v19 ) + tmaxa = 0; + if ( mydflags[0][v18] ) + tmaxa = 0; + miniset = (char *)v36; + ++v17; + ++v34; + v18 += 40; + } + while ( v34 < v36 ); + } + ++v16; + } + while ( v16 < v37 ); + } + v20 = 0; + if ( tmaxa ) + break; + if ( ++v14 == max ) + { + v14 = 0; + if ( ++v15 == v29 ) + v15 = 0; + } + if ( ++v33 > 4000 ) + return -1; + } + v22 = v36 * v37 + 2; + if ( v37 > 0 ) + { + do + { + if ( v36 > 0 ) + { + tmaxb = v36; + miniset = &dungeon[v14][v20 + v15]; + do + { + v23 = v30[v22]; + if ( v23 ) + *miniset = v23; + ++v22; + miniset += 40; + --tmaxb; + } + while ( tmaxb ); + } + ++v20; + } + while ( v20 < v37 ); + } + if ( ++v32 >= v31 ) + { + v8 = (unsigned char *)v30; + goto LABEL_57; + } + } + } + v14 = cx; + v15 = cx; +LABEL_57: + if ( v8 == PWATERIN ) + { + v24 = TransVal; + TransVal = 0; + Make_RectTrans(v14, v15 + 2, v14 + 5, v15 + 4); + TransVal = v24; + quests[13]._qtx = 2 * v14 + 21; + quests[13]._qty = 2 * v15 + 22; + } + result = 1; + if ( set_view == 1 ) + { + ViewX = 2 * v14 + 19; + ViewY = 2 * v15 + 20; + } + if ( !ldir ) + { + LvlViewX = 2 * v14 + 19; + LvlViewY = 2 * v15 + 20; + } + v27 = __OFSUB__(v14, cx); + v25 = v14 == cx; + v26 = v14 - cx < 0; + if ( v14 < cx ) + { + if ( v15 < cy ) + return 0; + v27 = __OFSUB__(v14, cx); + v25 = v14 == cx; + v26 = v14 - cx < 0; + } + if ( (unsigned char)(v26 ^ v27) | v25 || v15 >= cy ) + { + if ( v14 >= cx || v15 <= cy ) + v28 = 3; + else + v28 = 2; + result = v28; + } + return result; +} +// 5A5590: using guessed type char TransVal; +// 5CF320: using guessed type int LvlViewY; +// 5CF324: using guessed type int LvlViewX; + +//----- (0040BAF6) -------------------------------------------------------- +void __cdecl InitL5Dungeon() +{ + signed int v0; // edx + signed int v1; // eax + signed int v2; // ecx + + v0 = 0; + do + { + v1 = v0; + v2 = 40; + do + { + dungeon[0][v1] = 0; + mydflags[0][v1] = 0; + v1 += 40; + --v2; + } + while ( v2 ); + ++v0; + } + while ( v0 < 40 ); +} + +//----- (0040BB18) -------------------------------------------------------- +void __cdecl L5ClearFlags() +{ + signed int v0; // ecx + _BYTE *v1; // eax + signed int v2; // edx + + v0 = 0; + do + { + v1 = (unsigned char *)mydflags + v0; + v2 = 40; + do + { + *v1 &= 0xBFu; + v1 += 40; + --v2; + } + while ( v2 ); + ++v0; + } + while ( v0 < 40 ); +} + +//----- (0040BB33) -------------------------------------------------------- +void __cdecl L5firstRoom() +{ + signed int v0; // ebx + signed int v1; // ebp + signed int i; // ecx + char *v3; // eax + signed int v4; // ebp + signed int v5; // ebx + int v6; // ebp + _BYTE *v7; // eax + + if ( random(0, 2) ) + { + v4 = 39; + v5 = 1; + HR1 = random(0, 2); + HR2 = random(0, 2); + HR3 = random(0, 2); + if ( HR1 + HR3 <= 1 ) + HR2 = 1; + if ( HR1 ) + L5drawRoom(1, 15, 10, 10); + else + v5 = 18; + if ( HR2 ) + L5drawRoom(15, 15, 10, 10); + if ( HR3 ) + L5drawRoom(29, 15, 10, 10); + else + v4 = 22; + if ( v5 < v4 ) + { + v6 = v4 - v5; + v7 = (_BYTE *)(40 * v5 + 5477914); + do + { + *(v7 - 1) = 1; + *v7 = 1; + v7[1] = 1; + v7[2] = 1; + v7[3] = 1; + v7[4] = 1; + v7 += 40; + --v6; + } + while ( v6 ); + } + if ( HR1 ) + L5roomGen(1, 15, 10, 10, 1); + if ( HR2 ) + L5roomGen(15, 15, 10, 10, 1); + if ( HR3 ) + L5roomGen(29, 15, 10, 10, 1); + VR3 = 0; + VR2 = 0; + VR1 = 0; + } + else + { + v0 = 39; + v1 = 1; + VR1 = random(0, 2); + VR2 = random(0, 2); + VR3 = random(0, 2); + if ( VR1 + VR3 <= 1 ) + VR2 = 1; + if ( VR1 ) + L5drawRoom(15, 1, 10, 10); + else + v1 = 18; + if ( VR2 ) + L5drawRoom(15, 15, 10, 10); + if ( VR3 ) + L5drawRoom(15, 29, 10, 10); + else + v0 = 22; + for ( i = v1; i < v0; v3[160] = 1 ) + { + v3 = &dungeon[18][i++]; + *(v3 - 40) = 1; + *v3 = 1; + v3[40] = 1; + v3[80] = 1; + v3[120] = 1; + } + if ( VR1 ) + L5roomGen(15, 1, 10, 10, 0); + if ( VR2 ) + L5roomGen(15, 15, 10, 10, 0); + if ( VR3 ) + L5roomGen(15, 29, 10, 10, 0); + HR3 = 0; + HR2 = 0; + HR1 = 0; + } +} + +//----- (0040BD66) -------------------------------------------------------- +void __fastcall L5drawRoom(int tx, int ty, int tw, int th) +{ + int i; // esi + int v5; // edi + char *v6; // eax + + for ( i = 0; i < th; ++i ) + { + if ( tw > 0 ) + { + v5 = tw; + v6 = &dungeon[tx][i + ty]; + do + { + *v6 = 1; + v6 += 40; + --v5; + } + while ( v5 ); + } + } +} + +//----- (0040BD9D) -------------------------------------------------------- +void __fastcall L5roomGen(int tx, int ty, int tw, int th, bool dir_horiz) +{ + int v5; // eax + int v6; // ecx + int v7; // eax + int v8; // ecx + int v9; // eax + int v10; // ecx + int v11; // esi + int v12; // edi + int v13; // ebx + int v14; // eax + int v15; // eax + int v16; // eax + int v17; // ecx + int v18; // esi + int v19; // edi + int v20; // ebx + int v21; // eax + int v22; // eax + int tya; // [esp+Ch] [ebp-10h] + int tyb; // [esp+Ch] [ebp-10h] + int v25; // [esp+10h] [ebp-Ch] + int v26; // [esp+10h] [ebp-Ch] + int txa; // [esp+14h] [ebp-8h] + int txb; // [esp+14h] [ebp-8h] + int v29; // [esp+18h] [ebp-4h] + int twa; // [esp+24h] [ebp+8h] + int tha; // [esp+28h] [ebp+Ch] + int thb; // [esp+28h] [ebp+Ch] + int thc; // [esp+28h] [ebp+Ch] + signed int dir_horiza; // [esp+2Ch] [ebp+10h] + signed int dir_horizb; // [esp+2Ch] [ebp+10h] + + v29 = ty; + txa = tx; + while ( 1 ) + { + while ( 1 ) + { + _LOBYTE(tx) = 0; + v5 = random(tx, 4); + v6 = 0; + _LOBYTE(v6) = dir_horiz == 1 ? v5 != 0 : v5 == 0; + v7 = v6; + v8 = 0; + if ( !v7 ) + break; + if ( v7 != 1 ) + return; + dir_horiza = 0; + twa = tw / 2; + do + { + _LOBYTE(v8) = 0; + v9 = random(v8, 5); + _LOBYTE(v10) = 0; + v11 = (v9 + 2) & 0xFFFFFFFE; + v12 = (random(v10, 5) + 2) & 0xFFFFFFFE; + v13 = txa + twa - v11 / 2; + tya = v29 - v12; + _LOBYTE(v14) = L5checkRoom(v13 - 1, v29 - v12 - 1, v11 + 2, v12 + 1); + ++dir_horiza; + v25 = v14; + } + while ( !v14 && dir_horiza < 20 ); + if ( v14 == 1 ) + L5drawRoom(v13, tya, v11, v12); + txb = v29 + th; + _LOBYTE(v15) = L5checkRoom(v13 - 1, v29 + th, v11 + 2, v12 + 1); + tha = v15; + if ( v15 == 1 ) + L5drawRoom(v13, txb, v11, v12); + if ( v25 == 1 ) + L5roomGen(v13, tya, v11, v12, 0); + if ( tha != 1 ) + return; + *(_DWORD *)&dir_horiz = 0; + th = v12; + tw = v11; + v29 = txb; + txa = v13; + } + dir_horizb = 0; + thb = th / 2; + do + { + _LOBYTE(v8) = 0; + v16 = random(v8, 5); + _LOBYTE(v17) = 0; + v18 = (v16 + 2) & 0xFFFFFFFE; + v19 = (random(v17, 5) + 2) & 0xFFFFFFFE; + v20 = v29 + thb - v19 / 2; + tyb = txa - v18; + _LOBYTE(v21) = L5checkRoom(txa - v18 - 1, v20 - 1, v19 + 2, v18 + 1); + ++dir_horizb; + v26 = v21; + } + while ( !v21 && dir_horizb < 20 ); + if ( v21 == 1 ) + L5drawRoom(tyb, v20, v18, v19); + txa += tw; + _LOBYTE(v22) = L5checkRoom(txa, v20 - 1, v18 + 1, v19 + 2); + thc = v22; + if ( v22 == 1 ) + L5drawRoom(txa, v20, v18, v19); + if ( v26 == 1 ) + L5roomGen(tyb, v20, v18, v19, 1); + if ( thc != 1 ) + break; + *(_DWORD *)&dir_horiz = 1; + th = v19; + tw = v18; + v29 = v20; + } +} + +//----- (0040BFA4) -------------------------------------------------------- +bool __fastcall L5checkRoom(int tx, int ty, int tw, int th) +{ + int v4; // eax + int v5; // ebx + char *v6; // edi + int v8; // [esp+Ch] [ebp-4h] + + v4 = 0; + if ( th <= 0 ) + return 1; + while ( 1 ) + { + v8 = 0; + if ( tw > 0 ) + break; +LABEL_10: + if ( ++v4 >= th ) + return 1; + } + v5 = tx; + v6 = &dungeon[tx][v4 + ty]; + while ( v5 >= 0 && v5 < 40 && v4 + ty >= 0 && v4 + ty < 40 && !*v6 ) + { + ++v8; + v6 += 40; + ++v5; + if ( v8 >= tw ) + goto LABEL_10; + } + return 0; +} + +//----- (0040C008) -------------------------------------------------------- +int __cdecl L5GetArea() +{ + int result; // eax + signed int v1; // edx + _BYTE *v2; // ecx + signed int v3; // esi + + result = 0; + v1 = 0; + do + { + v2 = (unsigned char *)dungeon + v1; + v3 = 40; + do + { + if ( *v2 == 1 ) + ++result; + v2 += 40; + --v3; + } + while ( v3 ); + ++v1; + } + while ( v1 < 40 ); + return result; +} + +//----- (0040C02A) -------------------------------------------------------- +void __cdecl L5makeDungeon() +{ + signed int v0; // edi + signed int v1; // esi + char *v2; // edx + char v3; // cl + int v4; // eax + int v5; // eax + + v0 = 0; + do + { + v1 = 0; + v2 = (char *)dungeon + v0; + do + { + v3 = *v2; + v2 += 40; + v4 = 160 * v1++; + v5 = v4 + 2 * v0; + L5dungeon[0][v5] = v3; + L5dungeon[0][v5 + 1] = v3; + L5dungeon[1][v5] = v3; + L5dungeon[1][v5 + 1] = v3; + } + while ( v1 < 40 ); + ++v0; + } + while ( v0 < 40 ); +} + +//----- (0040C06E) -------------------------------------------------------- +void __cdecl L5makeDmt() +{ + signed int v0; // ecx + _BYTE *v1; // eax + signed int v2; // edx + signed int v3; // esi + char (*v4)[40]; // ecx + char *v5; // eax + signed int v6; // edi + int v7; // edx + int v8; // ebx + char (*v9)[40]; // [esp+0h] [ebp-4h] + + v0 = 0; + do + { + v1 = (unsigned char *)dungeon + v0; + v2 = 40; + do + { + *v1 = 22; + v1 += 40; + --v2; + } + while ( v2 ); + ++v0; + } + while ( v0 < 40 ); + v3 = 1; + v9 = dungeon; + do + { + v4 = v9; + v5 = &L5dungeon[1][v3 + 1]; + v6 = 39; + do + { + v7 = (unsigned char)v5[80]; + v8 = (unsigned char)*v5; + v5 += 160; + *(_BYTE *)v4 = L5ConvTbl[2 * ((unsigned char)*(v5 - 81) + 2 * (v8 + 2 * v7)) + + (unsigned char)*(v5 - 161)]; + ++v4; + --v6; + } + while ( v6 ); + v9 = (char (*)[40])((char *)v9 + 1); + v3 += 2; + } + while ( v3 <= 77 ); +} + +//----- (0040C0E0) -------------------------------------------------------- +void __cdecl L5AddWall() +{ + int v0; // edi + int v1; // esi + int v2; // ebx + int v3; // eax + int v4; // eax + int v5; // eax + int v6; // eax + int v7; // eax + int v8; // eax + + v0 = 0; + do + { + v1 = 0; + v2 = v0; + do + { + if ( !mydflags[0][v2] ) + { + if ( dungeon[0][v2] == 3 ) + { + if ( random(0, 100) < 100 ) + { + v3 = L5HWallOk(v1, v0); + if ( v3 != -1 ) + L5HorizWall(v1, v0, 2, v3); + } + if ( dungeon[0][v2] == 3 && random(0, 100) < 100 ) + { + v4 = L5VWallOk(v1, v0); + if ( v4 != -1 ) + L5VertWall(v1, v0, 1, v4); + } + } + if ( dungeon[0][v2] == 6 && random(0, 100) < 100 ) + { + v5 = L5HWallOk(v1, v0); + if ( v5 != -1 ) + L5HorizWall(v1, v0, 4, v5); + } + if ( dungeon[0][v2] == 7 && random(0, 100) < 100 ) + { + v6 = L5VWallOk(v1, v0); + if ( v6 != -1 ) + L5VertWall(v1, v0, 4, v6); + } + if ( dungeon[0][v2] == 2 && random(0, 100) < 100 ) + { + v7 = L5HWallOk(v1, v0); + if ( v7 != -1 ) + L5HorizWall(v1, v0, 2, v7); + } + if ( dungeon[0][v2] == 1 && random(0, 100) < 100 ) + { + v8 = L5VWallOk(v1, v0); + if ( v8 != -1 ) + L5VertWall(v1, v0, 1, v8); + } + } + ++v1; + v2 += 40; + } + while ( v1 < 40 ); + ++v0; + } + while ( v0 < 40 ); +} + +//----- (0040C23C) -------------------------------------------------------- +int __fastcall L5HWallOk(int tx, int ty) +{ + int v2; // esi + char *v3; // edi + int v4; // eax + char *v5; // ebx + signed int v6; // eax + char v7; // dl + int result; // eax + int v9; // [esp+8h] [ebp-4h] + + v2 = 8 * (5 * tx + 5); + v9 = 1; + v3 = (char *)dungeon + v2 + ty; + if ( *v3 == 13 ) + { + v4 = 8 * (5 * tx + 5); + v5 = &dungeon[tx + 1][ty]; + do + { + if ( *(v3 - 1) != 13 ) + break; + if ( dungeon[0][v2 + 1 + ty] != 13 ) + break; + if ( mydflags[0][v2 + ty] ) + break; + ++v9; + v5 += 40; + v4 += 40; + v3 = v5; + v2 = v4; + } + while ( *v5 == 13 ); + } + v6 = 0; + v7 = dungeon[v9 + tx][ty]; + if ( (unsigned char)v7 >= 3u && (unsigned char)v7 <= 7u ) + v6 = 1; + if ( (unsigned char)v7 >= 0x10u && (unsigned char)v7 <= 0x18u ) + v6 = 1; + if ( v7 == 22 ) + v6 = 0; + if ( v9 == 1 ) + v6 = 0; + if ( v6 ) + result = v9; + else + result = -1; + return result; +} + +//----- (0040C2DC) -------------------------------------------------------- +int __fastcall L5VWallOk(int tx, int ty) +{ + int v2; // ecx + int result; // eax + char *v4; // esi + signed int v5; // esi + char v6; // dl + + v2 = tx; + result = 1; + if ( dungeon[v2][ty + 1] == 13 ) + { + v4 = &dungeon[v2][ty]; + do + { + if ( v4[result - 40] != 13 ) + break; + if ( dungeon[v2 + 1][result + ty] != 13 ) + break; + if ( mydflags[v2][result + ty] ) + break; + ++result; + } + while ( v4[result] == 13 ); + } + v5 = 0; + v6 = dungeon[0][result + v2 * 40 + ty]; + if ( (unsigned char)v6 >= 3u && (unsigned char)v6 <= 7u ) + v5 = 1; + if ( (unsigned char)v6 >= 0x10u && (unsigned char)v6 <= 0x18u ) + v5 = 1; + if ( v6 == 22 ) + v5 = 0; + if ( result == 1 ) + v5 = 0; + if ( !v5 ) + result = -1; + return result; +} + +//----- (0040C35B) -------------------------------------------------------- +void __fastcall L5HorizWall(int tx, int ty, int tile_id, int tw) +{ + int v4; // edi + int v5; // esi + int v6; // eax + int v7; // ecx + char v8; // bl + int v9; // eax + int v10; // ecx + char *v11; // edi + int v12; // eax + int v13; // eax + int v14; // eax + int v15; // [esp+8h] [ebp-8h] + char v16; // [esp+Fh] [ebp-1h] + + v4 = ty; + v5 = tx; + _LOBYTE(tx) = 0; + v15 = ty; + v6 = random(tx, 4); + if ( v6 >= 0 ) + { + if ( v6 <= 1 ) + { + v16 = 2; + } + else if ( v6 == 2 ) + { + v16 = 12; + if ( (_BYTE)tile_id == 2 ) + _LOBYTE(tile_id) = 12; + if ( (_BYTE)tile_id == 4 ) + _LOBYTE(tile_id) = 10; + } + else if ( v6 == 3 ) + { + v16 = 36; + if ( (_BYTE)tile_id == 2 ) + _LOBYTE(tile_id) = 36; + if ( (_BYTE)tile_id == 4 ) + _LOBYTE(tile_id) = 27; + } + } + _LOBYTE(v7) = 0; + v8 = random(v7, 6) != 5 ? 26 : 12; + if ( v16 == 12 ) + v8 = 12; + v9 = v4 + 40 * v5; + dungeon[0][v9] = tile_id; + v10 = tw; + if ( tw > 1 ) + { + v11 = &dungeon[1][v9]; + v12 = tw - 1; + do + { + *v11 = v16; + v11 += 40; + --v12; + } + while ( v12 ); + v4 = v15; + } + _LOBYTE(v10) = 0; + v13 = random(v10, tw - 1) + 1; + if ( v8 == 12 ) + { + dungeon[v5 + v13][v4] = 12; + } + else + { + v14 = v4 + 40 * (v5 + v13); + mydflags[0][v14] |= 1u; + dungeon[0][v14] = 2; + } +} + +//----- (0040C449) -------------------------------------------------------- +void __fastcall L5VertWall(int tx, int ty, int tile_id, int th) +{ + int v4; // edi + int v5; // esi + int v6; // eax + int v7; // ecx + int v8; // eax + int v9; // ebx + int v10; // esi + int v11; // ecx + char *v12; // edi + int v13; // eax + unsigned int v14; // ecx + int v15; // edx + int v16; // eax + int v17; // eax + int v18; // [esp+8h] [ebp-8h] + char v19; // [esp+Eh] [ebp-2h] + char v20; // [esp+Fh] [ebp-1h] + + v4 = ty; + v5 = tx; + _LOBYTE(tx) = 0; + v18 = ty; + v6 = random(tx, 4); + if ( v6 >= 0 ) + { + if ( v6 <= 1 ) + { + v20 = 1; + } + else if ( v6 == 2 ) + { + v20 = 11; + if ( (_BYTE)tile_id == 1 ) + _LOBYTE(tile_id) = 11; + if ( (_BYTE)tile_id == 4 ) + _LOBYTE(tile_id) = 14; + } + else if ( v6 == 3 ) + { + v20 = 35; + if ( (_BYTE)tile_id == 1 ) + _LOBYTE(tile_id) = 35; + if ( (_BYTE)tile_id == 4 ) + _LOBYTE(tile_id) = 37; + } + } + _LOBYTE(v7) = 0; + v8 = random(v7, 6); + v9 = 5 - v8; + _LOBYTE(v9) = v8 != 5 ? 25 : 11; + v19 = v8 != 5 ? 25 : 11; + if ( v20 == 11 ) + { + _LOBYTE(v9) = 11; + v19 = 11; + } + v10 = v5; + dungeon[v10][v4] = tile_id; + v11 = th; + if ( th > 1 ) + { + v12 = &dungeon[v10][v4 + 1]; + _LOBYTE(v9) = v20; + BYTE1(v9) = v20; + v13 = v9 << 16; + _LOWORD(v13) = v9; + _LOBYTE(v9) = v19; + v14 = (unsigned int)(th - 1) >> 2; + memset(v12, v13, v14); + memset(&v12[4 * v14], v13, ((_BYTE)th - 1) & 3); + v11 = th; + v4 = v18; + } + v15 = v11 - 1; + _LOBYTE(v11) = 0; + v16 = random(v11, v15) + 1; + if ( (_BYTE)v9 == 11 ) + { + dungeon[0][v16 + v10 * 40 + v4] = 11; + } + else + { + v17 = v16 + v10 * 40 + v4; + mydflags[0][v17] |= 2u; + dungeon[0][v17] = 1; + } +} + +//----- (0040C551) -------------------------------------------------------- +void __cdecl L5tileFix() +{ + signed int v0; // esi + char *v1; // eax + signed int v2; // edx + char v3; // cl + signed int v4; // ecx + signed int v5; // edi + signed int v6; // eax + char *v7; // esi + char v8; // bl + char *v9; // edx + char *v10; // edx + char *v11; // edx + char *v12; // edx + char *v13; // edx + char *v14; // edx + char *v15; // edx + char *v16; // edx + char *v17; // edx + char *v18; // edx + char *v19; // edx + char *v20; // edx + char *v21; // edx + char *v22; // edx + char *v23; // edx + char *v24; // edx + char *v25; // edx + char *v26; // edx + char *v27; // edx + char *v28; // edx + char *v29; // edx + char *v30; // edx + char *v31; // edx + char *v32; // edx + char *v33; // edx + char *v34; // eax + signed int v35; // edx + char *v36; // eax + signed int v37; // esi + char v38; // cl + + v0 = 0; + do + { + v1 = &dungeon[1][v0]; + v2 = 40; + do + { + v3 = *(v1 - 40); + if ( v3 == 2 && *v1 == 22 ) + *v1 = 23; + if ( v3 == 13 ) + { + if ( *v1 == 22 ) + *v1 = 18; + if ( *v1 == 2 ) + *v1 = 7; + } + if ( v3 == 6 && *v1 == 22 ) + *v1 = 24; + if ( v3 == 1 && *(v1 - 39) == 22 ) + *(v1 - 39) = 24; + if ( v3 == 13 ) + { + if ( *(v1 - 39) == 1 ) + *(v1 - 39) = 6; + if ( *(v1 - 39) == 22 ) + *(v1 - 39) = 19; + } + v1 += 40; + --v2; + } + while ( v2 ); + ++v0; + } + while ( v0 < 40 ); + v4 = 0; + do + { + v5 = 0; + do + { + v6 = v5; + v7 = &dungeon[v5][v4]; + v8 = *v7; + if ( *v7 == 13 ) + { + v9 = &dungeon[v6 + 1][v4]; + if ( *v9 == 19 ) + *v9 = 21; + v10 = &dungeon[v6 + 1][v4]; + if ( *v10 == 22 ) + *v10 = 20; + } + if ( v8 == 7 ) + { + v11 = &dungeon[v6 + 1][v4]; + if ( *v11 == 22 ) + *v11 = 23; + } + if ( v8 == 13 ) + { + v12 = &dungeon[v6 + 1][v4]; + if ( *v12 == 24 ) + *v12 = 21; + } + if ( v8 == 19 ) + { + v13 = &dungeon[v6 + 1][v4]; + if ( *v13 == 22 ) + *v13 = 20; + } + if ( v8 == 2 ) + { + v14 = &dungeon[v6 + 1][v4]; + if ( *v14 == 19 ) + *v14 = 21; + } + if ( v8 == 19 ) + { + v15 = &dungeon[v6 + 1][v4]; + if ( *v15 == 1 ) + *v15 = 6; + } + if ( v8 == 7 ) + { + v16 = &dungeon[v6 + 1][v4]; + if ( *v16 == 19 ) + *v16 = 21; + } + if ( v8 == 2 ) + { + v17 = &dungeon[v6 + 1][v4]; + if ( *v17 == 1 ) + *v17 = 6; + } + if ( v8 == 3 ) + { + v18 = &dungeon[v6 + 1][v4]; + if ( *v18 == 22 ) + *v18 = 24; + } + if ( v8 == 21 ) + { + v19 = &dungeon[v6 + 1][v4]; + if ( *v19 == 1 ) + *v19 = 6; + } + if ( v8 == 7 ) + { + v20 = &dungeon[v6 + 1][v4]; + if ( *v20 == 1 ) + *v20 = 6; + v21 = &dungeon[v6 + 1][v4]; + if ( *v21 == 24 ) + *v21 = 21; + } + if ( v8 == 4 ) + { + v22 = &dungeon[v6 + 1][v4]; + if ( *v22 == 16 ) + *v22 = 17; + } + if ( v8 == 7 ) + { + v23 = &dungeon[v6 + 1][v4]; + if ( *v23 == 13 ) + *v23 = 17; + } + if ( v8 == 2 ) + { + v24 = &dungeon[v6 + 1][v4]; + if ( *v24 == 24 ) + *v24 = 21; + v25 = &dungeon[v6 + 1][v4]; + if ( *v25 == 13 ) + *v25 = 17; + } + if ( v8 == 23 && *(v7 - 40) == 22 ) + *(v7 - 40) = 19; + if ( v8 == 19 && *(v7 - 40) == 23 ) + *(v7 - 40) = 21; + if ( v8 == 6 ) + { + if ( *(v7 - 40) == 22 ) + *(v7 - 40) = 24; + if ( *(v7 - 40) == 23 ) + *(v7 - 40) = 21; + } + if ( v8 == 1 ) + { + v26 = &dungeon[v6][v4 + 1]; + if ( *v26 == 2 ) + *v26 = 7; + } + if ( v8 == 6 ) + { + v27 = &dungeon[v6][v4 + 1]; + if ( *v27 == 18 ) + *v27 = 21; + } + if ( v8 == 18 ) + { + v28 = &dungeon[v6][v4 + 1]; + if ( *v28 == 2 ) + *v28 = 7; + } + if ( v8 == 6 ) + { + v29 = &dungeon[v6][v4 + 1]; + if ( *v29 == 2 ) + *v29 = 7; + } + if ( v8 == 21 ) + { + v30 = &dungeon[v6][v4 + 1]; + if ( *v30 == 2 ) + *v30 = 7; + } + if ( v8 == 6 ) + { + v31 = &dungeon[v6][v4 + 1]; + if ( *v31 == 22 ) + *v31 = 24; + v32 = &dungeon[v6][v4 + 1]; + if ( *v32 == 13 ) + *v32 = 16; + } + if ( v8 == 1 ) + { + v33 = &dungeon[v6][v4 + 1]; + if ( *v33 == 13 ) + *v33 = 16; + } + if ( v8 == 13 ) + { + v34 = &dungeon[v6][v4 + 1]; + if ( *v34 == 16 ) + *v34 = 17; + } + if ( v8 == 6 ) + { + if ( *(v7 - 1) == 22 ) + *(v7 - 1) = 7; + if ( *(v7 - 1) == 22 ) + *(v7 - 1) = 24; + } + if ( v8 == 7 && *(v7 - 1) == 24 ) + *(v7 - 1) = 21; + if ( v8 == 18 && *(v7 - 1) == 24 ) + *(v7 - 1) = 21; + ++v5; + } + while ( v5 < 40 ); + ++v4; + } + while ( v4 < 40 ); + v35 = 0; + do + { + v36 = (char *)dungeon + v35; + v37 = 40; + do + { + v38 = *v36; + if ( *v36 == 4 && v36[1] == 2 ) + v36[1] = 7; + if ( v38 == 2 && v36[40] == 19 ) + v36[40] = 21; + if ( v38 == 18 && v36[1] == 22 ) + v36[1] = 20; + v36 += 40; + --v37; + } + while ( v37 ); + ++v35; + } + while ( v35 < 40 ); +} + +//----- (0040C8C0) -------------------------------------------------------- +void __cdecl DRLG_L5Subs() +{ + signed int v0; // edi + int v1; // esi + unsigned char v2; // bl + int v3; // eax + signed int v4; // ecx + signed int v5; // [esp+Ch] [ebp-4h] + + v0 = 0; + do + { + v1 = v0 - 1; + v5 = 40; + do + { + if ( !random(0, 4) ) + { + v2 = L5BTYPES[(unsigned char)dungeon[0][v1 + 1]]; + if ( v2 ) + { + if ( !mydflags[0][v1 + 1] ) + { + v3 = random(0, 16); + v4 = -1; + if ( v3 >= 0 ) + { + do + { + if ( ++v4 == 206 ) + v4 = 0; + if ( v2 == L5BTYPES[v4] ) + --v3; + } + while ( v3 >= 0 ); + if ( v4 == 89 ) + { + if ( L5BTYPES[(unsigned char)dungeon[0][v1]] == 79 && !mydflags[0][v1] ) + { + dungeon[0][v1] = 90; + goto LABEL_22; + } + v4 = 79; + } + if ( v4 == 91 ) + { + if ( L5BTYPES[(unsigned char)dungeon[1][v1 + 1]] != 80 || mydflags[1][v1 + 1] ) + _LOBYTE(v4) = 80; + else + dungeon[1][v1 + 1] = 92; + } + } +LABEL_22: + dungeon[0][v1 + 1] = v4; + goto LABEL_23; + } + } + } +LABEL_23: + v1 += 40; + --v5; + } + while ( v5 ); + ++v0; + } + while ( v0 < 40 ); +} + +//----- (0040C99D) -------------------------------------------------------- +void __cdecl L5FillChambers() +{ + int v0; // edi + int v1; // edi + int v2; // edx + int v3; // ecx + int v4; // edi + signed int v5; // [esp-4h] [ebp-10h] + + v0 = 1; + if ( HR1 ) + DRLG_L5GChamber(0, 14, 0, 0, 0, 1); + if ( !HR2 ) + goto LABEL_16; + if ( HR1 ) + { + if ( !HR3 ) + DRLG_L5GChamber(14, 14, 0, 0, 1, 0); + if ( HR1 ) + goto LABEL_111; + } + if ( HR3 ) + DRLG_L5GChamber(14, 14, 0, 0, 0, 1); + if ( HR1 ) + { +LABEL_111: + if ( HR3 ) + DRLG_L5GChamber(14, 14, 0, 0, 1, 1); + if ( HR1 ) + { +LABEL_16: + if ( !HR3 ) + goto LABEL_18; + goto LABEL_17; + } + } + if ( !HR3 ) + { + DRLG_L5GChamber(14, 14, 0, 0, 0, 0); + goto LABEL_16; + } +LABEL_17: + DRLG_L5GChamber(28, 14, 0, 0, 1, 0); +LABEL_18: + if ( HR1 ) + { + if ( !HR2 ) + goto LABEL_24; + DRLG_L5GHall(12, 18, 14, 18); + } + if ( HR2 && HR3 ) + DRLG_L5GHall(26, 18, 28, 18); +LABEL_24: + if ( HR1 && !HR2 && HR3 ) + DRLG_L5GHall(12, 18, 28, 18); + if ( VR1 ) + DRLG_L5GChamber(14, 0, 0, 1, 0, 0); + if ( !VR2 ) + goto LABEL_43; + if ( VR1 ) + { + if ( !VR3 ) + DRLG_L5GChamber(14, 14, 1, 0, 0, 0); + if ( VR1 ) + goto LABEL_112; + } + if ( VR3 ) + DRLG_L5GChamber(14, 14, 0, 1, 0, 0); + if ( VR1 ) + { +LABEL_112: + if ( VR3 ) + DRLG_L5GChamber(14, 14, 1, 1, 0, 0); + if ( VR1 ) + { +LABEL_43: + if ( !VR3 ) + goto LABEL_45; + goto LABEL_44; + } + } + if ( !VR3 ) + { + DRLG_L5GChamber(14, 14, 0, 0, 0, 0); + goto LABEL_43; + } +LABEL_44: + DRLG_L5GChamber(14, 28, 1, 0, 0, 0); +LABEL_45: + if ( VR1 ) + { + if ( !VR2 ) + goto LABEL_51; + DRLG_L5GHall(18, 12, 18, 14); + } + if ( VR2 && VR3 ) + DRLG_L5GHall(18, 26, 18, 28); +LABEL_51: + if ( VR1 && !VR2 && VR3 ) + DRLG_L5GHall(18, 12, 18, 28); + if ( setloadflag ) + { + if ( !VR1 && !VR2 && !VR3 ) + { + if ( HR1 ) + goto LABEL_113; + if ( HR2 && HR3 ) + { + if ( random(0, 2) ) + v0 = 2; + if ( HR1 ) + { +LABEL_113: + if ( HR2 && !HR3 && random(0, 2) ) + v0 = 0; + if ( HR1 ) + { + if ( !HR2 && HR3 ) + v0 = random(0, 2) != 0 ? 0 : 2; + if ( HR1 && HR2 ) + { + if ( HR3 ) + v0 = random(0, 3); + } + } + } + } + if ( !v0 ) + { + v3 = 2; + v2 = 16; + goto LABEL_108; + } + v1 = v0 - 1; + if ( v1 ) + { + if ( v1 != 1 ) + return; + v2 = 16; + v5 = 30; + goto LABEL_107; + } +LABEL_81: + v3 = 16; + v2 = 16; +LABEL_108: + DRLG_L5SetRoom(v3, v2); + return; + } + if ( VR1 ) + goto LABEL_114; + if ( VR2 && VR3 ) + { + if ( random(0, 2) ) + v0 = 2; + if ( VR1 ) + { +LABEL_114: + if ( VR2 && !VR3 && random(0, 2) ) + v0 = 0; + if ( VR1 ) + { + if ( !VR2 && VR3 ) + v0 = random(0, 2) != 0 ? 0 : 2; + if ( VR1 && VR2 && VR3 ) + v0 = random(0, 3); + } + } + } + if ( v0 ) + { + v4 = v0 - 1; + if ( !v4 ) + goto LABEL_81; + if ( v4 != 1 ) + return; + v2 = 30; + } + else + { + v2 = 2; + } + v5 = 16; +LABEL_107: + v3 = v5; + goto LABEL_108; + } +} +// 5276A4: using guessed type int setloadflag; + +//----- (0040CD86) -------------------------------------------------------- +void __fastcall DRLG_L5GChamber(int tx, int ty, bool top_right, bool bottom_left, bool top_left, bool bottom_right) +{ + int v6; // eax + int v7; // edx + int v8; // eax + char *v9; // eax + int v10; // eax + int v11; // ecx + int v12; // eax + char *v13; // eax + signed int v14; // edi + int v15; // eax + int v16; // edx + int v17; // ecx + signed int v18; // esi + + if ( top_right == 1 ) + { + v6 = ty + 40 * tx; + dungeon[2][v6] = 12; + dungeon[3][v6] = 12; + dungeon[4][v6] = 3; + dungeon[7][v6] = 9; + dungeon[8][v6] = 12; + dungeon[9][v6] = 2; + } + if ( bottom_left == 1 ) + { + v7 = ty + 11; + v8 = v7 + 40 * tx; + dungeon[2][v8] = 10; + dungeon[3][v8] = 12; + dungeon[4][v8] = 8; + dungeon[7][v8] = 5; + dungeon[8][v8] = 12; + v9 = &dungeon[9][v8]; + if ( *v9 != 4 ) + *v9 = 21; + ty = v7 - 11; + } + if ( top_left == 1 ) + { + v10 = ty + 40 * tx; + dungeon[0][v10 + 2] = 11; + dungeon[0][v10 + 3] = 11; + dungeon[0][v10 + 4] = 3; + dungeon[0][v10 + 7] = 8; + dungeon[0][v10 + 8] = 11; + dungeon[0][v10 + 9] = 1; + } + if ( bottom_right == 1 ) + { + v11 = tx + 11; + v12 = ty + 40 * v11; + dungeon[0][v12 + 2] = 14; + dungeon[0][v12 + 3] = 11; + dungeon[0][v12 + 4] = 9; + dungeon[0][v12 + 7] = 5; + dungeon[0][v12 + 8] = 11; + v13 = &dungeon[0][v12 + 9]; + if ( *v13 != 4 ) + *v13 = 21; + tx = v11 - 11; + } + v14 = 10; + v15 = ty + 40 * tx; + v16 = v15 + 1; + do + { + v17 = v16; + v18 = 10; + do + { + mydflags[1][v17] |= 0x40u; + dungeon[1][v17] = 13; + v17 += 40; + --v18; + } + while ( v18 ); + ++v16; + --v14; + } + while ( v14 ); + dungeon[4][v15 + 4] = 15; + dungeon[7][v15 + 4] = 15; + dungeon[4][v15 + 7] = 15; + dungeon[7][v15 + 7] = 15; +} + +//----- (0040CEC7) -------------------------------------------------------- +void __fastcall DRLG_L5GHall(int tx_start, int ty_start, int tx_end, int ty_end) +{ + int v4; // eax + char *v5; // edx + int v6; // eax + int v7; // ecx + + if ( ty_start == ty_end ) + { + if ( tx_start < tx_end ) + { + v4 = tx_end - tx_start; + v5 = &dungeon[tx_start][ty_start + 3]; + do + { + *(v5 - 3) = 12; + *v5 = 12; + v5 += 40; + --v4; + } + while ( v4 ); + } + } + else + { + v6 = ty_start; + if ( ty_start < ty_end ) + { + v7 = 40 * tx_start + 5478016; + do + { + *(_BYTE *)(v7 + v6 - 120) = 11; + *(_BYTE *)(v7 + v6++) = 11; + } + while ( v6 < ty_end ); + } + } +} + +//----- (0040CF17) -------------------------------------------------------- +void __fastcall DRLG_L5SetRoom(int tx, int ty) +{ + int v2; // edi + int v3; // esi + int v4; // eax + char v5; // bl + int v6; // [esp+8h] [ebp-Ch] + char *v7; // [esp+Ch] [ebp-8h] + int v8; // [esp+10h] [ebp-4h] + + v8 = 0; + v2 = *((unsigned char *)pSetPiece + 2); + v3 = *(unsigned char *)pSetPiece; + setpc_x = tx; + setpc_y = ty; + setpc_w = v3; + setpc_h = v2; + v7 = (char *)pSetPiece + 4; + if ( v2 > 0 ) + { + do + { + if ( v3 > 0 ) + { + v6 = v3; + v4 = ty + v8 + 40 * tx; + do + { + v5 = *v7; + if ( *v7 ) + { + mydflags[0][v4] |= 0x80u; + dungeon[0][v4] = v5; + } + else + { + dungeon[0][v4] = 13; + } + v7 += 2; + v4 += 40; + --v6; + } + while ( v6 ); + } + ++v8; + } + while ( v8 < v2 ); + } +} +// 5CF330: using guessed type int setpc_h; +// 5CF334: using guessed type int setpc_w; + +//----- (0040CF9C) -------------------------------------------------------- +void __cdecl DRLG_L5FloodTVal() +{ + int v0; // ebx + int v1; // esi + char *v2; // edi + _BYTE *v3; // [esp+Ch] [ebp-Ch] + signed int x; // [esp+10h] [ebp-8h] + signed int tx; // [esp+14h] [ebp-4h] + + v0 = 16; + v1 = 0; + do + { + tx = 0; + x = 16; + v2 = &dung_map[16][v0]; + v3 = (unsigned char *)dungeon + v1; + do + { + if ( *v3 == 13 && !*v2 ) + { + DRLG_L5FTVR(tx, v1, x, v0, 0); + ++TransVal; + } + x += 2; + v3 += 40; + v2 += 224; + ++tx; + } + while ( tx < 40 ); + v0 += 2; + ++v1; + } + while ( v1 < 40 ); +} +// 5A5590: using guessed type char TransVal; + +//----- (0040D00B) -------------------------------------------------------- +void __fastcall DRLG_L5FTVR(int tx, int ty, int x, int y, int direction) +{ + int v5; // ebx + int v6; // esi + int v7; // edi + int v8; // edx + int v9; // ecx + int v10; // ebx + int v11; // eax + int v12; // edi + char v13; // al + char v14; // al + int v15; // ecx + int v16; // ecx + int v17; // ecx + int v18; // ecx + int v19; // [esp+Ch] [ebp-14h] + int i; // [esp+10h] [ebp-10h] + int v21; // [esp+14h] [ebp-Ch] + int tya; // [esp+18h] [ebp-8h] + int txa; // [esp+1Ch] [ebp-4h] + int ya; // [esp+2Ch] [ebp+Ch] + + v5 = x; + v6 = y; + v7 = ty; + v8 = tx; + v9 = 112 * x + y; + tya = v7; + v21 = v8; + if ( !dung_map[0][v9] ) + { + v19 = x; + txa = v8 - 1; + v10 = x - 2; + v11 = 40 * v8; + ya = v7 - 1; + v12 = v6 - 2; + for ( i = 40 * v8; dungeon[0][v11 + tya] == 13; v11 = i ) + { + v13 = TransVal; + dung_map[0][v9] = TransVal; + dung_map[1][v9] = v13; + dung_map[0][v9 + 1] = v13; + dung_map[1][v9 + 1] = v13; + DRLG_L5FTVR(txa + 2, tya, v10 + 4, v6, 1); + DRLG_L5FTVR(txa, tya, v10, v6, 2); + DRLG_L5FTVR(v21, ya + 2, x, v12 + 4, 3); + DRLG_L5FTVR(v21, ya, x, v12, 4); + DRLG_L5FTVR(txa, ya, v10, v12, 5); + DRLG_L5FTVR(txa + 2, ya, v10 + 4, v12, 6); + DRLG_L5FTVR(txa, ya + 2, v10, v12 + 4, 7); + v19 += 2; + i += 40; + direction = 8; + x += 2; + v6 += 2; + v12 += 2; + v10 += 2; + ++tya; + ++ya; + ++v21; + ++txa; + v9 = v19 * 112 + v6; + if ( dung_map[v19][v6] ) + break; + } + v5 = x; + } + v14 = TransVal; + if ( direction == 1 ) + { + v15 = v6 + 112 * v5; + dung_map[0][v15] = TransVal; + dung_map[0][v15 + 1] = v14; + } + if ( direction == 2 ) + { + v16 = v6 + 112 * v5; + dung_map[1][v16] = v14; + dung_map[1][v16 + 1] = v14; + } + if ( direction == 3 ) + { + v17 = v6 + 112 * v5; + dung_map[0][v17] = v14; + dung_map[1][v17] = v14; + } + if ( direction == 4 ) + { + v18 = v6 + 112 * v5; + dung_map[0][v18 + 1] = v14; + dung_map[1][v18 + 1] = v14; + } + if ( direction == 5 ) + dung_map[v5 + 1][v6 + 1] = v14; + if ( direction == 6 ) + dung_map[v5][v6 + 1] = v14; + if ( direction == 7 ) + dung_map[v5 + 1][v6] = v14; + if ( direction == 8 ) + dung_map[v5][v6] = v14; +} +// 5A5590: using guessed type char TransVal; + +//----- (0040D1FB) -------------------------------------------------------- +void __cdecl DRLG_L5TransFix() +{ + signed int v0; // esi + char *v1; // eax + char *v2; // ecx + signed int v3; // edi + char v4; // bl + char v5; // dl + char v6; // dl + char v7; // dl + char v8; // dl + char v9; // dl + char *v10; // [esp+Ch] [ebp-4h] + + v0 = 0; + v10 = &dung_map[16][16]; + do + { + v1 = v10; + v2 = (char *)dungeon + v0; + v3 = 40; + do + { + v4 = *v2; + if ( *v2 == 23 && *(v2 - 1) == 18 ) + { + v5 = *v1; + v1[112] = *v1; + v1[113] = v5; + } + if ( v4 == 24 && v2[40] == 19 ) + { + v6 = *v1; + v1[1] = *v1; + v1[113] = v6; + } + if ( v4 == 18 ) + { + v7 = *v1; + v1[112] = *v1; + v1[113] = v7; + } + if ( v4 == 19 ) + { + v8 = *v1; + v1[1] = *v1; + v1[113] = v8; + } + if ( v4 == 20 ) + { + v9 = *v1; + v1[112] = *v1; + v1[1] = v9; + v1[113] = v9; + } + v1 += 224; + v2 += 40; + --v3; + } + while ( v3 ); + v10 += 2; + ++v0; + } + while ( v0 < 40 ); +} + +//----- (0040D283) -------------------------------------------------------- +void __cdecl DRLG_L5DirtFix() +{ + signed int v0; // ecx + char *v1; // eax + signed int v2; // edx + + v0 = 0; + do + { + v1 = (char *)dungeon + v0; + v2 = 40; + do + { + if ( *v1 == 21 && v1[40] != 19 ) + *v1 = -54; + if ( *v1 == 19 && v1[40] != 19 ) + *v1 = -56; + if ( *v1 == 24 && v1[40] != 19 ) + *v1 = -51; + if ( *v1 == 18 && v1[1] != 18 ) + *v1 = -57; + if ( *v1 == 21 && v1[1] != 18 ) + *v1 = -54; + if ( *v1 == 23 && v1[1] != 18 ) + *v1 = -52; + v1 += 40; + --v2; + } + while ( v2 ); + ++v0; + } + while ( v0 < 40 ); +} + +//----- (0040D2EF) -------------------------------------------------------- +void __cdecl DRLG_L5CornerFix() +{ + signed int v0; // esi + signed int v1; // eax + signed int v2; // edi + + v0 = 1; + do + { + v1 = v0; + v2 = 38; + do + { + if ( mydflags[1][v1] >= 0 && dungeon[1][v1] == 17 && dungeon[0][v1] == 13 && dungeon[0][v1 + 39] == 1 ) + { + mydflags[0][v1 + 39] &= 0x80u; + dungeon[1][v1] = 16; + } + if ( dungeon[1][v1] == -54 && dungeon[2][v1] == 13 && dungeon[1][v1 + 1] == 1 ) + dungeon[1][v1] = 8; + v1 += 40; + --v2; + } + while ( v2 ); + ++v0; + } + while ( v0 < 39 ); +} + +//----- (0040D357) -------------------------------------------------------- +void __cdecl InitDungeon() +{ + signed int v0; // edx + signed int v1; // eax + signed int v2; // ecx + + v0 = 0; + do + { + v1 = v0; + v2 = 40; + do + { + dflags[0][v1] = 0; + predungeon[0][v1] = 32; + v1 += 40; + --v2; + } + while ( v2 ); + ++v0; + } + while ( v0 < 40 ); +} + +//----- (0040D379) -------------------------------------------------------- +void __cdecl L2LockoutFix() +{ + signed int v0; // ecx + _BYTE *v1; // eax + signed int v2; // edx + signed int v3; // ecx + signed int v4; // edi + signed int v5; // eax + char *v6; // esi + signed int v7; // edx + char v8; // al + unsigned int v9; // ecx + signed int v10; // eax + char v11; // dl + signed int v12; // esi + char v13; // bl + char *v14; // edx + + v0 = 0; + do + { + v1 = (unsigned char *)dungeon + v0; + v2 = 40; + do + { + if ( *v1 == 4 && *(v1 - 40) != 3 ) + *v1 = 1; + if ( *v1 == 5 && *(v1 - 1) != 3 ) + *v1 = 2; + v1 += 40; + --v2; + } + while ( v2 ); + ++v0; + } + while ( v0 < 40 ); + v3 = 1; + do + { + v4 = 1; + do + { + v5 = v4; + if ( dflags[v4][v3] >= 0 ) + { + v6 = &dungeon[v5][v3]; + if ( (*v6 == 2 || *v6 == 5) && *(v6 - 1) == 3 && dungeon[v5][v3 + 1] == 3 ) + { + v7 = 0; + while ( 1 ) + { + v8 = *v6; + if ( *v6 != 2 && v8 != 5 ) + break; + if ( *(v6 - 1) != 3 || v6[1] != 3 ) + break; + if ( v8 == 5 ) + v7 = 1; + ++v4; + v6 += 40; + } + if ( !v7 && dTransVal2[111][40 * v4 + 80 + v3] >= 0 ) + *((_BYTE *)&dMonster[111][10 * v4 + 102] + v3) = 5; + } + } + ++v4; + } + while ( v4 < 39 ); + ++v3; + } + while ( v3 < 39 ); + v9 = 40; + do + { + v10 = 1; + do + { + if ( dflags[v9 / 0x28][v10] >= 0 ) + { + v11 = dungeon[v9 / 0x28][v10]; + if ( (v11 == 1 || v11 == 4) + && *((_BYTE *)&dMonster[111][v9 / 4 + 102] + v10) == 3 + && dungeon[v9 / 0x28 + 1][v10] == 3 ) + { + v12 = 0; + while ( 1 ) + { + v13 = dungeon[v9 / 0x28][v10]; + if ( v13 != 1 && v13 != 4 ) + break; + v14 = &dungeon[v9 / 0x28 + 1][v10]; + if ( *(v14 - 80) != 3 || *v14 != 3 ) + break; + if ( v13 == 4 ) + v12 = 1; + ++v10; + } + if ( !v12 && *(_BYTE *)(v9 + v10 + 5920151) >= 0 ) + *((_BYTE *)&dMonster[111][v9 / 4 + 111] + v10 + 3) = 4; + } + } + ++v10; + } + while ( v10 < 39 ); + v9 += 40; + } + while ( (signed int)v9 < 1560 ); +} + +//----- (0040D4CC) -------------------------------------------------------- +void __cdecl L2DoorFix() +{ + signed int v0; // ecx + char *v1; // eax + signed int v2; // edx + + v0 = 1; + do + { + v1 = &dungeon[1][v0]; + v2 = 39; + do + { + if ( *v1 == 4 && *(v1 - 1) == 3 ) + *v1 = 7; + if ( *v1 == 5 && *(v1 - 40) == 3 ) + *v1 = 9; + v1 += 40; + --v2; + } + while ( v2 ); + ++v0; + } + while ( v0 < 40 ); +} + +//----- (0040D501) -------------------------------------------------------- +void __fastcall LoadL2Dungeon(char *sFileName, int vx, int vy) +{ + char *v3; // esi + unsigned char *v4; // edi + signed int v5; // edx + signed int v6; // eax + signed int v7; // ecx + int v8; // esi + int v9; // eax + int v10; // ebx + int v11; // edi + char *v12; // eax + int v13; // ecx + char v14; // dl + signed int v15; // ecx + _BYTE *v16; // eax + signed int v17; // edx + int v18; // ebx + int (*v19)[112]; // esi + char *v20; // ecx + signed int v21; // edi + int v22; // edx + char v23; // al + int v24; // ecx + int (*v25)[112]; // edi + char *v26; // eax + int (*v27)[112]; // edx + signed int v28; // ebx + int v29; // esi + int v30; // [esp+Ch] [ebp-Ch] + char *ptr; // [esp+10h] [ebp-8h] + int v32; // [esp+14h] [ebp-4h] + int (*v33)[112]; // [esp+14h] [ebp-4h] + + v30 = vx; + v3 = sFileName; + InitDungeon(); + DRLG_InitTrans(); + v4 = LoadFileInMem(v3, 0); + v5 = 0; + ptr = (char *)v4; + do + { + v6 = v5; + v7 = 40; + do + { + dflags[0][v6] = 0; + dungeon[0][v6] = 12; + v6 += 40; + --v7; + } + while ( v7 ); + ++v5; + } + while ( v5 < 40 ); + v8 = *v4; + v9 = (int)(v4 + 2); + v10 = 0; + v11 = v4[2]; + v12 = (char *)(v9 + 2); + if ( v11 > 0 ) + { + do + { + if ( v8 > 0 ) + { + v13 = v10; + v32 = v8; + do + { + v14 = *v12; + if ( *v12 ) + { + dflags[0][v13] |= 0x80u; + dungeon[0][v13] = v14; + } + else + { + dungeon[0][v13] = 3; + } + v13 += 40; + v12 += 2; + --v32; + } + while ( v32 ); + } + ++v10; + } + while ( v10 < v11 ); + } + v15 = 0; + do + { + v16 = (unsigned char *)dungeon + v15; + v17 = 40; + do + { + if ( !*v16 ) + *v16 = 12; + v16 += 40; + --v17; + } + while ( v17 ); + ++v15; + } + while ( v15 < 40 ); + DRLG_L2Pass3(); + DRLG_Init_Globals(); + v18 = 0; + v33 = dPiece; + do + { + v19 = v33; + v20 = (char *)dArch + v18; + v21 = 112; + do + { + v22 = (*v19)[0]; + v23 = 0; + if ( (*v19)[0] == 541 ) + v23 = 5; + if ( v22 == 178 ) + v23 = 5; + if ( v22 == 551 ) + v23 = 5; + if ( v22 == 542 ) + v23 = 6; + if ( v22 == 553 ) + v23 = 6; + if ( v22 == 13 ) + v23 = 5; + if ( v22 == 17 ) + v23 = 6; + *v20 = v23; + ++v19; + v20 += 112; + --v21; + } + while ( v21 ); + v33 = (int (*)[112])((char *)v33 + 4); + ++v18; + } + while ( (signed int)v33 < (signed int)dPiece[1] ); + v24 = 0; + v25 = dPiece; + do + { + v26 = &dArch[0][v24 + 2]; + v27 = v25; + v28 = 112; + do + { + v29 = (*v27)[0]; + if ( (*v27)[0] == 132 ) + { + *(v26 - 1) = 2; + *v26 = 1; + } + else if ( v29 == 135 || v29 == 139 ) + { + v26[110] = 3; + v26[222] = 4; + } + ++v27; + v26 += 112; + --v28; + } + while ( v28 ); + v25 = (int (*)[112])((char *)v25 + 4); + ++v24; + } + while ( (signed int)v25 < (signed int)dPiece[1] ); + ViewX = v30; + ViewY = vy; + SetMapMonsters(ptr, 0, 0); + SetMapObjects(ptr, 0, 0); + mem_free_dbg(ptr); +} + +//----- (0040D6C1) -------------------------------------------------------- +void __cdecl DRLG_L2Pass3() +{ + int v0; // eax + int *v1; // edx + int *v2; // eax + signed int v3; // ecx + signed int v4; // ebx + int *v5; // ecx + unsigned char *v6; // edx + unsigned short *v7; // esi + unsigned short v8; // ax + int v9; // eax + int v10; // ST24_4 + int v11; // ST20_4 + int v12; // ST1C_4 + signed int v13; // [esp+Ch] [ebp-1Ch] + int *v14; // [esp+10h] [ebp-18h] + int v15; // [esp+14h] [ebp-14h] + int v16; // [esp+18h] [ebp-10h] + int v17; // [esp+1Ch] [ebp-Ch] + int v18; // [esp+20h] [ebp-8h] + + v0 = *((unsigned short *)pMegaTiles + 44) + 1; + v18 = *((unsigned short *)pMegaTiles + 44) + 1; + _LOWORD(v0) = *((_WORD *)pMegaTiles + 45); + v17 = ++v0; + _LOWORD(v0) = *((_WORD *)pMegaTiles + 46); + v16 = ++v0; + _LOWORD(v0) = *((_WORD *)pMegaTiles + 47); + v15 = v0 + 1; + v1 = dPiece[1]; + do + { + v2 = v1; + v3 = 56; + do + { + *(v2 - 112) = v18; + *v2 = v17; + *(v2 - 111) = v16; + v2[1] = v15; + v2 += 224; + --v3; + } + while ( v3 ); + v1 += 2; + } + while ( (signed int)v1 < (signed int)dPiece[2] ); + v4 = 0; + v14 = &dPiece[17][16]; + do + { + v5 = v14; + v6 = (unsigned char *)dungeon + v4; + v13 = 40; + do + { + v7 = (unsigned short *)((char *)pMegaTiles + 8 * (*v6 - 1)); + v8 = *v7; + ++v7; + v9 = v8 + 1; + v10 = v9; + _LOWORD(v9) = *v7; + ++v7; + v11 = ++v9; + _LOWORD(v9) = *v7; + v12 = ++v9; + _LOWORD(v9) = v7[1]; + v6 += 40; + *(v5 - 112) = v10; + *v5 = v11; + *(v5 - 111) = v12; + v5[1] = v9 + 1; + v5 += 224; + --v13; + } + while ( v13 ); + v14 += 2; + ++v4; + } + while ( v4 < 40 ); +} + +//----- (0040D7B3) -------------------------------------------------------- +void __fastcall LoadPreL2Dungeon(char *sFileName, int vx, int vy) +{ + char *v3; // esi + unsigned char *v4; // ebx + signed int v5; // esi + signed int v6; // edx + signed int v7; // eax + int v8; // eax + int v9; // edi + char *v10; // edx + int v11; // esi + char v12; // bl + signed int v13; // eax + _BYTE *v14; // edx + signed int v15; // esi + signed int v16; // eax + signed int v17; // edx + signed int v18; // esi + unsigned char *ptr; // [esp+8h] [ebp-Ch] + int v20; // [esp+Ch] [ebp-8h] + int v21; // [esp+10h] [ebp-4h] + + v3 = sFileName; + InitDungeon(); + DRLG_InitTrans(); + v4 = LoadFileInMem(v3, 0); + v5 = 0; + ptr = v4; + do + { + v6 = v5; + v7 = 40; + do + { + dflags[0][v6] = 0; + dungeon[0][v6] = 12; + v6 += 40; + --v7; + } + while ( v7 ); + ++v5; + } + while ( v5 < 40 ); + v21 = 0; + v8 = v4[2]; + v9 = *v4; + v10 = (char *)(v4 + 4); + if ( v8 > 0 ) + { + do + { + if ( v9 > 0 ) + { + v11 = v21; + v20 = v9; + do + { + v12 = *v10; + if ( *v10 ) + { + dflags[0][v11] |= 0x80u; + dungeon[0][v11] = v12; + } + else + { + dungeon[0][v11] = 3; + } + v11 += 40; + v10 += 2; + --v20; + } + while ( v20 ); + } + ++v21; + } + while ( v21 < v8 ); + } + v13 = 0; + do + { + v14 = (unsigned char *)dungeon + v13; + v15 = 40; + do + { + if ( !*v14 ) + *v14 = 12; + v14 += 40; + --v15; + } + while ( v15 ); + ++v13; + } + while ( v13 < 40 ); + v16 = 0; + do + { + v17 = v16; + v18 = 40; + do + { + pdungeon[0][v17] = dungeon[0][v17]; + v17 += 40; + --v18; + } + while ( v18 ); + ++v16; + } + while ( v16 < 40 ); + mem_free_dbg(ptr); +} + +//----- (0040D888) -------------------------------------------------------- +void __fastcall CreateL2Dungeon(int seed, int entry) +{ + int v2; // esi + int v3; // edi + int v4; // ecx + + v2 = entry; + v3 = seed; + if ( gbMaxPlayers == 1 ) + { + if ( currlevel == 7 ) + { + if ( quests[8]._qactive ) + goto LABEL_10; + currlevel = 6; + CreateL2Dungeon(glSeedTbl[6], 4); + currlevel = 7; + } + if ( currlevel == 8 ) + { + if ( quests[8]._qactive ) + { + v4 = glSeedTbl[7]; + currlevel = 7; + } + else + { + v4 = glSeedTbl[6]; + currlevel = 6; + } + CreateL2Dungeon(v4, 4); + currlevel = 8; + } + } +LABEL_10: + SetRndSeed(v3); + dminx = 16; + dminy = 16; + dmaxx = 96; + dmaxy = 96; + DRLG_InitTrans(); + DRLG_InitSetPC(); + DRLG_LoadL2SP(); + DRLG_L2(v2); + DRLG_L2Pass3(); + DRLG_FreeL2SP(); + DRLG_InitL2Vals(); + DRLG_SetPC(); +} +// 5CF328: using guessed type int dmaxx; +// 5CF32C: using guessed type int dmaxy; +// 5D2458: using guessed type int dminx; +// 5D245C: using guessed type int dminy; +// 679660: using guessed type char gbMaxPlayers; + +//----- (0040D94F) -------------------------------------------------------- +void __cdecl DRLG_LoadL2SP() +{ + int v0; // eax + char *v1; // ecx + int v2; // eax + int v3; // eax + + setloadflag_2 = 0; + _LOBYTE(v0) = QuestStatus(8); + if ( v0 ) + { + v1 = "Levels\\L2Data\\Blind2.DUN"; + } + else + { + _LOBYTE(v2) = QuestStatus(9); + if ( v2 ) + { + v1 = "Levels\\L2Data\\Blood1.DUN"; + } + else + { + _LOBYTE(v3) = QuestStatus(14); + if ( !v3 ) + return; + v1 = "Levels\\L2Data\\Bonestr2.DUN"; + } + } + pSetPiece_2 = (char *)LoadFileInMem(v1, 0); + setloadflag_2 = 1; +} +// 5B50D8: using guessed type int setloadflag_2; + +//----- (0040D9A4) -------------------------------------------------------- +void __cdecl DRLG_FreeL2SP() +{ + char *v0; // ecx + + v0 = pSetPiece_2; + pSetPiece_2 = 0; + mem_free_dbg(v0); +} + +//----- (0040D9B6) -------------------------------------------------------- +void __fastcall DRLG_L2(int entry) +{ + int v1; // esi + int v2; // eax + int v3; // eax + int v4; // eax + int v5; // eax + int v6; // eax + int v7; // eax + int v8; // eax + int v9; // eax + signed int v10; // ecx + signed int v11; // eax + signed int v12; // esi + int v13; // [esp+10h] [ebp-4h] + + v1 = 0; + v13 = entry; + do + { + nRoomCnt = 0; + InitDungeon(); + DRLG_InitTrans(); + CreateDungeon(); + if ( !v2 ) + continue; + L2TileFix(); + if ( setloadflag_2 ) + DRLG_L2SetRoom(nSx1, nSy1); + DRLG_L2FloodTVal(); + DRLG_L2TransFix(); + if ( !v13 ) + { + _LOBYTE(v3) = DRLG_L2PlaceMiniSet((char *)USTAIRS, 1, 1, -1, -1, 1, 0); + v1 = v3; + if ( !v3 ) + goto LABEL_21; + _LOBYTE(v4) = DRLG_L2PlaceMiniSet((char *)DSTAIRS, 1, 1, -1, -1, 0, 1); + v1 = v4; + if ( !v4 || currlevel != 5 ) + goto LABEL_21; + _LOBYTE(v5) = DRLG_L2PlaceMiniSet((char *)WARPSTAIRS, 1, 1, -1, -1, 0, 6); +LABEL_20: + v1 = v5; +LABEL_21: + ViewY -= 2; + continue; + } + _LOBYTE(v6) = DRLG_L2PlaceMiniSet((char *)USTAIRS, 1, 1, -1, -1, 0, 0); + v1 = v6; + if ( v13 != 1 ) + { + if ( !v6 ) + goto LABEL_21; + _LOBYTE(v9) = DRLG_L2PlaceMiniSet((char *)DSTAIRS, 1, 1, -1, -1, 0, 1); + v1 = v9; + if ( !v9 || currlevel != 5 ) + goto LABEL_21; + _LOBYTE(v5) = DRLG_L2PlaceMiniSet((char *)WARPSTAIRS, 1, 1, -1, -1, 1, 6); + goto LABEL_20; + } + if ( v6 ) + { + _LOBYTE(v7) = DRLG_L2PlaceMiniSet((char *)DSTAIRS, 1, 1, -1, -1, 1, 1); + v1 = v7; + if ( v7 ) + { + if ( currlevel == 5 ) + { + _LOBYTE(v8) = DRLG_L2PlaceMiniSet((char *)WARPSTAIRS, 1, 1, -1, -1, 0, 6); + v1 = v8; + } + } + } + --ViewX; + } + while ( !v1 ); + L2LockoutFix(); + L2DoorFix(); + L2DirtFix(); + DRLG_PlaceThemeRooms(6, 10, 3, 0, 0); + DRLG_L2PlaceRndSet((char *)CTRDOOR1, 100); + DRLG_L2PlaceRndSet((char *)CTRDOOR2, 100); + DRLG_L2PlaceRndSet((char *)CTRDOOR3, 100); + DRLG_L2PlaceRndSet((char *)CTRDOOR4, 100); + DRLG_L2PlaceRndSet((char *)CTRDOOR5, 100); + DRLG_L2PlaceRndSet((char *)CTRDOOR6, 100); + DRLG_L2PlaceRndSet((char *)CTRDOOR7, 100); + DRLG_L2PlaceRndSet((char *)CTRDOOR8, 100); + DRLG_L2PlaceRndSet((char *)VARCH33, 100); + DRLG_L2PlaceRndSet((char *)VARCH34, 100); + DRLG_L2PlaceRndSet((char *)VARCH35, 100); + DRLG_L2PlaceRndSet((char *)VARCH36, 100); + DRLG_L2PlaceRndSet((char *)VARCH37, 100); + DRLG_L2PlaceRndSet((char *)VARCH38, 100); + DRLG_L2PlaceRndSet((char *)VARCH39, 100); + DRLG_L2PlaceRndSet((char *)VARCH40, 100); + DRLG_L2PlaceRndSet((char *)VARCH1, 100); + DRLG_L2PlaceRndSet((char *)VARCH2, 100); + DRLG_L2PlaceRndSet((char *)VARCH3, 100); + DRLG_L2PlaceRndSet((char *)VARCH4, 100); + DRLG_L2PlaceRndSet((char *)VARCH5, 100); + DRLG_L2PlaceRndSet((char *)VARCH6, 100); + DRLG_L2PlaceRndSet((char *)VARCH7, 100); + DRLG_L2PlaceRndSet((char *)VARCH8, 100); + DRLG_L2PlaceRndSet((char *)VARCH9, 100); + DRLG_L2PlaceRndSet((char *)VARCH10, 100); + DRLG_L2PlaceRndSet((char *)VARCH11, 100); + DRLG_L2PlaceRndSet((char *)VARCH12, 100); + DRLG_L2PlaceRndSet((char *)VARCH13, 100); + DRLG_L2PlaceRndSet((char *)VARCH14, 100); + DRLG_L2PlaceRndSet((char *)VARCH15, 100); + DRLG_L2PlaceRndSet((char *)VARCH16, 100); + DRLG_L2PlaceRndSet((char *)VARCH17, 100); + DRLG_L2PlaceRndSet((char *)VARCH18, 100); + DRLG_L2PlaceRndSet((char *)VARCH19, 100); + DRLG_L2PlaceRndSet((char *)VARCH20, 100); + DRLG_L2PlaceRndSet((char *)VARCH21, 100); + DRLG_L2PlaceRndSet((char *)VARCH22, 100); + DRLG_L2PlaceRndSet((char *)VARCH23, 100); + DRLG_L2PlaceRndSet((char *)VARCH24, 100); + DRLG_L2PlaceRndSet((char *)VARCH25, 100); + DRLG_L2PlaceRndSet((char *)VARCH26, 100); + DRLG_L2PlaceRndSet((char *)VARCH27, 100); + DRLG_L2PlaceRndSet((char *)VARCH28, 100); + DRLG_L2PlaceRndSet((char *)VARCH29, 100); + DRLG_L2PlaceRndSet((char *)VARCH30, 100); + DRLG_L2PlaceRndSet((char *)VARCH31, 100); + DRLG_L2PlaceRndSet((char *)VARCH32, 100); + DRLG_L2PlaceRndSet((char *)HARCH1, 100); + DRLG_L2PlaceRndSet((char *)HARCH2, 100); + DRLG_L2PlaceRndSet((char *)HARCH3, 100); + DRLG_L2PlaceRndSet((char *)HARCH4, 100); + DRLG_L2PlaceRndSet((char *)HARCH5, 100); + DRLG_L2PlaceRndSet((char *)HARCH6, 100); + DRLG_L2PlaceRndSet((char *)HARCH7, 100); + DRLG_L2PlaceRndSet((char *)HARCH8, 100); + DRLG_L2PlaceRndSet((char *)HARCH9, 100); + DRLG_L2PlaceRndSet((char *)HARCH10, 100); + DRLG_L2PlaceRndSet((char *)HARCH11, 100); + DRLG_L2PlaceRndSet((char *)HARCH12, 100); + DRLG_L2PlaceRndSet((char *)HARCH13, 100); + DRLG_L2PlaceRndSet((char *)HARCH14, 100); + DRLG_L2PlaceRndSet((char *)HARCH15, 100); + DRLG_L2PlaceRndSet((char *)HARCH16, 100); + DRLG_L2PlaceRndSet((char *)HARCH17, 100); + DRLG_L2PlaceRndSet((char *)HARCH18, 100); + DRLG_L2PlaceRndSet((char *)HARCH19, 100); + DRLG_L2PlaceRndSet((char *)HARCH20, 100); + DRLG_L2PlaceRndSet((char *)HARCH21, 100); + DRLG_L2PlaceRndSet((char *)HARCH22, 100); + DRLG_L2PlaceRndSet((char *)HARCH23, 100); + DRLG_L2PlaceRndSet((char *)HARCH24, 100); + DRLG_L2PlaceRndSet((char *)HARCH25, 100); + DRLG_L2PlaceRndSet((char *)HARCH26, 100); + DRLG_L2PlaceRndSet((char *)HARCH27, 100); + DRLG_L2PlaceRndSet((char *)HARCH28, 100); + DRLG_L2PlaceRndSet((char *)HARCH29, 100); + DRLG_L2PlaceRndSet((char *)HARCH30, 100); + DRLG_L2PlaceRndSet((char *)HARCH31, 100); + DRLG_L2PlaceRndSet((char *)HARCH32, 100); + DRLG_L2PlaceRndSet((char *)HARCH33, 100); + DRLG_L2PlaceRndSet((char *)HARCH34, 100); + DRLG_L2PlaceRndSet((char *)HARCH35, 100); + DRLG_L2PlaceRndSet((char *)HARCH36, 100); + DRLG_L2PlaceRndSet((char *)HARCH37, 100); + DRLG_L2PlaceRndSet((char *)HARCH38, 100); + DRLG_L2PlaceRndSet((char *)HARCH39, 100); + DRLG_L2PlaceRndSet((char *)HARCH40, 100); + DRLG_L2PlaceRndSet((char *)CRUSHCOL, 99); + DRLG_L2PlaceRndSet((char *)RUINS1, 10); + DRLG_L2PlaceRndSet((char *)RUINS2, 10); + DRLG_L2PlaceRndSet((char *)RUINS3, 10); + DRLG_L2PlaceRndSet((char *)RUINS4, 10); + DRLG_L2PlaceRndSet((char *)RUINS5, 10); + DRLG_L2PlaceRndSet((char *)RUINS6, 10); + DRLG_L2PlaceRndSet((char *)RUINS7, 50); + DRLG_L2PlaceRndSet((char *)PANCREAS1, 1); + DRLG_L2PlaceRndSet((char *)PANCREAS2, 1); + DRLG_L2PlaceRndSet((char *)BIG1, 3); + DRLG_L2PlaceRndSet((char *)BIG2, 3); + DRLG_L2PlaceRndSet((char *)BIG3, 3); + DRLG_L2PlaceRndSet((char *)BIG4, 3); + DRLG_L2PlaceRndSet((char *)BIG5, 3); + DRLG_L2PlaceRndSet((char *)BIG6, 20); + DRLG_L2PlaceRndSet((char *)BIG7, 20); + DRLG_L2PlaceRndSet((char *)BIG8, 3); + DRLG_L2PlaceRndSet((char *)BIG9, 20); + DRLG_L2PlaceRndSet((char *)BIG10, 20); + DRLG_L2Subs(); + DRLG_L2Shadows(); + v10 = 0; + do + { + v11 = v10; + v12 = 40; + do + { + pdungeon[0][v11] = dungeon[0][v11]; + v11 += 40; + --v12; + } + while ( v12 ); + ++v10; + } + while ( v10 < 40 ); + DRLG_Init_Globals(); + DRLG_CheckQuests(nSx1, nSy1); +} +// 5B50D8: using guessed type int setloadflag_2; + +//----- (0040E074) -------------------------------------------------------- +bool __fastcall DRLG_L2PlaceMiniSet(char *miniset, int tmin, int tmax, int cx, int cy, bool set_view, int ldir) +{ + int v7; // ebx + int v8; // esi + int v9; // edi + int v10; // edx + int v11; // eax + int v12; // ecx + int v13; // esi + int v14; // ebx + int v15; // ecx + int v16; // eax + int v17; // ecx + int v18; // eax + int v19; // ecx + int v20; // edi + signed int i; // eax + int v22; // ecx + char v23; // dl + int v24; // eax + int v25; // edi + char *v26; // edx + char v27; // bl + bool result; // al + char *v29; // [esp+Ch] [ebp-28h] + int v30; // [esp+10h] [ebp-24h] + int v31; // [esp+14h] [ebp-20h] + int v32; // [esp+18h] [ebp-1Ch] + signed int v33; // [esp+1Ch] [ebp-18h] + int v34; // [esp+20h] [ebp-14h] + int v35; // [esp+24h] [ebp-10h] + int v36; // [esp+28h] [ebp-Ch] + int max; // [esp+2Ch] [ebp-8h] + int v38; // [esp+30h] [ebp-4h] + int v39; // [esp+30h] [ebp-4h] + int tmaxa; // [esp+3Ch] [ebp+8h] + + v7 = (unsigned char)miniset[1]; + v8 = tmin; + v9 = (unsigned char)*miniset; + v29 = miniset; + v10 = tmax - tmin; + v34 = (unsigned char)*miniset; + v35 = (unsigned char)miniset[1]; + if ( v10 ) + { + _LOBYTE(miniset) = 0; + v30 = v8 + random((int)miniset, v10); + } + else + { + v30 = 1; + } + v31 = 0; + if ( v30 <= 0 ) + { + v13 = ldir; + v14 = v38; + } + else + { + max = 40 - v9; + v36 = 40 - v7; + do + { + _LOBYTE(miniset) = 0; + v11 = random((int)miniset, max); + _LOBYTE(v12) = 0; + v13 = v11; + v33 = 0; + v14 = random(v12, v36); + v39 = v14; + do + { + if ( v33 >= 200 ) + return 0; + tmaxa = 1; + if ( v13 >= nSx1 && v13 <= nSx2 && v14 >= nSy1 && v14 <= nSy2 ) + tmaxa = 0; + if ( cx != -1 ) + { + v15 = cx - v34; + if ( v13 >= cx - v34 && v13 <= cx + 12 ) + { + _LOBYTE(v15) = 0; + v16 = random(v15, max); + _LOBYTE(v17) = 0; + v13 = v16; + tmaxa = 0; + v39 = random(v17, v36); + v14 = v39; + } + } + if ( cy != -1 && v14 >= cy - v35 && v14 <= cy + 12 ) + { + v18 = random(cy - v35, max); + _LOBYTE(v19) = 0; + v13 = v18; + tmaxa = 0; + v39 = random(v19, v36); + v14 = v39; + } + v20 = 0; + for ( i = 2; v20 < v35; ++v20 ) + { + if ( tmaxa != 1 ) + break; + v32 = 0; + if ( v34 > 0 ) + { + v22 = v14 + v20 + 40 * v13; + do + { + if ( tmaxa != 1 ) + break; + v23 = v29[i]; + if ( v23 && dungeon[0][v22] != v23 ) + tmaxa = 0; + if ( dflags[0][v22] ) + tmaxa = 0; + ++i; + ++v32; + v22 += 40; + } + while ( v32 < v34 ); + } + } + if ( !tmaxa && ++v13 == max ) + { + v13 = 0; + v39 = ++v14; + if ( v14 == v36 ) + { + v39 = 0; + v14 = 0; + } + } + ++v33; + } + while ( !tmaxa ); + if ( v33 >= 200 ) + return 0; + v24 = 0; + for ( miniset = (char *)(v34 * v35 + 2); v24 < v35; ++v24 ) + { + v25 = v34; + if ( v34 > 0 ) + { + v26 = &dungeon[v13][v24 + v14]; + do + { + v27 = v29[(_DWORD)miniset]; + if ( v27 ) + *v26 = v27; + ++miniset; + v26 += 40; + --v25; + } + while ( v25 ); + v14 = v39; + } + } + ++v31; + } + while ( v31 < v30 ); + } + result = 1; + if ( set_view == 1 ) + { + ViewX = 2 * v13 + 21; + ViewY = 2 * v14 + 22; + } + if ( !ldir ) + { + LvlViewX = 2 * v13 + 21; + LvlViewY = 2 * v14 + 22; + } + if ( ldir == 6 ) + { + LvlViewX = 2 * v13 + 21; + LvlViewY = 2 * v14 + 22; + } + return result; +} +// 5276CC: using guessed type int nSx2; +// 5276D4: using guessed type int nSy2; +// 5CF320: using guessed type int LvlViewY; +// 5CF324: using guessed type int LvlViewX; + +//----- (0040E2D1) -------------------------------------------------------- +void __fastcall DRLG_L2PlaceRndSet(char *miniset, int probability) +{ + char *v2; // ebx + signed int v3; // esi + signed int v4; // ecx + int v5; // edx + signed int v6; // edi + signed int i; // edx + signed int v8; // esi + int v9; // eax + char v10; // cl + int v11; // edi + _BYTE *v12; // ecx + int v13; // esi + int v14; // eax + int v15; // eax + signed int j; // edx + signed int v17; // esi + char *v18; // eax + char v19; // cl + int v20; // [esp+8h] [ebp-3Ch] + char *v21; // [esp+10h] [ebp-34h] + int v22; // [esp+14h] [ebp-30h] + int v23; // [esp+18h] [ebp-2Ch] + int v24; // [esp+1Ch] [ebp-28h] + int v25; // [esp+20h] [ebp-24h] + int v26; // [esp+24h] [ebp-20h] + int v27; // [esp+28h] [ebp-1Ch] + int v28; // [esp+2Ch] [ebp-18h] + int v29; // [esp+30h] [ebp-14h] + signed int v30; // [esp+34h] [ebp-10h] + signed int v31; // [esp+38h] [ebp-Ch] + int v32; // [esp+3Ch] [ebp-8h] + signed int v33; // [esp+40h] [ebp-4h] + + v2 = miniset; + v32 = 0; + v20 = probability; + v3 = (unsigned char)miniset[1]; + v4 = (unsigned char)*miniset; + v21 = v2; + v30 = v4; + v26 = 40 - v3; + v31 = v3; + if ( 40 - v3 > 0 ) + { + v27 = 40 - v4; + v23 = -v3; + while ( 1 ) + { + v5 = 0; + v25 = 0; + if ( v27 > 0 ) + { + v29 = -v4; + v22 = v4 * v3 + 2; + v28 = 0; + v24 = -40 * v4; + do + { + v33 = 1; + v6 = 2; + if ( v5 >= nSx1 && v5 <= nSx2 && v32 >= nSy1 && v32 <= nSy2 ) + v33 = 0; + for ( i = 0; i < v31; ++i ) + { + if ( v33 != 1 ) + break; + v8 = 0; + if ( v30 > 0 ) + { + v9 = v32 + i + v28; + do + { + if ( v33 != 1 ) + break; + v10 = v2[v6]; + if ( v10 && dungeon[0][v9] != v10 ) + v33 = 0; + if ( dflags[0][v9] ) + v33 = 0; + ++v6; + ++v8; + v9 += 40; + } + while ( v8 < v30 ); + } + } + v11 = v22; + if ( v33 == 1 ) + { + v12 = (_BYTE *)v31; + v13 = v23; + if ( v23 >= v32 + 2 * v31 ) + { +LABEL_34: + _LOBYTE(v12) = 0; + if ( random((int)v12, 100) < v20 ) + { + for ( j = 0; j < v31; ++j ) + { + v17 = v30; + if ( v30 > 0 ) + { + v18 = (char *)dungeon + j + v28 + v32; + do + { + v19 = v2[v11]; + if ( v19 ) + *v18 = v19; + ++v11; + v18 += 40; + --v17; + } + while ( v17 ); + } + } + } + } + else + { + while ( v33 == 1 ) + { + v12 = (_BYTE *)v30; + v14 = v25 + 2 * v30; + if ( v29 < v14 ) + { + v15 = v14 - v29; + v12 = (unsigned char *)dungeon + v24 + v13; + do + { + if ( *v12 == v2[v22] ) + v33 = 0; + v12 += 40; + --v15; + } + while ( v15 ); + v2 = v21; + } + if ( ++v13 >= v32 + 2 * v31 ) + { + if ( v33 != 1 ) + break; + goto LABEL_34; + } + } + } + } + v24 += 40; + v28 += 40; + v5 = v25 + 1; + ++v29; + ++v25; + } + while ( v25 < v27 ); + } + ++v32; + ++v23; + if ( v32 >= v26 ) + break; + v4 = v30; + v3 = v31; + } + } +} +// 5276CC: using guessed type int nSx2; +// 5276D4: using guessed type int nSy2; + +//----- (0040E49C) -------------------------------------------------------- +void __cdecl DRLG_L2Subs() +{ + signed int v0; // edi + unsigned char v1; // bl + int v2; // eax + signed int v3; // edx + int v4; // esi + int i; // ebx + int j; // eax + signed int v7; // [esp+Ch] [ebp-10h] + char *v8; // [esp+10h] [ebp-Ch] + signed int v9; // [esp+14h] [ebp-8h] + int v10; // [esp+18h] [ebp-4h] + + v0 = 3; + v9 = -2; + v7 = 3; + do + { + v10 = 0; + v8 = &dungeon[0][v9 + 2]; + do + { + if ( (v10 < nSx1 || v10 > nSx2) && (v0 - 3 < nSy1 || v0 - 3 > nSy2) && !random(0, 4) ) + { + v1 = BTYPESL2[(unsigned char)*v8]; + if ( v1 ) + { + v2 = random(0, 16); + v3 = -1; + while ( v2 >= 0 ) + { + if ( ++v3 == 161 ) + v3 = 0; + if ( v1 == BTYPESL2[v3] ) + --v2; + } + v4 = v9; + for ( i = v0 - 1; v4 < i; ++v4 ) + { + for ( j = v10 - 2; j < v10 + 2; ++j ) + { + v0 = v7; + if ( (unsigned char)dungeon[j][v4] == v3 ) + { + v4 = v7; + j = v10 + 2; + } + } + } + if ( v4 < v0 ) + *v8 = v3; + } + } + ++v10; + v8 += 40; + } + while ( v10 < 40 ); + ++v9; + v7 = ++v0; + } + while ( v0 - 3 < 40 ); +} +// 5276CC: using guessed type int nSx2; +// 5276D4: using guessed type int nSy2; + +//----- (0040E59C) -------------------------------------------------------- +void __cdecl DRLG_L2Shadows() +{ + char *v0; // eax + unsigned char *v1; // esi + unsigned char v2; // dl + signed int v3; // edi + char v4; // cl + char v5; // cl + char v6; // cl + char v7; // cl + char v8; // cl + signed int v9; // [esp+8h] [ebp-Ch] + signed int v10; // [esp+Ch] [ebp-8h] + unsigned char v11; // [esp+11h] [ebp-3h] + unsigned char v12; // [esp+12h] [ebp-2h] + unsigned char v13; // [esp+13h] [ebp-1h] + + v10 = 1; + do + { + v9 = 39; + v0 = &dungeon[0][v10 + 39]; + do + { + v1 = &SPATSL2[0].s1; + v2 = BSTYPESL2[(unsigned char)v0[1]]; + v12 = BSTYPESL2[(unsigned char)*(v0 - 39)]; + v11 = BSTYPESL2[(unsigned char)*v0]; + v13 = BSTYPESL2[(unsigned char)*(v0 - 40)]; + do + { + if ( *(v1 - 1) == v2 ) + { + v3 = 1; + if ( *v1 && *v1 != v13 ) + v3 = 0; + v4 = v1[1]; + if ( v4 && v4 != v11 ) + v3 = 0; + v5 = v1[2]; + if ( v5 && v5 != v12 ) + v3 = 0; + if ( v3 == 1 ) + { + v6 = v1[3]; + if ( v6 ) + *(v0 - 40) = v6; + v7 = v1[4]; + if ( v7 ) + *v0 = v7; + v8 = v1[5]; + if ( v8 ) + *(v0 - 39) = v8; + } + } + v1 += 7; + } + while ( (signed int)v1 < (signed int)&word_48489A + 1 ); + v0 += 40; + --v9; + } + while ( v9 ); + ++v10; + } + while ( v10 < 40 ); +} +// 48489A: using guessed type short word_48489A; + +//----- (0040E66B) -------------------------------------------------------- +void __fastcall DRLG_L2SetRoom(int rx1, int ry1) +{ + int v2; // edi + int v3; // esi + int v4; // eax + char v5; // bl + int v6; // [esp+8h] [ebp-Ch] + char *v7; // [esp+Ch] [ebp-8h] + int v8; // [esp+10h] [ebp-4h] + + v8 = 0; + v2 = (unsigned char)pSetPiece_2[2]; + v3 = (unsigned char)*pSetPiece_2; + setpc_x = rx1; + setpc_y = ry1; + setpc_w = v3; + setpc_h = v2; + v7 = pSetPiece_2 + 4; + if ( v2 > 0 ) + { + do + { + if ( v3 > 0 ) + { + v6 = v3; + v4 = ry1 + v8 + 40 * rx1; + do + { + v5 = *v7; + if ( *v7 ) + { + dflags[0][v4] |= 0x80u; + dungeon[0][v4] = v5; + } + else + { + dungeon[0][v4] = 3; + } + v7 += 2; + v4 += 40; + --v6; + } + while ( v6 ); + } + ++v8; + } + while ( v8 < v2 ); + } +} +// 5CF330: using guessed type int setpc_h; +// 5CF334: using guessed type int setpc_w; + +//----- (0040E6F0) -------------------------------------------------------- +void __cdecl L2TileFix() +{ + signed int v0; // edx + char *v1; // eax + signed int v2; // esi + char v3; // cl + + v0 = 0; + do + { + v1 = (char *)dungeon + v0; + v2 = 40; + do + { + v3 = *v1; + if ( *v1 == 1 && v1[1] == 3 ) + v1[1] = 1; + if ( v3 == 3 ) + { + if ( v1[1] == 1 ) + v1[1] = 3; + if ( v1[40] == 7 ) + v1[40] = 3; + } + if ( v3 == 2 && v1[40] == 3 ) + v1[40] = 2; + if ( v3 == 11 && v1[40] == 14 ) + v1[40] = 16; + v1 += 40; + --v2; + } + while ( v2 ); + ++v0; + } + while ( v0 < 40 ); +} + +//----- (0040E74F) -------------------------------------------------------- +void __cdecl CreateDungeon() +{ + int v0; // esi + int v1; // edx + int v2; // ecx + signed int v3; // esi + char *v4; // eax + signed int v5; // ebx + _BYTE *v6; // ecx + bool v7; // zf + int v8; // eax + int v9; // edi + int v10; // esi + signed int v11; // [esp-4h] [ebp-20h] + int nX1; // [esp+8h] [ebp-14h] + int nY1; // [esp+Ch] [ebp-10h] + int nX2; // [esp+10h] [ebp-Ch] + int nY2; // [esp+14h] [ebp-8h] + int nHd; // [esp+18h] [ebp-4h] + + v0 = 0; + v1 = 0; + v2 = 0; + if ( currlevel == 5 ) + { + if ( !quests[9]._qactive ) + goto LABEL_12; + v1 = 20; + v0 = 14; + } + else + { + if ( currlevel == 6 ) + { + if ( !quests[14]._qactive ) + goto LABEL_12; + v11 = 10; + } + else + { + if ( currlevel != 7 || !quests[8]._qactive ) + goto LABEL_12; + v11 = 15; + } + v0 = v11; + v1 = v11; + } + v2 = 1; +LABEL_12: + CreateRoom(2, 2, 39, 39, 0, 0, v2, v1, v0); + while ( pHallList ) + { + GetHall(&nX1, &nY1, &nX2, &nY2, &nHd); + ConnectHall(nX1, nY1, nX2, nY2, nHd); + } + v3 = 0; + do + { + v4 = &predungeon[-1][v3]; + v5 = 41; + do + { + v6 = (unsigned char *)v4 + 40; + if ( v4[40] == 67 ) + *v6 = 35; + if ( *v6 == 66 ) + *v6 = 35; + if ( *v6 == 69 ) + *v6 = 35; + if ( *v6 == 65 ) + *v6 = 35; + if ( *v6 == 44 ) + { + v7 = *(v4 - 1) == 32; + *v6 = 46; + if ( v7 ) + *(v4 - 1) = 35; + if ( *v4 == 32 ) + *v4 = 35; + if ( v4[1] == 32 ) + v4[1] = 35; + if ( v4[79] == 32 ) + v4[79] = 35; + if ( v4[80] == 32 ) + v4[80] = 35; + if ( v4[81] == 32 ) + v4[81] = 35; + if ( v4[39] == 32 ) + v4[39] = 35; + if ( v4[41] == 32 ) + v4[41] = 35; + } + --v5; + v4 += 40; + } + while ( v5 ); + ++v3; + } + while ( v3 <= 40 ); + DL2_FillVoids(); + if ( v8 ) + { + v9 = 0; + do + { + v10 = 0; + do + DoPatternCheck(v10++, v9); + while ( v10 < 40 ); + ++v9; + } + while ( v9 < 40 ); + } +} + +//----- (0040E8A4) -------------------------------------------------------- +void __fastcall CreateRoom(int nX1, int nY1, int nX2, int nY2, int nRDest, int nHDir, int ForceHW, int nH, int nW) +{ + int v9; // esi + int v10; // ebx + int v11; // edx + int v12; // eax + int v13; // edx + int v14; // edx + int v15; // edi + int v16; // ecx + int v17; // esi + int v18; // ebx + int v19; // edx + int v20; // ecx + int v21; // eax + int v22; // ecx + int v23; // eax + int v24; // eax + int v25; // ecx + int v26; // eax + int *v27; // ecx + int v28; // eax + int v29; // eax + int *v30; // ecx + int v31; // eax + int nX1a; // [esp+Ch] [ebp-30h] + int v33; // [esp+10h] [ebp-2Ch] + int v34; // [esp+14h] [ebp-28h] + int v35; // [esp+18h] [ebp-24h] + int v36; // [esp+1Ch] [ebp-20h] + int v37; // [esp+20h] [ebp-1Ch] + int nY1a; // [esp+24h] [ebp-18h] + int v39; // [esp+28h] [ebp-14h] + int v40; // [esp+2Ch] [ebp-10h] + int v41; // [esp+30h] [ebp-Ch] + int v42; // [esp+34h] [ebp-8h] + int v43; // [esp+38h] [ebp-4h] + int *ForceHWa; // [esp+54h] [ebp+18h] + int *ForceHWb; // [esp+54h] [ebp+18h] + + v39 = nY1; + v37 = nX1; + if ( nRoomCnt < 80 ) + { + v40 = nX2 - 2; + nY1a = nY1 + 2; + while ( 1 ) + { + v9 = nX2 - v37; + v10 = nY2 - v39; + if ( nX2 - v37 < Area_Min || v10 < Area_Min ) + return; + if ( v9 > Room_Max ) + break; + nX1 = Room_Min; + if ( v9 > Room_Min ) + { + v11 = v9 - Room_Min; + goto LABEL_7; + } + v41 = nX2 - v37; +LABEL_11: + v13 = Room_Max; + if ( v10 <= Room_Max ) + { + if ( v10 <= nX1 ) + { + v36 = nY2 - v39; + goto LABEL_16; + } + v13 = nY2 - v39; + } + v14 = v13 - nX1; + _LOBYTE(nX1) = 0; + v36 = Room_Min + random(nX1, v14); +LABEL_16: + if ( ForceHW == 1 ) + { + v41 = nW; + v36 = nH; + } + _LOBYTE(nX1) = 0; + v15 = v37 + random(nX1, v9); + _LOBYTE(v16) = 0; + v17 = v39 + random(v16, v10); + v18 = v15 + v41; + v43 = v17 + v36; + if ( v15 + v41 > nX2 ) + { + v18 = nX2; + v15 = nX2 - v41; + } + if ( v17 + v36 > nY2 ) + { + v43 = nY2; + v17 = nY2 - v36; + } + if ( v15 >= 38 ) + v15 = 38; + if ( v17 >= 38 ) + v17 = 38; + if ( v15 <= 1 ) + v15 = 1; + if ( v17 <= 1 ) + v17 = 1; + if ( v18 >= 38 ) + v18 = 38; + if ( v43 >= 38 ) + v43 = 38; + if ( v18 <= 1 ) + v18 = 1; + if ( v43 <= 1 ) + v43 = 1; + DefineRoom(v15, v17, v18, v43, ForceHW); + if ( ForceHW == 1 ) + { + nSx2 = v18; + nSx1 = v15 + 2; + nSy1 = v17 + 2; + nSy2 = v43; + } + v19 = nRoomCnt; + v20 = nRDest; + v42 = nRoomCnt; + RoomList[nRoomCnt].nRoomDest = nRDest; + if ( nRDest ) + { + if ( nHDir == 1 ) + { + _LOBYTE(v20) = 0; + v21 = random(v20, v18 - v15 - 2); + _LOBYTE(v22) = 0; + nX1a = v21 + v15 + 1; + v33 = v17; + v23 = random(v22, RoomList[nRDest].nRoomx2 - RoomList[nRDest].nRoomx1 - 2); + v20 = 20 * nRDest; + v34 = v23 + RoomList[nRDest].nRoomx1 + 1; + v35 = RoomList[nRDest].nRoomy2; + } + if ( nHDir == 3 ) + { + _LOBYTE(v20) = 0; + v24 = random(v20, v18 - v15 - 2); + _LOBYTE(v25) = 0; + nX1a = v24 + v15 + 1; + v33 = v43; + v26 = random(v25, RoomList[nRDest].nRoomx2 - RoomList[nRDest].nRoomx1 - 2); + v20 = 20 * nRDest; + v34 = v26 + RoomList[nRDest].nRoomx1 + 1; + v35 = RoomList[nRDest].nRoomy1; + } + if ( nHDir == 2 ) + { + _LOBYTE(v20) = 0; + nX1a = v18; + v33 = random(v20, v43 - v17 - 2) + v17 + 1; + v34 = RoomList[nRDest].nRoomx1; + v27 = &RoomList[nRDest].nRoomy1; + ForceHWa = v27; + v28 = RoomList[nRDest].nRoomy2 - *v27; + _LOBYTE(v27) = 0; + v29 = random((int)v27, v28 - 2); + v20 = *ForceHWa; + v35 = v29 + *ForceHWa + 1; + } + if ( nHDir == 4 ) + { + _LOBYTE(v20) = 0; + nX1a = v15; + v33 = random(v20, v43 - v17 - 2) + v17 + 1; + v34 = RoomList[nRDest].nRoomx2; + v30 = &RoomList[nRDest].nRoomy1; + ForceHWb = v30; + v31 = RoomList[nRDest].nRoomy2 - *v30; + _LOBYTE(v30) = 0; + v35 = random((int)v30, v31 - 2) + *ForceHWb + 1; + } + AddHall(nX1a, v33, v34, v35, nHDir); + v19 = v42; + } + if ( v36 <= v41 ) + { + CreateRoom(v37 + 2, nY1a, v18 - 2, v17 - 2, v19, 3, 0, 0, 0); + CreateRoom(v15 + 2, v43 + 2, v40, nY2 - 2, v42, 1, 0, 0, 0); + CreateRoom(v37 + 2, v17 + 2, v15 - 2, nY2 - 2, v42, 2, 0, 0, 0); + nHDir = 4; + nW = 0; + nH = 0; + ForceHW = 0; + nRDest = v42; + nY2 = v43 - 2; + nX2 -= 2; + v40 -= 2; + v39 += 2; + nY1a += 2; + v37 = v18 + 2; + } + else + { + CreateRoom(v37 + 2, nY1a, v15 - 2, v43 - 2, v19, 2, 0, 0, 0); + CreateRoom(v18 + 2, v17 + 2, v40, nY2 - 2, v42, 4, 0, 0, 0); + CreateRoom(v37 + 2, v43 + 2, v18 - 2, nY2 - 2, v42, 1, 0, 0, 0); + nW = 0; + nH = 0; + ForceHW = 0; + nRDest = v42; + nHDir = 3; + nX2 -= 2; + v40 -= 2; + v39 += 2; + nY1a += 2; + nY2 = v17 - 2; + v37 = v15 + 2; + } + if ( nRoomCnt >= 80 ) + return; + } + v11 = Room_Max - Room_Min; +LABEL_7: + _LOBYTE(nX1) = 0; + v12 = random(nX1, v11); + nX1 = Room_Min; + v41 = Room_Min + v12; + goto LABEL_11; + } +} +// 484858: using guessed type int Area_Min; +// 48485C: using guessed type int Room_Max; +// 484860: using guessed type int Room_Min; +// 5276CC: using guessed type int nSx2; +// 5276D4: using guessed type int nSy2; + +//----- (0040ECF9) -------------------------------------------------------- +void __fastcall DefineRoom(int nX1, int nY1, int nX2, int nY2, int ForceHW) +{ + int v5; // esi + int v6; // edi + int v7; // eax + int i; // eax + bool v9; // zf + int v10; // ecx + char *v11; // eax + char *v12; // ebx + int v13; // eax + int v14; // [esp+10h] [ebp-4h] + int v15; // [esp+10h] [ebp-4h] + int nY2a; // [esp+20h] [ebp+Ch] + char *ForceHWa; // [esp+24h] [ebp+10h] + + v5 = nX1; + v6 = nX2; + predungeon[v5][nY1] = 67; + predungeon[v5][nY2] = 69; + predungeon[v6][nY1] = 66; + predungeon[v6][nY2] = 65; + v7 = nRoomCnt + 1; + nRoomCnt = v7; + v7 *= 20; + *(int *)((char *)&RoomList[0].nRoomx1 + v7) = nX1; + *(int *)((char *)&RoomList[0].nRoomx2 + v7) = nX2; + *(int *)((char *)&RoomList[0].nRoomy1 + v7) = nY1; + *(int *)((char *)&RoomList[0].nRoomy2 + v7) = nY2; + if ( ForceHW == 1 ) + { + for ( i = nX1; i < nX2; ++i ) + { + if ( i < nY2 ) + { + ForceHWa = &dflags[i][nY1]; + v14 = nY2 - i; + i = nY2; + do + { + *ForceHWa |= 0x80u; + v9 = v14-- == 1; + ForceHWa += 40; + } + while ( !v9 ); + } + } + } + v10 = nX1 + 1; + if ( v10 <= nX2 - 1 ) + { + v15 = nX2 - v10; + v11 = &predungeon[v10][nY2]; + do + { + v11[nY1 - nY2] = 35; + *v11 = 35; + v11 += 40; + --v15; + } + while ( v15 ); + } + nY2a = nY2 - 1; + while ( ++nY1 <= nY2a ) + { + predungeon[v5][nY1] = 35; + predungeon[v6][nY1] = 35; + if ( v10 < nX2 ) + { + v12 = &predungeon[v10][nY1]; + v13 = nX2 - v10; + do + { + *v12 = 46; + v12 += 40; + --v13; + } + while ( v13 ); + } + } +} + +//----- (0040EE1D) -------------------------------------------------------- +void __fastcall AddHall(int nX1, int nY1, int nX2, int nY2, int nHd) +{ + int v5; // edi + int v6; // esi + HALLNODE *v7; // eax + HALLNODE *i; // ecx + + v5 = nX1; + v6 = nY1; + if ( pHallList ) + { + v7 = (HALLNODE *)DiabloAllocPtr(24); + v7->pNext = 0; + v7->nHallx2 = nX2; + v7->nHally2 = nY2; + v7->nHallx1 = v5; + v7->nHally1 = v6; + v7->nHalldir = nHd; + for ( i = pHallList; i->pNext; i = i->pNext ) + ; + i->pNext = v7; + } + else + { + pHallList = (HALLNODE *)DiabloAllocPtr(24); + pHallList->nHallx1 = v5; + pHallList->nHally1 = v6; + pHallList->nHallx2 = nX2; + pHallList->nHally2 = nY2; + pHallList->nHalldir = nHd; + pHallList->pNext = 0; + } +} + +//----- (0040EEAC) -------------------------------------------------------- +void __fastcall GetHall(int *nX1, int *nY1, int *nX2, int *nY2, int *nHd) +{ + HALLNODE *v5; // esi + HALLNODE *v6; // ecx + + v5 = pHallList->pNext; + *nX1 = pHallList->nHallx1; + *nY1 = pHallList->nHally1; + *nX2 = pHallList->nHallx2; + *nY2 = pHallList->nHally2; + *nHd = pHallList->nHalldir; + v6 = pHallList; + pHallList = 0; + mem_free_dbg(v6); + pHallList = v5; +} + +//----- (0040EF09) -------------------------------------------------------- +void __fastcall ConnectHall(int nX1, int nY1, int nX2, int nY2, int nHd) +{ + int v5; // edi + signed int v6; // esi + int v7; // eax + int v8; // ecx + int v9; // edi + int v10; // ebx + int v11; // ecx + char v12; // al + int v13; // eax + int v14; // ecx + char *v15; // ebx + int v16; // ecx + int v17; // edx + int v18; // ecx + int v19; // edx + int v20; // eax + int v21; // ST04_4 + int v22; // ecx + int v23; // ebx + int v24; // ebx + bool v25; // zf + signed int v26; // [esp-4h] [ebp-34h] + signed int v27; // [esp-4h] [ebp-34h] + signed int v28; // [esp-4h] [ebp-34h] + signed int v29; // [esp-4h] [ebp-34h] + int v30; // [esp+Ch] [ebp-24h] + int v31; // [esp+10h] [ebp-20h] + int v32; // [esp+14h] [ebp-1Ch] + signed int v33; // [esp+18h] [ebp-18h] + signed int v34; // [esp+1Ch] [ebp-14h] + signed int v35; // [esp+20h] [ebp-10h] + int v36; // [esp+24h] [ebp-Ch] + char *v37; // [esp+28h] [ebp-8h] + signed int nY; // [esp+2Ch] [ebp-4h] + int nX2a; // [esp+38h] [ebp+8h] + int nY2a; // [esp+3Ch] [ebp+Ch] + int nHda; // [esp+40h] [ebp+10h] + + v34 = 0; + v5 = nY1; + v6 = nX1; + _LOBYTE(nX1) = 0; + nY = nY1; + v7 = random(nX1, 100); + _LOBYTE(v8) = 0; + v33 = v7; + v32 = random(v8, 100); + v31 = v6; + v30 = v5; + CreateDoorType(v6, v5); + CreateDoorType(nX2, nY2); + abs(nX2 - v6); + abs(nY2 - v5); + v9 = nHd; + v10 = nX2 - Dir_Xadd[nHd]; + v11 = nY2 - Dir_Yadd[nHd]; + nHda = 0; + nY2a = v11; + nX2a = v10; + predungeon[v10][v11] = 44; + v37 = &predungeon[v6][nY]; + do + { + if ( v6 >= 38 && v9 == 2 ) + v9 = 4; + if ( nY >= 38 && v9 == 3 ) + v9 = 1; + if ( v6 <= 1 && v9 == 4 ) + v9 = 2; + if ( nY <= 1 && v9 == 1 ) + v9 = 3; + v12 = *v37; + if ( *v37 == 67 && (v9 == 1 || v9 == 4) ) + v9 = 2; + if ( v12 == 66 && (v9 == 1 || v9 == 2) ) + v9 = 3; + if ( v12 == 69 && (v9 == 4 || v9 == 3) ) + v9 = 1; + if ( v12 == 65 && (v9 == 2 || v9 == 3) ) + v9 = 4; + v13 = Dir_Xadd[v9]; + v14 = Dir_Yadd[v9]; + nY += v14; + v6 += v13; + v15 = &predungeon[v6][nY]; + v37 = v15; + if ( *v15 == 32 ) + { + if ( nHda ) + { + CreateDoorType(v6 - v13, nY - v14); + } + else + { + if ( v33 < 50 ) + { + if ( v9 == 1 || v9 == 3 ) + { + v17 = nY; + v16 = v6 - 1; + } + else + { + v16 = v6; + v17 = nY - 1; + } + PlaceHallExt(v16, v17); + } + if ( v32 < 50 ) + { + if ( v9 == 1 || v9 == 3 ) + { + v19 = nY; + v18 = v6 + 1; + } + else + { + v18 = v6; + v19 = nY + 1; + } + PlaceHallExt(v18, v19); + } + } + nHda = 0; + *v15 = 44; + } + else + { + if ( !nHda && *v15 == 35 ) + CreateDoorType(v6, nY); + if ( *v15 != 44 ) + nHda = 1; + } + v36 = abs(nX2a - v6); + v20 = abs(nY2a - nY); + v22 = v21; + v35 = v20; + if ( v36 <= v20 ) + { + v24 = 5 * v20; + if ( 5 * v20 > 80 ) + v24 = 80; + _LOBYTE(v22) = 0; + if ( random(v22, 100) < v24 ) + { + if ( nY2a <= nY || nY >= 40 ) + { + v9 = 1; + goto LABEL_67; + } + v26 = 3; + goto LABEL_58; + } + } + else + { + v23 = 2 * v36; + if ( 2 * v36 > 30 ) + v23 = 30; + _LOBYTE(v22) = 0; + if ( random(v22, 100) < v23 ) + { + if ( nX2a <= v6 || v6 >= 40 ) + v26 = 4; + else + v26 = 2; +LABEL_58: + v9 = v26; + goto LABEL_67; + } + } +LABEL_67: + if ( v35 < 10 && v6 == nX2a && (v9 == 2 || v9 == 4) ) + { + if ( nY2a <= nY || nY >= 40 ) + v9 = 1; + else + v9 = 3; + } + if ( v36 < 10 && nY == nY2a && (v9 == 1 || v9 == 3) ) + { + if ( nX2a <= v6 || v6 >= 40 ) + v27 = 4; + else + v27 = 2; + v9 = v27; + } + if ( v35 == 1 ) + { + v25 = v36 == 1; + if ( v36 <= 1 ) + goto LABEL_94; + if ( v9 == 1 || v9 == 3 ) + { + if ( nX2a <= v6 || v6 >= 40 ) + v28 = 4; + else + v28 = 2; + v9 = v28; + } + } + v25 = v36 == 1; +LABEL_94: + if ( v25 ) + { + if ( v35 <= 1 || v9 != 2 && v9 != 4 ) + goto LABEL_109; + if ( nY2a > nY && v6 < 40 ) + goto LABEL_100; + v9 = 1; + } + if ( !v36 && *v37 != 32 && (v9 == 2 || v9 == 4) ) + { + if ( nX2a <= v31 || v6 >= 40 ) + { + v9 = 1; + goto LABEL_109; + } +LABEL_100: + v9 = 3; + } +LABEL_109: + if ( !v35 && *v37 != 32 && (v9 == 1 || v9 == 3) ) + { + if ( nY2a <= v30 || nY >= 40 ) + v29 = 4; + else + v29 = 2; + v9 = v29; + } + if ( v6 == nX2a && nY == nY2a ) + v34 = 1; + } + while ( !v34 ); +} + +//----- (0040F265) -------------------------------------------------------- +void __fastcall CreateDoorType(int nX, int nY) +{ + int v2; // eax + signed int v3; // esi + char *v4; // ecx + char v5; // al + + v2 = nX; + v3 = 0; + v4 = &predungeon[nX][nY]; + if ( *(v4 - 40) == 68 ) + v3 = 1; + if ( predungeon[v2 + 1][nY] == 68 ) + v3 = 1; + if ( *(v4 - 1) == 68 ) + v3 = 1; + if ( predungeon[v2][nY + 1] == 68 ) + v3 = 1; + v5 = *v4; + if ( *v4 == 66 || v5 == 67 || v5 == 65 || v5 == 69 ) + v3 = 1; + if ( !v3 ) + *v4 = 68; +} + +//----- (0040F2BD) -------------------------------------------------------- +void __fastcall PlaceHallExt(int nX, int nY) +{ + char *v2; // eax + + v2 = &predungeon[nX][nY]; + if ( *v2 == 32 ) + *v2 = 44; +} + +//----- (0040F2D0) -------------------------------------------------------- +void __fastcall DoPatternCheck(int i, int j) +{ + int v2; // edx + signed int v3; // eax + signed int v4; // ebp + int v5; // esi + int v6; // ecx + bool v7; // zf + char v8; // bl + bool v9; // zf + char v10; // bl + int *v11; // [esp+0h] [ebp-10h] + int v12; // [esp+4h] [ebp-Ch] + int v13; // [esp+8h] [ebp-8h] + int v14; // [esp+Ch] [ebp-4h] + + v13 = j; + v14 = i; + if ( Patterns[0][4] != 255 ) + { + v12 = 0; + v2 = i - 1; + v11 = &Patterns[0][4]; + do + { + v3 = v2; + v4 = 254; + v5 = v13 - 1; + v6 = 0; + while ( v4 == 254 ) + { + v4 = 255; + if ( v6 == 3 || v6 == 6 ) + { + ++v5; + v3 = v2; + } + if ( v3 < 0 || v3 >= 40 || v5 < 0 || v5 >= 40 ) + { +LABEL_26: + v4 = 254; + } + else + { + switch ( Patterns[0][v6 + v12] ) + { + case 0: + goto LABEL_26; + case 1: + v7 = predungeon[v3][v5] == 35; + goto LABEL_25; + case 2: + v7 = predungeon[v3][v5] == 46; + goto LABEL_25; + case 3: + v7 = predungeon[v3][v5] == 68; + goto LABEL_25; + case 4: + v7 = predungeon[v3][v5] == 32; + goto LABEL_25; + case 5: + v8 = predungeon[v3][v5]; + v9 = v8 == 68; + goto LABEL_23; + case 6: + v10 = predungeon[v3][v5]; + if ( v10 == 68 ) + goto LABEL_26; + v7 = v10 == 35; + goto LABEL_25; + case 7: + v8 = predungeon[v3][v5]; + v9 = v8 == 32; + goto LABEL_23; + case 8: + v8 = predungeon[v3][v5]; + if ( v8 == 68 ) + goto LABEL_26; + v9 = v8 == 35; +LABEL_23: + if ( v9 ) + goto LABEL_26; + v7 = v8 == 46; +LABEL_25: + if ( v7 ) + goto LABEL_26; + break; + default: + break; + } + } + ++v3; + if ( ++v6 >= 9 ) + { + if ( v4 == 254 ) + dungeon[v14][v13] = *((_BYTE *)v11 + 20); + break; + } + } + v11 += 10; + v12 += 10; + } + while ( *v11 != 255 ); + } +} + +//----- (0040F459) -------------------------------------------------------- +void __cdecl DL2_FillVoids() +{ + int i; // eax + int v1; // ecx + int v2; // eax + int v3; // ecx + int v4; // edi + int v5; // eax + int v6; // ebx + int v7; // eax + int v8; // ecx + char v9; // dl + int v10; // eax + int v11; // esi + signed int v12; // ecx + signed int v13; // edi + signed int v14; // edx + signed int v15; // eax + int v16; // ebx + int v17; // eax + signed int v18; // edx + int k; // eax + int v20; // ebx + int v21; // ebx + int v22; // eax + int v23; // ebx + signed int v24; // edx + int v25; // eax + int v26; // esi + int v27; // edx + int v28; // esi + int v29; // edx + int v30; // edx + signed int v31; // ebx + int v32; // edi + int v33; // ecx + char *v34; // eax + int v35; // edi + int v36; // edx + signed int v37; // ecx + signed int v38; // eax + int v39; // edx + int v40; // edx + int v41; // edx + signed int v42; // ebx + int j; // edi + int v44; // ecx + char *v45; // eax + int v46; // edi + int v47; // [esp-4h] [ebp-30h] + signed int v48; // [esp+Ch] [ebp-20h] + signed int y1f; // [esp+10h] [ebp-1Ch] + signed int y2f; // [esp+14h] [ebp-18h] + signed int x2f; // [esp+18h] [ebp-14h] + signed int x1f; // [esp+1Ch] [ebp-10h] + int x2; // [esp+20h] [ebp-Ch] + int x2a; // [esp+20h] [ebp-Ch] + int y1; // [esp+24h] [ebp-8h] + int y1a; // [esp+24h] [ebp-8h] + int y1b; // [esp+24h] [ebp-8h] + int y2; // [esp+28h] [ebp-4h] + int y2a; // [esp+28h] [ebp-4h] + int y2b; // [esp+28h] [ebp-4h] + + v48 = 0; + for ( i = DL2_NumNoChar(); i > 700 && v48 < 100; i = DL2_NumNoChar() ) + { + _LOBYTE(v1) = 0; + v2 = random(v1, 38); + _LOBYTE(v3) = 0; + v4 = v2 + 1; + v5 = random(v3, 38); + v6 = v5 + 1; + v7 = v5 + 1 + 40 * v4; + if ( predungeon[0][v7] != 35 ) + continue; + y2f = 0; + y1f = 0; + x2f = 0; + x1f = 0; + v8 = *((unsigned char *)&VR1 + v7); + if ( (_BYTE)v8 == 32 && predungeon[1][v7] == 46 ) + { + if ( predungeon[0][v7 + 39] != 46 + || predungeon[1][v7 + 1] != 46 + || *((_BYTE *)&HR3 + v7 + 3) != 32 + || *((_BYTE *)&VR1 + v7 + 1) != 32 ) + { + goto LABEL_34; + } + y1f = 1; +LABEL_32: + x1f = 1; +LABEL_33: + y2f = 1; + goto LABEL_34; + } + if ( predungeon[1][v7] == 32 && (_BYTE)v8 == 46 ) + { + if ( *((_BYTE *)&HR3 + v7 + 3) != 46 + || *((_BYTE *)&VR1 + v7 + 1) != 46 + || predungeon[0][v7 + 39] != 32 + || predungeon[1][v7 + 1] != 32 ) + { + goto LABEL_34; + } + y1f = 1; + x2f = 1; + goto LABEL_33; + } + v9 = *(_BYTE *)(v7 + 5404379); + if ( v9 != 32 || predungeon[0][v7 + 1] != 46 ) + { + if ( predungeon[0][v7 + 1] != 32 + || v9 != 46 + || *((_BYTE *)&HR3 + v7 + 3) != 46 + || predungeon[0][v7 + 39] != 46 + || predungeon[-1][v7 + 1] != 32 + || predungeon[1][v7 + 1] != 32 ) + { + goto LABEL_34; + } + x2f = 1; + goto LABEL_32; + } + if ( predungeon[-1][v7 + 1] == 46 + && predungeon[1][v7 + 1] == 46 + && *((_BYTE *)&HR3 + v7 + 3) == 32 + && predungeon[0][v7 + 39] == 32 ) + { + x2f = 1; + x1f = 1; + y1f = 1; + v10 = DL2_Cont(1u, 1u, 1u, 0); + goto LABEL_35; + } +LABEL_34: + v10 = DL2_Cont(x1f, y1f, x2f, y2f); +LABEL_35: + if ( v10 ) + { + v11 = v4 - 1; + if ( !x1f ) + v11 = v4; + v12 = x2f; + if ( x2f ) + ++v4; + x2 = v4; + v13 = y1f; + if ( y1f ) + y1 = v6 - 1; + else + y1 = v6; + v14 = y2f; + if ( y2f ) + ++v6; + v15 = x1f; + y2 = v6; + if ( x1f ) + { + if ( x2f ) + { + if ( y1f ) + { + if ( y2f ) + goto LABEL_177; + v37 = x1f; + v38 = x2f; + v39 = x2; + while ( v37 || v38 ) + { + if ( !v11 ) + v37 = 0; + if ( v39 == 39 ) + v38 = 0; + if ( v39 - v11 >= 14 ) + { + v37 = 0; + v38 = 0; + } + if ( v37 ) + --v11; + if ( v38 ) + ++v39; + if ( predungeon[v11][y1] != 32 ) + v37 = 0; + if ( predungeon[v39][y1] != 32 ) + v38 = 0; + } + v28 = v11 + 2; + v40 = v39 - 2; + x2a = v40; + v41 = v40 - v28; + if ( v41 <= 5 ) + goto LABEL_177; + v42 = y1f; + for ( j = y1; ; --j ) + { + if ( !j ) + v42 = 0; + if ( y2 - j >= 12 ) + v42 = 0; + if ( v28 <= x2a ) + { + v44 = v41 + 1; + v45 = &predungeon[v28][j]; + do + { + if ( *v45 != 32 ) + v42 = 0; + v45 += 40; + --v44; + } + while ( v44 ); + } + if ( !v42 ) + break; + } + v46 = j + 2; + if ( y2 - v46 <= 5 ) + goto LABEL_177; + DL2_DrawRoom(v28, v46, x2a, y2); + v36 = v46; + v47 = y2; + } + else + { + v27 = x2; + while ( v15 || v12 ) + { + if ( !v11 ) + v15 = 0; + if ( v27 == 39 ) + v12 = 0; + if ( v27 - v11 >= 14 ) + { + v15 = 0; + v12 = 0; + } + if ( v15 ) + --v11; + if ( v12 ) + ++v27; + if ( predungeon[v11][v6] != 32 ) + v15 = 0; + if ( predungeon[v27][v6] != 32 ) + v12 = 0; + } + v28 = v11 + 2; + v29 = v27 - 2; + x2a = v29; + v30 = v29 - v28; + if ( v30 <= 5 ) + goto LABEL_177; + v31 = y2f; + v32 = y2; + if ( y2f ) + { + while ( 1 ) + { + if ( v32 == 39 ) + v31 = 0; + if ( v32 - y1 >= 12 ) + v31 = 0; + if ( v28 <= x2a ) + { + v33 = v30 + 1; + v34 = &predungeon[v28][v32]; + do + { + if ( *v34 != 32 ) + v31 = 0; + v34 += 40; + --v33; + } + while ( v33 ); + } + if ( !v31 ) + break; + ++v32; + } + } + v35 = v32 - 2; + if ( v35 - y1 <= 5 ) + goto LABEL_177; + DL2_DrawRoom(v28, y1, x2a, v35); + v36 = y1; + v47 = v35; + } + DL2_KnockWalls(v28, v36, x2a, v47); + } + else + { + v21 = y1; + while ( v13 || v14 ) + { + if ( !v21 ) + v13 = 0; + if ( y2 == 39 ) + v14 = 0; + if ( y2 - v21 >= 14 ) + { + v13 = 0; + v14 = 0; + } + if ( v13 ) + --v21; + if ( v14 ) + ++y2; + v22 = 40 * v11 + 5404380; + if ( *(_BYTE *)(v22 + v21) != 32 ) + v13 = 0; + if ( *(_BYTE *)(v22 + y2) != 32 ) + v14 = 0; + } + y2b = y2 - 2; + v23 = v21 + 2; + y1b = v23; + if ( y2b - v23 > 5 ) + { + v24 = x1f; + while ( 1 ) + { + if ( !v11 ) + v24 = 0; + if ( x2 - v11 >= 12 ) + v24 = 0; + v25 = v23; + if ( v23 <= y2b ) + { + do + { + if ( *(_BYTE *)(40 * v11 + 5404380 + v25) != 32 ) + v24 = 0; + ++v25; + } + while ( v25 <= y2b ); + v23 = y1b; + } + if ( !v24 ) + break; + --v11; + } + v26 = v11 + 2; + if ( x2 - v26 > 5 ) + { + DL2_DrawRoom(v26, v23, x2, y2b); + DL2_KnockWalls(v26, v23, x2, y2b); + } + } + } + } + else + { + v16 = x2; + while ( v13 || v14 ) + { + if ( !y1 ) + v13 = 0; + if ( y2 == 39 ) + v14 = 0; + if ( y2 - y1 >= 14 ) + { + v13 = 0; + v14 = 0; + } + if ( v13 ) + --y1; + if ( v14 ) + ++y2; + v17 = 40 * x2 + 5404380; + if ( *(_BYTE *)(v17 + y1) != 32 ) + v13 = 0; + if ( *(_BYTE *)(v17 + y2) != 32 ) + v14 = 0; + } + y2a = y2 - 2; + y1a = y1 + 2; + if ( y2a - y1a > 5 ) + { + v18 = x2f; + if ( x2f ) + { + while ( 1 ) + { + if ( v16 == 39 ) + v18 = 0; + if ( v16 - v11 >= 12 ) + v18 = 0; + for ( k = y1a; k <= y2a; ++k ) + { + if ( *(_BYTE *)(40 * v16 + 5404380 + k) != 32 ) + v18 = 0; + } + if ( !v18 ) + break; + ++v16; + } + } + v20 = v16 - 2; + if ( v20 - v11 > 5 ) + { + DL2_DrawRoom(v11, y1a, v20, y2a); + DL2_KnockWalls(v11, y1a, v20, y2a); + } + } + } + } +LABEL_177: + ++v48; + } + DL2_NumNoChar(); +} + +//----- (0040F9B1) -------------------------------------------------------- +int __fastcall DL2_Cont(unsigned char x1f, unsigned char y1f, unsigned char x2f, unsigned char y2f) +{ + bool v4; // zf + + if ( x1f && x2f ) + { + if ( !y1f ) + goto LABEL_16; + if ( y2f ) + return 0; + if ( !y1f ) + { +LABEL_16: + v4 = y2f == 0; + goto LABEL_11; + } + return 1; + } + if ( !y1f || !y2f ) + return 0; + if ( x1f ) + return 1; + v4 = x2f == 0; +LABEL_11: + if ( !v4 ) + return 1; + return 0; +} + +//----- (0040F9EE) -------------------------------------------------------- +int __cdecl DL2_NumNoChar() +{ + int result; // eax + signed int v1; // edx + _BYTE *v2; // ecx + signed int v3; // esi + + result = 0; + v1 = 0; + do + { + v2 = (unsigned char *)predungeon + v1; + v3 = 40; + do + { + if ( *v2 == 32 ) + ++result; + v2 += 40; + --v3; + } + while ( v3 ); + ++v1; + } + while ( v1 < 40 ); + return result; +} + +//----- (0040FA10) -------------------------------------------------------- +void __fastcall DL2_DrawRoom(int x1, int y1, int x2, int y2) +{ + int v4; // ebx + char *v5; // edx + int v6; // esi + int i; // esi + char *v8; // esi + int v9; // eax + int v10; // [esp+Ch] [ebp-4h] + + v4 = y1; + v10 = y1; + while ( v4 <= y2 ) + { + if ( x1 <= x2 ) + { + v5 = &predungeon[x1][v4]; + v6 = x2 - x1 + 1; + do + { + *v5 = 46; + v5 += 40; + --v6; + } + while ( v6 ); + } + ++v4; + } + for ( i = v10; i <= y2; ++i ) + { + *(_BYTE *)(40 * x1 + 5404380 + i) = 35; + *(_BYTE *)(40 * x2 + 5404380 + i) = 35; + } + if ( x1 <= x2 ) + { + v8 = &predungeon[x1][y2]; + v9 = x2 - x1 + 1; + do + { + v8[v10 - y2] = 35; + *v8 = 35; + v8 += 40; + --v9; + } + while ( v9 ); + } +} + +//----- (0040FA97) -------------------------------------------------------- +void __fastcall DL2_KnockWalls(int x1, int y1, int x2, int y2) +{ + int v4; // esi + char *v5; // ebx + _BYTE *v6; // eax + int v7; // edi + int v8; // eax + int v9; // ecx + int v10; // edx + _BYTE *v11; // esi + + v4 = x1 + 1; + if ( x1 + 1 < x2 ) + { + v5 = &predungeon[v4][y2 + 1]; + v6 = (_BYTE *)(40 * v4 + y1 + 5404379); + v7 = x2 - v4; + do + { + if ( *v6 == 46 && v6[2] == 46 ) + v6[1] = 46; + if ( v6[y2 - y1] == 46 && *v5 == 46 ) + *(v5 - 1) = 46; + if ( *v6 == 68 ) + *v6 = 46; + if ( *v5 == 68 ) + *v5 = 46; + v6 += 40; + v5 += 40; + --v7; + } + while ( v7 ); + } + v8 = y1 + 1; + if ( y1 + 1 < y2 ) + { + v9 = x1; + v10 = 40 * x2 + 5404420; + do + { + v11 = (unsigned char *)&VR1 + v9 * 40 + v8; + if ( *v11 == 46 && predungeon[v9 + 1][v8] == 46 ) + predungeon[v9][v8] = 46; + if ( *(_BYTE *)(v10 + v8 - 80) == 46 && *(_BYTE *)(v10 + v8) == 46 ) + *(_BYTE *)(v10 + v8 - 40) = 46; + if ( *v11 == 68 ) + *v11 = 46; + if ( *(_BYTE *)(v10 + v8) == 68 ) + *(_BYTE *)(v10 + v8) = 46; + ++v8; + } + while ( v8 < y2 ); + } +} + +//----- (0040FB6C) -------------------------------------------------------- +void __cdecl DRLG_L2FloodTVal() +{ + int v0; // ebx + int v1; // esi + char *v2; // edi + _BYTE *v3; // [esp+Ch] [ebp-Ch] + signed int x; // [esp+10h] [ebp-8h] + signed int i; // [esp+14h] [ebp-4h] + + v0 = 16; + v1 = 0; + do + { + i = 0; + x = 16; + v2 = &dung_map[16][v0]; + v3 = (unsigned char *)dungeon + v1; + do + { + if ( *v3 == 3 && !*v2 ) + { + DRLG_L2FTVR(i, v1, x, v0, 0); + ++TransVal; + } + x += 2; + v3 += 40; + v2 += 224; + ++i; + } + while ( i < 40 ); + v0 += 2; + ++v1; + } + while ( v1 < 40 ); +} +// 5A5590: using guessed type char TransVal; + +//----- (0040FBDB) -------------------------------------------------------- +void __fastcall DRLG_L2FTVR(int i, int j, int x, int y, int d) +{ + int v5; // ebx + int v6; // esi + int v7; // edi + int v8; // edx + int v9; // ecx + int v10; // ebx + int v11; // eax + int v12; // edi + char v13; // al + char v14; // al + int v15; // ecx + int v16; // ecx + int v17; // ecx + int v18; // ecx + int v19; // [esp+Ch] [ebp-14h] + int k; // [esp+10h] [ebp-10h] + int v21; // [esp+14h] [ebp-Ch] + int ja; // [esp+18h] [ebp-8h] + int ia; // [esp+1Ch] [ebp-4h] + int ya; // [esp+2Ch] [ebp+Ch] + + v5 = x; + v6 = y; + v7 = j; + v8 = i; + v9 = 112 * x + y; + ja = v7; + v21 = v8; + if ( !dung_map[0][v9] ) + { + v19 = x; + ia = v8 - 1; + v10 = x - 2; + v11 = 40 * v8; + ya = v7 - 1; + v12 = v6 - 2; + for ( k = 40 * v8; dungeon[0][v11 + ja] == 3; v11 = k ) + { + v13 = TransVal; + dung_map[0][v9] = TransVal; + dung_map[1][v9] = v13; + dung_map[0][v9 + 1] = v13; + dung_map[1][v9 + 1] = v13; + DRLG_L2FTVR(ia + 2, ja, v10 + 4, v6, 1); + DRLG_L2FTVR(ia, ja, v10, v6, 2); + DRLG_L2FTVR(v21, ya + 2, x, v12 + 4, 3); + DRLG_L2FTVR(v21, ya, x, v12, 4); + DRLG_L2FTVR(ia, ya, v10, v12, 5); + DRLG_L2FTVR(ia + 2, ya, v10 + 4, v12, 6); + DRLG_L2FTVR(ia, ya + 2, v10, v12 + 4, 7); + v19 += 2; + k += 40; + d = 8; + x += 2; + v6 += 2; + v12 += 2; + v10 += 2; + ++ja; + ++ya; + ++v21; + ++ia; + v9 = v19 * 112 + v6; + if ( dung_map[v19][v6] ) + break; + } + v5 = x; + } + v14 = TransVal; + if ( d == 1 ) + { + v15 = v6 + 112 * v5; + dung_map[0][v15] = TransVal; + dung_map[0][v15 + 1] = v14; + } + if ( d == 2 ) + { + v16 = v6 + 112 * v5; + dung_map[1][v16] = v14; + dung_map[1][v16 + 1] = v14; + } + if ( d == 3 ) + { + v17 = v6 + 112 * v5; + dung_map[0][v17] = v14; + dung_map[1][v17] = v14; + } + if ( d == 4 ) + { + v18 = v6 + 112 * v5; + dung_map[0][v18 + 1] = v14; + dung_map[1][v18 + 1] = v14; + } + if ( d == 5 ) + dung_map[v5 + 1][v6 + 1] = v14; + if ( d == 6 ) + dung_map[v5][v6 + 1] = v14; + if ( d == 7 ) + dung_map[v5 + 1][v6] = v14; + if ( d == 8 ) + dung_map[v5][v6] = v14; +} +// 5A5590: using guessed type char TransVal; + +//----- (0040FDCB) -------------------------------------------------------- +void __cdecl DRLG_L2TransFix() +{ + signed int v0; // esi + char *v1; // eax + char *v2; // ecx + signed int v3; // edi + char v4; // bl + char v5; // dl + char v6; // dl + char v7; // dl + char v8; // dl + char v9; // dl + char *v10; // [esp+Ch] [ebp-4h] + + v0 = 0; + v10 = &dung_map[16][16]; + do + { + v1 = v10; + v2 = (char *)dungeon + v0; + v3 = 40; + do + { + v4 = *v2; + if ( *v2 == 14 && *(v2 - 1) == 10 ) + { + v5 = *v1; + v1[112] = *v1; + v1[113] = v5; + } + if ( v4 == 15 && v2[40] == 11 ) + { + v6 = *v1; + v1[1] = *v1; + v1[113] = v6; + } + if ( v4 == 10 ) + { + v7 = *v1; + v1[112] = *v1; + v1[113] = v7; + } + if ( v4 == 11 ) + { + v8 = *v1; + v1[1] = *v1; + v1[113] = v8; + } + if ( v4 == 16 ) + { + v9 = *v1; + v1[112] = *v1; + v1[1] = v9; + v1[113] = v9; + } + v1 += 224; + v2 += 40; + --v3; + } + while ( v3 ); + v10 += 2; + ++v0; + } + while ( v0 < 40 ); +} + +//----- (0040FE53) -------------------------------------------------------- +void __cdecl L2DirtFix() +{ + signed int v0; // ecx + char *v1; // eax + signed int v2; // edx + + v0 = 0; + do + { + v1 = (char *)dungeon + v0; + v2 = 40; + do + { + if ( *v1 == 13 && v1[40] != 11 ) + *v1 = -110; + if ( *v1 == 11 && v1[40] != 11 ) + *v1 = -112; + if ( *v1 == 15 && v1[40] != 11 ) + *v1 = -108; + if ( *v1 == 10 && v1[1] != 10 ) + *v1 = -113; + if ( *v1 == 13 && v1[1] != 10 ) + *v1 = -110; + if ( *v1 == 14 && v1[1] != 15 ) + *v1 = -109; + v1 += 40; + --v2; + } + while ( v2 ); + ++v0; + } + while ( v0 < 40 ); +} + +//----- (0040FEBF) -------------------------------------------------------- +void __cdecl DRLG_InitL2Vals() +{ + int v0; // edi + int (*v1)[112]; // ebx + char *v2; // ecx + int (*v3)[112]; // edx + signed int v4; // esi + int v5; // eax + int v6; // ecx + int (*v7)[112]; // esi + char *v8; // eax + int (*v9)[112]; // edx + signed int v10; // ebx + int v11; // edi + char v12; // [esp-4h] [ebp-14h] + + v0 = 0; + v1 = dPiece; + do + { + v2 = (char *)dArch + v0; + v3 = v1; + v4 = 112; + do + { + v5 = (*v3)[0]; + if ( (*v3)[0] != 541 && v5 != 178 && v5 != 551 ) + { + if ( v5 == 542 || v5 == 553 ) + goto LABEL_11; + if ( v5 != 13 ) + { + if ( v5 != 17 ) + goto LABEL_13; +LABEL_11: + v12 = 6; + goto LABEL_12; + } + } + v12 = 5; +LABEL_12: + *v2 = v12; +LABEL_13: + ++v3; + v2 += 112; + --v4; + } + while ( v4 ); + v1 = (int (*)[112])((char *)v1 + 4); + ++v0; + } + while ( (signed int)v1 < (signed int)dPiece[1] ); + v6 = 0; + v7 = dPiece; + do + { + v8 = &dArch[0][v6 + 2]; + v9 = v7; + v10 = 112; + do + { + v11 = (*v9)[0]; + if ( (*v9)[0] == 132 ) + { + *(v8 - 1) = 2; + *v8 = 1; + } + else if ( v11 == 135 || v11 == 139 ) + { + v8[110] = 3; + v8[222] = 4; + } + ++v9; + v8 += 112; + --v10; + } + while ( v10 ); + v7 = (int (*)[112])((char *)v7 + 4); + ++v6; + } + while ( (signed int)v7 < (signed int)dPiece[1] ); +} + +//----- (0040FF81) -------------------------------------------------------- +void __cdecl AddFenceDoors() +{ + signed int v0; // esi + char *v1; // eax + signed int v2; // ebx + unsigned char v3; // cl + char v4; // cl + char v5; // cl + + v0 = 0; + do + { + v1 = &dungeon[-1][v0 + 39]; + v2 = 40; + do + { + if ( v1[1] == 7 ) + { + v3 = *(v1 - 39); + if ( v3 > 0x98u + || v3 < 0x82u + || (v4 = v1[41], (unsigned char)v4 > 0x98u) + || (unsigned char)v4 < 0x82u ) + { + if ( (unsigned char)*v1 <= 0x98u && (unsigned char)*v1 >= 0x82u ) + { + v5 = v1[2]; + if ( (unsigned char)v5 <= 0x98u && (unsigned char)v5 >= 0x82u ) + v1[1] = -109; + } + } + else + { + v1[1] = -110; + } + } + v1 += 40; + --v2; + } + while ( v2 ); + ++v0; + } + while ( v0 < 40 ); +} + +//----- (0040FFEC) -------------------------------------------------------- +void __cdecl FenceDoorFix() +{ + signed int v0; // edi + char *v1; // eax + signed int v2; // esi + char v3; // bl + char v4; // cl + unsigned char v5; // cl + char v6; // dl + char v7; // cl + char v8; // cl + char v9; // dl + + v0 = 0; + do + { + v1 = &dungeon[-1][v0 + 39]; + v2 = 40; + do + { + v3 = v1[1]; + if ( v3 == -110 + && ((v4 = v1[41], (unsigned char)v4 > 0x98u) + || (unsigned char)v4 < 0x82u + || (v5 = *(v1 - 39), v5 > 0x98u) + || v5 < 0x82u + || (v6 = v1[41], v6 != -126) + && v5 != -126 + && v6 != -124 + && v5 != -124 + && v6 != -123 + && v5 != -123 + && v6 != -122 + && v5 != -122 + && v6 != -120 + && v5 != -120 + && v6 != -118 + && v5 != -118 + && v6 != -116 + && v5 != -116) + || v3 == -109 + && ((v7 = v1[2], (unsigned char)v7 > 0x98u) + || (unsigned char)v7 < 0x82u + || (v8 = *v1, (unsigned char)*v1 > 0x98u) + || (unsigned char)v8 < 0x82u + || (v9 = v1[2], v9 != -125) + && v8 != -125 + && v9 != -124 + && v8 != -124 + && v9 != -123 + && v8 != -123 + && v9 != -121 + && v8 != -121 + && v9 != -119 + && v8 != -119 + && v9 != -118 + && v8 != -118 + && v9 != -117 + && v8 != -117) ) + { + v1[1] = 7; + } + v1 += 40; + --v2; + } + while ( v2 ); + ++v0; + } + while ( v0 < 40 ); +} + +//----- (00410105) -------------------------------------------------------- +void __cdecl DRLG_L3Anvil() +{ + int v0; // esi + signed int v1; // edi + signed int v2; // ebx + signed int v3; // eax + int v4; // ecx + unsigned char v5; // dl + signed int v6; // ebx + int v7; // edi + int v8; // ecx + signed int v9; // eax + unsigned char v10; // dl + signed int v11; // [esp+Ch] [ebp-Ch] + signed int v12; // [esp+Ch] [ebp-Ch] + signed int v13; // [esp+10h] [ebp-8h] + int v14; // [esp+14h] [ebp-4h] + + v0 = random(0, 29); + v1 = 0; + v14 = random(0, 29); + v11 = 0; + while ( v11 < 200 ) + { + ++v11; + v13 = 1; + v2 = 2; + do + { + if ( v13 != 1 ) + break; + v3 = 0; + v4 = v14 + v1 + 40 * v0; + do + { + if ( v13 != 1 ) + break; + v5 = L3ANVIL[v2]; + if ( v5 && dungeon[0][v4] != v5 ) + v13 = 0; + if ( dflags[0][v4] ) + v13 = 0; + ++v2; + ++v3; + v4 += 40; + } + while ( v3 < 11 ); + ++v1; + } + while ( v1 < 11 ); + v1 = 0; + if ( v13 ) + { + if ( v11 < 200 ) + { + v12 = 11; + v6 = 123; + v7 = v14 + 40 * v0; + do + { + v8 = v7; + v9 = 11; + do + { + v10 = L3ANVIL[v6]; + if ( v10 ) + dungeon[0][v8] = v10; + dflags[0][v8] |= 0x80u; + ++v6; + v8 += 40; + --v9; + } + while ( v9 ); + ++v7; + --v12; + } + while ( v12 ); + setpc_y = v14; + setpc_w = 11; + setpc_h = 11; + setpc_x = v0; + } + return; + } + if ( ++v0 == 29 ) + { + v0 = 0; + if ( ++v14 == 29 ) + v14 = 0; + } + } +} +// 5CF330: using guessed type int setpc_h; +// 5CF334: using guessed type int setpc_w; + +//----- (00410215) -------------------------------------------------------- +void __cdecl FixL3Warp() +{ + int v0; // ecx + signed int v1; // esi + char *v2; // eax + char v3; // dl + signed int v4; // eax + + v0 = 0; + while ( 2 ) + { + v1 = 0; + v2 = &dungeon[1][v0 + 1]; + do + { + v3 = *(v2 - 41); + if ( v3 == 125 && *(v2 - 1) == 125 && *(v2 - 40) == 125 && *v2 == 125 ) + { + v4 = v1; + dungeon[v4][v0] = -100; + dungeon[v4 + 1][v0] = -101; + dungeon[v4][v0 + 1] = -103; + dungeon[v4 + 1][v0 + 1] = -102; + return; + } + if ( v3 == 5 && *v2 == 7 ) + *(v2 - 41) = 7; + ++v1; + v2 += 40; + } + while ( v1 < 40 ); + if ( ++v0 < 40 ) + continue; + break; + } +} + +//----- (0041027D) -------------------------------------------------------- +void __cdecl FixL3HallofHeroes() +{ + signed int v0; // ecx + char *v1; // eax + signed int v2; // edx + signed int v3; // ecx + char *v4; // eax + signed int v5; // edx + + v0 = 0; + do + { + v1 = (char *)dungeon + v0; + v2 = 40; + do + { + if ( *v1 == 5 && v1[41] == 7 ) + *v1 = 7; + v1 += 40; + --v2; + } + while ( v2 ); + ++v0; + } + while ( v0 < 40 ); + v3 = 0; + do + { + v4 = (char *)dungeon + v3; + v5 = 40; + do + { + if ( *v4 == 5 ) + { + if ( v4[41] == 12 && v4[40] == 7 ) + { + *v4 = 7; + v4[1] = 7; + v4[41] = 7; + } + if ( *v4 == 5 && v4[41] == 12 && v4[1] == 7 ) + { + *v4 = 7; + v4[40] = 7; + v4[41] = 7; + } + } + v4 += 40; + --v5; + } + while ( v5 ); + ++v3; + } + while ( v3 < 40 ); +} + +//----- (004102F1) -------------------------------------------------------- +void __fastcall DRLG_L3LockRec(int x, int y) +{ + int v2; // esi + int v3; // edi + char *v4; // eax + char *v5; // ebp + + v2 = x; + v3 = y; + v4 = &lockout[x][y]; + if ( *v4 ) + { + v5 = &lockout[x][y]; + do + { + *v4 = 0; + ++lockoutcnt; + DRLG_L3LockRec(v2, v3 - 1); + DRLG_L3LockRec(v2, v3 + 1); + DRLG_L3LockRec(v2 - 1, v3); + v5 += 40; + ++v2; + v4 = v5; + } + while ( *v5 ); + } +} +// 528380: using guessed type int lockoutcnt; + +//----- (00410344) -------------------------------------------------------- +void __cdecl DRLG_L3Lockout() +{ + int v0; // esi + signed int v1; // edx + signed int v2; // ecx + signed int v3; // eax + int x; // [esp+4h] [ebp-8h] + int y; // [esp+8h] [ebp-4h] + + v0 = 0; + v1 = 0; + do + { + v2 = 0; + v3 = v1; + do + { + if ( dungeon[0][v3] ) + { + lockout[0][v3] = 1; + x = v2; + y = v1; + ++v0; + } + else + { + lockout[0][v3] = 0; + } + ++v2; + v3 += 40; + } + while ( v2 < 40 ); + ++v1; + } + while ( v1 < 40 ); + lockoutcnt = 0; + DRLG_L3LockRec(x, y); +} +// 528380: using guessed type int lockoutcnt; + +//----- (004103A1) -------------------------------------------------------- +void __fastcall CreateL3Dungeon(int seed, int entry) +{ + int v2; // esi + int v3; // edi + int v4; // esi + signed int v5; // eax + signed int *v6; // [esp+8h] [ebp-8h] + int (*v7)[112]; // [esp+Ch] [ebp-4h] + + v2 = entry; + SetRndSeed(seed); + dminx = 16; + dminy = 16; + dmaxx = 96; + dmaxy = 96; + DRLG_InitTrans(); + DRLG_InitSetPC(); + DRLG_L3(v2); + DRLG_L3Pass3(); + v3 = 0; + v7 = dPiece; + do + { + v4 = 0; + v6 = (signed int *)v7; + do + { + v5 = *v6; + if ( *v6 >= 56 && v5 <= 147 || v5 >= 154 && v5 <= 161 || v5 == 150 || v5 == 152 ) + DoLighting(v4, v3, 7, -1); + v6 += 112; + ++v4; + } + while ( v4 < 112 ); + v7 = (int (*)[112])((char *)v7 + 4); + ++v3; + } + while ( (signed int)v7 < (signed int)dPiece[1] ); + DRLG_SetPC(); +} +// 5CF328: using guessed type int dmaxx; +// 5CF32C: using guessed type int dmaxy; +// 5D2458: using guessed type int dminx; +// 5D245C: using guessed type int dminy; + +//----- (0041044E) -------------------------------------------------------- +void __fastcall DRLG_L3(int entry) +{ + int v1; // ecx + int v2; // eax + int v3; // ecx + int v4; // esi + int v5; // eax + int v6; // edi + int y; // ST28_4 + int v8; // eax + int v9; // ecx + int v10; // eax + int v11; // ecx + int v12; // esi + int v13; // eax + signed int v14; // eax + int v15; // eax + int v16; // eax + int v17; // eax + int v18; // eax + int v19; // eax + char *v20; // eax + signed int v21; // ecx + signed int v22; // eax + signed int v23; // esi + bool v24; // [esp-8h] [ebp-20h] + int v25; // [esp+10h] [ebp-8h] + + lavapool = 0; + v25 = entry; + do + { + do + { + do + { + InitL3Dungeon(); + _LOBYTE(v1) = 0; + v2 = random(v1, 20); + _LOBYTE(v3) = 0; + v4 = v2 + 10; + v5 = random(v3, 20); + v6 = v5 + 10; + y = v5 + 12; + DRLG_L3FillRoom(v4, v5 + 10, v4 + 2, v5 + 12); + DRLG_L3CreateBlock(v4, v6, 2, 0); + DRLG_L3CreateBlock(v4 + 2, v6, 2, 1); + DRLG_L3CreateBlock(v4, y, 2, 2); + DRLG_L3CreateBlock(v4, v6, 2, 3); + _LOBYTE(v8) = QuestStatus(10); + if ( v8 ) + { + _LOBYTE(v9) = 0; + v10 = random(v9, 10); + _LOBYTE(v11) = 0; + v12 = v10 + 10; + v13 = random(v11, 10); + DRLG_L3FloorArea(v12, v13 + 10, v12 + 12, v13 + 22); + } + DRLG_L3FillDiags(); + DRLG_L3FillSingles(); + DRLG_L3FillStraights(); + DRLG_L3FillDiags(); + DRLG_L3Edges(); + DRLG_L3GetFloorArea(); + if ( v14 < 600 ) + v15 = 0; + else + DRLG_L3Lockout(); + } + while ( !v15 ); + DRLG_L3MakeMegas(); + if ( !v25 ) + { + _LOBYTE(v16) = DRLG_L3PlaceMiniSet((char *)L3UP, 1, 1, -1, -1, 1, 0); + if ( v16 ) + continue; + _LOBYTE(v16) = DRLG_L3PlaceMiniSet((char *)L3DOWN, 1, 1, -1, -1, 0, 1); + if ( v16 ) + continue; + if ( currlevel != 9 ) + goto LABEL_24; + _LOBYTE(v16) = DRLG_L3PlaceMiniSet((char *)L3HOLDWARP, 1, 1, -1, -1, 0, 6); + goto LABEL_23; + } + _LOBYTE(v16) = DRLG_L3PlaceMiniSet((char *)L3UP, 1, 1, -1, -1, 0, 0); + if ( v25 == 1 ) + { + if ( v16 ) + continue; + _LOBYTE(v16) = DRLG_L3PlaceMiniSet((char *)L3DOWN, 1, 1, -1, -1, 1, 1); + ViewX += 2; + ViewY -= 2; + if ( v16 ) + continue; + if ( currlevel != 9 ) + goto LABEL_24; + v24 = 0; +LABEL_22: + _LOBYTE(v16) = DRLG_L3PlaceMiniSet((char *)L3HOLDWARP, 1, 1, -1, -1, v24, 6); +LABEL_23: + if ( v16 ) + continue; + goto LABEL_24; + } + if ( v16 ) + continue; + _LOBYTE(v16) = DRLG_L3PlaceMiniSet((char *)L3DOWN, 1, 1, -1, -1, 0, 1); + if ( v16 ) + continue; + if ( currlevel == 9 ) + { + v24 = 1; + goto LABEL_22; + } +LABEL_24: + _LOBYTE(v17) = QuestStatus(10); + if ( !v17 ) + break; + DRLG_L3Anvil(); + } + while ( v16 == 1 ); + DRLG_L3Pool(); + } + while ( !lavapool ); + DRLG_L3PoolFix(); + FixL3Warp(); + DRLG_L3PlaceRndSet(L3ISLE1, 70); + DRLG_L3PlaceRndSet(L3ISLE2, 70); + DRLG_L3PlaceRndSet(L3ISLE3, 30); + DRLG_L3PlaceRndSet(L3ISLE4, 30); + DRLG_L3PlaceRndSet(L3ISLE1, 100); + DRLG_L3PlaceRndSet(L3ISLE2, 100); + DRLG_L3PlaceRndSet(L3ISLE5, 90); + FixL3HallofHeroes(); + DRLG_L3River(); + _LOBYTE(v18) = QuestStatus(10); + if ( v18 ) + { + v19 = setpc_y + 40 * setpc_x; + dungeon[7][v19 + 5] = 7; + dungeon[8][v19 + 5] = 7; + dungeon[9][v19 + 5] = 7; + v20 = &dungeon[10][v19 + 5]; + if ( *v20 == 17 || *v20 == 18 ) + *v20 = 45; + } + DRLG_PlaceThemeRooms(5, 10, 7, 0, 0); + DRLG_L3Wood(); + DRLG_L3PlaceRndSet(L3TITE1, 10); + DRLG_L3PlaceRndSet(L3TITE2, 10); + DRLG_L3PlaceRndSet(L3TITE3, 10); + DRLG_L3PlaceRndSet(L3TITE6, 20); + DRLG_L3PlaceRndSet(L3TITE7, 20); + DRLG_L3PlaceRndSet(L3TITE8, 20); + DRLG_L3PlaceRndSet(L3TITE9, 20); + DRLG_L3PlaceRndSet(L3TITE10, 20); + DRLG_L3PlaceRndSet(L3TITE11, 30); + DRLG_L3PlaceRndSet(L3TITE12, 20); + DRLG_L3PlaceRndSet(L3TITE13, 20); + DRLG_L3PlaceRndSet(L3CREV1, 30); + DRLG_L3PlaceRndSet(L3CREV2, 30); + DRLG_L3PlaceRndSet(L3CREV3, 30); + DRLG_L3PlaceRndSet(L3CREV4, 30); + DRLG_L3PlaceRndSet(L3CREV5, 30); + DRLG_L3PlaceRndSet(L3CREV6, 30); + DRLG_L3PlaceRndSet(L3CREV7, 30); + DRLG_L3PlaceRndSet(L3CREV8, 30); + DRLG_L3PlaceRndSet(L3CREV9, 30); + DRLG_L3PlaceRndSet(L3CREV10, 30); + DRLG_L3PlaceRndSet(L3CREV11, 30); + DRLG_L3PlaceRndSet(L3XTRA1, 25); + DRLG_L3PlaceRndSet(L3XTRA2, 25); + DRLG_L3PlaceRndSet(L3XTRA3, 25); + DRLG_L3PlaceRndSet(L3XTRA4, 25); + DRLG_L3PlaceRndSet(L3XTRA5, 25); + v21 = 0; + do + { + v22 = v21; + v23 = 40; + do + { + pdungeon[0][v22] = dungeon[0][v22]; + v22 += 40; + --v23; + } + while ( v23 ); + ++v21; + } + while ( v21 < 40 ); + DRLG_Init_Globals(); +} +// 528378: using guessed type char lavapool; + +//----- (0041087F) -------------------------------------------------------- +void __cdecl InitL3Dungeon() +{ + signed int v0; // edx + signed int v1; // eax + signed int v2; // ecx + + memset(dungeon, 0, 0x640u); + v0 = 0; + do + { + v1 = v0; + v2 = 40; + do + { + dungeon[0][v1] = 0; + dflags[0][v1] = 0; + v1 += 40; + --v2; + } + while ( v2 ); + ++v0; + } + while ( v0 < 40 ); +} + +//----- (004108B5) -------------------------------------------------------- +int __fastcall DRLG_L3FillRoom(int x1, int y1, int x2, int y2) +{ + int v4; // esi + int v5; // eax + int v6; // edi + int v7; // edx + int v8; // ecx + char *v9; // ecx + int v10; // eax + int v11; // ebx + char *v12; // edx + int v13; // eax + int i; // ebx + int v15; // ecx + int v16; // ecx + char *v17; // ebx + int v18; // edi + int v19; // ecx + int v21; // [esp+Ch] [ebp-4h] + int x2a; // [esp+18h] [ebp+8h] + int y2a; // [esp+1Ch] [ebp+Ch] + + v4 = x1; + v5 = y1; + v21 = y1; + if ( x1 <= 1 ) + return 0; + v6 = x2; + if ( x2 >= 34 || y1 <= 1 || y2 >= 38 ) + return 0; + v7 = 0; + v8 = v5; + x2a = v5; + if ( v5 <= y2 ) + { + do + { + if ( v4 <= v6 ) + { + v9 = &dungeon[v4][v8]; + v10 = v6 - v4 + 1; + do + { + v7 += (unsigned char)*v9; + v9 += 40; + --v10; + } + while ( v10 ); + } + v8 = x2a++ + 1; + } + while ( x2a <= y2 ); + if ( !v7 ) + { + v5 = v21; + goto LABEL_12; + } + return 0; + } +LABEL_12: + v11 = v5 + 1; + if ( v5 + 1 < y2 ) + { + v8 = v4 + 1; + do + { + if ( v8 < v6 ) + { + v12 = &dungeon[v8][v11]; + v13 = v6 - v8; + do + { + *v12 = 1; + v12 += 40; + --v13; + } + while ( v13 ); + } + ++v11; + } + while ( v11 < y2 ); + v5 = v21; + } + for ( i = v5; i <= y2; ++i ) + { + _LOBYTE(v8) = 0; + if ( random(v8, 2) ) + dungeon[v4][i] = 1; + _LOBYTE(v15) = 0; + if ( random(v15, 2) ) + dungeon[v6][i] = 1; + } + if ( v4 <= v6 ) + { + v16 = y2; + v17 = &dungeon[v4][y2]; + v18 = v6 - v4 + 1; + y2a = v21 - y2; + do + { + _LOBYTE(v16) = 0; + if ( random(v16, 2) ) + v17[y2a] = 1; + _LOBYTE(v19) = 0; + if ( random(v19, 2) ) + *v17 = 1; + v17 += 40; + --v18; + } + while ( v18 ); + } + return 1; +} + +//----- (004109F0) -------------------------------------------------------- +void __fastcall DRLG_L3CreateBlock(int x, int y, int obs, int dir) +{ + int v4; // esi + int v5; // edi + int v6; // eax + int v7; // ecx + int v8; // ecx + int v9; // ebx + bool v10; // zf + bool v11; // zf + int v12; // ecx + int y2; // [esp+Ch] [ebp-14h] + int x2; // [esp+10h] [ebp-10h] + int i; // [esp+14h] [ebp-Ch] + int v16; // [esp+18h] [ebp-8h] + int max; // [esp+1Ch] [ebp-4h] + + v4 = obs; + v5 = obs; + v16 = y; + for ( i = x; ; i = v4 ) + { + _LOBYTE(x) = 0; + v6 = random(x, 2); + _LOBYTE(v7) = 0; + max = v6 + 3; + v9 = random(v7, 2) + 3; + if ( !dir ) + { + y2 = v16 - 1; + v5 = v16 - 1 - v9; + if ( max < obs ) + { + _LOBYTE(v8) = 0; + v4 = i + random(v8, max); + } + if ( max == obs ) + v4 = i; + if ( max > obs ) + { + _LOBYTE(v8) = 0; + v4 = i - random(v8, max); + } + x2 = v4 + max; + } + if ( dir == 3 ) + { + x2 = i - 1; + v4 = i - 1 - max; + v10 = v9 == obs; + if ( v9 < obs ) + { + _LOBYTE(v8) = 0; + v5 = v16 + random(v8, v9); + v10 = v9 == obs; + } + if ( v10 ) + v5 = v16; + if ( v9 > obs ) + { + _LOBYTE(v8) = 0; + v5 = v16 - random(v8, v9); + } + y2 = v5 + v9; + } + if ( dir == 2 ) + { + v5 = v16 + 1; + y2 = v16 + 1 + v9; + if ( max < obs ) + { + _LOBYTE(v8) = 0; + v4 = i + random(v8, max); + } + if ( max == obs ) + v4 = i; + if ( max > obs ) + { + _LOBYTE(v8) = 0; + v4 = i - random(v8, max); + } + x2 = v4 + max; + } + if ( dir == 1 ) + { + v4 = i + 1; + v11 = v9 == obs; + x2 = i + 1 + max; + if ( v9 < obs ) + { + _LOBYTE(v8) = 0; + v5 = v16 + random(v8, v9); + v11 = v9 == obs; + } + if ( v11 ) + v5 = v16; + if ( v9 > obs ) + { + _LOBYTE(v8) = 0; + v5 = v16 - random(v8, v9); + } + y2 = v5 + v9; + } + if ( DRLG_L3FillRoom(v4, v5, x2, y2) != 1 ) + break; + _LOBYTE(v12) = 0; + if ( !random(v12, 4) ) + break; + if ( dir != 2 ) + DRLG_L3CreateBlock(v4, v5, v9, 0); + if ( dir != 3 ) + DRLG_L3CreateBlock(x2, v5, max, 1); + if ( dir ) + DRLG_L3CreateBlock(v4, y2, v9, 2); + if ( dir == 1 ) + break; + dir = 3; + obs = max; + v16 = v5; + } +} + +//----- (00410BC0) -------------------------------------------------------- +void __fastcall DRLG_L3FloorArea(int x1, int y1, int x2, int y2) +{ + int i; // esi + char *v5; // edx + int v6; // eax + + for ( i = y1; i <= y2; ++i ) + { + if ( x1 <= x2 ) + { + v5 = &dungeon[x1][i]; + v6 = x2 - x1 + 1; + do + { + *v5 = 1; + v5 += 40; + --v6; + } + while ( v6 ); + } + } +} + +//----- (00410BF4) -------------------------------------------------------- +void __cdecl DRLG_L3FillDiags() +{ + signed int v0; // ebx + char *v1; // esi + signed int v2; // ebp + int v3; // ecx + int v4; // edi + + v0 = 0; + do + { + v1 = &dungeon[1][v0 + 1]; + v2 = 39; + do + { + v3 = (unsigned char)*v1; + v4 = v3 + + 2 * ((unsigned char)*(v1 - 40) + 2 * ((unsigned char)*(v1 - 1) + 2 * (unsigned char)*(v1 - 41))); + if ( v4 == 6 ) + { + _LOBYTE(v3) = 0; + if ( !random(v3, 2) ) + { + *(v1 - 41) = 1; + goto LABEL_11; + } + *v1 = 1; + } + if ( v4 == 9 ) + { + _LOBYTE(v3) = 0; + if ( random(v3, 2) ) + *(v1 - 40) = 1; + else + *(v1 - 1) = 1; + } +LABEL_11: + v1 += 40; + --v2; + } + while ( v2 ); + ++v0; + } + while ( v0 < 39 ); +} + +//----- (00410C65) -------------------------------------------------------- +void __cdecl DRLG_L3FillSingles() +{ + signed int v0; // ecx + char *v1; // eax + signed int v2; // edx + + v0 = 1; + do + { + v1 = &dungeon[0][v0 + 39]; + v2 = 38; + do + { + if ( !v1[1] + && (unsigned char)*v1 + (unsigned char)v1[40] + (unsigned char)*(v1 - 40) == 3 + && (unsigned char)*(v1 - 39) + (unsigned char)v1[41] == 2 + && (unsigned char)v1[2] + (unsigned char)*(v1 - 38) + (unsigned char)v1[42] == 3 ) + { + v1[1] = 1; + } + v1 += 40; + --v2; + } + while ( v2 ); + ++v0; + } + while ( v0 < 39 ); +} + +//----- (00410CC4) -------------------------------------------------------- +void __cdecl DRLG_L3FillStraights() +{ + int v0; // esi + char *v1; // ecx + signed int v2; // eax + char *v3; // ebx + int v4; // edi + int v5; // ebx + char v6; // al + char *v7; // ecx + signed int v8; // eax + char *v9; // ebx + int v10; // edi + int v11; // ebx + char v12; // al + signed int v13; // ebx + signed int v14; // eax + signed int v15; // esi + signed int i; // edi + signed int v17; // ebx + signed int v18; // eax + signed int v19; // esi + signed int j; // edi + int v21; // [esp+Ch] [ebp-14h] + char *v22; // [esp+Ch] [ebp-14h] + char *v23; // [esp+Ch] [ebp-14h] + char *v24; // [esp+10h] [ebp-10h] + signed int v25; // [esp+14h] [ebp-Ch] + signed int v26; // [esp+14h] [ebp-Ch] + signed int v27; // [esp+18h] [ebp-8h] + signed int v28; // [esp+18h] [ebp-8h] + int v29; // [esp+1Ch] [ebp-4h] + int v30; // [esp+1Ch] [ebp-4h] + + v27 = 0; + v0 = v21; + do + { + v1 = (char *)v27; + v2 = 0; + v29 = 0; + v3 = &dungeon[0][v27 + 1]; + v4 = 40 * v0; + v25 = 0; + v22 = &dungeon[0][v27 + 1]; + do + { + if ( *(v3 - 1) || *v3 != 1 ) + { + if ( v2 > 3 ) + { + _LOBYTE(v1) = 0; + if ( random((int)v1, 2) ) + { + if ( v0 < v29 ) + { + v5 = v29 - v0; + v24 = (char *)dungeon + v4 + v27; + do + { + _LOBYTE(v1) = 0; + v6 = random((int)v1, 2); + v1 = v24; + v24 += 40; + --v5; + *v1 = v6; + } + while ( v5 ); + v3 = v22; + } + } + } + v2 = 0; + } + else + { + if ( !v2 ) + { + v0 = v29; + v4 = v25; + } + ++v2; + } + v25 += 40; + ++v29; + v3 += 40; + v22 = v3; + } + while ( v25 < 1480 ); + ++v27; + } + while ( v27 < 39 ); + v28 = 0; + do + { + v7 = (char *)v28; + v8 = 0; + v30 = 0; + v9 = &dungeon[0][v28 + 1]; + v26 = 0; + v10 = 40 * v0; + v23 = &dungeon[0][v28 + 1]; + do + { + if ( *(v9 - 1) != 1 || *v9 ) + { + if ( v8 > 3 ) + { + _LOBYTE(v7) = 0; + if ( random((int)v7, 2) ) + { + if ( v0 < v30 ) + { + v11 = v30 - v0; + v24 = &dungeon[0][v10 + 1 + v28]; + do + { + _LOBYTE(v7) = 0; + v12 = random((int)v7, 2); + v7 = v24; + v24 += 40; + --v11; + *v7 = v12; + } + while ( v11 ); + v9 = v23; + } + } + } + v8 = 0; + } + else + { + if ( !v8 ) + { + v0 = v30; + v10 = v26; + } + ++v8; + } + v26 += 40; + ++v30; + v9 += 40; + v23 = v9; + } + while ( v26 < 1480 ); + ++v28; + } + while ( v28 < 39 ); + v13 = 0; + do + { + v14 = 0; + v15 = 0; + do + { + if ( dungeon[v13][v15] || dungeon[v13 + 1][v15] != 1 ) + { + if ( v14 > 3 ) + { + _LOBYTE(v7) = 0; + if ( random((int)v7, 2) ) + { + for ( i = (signed int)v24; i < v15; ++i ) + { + _LOBYTE(v7) = 0; + dungeon[v13][i] = random((int)v7, 2); + } + } + } + v14 = 0; + } + else + { + if ( !v14 ) + v24 = (char *)v15; + ++v14; + } + ++v15; + } + while ( v15 < 37 ); + ++v13; + } + while ( v13 < 39 ); + v17 = 0; + do + { + v18 = 0; + v19 = 0; + do + { + if ( dungeon[v17][v19] != 1 || dungeon[v17 + 1][v19] ) + { + if ( v18 > 3 ) + { + _LOBYTE(v7) = 0; + if ( random((int)v7, 2) ) + { + for ( j = (signed int)v24; j < v19; ++j ) + { + _LOBYTE(v7) = 0; + dungeon[v17 + 1][j] = random((int)v7, 2); + } + } + } + v18 = 0; + } + else + { + if ( !v18 ) + v24 = (char *)v19; + ++v18; + } + ++v19; + } + while ( v19 < 37 ); + ++v17; + } + while ( v17 < 39 ); +} + +//----- (00410EDB) -------------------------------------------------------- +void __cdecl DRLG_L3Edges() +{ + char *v0; // eax + + memset(dungeon[39], 0, sizeof(char[40])); + v0 = &dungeon[0][39]; + do + { + *v0 = 0; + v0 += 40; + } + while ( (signed int)v0 < (signed int)&dObject[0][39] ); +} + +//----- (00410EFC) -------------------------------------------------------- +void __cdecl DRLG_L3GetFloorArea() +{ + int v0; // eax + signed int v1; // edx + unsigned char *v2; // ecx + signed int v3; // esi + + v0 = 0; + v1 = 0; + do + { + v2 = (unsigned char *)dungeon + v1; + v3 = 40; + do + { + v0 += *v2; + v2 += 40; + --v3; + } + while ( v3 ); + ++v1; + } + while ( v1 < 40 ); +} + +//----- (00410F1F) -------------------------------------------------------- +void __cdecl DRLG_L3MakeMegas() +{ + signed int v0; // edi + char *v1; // esi + signed int v2; // ebp + int v3; // ecx + int v4; // eax + char *v5; // eax + + v0 = 0; + do + { + v1 = &dungeon[0][v0 + 1]; + v2 = 39; + do + { + v3 = (unsigned char)v1[40]; + v4 = v3 + 2 * ((unsigned char)*v1 + 2 * ((unsigned char)v1[39] + 2 * (unsigned char)*(v1 - 1))); + if ( v4 == 6 ) + { + _LOBYTE(v3) = 0; + if ( !random(v3, 2) ) + { + v4 = 12; + goto LABEL_9; + } + v4 = 5; + } + if ( v4 == 9 ) + { + _LOBYTE(v3) = 0; + v4 = (random(v3, 2) != 0) + 13; + } +LABEL_9: + --v2; + *(v1 - 1) = L3ConvTbl[v4]; + v1 += 40; + } + while ( v2 ); + dungeon[39][v0++] = 8; + } + while ( v0 < 39 ); + v5 = &dungeon[0][39]; + do + { + *v5 = 8; + v5 += 40; + } + while ( (signed int)v5 < (signed int)&dObject[0][39] ); +} + +//----- (00410FAD) -------------------------------------------------------- +void __cdecl DRLG_L3River() +{ + signed int v0; // ebx + int v1; // esi + int v2; // edi + char v3; // al + char v4; // al + signed int v5; // edx + int v6; // eax + int v7; // ebx + unsigned char v8; // al + unsigned char v9; // al + int v10; // eax + char *v11; // eax + signed int v12; // eax + int v13; // ecx + bool v14; // zf + int v15; // eax + signed int v16; // eax + int v17; // eax + signed int v18; // eax + signed int v19; // eax + signed int v20; // edi + int v21; // eax + int v22; // eax + int v23; // edx + int v24; // ecx + int v25; // ecx + int v26; // esi + int v27; // ecx + int v28; // edx + int v29; // ecx + int v30; // edx + int v31; // ecx + int v32; // edx + bool v33; // sf + unsigned char v34; // of + int v35[100]; // [esp+Ch] [ebp-4E8h] + int v36[98]; // [esp+19Ch] [ebp-358h] + int v37; // [esp+324h] [ebp-1D0h] + int v38; // [esp+328h] [ebp-1CCh] + int v39[100]; // [esp+32Ch] [ebp-1C8h] + int v40; // [esp+4BCh] [ebp-38h] + int v41; // [esp+4C0h] [ebp-34h] + int v42; // [esp+4C4h] [ebp-30h] + int v43; // [esp+4C8h] [ebp-2Ch] + int v44; // [esp+4CCh] [ebp-28h] + int v45; // [esp+4D0h] [ebp-24h] + int v46; // [esp+4D4h] [ebp-20h] + int v47; // [esp+4D8h] [ebp-1Ch] + int v48; // [esp+4DCh] [ebp-18h] + int v49; // [esp+4E0h] [ebp-14h] + int v50; // [esp+4E4h] [ebp-10h] + int v51; // [esp+4E8h] [ebp-Ch] + int v52; // [esp+4ECh] [ebp-8h] + int max; // [esp+4F0h] [ebp-4h] + + v0 = 0; + v43 = 0; + v45 = 0; + while ( v43 < 4 ) + { + v51 = 0; + do + { + if ( v45 >= 200 ) + { + v5 = max; + break; + } + ++v45; + v1 = 0; + v2 = 0; + while ( 1 ) + { + v3 = dungeon[v1][v2]; + if ( (unsigned char)v3 >= 0x19u && (unsigned char)v3 <= 0x1Cu ) + break; + if ( v0 >= 100 ) + return; + v1 = random(0, 40); + v2 = random(0, 40); + ++v0; + while ( 1 ) + { + v4 = dungeon[v1][v2]; + if ( (unsigned char)v4 >= 0x19u && (unsigned char)v4 <= 0x1Cu ) + break; + if ( v2 >= 40 ) + break; + if ( ++v1 >= 40 ) + { + v1 = 0; + ++v2; + } + } + } + if ( v0 >= 100 ) + return; + switch ( dungeon[v1][v2] ) + { + case 0x19: + v52 = 3; + v46 = 2; + v39[0] = 40; + break; + case 0x1A: + v52 = 0; + v46 = 1; + v39[0] = 38; + break; + case 0x1B: + v46 = 0; + v52 = 1; + v39[0] = 41; + break; + case 0x1C: + v52 = 2; + v46 = 3; + v39[0] = 39; + break; + } + v47 = 0; + max = 1; + v5 = 1; + v35[0] = v1; + v36[0] = v2; + v50 = 4; + v49 = 40 * v1; + while ( v5 < 100 ) + { + v42 = v1; + v40 = v49; + v41 = v2; + if ( v47 ) + { + v52 = ((_BYTE)v52 + 1) & 3; + v7 = v52; + } + else + { + v6 = random(0, 4); + v5 = max; + v7 = v6; + v52 = v6; + } + while ( 1 ) + { + ++v47; + if ( v7 != v46 && v7 != v50 ) + break; + v7 = ((_BYTE)v7 + 1) & 3; + } + v52 = v7; + if ( !v7 ) + { + if ( v2 <= 0 ) + goto LABEL_44; + --v2; + } + if ( v7 == 1 ) + { + if ( v2 >= 40 ) + goto LABEL_44; + ++v2; + } + if ( v7 != 2 ) + goto LABEL_41; + if ( v1 < 40 ) + { + ++v1; + v49 += 40; +LABEL_41: + if ( v7 == 3 && v1 > 0 ) + { + --v1; + v49 -= 40; + } + } +LABEL_44: + if ( dungeon[0][v49 + v2] == 7 ) + { + v47 = 0; + if ( v7 < 2 ) + { + v8 = random(0, 2); + v5 = max; + v39[max] = v8 + 17; + } + if ( v7 > 1 ) + { + v9 = random(0, 2); + v5 = max; + v39[max] = v9 + 15; + } + v10 = v44; + v35[v5] = v1; + v36[v5++] = v2; + max = v5; + if ( v7 || v10 != 2 ) + { + if ( v7 != 3 ) + goto LABEL_58; + if ( v10 != 1 ) + goto LABEL_70; + } + if ( v5 > 2 ) + *(&v37 + v5) = 22; + if ( !v7 ) + { + v50 = 1; +LABEL_59: + if ( v10 == 3 ) + goto LABEL_62; + goto LABEL_60; + } + v50 = 2; +LABEL_58: + if ( !v7 ) + goto LABEL_59; +LABEL_60: + if ( v7 != 2 ) + goto LABEL_67; + if ( v10 != 1 ) + goto LABEL_79; +LABEL_62: + if ( v5 > 2 ) + *(&v37 + v5) = 21; + if ( !v7 ) + { + v50 = 1; + goto LABEL_83; + } + v50 = 3; +LABEL_67: + if ( v7 != 1 || v10 != 2 ) + { + if ( v7 != 3 ) + goto LABEL_76; +LABEL_70: + if ( v10 ) + goto LABEL_83; + } + if ( v5 > 2 ) + *(&v37 + v5) = 20; + if ( v7 == 1 ) + { + v50 = 0; + goto LABEL_77; + } + v50 = 2; +LABEL_76: + if ( v7 != 1 ) + goto LABEL_78; +LABEL_77: + if ( v10 != 3 ) + { +LABEL_78: + if ( v7 != 2 ) + goto LABEL_83; +LABEL_79: + if ( v10 ) + goto LABEL_83; + } + if ( v5 > 2 ) + *(&v37 + v5) = 19; + v50 = v7 != 1 ? 3 : 0; +LABEL_83: + v44 = v7; + } + else + { + v1 = v42; + v2 = v41; + v49 = v40; + if ( v47 >= 4 ) + break; + } + } + if ( v52 ) + { + v13 = v44; + goto LABEL_94; + } + v11 = &dungeon[v1][v2]; + if ( *(v11 - 1) == 10 && *(v11 - 2) == 8 ) + { + v12 = v5; + v36[v12] = v2 - 1; + v13 = v44; + v14 = v44 == 2; + v35[v12] = v1; + v39[v12] = 24; + if ( v14 ) + *(int *)((char *)&v38 + v12 * 4) = 22; + if ( v13 == 3 ) + *(int *)((char *)&v38 + v12 * 4) = 21; + v51 = 1; +LABEL_94: + if ( v52 == 1 ) + { + v15 = v2 + 40 * v1; + if ( dungeon[0][v15 + 1] == 2 && dungeon[0][v15 + 2] == 8 ) + { + v16 = v5; + v35[v16] = v1; + v36[v16] = v2 + 1; + v39[v16] = 42; + if ( v13 == 2 ) + *(int *)((char *)&v38 + v16 * 4) = 20; + if ( v13 == 3 ) + *(int *)((char *)&v38 + v16 * 4) = 19; + v51 = 1; + goto LABEL_102; + } + } + else + { +LABEL_102: + if ( v52 == 2 ) + { + v17 = v2 + 40 * v1; + if ( dungeon[1][v17] != 4 || dungeon[2][v17] != 8 ) + goto LABEL_118; + v18 = v5; + v35[v18] = v1 + 1; + v36[v18] = v2; + v39[v18] = 43; + if ( !v13 ) + *(int *)((char *)&v38 + v18 * 4) = 19; + if ( v13 == 1 ) + *(int *)((char *)&v38 + v18 * 4) = 21; + v51 = 1; + } + if ( v52 == 3 + && *((_BYTE *)&dMonster[111][10 * v1 + 102] + v2) == 9 + && dungeon[0][8 * (5 * v1 - 10) + v2] == 8 ) + { + v19 = v5; + v35[v19] = v1 - 1; + v36[v19] = v2; + v39[v19] = 23; + if ( !v13 ) + *(int *)((char *)&v38 + v19 * 4) = 20; + if ( v13 == 1 ) + *(int *)((char *)&v38 + v19 * 4) = 22; + v51 = 1; + } + } + } +LABEL_118: + v0 = 0; + } + while ( !v51 ); + if ( v51 == 1 && v5 >= 7 ) + { + v20 = 0; + v51 = 0; +LABEL_124: + while ( v51 < 30 ) + { + ++v51; + v21 = random(0, max); + v48 = v21; + v22 = v21; + v23 = v39[v22]; + if ( v23 == 15 || v23 == 16 ) + { + v24 = v36[v22] + 40 * v35[v22]; + if ( *((_BYTE *)&dMonster[111][111] + v24 + 3) == 7 && dungeon[0][v24 + 1] == 7 ) + v20 = 1; + } + if ( v23 == 17 || v23 == 18 ) + { + v25 = v36[v22] + 40 * v35[v22]; + if ( *((_BYTE *)&dMonster[111][102] + v25) == 7 && dungeon[1][v25] == 7 ) + v20 = 2; + } + v26 = 0; + if ( max > 0 ) + { + while ( 1 ) + { + if ( !v20 ) + goto LABEL_124; + if ( v20 != 1 ) + goto LABEL_142; + v27 = v36[v22]; + v28 = v36[v26]; + if ( (v27 - 1 == v28 || v27 + 1 == v28) && v35[v22] == v35[v26] ) + break; +LABEL_147: + if ( ++v26 >= max ) + goto LABEL_148; + } + v20 = 0; +LABEL_142: + if ( v20 == 2 ) + { + v29 = v35[v22]; + v30 = v35[v26]; + if ( (v29 - 1 == v30 || v29 + 1 == v30) && v36[v22] == v36[v26] ) + v20 = 0; + } + goto LABEL_147; + } +LABEL_148: + if ( v20 ) + break; + } + v0 = 0; + if ( v20 ) + { + v39[v48] = v20 == 1 ? 44 : 45; + v31 = max; + ++v43; + v48 = 0; + if ( max >= 0 ) + { + do + { + v32 = v48++; + v34 = __OFSUB__(v48, v31); + v14 = v48 == v31; + v33 = v48 - v31 < 0; + dungeon[v35[v32]][v36[v32]] = v39[v32]; + } + while ( (unsigned char)(v33 ^ v34) | v14 ); + } + } + } + if ( v45 >= 200 ) + return; + } +} +// 410FAD: using guessed type int var_1C8[100]; +// 410FAD: using guessed type int var_4E8[100]; +// 410FAD: using guessed type int var_358[98]; + +//----- (00411614) -------------------------------------------------------- +void __cdecl DRLG_L3Pool() +{ + int v0; // ebx + _BYTE *v1; // ecx + int v2; // esi + int v3; // ecx + signed int v4; // eax + signed int v5; // eax + signed int v6; // eax + int v7; // eax + int v8; // edi + int v9; // ecx + int v10; // eax + int v11; // esi + char *v12; // edx + unsigned char v13; // al + unsigned char v14; // al + signed int v15; // [esp+Ch] [ebp-18h] + char *v16; // [esp+10h] [ebp-14h] + signed int v17; // [esp+14h] [ebp-10h] + int v18; // [esp+18h] [ebp-Ch] + int totarea; // [esp+1Ch] [ebp-8h] + int x; // [esp+20h] [ebp-4h] + + v0 = 0; + v18 = 0; + do + { + x = 0; + v1 = (unsigned char *)dungeon + v0; + v16 = (char *)dungeon + v0; + do + { + if ( *v1 == 8 ) + { + *v1 = -120; + v2 = x - 1; + totarea = 1; + v3 = x - 1 + 2; + v4 = v3 >= 40 ? 1 : DRLG_L3SpawnEdge(v3, v0, &totarea); + v5 = v2 <= 0 || v4 ? 1 : DRLG_L3SpawnEdge(v2, v0, &totarea); + v6 = v0 + 1 >= 40 || v5 ? 1 : DRLG_L3SpawnEdge(x, v0 + 1, &totarea); + v17 = v0 - 1 <= 0 || v6 ? 1 : DRLG_L3SpawnEdge(x, v0 - 1, &totarea); + _LOBYTE(v3) = 0; + v7 = random(v3, 100); + v8 = totarea; + v15 = v7; + v9 = v0 - totarea; + if ( v0 - totarea < totarea + v0 ) + { + totarea = x - totarea; + v10 = v8 + x; + do + { + v11 = totarea; + if ( totarea < v10 ) + { + v12 = &dungeon[totarea][v9]; + do + { + if ( *v12 < 0 && v9 >= 0 && v9 < 40 && v11 >= 0 && v11 < 40 ) + { + v13 = *v12 & 0x7F; + *v12 = v13; + if ( v8 > 4 ) + { + if ( v15 < 25 && !v17 ) + { + v14 = L3PoolSub[v13]; + if ( v14 ) + { + if ( v14 <= 0x25u ) + *v12 = v14; + } + lavapool = 1; + } + v0 = v18; + } + } + ++v11; + v10 = v8 + x; + v12 += 40; + } + while ( v11 < v8 + x ); + } + ++v9; + } + while ( v9 < v8 + v0 ); + } + } + ++x; + v1 = (unsigned char *)v16 + 40; + v16 += 40; + } + while ( x < 40 ); + v18 = ++v0; + } + while ( v0 < 40 ); +} +// 528378: using guessed type char lavapool; + +//----- (00411772) -------------------------------------------------------- +int __fastcall DRLG_L3SpawnEdge(int x, int y, int *totarea) +{ + int *v3; // ebp + int v4; // edi + int v5; // esi + char *v6; // ecx + int *v7; // eax + int v8; // eax + int *totareaa; // [esp+14h] [ebp+4h] + + v3 = totarea; + v4 = y; + v5 = x; + if ( *totarea <= 40 && x >= 0 && y >= 0 && x < 40 && y < 40 ) + { + v6 = &dungeon[x][y]; + _LOBYTE(v7) = *v6; + if ( *v6 < 0 ) + return 0; + if ( (unsigned char)v7 <= 0xFu ) + { + *v6 = (unsigned char)v7 | 0x80; + ++*totarea; + if ( (_BYTE)v7 == 8 ) + { + if ( DRLG_L3SpawnEdge(v5 + 1, y, totarea) == 1 + || DRLG_L3SpawnEdge(v5 - 1, v4, totarea) == 1 + || DRLG_L3SpawnEdge(v5, v4 + 1, totarea) == 1 ) + { + return 1; + } + v8 = DRLG_L3SpawnEdge(v5, v4 - 1, totarea); +LABEL_24: + if ( v8 == 1 ) + return 1; + return 0; + } + v7 = (int *)(unsigned char)v7; + totareaa = v7; + if ( L3SpawnTbl2[(unsigned char)v7] & 8 ) + { + if ( DRLG_L3Spawn(v5, y - 1, v3) == 1 ) + return 1; + v7 = totareaa; + } + if ( L3SpawnTbl2[(_DWORD)v7] & 4 ) + { + if ( DRLG_L3Spawn(v5, v4 + 1, v3) == 1 ) + return 1; + v7 = totareaa; + } + if ( !(L3SpawnTbl2[(_DWORD)v7] & 2) ) + goto LABEL_18; + if ( DRLG_L3Spawn(v5 + 1, v4, v3) != 1 ) + { + v7 = totareaa; +LABEL_18: + if ( L3SpawnTbl2[(_DWORD)v7] & 1 ) + { + v8 = DRLG_L3Spawn(v5 - 1, v4, v3); + goto LABEL_24; + } + return 0; + } + return 1; + } + } + return 1; +} + +//----- (0041189C) -------------------------------------------------------- +int __fastcall DRLG_L3Spawn(int x, int y, int *totarea) +{ + int v3; // edi + int v4; // esi + char *v5; // eax + unsigned char v6; // cl + int v7; // ebx + int result; // eax + + v3 = y; + v4 = x; + result = 1; + if ( *totarea <= 40 && x >= 0 && y >= 0 && x < 40 && y < 40 ) + { + v5 = &dungeon[x][y]; + v6 = *v5; + if ( *v5 < 0 + || v6 <= 0xFu + && ((v7 = v6, *v5 = v6 | 0x80, ++*totarea, !(L3SpawnTbl1[v6] & 8)) || DRLG_L3Spawn(v4, y - 1, totarea) != 1) + && (!(L3SpawnTbl1[v7] & 4) || DRLG_L3Spawn(v4, v3 + 1, totarea) != 1) + && (!(L3SpawnTbl1[v7] & 2) || DRLG_L3Spawn(v4 + 1, v3, totarea) != 1) + && (!(L3SpawnTbl1[v7] & 1) || DRLG_L3Spawn(v4 - 1, v3, totarea) != 1) + && ((L3SpawnTbl1[v7] & 0x80u) == 0 || DRLG_L3SpawnEdge(v4, v3 - 1, totarea) != 1) + && (!(L3SpawnTbl1[v7] & 0x40) || DRLG_L3SpawnEdge(v4, v3 + 1, totarea) != 1) + && (!(L3SpawnTbl1[v7] & 0x20) || DRLG_L3SpawnEdge(v4 + 1, v3, totarea) != 1) + && (!(L3SpawnTbl1[v7] & 0x10) || DRLG_L3SpawnEdge(v4 - 1, v3, totarea) != 1) ) + { + result = 0; + } + } + return result; +} + +//----- (004119E0) -------------------------------------------------------- +void __cdecl DRLG_L3PoolFix() +{ + signed int v0; // esi + char *v1; // eax + char *v2; // edi + unsigned char v3; // cl + char v4; // cl + char v5; // cl + char v6; // cl + char v7; // cl + char v8; // cl + char v9; // al + bool v10; // zf + signed int v11; // [esp+10h] [ebp-4h] + + v0 = 0; + do + { + v1 = &dungeon[-1][v0]; + v11 = 40; + do + { + v2 = v1 + 40; + if ( v1[40] == 8 ) + { + v3 = *(v1 - 1); + if ( v3 >= 0x19u && v3 <= 0x29u && (unsigned char)*v1 >= 0x19u && (unsigned char)*v1 <= 0x29u ) + { + v4 = v1[1]; + if ( (unsigned char)v4 >= 0x19u && (unsigned char)v4 <= 0x29u ) + { + v5 = v1[39]; + if ( (unsigned char)v5 >= 0x19u && (unsigned char)v5 <= 0x29u ) + { + v6 = v1[41]; + if ( (unsigned char)v6 >= 0x19u && (unsigned char)v6 <= 0x29u ) + { + v7 = v1[79]; + if ( (unsigned char)v7 >= 0x19u && (unsigned char)v7 <= 0x29u ) + { + v8 = v1[80]; + if ( (unsigned char)v8 >= 0x19u && (unsigned char)v8 <= 0x29u ) + { + v9 = v1[81]; + if ( (unsigned char)v9 >= 0x19u && (unsigned char)v9 <= 0x29u ) + *v2 = 33; + } + } + } + } + } + } + } + v10 = v11-- == 1; + v1 = v2; + } + while ( !v10 ); + ++v0; + } + while ( v0 < 40 ); +} + +//----- (00411A74) -------------------------------------------------------- +bool __fastcall DRLG_L3PlaceMiniSet(char *miniset, int tmin, int tmax, int cx, int cy, bool set_view, int ldir) +{ + int v7; // ebx + int v8; // esi + int v9; // edi + int v10; // edx + int v11; // eax + int v12; // ecx + int v13; // esi + signed int v14; // ebx + int v15; // ecx + int v16; // eax + int v17; // ecx + int v18; // eax + int v19; // ecx + int v20; // edi + signed int i; // eax + int v22; // ecx + char v23; // dl + int v24; // eax + int v25; // edi + char *v26; // edx + char v27; // bl + char *v29; // [esp+Ch] [ebp-24h] + int v30; // [esp+10h] [ebp-20h] + int v31; // [esp+14h] [ebp-1Ch] + int v32; // [esp+18h] [ebp-18h] + signed int v33; // [esp+1Ch] [ebp-14h] + int v34; // [esp+20h] [ebp-10h] + int v35; // [esp+24h] [ebp-Ch] + int v36; // [esp+28h] [ebp-8h] + int max; // [esp+2Ch] [ebp-4h] + + v7 = (unsigned char)miniset[1]; + v8 = tmin; + v9 = (unsigned char)*miniset; + v29 = miniset; + v10 = tmax - tmin; + v34 = (unsigned char)*miniset; + v35 = (unsigned char)miniset[1]; + if ( v10 ) + { + _LOBYTE(miniset) = 0; + v30 = v8 + random((int)miniset, v10); + } + else + { + v30 = 1; + } + v31 = 0; + if ( v30 <= 0 ) + { + v13 = tmax; + } + else + { + max = 40 - v9; + v36 = 40 - v7; + do + { + _LOBYTE(miniset) = 0; + v11 = random((int)miniset, max); + _LOBYTE(v12) = 0; + v13 = v11; + v33 = 0; + tmax = random(v12, v36); + while ( 1 ) + { + if ( v33 >= 200 ) + return 1; + ++v33; + v14 = 1; + if ( cx != -1 ) + { + v15 = cx - v34; + if ( v13 >= cx - v34 && v13 <= cx + 12 ) + { + _LOBYTE(v15) = 0; + v16 = random(v15, max); + _LOBYTE(v17) = 0; + v13 = v16; + tmax = random(v17, v36); + v14 = 0; + } + } + if ( cy != -1 && tmax >= cy - v35 && tmax <= cy + 12 ) + { + v18 = random(cy - v35, max); + _LOBYTE(v19) = 0; + v13 = v18; + tmax = random(v19, v36); + v14 = 0; + } + v20 = 0; + for ( i = 2; v20 < v35; ++v20 ) + { + if ( v14 != 1 ) + break; + v32 = 0; + if ( v34 > 0 ) + { + v22 = tmax + v20 + 40 * v13; + do + { + if ( v14 != 1 ) + break; + v23 = v29[i]; + if ( v23 && dungeon[0][v22] != v23 ) + v14 = 0; + if ( dflags[0][v22] ) + v14 = 0; + ++i; + ++v32; + v22 += 40; + } + while ( v32 < v34 ); + } + } + v24 = 0; + if ( v14 ) + break; + if ( ++v13 == max ) + { + v13 = 0; + if ( ++tmax == v36 ) + tmax = 0; + } + } + if ( v33 >= 200 ) + return 1; + miniset = (char *)(v34 * v35 + 2); + if ( v35 > 0 ) + { + do + { + v25 = v34; + if ( v34 > 0 ) + { + v26 = &dungeon[v13][v24 + tmax]; + do + { + v27 = v29[(_DWORD)miniset]; + if ( v27 ) + *v26 = v27; + ++miniset; + v26 += 40; + --v25; + } + while ( v25 ); + } + ++v24; + } + while ( v24 < v35 ); + } + ++v31; + } + while ( v31 < v30 ); + } + if ( set_view == 1 ) + { + ViewX = 2 * v13 + 17; + ViewY = 2 * tmax + 19; + } + if ( !ldir ) + { + LvlViewX = 2 * v13 + 17; + LvlViewY = 2 * tmax + 19; + } + return 0; +} +// 5CF320: using guessed type int LvlViewY; +// 5CF324: using guessed type int LvlViewX; + +//----- (00411C83) -------------------------------------------------------- +void __fastcall DRLG_L3PlaceRndSet(unsigned char *miniset, int rndper) +{ + unsigned char *v2; // ebx + int v3; // ecx + int v4; // eax + char *v5; // ecx + int v6; // esi + signed int i; // edx + int v8; // edi + int v9; // eax + unsigned char v10; // cl + int v11; // edi + unsigned char v12; // al + char v13; // al + int j; // edx + int v15; // esi + unsigned char *v16; // eax + unsigned char v17; // cl + bool v18; // zf + int v19; // [esp+8h] [ebp-30h] + int v20; // [esp+10h] [ebp-28h] + char *v21; // [esp+14h] [ebp-24h] + int v22; // [esp+18h] [ebp-20h] + int v23; // [esp+1Ch] [ebp-1Ch] + int v24; // [esp+20h] [ebp-18h] + int v25; // [esp+24h] [ebp-14h] + int v26; // [esp+28h] [ebp-10h] + int v27; // [esp+2Ch] [ebp-Ch] + int v28; // [esp+30h] [ebp-8h] + signed int v29; // [esp+34h] [ebp-4h] + + v2 = miniset; + v19 = rndper; + v3 = miniset[1]; + v4 = 0; + v23 = 40 - v3; + v27 = *v2; + v28 = v3; + v24 = 0; + if ( 40 - v3 > 0 ) + { + v22 = 40 - *v2; + v21 = dungeon[-1]; + while ( v22 <= 0 ) + { +LABEL_44: + v4 = v24++ + 1; + if ( v24 >= v23 ) + return; + } + v26 = 0; + v20 = v22; + v5 = &v21[v4]; + v25 = (int)&v21[v4]; + while ( 1 ) + { + v6 = 0; + v29 = 1; + for ( i = 2; v6 < v28; ++v6 ) + { + if ( v29 != 1 ) + break; + v8 = 0; + if ( v27 > 0 ) + { + v9 = v24 + v6 + v26; + do + { + if ( v29 != 1 ) + break; + v10 = v2[i]; + if ( v10 && dungeon[0][v9] != v10 ) + v29 = 0; + if ( dflags[0][v9] ) + v29 = 0; + ++i; + ++v8; + v9 += 40; + } + while ( v8 < v27 ); + v5 = (char *)v25; + } + } + v11 = v27 * v28 + 2; + v12 = v2[v11]; + if ( v12 < 0x54u || v12 > 0x64u ) + goto LABEL_33; + if ( v29 == 1 ) + break; +LABEL_43: + v26 += 40; + v5 += 40; + v18 = v20-- == 1; + v25 = (int)v5; + if ( v18 ) + goto LABEL_44; + } + v13 = *v5; + if ( (unsigned char)*v5 >= 0x54u && (unsigned char)v13 <= 0x64u ) + v29 = 0; + if ( (unsigned char)v5[80] >= 0x54u && (unsigned char)v13 <= 0x64u ) + v29 = 0; + if ( (unsigned char)v5[41] >= 0x54u && (unsigned char)v13 <= 0x64u ) + v29 = 0; + if ( (unsigned char)v5[39] >= 0x54u && (unsigned char)v13 <= 0x64u ) + v29 = 0; +LABEL_33: + if ( v29 == 1 ) + { + _LOBYTE(v5) = 0; + if ( random((int)v5, 100) < v19 ) + { + for ( j = 0; j < v28; ++j ) + { + v15 = v27; + if ( v27 > 0 ) + { + v16 = (unsigned char *)dungeon + j + v26 + v24; + do + { + v17 = v2[v11]; + if ( v17 ) + *v16 = v17; + ++v11; + v16 += 40; + --v15; + } + while ( v15 ); + } + } + } + v5 = (char *)v25; + } + goto LABEL_43; + } +} + +//----- (00411E0E) -------------------------------------------------------- +void __cdecl DRLG_L3Wood() +{ + char *v0; // edi + int v1; // edx + _BYTE *v2; // eax + int v3; // edx + _BYTE *v4; // ebx + int v5; // esi + int v6; // esi + int v7; // ebx + int v8; // ebx + signed int v9; // esi + _BYTE *v10; // eax + int v11; // esi + int v12; // ebx + int v13; // eax + _BYTE *v14; // ecx + int v15; // ecx + int v16; // eax + int v17; // esi + int v18; // esi + int v19; // eax + int v20; // edi + int v21; // esi + int i; // edx + int v23; // esi + int v24; // edi + signed int v25; // ecx + int v26; // ebx + char *v27; // esi + int v28; // ecx + int v29; // edi + int v30; // ecx + int v31; // edi + int v32; // ebx + int v33; // ebx + char *v34; // esi + signed int v35; // ecx + int v36; // [esp+Ch] [ebp-14h] + int v37; // [esp+10h] [ebp-10h] + int v38; // [esp+10h] [ebp-10h] + int v39; // [esp+10h] [ebp-10h] + int v40; // [esp+10h] [ebp-10h] + int v41; // [esp+10h] [ebp-10h] + int x; // [esp+14h] [ebp-Ch] + int xa; // [esp+14h] [ebp-Ch] + signed int v44; // [esp+18h] [ebp-8h] + signed int v45; // [esp+18h] [ebp-8h] + int y; // [esp+1Ch] [ebp-4h] + signed int ya; // [esp+1Ch] [ebp-4h] + + y = 0; + do + { + x = 0; + v44 = 1; + v0 = (char *)dungeon + y; + do + { + if ( *v0 == 10 && random(0, 2) ) + { + v1 = v44 - 1; + if ( *v0 == 10 ) + { + v2 = (unsigned char *)v0; + do + { + v2 += 40; + ++v1; + } + while ( *v2 == 10 ); + } + v3 = v1 - 1; + v37 = v3; + if ( v3 - (v44 - 1) > 0 ) + { + *v0 = 127; + if ( v44 < v3 ) + { + v4 = (unsigned char *)v0 + 40; + v5 = v3 - v44; + do + { + *v4 = random(0, 2) != 0 ? 126 : -127; + v4 += 40; + --v5; + } + while ( v5 ); + } + dungeon[v37][y] = -128; + } + } + if ( *v0 == 9 && random(0, 2) ) + { + v6 = y; + v7 = y; + if ( *v0 == 9 ) + { + do + ++v7; + while ( dungeon[x][v7] == 9 ); + } + v8 = v7 - 1; + if ( v8 - y > 0 ) + { + *v0 = 123; + while ( ++v6 < v8 ) + { + if ( random(0, 2) ) + dungeon[x][v6] = 121; + else + dungeon[x][v6] = 124; + } + dungeon[x][v8] = 122; + } + } + if ( *v0 == 11 && v0[40] == 10 && v0[1] == 9 && random(0, 2) ) + { + v9 = v44; + *v0 = 125; + if ( v0[40] == 10 ) + { + v10 = (unsigned char *)v0 + 40; + do + { + v10 += 40; + ++v9; + } + while ( *v10 == 10 ); + } + v11 = v9 - 1; + if ( v44 < v11 ) + { + v38 = (int)(v0 + 40); + v12 = v11 - v44; + do + { + v13 = random(0, 2); + v14 = (_BYTE *)v38; + v38 += 40; + --v12; + *v14 = v13 != 0 ? 126 : -127; + } + while ( v12 ); + } + v15 = 5 * v11; + v16 = y + 1; + v17 = v16; + for ( *((_BYTE *)&dMonster[111][2 * v15 + 111] + v16 + 3) = -128; dungeon[x][v17] == 9; ++v17 ) + ; + v18 = v17 - 1; + v39 = y + 1; + if ( v16 < v18 ) + { + do + { + if ( random(0, 2) ) + dungeon[x][v39] = 121; + else + dungeon[x][v39] = 124; + ++v39; + } + while ( v39 < v18 ); + } + dungeon[x][v18] = 122; + } + ++v44; + ++x; + v0 += 40; + } + while ( v44 - 1 < 39 ); + ++y; + } + while ( y < 39 ); + ya = 0; + do + { + xa = 0; + v45 = 0; + do + { + if ( dungeon[v45][ya] != 7 ) + goto LABEL_112; + if ( random(0, 1) ) + goto LABEL_112; + _LOBYTE(v19) = SkipThemeRoom(xa, ya); + if ( !v19 ) + goto LABEL_112; + v36 = random(0, 2); + if ( !v36 ) + { + v20 = ya; + v21 = ya; + for ( i = ya; WoodVertU(xa, i); i = v21 ) + --v21; + v23 = v21 + 1; + while ( WoodVertD(xa, v20) ) + ++v20; + v24 = v20 - 1; + v25 = 1; + if ( dungeon[v45][v23] == 7 ) + v25 = 0; + if ( dungeon[v45][v24] == 7 ) + v25 = 0; + if ( v24 - v23 <= 1 ) + goto LABEL_112; + if ( !v25 ) + goto LABEL_112; + v40 = random(0, v24 - v23 - 1) + v23 + 1; + v26 = v23; + if ( v23 > v24 ) + goto LABEL_112; + do + { + if ( v26 != v40 ) + { + v27 = &dungeon[v45][v26]; + if ( *v27 == 7 ) + *v27 = random(0, 2) != 0 ? -121 : -119; + if ( *v27 == 10 ) + *v27 = -125; + if ( *v27 == 126 ) + *v27 = -123; + if ( *v27 == -127 ) + *v27 = -123; + if ( *v27 == 2 ) + *v27 = -117; + if ( *v27 == -122 ) + *v27 = -118; + if ( *v27 == -120 ) + *v27 = -118; + } + ++v26; + } + while ( v26 <= v24 ); + } + if ( v36 == 1 ) + { + v28 = xa; + v29 = xa; + while ( WoodHorizL(v28, ya) ) + v28 = --v29; + v30 = xa; + v31 = v29 + 1; + v32 = xa; + while ( WoodHorizR(v30, ya) ) + v30 = ++v32; + v33 = v32 - 1; + v34 = &dungeon[v31][ya]; + v35 = 1; + if ( *v34 == 7 ) + v35 = 0; + if ( dungeon[v33][ya] == 7 ) + v35 = 0; + if ( v33 - v31 > 1 && v35 ) + { + v41 = random(0, v33 - v31 - 1) + v31 + 1; + while ( 1 ) + { + if ( v31 > v33 ) + break; + if ( v31 != v41 ) + { + if ( *v34 == 7 ) + { + if ( random(0, 2) ) + { + *v34 = -122; + goto LABEL_110; + } + *v34 = -120; + } + if ( *v34 == 9 ) + *v34 = -126; + if ( *v34 == 121 ) + *v34 = -124; + if ( *v34 == 124 ) + *v34 = -124; + if ( *v34 == 4 ) + *v34 = -116; + if ( *v34 == -121 ) + *v34 = -118; + if ( *v34 == -119 ) + *v34 = -118; + } +LABEL_110: + ++v31; + v34 += 40; + } + } + } +LABEL_112: + ++v45; + ++xa; + } + while ( v45 < 40 ); + ++ya; + } + while ( ya < 40 ); + AddFenceDoors(); + FenceDoorFix(); +} + +//----- (0041223E) -------------------------------------------------------- +int __fastcall WoodVertU(int i, int y) +{ + int v2; // eax + char v3; // cl + char *v4; // eax + unsigned char v5; // cl + char v6; // al + int result; // eax + + v2 = i; + v3 = dungeon[i + 1][y]; + result = 0; + if ( (unsigned char)v3 > 0x98u || (unsigned char)v3 < 0x82u ) + { + v4 = &dungeon[v2][y]; + v5 = *(v4 - 40); + if ( v5 > 0x98u || v5 < 0x82u ) + { + v6 = *v4; + if ( v6 == 7 || v6 == 10 || v6 == 126 || v6 == -127 || v6 == -122 || v6 == -120 ) + result = 1; + } + } + return result; +} + +//----- (0041228A) -------------------------------------------------------- +int __fastcall WoodVertD(int i, int y) +{ + int v2; // eax + char v3; // cl + char *v4; // eax + unsigned char v5; // cl + char v6; // al + int result; // eax + + v2 = i; + v3 = dungeon[i + 1][y]; + result = 0; + if ( (unsigned char)v3 > 0x98u || (unsigned char)v3 < 0x82u ) + { + v4 = &dungeon[v2][y]; + v5 = *(v4 - 40); + if ( v5 > 0x98u || v5 < 0x82u ) + { + v6 = *v4; + if ( v6 == 7 || v6 == 2 || v6 == -122 || v6 == -120 ) + result = 1; + } + } + return result; +} + +//----- (004122CE) -------------------------------------------------------- +int __fastcall WoodHorizL(int x, int j) +{ + int v2; // eax + char v3; // cl + char *v4; // eax + unsigned char v5; // cl + char v6; // al + int result; // eax + + v2 = x; + v3 = dungeon[x][j + 1]; + result = 0; + if ( (unsigned char)v3 > 0x98u || (unsigned char)v3 < 0x82u ) + { + v4 = &dungeon[v2][j]; + v5 = *(v4 - 1); + if ( v5 > 0x98u || v5 < 0x82u ) + { + v6 = *v4; + if ( v6 == 7 || v6 == 9 || v6 == 121 || v6 == 124 || v6 == -121 || v6 == -119 ) + result = 1; + } + } + return result; +} + +//----- (0041231A) -------------------------------------------------------- +int __fastcall WoodHorizR(int x, int j) +{ + int v2; // eax + char v3; // cl + char *v4; // eax + unsigned char v5; // cl + char v6; // al + int result; // eax + + v2 = x; + v3 = dungeon[x][j + 1]; + result = 0; + if ( (unsigned char)v3 > 0x98u || (unsigned char)v3 < 0x82u ) + { + v4 = &dungeon[v2][j]; + v5 = *(v4 - 1); + if ( v5 > 0x98u || v5 < 0x82u ) + { + v6 = *v4; + if ( v6 == 7 || v6 == 4 || v6 == -121 || v6 == -119 ) + result = 1; + } + } + return result; +} + +//----- (0041235E) -------------------------------------------------------- +void __cdecl DRLG_L3Pass3() +{ + int v0; // eax + int *v1; // esi + int *v2; // eax + signed int v3; // ecx + signed int v4; // ebx + int *v5; // ecx + unsigned char *v6; // edi + unsigned short *v7; // esi + unsigned short v8; // ax + int v9; // eax + signed int v10; // [esp+Ch] [ebp-1Ch] + int *v11; // [esp+10h] [ebp-18h] + int v12; // [esp+14h] [ebp-14h] + int v13; // [esp+18h] [ebp-10h] + int v14; // [esp+18h] [ebp-10h] + int v15; // [esp+1Ch] [ebp-Ch] + int v16; // [esp+1Ch] [ebp-Ch] + int v17; // [esp+20h] [ebp-8h] + int v18; // [esp+20h] [ebp-8h] + int v19; // [esp+24h] [ebp-4h] + int v20; // [esp+24h] [ebp-4h] + + v0 = *((unsigned short *)pMegaTiles + 28) + 1; + v19 = *((unsigned short *)pMegaTiles + 28) + 1; + _LOWORD(v0) = *((_WORD *)pMegaTiles + 29); + v17 = ++v0; + _LOWORD(v0) = *((_WORD *)pMegaTiles + 30); + v15 = ++v0; + _LOWORD(v0) = *((_WORD *)pMegaTiles + 31); + v13 = v0 + 1; + v1 = dPiece[1]; + do + { + v2 = v1; + v3 = 56; + do + { + *(v2 - 112) = v19; + *v2 = v17; + *(v2 - 111) = v15; + v2[1] = v13; + v2 += 224; + --v3; + } + while ( v3 ); + v1 += 2; + } + while ( (signed int)v1 < (signed int)dPiece[2] ); + v4 = 0; + v11 = &dPiece[17][16]; + do + { + v5 = v11; + v6 = (unsigned char *)dungeon + v4; + v10 = 40; + do + { + v12 = *v6 - 1; + if ( v12 < 0 ) + { + v20 = 0; + v18 = 0; + v16 = 0; + v14 = 0; + } + else + { + v7 = (unsigned short *)((char *)pMegaTiles + 8 * v12); + v8 = *v7; + ++v7; + v9 = v8 + 1; + v20 = v9; + _LOWORD(v9) = *v7; + ++v7; + v18 = ++v9; + _LOWORD(v9) = *v7; + v16 = ++v9; + _LOWORD(v9) = v7[1]; + v14 = v9 + 1; + } + v6 += 40; + *(v5 - 112) = v20; + *v5 = v18; + *(v5 - 111) = v16; + v5[1] = v14; + v5 += 224; + --v10; + } + while ( v10 ); + v11 += 2; + ++v4; + } + while ( v4 < 40 ); +} + +//----- (00412466) -------------------------------------------------------- +void __fastcall LoadL3Dungeon(char *sFileName, int vx, int vy) +{ + char *v3; // esi + unsigned char *v4; // eax + char *v5; // esi + int v6; // edi + int v7; // ecx + _BYTE *v8; // eax + _BYTE *v9; // edx + int v10; // ebx + signed int v11; // ecx + _BYTE *v12; // eax + signed int v13; // edx + int v14; // edi + signed int v15; // eax + int v16; // [esp+Ch] [ebp-8h] + signed int *v17; // [esp+Ch] [ebp-8h] + int v18; // [esp+10h] [ebp-4h] + int (*v19)[112]; // [esp+10h] [ebp-4h] + + v3 = sFileName; + InitL3Dungeon(); + dminx = 16; + dminy = 16; + dmaxx = 96; + dmaxy = 96; + DRLG_InitTrans(); + v4 = LoadFileInMem(v3, 0); + v5 = (char *)v4; + v18 = 0; + v6 = *v4; + v4 += 2; + v7 = *v4; + v8 = v4 + 2; + if ( v7 > 0 ) + { + do + { + if ( v6 > 0 ) + { + v16 = v6; + v9 = (unsigned char *)dungeon + v18; + do + { + if ( *v8 ) + *v9 = *v8; + else + *v9 = 7; + v9 += 40; + v8 += 2; + --v16; + } + while ( v16 ); + } + ++v18; + } + while ( v18 < v7 ); + } + v10 = 0; + v11 = 0; + do + { + v12 = (unsigned char *)dungeon + v11; + v13 = 40; + do + { + if ( !*v12 ) + *v12 = 8; + v12 += 40; + --v13; + } + while ( v13 ); + ++v11; + } + while ( v11 < 40 ); + abyssx = 112; + DRLG_L3Pass3(); + DRLG_Init_Globals(); + ViewX = 31; + ViewY = 83; + SetMapMonsters(v5, 0, 0); + SetMapObjects(v5, 0, 0); + v19 = dPiece; + do + { + v14 = 0; + v17 = (signed int *)v19; + do + { + v15 = *v17; + if ( *v17 >= 56 && v15 <= 147 || v15 >= 154 && v15 <= 161 || v15 == 150 || v15 == 152 ) + DoLighting(v14, v10, 7, -1); + v17 += 112; + ++v14; + } + while ( v14 < 112 ); + v19 = (int (*)[112])((char *)v19 + 4); + ++v10; + } + while ( (signed int)v19 < (signed int)dPiece[1] ); + mem_free_dbg(v5); +} +// 52837C: using guessed type int abyssx; +// 5CF328: using guessed type int dmaxx; +// 5CF32C: using guessed type int dmaxy; +// 5D2458: using guessed type int dminx; +// 5D245C: using guessed type int dminy; + +//----- (004125B0) -------------------------------------------------------- +void __fastcall LoadPreL3Dungeon(char *sFileName, int vx, int vy) +{ + char *v3; // esi + unsigned char *v4; // eax + unsigned char *v5; // esi + int v6; // edx + int v7; // edi + _BYTE *v8; // eax + _BYTE *v9; // ecx + signed int v10; // ecx + _BYTE *v11; // eax + signed int v12; // edx + int v13; // [esp+8h] [ebp-8h] + int v14; // [esp+Ch] [ebp-4h] + + v3 = sFileName; + InitL3Dungeon(); + DRLG_InitTrans(); + v4 = LoadFileInMem(v3, 0); + v5 = v4; + v14 = 0; + v6 = *v4; + v4 += 2; + v7 = *v4; + v8 = v4 + 2; + if ( v7 > 0 ) + { + do + { + if ( v6 > 0 ) + { + v13 = v6; + v9 = (unsigned char *)dungeon + v14; + do + { + if ( *v8 ) + *v9 = *v8; + else + *v9 = 7; + v9 += 40; + v8 += 2; + --v13; + } + while ( v13 ); + } + ++v14; + } + while ( v14 < v7 ); + } + v10 = 0; + do + { + v11 = (unsigned char *)dungeon + v10; + v12 = 40; + do + { + if ( !*v11 ) + *v11 = 8; + v11 += 40; + --v12; + } + while ( v12 ); + ++v10; + } + while ( v10 < 40 ); + memcpy(pdungeon, dungeon, 0x640u); + mem_free_dbg(v5); +} + +//----- (00412655) -------------------------------------------------------- +void __cdecl DRLG_LoadL4SP() +{ + int v0; // eax + + setloadflag_2 = 0; + _LOBYTE(v0) = QuestStatus(11); + if ( v0 ) + { + pSetPiece_2 = (char *)LoadFileInMem("Levels\\L4Data\\Warlord.DUN", 0); + setloadflag_2 = 1; + } + if ( currlevel == 15 && gbMaxPlayers != 1 ) + { + pSetPiece_2 = (char *)LoadFileInMem("Levels\\L4Data\\Vile1.DUN", 0); + setloadflag_2 = 1; + } +} +// 5B50D8: using guessed type int setloadflag_2; +// 679660: using guessed type char gbMaxPlayers; + +//----- (004126AD) -------------------------------------------------------- +void __cdecl DRLG_FreeL4SP() +{ + char *v0; // ecx + + v0 = pSetPiece_2; + pSetPiece_2 = 0; + mem_free_dbg(v0); +} + +//----- (004126BF) -------------------------------------------------------- +void __fastcall DRLG_L4SetSPRoom(int rx1, int ry1) +{ + int v2; // edi + int v3; // esi + int v4; // eax + char v5; // bl + int v6; // [esp+8h] [ebp-Ch] + char *v7; // [esp+Ch] [ebp-8h] + int v8; // [esp+10h] [ebp-4h] + + v8 = 0; + v2 = (unsigned char)pSetPiece_2[2]; + v3 = (unsigned char)*pSetPiece_2; + setpc_x = rx1; + setpc_y = ry1; + setpc_w = v3; + setpc_h = v2; + v7 = pSetPiece_2 + 4; + if ( v2 > 0 ) + { + do + { + if ( v3 > 0 ) + { + v6 = v3; + v4 = ry1 + v8 + 40 * rx1; + do + { + v5 = *v7; + if ( *v7 ) + { + dflags[0][v4] |= 0x80u; + dungeon[0][v4] = v5; + } + else + { + dungeon[0][v4] = 6; + } + v7 += 2; + v4 += 40; + --v6; + } + while ( v6 ); + } + ++v8; + } + while ( v8 < v2 ); + } +} +// 5CF330: using guessed type int setpc_h; +// 5CF334: using guessed type int setpc_w; + +//----- (00412744) -------------------------------------------------------- +void __cdecl L4SaveQuads() +{ + char *v0; // esi + char *v1; // edx + char *v2; // edi + char *v3; // eax + char *v4; // ecx + char *v5; // ebx + signed int v6; // [esp+Ch] [ebp-14h] + signed int v7; // [esp+10h] [ebp-10h] + char *v8; // [esp+14h] [ebp-Ch] + char *v9; // [esp+18h] [ebp-8h] + char *v10; // [esp+1Ch] [ebp-4h] + + v0 = &dflags[39][l4holdy - 40 * l4holdx]; + v1 = &dflags[39][-l4holdy + 39 + -40 * l4holdx]; + v9 = &dflags[l4holdx][l4holdy]; + v8 = &dflags[0][40 * l4holdx - l4holdy + 39]; + v6 = 14; + do + { + v2 = v1; + v10 = v8; + v3 = v9; + v4 = v0; + v7 = 14; + do + { + v5 = v10; + v10 += 40; + *v3 = 1; + *v4 = 1; + *v5 = 1; + *v2 = 1; + v4 -= 40; + v2 -= 40; + v3 += 40; + --v7; + } + while ( v7 ); + ++v9; + --v8; + --v1; + ++v0; + --v6; + } + while ( v6 ); +} +// 528A34: using guessed type int l4holdx; +// 528A38: using guessed type int l4holdy; + +//----- (004127D3) -------------------------------------------------------- +void __fastcall DRLG_L4SetRoom(unsigned char *pSetPiece, int rx1, int ry1) +{ + int v3; // ebx + int v4; // edi + unsigned char *v5; // esi + int v6; // eax + char v7; // cl + int v8; // [esp+Ch] [ebp-8h] + int v9; // [esp+10h] [ebp-4h] + + v3 = *pSetPiece; + v4 = 0; + v8 = pSetPiece[2]; + v5 = pSetPiece + 4; + if ( v8 > 0 ) + { + do + { + if ( v3 > 0 ) + { + v9 = v3; + v6 = ry1 + v4 + 40 * rx1; + do + { + v7 = *v5; + if ( *v5 ) + { + dflags[0][v6] |= 0x80u; + dungeon[0][v6] = v7; + } + else + { + dungeon[0][v6] = 6; + } + v6 += 40; + v5 += 2; + --v9; + } + while ( v9 ); + } + ++v4; + } + while ( v4 < v8 ); + } +} + +//----- (00412831) -------------------------------------------------------- +void __fastcall DRLG_LoadDiabQuads(char preflag) +{ + int v1; // esi + unsigned char *v2; // edi + char *v3; // ecx + unsigned char *v4; // edi + char *v5; // ecx + unsigned char *v6; // edi + char *v7; // ecx + unsigned char *v8; // esi + + v1 = preflag; + v2 = LoadFileInMem("Levels\\L4Data\\diab1.DUN", 0); + diabquad1x = l4holdx + 4; + diabquad1y = l4holdy + 4; + DRLG_L4SetRoom(v2, l4holdx + 4, l4holdy + 4); + mem_free_dbg(v2); + v3 = "Levels\\L4Data\\diab2b.DUN"; + if ( !v1 ) + v3 = "Levels\\L4Data\\diab2a.DUN"; + v4 = LoadFileInMem(v3, 0); + diabquad2y = l4holdy + 1; + diabquad2x = 27 - l4holdx; + DRLG_L4SetRoom(v4, 27 - l4holdx, l4holdy + 1); + mem_free_dbg(v4); + v5 = "Levels\\L4Data\\diab3b.DUN"; + if ( !v1 ) + v5 = "Levels\\L4Data\\diab3a.DUN"; + v6 = LoadFileInMem(v5, 0); + diabquad3x = l4holdx + 1; + diabquad3y = 27 - l4holdy; + DRLG_L4SetRoom(v6, l4holdx + 1, 27 - l4holdy); + mem_free_dbg(v6); + v7 = "Levels\\L4Data\\diab4b.DUN"; + if ( !v1 ) + v7 = "Levels\\L4Data\\diab4a.DUN"; + v8 = LoadFileInMem(v7, 0); + diabquad4y = 28 - l4holdy; + diabquad4x = 28 - l4holdx; + DRLG_L4SetRoom(v8, 28 - l4holdx, 28 - l4holdy); + mem_free_dbg(v8); +} +// 5289C4: using guessed type int diabquad1x; +// 5289C8: using guessed type int diabquad1y; +// 528A34: using guessed type int l4holdx; +// 528A38: using guessed type int l4holdy; + +//----- (00412933) -------------------------------------------------------- +unsigned char __fastcall IsDURWall(char d) +{ + unsigned char result; // al + + if ( d == 25 || d == 28 ) + result = 1; + else + result = d == 23; + return result; +} + +//----- (00412948) -------------------------------------------------------- +unsigned char __fastcall IsDLLWall(char dd) +{ + unsigned char result; // al + + if ( dd == 27 || dd == 26 ) + result = 1; + else + result = dd == 22; + return result; +} + +//----- (0041295D) -------------------------------------------------------- +void __cdecl L4FixRim() +{ + char (*v0)[20]; // eax + + v0 = dung; + do + { + *(_BYTE *)v0 = 0; + ++v0; + } + while ( (signed int)v0 < (signed int)&dword_52A4DC ); + *(_DWORD *)&dung[0][0] = 0; + *(_DWORD *)&dung[0][4] = 0; + *(_DWORD *)&dung[0][8] = 0; + *(_DWORD *)&dung[0][12] = 0; + *(_DWORD *)&dung[0][16] = 0; +} +// 52A4DC: using guessed type int dword_52A4DC; + +//----- (0041297B) -------------------------------------------------------- +void __cdecl DRLG_L4GeneralFix() +{ + signed int v0; // ecx + char *v1; // eax + signed int v2; // esi + + v0 = 0; + do + { + v1 = (char *)dungeon + v0; + v2 = 39; + do + { + if ( (*v1 == 24 || *v1 == 122) && v1[40] == 2 && v1[1] == 5 ) + *v1 = 17; + v1 += 40; + --v2; + } + while ( v2 ); + ++v0; + } + while ( v0 < 39 ); +} + +//----- (004129B0) -------------------------------------------------------- +void __fastcall CreateL4Dungeon(int seed, int entry) +{ + int v2; // esi + + v2 = entry; + SetRndSeed(seed); + dminx = 16; + dminy = 16; + dmaxx = 96; + dmaxy = 96; + ViewX = 40; + ViewY = 40; + DRLG_InitSetPC(); + DRLG_LoadL4SP(); + DRLG_L4(v2); + DRLG_L4Pass3(); + DRLG_FreeL4SP(); + DRLG_SetPC(); +} +// 5CF328: using guessed type int dmaxx; +// 5CF32C: using guessed type int dmaxy; +// 5D2458: using guessed type int dminx; +// 5D245C: using guessed type int dminy; + +//----- (00412A00) -------------------------------------------------------- +void __fastcall DRLG_L4(int entry) +{ + signed int v1; // ebp + int v2; // eax + int v3; // edx + char *v4; // edi + char v5; // bp + unsigned int v6; // ecx + char *v7; // edi + int v8; // ecx + int v9; // eax + int v10; // eax + unsigned char *v11; // ecx + unsigned char *v12; // ecx + int v13; // eax + signed int v14; // eax + signed int v15; // ecx + int v16; // ebx + int v17; // edi + char *v18; // ebp + signed int v19; // ecx + signed int v20; // eax + signed int v21; // esi + int v22; // [esp-8h] [ebp-20h] + int v23; // [esp+10h] [ebp-8h] + int v24; // [esp+14h] [ebp-4h] + + v1 = 0; + v23 = entry; + do + { + DRLG_InitTrans(); + do + { + InitL4Dungeon(); + L4firstRoom(); + L4FixRim(); + } + while ( GetArea() < 173 ); + uShape(); + L4makeDungeon(); + L4makeDmt(); + L4tileFix(); + if ( currlevel == 16 ) + L4SaveQuads(); + _LOBYTE(v2) = QuestStatus(11); + if ( (v2 || currlevel == quests[15]._qlevel && gbMaxPlayers != 1) && SP4x1 < SP4x2 ) + { + v3 = SP4x1; + v24 = SP4x2 - SP4x1; + do + { + if ( SP4y1 < SP4y2 ) + { + v4 = &dflags[v3][SP4y1]; + v5 = SP4y2 - SP4y1; + v6 = (unsigned int)(SP4y2 - SP4y1) >> 2; + memset(v4, 1u, 4 * v6); + v7 = &v4[4 * v6]; + v8 = v5 & 3; + v1 = 0; + memset(v7, 1, v8); + } + ++v3; + --v24; + } + while ( v24 ); + } + L4AddWall(); + DRLG_L4FloodTVal(); + DRLG_L4TransFix(); + if ( setloadflag_2 ) + DRLG_L4SetSPRoom(SP4x1, SP4y1); + if ( currlevel == 16 ) + DRLG_LoadDiabQuads(1); + _LOBYTE(v9) = QuestStatus(11); + if ( !v9 ) + { + if ( currlevel == 15 ) + { + if ( !v23 ) + { + _LOBYTE(v10) = DRLG_L4PlaceMiniSet(L4USTAIRS, 1, 1, -1, -1, 1, 0); + if ( v10 ) + { + if ( gbMaxPlayers != 1 || (v11 = L4PENTA, quests[5]._qactive == 2) ) + v11 = L4PENTA2; + _LOBYTE(v10) = DRLG_L4PlaceMiniSet(v11, 1, 1, -1, -1, 0, 1); + } + goto LABEL_35; + } + _LOBYTE(v10) = DRLG_L4PlaceMiniSet(L4USTAIRS, 1, 1, -1, -1, 0, 0); + if ( v10 ) + { + if ( gbMaxPlayers != 1 || (v12 = L4PENTA, quests[5]._qactive == 2) ) + v12 = L4PENTA2; + _LOBYTE(v10) = DRLG_L4PlaceMiniSet(v12, 1, 1, -1, -1, 1, 1); + } + } + else + { + if ( !v23 ) + { + _LOBYTE(v10) = DRLG_L4PlaceMiniSet(L4USTAIRS, 1, 1, -1, -1, 1, 0); + if ( v10 ) + { + if ( currlevel != 16 ) + _LOBYTE(v10) = DRLG_L4PlaceMiniSet(L4DSTAIRS, 1, 1, -1, -1, 0, 1); + goto LABEL_31; + } +LABEL_35: + ++ViewX; + continue; + } + _LOBYTE(v10) = DRLG_L4PlaceMiniSet(L4USTAIRS, 1, 1, -1, -1, 0, 0); + if ( v23 != 1 ) + { + if ( v10 ) + { + if ( currlevel != 16 ) + _LOBYTE(v10) = DRLG_L4PlaceMiniSet(L4DSTAIRS, 1, 1, -1, -1, 0, 1); +LABEL_46: + if ( v10 ) + { + if ( currlevel == 13 ) + { + v22 = 1; +LABEL_34: + _LOBYTE(v10) = DRLG_L4PlaceMiniSet(L4TWARP, 1, 1, -1, -1, v22, 6); + goto LABEL_35; + } + } + } + goto LABEL_35; + } + if ( v10 ) + { + if ( currlevel != 16 ) + _LOBYTE(v10) = DRLG_L4PlaceMiniSet(L4DSTAIRS, 1, 1, -1, -1, 1, 1); + if ( v10 && currlevel == 13 ) + _LOBYTE(v10) = DRLG_L4PlaceMiniSet(L4TWARP, 1, 1, -1, -1, 0, 6); + } + } + ++ViewY; + continue; + } + if ( !v23 ) + { + _LOBYTE(v10) = DRLG_L4PlaceMiniSet(L4USTAIRS, 1, 1, -1, -1, 1, 0); +LABEL_31: + if ( !v10 || currlevel != 13 ) + goto LABEL_35; + v22 = 0; + goto LABEL_34; + } + _LOBYTE(v10) = DRLG_L4PlaceMiniSet(L4USTAIRS, 1, 1, -1, -1, 0, 0); + if ( v23 != 1 ) + goto LABEL_46; + if ( v10 && currlevel == 13 ) + _LOBYTE(v10) = DRLG_L4PlaceMiniSet(L4TWARP, 1, 1, -1, -1, 0, 6); + ViewX = 2 * setpc_x + 22; + ViewY = 2 * setpc_y + 22; + } + while ( !v10 ); + DRLG_L4GeneralFix(); + if ( currlevel != 16 ) + DRLG_PlaceThemeRooms(7, 10, 6, 8, 1); + DRLG_L4Shadows(); + DRLG_L4Corners(); + DRLG_L4Subs(); + DRLG_Init_Globals(); + _LOBYTE(v13) = QuestStatus(11); + if ( v13 ) + { + do + { + v14 = v1; + v15 = 40; + do + { + pdungeon[0][v14] = dungeon[0][v14]; + v14 += 40; + --v15; + } + while ( v15 ); + ++v1; + } + while ( v1 < 40 ); + } + DRLG_CheckQuests(SP4x1, SP4y1); + if ( currlevel == 15 ) + { + v16 = -1; + do + { + v17 = -1; + v18 = &dungeon[0][v16 + 1]; + do + { + if ( *v18 == 98 ) + Make_SetPC(v17, v16, 5, 5); + if ( *v18 == 107 ) + Make_SetPC(v17, v16, 5, 5); + v18 += 40; + ++v17; + } + while ( v17 + 1 < 40 ); + ++v16; + } + while ( v16 < 39 ); + } + if ( currlevel == 16 ) + { + v19 = 0; + do + { + v20 = v19; + v21 = 40; + do + { + pdungeon[0][v20] = dungeon[0][v20]; + v20 += 40; + --v21; + } + while ( v21 ); + ++v19; + } + while ( v19 < 40 ); + DRLG_LoadDiabQuads(0); + } +} +// 528A40: using guessed type int SP4x2; +// 528A48: using guessed type int SP4y2; +// 5B50D8: using guessed type int setloadflag_2; +// 679660: using guessed type char gbMaxPlayers; + +//----- (00412DDD) -------------------------------------------------------- +void __cdecl DRLG_L4Shadows() +{ + signed int v0; // esi + char *v1; // eax + signed int v2; // edi + char v3; // dl + signed int v4; // ecx + + v0 = 1; + do + { + v1 = &dungeon[1][v0]; + v2 = 39; + do + { + v3 = *v1; + v4 = 0; + if ( *v1 == 3 ) + v4 = 1; + if ( v3 == 4 ) + v4 = 1; + if ( v3 == 8 ) + v4 = 1; + if ( v3 == 15 ) + v4 = 1; + if ( v4 ) + { + if ( *(v1 - 40) == 6 ) + *(v1 - 40) = 47; + if ( *(v1 - 41) == 6 ) + *(v1 - 41) = 48; + } + v1 += 40; + --v2; + } + while ( v2 ); + ++v0; + } + while ( v0 < 40 ); +} + +//----- (00412E34) -------------------------------------------------------- +void __cdecl InitL4Dungeon() +{ + signed int v0; // edx + signed int v1; // eax + signed int v2; // ecx + + memset(dung, 0, 0x190u); + memset(L4dungeon, 0, 0x1900u); + v0 = 0; + do + { + v1 = v0; + v2 = 40; + do + { + dflags[0][v1] = 0; + dungeon[0][v1] = 30; + v1 += 40; + --v2; + } + while ( v2 ); + ++v0; + } + while ( v0 < 40 ); +} + +//----- (00412E7B) -------------------------------------------------------- +void __cdecl L4makeDmt() +{ + signed int v0; // ecx + char (*v1)[40]; // ebp + char (*v2)[40]; // esi + char *v3; // eax + signed int v4; // edi + int v5; // edx + int v6; // ebx + + v0 = 1; + v1 = dungeon; + do + { + v2 = v1; + v3 = &L4dungeon[1][v0 + 1]; + v4 = 39; + do + { + v5 = (unsigned char)v3[80]; + v6 = (unsigned char)*v3; + v3 += 160; + *(_BYTE *)v2 = L4ConvTbl[2 * ((unsigned char)*(v3 - 81) + 2 * (v6 + 2 * v5)) + + (unsigned char)*(v3 - 161)]; + ++v2; + --v4; + } + while ( v4 ); + v1 = (char (*)[40])((char *)v1 + 1); + v0 += 2; + } + while ( v0 <= 77 ); +} + +//----- (00412ECB) -------------------------------------------------------- +void __cdecl L4AddWall() +{ + int v0; // edi + int v1; // esi + int v2; // ebx + int v3; // eax + int v4; // eax + int v5; // eax + int v6; // eax + int v7; // eax + int v8; // eax + int v9; // eax + int v10; // eax + int v11; // eax + int v12; // eax + int v13; // eax + int v14; // eax + int v15; // eax + int v16; // eax + int v17; // eax + + v0 = 0; + do + { + v1 = 0; + v2 = v0; + do + { + if ( !dflags[0][v2] ) + { + if ( dungeon[0][v2] == 10 && random(0, 100) < 100 ) + { + v3 = L4HWallOk(v1, v0); + if ( v3 != -1 ) + L4HorizWall(v1, v0, v3); + } + if ( dungeon[0][v2] == 12 && random(0, 100) < 100 ) + { + v4 = L4HWallOk(v1, v0); + if ( v4 != -1 ) + L4HorizWall(v1, v0, v4); + } + if ( dungeon[0][v2] == 13 && random(0, 100) < 100 ) + { + v5 = L4HWallOk(v1, v0); + if ( v5 != -1 ) + L4HorizWall(v1, v0, v5); + } + if ( dungeon[0][v2] == 15 && random(0, 100) < 100 ) + { + v6 = L4HWallOk(v1, v0); + if ( v6 != -1 ) + L4HorizWall(v1, v0, v6); + } + if ( dungeon[0][v2] == 16 && random(0, 100) < 100 ) + { + v7 = L4HWallOk(v1, v0); + if ( v7 != -1 ) + L4HorizWall(v1, v0, v7); + } + if ( dungeon[0][v2] == 21 && random(0, 100) < 100 ) + { + v8 = L4HWallOk(v1, v0); + if ( v8 != -1 ) + L4HorizWall(v1, v0, v8); + } + if ( dungeon[0][v2] == 22 && random(0, 100) < 100 ) + { + v9 = L4HWallOk(v1, v0); + if ( v9 != -1 ) + L4HorizWall(v1, v0, v9); + } + if ( dungeon[0][v2] == 8 && random(0, 100) < 100 ) + { + v10 = L4VWallOk(v1, v0); + if ( v10 != -1 ) + L4VertWall(v1, v0, v10); + } + if ( dungeon[0][v2] == 9 && random(0, 100) < 100 ) + { + v11 = L4VWallOk(v1, v0); + if ( v11 != -1 ) + L4VertWall(v1, v0, v11); + } + if ( dungeon[0][v2] == 11 && random(0, 100) < 100 ) + { + v12 = L4VWallOk(v1, v0); + if ( v12 != -1 ) + L4VertWall(v1, v0, v12); + } + if ( dungeon[0][v2] == 14 && random(0, 100) < 100 ) + { + v13 = L4VWallOk(v1, v0); + if ( v13 != -1 ) + L4VertWall(v1, v0, v13); + } + if ( dungeon[0][v2] == 15 && random(0, 100) < 100 ) + { + v14 = L4VWallOk(v1, v0); + if ( v14 != -1 ) + L4VertWall(v1, v0, v14); + } + if ( dungeon[0][v2] == 16 && random(0, 100) < 100 ) + { + v15 = L4VWallOk(v1, v0); + if ( v15 != -1 ) + L4VertWall(v1, v0, v15); + } + if ( dungeon[0][v2] == 21 && random(0, 100) < 100 ) + { + v16 = L4VWallOk(v1, v0); + if ( v16 != -1 ) + L4VertWall(v1, v0, v16); + } + if ( dungeon[0][v2] == 23 && random(0, 100) < 100 ) + { + v17 = L4VWallOk(v1, v0); + if ( v17 != -1 ) + L4VertWall(v1, v0, v17); + } + } + ++v1; + v2 += 40; + } + while ( v1 < 40 ); + ++v0; + } + while ( v0 < 40 ); +} + +//----- (004131C2) -------------------------------------------------------- +int __fastcall L4HWallOk(int i, int j) +{ + int v2; // esi + int v3; // edi + char *v4; // ebx + int result; // eax + signed int v6; // esi + char v7; // dl + int v8; // [esp+8h] [ebp-4h] + + v2 = 8 * (5 * i + 5); + v8 = 1; + if ( dungeon[0][v2 + j] == 6 ) + { + v3 = 8 * (5 * i + 5); + v4 = &dungeon[i + 1][j]; + do + { + if ( dflags[0][v3 + j] ) + break; + if ( *((_BYTE *)&dMonster[111][111] + v3 + j + 3) != 6 ) + break; + if ( dungeon[0][v3 + 1 + j] != 6 ) + break; + ++v8; + v4 += 40; + v2 += 40; + v3 = v2; + } + while ( *v4 == 6 ); + } + result = v8; + v6 = 0; + v7 = dungeon[v8 + i][j]; + if ( v7 == 10 ) + v6 = 1; + if ( v7 == 12 ) + v6 = 1; + if ( v7 == 13 ) + v6 = 1; + if ( v7 == 15 ) + v6 = 1; + if ( v7 == 16 ) + v6 = 1; + if ( v7 == 21 ) + v6 = 1; + if ( v7 == 22 ) + v6 = 1; + if ( v8 <= 3 ) + v6 = 0; + if ( !v6 ) + result = -1; + return result; +} + +//----- (00413270) -------------------------------------------------------- +int __fastcall L4VWallOk(int i, int j) +{ + int v2; // ecx + int result; // eax + char *v4; // esi + signed int v5; // esi + char v6; // dl + + v2 = i; + result = 1; + if ( dungeon[v2][j + 1] == 6 ) + { + do + { + if ( dflags[v2][j + result] ) + break; + v4 = &dungeon[v2][j]; + if ( v4[result - 40] != 6 ) + break; + if ( dungeon[v2 + 1][result + j] != 6 ) + break; + ++result; + } + while ( v4[result] == 6 ); + } + v5 = 0; + v6 = dungeon[0][result + v2 * 40 + j]; + if ( v6 == 8 ) + v5 = 1; + if ( v6 == 9 ) + v5 = 1; + if ( v6 == 11 ) + v5 = 1; + if ( v6 == 14 ) + v5 = 1; + if ( v6 == 15 ) + v5 = 1; + if ( v6 == 16 ) + v5 = 1; + if ( v6 == 21 ) + v5 = 1; + if ( v6 == 23 ) + v5 = 1; + if ( result <= 3 ) + v5 = 0; + if ( !v5 ) + result = -1; + return result; +} + +//----- (0041330B) -------------------------------------------------------- +void __fastcall L4HorizWall(int i, int j, int dx) +{ + int v3; // esi + int v4; // edi + int v5; // eax + int v6; // ecx + char *v7; // eax + int v8; // edx + char *v9; // eax + int v10; // eax + bool v11; // zf + char *v12; // eax + + v3 = i; + v4 = j; + v5 = j + 40 * i; + if ( dungeon[0][v5] == 13 ) + dungeon[0][v5] = 17; + if ( dungeon[0][v5] == 16 ) + dungeon[0][v5] = 11; + if ( dungeon[0][v5] == 12 ) + dungeon[0][v5] = 14; + v6 = dx; + if ( dx > 1 ) + { + v7 = &dungeon[1][v5]; + v8 = dx - 1; + do + { + *v7 = 2; + v7 += 40; + --v8; + } + while ( v8 ); + } + v9 = &dungeon[v3 + dx][v4]; + if ( *v9 == 15 ) + *v9 = 14; + if ( *v9 == 10 ) + *v9 = 17; + if ( *v9 == 21 ) + *v9 = 23; + if ( *v9 == 22 ) + *v9 = 29; + _LOBYTE(v6) = 0; + v10 = v4 + 40 * (v3 + random(v6, dx - 3) + 1); + dungeon[2][v10] = 56; + dungeon[1][v10] = 60; + v11 = dungeon[0][v10 - 1] == 6; + dungeon[0][v10] = 57; + if ( v11 ) + dungeon[0][v10 - 1] = 58; + v12 = &dungeon[0][v10 + 39]; + if ( *v12 == 6 ) + *v12 = 59; +} + +//----- (004133D6) -------------------------------------------------------- +void __fastcall L4VertWall(int i, int j, int dy) +{ + int v3; // edi + int v4; // esi + int v5; // edx + int v6; // ecx + _BYTE *v7; // eax + int v8; // edx + int v9; // eax + char *v10; // ecx + bool v11; // zf + int v12; // [esp+8h] [ebp-4h] + + v3 = j; + v4 = 40 * i; + v12 = j; + v5 = 40 * i + j; + if ( dungeon[0][v5] == 14 ) + dungeon[0][v5] = 17; + if ( dungeon[0][v5] == 8 ) + dungeon[0][v5] = 9; + if ( dungeon[0][v5] == 15 ) + dungeon[0][v5] = 10; + v6 = dy; + if ( dy > 1 ) + { + memset(&dungeon[0][v5 + 1], 1u, dy - 1); + v3 = v12; + v6 = dy; + } + v7 = (unsigned char *)dungeon + v5 + v6; + if ( *v7 == 11 ) + *v7 = 17; + if ( *v7 == 9 ) + *v7 = 10; + if ( *v7 == 16 ) + *v7 = 13; + if ( *v7 == 21 ) + *v7 = 22; + if ( *v7 == 23 ) + *v7 = 29; + v8 = v6 - 3; + _LOBYTE(v6) = 0; + v9 = random(v6, v8) + 1 + v4 + v3; + v10 = (char *)dungeon + v9; + dungeon[0][v9 + 2] = 52; + dungeon[0][v9 + 1] = 6; + v11 = dungeon[-1][v9] == 6; + dungeon[0][v9] = 53; + if ( v11 ) + *(v10 - 40) = 54; + if ( *(v10 - 41) == 6 ) + *(v10 - 41) = 55; +} + +//----- (004134B4) -------------------------------------------------------- +void __cdecl L4tileFix() +{ + signed int v0; // edx + char *v1; // eax + signed int v2; // esi + char v3; // cl + signed int v4; // edx + char *v5; // eax + signed int v6; // esi + char v7; // cl + signed int v8; // ecx + int v9; // eax + int v10; // eax + char *v11; // esi + char v12; // bl + char *v13; // edx + char *v14; // edx + char *v15; // edx + char *v16; // edx + char *v17; // edx + char *v18; // edx + char *v19; // edx + char *v20; // edx + char *v21; // edx + char *v22; // edx + char *v23; // edx + char *v24; // edx + char *v25; // edx + char *v26; // edx + char *v27; // edx + char *v28; // edx + char *v29; // edx + char *v30; // edx + char *v31; // edx + char *v32; // edx + char *v33; // edx + char *v34; // edx + char *v35; // edx + char *v36; // edx + char *v37; // edx + char *v38; // edx + char *v39; // edx + char *v40; // edx + char *v41; // edx + char *v42; // edx + char *v43; // edx + char *v44; // edx + char *v45; // edx + char *v46; // edx + char *v47; // edx + char *v48; // edx + char *v49; // edx + char *v50; // edx + char *v51; // edx + char *v52; // edx + char *v53; // edx + char *v54; // edx + char *v55; // edx + char *v56; // edx + char *v57; // edx + char *v58; // edx + char *v59; // edx + char *v60; // edx + char *v61; // edx + char *v62; // edx + char *v63; // edx + char *v64; // edx + char *v65; // edx + char *v66; // edx + char *v67; // edx + char *v68; // edx + char *v69; // edx + char *v70; // edx + char *v71; // edx + char *v72; // edx + char *v73; // edx + char *v74; // edx + char *v75; // edx + char *v76; // edx + char *v77; // edx + char *v78; // edx + char *v79; // edx + char *v80; // edx + char *v81; // edx + char *v82; // edx + char *v83; // edx + char *v84; // edx + char *v85; // edx + char *v86; // edx + char *v87; // edx + char *v88; // edx + char *v89; // edx + char *v90; // edx + char *v91; // edx + char *v92; // edx + char *v93; // edx + char *v94; // edx + char *v95; // edx + signed int v96; // ecx + signed int v97; // edi + signed int v98; // eax + char *v99; // esi + char v100; // bl + char *v101; // edx + char *v102; // edx + char *v103; // edx + char *v104; // edx + char *v105; // edx + char *v106; // edx + char *v107; // edx + char *v108; // edx + char *v109; // edx + char *v110; // edx + char *v111; // edx + char *v112; // edx + char *v113; // edx + char *v114; // edx + char *v115; // edx + char *v116; // edx + char *v117; // edx + char *v118; // edx + char *v119; // edx + char *v120; // edx + char *v121; // edx + char *v122; // edx + char *v123; // edx + char *v124; // edx + char *v125; // edx + char *v126; // edx + char *v127; // edx + char *v128; // edx + char *v129; // edx + char *v130; // edx + signed int v131; // edx + char *v132; // eax + signed int v133; // esi + char v134; // cl + signed int v135; // edx + char *v136; // eax + signed int v137; // esi + char v138; // cl + signed int v139; // [esp+8h] [ebp-4h] + + v0 = 0; + do + { + v1 = &dungeon[1][v0]; + v2 = 40; + do + { + v3 = *(v1 - 40); + if ( v3 == 2 ) + { + if ( *v1 == 6 ) + *v1 = 5; + if ( *v1 == 1 ) + *v1 = 13; + } + if ( v3 == 1 && *(v1 - 39) == 2 ) + *(v1 - 39) = 14; + v1 += 40; + --v2; + } + while ( v2 ); + ++v0; + } + while ( v0 < 40 ); + v4 = 0; + do + { + v5 = &dungeon[1][v4]; + v6 = 40; + do + { + v7 = *(v5 - 40); + if ( v7 == 2 ) + { + if ( *v5 == 6 ) + *v5 = 2; + if ( *v5 == 9 ) + *v5 = 11; + } + if ( v7 == 9 && *v5 == 6 ) + *v5 = 12; + if ( v7 == 14 && *v5 == 1 ) + *v5 = 13; + if ( v7 == 6 ) + { + if ( *v5 == 14 ) + *v5 = 15; + if ( *(v5 - 39) == 13 ) + *(v5 - 39) = 16; + } + if ( v7 == 1 && *(v5 - 39) == 9 ) + *(v5 - 39) = 10; + if ( v7 == 6 && *(v5 - 41) == 1 ) + *(v5 - 41) = 1; + v5 += 40; + --v6; + } + while ( v6 ); + ++v4; + } + while ( v4 < 40 ); + v8 = 0; + do + { + v9 = 0; + v139 = 0; + do + { + v10 = v9; + v11 = &dungeon[v10][v8]; + v12 = *v11; + if ( *v11 == 13 ) + { + v13 = &dungeon[v10][v8 + 1]; + if ( *v13 == 30 ) + *v13 = 27; + } + if ( v12 == 27 ) + { + v14 = &dungeon[v10 + 1][v8]; + if ( *v14 == 30 ) + *v14 = 19; + } + if ( v12 == 1 ) + { + v15 = &dungeon[v10][v8 + 1]; + if ( *v15 == 30 ) + *v15 = 27; + } + if ( v12 == 27 ) + { + v16 = &dungeon[v10 + 1][v8]; + if ( *v16 == 1 ) + *v16 = 16; + } + if ( v12 == 19 ) + { + v17 = &dungeon[v10 + 1][v8]; + if ( *v17 == 27 ) + *v17 = 26; + } + if ( v12 == 27 ) + { + v18 = &dungeon[v10 + 1][v8]; + if ( *v18 == 30 ) + *v18 = 19; + } + if ( v12 == 2 ) + { + v19 = &dungeon[v10 + 1][v8]; + if ( *v19 == 15 ) + *v19 = 14; + } + if ( v12 == 14 ) + { + v20 = &dungeon[v10 + 1][v8]; + if ( *v20 == 15 ) + *v20 = 14; + } + if ( v12 == 22 ) + { + v21 = &dungeon[v10 + 1][v8]; + if ( *v21 == 1 ) + *v21 = 16; + } + if ( v12 == 27 ) + { + v22 = &dungeon[v10 + 1][v8]; + if ( *v22 == 1 ) + *v22 = 16; + } + if ( v12 == 6 ) + { + v23 = &dungeon[v10 + 1][v8]; + if ( *v23 == 27 ) + { + if ( dungeon[v10 + 1][v8 + 1] ) + *v23 = 22; + } + } + if ( v12 == 22 ) + { + v24 = &dungeon[v10 + 1][v8]; + if ( *v24 == 30 ) + *v24 = 19; + } + if ( v12 == 21 ) + { + v25 = &dungeon[v10 + 1][v8]; + if ( *v25 == 1 && dungeon[v10][v8 + 39] == 1 ) + *v25 = 13; + } + if ( v12 == 14 ) + { + v26 = &dungeon[v10 + 1][v8]; + if ( *v26 == 30 && dungeon[v10][v8 + 1] == 6 ) + *v26 = 28; + } + if ( v12 == 16 ) + { + if ( dungeon[v10 + 1][v8] == 6 ) + { + v27 = &dungeon[v10][v8 + 1]; + if ( *v27 == 30 ) + *v27 = 27; + } + v28 = &dungeon[v10][v8 + 1]; + if ( *v28 == 30 && dungeon[v10 + 1][v8 + 1] == 30 ) + *v28 = 27; + } + if ( v12 == 6 ) + { + v29 = &dungeon[v10 + 1][v8]; + if ( *v29 == 30 && dungeon[v10][v8 + 39] == 6 ) + *v29 = 21; + } + if ( v12 == 2 ) + { + v30 = &dungeon[v10 + 1][v8]; + if ( *v30 == 27 && dungeon[v10 + 1][v8 + 1] == 9 ) + *v30 = 29; + } + if ( v12 == 9 ) + { + v31 = &dungeon[v10 + 1][v8]; + if ( *v31 == 15 ) + *v31 = 14; + } + if ( v12 == 15 ) + { + v32 = &dungeon[v10 + 1][v8]; + if ( *v32 == 27 && dungeon[v10 + 1][v8 + 1] == 2 ) + *v32 = 29; + } + if ( v12 == 19 ) + { + v33 = &dungeon[v10 + 1][v8]; + if ( *v33 == 18 ) + *v33 = 24; + } + if ( v12 == 9 ) + { + v34 = &dungeon[v10 + 1][v8]; + if ( *v34 == 15 ) + *v34 = 14; + } + if ( v12 == 19 ) + { + v35 = &dungeon[v10 + 1][v8]; + if ( *v35 == 19 && dungeon[v10][v8 + 39] == 30 ) + *v35 = 24; + } + if ( v12 == 24 && *(v11 - 1) == 30 && *(v11 - 2) == 6 ) + *(v11 - 1) = 21; + if ( v12 == 2 ) + { + v36 = &dungeon[v10 + 1][v8]; + if ( *v36 == 30 ) + *v36 = 28; + } + if ( v12 == 15 ) + { + v37 = &dungeon[v10 + 1][v8]; + if ( *v37 == 30 ) + *v37 = 28; + } + if ( v12 == 28 ) + { + v38 = &dungeon[v10][v8 + 1]; + if ( *v38 == 30 ) + *v38 = 18; + v39 = &dungeon[v10][v8 + 1]; + if ( *v39 == 2 ) + *v39 = 15; + } + if ( v12 == 19 ) + { + if ( dungeon[v10 + 2][v8] == 2 && dungeon[v10][v8 + 39] == 18 && dungeon[v10 + 1][v8 + 1] == 1 ) + dungeon[v10 + 1][v8] = 17; + if ( dungeon[v10 + 2][v8] == 2 && dungeon[v10][v8 + 39] == 22 && dungeon[v10 + 1][v8 + 1] == 1 ) + dungeon[v10 + 1][v8] = 17; + if ( dungeon[v10 + 2][v8] == 2 && dungeon[v10][v8 + 39] == 18 && dungeon[v10 + 1][v8 + 1] == 13 ) + dungeon[v10 + 1][v8] = 17; + } + if ( v12 == 21 ) + { + if ( dungeon[v10 + 2][v8] == 2 && dungeon[v10][v8 + 39] == 18 && dungeon[v10 + 1][v8 + 1] == 1 ) + dungeon[v10 + 1][v8] = 17; + if ( dungeon[v10 + 1][v8 + 1] == 1 && dungeon[v10][v8 + 39] == 22 && dungeon[v10 + 2][v8] == 3 ) + dungeon[v10 + 1][v8] = 17; + } + if ( v12 == 15 ) + { + v40 = &dungeon[v10 + 1][v8]; + if ( *v40 == 28 && dungeon[v10 + 2][v8] == 30 && dungeon[v10][v8 + 39] == 6 ) + *v40 = 23; + } + if ( v12 == 14 ) + { + v41 = &dungeon[v10 + 1][v8]; + if ( *v41 == 28 && dungeon[v10 + 2][v8] == 1 ) + *v41 = 23; + } + if ( v12 == 15 ) + { + v42 = &dungeon[v10 + 1][v8]; + if ( *v42 == 27 && dungeon[v10 + 1][v8 + 1] == 30 ) + *v42 = 29; + } + if ( v12 == 28 ) + { + v43 = &dungeon[v10][v8 + 1]; + if ( *v43 == 9 ) + *v43 = 15; + } + if ( v12 == 21 && dungeon[v10][v8 + 39] == 21 ) + dungeon[v10 + 1][v8] = 24; + if ( v12 == 2 ) + { + v44 = &dungeon[v10 + 1][v8]; + if ( *v44 == 27 && dungeon[v10 + 1][v8 + 1] == 30 ) + *v44 = 29; + v45 = &dungeon[v10 + 1][v8]; + if ( *v45 == 18 ) + *v45 = 25; + } + if ( v12 == 21 ) + { + v46 = &dungeon[v10 + 1][v8]; + if ( *v46 == 9 && dungeon[v10 + 2][v8] == 2 ) + *v46 = 11; + } + if ( v12 == 19 ) + { + v47 = &dungeon[v10 + 1][v8]; + if ( *v47 == 10 ) + *v47 = 17; + } + if ( v12 == 15 ) + { + v48 = &dungeon[v10][v8 + 1]; + if ( *v48 == 3 ) + *v48 = 4; + } + if ( v12 == 22 ) + { + v49 = &dungeon[v10][v8 + 1]; + if ( *v49 == 9 ) + *v49 = 15; + } + if ( v12 == 18 ) + { + v50 = &dungeon[v10][v8 + 1]; + if ( *v50 == 30 ) + *v50 = 18; + } + if ( v12 == 24 && *(v11 - 40) == 30 ) + *(v11 - 40) = 19; + if ( v12 == 21 ) + { + v51 = &dungeon[v10][v8 + 1]; + if ( *v51 == 2 ) + *v51 = 15; + v52 = &dungeon[v10][v8 + 1]; + if ( *v52 == 9 ) + *v52 = 10; + } + if ( v12 == 22 ) + { + v53 = &dungeon[v10][v8 + 1]; + if ( *v53 == 30 ) + *v53 = 18; + } + if ( v12 == 21 ) + { + v54 = &dungeon[v10][v8 + 1]; + if ( *v54 == 30 ) + *v54 = 18; + } + if ( v12 == 16 ) + { + v55 = &dungeon[v10][v8 + 1]; + if ( *v55 == 2 ) + *v55 = 15; + } + if ( v12 == 13 ) + { + v56 = &dungeon[v10][v8 + 1]; + if ( *v56 == 2 ) + *v56 = 15; + } + if ( v12 == 22 ) + { + v57 = &dungeon[v10][v8 + 1]; + if ( *v57 == 2 ) + *v57 = 15; + } + if ( v12 == 21 ) + { + v58 = &dungeon[v10 + 1][v8]; + if ( *v58 == 18 && dungeon[v10 + 2][v8] == 30 ) + *v58 = 24; + v59 = &dungeon[v10 + 1][v8]; + if ( *v59 == 9 && dungeon[v10 + 1][v8 + 1] == 1 ) + *v59 = 16; + } + if ( v12 == 2 ) + { + v60 = &dungeon[v10 + 1][v8]; + if ( *v60 == 27 && dungeon[v10 + 1][v8 + 1] == 2 ) + *v60 = 29; + } + if ( v12 == 23 ) + { + v61 = &dungeon[v10][v8 + 1]; + if ( *v61 == 2 ) + *v61 = 15; + v62 = &dungeon[v10][v8 + 1]; + if ( *v62 == 9 ) + *v62 = 15; + } + if ( v12 == 25 ) + { + v63 = &dungeon[v10][v8 + 1]; + if ( *v63 == 2 ) + *v63 = 15; + } + if ( v12 == 22 ) + { + v64 = &dungeon[v10 + 1][v8]; + if ( *v64 == 9 ) + *v64 = 11; + } + if ( v12 == 23 ) + { + v65 = &dungeon[v10 + 1][v8]; + if ( *v65 == 9 ) + *v65 = 11; + } + if ( v12 == 15 ) + { + v66 = &dungeon[v10 + 1][v8]; + if ( *v66 == 1 ) + *v66 = 16; + } + if ( v12 == 11 ) + { + v67 = &dungeon[v10 + 1][v8]; + if ( *v67 == 15 ) + *v67 = 14; + } + if ( v12 == 23 ) + { + v68 = &dungeon[v10 + 1][v8]; + if ( *v68 == 1 ) + *v68 = 16; + } + if ( v12 == 21 ) + { + v69 = &dungeon[v10 + 1][v8]; + if ( *v69 == 27 ) + *v69 = 26; + v70 = &dungeon[v10 + 1][v8]; + if ( *v70 == 18 ) + *v70 = 24; + } + if ( v12 == 26 ) + { + v71 = &dungeon[v10 + 1][v8]; + if ( *v71 == 1 ) + *v71 = 16; + } + if ( v12 == 29 ) + { + v72 = &dungeon[v10 + 1][v8]; + if ( *v72 == 1 ) + *v72 = 16; + v73 = &dungeon[v10][v8 + 1]; + if ( *v73 == 2 ) + *v73 = 15; + } + if ( v12 == 1 && *(v11 - 1) == 15 ) + *(v11 - 1) = 10; + if ( v12 == 18 ) + { + v74 = &dungeon[v10][v8 + 1]; + if ( *v74 == 2 ) + *v74 = 15; + } + if ( v12 == 23 ) + { + v75 = &dungeon[v10][v8 + 1]; + if ( *v75 == 30 ) + *v75 = 18; + } + if ( v12 == 18 ) + { + v76 = &dungeon[v10][v8 + 1]; + if ( *v76 == 9 ) + *v76 = 10; + } + if ( v12 == 14 ) + { + v77 = &dungeon[v10 + 1][v8]; + if ( *v77 == 30 && dungeon[v10 + 1][v8 + 1] == 30 ) + *v77 = 23; + } + if ( v12 == 2 ) + { + v78 = &dungeon[v10 + 1][v8]; + if ( *v78 == 28 && dungeon[v10][v8 + 39] == 6 ) + *v78 = 23; + } + if ( v12 == 23 ) + { + v79 = &dungeon[v10 + 1][v8]; + if ( *v79 == 18 && *(v11 - 1) == 6 ) + *v79 = 24; + } + if ( v12 == 14 ) + { + v80 = &dungeon[v10 + 1][v8]; + if ( *v80 == 23 && dungeon[v10 + 2][v8] == 30 ) + *v80 = 28; + v81 = &dungeon[v10 + 1][v8]; + if ( *v81 == 28 && dungeon[v10 + 2][v8] == 30 && dungeon[v10][v8 + 39] == 6 ) + *v81 = 23; + } + if ( v12 == 23 ) + { + v82 = &dungeon[v10 + 1][v8]; + if ( *v82 == 30 ) + *v82 = 19; + } + if ( v12 == 29 ) + { + v83 = &dungeon[v10 + 1][v8]; + if ( *v83 == 30 ) + *v83 = 19; + v84 = &dungeon[v10][v8 + 1]; + if ( *v84 == 30 ) + *v84 = 18; + } + if ( v12 == 19 ) + { + v85 = &dungeon[v10 + 1][v8]; + if ( *v85 == 30 ) + *v85 = 19; + } + if ( v12 == 21 ) + { + v86 = &dungeon[v10 + 1][v8]; + if ( *v86 == 30 ) + *v86 = 19; + } + if ( v12 == 26 ) + { + v87 = &dungeon[v10 + 1][v8]; + if ( *v87 == 30 ) + *v87 = 19; + } + if ( v12 == 16 ) + { + v88 = &dungeon[v10][v8 + 1]; + if ( *v88 == 30 ) + *v88 = 18; + } + if ( v12 == 13 ) + { + v89 = &dungeon[v10][v8 + 1]; + if ( *v89 == 9 ) + *v89 = 10; + } + if ( v12 == 25 ) + { + v90 = &dungeon[v10][v8 + 1]; + if ( *v90 == 30 ) + *v90 = 18; + } + if ( v12 == 18 ) + { + v91 = &dungeon[v10][v8 + 1]; + if ( *v91 == 2 ) + *v91 = 15; + } + if ( v12 == 11 ) + { + v92 = &dungeon[v10 + 1][v8]; + if ( *v92 == 3 ) + *v92 = 5; + } + if ( v12 == 19 ) + { + v93 = &dungeon[v10 + 1][v8]; + if ( *v93 == 9 ) + *v93 = 11; + v94 = &dungeon[v10 + 1][v8]; + if ( *v94 == 1 ) + *v94 = 13; + v95 = &dungeon[v10 + 1][v8]; + if ( *v95 == 13 && dungeon[v10][v8 + 39] == 6 ) + *v95 = 16; + } + v9 = v139++ + 1; + } + while ( v139 < 40 ); + ++v8; + } + while ( v8 < 40 ); + v96 = 0; + do + { + v97 = 0; + do + { + v98 = v97; + v99 = &dungeon[v97][v96]; + v100 = *v99; + if ( *v99 == 21 ) + { + v101 = &dungeon[v98][v96 + 1]; + if ( *v101 == 24 && dungeon[v98][v96 + 2] == 1 ) + *v101 = 17; + } + if ( v100 == 15 + && dungeon[v98 + 1][v96 + 1] == 9 + && dungeon[v98][v96 + 39] == 1 + && dungeon[v98 + 2][v96] == 16 ) + { + dungeon[v98 + 1][v96] = 29; + } + if ( v100 == 2 && *(v99 - 40) == 6 ) + *(v99 - 40) = 8; + if ( v100 == 1 && *(v99 - 1) == 6 ) + *(v99 - 1) = 7; + if ( v100 == 6 ) + { + v102 = &dungeon[v98 + 1][v96]; + if ( *v102 == 15 && dungeon[v98 + 1][v96 + 1] == 4 ) + *v102 = 10; + } + if ( v100 == 1 ) + { + v103 = &dungeon[v98][v96 + 1]; + if ( *v103 == 3 ) + *v103 = 4; + v104 = &dungeon[v98][v96 + 1]; + if ( *v104 == 6 ) + *v104 = 4; + } + if ( v100 == 9 ) + { + v105 = &dungeon[v98][v96 + 1]; + if ( *v105 == 3 ) + *v105 = 4; + } + if ( v100 == 10 ) + { + v106 = &dungeon[v98][v96 + 1]; + if ( *v106 == 3 ) + *v106 = 4; + } + if ( v100 == 13 ) + { + v107 = &dungeon[v98][v96 + 1]; + if ( *v107 == 3 ) + *v107 = 4; + } + if ( v100 == 1 ) + { + v108 = &dungeon[v98][v96 + 1]; + if ( *v108 == 5 ) + *v108 = 12; + v109 = &dungeon[v98][v96 + 1]; + if ( *v109 == 16 ) + *v109 = 13; + } + if ( v100 == 6 ) + { + v110 = &dungeon[v98][v96 + 1]; + if ( *v110 == 13 ) + *v110 = 16; + } + if ( v100 == 25 ) + { + v111 = &dungeon[v98][v96 + 1]; + if ( *v111 == 9 ) + *v111 = 10; + } + if ( v100 == 13 ) + { + v112 = &dungeon[v98][v96 + 1]; + if ( *v112 == 5 ) + *v112 = 12; + } + if ( v100 == 28 && *(v99 - 1) == 6 ) + { + v113 = &dungeon[v98 + 1][v96]; + if ( *v113 == 1 ) + *v113 = 23; + } + if ( v100 == 19 ) + { + v114 = &dungeon[v98 + 1][v96]; + if ( *v114 == 10 ) + *v114 = 17; + } + if ( v100 == 21 ) + { + v115 = &dungeon[v98 + 1][v96]; + if ( *v115 == 9 ) + *v115 = 11; + } + if ( v100 == 11 ) + { + v116 = &dungeon[v98 + 1][v96]; + if ( *v116 == 3 ) + *v116 = 5; + } + if ( v100 == 10 ) + { + v117 = &dungeon[v98 + 1][v96]; + if ( *v117 == 4 ) + *v117 = 12; + } + if ( v100 == 14 ) + { + v118 = &dungeon[v98 + 1][v96]; + if ( *v118 == 4 ) + *v118 = 12; + } + if ( v100 == 27 ) + { + v119 = &dungeon[v98 + 1][v96]; + if ( *v119 == 9 ) + *v119 = 11; + } + if ( v100 == 15 ) + { + v120 = &dungeon[v98 + 1][v96]; + if ( *v120 == 4 ) + *v120 = 12; + } + if ( v100 == 21 ) + { + v121 = &dungeon[v98 + 1][v96]; + if ( *v121 == 1 ) + *v121 = 16; + } + if ( v100 == 11 ) + { + v122 = &dungeon[v98 + 1][v96]; + if ( *v122 == 4 ) + *v122 = 12; + } + if ( v100 == 2 ) + { + v123 = &dungeon[v98 + 1][v96]; + if ( *v123 == 3 ) + *v123 = 5; + } + if ( v100 == 9 ) + { + v124 = &dungeon[v98 + 1][v96]; + if ( *v124 == 3 ) + *v124 = 5; + } + if ( v100 == 14 ) + { + v125 = &dungeon[v98 + 1][v96]; + if ( *v125 == 3 ) + *v125 = 5; + } + if ( v100 == 15 ) + { + v126 = &dungeon[v98 + 1][v96]; + if ( *v126 == 3 ) + *v126 = 5; + } + if ( v100 == 2 ) + { + v127 = &dungeon[v98 + 1][v96]; + if ( *v127 == 5 && dungeon[v98][v96 + 39] == 16 ) + *v127 = 12; + v128 = &dungeon[v98 + 1][v96]; + if ( *v128 == 4 ) + *v128 = 12; + } + if ( v100 == 9 ) + { + v129 = &dungeon[v98 + 1][v96]; + if ( *v129 == 4 ) + *v129 = 12; + } + if ( v100 == 1 && *(v99 - 1) == 8 ) + *(v99 - 1) = 9; + if ( v100 == 28 ) + { + v130 = &dungeon[v98 + 1][v96]; + if ( *v130 == 23 && dungeon[v98 + 1][v96 + 1] == 3 ) + *v130 = 16; + } + ++v97; + } + while ( v97 < 40 ); + ++v96; + } + while ( v96 < 40 ); + v131 = 0; + do + { + v132 = &dungeon[0][v131 + 1]; + v133 = 40; + do + { + v134 = *(v132 - 1); + if ( v134 == 21 && v132[39] == 10 ) + v132[39] = 17; + if ( v134 == 17 && v132[39] == 4 ) + v132[39] = 12; + if ( v134 == 10 && v132[39] == 4 ) + v132[39] = 12; + if ( v134 == 17 && *v132 == 5 ) + *v132 = 12; + if ( v134 == 29 && *v132 == 9 ) + *v132 = 10; + if ( v134 == 13 && *v132 == 5 ) + *v132 = 12; + if ( v134 == 9 && *v132 == 16 ) + *v132 = 13; + if ( v134 == 10 && *v132 == 16 ) + *v132 = 13; + if ( v134 == 16 && *v132 == 3 ) + *v132 = 4; + if ( v134 == 11 && *v132 == 5 ) + *v132 = 12; + if ( v134 == 10 && v132[39] == 3 && v132[38] == 16 ) + v132[39] = 12; + if ( v134 == 16 && *v132 == 5 ) + *v132 = 12; + if ( v134 == 1 && *v132 == 6 ) + *v132 = 4; + if ( v134 == 21 && v132[39] == 13 && *v132 == 10 ) + v132[40] = 12; + if ( v134 == 15 && v132[39] == 10 ) + v132[39] = 17; + if ( v134 == 22 && *v132 == 11 ) + *v132 = 17; + if ( v134 == 15 && v132[39] == 28 && v132[79] == 16 ) + v132[39] = 23; + if ( v134 == 28 && v132[39] == 23 && v132[40] == 1 && v132[79] == 6 ) + v132[39] = 16; + v132 += 40; + --v133; + } + while ( v133 ); + ++v131; + } + while ( v131 < 40 ); + v135 = 0; + do + { + v136 = (char *)dungeon + v135; + v137 = 40; + do + { + v138 = *v136; + if ( *v136 == 15 && v136[40] == 28 && v136[80] == 16 ) + v136[40] = 23; + if ( v138 == 21 && v136[39] == 21 && v136[41] == 13 && v136[80] == 2 ) + v136[40] = 17; + if ( v138 == 19 && v136[40] == 15 && v136[41] == 12 ) + v136[40] = 17; + v136 += 40; + --v137; + } + while ( v137 ); + ++v135; + } + while ( v135 < 40 ); +} + +//----- (004142DD) -------------------------------------------------------- +void __cdecl DRLG_L4Subs() +{ + signed int v0; // edi + signed int v1; // esi + signed int v2; // ebp + unsigned char v3; // bl + int v4; // eax + signed int v5; // ecx + signed int v6; // edi + signed int v7; // esi + signed int v8; // ebx + + v0 = 0; + do + { + v1 = v0; + v2 = 40; + do + { + if ( !random(0, 3) ) + { + v3 = L4BTYPES[(unsigned char)dungeon[0][v1]]; + if ( v3 ) + { + if ( !dflags[0][v1] ) + { + v4 = random(0, 16); + v5 = -1; + while ( v4 >= 0 ) + { + if ( ++v5 == 140 ) + v5 = 0; + if ( v3 == L4BTYPES[v5] ) + --v4; + } + dungeon[0][v1] = v5; + } + } + } + v1 += 40; + --v2; + } + while ( v2 ); + ++v0; + } + while ( v0 < 40 ); + v6 = 0; + do + { + v7 = v6; + v8 = 40; + do + { + if ( !random(0, 10) && L4BTYPES[(unsigned char)dungeon[0][v7]] == 6 && !dflags[0][v7] ) + dungeon[0][v7] = random(0, 3) + 95; + v7 += 40; + --v8; + } + while ( v8 ); + ++v6; + } + while ( v6 < 40 ); +} + +//----- (0041439A) -------------------------------------------------------- +void __cdecl L4makeDungeon() +{ + signed int v0; // ebx + signed int v1; // esi + char *v2; // edx + char v3; // cl + int v4; // eax + int v5; // eax + int v6; // ebx + char *v7; // esi + signed int v8; // edx + char v9; // cl + int v10; // eax + int v11; // eax + signed int v12; // ebx + signed int v13; // esi + char *v14; // edx + char v15; // cl + int v16; // eax + int v17; // eax + int v18; // ebx + char *v19; // esi + signed int v20; // edx + char v21; // cl + int v22; // eax + int v23; // eax + signed int v24; // [esp+Ch] [ebp-8h] + char *v25; // [esp+10h] [ebp-4h] + char *v26; // [esp+10h] [ebp-4h] + + v0 = 0; + do + { + v1 = 0; + v2 = (char *)dung + v0; + do + { + v3 = *v2; + v2 += 20; + v4 = 160 * v1++; + v5 = v4 + 2 * v0; + L4dungeon[0][v5] = v3; + L4dungeon[0][v5 + 1] = v3; + L4dungeon[1][v5] = v3; + L4dungeon[1][v5 + 1] = v3; + } + while ( v1 < 20 ); + ++v0; + } + while ( v0 < 20 ); + v6 = 0; + v25 = &dung[0][19]; + v24 = 20; + do + { + v7 = v25; + v8 = 0; + do + { + v9 = *v7; + v7 += 20; + v10 = 160 * v8++; + v11 = v10 + 2 * v6; + L4dungeon[0][v11 + 40] = v9; + L4dungeon[0][v11 + 41] = v9; + L4dungeon[1][v11 + 40] = v9; + L4dungeon[1][v11 + 41] = v9; + } + while ( v8 < 20 ); + ++v6; + --v25; + --v24; + } + while ( v24 ); + v12 = 0; + do + { + v13 = 0; + v14 = &dung[19][v12]; + do + { + v15 = *v14; + v14 -= 20; + v16 = 160 * v13++; + v17 = v16 + 2 * v12; + L4dungeon[40][v17] = v15; + L4dungeon[40][v17 + 1] = v15; + L4dungeon[41][v17] = v15; + L4dungeon[41][v17 + 1] = v15; + } + while ( v13 < 20 ); + ++v12; + } + while ( v12 < 20 ); + v18 = 0; + v26 = &dung[19][19]; + do + { + v19 = v26; + v20 = 0; + do + { + v21 = *v19; + v19 -= 20; + v22 = 160 * v20++; + v23 = v22 + 2 * v18; + L4dungeon[40][v23 + 40] = v21; + L4dungeon[40][v23 + 41] = v21; + L4dungeon[41][v23 + 40] = v21; + L4dungeon[41][v23 + 41] = v21; + } + while ( v20 < 20 ); + ++v18; + --v26; + } + while ( (signed int)v26 > (signed int)&dung[18][19] ); +} + +//----- (004144B1) -------------------------------------------------------- +void __cdecl uShape() +{ + int v0; // ecx + signed int v1; // esi + signed int v2; // eax + char v3; // dl + int v4; // eax + signed int v5; // esi + int v6; // ecx + int v7; // ecx + int *v8; // esi + signed int v9; // eax + char v10; // dl + int v11; // eax + signed int v12; // esi + char *v13; // edx + + v0 = 19; + do + { + v1 = 19; + do + { + v2 = v1; + v3 = dung[v1][v0]; + if ( v3 == 1 || (hallok[v0] = 0, v3 == 1) ) + { + hallok[v0] = dung[v2][v0 + 1] == 1 && !dung[v2 + 1][v0 + 1]; + v1 = 0; + } + --v1; + } + while ( v1 >= 0 ); + --v0; + } + while ( v0 >= 0 ); + _LOBYTE(v0) = 0; + v4 = random(v0, 19) + 1; + do + { + if ( hallok[v4] ) + { + v5 = 19; + do + { + v6 = v4 + 20 * v5; + if ( dung[0][v6] == 1 ) + { + v5 = -1; + v4 = 0; + } + else + { + dung[0][v6] = 1; + dung[0][v6 + 1] = 1; + } + --v5; + } + while ( v5 >= 0 ); + } + else if ( ++v4 == 20 ) + { + v4 = 1; + } + } + while ( v4 ); + v7 = 380; + v8 = &hallok[19]; + do + { + v9 = 19; + do + { + v10 = dung[0][v7 + v9]; + if ( v10 == 1 || (*v8 = 0, v10 == 1) ) + { + *v8 = dung[1][v7 + v9] == 1 && !dung[1][v7 + 1 + v9]; + v9 = 0; + } + --v9; + } + while ( v9 >= 0 ); + --v8; + v7 -= 20; + } + while ( (signed int)v8 >= (signed int)hallok ); + _LOBYTE(v7) = 0; + v11 = random(v7, 19) + 1; + do + { + if ( hallok[v11] ) + { + v12 = 19; + do + { + v13 = &dung[v11][v12]; + if ( *v13 == 1 ) + { + v12 = -1; + v11 = 0; + } + else + { + *v13 = 1; + dung[v11 + 1][v12] = 1; + } + --v12; + } + while ( v12 >= 0 ); + } + else if ( ++v11 == 20 ) + { + v11 = 1; + } + } + while ( v11 ); +} + +//----- (004145E4) -------------------------------------------------------- +int __cdecl GetArea() +{ + int result; // eax + signed int v1; // edx + _BYTE *v2; // ecx + signed int v3; // esi + + result = 0; + v1 = 0; + do + { + v2 = (unsigned char *)dung + v1; + v3 = 20; + do + { + if ( *v2 == 1 ) + ++result; + v2 += 20; + --v3; + } + while ( v3 ); + ++v1; + } + while ( v1 < 20 ); + return result; +} + +//----- (00414606) -------------------------------------------------------- +void __cdecl L4firstRoom() +{ + int v0; // esi + int v1; // edi + int v2; // ebx + int v3; // eax + int v4; // eax + int v5; // ebp + int v6; // eax + int v7; // eax + int v8; // eax + signed int v9; // [esp-4h] [ebp-18h] + + if ( currlevel == 16 ) + { + v9 = 14; + } + else + { + if ( (currlevel != quests[11]._qlevel || !quests[11]._qactive) + && (currlevel != quests[15]._qlevel || gbMaxPlayers == 1) ) + { + v0 = random(0, 5) + 2; + v1 = random(0, 5) + 2; + goto LABEL_10; + } + v9 = 11; + } + v1 = v9; + v0 = v9; +LABEL_10: + v2 = 20 - v0; + v3 = ((20 - v0) >> 1) + random(0, 20 - ((20 - v0) >> 1) - v0); + if ( v3 + v0 <= 19 ) + v2 = v3; + v4 = ((20 - v1) >> 1) + random(0, 20 - ((20 - v1) >> 1) - v1); + v5 = 20 - v1; + if ( v4 + v1 <= 19 ) + v5 = v4; + if ( currlevel == 16 ) + { + l4holdx = v2; + l4holdy = v5; + } + _LOBYTE(v6) = QuestStatus(11); + if ( v6 || currlevel == quests[15]._qlevel && gbMaxPlayers != 1 ) + { + SP4x1 = v2 + 1; + SP4y1 = v5 + 1; + v7 = v0 + v2 + 1; + SP4y2 = v1 + v5 + 1; + } + else + { + v7 = 0; + SP4x1 = 0; + SP4y1 = 0; + SP4y2 = 0; + } + SP4x2 = v7; + L4drawRoom(v2, v5, v0, v1); + v8 = random(0, 2); + L4roomGen(v2, v5, v0, v1, v8); +} +// 528A34: using guessed type int l4holdx; +// 528A38: using guessed type int l4holdy; +// 528A40: using guessed type int SP4x2; +// 528A48: using guessed type int SP4y2; +// 679660: using guessed type char gbMaxPlayers; + +//----- (00414738) -------------------------------------------------------- +void __fastcall L4drawRoom(int x, int y, int width, int height) +{ + int i; // esi + int v5; // edi + char *v6; // eax + + for ( i = 0; i < height; ++i ) + { + if ( width > 0 ) + { + v5 = width; + v6 = &dung[x][i + y]; + do + { + *v6 = 1; + v6 += 20; + --v5; + } + while ( v5 ); + } + } +} + +//----- (0041476F) -------------------------------------------------------- +void __fastcall L4roomGen(int x, int y, int w, int h, int dir) +{ + int v5; // eax + int v6; // ecx + int v7; // eax + int v8; // ecx + int v9; // eax + int v10; // ecx + int v11; // esi + int v12; // edi + int v13; // ebx + int v14; // eax + int v15; // eax + int v16; // ecx + int v17; // esi + int v18; // edi + int v19; // ebx + int v20; // eax + int ya; // [esp+Ch] [ebp-10h] + int yb; // [esp+Ch] [ebp-10h] + int v23; // [esp+10h] [ebp-Ch] + int v24; // [esp+10h] [ebp-Ch] + int xa; // [esp+14h] [ebp-8h] + int xb; // [esp+14h] [ebp-8h] + int v27; // [esp+18h] [ebp-4h] + int wa; // [esp+24h] [ebp+8h] + int ha; // [esp+28h] [ebp+Ch] + int hb; // [esp+28h] [ebp+Ch] + int hc; // [esp+28h] [ebp+Ch] + int dira; // [esp+2Ch] [ebp+10h] + int dirb; // [esp+2Ch] [ebp+10h] + + v27 = y; + xa = x; + while ( 1 ) + { + while ( 1 ) + { + _LOBYTE(x) = 0; + v5 = random(x, 4); + v6 = 0; + _LOBYTE(v6) = dir == 1 ? v5 != 0 : v5 == 0; + v7 = v6; + v8 = 0; + if ( !v7 ) + break; + if ( v7 != 1 ) + return; + dira = 0; + wa = w / 2; + do + { + _LOBYTE(v8) = 0; + v9 = random(v8, 5); + _LOBYTE(v10) = 0; + v11 = (v9 + 2) & 0xFFFFFFFE; + v12 = (random(v10, 5) + 2) & 0xFFFFFFFE; + v13 = xa + wa - v11 / 2; + ya = v27 - v12; + v14 = L4checkRoom(v13 - 1, v27 - v12 - 1, v11 + 2, v12 + 1); + ++dira; + v23 = v14; + } + while ( !v14 && dira < 20 ); + if ( v14 == 1 ) + L4drawRoom(v13, ya, v11, v12); + xb = v27 + h; + ha = L4checkRoom(v13 - 1, v27 + h, v11 + 2, v12 + 1); + if ( ha == 1 ) + L4drawRoom(v13, xb, v11, v12); + if ( v23 == 1 ) + L4roomGen(v13, ya, v11, v12, 0); + if ( ha != 1 ) + return; + dir = 0; + h = v12; + w = v11; + v27 = xb; + xa = v13; + } + dirb = 0; + hb = h / 2; + do + { + _LOBYTE(v8) = 0; + v15 = random(v8, 5); + _LOBYTE(v16) = 0; + v17 = (v15 + 2) & 0xFFFFFFFE; + v18 = (random(v16, 5) + 2) & 0xFFFFFFFE; + v19 = v27 + hb - v18 / 2; + yb = xa - v17; + v20 = L4checkRoom(xa - v17 - 1, v19 - 1, v18 + 2, v17 + 1); + ++dirb; + v24 = v20; + } + while ( !v20 && dirb < 20 ); + if ( v20 == 1 ) + L4drawRoom(yb, v19, v17, v18); + xa += w; + hc = L4checkRoom(xa, v19 - 1, v17 + 1, v18 + 2); + if ( hc == 1 ) + L4drawRoom(xa, v19, v17, v18); + if ( v24 == 1 ) + L4roomGen(yb, v19, v17, v18, 1); + if ( hc != 1 ) + break; + dir = 1; + h = v18; + w = v17; + v27 = v19; + } +} + +//----- (00414976) -------------------------------------------------------- +int __fastcall L4checkRoom(int x, int y, int width, int height) +{ + int v4; // esi + int v5; // ebx + char *v6; // edi + int v8; // [esp+Ch] [ebp-4h] + + v4 = 0; + if ( x > 0 && y > 0 ) + { + if ( height <= 0 ) + return 1; + while ( 1 ) + { + v8 = 0; + if ( width > 0 ) + break; +LABEL_12: + if ( ++v4 >= height ) + return 1; + } + v5 = x; + v6 = &dung[x][v4 + y]; + while ( v5 >= 0 && v5 < 20 && v4 + y >= 0 && v4 + y < 20 && !*v6 ) + { + ++v8; + v6 += 20; + ++v5; + if ( v8 >= width ) + goto LABEL_12; + } + } + return 0; +} + +//----- (004149E2) -------------------------------------------------------- +unsigned char __fastcall DRLG_L4PlaceMiniSet(unsigned char *miniset, int tmin, int tmax, int cx, int cy, int setview, int ldir) +{ + int v7; // ebx + int v8; // esi + int v9; // edi + int v10; // edx + int v11; // eax + int v12; // ecx + int v13; // esi + int v14; // ebx + int v15; // ecx + int v16; // eax + int v17; // ecx + int v18; // eax + int v19; // ecx + int v20; // edi + signed int i; // eax + int v22; // ecx + unsigned char v23; // dl + int v24; // eax + int v25; // edi + int v26; // edx + unsigned char v27; // bl + unsigned char result; // al + unsigned char *v29; // [esp+Ch] [ebp-28h] + int v30; // [esp+10h] [ebp-24h] + int v31; // [esp+14h] [ebp-20h] + int v32; // [esp+18h] [ebp-1Ch] + signed int v33; // [esp+1Ch] [ebp-18h] + int v34; // [esp+20h] [ebp-14h] + int v35; // [esp+24h] [ebp-10h] + int v36; // [esp+28h] [ebp-Ch] + int max; // [esp+2Ch] [ebp-8h] + int v38; // [esp+30h] [ebp-4h] + int v39; // [esp+30h] [ebp-4h] + int tmaxa; // [esp+3Ch] [ebp+8h] + + v7 = miniset[1]; + v8 = tmin; + v9 = *miniset; + v29 = miniset; + v10 = tmax - tmin; + v34 = *miniset; + v35 = miniset[1]; + if ( v10 ) + { + _LOBYTE(miniset) = 0; + v30 = v8 + random((int)miniset, v10); + } + else + { + v30 = 1; + } + v31 = 0; + if ( v30 <= 0 ) + { + v13 = tmax; + v14 = v38; + } + else + { + max = 40 - v9; + v36 = 40 - v7; + do + { + _LOBYTE(miniset) = 0; + v11 = random((int)miniset, max); + _LOBYTE(v12) = 0; + v13 = v11; + v33 = 0; + v14 = random(v12, v36); + v39 = v14; + do + { + if ( v33 >= 200 ) + return 0; + tmaxa = 1; + if ( v13 >= SP4x1 && v13 <= SP4x2 && v14 >= SP4y1 && v14 <= SP4y2 ) + tmaxa = 0; + if ( cx != -1 ) + { + v15 = cx - v34; + if ( v13 >= cx - v34 && v13 <= cx + 12 ) + { + _LOBYTE(v15) = 0; + v16 = random(v15, max); + _LOBYTE(v17) = 0; + v13 = v16; + tmaxa = 0; + v39 = random(v17, v36); + v14 = v39; + } + } + if ( cy != -1 && v14 >= cy - v35 && v14 <= cy + 12 ) + { + v18 = random(cy - v35, max); + _LOBYTE(v19) = 0; + v13 = v18; + tmaxa = 0; + v39 = random(v19, v36); + v14 = v39; + } + v20 = 0; + for ( i = 2; v20 < v35; ++v20 ) + { + if ( tmaxa != 1 ) + break; + v32 = 0; + if ( v34 > 0 ) + { + v22 = v14 + v20 + 40 * v13; + do + { + if ( tmaxa != 1 ) + break; + v23 = v29[i]; + if ( v23 && dungeon[0][v22] != v23 ) + tmaxa = 0; + if ( dflags[0][v22] ) + tmaxa = 0; + ++i; + ++v32; + v22 += 40; + } + while ( v32 < v34 ); + } + } + if ( !tmaxa && ++v13 == max ) + { + v13 = 0; + v39 = ++v14; + if ( v14 == v36 ) + { + v39 = 0; + v14 = 0; + } + } + ++v33; + } + while ( !tmaxa ); + if ( v33 >= 200 ) + return 0; + v24 = 0; + for ( miniset = (unsigned char *)(v34 * v35 + 2); v24 < v35; ++v24 ) + { + v25 = v34; + if ( v34 > 0 ) + { + v26 = v14 + v24 + 40 * v13; + do + { + v27 = v29[(_DWORD)miniset]; + if ( v27 ) + { + dflags[0][v26] |= 8u; + dungeon[0][v26] = v27; + } + ++miniset; + v26 += 40; + --v25; + } + while ( v25 ); + v14 = v39; + } + } + ++v31; + } + while ( v31 < v30 ); + } + if ( currlevel == 15 ) + { + quests[15]._qtx = v13 + 1; + quests[15]._qty = v14 + 1; + } + result = 1; + if ( setview == 1 ) + { + ViewX = 2 * v13 + 21; + ViewY = 2 * v14 + 22; + } + if ( !ldir ) + { + LvlViewX = 2 * v13 + 21; + LvlViewY = 2 * v14 + 22; + } + return result; +} +// 528A40: using guessed type int SP4x2; +// 528A48: using guessed type int SP4y2; +// 5CF320: using guessed type int LvlViewY; +// 5CF324: using guessed type int LvlViewX; + +//----- (00414C44) -------------------------------------------------------- +void __cdecl DRLG_L4FloodTVal() +{ + int v0; // ebx + int v1; // esi + char *v2; // edi + _BYTE *v3; // [esp+Ch] [ebp-Ch] + signed int x; // [esp+10h] [ebp-8h] + signed int i; // [esp+14h] [ebp-4h] + + v0 = 16; + v1 = 0; + do + { + i = 0; + x = 16; + v2 = &dung_map[16][v0]; + v3 = (unsigned char *)dungeon + v1; + do + { + if ( *v3 == 6 && !*v2 ) + { + DRLG_L4FTVR(i, v1, x, v0, 0); + ++TransVal; + } + x += 2; + v3 += 40; + v2 += 224; + ++i; + } + while ( i < 40 ); + v0 += 2; + ++v1; + } + while ( v1 < 40 ); +} +// 5A5590: using guessed type char TransVal; + +//----- (00414CB3) -------------------------------------------------------- +void __fastcall DRLG_L4FTVR(int i, int j, int x, int y, int d) +{ + int v5; // ebx + int v6; // esi + int v7; // edi + int v8; // edx + int v9; // ecx + int v10; // ebx + int v11; // eax + int v12; // edi + char v13; // al + char v14; // al + int v15; // ecx + int v16; // ecx + int v17; // ecx + int v18; // ecx + int v19; // [esp+Ch] [ebp-14h] + int k; // [esp+10h] [ebp-10h] + int v21; // [esp+14h] [ebp-Ch] + int ja; // [esp+18h] [ebp-8h] + int ia; // [esp+1Ch] [ebp-4h] + int ya; // [esp+2Ch] [ebp+Ch] + + v5 = x; + v6 = y; + v7 = j; + v8 = i; + v9 = 112 * x + y; + ja = v7; + v21 = v8; + if ( !dung_map[0][v9] ) + { + v19 = x; + ia = v8 - 1; + v10 = x - 2; + v11 = 40 * v8; + ya = v7 - 1; + v12 = v6 - 2; + for ( k = 40 * v8; dungeon[0][v11 + ja] == 6; v11 = k ) + { + v13 = TransVal; + dung_map[0][v9] = TransVal; + dung_map[1][v9] = v13; + dung_map[0][v9 + 1] = v13; + dung_map[1][v9 + 1] = v13; + DRLG_L4FTVR(ia + 2, ja, v10 + 4, v6, 1); + DRLG_L4FTVR(ia, ja, v10, v6, 2); + DRLG_L4FTVR(v21, ya + 2, x, v12 + 4, 3); + DRLG_L4FTVR(v21, ya, x, v12, 4); + DRLG_L4FTVR(ia, ya, v10, v12, 5); + DRLG_L4FTVR(ia + 2, ya, v10 + 4, v12, 6); + DRLG_L4FTVR(ia, ya + 2, v10, v12 + 4, 7); + v19 += 2; + k += 40; + d = 8; + x += 2; + v6 += 2; + v12 += 2; + v10 += 2; + ++ja; + ++ya; + ++v21; + ++ia; + v9 = v19 * 112 + v6; + if ( dung_map[v19][v6] ) + break; + } + v5 = x; + } + v14 = TransVal; + if ( d == 1 ) + { + v15 = v6 + 112 * v5; + dung_map[0][v15] = TransVal; + dung_map[0][v15 + 1] = v14; + } + if ( d == 2 ) + { + v16 = v6 + 112 * v5; + dung_map[1][v16] = v14; + dung_map[1][v16 + 1] = v14; + } + if ( d == 3 ) + { + v17 = v6 + 112 * v5; + dung_map[0][v17] = v14; + dung_map[1][v17] = v14; + } + if ( d == 4 ) + { + v18 = v6 + 112 * v5; + dung_map[0][v18 + 1] = v14; + dung_map[1][v18 + 1] = v14; + } + if ( d == 5 ) + dung_map[v5 + 1][v6 + 1] = v14; + if ( d == 6 ) + dung_map[v5][v6 + 1] = v14; + if ( d == 7 ) + dung_map[v5 + 1][v6] = v14; + if ( d == 8 ) + dung_map[v5][v6] = v14; +} +// 5A5590: using guessed type char TransVal; + +//----- (00414EA3) -------------------------------------------------------- +void __cdecl DRLG_L4TransFix() +{ + signed int v0; // edi + char *v1; // esi + signed int v2; // ebx + int v3; // eax + _BYTE *v4; // edx + char v5; // cl + char v6; // al + int v7; // eax + _BYTE *v8; // edx + char v9; // cl + char v10; // al + char v11; // al + char v12; // al + char v13; // al + char v14; // al + char v15; // al + char *v16; // [esp+Ch] [ebp-4h] + + v0 = 0; + v16 = &dung_map[17][17]; + do + { + v1 = (char *)dungeon + v0; + v2 = 40; + do + { + _LOBYTE(v3) = IsDURWall(*v1); + if ( v3 && *(v1 - 1) == 18 ) + { + v6 = *(v4 - 113); + *(v4 - 1) = v6; + *v4 = v6; + } + _LOBYTE(v7) = IsDLLWall(v5); + if ( v7 && v1[40] == 19 ) + { + v10 = *(v8 - 113); + *(v8 - 112) = v10; + *v8 = v10; + } + if ( v9 == 18 ) + { + v11 = *(v8 - 113); + *(v8 - 1) = v11; + *v8 = v11; + } + if ( v9 == 19 ) + { + v12 = *(v8 - 113); + *(v8 - 112) = v12; + *v8 = v12; + } + if ( v9 == 24 ) + { + v13 = *(v8 - 113); + *(v8 - 1) = v13; + *(v8 - 112) = v13; + *v8 = v13; + } + if ( v9 == 57 ) + { + v14 = *(v8 - 112); + *(v8 - 225) = v14; + *(v8 - 113) = v14; + } + if ( v9 == 53 ) + { + v15 = *(v8 - 1); + *(v8 - 114) = v15; + *(v8 - 113) = v15; + } + v1 += 40; + --v2; + } + while ( v2 ); + v16 += 2; + ++v0; + } + while ( v0 < 40 ); +} + +//----- (00414F5B) -------------------------------------------------------- +void __cdecl DRLG_L4Corners() +{ + signed int v0; // edx + char *v1; // ecx + signed int v2; // esi + char v3; // al + + v0 = 1; + do + { + v1 = &dungeon[1][v0]; + v2 = 38; + do + { + v3 = *v1; + if ( (unsigned char)*v1 >= 0x12u + && (unsigned char)v3 <= 0x1Eu + && ((unsigned char)v1[40] < 0x12u || (unsigned char)v1[1] < 0x12u) ) + { + *v1 = v3 + 98; + } + v1 += 40; + --v2; + } + while ( v2 ); + ++v0; + } + while ( v0 < 39 ); +} + +//----- (00414F90) -------------------------------------------------------- +void __cdecl DRLG_L4Pass3() +{ + int v0; // eax + int *v1; // esi + int *v2; // eax + signed int v3; // ecx + signed int v4; // ebx + int *v5; // ecx + unsigned char *v6; // edi + unsigned short *v7; // esi + unsigned short v8; // ax + int v9; // eax + signed int v10; // [esp+Ch] [ebp-1Ch] + int *v11; // [esp+10h] [ebp-18h] + int v12; // [esp+14h] [ebp-14h] + int v13; // [esp+18h] [ebp-10h] + int v14; // [esp+18h] [ebp-10h] + int v15; // [esp+1Ch] [ebp-Ch] + int v16; // [esp+1Ch] [ebp-Ch] + int v17; // [esp+20h] [ebp-8h] + int v18; // [esp+20h] [ebp-8h] + int v19; // [esp+24h] [ebp-4h] + int v20; // [esp+24h] [ebp-4h] + + v0 = *((unsigned short *)pMegaTiles + 116) + 1; + v19 = *((unsigned short *)pMegaTiles + 116) + 1; + _LOWORD(v0) = *((_WORD *)pMegaTiles + 117); + v17 = ++v0; + _LOWORD(v0) = *((_WORD *)pMegaTiles + 118); + v15 = ++v0; + _LOWORD(v0) = *((_WORD *)pMegaTiles + 119); + v13 = v0 + 1; + v1 = dPiece[1]; + do + { + v2 = v1; + v3 = 56; + do + { + *(v2 - 112) = v19; + *v2 = v17; + *(v2 - 111) = v15; + v2[1] = v13; + v2 += 224; + --v3; + } + while ( v3 ); + v1 += 2; + } + while ( (signed int)v1 < (signed int)dPiece[2] ); + v4 = 0; + v11 = &dPiece[17][16]; + do + { + v5 = v11; + v6 = (unsigned char *)dungeon + v4; + v10 = 40; + do + { + v12 = *v6 - 1; + if ( v12 < 0 ) + { + v20 = 0; + v18 = 0; + v16 = 0; + v14 = 0; + } + else + { + v7 = (unsigned short *)((char *)pMegaTiles + 8 * v12); + v8 = *v7; + ++v7; + v9 = v8 + 1; + v20 = v9; + _LOWORD(v9) = *v7; + ++v7; + v18 = ++v9; + _LOWORD(v9) = *v7; + v16 = ++v9; + _LOWORD(v9) = v7[1]; + v14 = v9 + 1; + } + v6 += 40; + *(v5 - 112) = v20; + *v5 = v18; + *(v5 - 111) = v16; + v5[1] = v14; + v5 += 224; + --v10; + } + while ( v10 ); + v11 += 2; + ++v4; + } + while ( v4 < 40 ); +} + +//----- (0041509D) -------------------------------------------------------- +void __cdecl dthread_cpp_init_1() +{ + dthread_cpp_init_value = dthread_inf; +} +// 47A460: using guessed type int dthread_inf; +// 52A4E0: using guessed type int dthread_cpp_init_value; + +//----- (004150A8) -------------------------------------------------------- +void __cdecl dthread_cpp_init_2() +{ + dthread_init_mutex(); + dthread_cleanup_mutex_atexit(); +} + +//----- (004150B2) -------------------------------------------------------- +void __cdecl dthread_init_mutex() +{ + InitializeCriticalSection(&CriticalSection); +} + +//----- (004150BE) -------------------------------------------------------- +void __cdecl dthread_cleanup_mutex_atexit() +{ + atexit(dthread_cleanup_mutex); +} + +//----- (004150CA) -------------------------------------------------------- +void __cdecl dthread_cleanup_mutex() +{ + DeleteCriticalSection(&CriticalSection); +} + +//----- (004150D6) -------------------------------------------------------- +void __fastcall dthread_remove_player(int player_num) +{ + int v1; // edi + _DWORD *i; // eax + + v1 = player_num; + EnterCriticalSection(&CriticalSection); + for ( i = (_DWORD *)sgpInfoHead; i; i = (_DWORD *)*i ) + { + if ( i[1] == v1 ) + i[1] = 4; + } + LeaveCriticalSection(&CriticalSection); +} + +//----- (00415109) -------------------------------------------------------- +void __fastcall dthread_send_delta(int player_num, int cmd, void *src, int len) +{ + char v4; // bl + _DWORD *v5; // eax + int v6; // esi + int *v7; // eax + int *v8; // ecx + int v9; // [esp+4h] [ebp-4h] + + v4 = cmd; + v9 = player_num; + if ( gbMaxPlayers != 1 ) + { + v5 = (unsigned int *)DiabloAllocPtr(len + 20); + v6 = (int)v5; + *v5 = 0; + v5[1] = v9; + *((_BYTE *)v5 + 8) = v4; + v5[3] = len; + memcpy(v5 + 4, src, len); + EnterCriticalSection(&CriticalSection); + v7 = (int *)sgpInfoHead; + v8 = &sgpInfoHead; + while ( v7 ) + { + v8 = v7; + v7 = (int *)*v7; + } + *v8 = v6; + SetEvent(sghWorkToDoEvent); + LeaveCriticalSection(&CriticalSection); + } +} +// 679660: using guessed type char gbMaxPlayers; + +//----- (00415186) -------------------------------------------------------- +void __cdecl dthread_start() +{ + char *v0; // eax + char *v1; // eax + + if ( gbMaxPlayers != 1 ) + { + sghWorkToDoEvent = CreateEventA(0, 1, 0, 0); + if ( !sghWorkToDoEvent ) + { + v0 = GetLastErr(); + TermMsg("dthread:1\n%s", v0); + } + byte_52A508 = 1; + sghThread = (HANDLE)_beginthreadex(0, 0, dthread_handler, 0, 0, &ThreadId); + if ( sghThread == (HANDLE)-1 ) + { + v1 = GetLastErr(); + TermMsg("dthread2:\n%s", v1); + } + } +} +// 52A508: using guessed type char byte_52A508; +// 679660: using guessed type char gbMaxPlayers; + +//----- (004151F3) -------------------------------------------------------- +unsigned int __stdcall dthread_handler(void *a1) +{ + char *v1; // eax + int v2; // esi + int v3; // ecx + unsigned int v4; // edi + + while ( byte_52A508 ) + { + if ( !sgpInfoHead && WaitForSingleObject(sghWorkToDoEvent, 0xFFFFFFFF) == -1 ) + { + v1 = GetLastErr(); + TermMsg("dthread4:\n%s", v1); + } + EnterCriticalSection(&CriticalSection); + v2 = sgpInfoHead; + if ( sgpInfoHead ) + sgpInfoHead = *(_DWORD *)sgpInfoHead; + else + ResetEvent(sghWorkToDoEvent); + LeaveCriticalSection(&CriticalSection); + if ( v2 ) + { + v3 = *(_DWORD *)(v2 + 4); + if ( v3 != 4 ) + multi_send_zero_packet(v3, *(_BYTE *)(v2 + 8), (void *)(v2 + 16), *(_DWORD *)(v2 + 12)); + v4 = 1000 * *(_DWORD *)(v2 + 12) / (unsigned int)gdwDeltaBytesSec; + if ( v4 >= 1 ) + v4 = 1; + mem_free_dbg((void *)v2); + if ( v4 ) + Sleep(v4); + } + } + return 0; +} +// 52A508: using guessed type char byte_52A508; +// 679730: using guessed type int gdwDeltaBytesSec; + +//----- (004152C0) -------------------------------------------------------- +void __cdecl dthread_cleanup() +{ + char *v0; // eax + int *v1; // eax + int v2; // esi + + if ( sghWorkToDoEvent ) + { + byte_52A508 = 0; + SetEvent(sghWorkToDoEvent); + if ( sghThread != (HANDLE)-1 && ThreadId != GetCurrentThreadId() ) + { + if ( WaitForSingleObject(sghThread, 0xFFFFFFFF) == -1 ) + { + v0 = GetLastErr(); + TermMsg("dthread3:\n(%s)", v0); + } + CloseHandle(sghThread); + sghThread = (HANDLE)-1; + } + CloseHandle(sghWorkToDoEvent); + v1 = (int *)sgpInfoHead; + sghWorkToDoEvent = 0; + if ( sgpInfoHead ) + { + do + { + v2 = *v1; + sgpInfoHead = 0; + mem_free_dbg(v1); + v1 = (int *)v2; + sgpInfoHead = v2; + } + while ( v2 ); + } + } +} +// 52A508: using guessed type char byte_52A508; + +//----- (00415367) -------------------------------------------------------- +void __cdecl dx_cpp_init_1() +{ + dx_cpp_init_value = dx_inf; +} +// 47A464: using guessed type int dx_inf; +// 52A514: using guessed type int dx_cpp_init_value; + +//----- (00415372) -------------------------------------------------------- +void __cdecl dx_cpp_init_2() +{ + dx_init_mutex(); + dx_cleanup_mutex_atexit(); +} + +//----- (0041537C) -------------------------------------------------------- +void __cdecl dx_init_mutex() +{ + InitializeCriticalSection(&stru_52A530); +} + +//----- (00415388) -------------------------------------------------------- +void __cdecl dx_cleanup_mutex_atexit() +{ + atexit(dx_cleanup_mutex); +} + +//----- (00415394) -------------------------------------------------------- +void __cdecl dx_cleanup_mutex() +{ + DeleteCriticalSection(&stru_52A530); +} + +//----- (004153A0) -------------------------------------------------------- +void __fastcall dx_init(HWND hWnd) +{ + HWND v1; // esi + GUID *v2; // ecx + int v3; // eax + int v4; // eax + int v5; // ecx + int v6; // edi + int v7; // eax + int v8; // eax + HWND hWnda; // [esp+1Ch] [ebp-4h] + + v1 = hWnd; + hWnda = hWnd; + SetFocus(hWnd); + ShowWindow(v1, 1); + v2 = 0; + if ( gbEmulate ) + v2 = (GUID *)2; + v3 = dx_DirectDrawCreate(v2, (IDirectDraw **)&lpDDPPrimary, 0); + if ( v3 ) + TermDlg(104, v3, "C:\\Src\\Diablo\\Source\\dx.cpp", 149); + exclusive = 1; + v4 = IDirectDrawPalette_SetEntries( + (IDirectDrawPalette *)lpDDPPrimary, + (unsigned long)v1, + 19, 0, 0); + if ( v4 == -2005532091 ) + { + MI_Dummy(v5); + } + else if ( v4 ) + { + TermDlg(104, v4, "C:\\Src\\Diablo\\Source\\dx.cpp", 170); + } + int xyz=640; + if ( lpDDPPrimary->QueryInterface( + (const struct _GUID &)xyz, + (void **)480) ) + { + v6 = GetSystemMetrics(0); + v7 = GetSystemMetrics(1); + v8 = lpDDPPrimary->QueryInterface( + (const struct _GUID &)v6, + (void **)v7); + if ( v8 ) + TermDlg(104, v8, "C:\\Src\\Diablo\\Source\\dx.cpp", 183); + } + dx_create_primary_surface(); + palette_init(); + GdiSetBatchLimit(1u); + dx_create_back_buffer(); + SDrawManualInitialize(hWnda, (IDirectDraw *)lpDDPPrimary, lpDDSPrimary, 0, 0, lpDDSBackBuf, (IDirectDrawPalette *)lpDDPRed, 0); +} +// 484364: using guessed type int exclusive; +// 52A549: using guessed type char gbEmulate; + +//----- (004154B5) -------------------------------------------------------- +void __cdecl dx_create_back_buffer() +{ + int v0; // eax + int v1; // eax + int v2; // eax + int v3; // eax + int v4; // [esp+Ch] [ebp-70h] + int v5; // [esp+10h] [ebp-6Ch] + int v6; // [esp+14h] [ebp-68h] + int v7; // [esp+18h] [ebp-64h] + int v8[14]; // [esp+1Ch] [ebp-60h] + int v9[8]; // [esp+54h] [ebp-28h] + int v10; // [esp+74h] [ebp-8h] + char v11; // [esp+78h] [ebp-4h] + + v0 = IDirectDrawSurface_GetCaps(lpDDSPrimary, (LPDDSCAPS)&v11); + if ( v0 ) + DDErrDlg(v0, 59, "C:\\Src\\Diablo\\Source\\dx.cpp"); + if ( !gbBackBuf ) + { + v4 = 108; + v1 = IDirectDrawSurface_Lock(lpDDSPrimary, 0, (LPDDSURFACEDESC)&v4, 33, 0); + if ( !v1 ) + { + IDirectDrawSurface_Unlock(lpDDSPrimary, 0); + sgpBackBuf = DiabloAllocPtr(503808); + return; + } + if ( v1 != -2005532237 ) + TermDlg(104, v1, "C:\\Src\\Diablo\\Source\\dx.cpp", 81); + } + memset(&v4, 0, 0x6Cu); + v7 = 768; + v8[0] = 768; + v4 = 108; + v5 = 4111; + v10 = 2112; + v6 = 656; + v9[0] = 32; + v2 = IDirectDrawSurface_GetPixelFormat(lpDDSPrimary, (LPDDPIXELFORMAT)v9); + if ( v2 ) + TermDlg(104, v2, "C:\\Src\\Diablo\\Source\\dx.cpp", 94); + v3 = lpDDPPrimary->SetEntries( + (unsigned long)&v4, + (unsigned long)&lpDDSBackBuf, + 0, 0); + if ( v3 ) + TermDlg(104, v3, "C:\\Src\\Diablo\\Source\\dx.cpp", 96); +} +// 52A548: using guessed type char gbBackBuf; + +//----- (004155C2) -------------------------------------------------------- +void __cdecl dx_create_primary_surface() +{ + int v0; // eax + int v1; // [esp+0h] [ebp-6Ch] + int v2[25]; // [esp+4h] [ebp-68h] + int v3; // [esp+68h] [ebp-4h] + + memset(&v1, 0, 0x6Cu); + v1 = 108; + v2[0] = 1; + v3 = 512; + v0 = lpDDPPrimary->SetEntries( + (unsigned long)&v1, + (unsigned long)&lpDDSPrimary, + 0, 0); + if ( v0 ) + TermDlg(104, v0, "C:\\Src\\Diablo\\Source\\dx.cpp", 109); +} + +//----- (0041561A) -------------------------------------------------------- +HRESULT __fastcall dx_DirectDrawCreate(GUID *guid, IDirectDraw **DD, void *unknown) +{ + IDirectDraw **v3; // ebp + int v4; // eax + FARPROC v5; // ebx + int v6; // eax + GUID *v8; // [esp+10h] [ebp-4h] + + v3 = DD; + v8 = guid; + if ( !hModule ) + { + hModule = LoadLibraryA("ddraw.dll"); + if ( !hModule ) + { + v4 = GetLastError(); + TermDlg(107, v4, "C:\\Src\\Diablo\\Source\\dx.cpp", 122); + } + } + v5 = GetProcAddress(hModule, "DirectDrawCreate"); + if ( !v5 ) + { + v6 = GetLastError(); + TermDlg(107, v6, "C:\\Src\\Diablo\\Source\\dx.cpp", 127); + } + return ((int (__stdcall *)(GUID *, IDirectDraw **, void *))v5)(v8, v3, unknown); +} + +//----- (0041569A) -------------------------------------------------------- +void __cdecl dx_lock_mutex() +{ + Screen *v0; // eax + int v1; // eax + int v2[9]; // [esp+0h] [ebp-6Ch] + int v3[18]; // [esp+24h] [ebp-48h] + + EnterCriticalSection(&stru_52A530); + v0 = (Screen *)sgpBackBuf; + if ( sgpBackBuf ) + goto LABEL_8; + if ( lpDDSBackBuf ) + { + if ( sgdwLockCount ) + goto LABEL_9; + v2[0] = 108; + v1 = IDirectDrawSurface_Lock(lpDDSBackBuf, 0, (LPDDSURFACEDESC)v2, 1, 0); + if ( v1 ) + DDErrDlg(v1, 235, "C:\\Src\\Diablo\\Source\\dx.cpp"); + v0 = (Screen *)v3[0]; + screen_buf_end += v3[0]; +LABEL_8: + gpBuffer = v0; + goto LABEL_9; + } + Sleep(0x4E20u); + TermMsg("lock_buf_priv"); +LABEL_9: + ++sgdwLockCount; +} +// 69CF0C: using guessed type int screen_buf_end; + +//----- (00415725) -------------------------------------------------------- +void __cdecl dx_unlock_mutex() +{ + Screen *v0; // eax + int v1; // eax + + if ( !sgdwLockCount ) + TermMsg("draw main unlock error"); + if ( !gpBuffer ) + TermMsg("draw consistency error"); + if ( !--sgdwLockCount ) + { + v0 = gpBuffer; + gpBuffer = 0; + screen_buf_end -= (signed int)v0; + if ( !sgpBackBuf ) + { + v1 = IDirectDrawSurface_Unlock(lpDDSBackBuf, 0); + if ( v1 ) + DDErrDlg(v1, 273, "C:\\Src\\Diablo\\Source\\dx.cpp"); + } + } + LeaveCriticalSection(&stru_52A530); +} +// 69CF0C: using guessed type int screen_buf_end; + +//----- (004157A0) -------------------------------------------------------- +void __cdecl dx_cleanup() +{ + void *v0; // ecx + + if ( ghMainWnd ) + ShowWindow(ghMainWnd, 0); + SDrawDestroy(); + EnterCriticalSection(&stru_52A530); + if ( sgpBackBuf ) + { + v0 = sgpBackBuf; + sgpBackBuf = 0; + mem_free_dbg(v0); + } + else if ( lpDDSBackBuf ) + { + IDirectDrawSurface_Release(lpDDSBackBuf); + lpDDSBackBuf = 0; + } + sgdwLockCount = 0; + gpBuffer = 0; + LeaveCriticalSection(&stru_52A530); + if ( lpDDSPrimary ) + { + IDirectDrawSurface_Release(lpDDSPrimary); + lpDDSPrimary = 0; + } + if ( lpDDPRed ) + { + IDirectDrawSurface_Release(lpDDPRed); + lpDDPRed = 0; + } + if ( lpDDPPrimary ) + { + IDirectDrawSurface_Release(lpDDPPrimary); + lpDDPPrimary = 0; + } +} + +//----- (00415848) -------------------------------------------------------- +void __cdecl dx_reinit() +{ + int v0; // esi + + EnterCriticalSection(&stru_52A530); + ClearCursor(); + v0 = sgdwLockCount; + while ( sgdwLockCount ) + dx_unlock_mutex(); + dx_cleanup(); + force_redraw = 255; + dx_init(ghMainWnd); + for ( ; v0; --v0 ) + dx_lock_mutex(); + LeaveCriticalSection(&stru_52A530); +} +// 52571C: using guessed type int force_redraw; + +//----- (004158AE) -------------------------------------------------------- +void __cdecl effects_cpp_init() +{ + effects_cpp_init_value = effects_inf; +} +// 47A468: using guessed type int effects_inf; +// 52A550: using guessed type int effects_cpp_init_value; + +//----- (004158B9) -------------------------------------------------------- +bool __fastcall effect_is_playing(int nSFX) +{ + TSFX *v1; // eax + TSnd *v2; // ecx + + v1 = &sgSFX[nSFX]; + v2 = (TSnd *)v1->Channel; + if ( v2 ) + return snd_playing(v2); + if ( v1->bFlags & 1 ) + return v1 == sfx_data_cur; + return 0; +} + +//----- (004158E2) -------------------------------------------------------- +void __cdecl sfx_stop() +{ + if ( sfx_stream ) + { + SFileDdaEnd(sfx_stream); + SFileCloseFile(sfx_stream); + sfx_stream = 0; + sfx_data_cur = 0; + } +} + +//----- (0041590B) -------------------------------------------------------- +void __fastcall InitMonsterSND(int monst) +{ + signed int v1; // ebx + int v2; // eax + TSnd **v3; // esi + int v4; // edi + size_t v5; // eax + TSnd *v6; // eax + char v7[260]; // [esp+0h] [ebp-110h] + int v8; // [esp+104h] [ebp-Ch] + int v9; // [esp+108h] [ebp-8h] + void *ptr; // [esp+10Ch] [ebp-4h] + + v8 = monst; + if ( gbSndInited ) + { + v1 = 0; + v9 = (unsigned char)Monsters[monst].mtype << 7; + do + { + if ( monster_action_sounds[v1] != 115 || *(int *)((char *)&monsterdata[0].snd_special + v9) ) + { + v2 = 0; + v3 = &Monsters[0].Snds[2 * (v1 + 41 * v8)]; + do + { + v4 = v2 + 1; + sprintf( + v7, + *(const char **)((char *)&monsterdata[0].sndfile + v9), + monster_action_sounds[v1], + v2 + 1); + v5 = strlen(v7); + ptr = DiabloAllocPtr(v5 + 1); + strcpy((char *)ptr, v7); + v6 = sound_file_load((char *)ptr); + *v3 = v6; + if ( !v6 ) + mem_free_dbg(ptr); + v2 = v4; + ++v3; + } + while ( v4 < 2 ); + } + ++v1; + } + while ( v1 < 4 ); + } +} + +//----- (004159DB) -------------------------------------------------------- +void __cdecl FreeEffects() +{ + TSnd **v0; // esi + signed int v1; // ebp + signed int v2; // ebx + TSnd *v3; // ecx + void *v4; // edi + TSnd **v5; // [esp+0h] [ebp-8h] + int v6; // [esp+4h] [ebp-4h] + + v6 = 0; + if ( nummtypes > 0 ) + { + v5 = Monsters[0].Snds; + do + { + v0 = v5; + v1 = 4; + do + { + v2 = 2; + do + { + v3 = *v0; + if ( *v0 ) + { + *v0 = 0; + v4 = (void *)v3->sound_path; + v3->sound_path = 0; + sound_file_cleanup(v3); + mem_free_dbg(v4); + } + ++v0; + --v2; + } + while ( v2 ); + --v1; + } + while ( v1 ); + ++v6; + v5 += 82; + } + while ( v6 < nummtypes ); + } +} + +//----- (00415A45) -------------------------------------------------------- +void __fastcall PlayEffect(int i, int mode) +{ + int v2; // edi + int v3; // esi + int v4; // eax + int v5; // esi + int v6; // eax + TSnd *v7; // edi + int v8; // eax + int volume_delta; // [esp+8h] [ebp-8h] + int pan; // [esp+Ch] [ebp-4h] + + v2 = mode; + v3 = i; + if ( !plr[myplr].pLvlLoad ) + { + _LOBYTE(i) = -92; + v4 = random(i, 2); + if ( gbSndInited ) + { + if ( gbSoundOn ) + { + if ( !gbBufferMsgs ) + { + v5 = v3; + v6 = v4 + 2 * (v2 + 41 * monster[v5]._mMTidx); + v7 = Monsters[0].Snds[v6]; + if ( v7 ) + { + _LOBYTE(v8) = snd_playing(Monsters[0].Snds[v6]); + if ( !v8 ) + { + if ( calc_snd_position(monster[v5]._mx, monster[v5]._my, &volume_delta, &pan) ) + snd_play_snd(v7, volume_delta, pan); + } + } + } + } + } + } +} +// 4A22D5: using guessed type char gbSoundOn; +// 676194: using guessed type char gbBufferMsgs; + +//----- (00415AE1) -------------------------------------------------------- +int __fastcall calc_snd_position(int x, int y, int *plVolume, int *plPan) +{ + int v4; // edi + int v5; // esi + int v6; // eax + int v7; // ebx + int v8; // eax + int v9; // eax + + v4 = x - plr[myplr].WorldX; + v5 = y - plr[myplr].WorldY; + v6 = (v4 - v5) << 8; + *plPan = v6; + if ( abs(v6) > 6400 ) + return 0; + v7 = abs(v4); + v8 = v7 <= abs(v5) ? abs(v5) : abs(v4); + v9 = v8 << 6; + *plVolume = v9; + if ( v9 >= 6400 ) + return 0; + *plVolume = -v9; + return 1; +} + +//----- (00415B59) -------------------------------------------------------- +void __fastcall PlaySFX(int psfx) +{ + int v1; // eax + + v1 = RndSFX(psfx); + PlaySFX_priv(&sgSFX[v1], 0, 0, 0); +} + +//----- (00415B71) -------------------------------------------------------- +void __fastcall PlaySFX_priv(TSFX *pSFX, char loc, int x, int y) +{ + int v4; // edi + TSFX *v5; // esi + TSnd *v6; // ecx + int v7; // eax + TSnd *v8; // ecx + int volume_delta; // [esp+Ch] [ebp-8h] + int pan; // [esp+10h] [ebp-4h] + + v4 = loc; + v5 = pSFX; + if ( !plr[myplr].pLvlLoad || gbMaxPlayers == 1 ) + { + if ( gbSndInited ) + { + if ( gbSoundOn ) + { + if ( !gbBufferMsgs ) + { + if ( pSFX->bFlags & 3 || (v6 = (TSnd *)pSFX->Channel) == 0 || (_LOBYTE(v7) = snd_playing(v6), !v7) ) + { + pan = 0; + volume_delta = 0; + if ( !v4 || calc_snd_position(x, y, &volume_delta, &pan) ) + { + if ( v5->bFlags & 1 ) + { + stream_play(v5, volume_delta, pan); + } + else + { + if ( !v5->Channel ) + v5->Channel = (int)sound_file_load(v5->pszName); + v8 = (TSnd *)v5->Channel; + if ( v8 ) + snd_play_snd(v8, volume_delta, pan); + } + } + } + } + } + } + } +} +// 4A22D5: using guessed type char gbSoundOn; +// 676194: using guessed type char gbBufferMsgs; +// 679660: using guessed type char gbMaxPlayers; + +//----- (00415C2A) -------------------------------------------------------- +void __fastcall stream_play(TSFX *pSFX, int lVolume, int lPan) +{ + int v3; // esi + TSFX *v4; // edi + int v5; // esi + int v6; // eax + int v7; // eax + + v3 = lVolume; + v4 = pSFX; + sfx_stop(); + v5 = sound_get_or_set_sound_volume(1) + v3; + if ( v5 >= -1600 ) + { + if ( v5 > 0 ) + v5 = 0; + _LOBYTE(v6) = SFileOpenFile(v4->pszName, &sfx_stream); + if ( v6 ) + { + _LOBYTE(v7) = SFileDdaBeginEx(sfx_stream, 0x40000, 0, 0, v5, lPan, 0); + if ( v7 ) + sfx_data_cur = v4; + else + sfx_stop(); + } + else + { + sfx_stream = 0; + } + } +} + +//----- (00415C97) -------------------------------------------------------- +int __fastcall RndSFX(int psfx) +{ + int v1; // esi + int v3; // [esp-4h] [ebp-8h] + + v1 = psfx; + switch ( psfx ) + { + case PS_WARR69: + goto LABEL_12; + case PS_WARR14: + case PS_WARR15: + case PS_WARR16: + goto LABEL_19; + case PS_MAGE69: + case PS_ROGUE69: + case PS_SWING: + case LS_ACID: + case IS_FMAG: + case IS_MAGIC: + case IS_BHIT: +LABEL_12: + v3 = 2; +LABEL_15: + _LOBYTE(psfx) = -91; + return v1 + random(psfx, v3); + case PS_WARR2: +LABEL_19: + v3 = 3; + goto LABEL_15; + } + return psfx; +} + +//----- (00415D01) -------------------------------------------------------- +void __fastcall PlaySfxLoc(int psfx, int x, int y) +{ + int v3; // esi + int v4; // eax + int v5; // ecx + + v3 = x; + v4 = RndSFX(psfx); + if ( v4 >= 0 && v4 <= 3 ) + { + v5 = sgSFX[v4].Channel; + if ( v5 ) + *(_DWORD *)(v5 + 36) = 0; + } + PlaySFX_priv(&sgSFX[v4], 1, v3, y); +} + +//----- (00415D39) -------------------------------------------------------- +void __cdecl FreeMonsterSnd() +{ + TSnd **v0; // esi + signed int v1; // ebx + signed int v2; // edi + int v3; // [esp+0h] [ebp-8h] + TSnd **v4; // [esp+4h] [ebp-4h] + + snd_update(1); + sfx_stop(); + sound_stop(); + v3 = 0; + if ( nummtypes > 0 ) + { + v4 = Monsters[0].Snds; + do + { + v0 = v4; + v1 = 4; + do + { + v2 = 2; + do + { + snd_stop_snd(*v0); + ++v0; + --v2; + } + while ( v2 ); + --v1; + } + while ( v1 ); + ++v3; + v4 += 82; + } + while ( v3 < nummtypes ); + } +} + +//----- (00415D9A) -------------------------------------------------------- +void __cdecl sound_stop() +{ + TSnd **v0; // esi + signed int v1; // edi + + v0 = (TSnd **)&sgSFX[0].Channel; + v1 = 858; + do + { + if ( *v0 ) + snd_stop_snd(*v0); + v0 = (TSnd **)((char *)v0 + 9); + --v1; + } + while ( v1 ); +} + +//----- (00415DBA) -------------------------------------------------------- +void __cdecl sound_update() +{ + int v0; // ebp + unsigned int v1; // ecx + int v2; // eax + unsigned int v3; // [esp-Ch] [ebp-Ch] + unsigned int v4; // [esp-8h] [ebp-8h] + int v5; // [esp-4h] [ebp-4h] + + if ( gbSndInited ) + { + snd_update(0); + v5 = v0; + v4 = v1; + v3 = v1; + if ( sfx_stream ) + { + _LOBYTE(v2) = SFileDdaGetPos(sfx_stream, (int)&v4, (int)&v3); + if ( v2 ) + { + if ( v4 >= v3 ) + sfx_stop(); + } + } + } +} +// 415DBA: could not find valid save-restore pair for ebp + +//----- (00415DFF) -------------------------------------------------------- +void __cdecl effects_cleanup_sfx() +{ + unsigned int v0; // edi + TSnd *v1; // ecx + + FreeMonsterSnd(); + v0 = 0; + do + { + v1 = (TSnd *)sgSFX[v0].Channel; + if ( v1 ) + { + sound_file_cleanup(v1); + sgSFX[v0].Channel = 0; + } + ++v0; + } + while ( v0 < 858 ); +} + +//----- (00415E2A) -------------------------------------------------------- +void __cdecl stream_update() +{ + char v0; // bl + char v1; // al + + v0 = 0; + if ( (unsigned char)gbMaxPlayers <= 1u ) + { + v1 = plr[myplr]._pClass; + if ( v1 ) + { + if ( v1 == 1 ) + { + v0 = 16; + } + else if ( v1 == 2 ) + { + v0 = 64; + } + else + { + TermMsg("effects:1"); + } + } + else + { + v0 = 32; + } + } + else + { + v0 = 112; + } + priv_sound_init(v0); +} +// 679660: using guessed type char gbMaxPlayers; + +//----- (00415E77) -------------------------------------------------------- +void __fastcall priv_sound_init(int bLoadMask) +{ + unsigned char v1; // bl + unsigned char v2; // cl + unsigned int v3; // esi + unsigned char v4; // al + TSnd *v5; // eax + unsigned char v6; // [esp+0h] [ebp-4h] + + if ( gbSndInited ) + { + v1 = bLoadMask & 0x70; + v2 = bLoadMask & 0x70 ^ bLoadMask; + v3 = 0; + v6 = v2; + do + { + if ( !sgSFX[v3].Channel ) + { + v4 = sgSFX[v3].bFlags; + if ( !(v4 & 1) && (!v2 || v4 & v2) && (!(v4 & 0x70) || v4 & v1) ) + { + v5 = sound_file_load(sgSFX[v3].pszName); + v2 = v6; + sgSFX[v3].Channel = (int)v5; + } + } + ++v3; + } + while ( v3 < 858 ); + } +} + +//----- (00415ED8) -------------------------------------------------------- +void __cdecl sound_init() +{ + priv_sound_init(4); +} + +//----- (00415EDF) -------------------------------------------------------- +void __stdcall effects_play_sound(char *snd_file) +{ + int v1; // edi + unsigned int v2; // esi + TSnd **v3; // esi + int v4; // eax + + if ( gbSndInited && gbSoundOn ) + { + v1 = 0; + v2 = 0; + while ( _strcmpi(sgSFX[v2].pszName, snd_file) || !sgSFX[v2].Channel ) + { + ++v2; + ++v1; + if ( v2 >= 858 ) + return; + } + v3 = (TSnd **)&sgSFX[v1].Channel; + _LOBYTE(v4) = snd_playing(*v3); + if ( !v4 ) + snd_play_snd(*v3, 0, 0); + } +} +// 4A22D5: using guessed type char gbSoundOn; + +//----- (00415F43) -------------------------------------------------------- +void __fastcall encrypt_decrypt_block(void *block, int size, int key) +{ + unsigned int v3; // edx + int v4; // eax + unsigned int v5; // edi + unsigned int v6; // edx + int v7; // eax + int v8; // esi + + v3 = (unsigned int)size >> 2; + v4 = 0xEEEEEEEE; + if ( v3 ) + { + v5 = v3; + v6 = key; + do + { + v7 = encrypt_52B564[(unsigned char)v6] + v4; + *(_DWORD *)block ^= v7 + v6; + v8 = *(_DWORD *)block; + block = (char *)block + 4; + v4 = 33 * v7 + v8 + 3; + v6 = ((~v6 << 21) + 0x11111111) | (v6 >> 11); + --v5; + } + while ( v5 ); + } +} + +//----- (00415F8F) -------------------------------------------------------- +void __fastcall encrypt_encrypt_block(void *block, int size, int key) +{ + unsigned int v3; // edx + int v4; // eax + unsigned int v5; // edi + unsigned int v6; // edx + int v7; // eax + int v8; // ebx + + v3 = (unsigned int)size >> 2; + v4 = 0xEEEEEEEE; + if ( v3 ) + { + v5 = v3; + v6 = key; + do + { + v7 = encrypt_52B564[(unsigned char)v6] + v4; + v8 = *(_DWORD *)block ^ (v7 + v6); + v4 = 33 * v7 + *(_DWORD *)block + 3; + *(_DWORD *)block = v8; + block = (char *)block + 4; + v6 = ((~v6 << 21) + 0x11111111) | (v6 >> 11); + --v5; + } + while ( v5 ); + } +} + +//----- (00415FDF) -------------------------------------------------------- +int __fastcall encrypt_hash(char *s, int type) +{ + int v2; // ebp + char *v3; // ebx + signed int v4; // esi + int v5; // edi + int v6; // ST00_4 + char v7; // al + + v2 = type; + v3 = s; + v4 = 2146271213; + v5 = -286331154; + while ( v3 && *v3 ) + { + v6 = *v3++; + v7 = toupper(v6); + v4 = (v5 + v4) ^ encrypt_52A564[v7 + (v2 << 8)]; + v5 = v7 + 33 * v5 + v4 + 3; + } + return v4; +} + +//----- (0041602E) -------------------------------------------------------- +void __cdecl encrypt_init_lookup_table() +{ + unsigned int v0; // eax + int *v1; // edi + unsigned int v2; // eax + int v3; // ecx + signed int v4; // [esp+Ch] [ebp-8h] + int *v5; // [esp+10h] [ebp-4h] + + v0 = 0x100001; + v5 = encrypt_52A564; + do + { + v1 = v5; + v4 = 5; + do + { + v2 = (125 * v0 + 3) % 0x2AAAAB; + v3 = (unsigned short)v2 << 16; + v0 = (125 * v2 + 3) % 0x2AAAAB; + *v1 = (unsigned short)v0 | v3; + v1 += 256; + --v4; + } + while ( v4 ); + ++v5; + } + while ( (signed int)v5 < (signed int)&encrypt_52A564[256] ); +} + +//----- (0041609D) -------------------------------------------------------- +int __fastcall encrypt_compress(void *buf, int size) +{ + void *v2; // ebx + unsigned int v3; // esi + int v4; // ecx + void *v5; // edi + void *param; // [esp+Ch] [ebp-20h] + int v8; // [esp+10h] [ebp-1Ch] + void *v9; // [esp+14h] [ebp-18h] + size_t v10; // [esp+18h] [ebp-14h] + unsigned int v11; // [esp+1Ch] [ebp-10h] + unsigned int type; // [esp+20h] [ebp-Ch] + unsigned int dsize; // [esp+24h] [ebp-8h] + void *ptr; // [esp+28h] [ebp-4h] + + v2 = buf; + v3 = size; + ptr = DiabloAllocPtr(36312); + v4 = 2 * v3; + if ( 2 * v3 < 0x2000 ) + v4 = 0x2000; + v5 = DiabloAllocPtr(v4); + v8 = 0; + v10 = 0; + type = 0; + param = v2; + v9 = v5; + v11 = v3; + dsize = 4096; + implode( + (unsigned int (__cdecl *)(char *, unsigned int *, void *))encrypt_pkware_read, + (void (__cdecl *)(char *, unsigned int *, void *))encrypt_pkware_write, + (char *)ptr, + ¶m, + &type, + &dsize); + if ( v10 < v3 ) + { + memcpy(v2, v5, v10); + v3 = v10; + } + mem_free_dbg(ptr); + mem_free_dbg(v5); + return v3; +} + +//----- (00416133) -------------------------------------------------------- +int __cdecl encrypt_pkware_read(void *buf, int *size, void *param) +{ + int v3; // edi + int v4; // ecx + + v3 = *size; + v4 = *((_DWORD *)param + 1); + if ( *size >= (unsigned int)(*((_DWORD *)param + 4) - v4) ) + v3 = *((_DWORD *)param + 4) - v4; + memcpy(buf, (const void *)(v4 + *(_DWORD *)param), v3); + *((_DWORD *)param + 1) += v3; + return v3; +} + +//----- (00416167) -------------------------------------------------------- +int __cdecl encrypt_pkware_write(void *buf, int *size, void *param) +{ + int result; // eax + + memcpy((void *)(*((_DWORD *)param + 3) + *((_DWORD *)param + 2)), buf, *size); + result = *size; + *((_DWORD *)param + 3) += *size; + return result; +} + +//----- (0041618E) -------------------------------------------------------- +void __fastcall encrypt_decompress(void *param, int a2, int size) +{ + void *v3; // edi + int v4; // ebx + void *v5; // esi + void *parama; // [esp+Ch] [ebp-18h] + int v7; // [esp+10h] [ebp-14h] + void *v8; // [esp+14h] [ebp-10h] + size_t v9; // [esp+18h] [ebp-Ch] + int v10; // [esp+1Ch] [ebp-8h] + void *ptr; // [esp+20h] [ebp-4h] + + v3 = param; + v4 = a2; + ptr = DiabloAllocPtr(36312); + v5 = DiabloAllocPtr(size); + v7 = 0; + v9 = 0; + parama = v3; + v8 = v5; + v10 = v4; + explode( + (unsigned int (__cdecl *)(char *, unsigned int *, void *))encrypt_pkware_read, + (void (__cdecl *)(char *, unsigned int *, void *))encrypt_pkware_write, + (char *)ptr, + ¶ma); + memcpy(v3, v5, v9); + mem_free_dbg(ptr); + mem_free_dbg(v5); +} + +//----- (00416201) -------------------------------------------------------- +void __cdecl engine_cpp_init_1() +{ + engine_cpp_init_value = engine_inf; +} +// 47A474: using guessed type int engine_inf; +// 52B968: using guessed type int engine_cpp_init_value; + +//----- (0041620C) -------------------------------------------------------- +void __fastcall Cel_content_into_buf(char *pDecodeTo, char *pRLEBytes, int dwRLESize, int dwRLEWdt) +{ + char *v4; // esi + char *v5; // edi + int v6; // edx + unsigned int v7; // eax + unsigned int v8; // ecx + char v9; // cf + unsigned int v10; // ecx + char *v11; // [esp+4h] [ebp-8h] + + v11 = pRLEBytes; + if ( pDecodeTo && pRLEBytes ) + { + v4 = pRLEBytes; + v5 = pDecodeTo; + do + { + v6 = dwRLEWdt; + do + { + while ( 1 ) + { + v7 = (unsigned char)*v4++; + if ( (v7 & 0x80u) == 0 ) + break; + _LOBYTE(v7) = -(char)v7; + v5 += v7; + v6 -= v7; + if ( !v6 ) + goto LABEL_14; + } + v6 -= v7; + v8 = v7 >> 1; + if ( v7 & 1 ) + { + *v5++ = *v4++; + if ( !v8 ) + continue; + } + v9 = v8 & 1; + v10 = v7 >> 2; + if ( v9 ) + { + *(_WORD *)v5 = *(_WORD *)v4; + v4 += 2; + v5 += 2; + if ( !v10 ) + continue; + } + qmemcpy(v5, v4, 4 * v10); + v4 += 4 * v10; + v5 += 4 * v10; + } + while ( v6 ); +LABEL_14: + v5 += -dwRLEWdt - 768; + } + while ( &v11[dwRLESize] != v4 ); + } +} + +//----- (00416274) -------------------------------------------------------- +void __fastcall Cel_decode(int screen_x, int screen_y, void *pCelBuff, int frame, int frame_width) +{ + if ( gpBuffer ) + { + if ( pCelBuff ) + Cel_content_into_buf( + (char *)gpBuffer + screen_y_times_768[screen_y] + screen_x, + (char *)pCelBuff + *((_DWORD *)pCelBuff + frame), + *((_DWORD *)pCelBuff + frame + 1) - *((_DWORD *)pCelBuff + frame), + frame_width); + } +} + +//----- (004162B8) -------------------------------------------------------- +void __fastcall Cel_into_buf(char *pBuff, char *pCelBuff, int frame, int frame_width) +{ + if ( pCelBuff ) + { + if ( pBuff ) + Cel_content_into_buf( + pBuff, + &pCelBuff[*(_DWORD *)&pCelBuff[4 * frame]], + *(_DWORD *)&pCelBuff[4 * frame + 4] - *(_DWORD *)&pCelBuff[4 * frame], + frame_width); + } +} + +//----- (004162DE) -------------------------------------------------------- +void __fastcall Cel_header(int screen_x, int screen_y, char *pCelBuff, int frame, int frame_width, int always_0, int direction) +{ + int v7; // edx + char *v8; // eax + int v9; // edi + int v10; // ecx + int v11; // [esp+Ch] [ebp-8h] + int v12; // [esp+10h] [ebp-4h] + + v12 = screen_y; + v11 = screen_x; + if ( gpBuffer ) + { + if ( pCelBuff ) + { + v7 = *(_DWORD *)&pCelBuff[4 * frame]; + v8 = &pCelBuff[v7]; + v9 = *(unsigned short *)&pCelBuff[v7 + always_0]; + if ( *(_WORD *)&pCelBuff[v7 + always_0] ) + { + if ( direction != 8 && *(_WORD *)&v8[direction] ) + v10 = *(unsigned short *)&v8[direction] - v9; + else + v10 = *(_DWORD *)&pCelBuff[4 * frame + 4] - v7 - v9; + Cel_content_into_buf( + (char *)gpBuffer + screen_y_times_768[v12 - 16 * always_0] + v11, + &v8[v9], + v10, + frame_width); + } + } + } +} + +//----- (00416359) -------------------------------------------------------- +void __fastcall Cel_header_into_buf(char *pBuff, char *pCelBuff, int frame, int frame_width, int always_0, int direction) +{ + int v6; // esi + char *v7; // eax + int v8; // ebx + int v9; // edx + int v10; // edx + + if ( pCelBuff ) + { + if ( pBuff ) + { + v6 = *(_DWORD *)&pCelBuff[4 * frame]; + v7 = &pCelBuff[v6]; + v8 = *(unsigned short *)&pCelBuff[v6 + always_0]; + if ( *(_WORD *)&pCelBuff[v6 + always_0] ) + { + v9 = *(_DWORD *)&pCelBuff[4 * frame + 4] - v6; + if ( direction != 8 && *(_WORD *)&v7[direction] ) + v10 = *(unsigned short *)&v7[direction] - v8; + else + v10 = v9 - v8; + Cel_content_into_buf(pBuff, &v7[v8], v10, frame_width); + } + } + } +} + +//----- (004163AC) -------------------------------------------------------- +void __fastcall Cel_content_light_into_buf(char *pDecodeTo, char *pRLEBytes, int frame_content_size, int frame_width) +{ + char *v4; // esi + char *v5; // edi + char *v6; // ebx + int v7; // edx + int v8; // eax + int v9; // ST00_4 + + if ( pDecodeTo && pRLEBytes ) + { + v4 = pRLEBytes; + v5 = pDecodeTo; + v6 = &pRLEBytes[frame_content_size]; + do + { + v7 = frame_width; + do + { + while ( 1 ) + { + v8 = (unsigned char)*v4++; + if ( (v8 & 0x80u) != 0 ) + break; + v9 = v7 - v8; + Cel_content_light_entry_into_buf(v8, v7 - v8); + v7 = v9; + if ( !v9 ) + goto LABEL_9; + } + _LOBYTE(v8) = -(char)v8; + v5 += v8; + v7 -= v8; + } + while ( v7 ); +LABEL_9: + v5 += -frame_width - 768; + } + while ( v6 != v4 ); + } +} +// 69BEF8: using guessed type int light_table_index; + +//----- (00416423) -------------------------------------------------------- +void __fastcall Cel_content_light_entry_into_buf(int a1, int a2) +{ + int v2; // ebx + _BYTE *v3; // edi + _BYTE *v4; // esi + char v5; // cf + unsigned char v6; // cl + char v7; // cl + int v8; // eax + char v9; // ch + char v10; // ch + char v11; // ch + + v5 = a1 & 1; + v6 = (unsigned char)a1 >> 1; + if ( v5 ) + { + _LOBYTE(a2) = *v4; + *v3 = *(_BYTE *)(v2 + a2); + ++v4; + ++v3; + } + v5 = v6 & 1; + v7 = v6 >> 1; + if ( v5 ) + { + _LOBYTE(a2) = *v4; + *v3 = *(_BYTE *)(v2 + a2); + _LOBYTE(a2) = v4[1]; + v3[1] = *(_BYTE *)(v2 + a2); + v4 += 2; + v3 += 2; + } + for ( ; v7; --v7 ) + { + v8 = *(_DWORD *)v4; + v4 += 4; + _LOBYTE(a2) = v8; + v9 = *(_BYTE *)(v2 + a2); + _LOBYTE(a2) = BYTE1(v8); + v8 = __ROR4__(v8, 16); + *v3 = v9; + v10 = *(_BYTE *)(v2 + a2); + _LOBYTE(a2) = v8; + v3[1] = v10; + v11 = *(_BYTE *)(v2 + a2); + _LOBYTE(a2) = BYTE1(v8); + v3[2] = v11; + v3[3] = *(_BYTE *)(v2 + a2); + v3 += 4; + } +} + +//----- (00416488) -------------------------------------------------------- +void __fastcall Cel_content_light_trans_into_buf(char *pDecodeTo, char *pRLEBytes, int frame_content_size, int frame_width) +{ + char *v4; // esi + int v5; // edi + char *v6; // ebx + int v7; // edx + unsigned int v8; // eax + unsigned int v10; // ecx + char v11; // cf + unsigned int v12; // ecx + char *v13; // esi + _BYTE *v14; // edi + _BYTE *v18; // edi + unsigned int v21; // ecx + _BYTE *v25; // edi + char *v26; // [esp-4h] [ebp-24h] + int v27; // [esp+Ch] [ebp-14h] + int v28; // [esp+14h] [ebp-Ch] + + if ( pDecodeTo && pRLEBytes ) + { + v27 = dword_646A20 + (light_table_index << 8); + v4 = pRLEBytes; + v5 = (int)pDecodeTo; + v6 = &pRLEBytes[frame_content_size]; + v28 = (unsigned char)pDecodeTo & 1; + do + { + v7 = frame_width; + do + { +/* while ( 1 ) + { + v8 = (unsigned char)*v4++; + if ( (v8 & 0x80u) != 0 ) + break; + v26 = v6; + _EBX = v27; + v7 -= v8; + if ( (v5 & 1) == v28 ) + { + v10 = v8 >> 1; + if ( !(v8 & 1) ) + goto LABEL_10; + ++v4; + ++v5; + if ( v10 ) + { +LABEL_17: + v11 = v10 & 1; + v21 = v10 >> 1; + if ( !v11 ) + goto LABEL_26; + _AL = *v4; + __asm { xlat } + *(_BYTE *)v5 = _AL; + v4 += 2; + v5 += 2; + if ( v21 ) + { +LABEL_26: + do + { + _EAX = *(_DWORD *)v4; + v4 += 4; + __asm { xlat } + *(_BYTE *)v5 = _EAX; + v25 = (_BYTE *)(v5 + 2); + _EAX = __ROR4__(_EAX, 16); + __asm { xlat } + *v25 = _EAX; + v5 = (int)(v25 + 2); + --v21; + } + while ( v21 ); + } + goto LABEL_20; + } + } + else + { + v10 = v8 >> 1; + if ( !(v8 & 1) ) + goto LABEL_17; + _AL = *v4++; + __asm { xlat } + *(_BYTE *)v5++ = _AL; + if ( v10 ) + { +LABEL_10: + v11 = v10 & 1; + v12 = v10 >> 1; + if ( !v11 ) + goto LABEL_27; + v13 = v4 + 1; + v14 = (_BYTE *)(v5 + 1); + _AL = *v13; + v4 = v13 + 1; + __asm { xlat } + *v14 = _AL; + v5 = (int)(v14 + 1); + if ( v12 ) + { +LABEL_27: + do + { + _EAX = *(_DWORD *)v4; + v4 += 4; + v18 = (_BYTE *)(v5 + 1); + _EAX = __ROR4__(_EAX, 8); + __asm { xlat } + *v18 = _EAX; + _EAX = __ROR4__(_EAX, 16); + v18 += 2; + __asm { xlat } + *v18 = _EAX; + v5 = (int)(v18 + 1); + --v12; + } + while ( v12 ); + } + goto LABEL_20; + } + } +LABEL_20: + v6 = v26; + if ( !v7 ) + goto LABEL_23; + }*/ + _LOBYTE(v8) = -(char)v8; + v5 += v8; + v7 -= v8; + } + while ( v7 ); +LABEL_23: + v5 -= frame_width + 768; + v28 = ((_BYTE)v28 + 1) & 1; + } + while ( v6 != v4 ); + } +} +// 69BEF8: using guessed type int light_table_index; + +//----- (00416565) -------------------------------------------------------- +void __fastcall Cel_light(int screen_x, int screen_y, char *pCelBuff, int frame, int frame_width) +{ + int v5; // ebx + int v6; // esi + char *v7; // edx + char *v8; // ecx + int v9; // [esp-8h] [ebp-14h] + + v5 = screen_y; + if ( gpBuffer && pCelBuff ) + { + v6 = *(_DWORD *)&pCelBuff[4 * frame]; + v7 = &pCelBuff[v6]; + v8 = (char *)gpBuffer + screen_y_times_768[v5] + screen_x; + v9 = *(_DWORD *)&pCelBuff[4 * frame + 4] - v6; + if ( light_table_index ) + Cel_content_light_into_buf(v8, v7, v9, frame_width); + else + Cel_content_into_buf(v8, v7, v9, frame_width); + } +} +// 69BEF8: using guessed type int light_table_index; + +//----- (004165BD) -------------------------------------------------------- +void __fastcall Cel_header_and_light(int screen_x, int screen_y, char *pCelBuff, int frame, int frame_width, int always_0, int direction) +{ + int v7; // esi + char *v8; // ecx + int v9; // edi + char *v10; // edx + int v11; // ebx + int v12; // ebx + char *v13; // edx + char *v14; // ecx + int v15; // [esp+Ch] [ebp-4h] + char *cel_buf; // [esp+18h] [ebp+8h] + + v7 = screen_y; + v15 = screen_x; + if ( gpBuffer ) + { + v8 = pCelBuff; + if ( pCelBuff ) + { + v9 = *(_DWORD *)&pCelBuff[4 * frame]; + v10 = &pCelBuff[v9]; + v11 = *(unsigned short *)&pCelBuff[v9 + always_0]; + cel_buf = (char *)*(unsigned short *)&pCelBuff[v9 + always_0]; + if ( v11 ) + { + if ( direction != 8 && *(_WORD *)&v10[direction] ) + v12 = *(unsigned short *)&v10[direction] - (_DWORD)cel_buf; + else + v12 = *(_DWORD *)&v8[4 * frame + 4] - v9 - (_DWORD)cel_buf; + v13 = &v10[(_DWORD)cel_buf]; + v14 = (char *)gpBuffer + screen_y_times_768[v7 - 16 * always_0] + v15; + if ( light_table_index ) + Cel_content_light_into_buf(v14, v13, v12, frame_width); + else + Cel_content_into_buf(v14, v13, v12, frame_width); + } + } + } +} +// 69BEF8: using guessed type int light_table_index; + +//----- (0041664B) -------------------------------------------------------- +void __fastcall Cel_header_light_and_trans_into_buf(char *pBuff, char *pCelBuff, int frame, int frame_width, int always_0, int direction) +{ + char *v6; // eax + int v7; // esi + char *v8; // edx + int v9; // ebx + int v10; // eax + int v11; // eax + char *v12; // edx + + v6 = pCelBuff; + if ( pCelBuff ) + { + if ( pBuff ) + { + v7 = *(_DWORD *)&pCelBuff[4 * frame]; + v8 = &pCelBuff[v7]; + v9 = *(unsigned short *)&v6[v7 + always_0]; + if ( *(_WORD *)&v6[v7 + always_0] ) + { + v10 = *(_DWORD *)&v6[4 * frame + 4] - v7; + if ( direction != 8 && *(_WORD *)&v8[direction] ) + v11 = *(unsigned short *)&v8[direction] - v9; + else + v11 = v10 - v9; + v12 = &v8[v9]; + if ( cel_transparency_active ) + { + Cel_content_light_trans_into_buf(pBuff, v12, v11, frame_width); + } + else if ( light_table_index ) + { + Cel_content_light_into_buf(pBuff, v12, v11, frame_width); + } + else + { + Cel_content_into_buf(pBuff, v12, v11, frame_width); + } + } + } + } +} +// 69BEF8: using guessed type int light_table_index; +// 69CF94: using guessed type int cel_transparency_active; + +//----- (004166BF) -------------------------------------------------------- +void __fastcall Cel_header_and_light_not_equipable(int screen_x, int screen_y, char *pCelBuff, int frame, int frame_width, int always_0, int direction, char always_1) +{ + char *v8; // esi + int v9; // ebx + int v10; // eax + char *v11; // edi + int v12; // ecx + int v13; // esi + int v14; // eax + int v15; // eax + _BYTE *v16; // esi + char *v17; // edi + int v18; // edx + int v19; // eax + int v20; // ecx + int v21; // [esp+Ch] [ebp-4h] + int v22; // [esp+Ch] [ebp-4h] + char *cel_buf; // [esp+18h] [ebp+8h] + char *cel_bufa; // [esp+18h] [ebp+8h] + int framea; // [esp+1Ch] [ebp+Ch] + int always_0a; // [esp+24h] [ebp+14h] + int directiona; // [esp+28h] [ebp+18h] + + v21 = screen_x; + if ( gpBuffer ) + { + v8 = pCelBuff; + if ( pCelBuff ) + { + v9 = *(_DWORD *)&pCelBuff[4 * frame]; + v10 = always_0; + v11 = &pCelBuff[v9]; + v12 = *(unsigned short *)&pCelBuff[v9 + always_0]; + cel_buf = (char *)*(unsigned short *)&pCelBuff[v9 + always_0]; + if ( v12 ) + { + v13 = *(_DWORD *)&v8[4 * frame + 4] - v9; + if ( direction != 8 && *(_WORD *)&v11[direction] ) + always_0a = *(unsigned short *)&v11[direction] - (_DWORD)cel_buf; + else + always_0a = v13 - (_DWORD)cel_buf; + directiona = (int)&v11[(_DWORD)cel_buf]; + cel_bufa = (char *)gpBuffer + screen_y_times_768[screen_y - 16 * v10] + v21; + v14 = -(light4flag != 0); + _LOWORD(v14) = v14 & 0xF400; + v15 = v14 + 4096; + framea = v15; + if ( always_1 == 2 ) + { + v15 += 256; + framea = v15; + } + if ( always_1 >= 4 ) + framea = v15 + (always_1 << 8) - 256; + v22 = framea + dword_646A20; + v16 = (_BYTE *)directiona; + v17 = cel_bufa; + do + { + v18 = frame_width; + do + { + while ( 1 ) + { + v19 = (unsigned char)*v16++; + if ( (v19 & 0x80u) == 0 ) + break; + _LOBYTE(v19) = -(char)v19; + v17 += v19; + v18 -= v19; + if ( !v18 ) + goto LABEL_20; + } + v18 -= v19; + v20 = v19; + do + { + _LOBYTE(v19) = *v16++; + *v17 = *(_BYTE *)(v22 + v19); + --v20; + ++v17; + } + while ( v20 ); + } + while ( v18 ); +LABEL_20: + v17 += -frame_width - 768; + } + while ( (_BYTE *)(directiona + always_0a) != v16 ); + } + } + } +} +// 525728: using guessed type int light4flag; + +//----- (004167DB) -------------------------------------------------------- +void __fastcall Cel2_content_into_buf(char *pDecodeTo, char *pRLEBytes, int frame_content_size, int frame_width) +{ + char *v4; // esi + char *v5; // edi + int v6; // edx + unsigned int v7; // eax + unsigned int v8; // ecx + char v9; // cf + unsigned int v10; // ecx + char *v11; // [esp+4h] [ebp-8h] + + v11 = pRLEBytes; + if ( pDecodeTo && pRLEBytes && gpBuffer ) + { + v4 = pRLEBytes; + v5 = pDecodeTo; + do + { + v6 = frame_width; + do + { + while ( 1 ) + { + v7 = (unsigned char)*v4++; + if ( (v7 & 0x80u) == 0 ) + break; + _LOBYTE(v7) = -(char)v7; + v5 += v7; + v6 -= v7; + if ( !v6 ) + goto LABEL_17; + } + v6 -= v7; + if ( (unsigned int)v5 < screen_buf_end ) + { + v8 = v7 >> 1; + if ( !(v7 & 1) || (*v5 = *v4, ++v4, ++v5, v8) ) + { + v9 = v8 & 1; + v10 = v7 >> 2; + if ( !v9 || (*(_WORD *)v5 = *(_WORD *)v4, v4 += 2, v5 += 2, v10) ) + { + qmemcpy(v5, v4, 4 * v10); + v4 += 4 * v10; + v5 += 4 * v10; + } + } + } + else + { + v4 += v7; + v5 += v7; + } + } + while ( v6 ); +LABEL_17: + v5 += -frame_width - 768; + } + while ( &v11[frame_content_size] != v4 ); + } +} +// 69CF0C: using guessed type int screen_buf_end; + +//----- (0041685A) -------------------------------------------------------- +void __fastcall Cel2_header(int screen_x, int screen_y, char *pCelBuff, int frame, int frame_width, int a6, int direction) +{ + int v7; // edx + char *v8; // eax + int v9; // edi + int v10; // ecx + int v11; // [esp+Ch] [ebp-8h] + int v12; // [esp+10h] [ebp-4h] + + v12 = screen_y; + v11 = screen_x; + if ( gpBuffer ) + { + if ( pCelBuff ) + { + v7 = *(_DWORD *)&pCelBuff[4 * frame]; + v8 = &pCelBuff[v7]; + v9 = *(unsigned short *)&pCelBuff[v7 + a6]; + if ( *(_WORD *)&pCelBuff[v7 + a6] ) + { + if ( direction != 8 && *(_WORD *)&v8[direction] ) + v10 = *(unsigned short *)&v8[direction] - v9; + else + v10 = *(_DWORD *)&pCelBuff[4 * frame + 4] - v7 - v9; + Cel2_content_into_buf( + (char *)gpBuffer + screen_y_times_768[v12 - 16 * a6] + v11, + &v8[v9], + v10, + frame_width); + } + } + } +} + +//----- (004168D5) -------------------------------------------------------- +void __fastcall Cel2_header_into_buf(char *pBuff, char *pCelBuff, int frame, int frame_width, int a5, int direction) +{ + int v6; // edi + char *v7; // esi + int v8; // ebx + int v9; // eax + int v10; // edx + int v11; // eax + + if ( pCelBuff ) + { + if ( pBuff ) + { + v6 = *(_DWORD *)&pCelBuff[4 * frame]; + v7 = &pCelBuff[v6]; + v8 = *(unsigned short *)&pCelBuff[v6 + a5]; + if ( *(_WORD *)&pCelBuff[v6 + a5] ) + { + v9 = *(_DWORD *)&pCelBuff[4 * frame + 4] - v6; + v10 = *(unsigned short *)&v7[direction]; + if ( direction == 8 ) + v10 = 0; + if ( v10 ) + v11 = v10 - v8; + else + v11 = v9 - v8; + Cel2_content_into_buf(pBuff, &v7[v8], v11, frame_width); + } + } + } +} + +//----- (0041692A) -------------------------------------------------------- +void __fastcall Cel2_content_light_into_buf(char *pDecodeTo, char *pRLEBytes, int frame_content_size, int frame_width) +{ + char *v4; // esi + char *v5; // edi + char *v6; // ebx + int v7; // edx + int v8; // eax + int v9; // ST00_4 + + if ( pDecodeTo && pRLEBytes && gpBuffer ) + { + v4 = pRLEBytes; + v5 = pDecodeTo; + v6 = &pRLEBytes[frame_content_size]; + do + { + v7 = frame_width; + do + { + while ( 1 ) + { + v8 = (unsigned char)*v4++; + if ( (v8 & 0x80u) == 0 ) + break; + _LOBYTE(v8) = -(char)v8; + v5 += v8; + v7 -= v8; + if ( !v7 ) + goto LABEL_13; + } + v7 -= v8; + if ( (unsigned int)v5 < screen_buf_end ) + { + v9 = v7; + Cel2_content_light_entry_into_buf(v8, v7); + v7 = v9; + } + else + { + v4 += v8; + v5 += v8; + } + } + while ( v7 ); +LABEL_13: + v5 += -frame_width - 768; + } + while ( v6 != v4 ); + } +} +// 69BEF8: using guessed type int light_table_index; +// 69CF0C: using guessed type int screen_buf_end; + +//----- (004169BC) -------------------------------------------------------- +void __fastcall Cel2_content_light_entry_into_buf(int a1, int a2) +{ + int v2; // ebx + _BYTE *v3; // edi + _BYTE *v4; // esi + char v5; // cf + unsigned char v6; // cl + char v7; // cl + int v8; // eax + char v9; // ch + char v10; // ch + char v11; // ch + + v5 = a1 & 1; + v6 = (unsigned char)a1 >> 1; + if ( v5 ) + { + _LOBYTE(a2) = *v4; + *v3 = *(_BYTE *)(v2 + a2); + ++v4; + ++v3; + } + v5 = v6 & 1; + v7 = v6 >> 1; + if ( v5 ) + { + _LOBYTE(a2) = *v4; + *v3 = *(_BYTE *)(v2 + a2); + _LOBYTE(a2) = v4[1]; + v3[1] = *(_BYTE *)(v2 + a2); + v4 += 2; + v3 += 2; + } + for ( ; v7; --v7 ) + { + v8 = *(_DWORD *)v4; + v4 += 4; + _LOBYTE(a2) = v8; + v9 = *(_BYTE *)(v2 + a2); + _LOBYTE(a2) = BYTE1(v8); + v8 = __ROR4__(v8, 16); + *v3 = v9; + v10 = *(_BYTE *)(v2 + a2); + _LOBYTE(a2) = v8; + v3[1] = v10; + v11 = *(_BYTE *)(v2 + a2); + _LOBYTE(a2) = BYTE1(v8); + v3[2] = v11; + v3[3] = *(_BYTE *)(v2 + a2); + v3 += 4; + } +} + +//----- (00416A21) -------------------------------------------------------- +void __fastcall Cel2_content_light_trans_into_buf(char *pDecodeTo, char *pRLEBytes, int frame_content_size, int frame_width) +{ + char *v4; // esi + unsigned int v5; // edi + char *v6; // ebx + int v7; // edx + unsigned int v8; // eax + unsigned int v10; // ecx + char v11; // cf + unsigned int v12; // ecx + char *v13; // esi + _BYTE *v14; // edi + _BYTE *v18; // edi + unsigned int v21; // ecx + _BYTE *v25; // edi + char *v26; // [esp-4h] [ebp-24h] + int v27; // [esp+Ch] [ebp-14h] + int v28; // [esp+14h] [ebp-Ch] + + if ( pDecodeTo && pRLEBytes && gpBuffer ) + { + v27 = dword_646A20 + (light_table_index << 8); + v4 = pRLEBytes; + v5 = (unsigned int)pDecodeTo; + v6 = &pRLEBytes[frame_content_size]; + v28 = (unsigned char)pDecodeTo & 1; + do + { + v7 = frame_width; + do + { +/* while ( 1 ) + { + v8 = (unsigned char)*v4++; + if ( (v8 & 0x80u) != 0 ) + break; + v26 = v6; + _EBX = v27; + v7 -= v8; + if ( v5 < screen_buf_end ) + { + if ( (v5 & 1) == v28 ) + { + v10 = v8 >> 1; + if ( !(v8 & 1) ) + goto LABEL_13; + ++v4; + ++v5; + if ( v10 ) + { +LABEL_20: + v11 = v10 & 1; + v21 = v10 >> 1; + if ( !v11 ) + goto LABEL_29; + _AL = *v4; + __asm { xlat } + *(_BYTE *)v5 = _AL; + v4 += 2; + v5 += 2; + if ( v21 ) + { +LABEL_29: + do + { + _EAX = *(_DWORD *)v4; + v4 += 4; + __asm { xlat } + *(_BYTE *)v5 = _EAX; + v25 = (_BYTE *)(v5 + 2); + _EAX = __ROR4__(_EAX, 16); + __asm { xlat } + *v25 = _EAX; + v5 = (unsigned int)(v25 + 2); + --v21; + } + while ( v21 ); + } + goto LABEL_23; + } + } + else + { + v10 = v8 >> 1; + if ( !(v8 & 1) ) + goto LABEL_20; + _AL = *v4++; + __asm { xlat } + *(_BYTE *)v5++ = _AL; + if ( v10 ) + { +LABEL_13: + v11 = v10 & 1; + v12 = v10 >> 1; + if ( !v11 ) + goto LABEL_30; + v13 = v4 + 1; + v14 = (_BYTE *)(v5 + 1); + _AL = *v13; + v4 = v13 + 1; + __asm { xlat } + *v14 = _AL; + v5 = (unsigned int)(v14 + 1); + if ( v12 ) + { +LABEL_30: + do + { + _EAX = *(_DWORD *)v4; + v4 += 4; + v18 = (_BYTE *)(v5 + 1); + _EAX = __ROR4__(_EAX, 8); + __asm { xlat } + *v18 = _EAX; + _EAX = __ROR4__(_EAX, 16); + v18 += 2; + __asm { xlat } + *v18 = _EAX; + v5 = (unsigned int)(v18 + 1); + --v12; + } + while ( v12 ); + } + goto LABEL_23; + } + } + } + else + { + v4 += v8; + v5 += v8; + } +LABEL_23: + v6 = v26; + if ( !v7 ) + goto LABEL_26; + }*/ + _LOBYTE(v8) = -(char)v8; + v5 += v8; + v7 -= v8; + } + while ( v7 ); +LABEL_26: + v5 -= frame_width + 768; + v28 = ((_BYTE)v28 + 1) & 1; + } + while ( v6 != v4 ); + } +} +// 69BEF8: using guessed type int light_table_index; +// 69CF0C: using guessed type int screen_buf_end; + +//----- (00416B19) -------------------------------------------------------- +void __fastcall Cel2_header_and_light(int screen_x, int screen_y, char *pCelBuff, int frame, int frame_width, int a6, int direction) +{ + int v7; // esi + char *v8; // eax + int v9; // edi + char *v10; // edx + int v11; // ebx + int v12; // eax + int v13; // edi + int v14; // eax + char *v15; // edx + char *v16; // ecx + char *cel_buf; // [esp+18h] [ebp+8h] + + v7 = screen_y; + if ( gpBuffer ) + { + v8 = pCelBuff; + if ( pCelBuff ) + { + v9 = *(_DWORD *)&pCelBuff[4 * frame]; + v10 = &pCelBuff[v9]; + v11 = *(unsigned short *)&pCelBuff[v9 + a6]; + cel_buf = (char *)*(unsigned short *)&pCelBuff[v9 + a6]; + if ( v11 ) + { + v12 = *(_DWORD *)&v8[4 * frame + 4] - v9; + v13 = *(unsigned short *)&v10[direction]; + if ( direction == 8 ) + v13 = 0; + if ( v13 ) + v14 = v13 - (_DWORD)cel_buf; + else + v14 = v12 - (_DWORD)cel_buf; + v15 = &v10[(_DWORD)cel_buf]; + v16 = (char *)gpBuffer + screen_y_times_768[v7 - 16 * a6] + screen_x; + if ( light_table_index ) + Cel2_content_light_into_buf(v16, v15, v14, frame_width); + else + Cel2_content_into_buf(v16, v15, v14, frame_width); + } + } + } +} +// 69BEF8: using guessed type int light_table_index; + +//----- (00416BA9) -------------------------------------------------------- +void __fastcall Cel2_header_light_and_trans_into_buf(char *dst_buf, char *pCelBuff, int frame, int frame_width, int a5, int direction) +{ + char *v6; // eax + int v7; // esi + char *v8; // edx + int v9; // ebx + int v10; // eax + int v11; // esi + int v12; // eax + char *v13; // edx + + v6 = pCelBuff; + if ( pCelBuff ) + { + v7 = *(_DWORD *)&pCelBuff[4 * frame]; + v8 = &pCelBuff[v7]; + v9 = *(unsigned short *)&v6[v7 + a5]; + if ( *(_WORD *)&v6[v7 + a5] ) + { + v10 = *(_DWORD *)&v6[4 * frame + 4] - v7; + v11 = *(unsigned short *)&v8[direction]; + if ( direction == 8 ) + v11 = 0; + if ( v11 ) + v12 = v11 - v9; + else + v12 = v10 - v9; + v13 = &v8[v9]; + if ( cel_transparency_active ) + { + Cel2_content_light_trans_into_buf(dst_buf, v13, v12, frame_width); + } + else if ( light_table_index ) + { + Cel2_content_light_into_buf(dst_buf, v13, v12, frame_width); + } + else + { + Cel2_content_into_buf(dst_buf, v13, v12, frame_width); + } + } + } +} +// 69BEF8: using guessed type int light_table_index; +// 69CF94: using guessed type int cel_transparency_active; + +//----- (00416C1B) -------------------------------------------------------- +void __fastcall Cel2_header_and_light_not_equipable(int screen_x, int screen_y, char *pCelBuff, int frame, int frame_width, int always_0, int direction, char always_1) +{ + char *v8; // esi + int v9; // ebx + char *v10; // edi + int v11; // ecx + int v12; // esi + int v13; // eax + int v14; // eax + _BYTE *v15; // esi + _BYTE *v16; // edi + int v17; // ecx + int v18; // edx + int v19; // ecx + int v20; // eax + _BYTE *v21; // [esp-4h] [ebp-14h] + int v22; // [esp+Ch] [ebp-4h] + char *cel_buf; // [esp+18h] [ebp+8h] + char *cel_bufa; // [esp+18h] [ebp+8h] + int framea; // [esp+1Ch] [ebp+Ch] + char *always_0a; // [esp+24h] [ebp+14h] + int directiona; // [esp+28h] [ebp+18h] + + v22 = screen_x; + if ( gpBuffer ) + { + v8 = pCelBuff; + if ( pCelBuff ) + { + v9 = *(_DWORD *)&pCelBuff[4 * frame]; + v10 = &pCelBuff[v9]; + v11 = *(unsigned short *)&pCelBuff[v9 + always_0]; + cel_buf = (char *)*(unsigned short *)&pCelBuff[v9 + always_0]; + if ( v11 ) + { + v12 = *(_DWORD *)&v8[4 * frame + 4] - v9; + if ( direction != 8 && *(_WORD *)&v10[direction] ) + framea = *(unsigned short *)&v10[direction] - (_DWORD)cel_buf; + else + framea = v12 - (_DWORD)cel_buf; + directiona = (int)&v10[(_DWORD)cel_buf]; + always_0a = (char *)gpBuffer + screen_y_times_768[screen_y - 16 * always_0] + v22; + v13 = -(light4flag != 0); + _LOWORD(v13) = v13 & 0xF400; + v14 = v13 + 4096; + if ( always_1 == 2 ) + v14 += 256; + if ( always_1 >= 4 ) + v14 = v14 + (always_1 << 8) - 256; + cel_bufa = (char *)(v14 + dword_646A20); + v15 = (_BYTE *)directiona; + v16 = (unsigned char *)always_0a; + v17 = directiona + framea; + do + { + v21 = (_BYTE *)v17; + v18 = frame_width; + v19 = 0; + do + { + while ( 1 ) + { + v20 = (unsigned char)*v15++; + if ( (v20 & 0x80u) == 0 ) + break; + _LOBYTE(v20) = -(char)v20; + v16 += v20; + v18 -= v20; + if ( !v18 ) + goto LABEL_21; + } + v18 -= v20; + if ( (unsigned int)v16 < screen_buf_end ) + { + do + { + _LOBYTE(v19) = *v15++; + *v16 = cel_bufa[v19]; + --v20; + ++v16; + } + while ( v20 ); + } + else + { + v15 += v20; + v16 += v20; + } + } + while ( v18 ); +LABEL_21: + v17 = (int)v21; + v16 += -frame_width - 768; + } + while ( v21 != v15 ); + } + } + } +} +// 525728: using guessed type int light4flag; +// 69CF0C: using guessed type int screen_buf_end; + +//----- (00416D3C) -------------------------------------------------------- +void __fastcall Cel_into_rect_of_buf(char *pBuff, int always_0, int dst_height, int dst_width, char *pCelBuff, int frame, int frame_width) +{ + char *v7; // ebx + char *v8; // esi + char *v9; // edi + int v10; // ebx + int v11; // edx + unsigned int v12; // eax + unsigned int v13; // ecx + char v14; // cf + unsigned int v15; // ecx + int dst_widtha; // [esp+14h] [ebp+Ch] + + if ( pCelBuff && pBuff ) + { + v7 = &pCelBuff[4 * frame]; + v8 = &pCelBuff[*(_DWORD *)v7]; + v9 = &pBuff[dst_width * dst_height + always_0]; + dst_widtha = frame_width + dst_width; + v10 = (int)&v8[*((_DWORD *)v7 + 1) - *(_DWORD *)v7]; + do + { + v11 = frame_width; + do + { + while ( 1 ) + { + v12 = (unsigned char)*v8++; + if ( (v12 & 0x80u) == 0 ) + break; + _LOBYTE(v12) = -(char)v12; + v9 += v12; + v11 -= v12; + if ( !v11 ) + goto LABEL_14; + } + v11 -= v12; + v13 = v12 >> 1; + if ( v12 & 1 ) + { + *v9++ = *v8++; + if ( !v13 ) + continue; + } + v14 = v13 & 1; + v15 = v12 >> 2; + if ( v14 ) + { + *(_WORD *)v9 = *(_WORD *)v8; + v8 += 2; + v9 += 2; + if ( !v15 ) + continue; + } + qmemcpy(v9, v8, 4 * v15); + v8 += 4 * v15; + v9 += 4 * v15; + } + while ( v11 ); +LABEL_14: + v9 -= dst_widtha; + } + while ( (char *)v10 != v8 ); + } +} + +//----- (00416DC6) -------------------------------------------------------- +void __fastcall Cel_colour(char colour, int screen_x, int screen_y, char *pCelBuff, int frame, int frame_width, int a7, int direction) +{ + char *v8; // ebx + int v9; // eax + char *v10; // esi + char *v11; // edi + int v12; // edx + int v13; // eax + int v14; // ecx + char v15; // al + int v16; // [esp+Ch] [ebp-10h] + char *v17; // [esp+10h] [ebp-Ch] + int v18; // [esp+14h] [ebp-8h] + char v19; // [esp+18h] [ebp-4h] + + v19 = colour; + if ( pCelBuff ) + { + if ( gpBuffer ) + { + v8 = &pCelBuff[4 * frame]; + v17 = &pCelBuff[*(_DWORD *)v8]; + v16 = *(unsigned short *)&v17[a7]; + if ( *(_WORD *)&v17[a7] ) + { + if ( direction == 8 ) + v9 = 0; + else + v9 = *(unsigned short *)&v17[direction]; + if ( v9 ) + v18 = v9 - v16; + else + v18 = *((_DWORD *)v8 + 1) - *(_DWORD *)v8 - v16; + v10 = &v17[v16]; + v11 = (char *)gpBuffer + screen_y_times_768[screen_y - 16 * a7] + screen_x; + do + { + v12 = frame_width; + do + { + while ( 1 ) + { + v13 = (unsigned char)*v10++; + if ( (v13 & 0x80u) == 0 ) + break; + _LOBYTE(v13) = -(char)v13; + v11 += v13; + v12 -= v13; + if ( !v12 ) + goto LABEL_20; + } + v12 -= v13; + v14 = v13; + do + { + v15 = *v10++; + if ( v15 ) + { + *(v11 - 768) = v19; + *(v11 - 1) = v19; + v11[1] = v19; + v11[768] = v19; + } + ++v11; + --v14; + } + while ( v14 ); + } + while ( v12 ); +LABEL_20: + v11 += -frame_width - 768; + } + while ( &v17[v16 + v18] != v10 ); + } + } + } +} + +//----- (00416EC0) -------------------------------------------------------- +void __fastcall Cel_header_and_colour_highlight(char colour, int screen_x, int screen_y, char *pCelBuff, int frame, int frame_width, int a7, int direction) +{ + char *v8; // ebx + int v9; // eax + char *v10; // esi + char *v11; // edi + int v12; // edx + int v13; // eax + int v14; // ecx + char v15; // al + int v16; // ecx + char v17; // al + int v18; // [esp+Ch] [ebp-10h] + char *v19; // [esp+10h] [ebp-Ch] + int v20; // [esp+14h] [ebp-8h] + char v21; // [esp+18h] [ebp-4h] + + v21 = colour; + if ( pCelBuff ) + { + if ( gpBuffer ) + { + v8 = &pCelBuff[4 * frame]; + v19 = &pCelBuff[*(_DWORD *)v8]; + v18 = *(unsigned short *)&v19[a7]; + if ( *(_WORD *)&v19[a7] ) + { + if ( direction == 8 ) + v9 = 0; + else + v9 = *(unsigned short *)&v19[direction]; + if ( v9 ) + v20 = v9 - v18; + else + v20 = *((_DWORD *)v8 + 1) - *(_DWORD *)v8 - v18; + v10 = &v19[v18]; + v11 = (char *)gpBuffer + screen_y_times_768[screen_y - 16 * a7] + screen_x; + do + { + v12 = frame_width; + do + { + while ( 1 ) + { + v13 = (unsigned char)*v10++; + if ( (v13 & 0x80u) == 0 ) + break; + _LOBYTE(v13) = -(char)v13; + v11 += v13; + v12 -= v13; + if ( !v12 ) + goto LABEL_28; + } + v12 -= v13; + if ( (unsigned int)v11 < screen_buf_end ) + { + if ( (unsigned int)v11 >= screen_buf_end - 768 ) + { + v16 = v13; + do + { + v17 = *v10++; + if ( v17 ) + { + *(v11 - 768) = v21; + *(v11 - 1) = v21; + v11[1] = v21; + } + ++v11; + --v16; + } + while ( v16 ); + } + else + { + v14 = v13; + do + { + v15 = *v10++; + if ( v15 ) + { + *(v11 - 768) = v21; + *(v11 - 1) = v21; + v11[1] = v21; + v11[768] = v21; + } + ++v11; + --v14; + } + while ( v14 ); + } + } + else + { + v10 += v13; + v11 += v13; + } + } + while ( v12 ); +LABEL_28: + v11 += -frame_width - 768; + } + while ( &v19[v18 + v20] != v10 ); + } + } + } +} +// 69CF0C: using guessed type int screen_buf_end; + +//----- (00416FEF) -------------------------------------------------------- +void __fastcall ENG_set_pixel(int screen_x, int screen_y, char pixel) +{ + char *v3; // edi + + if ( screen_y >= 0 && screen_y < 640 && screen_x >= 64 && screen_x < 704 ) + { + v3 = (char *)gpBuffer + screen_y_times_768[screen_y] + screen_x; + if ( (unsigned int)v3 < screen_buf_end ) + *v3 = pixel; + } +} +// 69CF0C: using guessed type int screen_buf_end; + +//----- (00417034) -------------------------------------------------------- +void __fastcall engine_417034(int x, int y) +{ + _BYTE *v2; // eax + + if ( dword_52B970 ) + { + if ( !dword_52B99C || x >= 0 && x < 640 && y >= 64 && y < 704 ) + { + v2 = (unsigned char *)gpBuffer + screen_y_times_768[x] + y; + goto LABEL_14; + } + } + else if ( !dword_52B99C || y >= 0 && y < 640 && x >= 64 && x < 704 ) + { + v2 = (unsigned char *)gpBuffer + screen_y_times_768[y] + x; +LABEL_14: + if ( (unsigned int)v2 < screen_buf_end ) + *v2 = byte_52B96C; + return; + } +} +// 52B96C: using guessed type char byte_52B96C; +// 52B970: using guessed type int dword_52B970; +// 52B99C: using guessed type int dword_52B99C; +// 69CF0C: using guessed type int screen_buf_end; + +//----- (004170BD) -------------------------------------------------------- +void __fastcall engine_4170BD(int x1, int y1, int x2, int y2, char a5) +{ + int v5; // edi + int v6; // edx + int v7; // ecx + int v8; // eax + int v9; // edx + int v10; // eax + int v11; // ebx + int v12; // edx + int v13; // eax + int v14; // esi + int v15; // edi + __int64 v16; // rax + int v17; // ebx + int v18; // esi + int v19; // edx + int v20; // edx + int v21; // edx + int v22; // edx + int v23; // edx + int v24; // esi + int v25; // edx + int v26; // ecx + int v27; // esi + int v28; // edx + int v29; // edx + int v30; // esi + int v31; // ebx + int v32; // edi + int v33; // ebx + int v34; // edx + int v35; // eax + int v36; // edx + int v37; // edx + int v38; // edx + int v39; // edi + int v40; // esi + int v41; // esi + int v42; // esi + int v43; // edx + int v44; // [esp+Ch] [ebp-18h] + int v45; // [esp+10h] [ebp-14h] + int v46; // [esp+14h] [ebp-10h] + int v47; // [esp+14h] [ebp-10h] + int v48; // [esp+18h] [ebp-Ch] + int v49; // [esp+18h] [ebp-Ch] + int v50; // [esp+18h] [ebp-Ch] + int v51; // [esp+1Ch] [ebp-8h] + int v52; // [esp+1Ch] [ebp-8h] + int v53; // [esp+1Ch] [ebp-8h] + signed int v54; // [esp+20h] [ebp-4h] + int xa; // [esp+2Ch] [ebp+8h] + int x; // [esp+2Ch] [ebp+8h] + signed int a4; // [esp+30h] [ebp+Ch] + int a5a; // [esp+34h] [ebp+10h] + int a5b; // [esp+34h] [ebp+10h] + + dword_52B99C = 0; + v5 = y1; + v6 = x1; + byte_52B96C = a5; + v51 = v5; + v48 = x1; + if ( x1 < 64 || x1 >= 704 ) + dword_52B99C = 1; + if ( x2 < 64 || x2 >= 704 ) + dword_52B99C = 1; + if ( v5 < 160 || v5 >= 512 ) + dword_52B99C = 1; + v7 = y2; + if ( y2 < 160 || y2 >= 512 ) + dword_52B99C = 1; + v8 = x2 - v6; + v9 = 2 * (x2 - v6 >= 0) - 1; + v10 = v9 * v8; + v46 = v10; + v11 = (2 * (y2 - v5 >= 0) - 1) * (y2 - v5); + a4 = 2 * (v9 == 2 * (y2 - v5 >= 0) - 1) - 1; + v12 = v48; + if ( v11 <= v10 ) + { + dword_52B970 = 0; + } + else + { + xa = v7 ^ x2; + v7 ^= xa; + v13 = v11 ^ v10; + v51 = v5 ^ v48 ^ v5; + v11 ^= v13; + v12 = v51 ^ v5 ^ v48; + x2 = v7 ^ xa; + v10 = v11 ^ v13; + dword_52B970 = 1; + v46 = v10; + } + v14 = x2; + if ( v12 <= x2 ) + { + v15 = v51; + v14 = v12; + v12 = x2; + } + else + { + v15 = v7; + v7 = v51; + } + a5a = v12; + x = v7; + v16 = v10 - 1; + v54 = v16 % 4; + v45 = v16 / 4; + engine_417034(v14, v15); + engine_417034(a5a, x); + v49 = 2 * v11; + v44 = 2 * (2 * v11 - v46); + if ( v44 >= 0 ) + { + v50 = 2 * (v11 - v46); + v53 = v46 + 4 * (v11 - v46); + if ( v45 <= 0 ) + { + v33 = a5a; + } + else + { + do + { + v30 = v14 + 1; + v31 = a5a - 1; + if ( v53 <= 0 ) + { + if ( v53 >= v50 ) + { + v15 += a4; + engine_417034(v30, v15); + v14 = v30 + 1; + engine_417034(v14, v38); + x -= a4; + engine_417034(v31, x); + } + else + { + engine_417034(v30, v15); + v15 += a4; + v14 = v30 + 1; + engine_417034(v14, v15); + engine_417034(v31, x); + v37 = v36 - a4; + x = v37; + } + v33 = a5a - 2; + a5a = v33; + engine_417034(v33, v37); + v35 = v44; + } + else + { + v32 = a4 + v15; + engine_417034(v30, v32); + v15 = a4 + v32; + v14 = v30 + 1; + engine_417034(v14, v15); + engine_417034(v31, x - a4); + v33 = a5a - 2; + a5a = v33; + x = v34 - a4; + engine_417034(v33, v34 - a4); + v35 = 2 * v50; + } + v53 += v35; + --v45; + } + while ( v45 ); + } + if ( !v54 ) + return; + if ( v53 > 0 ) + { + v39 = a4 + v15; + v40 = v14 + 1; + engine_417034(v40, v39); + if ( v54 > 1 ) + engine_417034(v40 + 1, v39 + a4); + if ( v54 <= 2 ) + return; + goto LABEL_71; + } + if ( v53 >= v50 ) + { + v42 = v14 + 1; + engine_417034(v42, a4 + v15); + if ( v54 > 1 ) + engine_417034(v42 + 1, v43); + if ( v54 <= 2 ) + return; + if ( v53 > v50 ) + { +LABEL_71: + v26 = v33 - 1; + v29 = x - a4; + goto LABEL_65; + } + } + else + { + v41 = v14 + 1; + engine_417034(v41, v15); + if ( v54 > 1 ) + engine_417034(v41 + 1, v15 + a4); + if ( v54 <= 2 ) + return; + } + v26 = v33 - 1; +LABEL_64: + v29 = x; + goto LABEL_65; + } + v52 = 4 * v11; + v17 = 4 * v11 - v46; + if ( v45 > 0 ) + { + v47 = v45; + do + { + v18 = v14 + 1; + a5b = a5a - 1; + if ( v17 >= 0 ) + { + if ( v17 >= v49 ) + { + v15 += a4; + engine_417034(v18, v15); + v14 = v18 + 1; + engine_417034(v14, v23); + x -= a4; + engine_417034(a5b, x); + } + else + { + engine_417034(v18, v15); + v15 += a4; + v14 = v18 + 1; + engine_417034(v14, v15); + engine_417034(a5b, x); + v22 = v21 - a4; + x = v22; + } + a5a = a5b - 1; + engine_417034(a5a, v22); + v17 += v44; + } + else + { + engine_417034(v18, v15); + v14 = v18 + 1; + engine_417034(v14, v19); + engine_417034(a5b, x); + a5a = a5b - 1; + engine_417034(a5a, v20); + v17 += v52; + } + --v47; + } + while ( v47 ); + } + if ( v54 ) + { + if ( v17 < 0 ) + { + v24 = v14 + 1; + engine_417034(v24, v15); + if ( v54 > 1 ) + goto LABEL_36; + goto LABEL_37; + } + if ( v17 < v49 ) + { + v24 = v14 + 1; + engine_417034(v24, v15); + if ( v54 > 1 ) + { + v25 = v15 + a4; +LABEL_36: + engine_417034(v24 + 1, v25); + } +LABEL_37: + if ( v54 <= 2 ) + return; + v26 = a5a - 1; + goto LABEL_64; + } + v27 = v14 + 1; + engine_417034(v27, a4 + v15); + if ( v54 > 1 ) + engine_417034(v27 + 1, v28); + if ( v54 > 2 ) + { + v29 = x - a4; + v26 = a5a - 1; +LABEL_65: + engine_417034(v26, v29); + return; + } + } +} +// 52B96C: using guessed type char byte_52B96C; +// 52B970: using guessed type int dword_52B970; +// 52B99C: using guessed type int dword_52B99C; + +//----- (004174B3) -------------------------------------------------------- +int __fastcall GetDirection(int x1, int y1, int x2, int y2) +{ + int v4; // esi + int v5; // ecx + int v6; // edx + int result; // eax + int v8; // esi + int v9; // edx + + v4 = x2 - x1; + v5 = y2 - y1; + if ( v4 < 0 ) + { + v8 = -v4; + v9 = 2 * v8; + if ( v5 < 0 ) + { + v5 = -v5; + result = 4; + if ( v9 < v5 ) + result = 5; + } + else + { + result = 2; + if ( v9 < v5 ) + result = 1; + } + if ( 2 * v5 < v8 ) + return 3; + } + else + { + v6 = 2 * v4; + if ( v5 < 0 ) + { + v5 = -v5; + result = 6; + if ( v6 < v5 ) + result = 5; + } + else + { + result = 0; + if ( v6 < v5 ) + result = 1; + } + if ( 2 * v5 < v4 ) + return 7; + } + return result; +} + +//----- (00417518) -------------------------------------------------------- +void __fastcall SetRndSeed(int s) +{ + SeedCount = 0; + sglGameSeed = s; + orgseed = s; +} +// 52B974: using guessed type int orgseed; +// 52B97C: using guessed type int sglGameSeed; +// 52B998: using guessed type int SeedCount; + +//----- (0041752C) -------------------------------------------------------- +int __cdecl GetRndSeed() +{ + ++SeedCount; + sglGameSeed = 22695477 * sglGameSeed + 1; + return abs(sglGameSeed); +} +// 52B97C: using guessed type int sglGameSeed; +// 52B998: using guessed type int SeedCount; + +//----- (0041754B) -------------------------------------------------------- +int __fastcall random(int unused, int max) +{ + int v2; // esi + int v4; // eax + + v2 = max; + if ( max <= 0 ) + return 0; + v4 = GetRndSeed(); + if ( v2 < 0xFFFF ) + v4 >>= 16; + return v4 % v2; +} + +//----- (0041756D) -------------------------------------------------------- +void __cdecl engine_cpp_init_2() +{ + mem_init_mutex(); + mem_atexit_mutex(); +} + +//----- (00417577) -------------------------------------------------------- +void __cdecl mem_init_mutex() +{ + InitializeCriticalSection(&sgMemCrit); +} + +//----- (00417583) -------------------------------------------------------- +void __cdecl mem_atexit_mutex() +{ + atexit(mem_free_mutex); +} + +//----- (0041758F) -------------------------------------------------------- +void __cdecl mem_free_mutex() +{ + DeleteCriticalSection(&sgMemCrit); +} + +//----- (0041759B) -------------------------------------------------------- +void *__fastcall DiabloAllocPtr(int size) +{ + int v1; // ebx + void *v2; // ebx + int v3; // eax + + v1 = size; + EnterCriticalSection(&sgMemCrit); + v2 = SMemAlloc(v1, "C:\\Src\\Diablo\\Source\\ENGINE.CPP", 2236, 0); + LeaveCriticalSection(&sgMemCrit); + if ( !v2 ) + { + v3 = GetLastError(); + TermDlg(105, v3, "C:\\Src\\Diablo\\Source\\ENGINE.CPP", 2269); + } + return v2; +} + +//----- (004175E8) -------------------------------------------------------- +void __fastcall mem_free_dbg(void *ptr) +{ + void *v1; // edi + + v1 = ptr; + if ( ptr ) + { + EnterCriticalSection(&sgMemCrit); + SMemFree(v1, "C:\\Src\\Diablo\\Source\\ENGINE.CPP", 2317, 0); + LeaveCriticalSection(&sgMemCrit); + } +} + +//----- (00417618) -------------------------------------------------------- +unsigned char *__fastcall LoadFileInMem(char *file_path, void *size) +{ + _DWORD *v2; // edi + char *v3; // ebx + int v4; // eax + int v5; // esi + char *v6; // edi + void *a1; // [esp+Ch] [ebp-4h] + + v2 = (unsigned int *)size; + v3 = file_path; + wave_open_file((LPARAM)file_path, (DIABFILE *)&a1, 0); + v4 = wave_get_file_size((int *)a1, 0); + v5 = v4; + if ( v2 ) + *v2 = v4; + if ( !v4 ) + TermMsg("Zero length SFILE:\n%s", v3); + v6 = (char *)DiabloAllocPtr(v5); + wave_read_file((int)a1, v6, v5); + wave_close_file(a1); + return (unsigned char *)v6; +} + +//----- (00417673) -------------------------------------------------------- +void __fastcall LoadFileWithMem(char *pszName, void *buf) +{ + char *v2; // ebx + char *v3; // edi + int v4; // esi + void *a1; // [esp+Ch] [ebp-4h] + + v2 = (char *)buf; + v3 = pszName; + if ( !buf ) + TermMsg("LoadFileWithMem(NULL):\n%s", pszName); + wave_open_file((LPARAM)v3, (DIABFILE *)&a1, 0); + v4 = wave_get_file_size((int *)a1, 0); + if ( !v4 ) + TermMsg("Zero length SFILE:\n%s", v3); + wave_read_file((int)a1, v2, v4); + wave_close_file(a1); +} + +//----- (004176D2) -------------------------------------------------------- +void __fastcall engine_cel_trn(int p, int ttbl, int a3) +{ + int v3; // eax + int v4; // edi + int v5; // esi + char *v6; // eax + char v7; // bl + unsigned char v8; // bl + int v9; // edi + int i; // [esp+0h] [ebp-4h] + + v3 = 1; + for ( i = 1; i <= a3; ++i ) + { + v4 = *(_DWORD *)(4 * v3 + p); + v5 = *(_DWORD *)(4 * v3 + p + 4) - v4 - 10; + v6 = (char *)(v4 + p + 10); + while ( v5 ) + { + v7 = *v6++; + --v5; + if ( v7 < 0 ) + { + v8 = -v7; + if ( (char)v8 <= 65 ) + { + v5 -= (char)v8; + if ( v8 ) + { + v9 = v8; + do + { + *v6 = *(_BYTE *)((unsigned char)*v6 + ttbl); + ++v6; + --v9; + } + while ( v9 ); + } + } + else + { + --v5; + *v6 = *(_BYTE *)((unsigned char)*v6 + ttbl); + ++v6; + } + } + } + v3 = i + 1; + } +} + +//----- (00417745) -------------------------------------------------------- +void __fastcall engine_417745(int a1, int a2, void *pCelBuff, int nCel, int a5, int a6, int a7) +{ + int v7; // ebx + void *v8; // edx + char *v9; // ecx + int v10; // ecx + int v11; // eax + int v12; // [esp+Ch] [ebp-4h] + void *pCelBuffa; // [esp+18h] [ebp+8h] + + v7 = a2; + v12 = a1; + if ( gpBuffer ) + { + v8 = pCelBuff; + if ( pCelBuff ) + { + if ( nCel > 0 ) + { + v9 = (char *)*((_DWORD *)pCelBuff + nCel); + pCelBuffa = v9; + v10 = (int)&v9[(_DWORD)v8]; + if ( *(_WORD *)(v10 + a6) ) + { + if ( a7 == 8 || (v11 = *(unsigned short *)(v10 + a7), !*(_WORD *)(v10 + a7)) ) + v11 = *((_DWORD *)v8 + nCel + 1) - (_DWORD)pCelBuffa; + engine_4177BF( + (char *)gpBuffer + screen_y_times_768[v7 - 16 * a6] + v12, + (char *)(*(unsigned short *)(v10 + a6) + v10), + v11 - *(unsigned short *)(v10 + a6), + a5); + } + } + } + } +} + +//----- (004177BF) -------------------------------------------------------- +void __fastcall engine_4177BF(char *buffer, char *a2, int a3, int a4) +{ + char *v4; // esi + char *v5; // edi + int v6; // eax + int v7; // ebx + int v8; // ecx + char v9; // dl + char v10; // dl + int v11; // edx + + v4 = a2; + v5 = buffer; + v6 = 0; + v7 = a4; + v8 = a3; + do + { + _LOBYTE(v6) = *v4++; + --v8; + if ( (v6 & 0x80u) == 0 ) + { + do + { + if ( v6 <= v7 ) + { + v11 = v6; + v5 += v6; + v6 = 0; + } + else + { + v11 = v7; + v5 += v7; + v6 -= v7; + } + v7 -= v11; + if ( !v7 ) + { + v7 = a4; + v5 = &v5[-a4 - 768]; + } + } + while ( v6 ); + } + else + { + _LOBYTE(v6) = -(char)v6; + if ( (char)v6 <= 65 ) + { + v8 -= v6; + v7 -= v6; + do + { + v10 = *v4++; + *v5 = v10; + --v6; + ++v5; + } + while ( v6 ); + } + else + { + _LOBYTE(v6) = v6 - 65; + --v8; + v9 = *v4++; + v7 -= v6; + do + { + *v5 = v9; + --v6; + ++v5; + } + while ( v6 ); + } + if ( !v7 ) + { + v7 = a4; + v5 = &v5[-a4 - 768]; + } + } + } + while ( v8 ); +} + +//----- (00417847) -------------------------------------------------------- +void __fastcall engine_417847(char a1, int a2, int a3, void *pCelBuff, int nCel, int a6, int a7, int a8) +{ + int v8; // ebx + char *v9; // edx + int v10; // eax + int v11; // [esp+Ch] [ebp-8h] + + v11 = a2; + if ( gpBuffer ) + { + if ( pCelBuff ) + { + if ( nCel > 0 ) + { + v8 = *((_DWORD *)pCelBuff + nCel); + v9 = (char *)pCelBuff + v8; + if ( *(_WORD *)((char *)pCelBuff + v8 + a7) ) + { + if ( a8 == 8 || (v10 = *(unsigned short *)&v9[a8], !*(_WORD *)&v9[a8]) ) + v10 = *((_DWORD *)pCelBuff + nCel + 1) - v8; + engine_4178C5( + (char *)gpBuffer + screen_y_times_768[a3 - 16 * a7] + v11, + &v9[*(unsigned short *)((char *)pCelBuff + v8 + a7)], + (char *)(v10 - *(unsigned short *)((char *)pCelBuff + v8 + a7)), + a6, + a1); + } + } + } + } +} + +//----- (004178C5) -------------------------------------------------------- +void __fastcall engine_4178C5(char *buffer, char *a2, char *a3, int a4, char a5) +{ + char *v5; // esi + char *v6; // edi + int v7; // eax + int v8; // ebx + char *v9; // ecx + char v10; // dl + char v11; // dh + char v12; // dh + int v13; // edx + + v5 = a2; + v6 = buffer; + v7 = 0; + v8 = a4; + v9 = a3; + v10 = a5; + do + { + _LOBYTE(v7) = *v5++; + --v9; + if ( (v7 & 0x80u) != 0 ) + { + _LOBYTE(v7) = -(char)v7; + if ( (char)v7 <= 65 ) + { + v9 -= v7; + v8 -= v7; + do + { + v12 = *v5++; + if ( v12 ) + { + *(v6 - 1) = v10; + v6[1] = v10; + *(v6 - 768) = v10; + v6[768] = v10; + } + --v7; + ++v6; + } + while ( v7 ); + goto LABEL_12; + } + _LOBYTE(v7) = v7 - 65; + --v9; + v11 = *v5++; + if ( v11 ) + { + *(v6 - 1) = v10; + v8 -= v7; + v6[v7] = v10; + do + { + *(v6 - 768) = v10; + v6[768] = v10; + --v7; + ++v6; + } + while ( v7 ); +LABEL_12: + if ( !v8 ) + { + v8 = a4; + v6 = &v6[-a4 - 768]; + } + continue; + } + } + do + { + if ( v7 <= v8 ) + { + v13 = v7; + v6 += v7; + v7 = 0; + } + else + { + v13 = v8; + v6 += v8; + v7 -= v8; + } + v8 -= v13; + if ( !v8 ) + { + v8 = a4; + v6 = &v6[-a4 - 768]; + } + } + while ( v7 ); + v10 = a5; + } + while ( v9 ); +} + +//----- (00417981) -------------------------------------------------------- +void __fastcall engine_417981(int a1, int a2, void *pCelBuff, int nCel, int a5, int a6, int a7, char a8) +{ + _DWORD *v8; // edi + int v9; // ebx + char *v10; // esi + int v11; // eax + int v12; // eax + char *v13; // esi + int v14; // edi + int v15; // eax + int v16; // eax + void *pCelBuffa; // [esp+18h] [ebp+8h] + + if ( gpBuffer ) + { + v8 = (unsigned int *)pCelBuff; + if ( pCelBuff ) + { + if ( nCel > 0 ) + { + v9 = *((_DWORD *)pCelBuff + nCel); + v10 = (char *)pCelBuff + v9; + v11 = *(unsigned short *)((char *)pCelBuff + v9 + a6); + pCelBuffa = (void *)*(unsigned short *)((char *)pCelBuff + v9 + a6); + if ( v11 ) + { + if ( a7 == 8 || (v12 = *(unsigned short *)&v10[a7], !*(_WORD *)&v10[a7]) ) + v12 = v8[nCel + 1] - v9; + v13 = &v10[(_DWORD)pCelBuffa]; + v14 = v12 - (_DWORD)pCelBuffa; + v15 = -(light4flag != 0); + _LOWORD(v15) = v15 & 0xF400; + v16 = v15 + 4096; + if ( a8 == 2 ) + v16 += 256; + if ( a8 >= 4 ) + v16 = v16 + (a8 << 8) - 256; + engine_417A44( + (char *)gpBuffer + screen_y_times_768[a2 - 16 * a6] + a1, + v13, + v14, + a5, + v16 + dword_646A20); + } + } + } + } +} +// 525728: using guessed type int light4flag; + +//----- (00417A44) -------------------------------------------------------- +void __fastcall engine_417A44(char *a1, char *a2, int a3, int a4, int unused_lindex) +{ + char *v5; // esi + char *v6; // edi + int v7; // ebx + int v8; // ecx + int v9; // eax + int v10; // edx + char v11; // dl + char vars0[4]; // [esp+Ch] [ebp+0h] + + v5 = a2; + v6 = a1; + v7 = a4; + v8 = a3; + dword_52B978 = a4; + v9 = 0; + v10 = 0; + do + { + _LOBYTE(v9) = *v5++; + --v8; + if ( (v9 & 0x80u) == 0 ) + { + do + { + if ( v9 <= v7 ) + { + v10 = v9; + v6 += v9; + v9 = 0; + } + else + { + v10 = v7; + v6 += v7; + v9 -= v7; + } + v7 -= v10; + if ( !v7 ) + { + v7 = dword_52B978; + v6 = &v6[-dword_52B978 - 768]; + } + } + while ( v9 ); + } + else + { + _LOBYTE(v9) = -(char)v9; + if ( (char)v9 <= 65 ) + { + v8 -= v9; + v7 -= v9; + do + { + _LOBYTE(v10) = *v5++; + *v6 = vars0[v10]; + --v9; + ++v6; + } + while ( v9 ); + } + else + { + _LOBYTE(v9) = v9 - 65; + --v8; + v7 -= v9; + _LOBYTE(v10) = *v5++; + v11 = vars0[v10]; + do + { + *v6 = v11; + --v9; + ++v6; + } + while ( v9 ); + } + if ( !v7 ) + { + v7 = dword_52B978; + v6 = &v6[-dword_52B978 - 768]; + } + } + } + while ( v8 ); +} +// 52B978: using guessed type int dword_52B978; +// 417A44: using guessed type char var_s0[4]; + +//----- (00417AE9) -------------------------------------------------------- +void __fastcall engine_417AE9(int a1, int a2, void *pCelBuff, int nCel, int a5, int a6, int a7) +{ + int v7; // esi + _DWORD *v8; // edi + int v9; // ebx + char *v10; // edx + int v11; // eax + int v12; // eax + int v13; // eax + char *v14; // edx + char *v15; // ecx + void *pCelBuffa; // [esp+18h] [ebp+8h] + + v7 = a2; + if ( gpBuffer ) + { + v8 = (unsigned int *)pCelBuff; + if ( pCelBuff ) + { + if ( nCel > 0 ) + { + v9 = *((_DWORD *)pCelBuff + nCel); + v10 = (char *)pCelBuff + v9; + v11 = *(unsigned short *)((char *)pCelBuff + v9 + a6); + pCelBuffa = (void *)*(unsigned short *)((char *)pCelBuff + v9 + a6); + if ( v11 ) + { + if ( a7 == 8 || (v12 = *(unsigned short *)&v10[a7], !*(_WORD *)&v10[a7]) ) + v12 = v8[nCel + 1] - v9; + v13 = v12 - (_DWORD)pCelBuffa; + v14 = &v10[(_DWORD)pCelBuffa]; + v15 = (char *)gpBuffer + screen_y_times_768[v7 - 16 * a6] + a1; + if ( light_table_index ) + engine_417A44(v15, v14, v13, a5, dword_646A20 + (light_table_index << 8)); + else + engine_4177BF(v15, v14, v13, a5); + } + } + } + } +} +// 69BEF8: using guessed type int light_table_index; + +//----- (00417B83) -------------------------------------------------------- +void __fastcall engine_417B83(int a1, int a2, void *pCelBuff, int nCel, int a5, int a6, int a7) +{ + int v7; // ebx + void *v8; // edx + char *v9; // ecx + int v10; // ecx + int v11; // eax + int v12; // [esp+Ch] [ebp-4h] + void *pCelBuffa; // [esp+18h] [ebp+8h] + + v7 = a2; + v12 = a1; + if ( gpBuffer ) + { + v8 = pCelBuff; + if ( pCelBuff ) + { + if ( nCel > 0 ) + { + v9 = (char *)*((_DWORD *)pCelBuff + nCel); + pCelBuffa = v9; + v10 = (int)&v9[(_DWORD)v8]; + if ( *(_WORD *)(v10 + a6) ) + { + if ( a7 == 8 || (v11 = *(unsigned short *)(v10 + a7), !*(_WORD *)(v10 + a7)) ) + v11 = *((_DWORD *)v8 + nCel + 1) - (_DWORD)pCelBuffa; + engine_417BFD( + (char *)gpBuffer + screen_y_times_768[v7 - 16 * a6] + v12, + (char *)(*(unsigned short *)(v10 + a6) + v10), + v11 - *(unsigned short *)(v10 + a6), + a5); + } + } + } + } +} + +//----- (00417BFD) -------------------------------------------------------- +void __fastcall engine_417BFD(char *a1, char *a2, int a3, int a4) +{ + char *v4; // esi + char *v5; // edi + int v6; // eax + int v7; // ebx + int v8; // ecx + char v9; // dl + char v10; // dl + int v11; // edx + + v4 = a2; + v5 = a1; + v6 = 0; + v7 = a4; + v8 = a3; + do + { + _LOBYTE(v6) = *v4++; + --v8; + if ( (v6 & 0x80u) != 0 ) + { + _LOBYTE(v6) = -(char)v6; + if ( (char)v6 <= 65 ) + { + v8 -= v6; + if ( (signed int)v5 < screen_buf_end ) + { + v7 -= v6; + do + { + v10 = *v4++; + *v5 = v10; + --v6; + ++v5; + } + while ( v6 ); + goto LABEL_12; + } + v4 += v6; + } + else + { + _LOBYTE(v6) = v6 - 65; + --v8; + v9 = *v4++; + if ( (signed int)v5 < screen_buf_end ) + { + v7 -= v6; + do + { + *v5 = v9; + --v6; + ++v5; + } + while ( v6 ); +LABEL_12: + if ( !v7 ) + { + v7 = a4; + v5 = &v5[-a4 - 768]; + } + continue; + } + } + } + do + { + if ( v6 <= v7 ) + { + v11 = v6; + v5 += v6; + v6 = 0; + } + else + { + v11 = v7; + v5 += v7; + v6 -= v7; + } + v7 -= v11; + if ( !v7 ) + { + v7 = a4; + v5 = &v5[-a4 - 768]; + } + } + while ( v6 ); + } + while ( v8 ); +} +// 69CF0C: using guessed type int screen_buf_end; + +//----- (00417C99) -------------------------------------------------------- +void __fastcall engine_417C99(char a1, int a2, int a3, void *pCelBuff, int nCel, int a6, int a7, int a8) +{ + int v8; // ebx + char *v9; // edx + int v10; // ecx + int v11; // eax + int v12; // [esp+Ch] [ebp-8h] + char a5; // [esp+10h] [ebp-4h] + + v12 = a2; + a5 = a1; + if ( gpBuffer ) + { + if ( pCelBuff ) + { + if ( nCel > 0 ) + { + v8 = *((_DWORD *)pCelBuff + nCel); + v9 = (char *)pCelBuff + v8; + v10 = *(unsigned short *)((char *)pCelBuff + v8 + a7); + if ( *(_WORD *)((char *)pCelBuff + v8 + a7) ) + { + if ( a8 == 8 || (v11 = *(unsigned short *)&v9[a8], !*(_WORD *)&v9[a8]) ) + v11 = *((_DWORD *)pCelBuff + nCel + 1) - v8; + screen_buf_end -= 768; + engine_417D28( + (char *)gpBuffer + screen_y_times_768[a3 - 16 * a7] + v12, + &v9[v10], + v11 - v10, + a6, + a5); + screen_buf_end += 768; + } + } + } + } +} +// 69CF0C: using guessed type int screen_buf_end; + +//----- (00417D28) -------------------------------------------------------- +void __fastcall engine_417D28(char *a1, char *a2, int a3, int a4, char a5) +{ + char *v5; // esi + char *v6; // edi + int v7; // eax + int v8; // ebx + int v9; // ecx + char v10; // dl + char v11; // dh + char v12; // dh + int v13; // edx + + v5 = a2; + v6 = a1; + v7 = 0; + v8 = a4; + v9 = a3; + v10 = a5; + do + { + _LOBYTE(v7) = *v5++; + --v9; + if ( (v7 & 0x80u) != 0 ) + { + _LOBYTE(v7) = -(char)v7; + if ( (char)v7 <= 65 ) + { + v9 -= v7; + if ( (signed int)v6 < screen_buf_end ) + { + v8 -= v7; + do + { + v12 = *v5++; + if ( v12 ) + { + *(v6 - 1) = v10; + v6[1] = v10; + *(v6 - 768) = v10; + v6[768] = v10; + } + --v7; + ++v6; + } + while ( v7 ); + goto LABEL_15; + } + v5 += v7; + } + else + { + _LOBYTE(v7) = v7 - 65; + --v9; + v11 = *v5++; + if ( v11 && (signed int)v6 < screen_buf_end ) + { + *(v6 - 1) = v10; + v8 -= v7; + v6[v7] = v10; + do + { + *(v6 - 768) = v10; + v6[768] = v10; + --v7; + ++v6; + } + while ( v7 ); +LABEL_15: + if ( !v8 ) + { + v8 = a4; + v6 = &v6[-a4 - 768]; + } + continue; + } + } + } + do + { + if ( v7 <= v8 ) + { + v13 = v7; + v6 += v7; + v7 = 0; + } + else + { + v13 = v8; + v6 += v8; + v7 -= v8; + } + v8 -= v13; + if ( !v8 ) + { + v8 = a4; + v6 = &v6[-a4 - 768]; + } + } + while ( v7 ); + v10 = a5; + } + while ( v9 ); +} +// 69CF0C: using guessed type int screen_buf_end; + +//----- (00417DF8) -------------------------------------------------------- +void __fastcall engine_417DF8(int a1, int a2, void *pCelBuff, int nCel, int a5, int a6, int a7, char a8) +{ + _DWORD *v8; // edi + int v9; // ebx + char *v10; // esi + int v11; // eax + int v12; // eax + char *v13; // esi + int v14; // edi + int v15; // eax + int v16; // eax + void *pCelBuffa; // [esp+18h] [ebp+8h] + + if ( gpBuffer ) + { + v8 = (unsigned int *)pCelBuff; + if ( pCelBuff ) + { + if ( nCel > 0 ) + { + v9 = *((_DWORD *)pCelBuff + nCel); + v10 = (char *)pCelBuff + v9; + v11 = *(unsigned short *)((char *)pCelBuff + v9 + a6); + pCelBuffa = (void *)*(unsigned short *)((char *)pCelBuff + v9 + a6); + if ( v11 ) + { + if ( a7 == 8 || (v12 = *(unsigned short *)&v10[a7], !*(_WORD *)&v10[a7]) ) + v12 = v8[nCel + 1] - v9; + v13 = &v10[(_DWORD)pCelBuffa]; + v14 = v12 - (_DWORD)pCelBuffa; + v15 = -(light4flag != 0); + _LOWORD(v15) = v15 & 0xF400; + v16 = v15 + 4096; + if ( a8 == 2 ) + v16 += 256; + if ( a8 >= 4 ) + v16 = v16 + (a8 << 8) - 256; + engine_417EBB( + (char *)gpBuffer + screen_y_times_768[a2 - 16 * a6] + a1, + v13, + v14, + a5, + v16 + dword_646A20); + } + } + } + } +} +// 525728: using guessed type int light4flag; + +//----- (00417EBB) -------------------------------------------------------- +void __fastcall engine_417EBB(char *a1, char *a2, int a3, int a4, int a5) +{ + char *v5; // esi + char *v6; // edi + int v7; // ebx + int v8; // ecx + int v9; // eax + int v10; // edx + char v11; // dl + char vars0[4]; // [esp+Ch] [ebp+0h] + + v5 = a2; + v6 = a1; + v7 = a4; + v8 = a3; + dword_52B978 = a4; + v9 = 0; + v10 = 0; + do + { + _LOBYTE(v9) = *v5++; + --v8; + if ( (v9 & 0x80u) != 0 ) + { + _LOBYTE(v9) = -(char)v9; + if ( (char)v9 <= 65 ) + { + v8 -= v9; + if ( (signed int)v6 < screen_buf_end ) + { + v7 -= v9; + do + { + _LOBYTE(v10) = *v5++; + *v6 = vars0[v10]; + --v9; + ++v6; + } + while ( v9 ); + goto LABEL_12; + } + v5 += v9; + } + else + { + _LOBYTE(v9) = v9 - 65; + --v8; + _LOBYTE(v10) = *v5++; + v11 = vars0[v10]; + if ( (signed int)v6 < screen_buf_end ) + { + v7 -= v9; + do + { + *v6 = v11; + --v9; + ++v6; + } + while ( v9 ); +LABEL_12: + if ( !v7 ) + { + v7 = dword_52B978; + v6 = &v6[-dword_52B978 - 768]; + } + continue; + } + } + } + do + { + if ( v9 <= v7 ) + { + v10 = v9; + v6 += v9; + v9 = 0; + } + else + { + v10 = v7; + v6 += v7; + v9 -= v7; + } + v7 -= v10; + if ( !v7 ) + { + v7 = dword_52B978; + v6 = &v6[-dword_52B978 - 768]; + } + } + while ( v9 ); + } + while ( v8 ); +} +// 52B978: using guessed type int dword_52B978; +// 69CF0C: using guessed type int screen_buf_end; +// 417EBB: using guessed type char var_s0[4]; + +//----- (00417F78) -------------------------------------------------------- +void __fastcall engine_417F78(int a1, int a2, void *pCelBuff, int nCel, int a5, int a6, int a7) +{ + int v7; // esi + _DWORD *v8; // edi + int v9; // ebx + char *v10; // edx + int v11; // eax + int v12; // eax + int v13; // eax + char *v14; // edx + char *v15; // ecx + void *pCelBuffa; // [esp+18h] [ebp+8h] + + v7 = a2; + if ( gpBuffer ) + { + v8 = (unsigned int *)pCelBuff; + if ( pCelBuff ) + { + if ( nCel > 0 ) + { + v9 = *((_DWORD *)pCelBuff + nCel); + v10 = (char *)pCelBuff + v9; + v11 = *(unsigned short *)((char *)pCelBuff + v9 + a6); + pCelBuffa = (void *)*(unsigned short *)((char *)pCelBuff + v9 + a6); + if ( v11 ) + { + if ( a7 == 8 || (v12 = *(unsigned short *)&v10[a7], !*(_WORD *)&v10[a7]) ) + v12 = v8[nCel + 1] - v9; + v13 = v12 - (_DWORD)pCelBuffa; + v14 = &v10[(_DWORD)pCelBuffa]; + v15 = (char *)gpBuffer + screen_y_times_768[v7 - 16 * a6] + a1; + if ( light_table_index ) + engine_417EBB(v15, v14, v13, a5, dword_646A20 + (light_table_index << 8)); + else + engine_417BFD(v15, v14, v13, a5); + } + } + } + } +} +// 69BEF8: using guessed type int light_table_index; + +//----- (00418012) -------------------------------------------------------- +void __fastcall PlayInGameMovie(char *pszMovie) +{ + char *v1; // esi + + v1 = pszMovie; + PaletteFadeOut(8); + play_movie(v1, 0); + ClearScreenBuffer(); + force_redraw = 255; + scrollrt_455E65(1); + PaletteFadeIn(8); + force_redraw = 255; +} +// 52571C: using guessed type int force_redraw; + +//----- (0041804E) -------------------------------------------------------- +void __fastcall InitDiabloMsg(int error_id) +{ + int v1; // edx + bool v2; // sf + unsigned char v3; // of + + v1 = 0; + if ( msgcnt <= 0 ) + { +LABEL_4: + v3 = __OFSUB__(msgcnt, 80); + v2 = (char)(msgcnt - 80) < 0; + msgtable[msgcnt] = error_id; + if ( v2 ^ v3 ) + ++msgcnt; + msgdelay = 70; + msgflag = msgtable[0]; + } + else + { + while ( msgtable[v1] != (_BYTE)error_id ) + { + if ( ++v1 >= msgcnt ) + goto LABEL_4; + } + } +} +// 52B9F0: using guessed type char msgdelay; +// 52B9F1: using guessed type char msgflag; +// 52B9F2: using guessed type char msgcnt; + +//----- (0041808F) -------------------------------------------------------- +void __cdecl ClrDiabloMsg() +{ + msgflag = 0; + msgcnt = 0; + memset(msgtable, 0, sizeof(msgtable)); +} +// 52B9F1: using guessed type char msgflag; +// 52B9F2: using guessed type char msgcnt; + +//----- (004180AA) -------------------------------------------------------- +void __cdecl DrawDiabloMsg() +{ + int v0; // esi + signed int v1; // edi + char *v2; // edi + signed int v3; // edx + signed int v4; // ecx + int v5; // edi + signed int v6; // ecx + _BYTE *v7; // edi + int v8; // edi + signed int v9; // ebx + signed int v10; // eax + signed int v11; // ecx + int v12; // esi + signed int v13; // esi + unsigned char v14; // bl + bool v15; // zf + signed int v16; // [esp+Ch] [ebp-8h] + signed int v17; // [esp+Ch] [ebp-8h] + signed int screen_x; // [esp+10h] [ebp-4h] + + Cel_decode(165, 318, pSTextSlidCels, 1, 12); + Cel_decode(591, 318, pSTextSlidCels, 4, 12); + Cel_decode(165, 366, pSTextSlidCels, 2, 12); + Cel_decode(591, 366, pSTextSlidCels, 3, 12); + screen_x = 173; + v16 = 35; + do + { + Cel_decode(screen_x, 318, pSTextSlidCels, 5, 12); + Cel_decode(screen_x, 366, pSTextSlidCels, 7, 12); + screen_x += 12; + --v16; + } + while ( v16 ); + v0 = 330; + v1 = 3; + do + { + Cel_decode(165, v0, pSTextSlidCels, 6, 12); + Cel_decode(591, v0, pSTextSlidCels, 8, 12); + v0 += 12; + --v1; + } + while ( v1 ); + v2 = &gpBuffer->row[203].pixels[104]; + v3 = 27; + do + { + v4 = 216; + do + { + *v2 = 0; + v2 += 2; + --v4; + } + while ( v4 ); + v5 = (int)(v2 - 1200); + v6 = 216; + do + { + v7 = (_BYTE *)(v5 + 1); + *v7 = 0; + v5 = (int)(v7 + 1); + --v6; + } + while ( v6 ); + v2 = (char *)(v5 - 1200); + --v3; + } + while ( v3 ); + strcpy(tempstr, MsgStrings[msgflag]); + v8 = screen_y_times_768[342] + 165; + v9 = strlen(tempstr); + v10 = 0; + v11 = 0; + v17 = v9; + if ( v9 <= 0 ) + goto LABEL_27; + do + { + v12 = (unsigned char)tempstr[v11++]; + v10 += fontkern[fontframe[fontidx[v12]]] + 1; + } + while ( v11 < v9 ); + if ( v10 < 442 ) +LABEL_27: + v8 += (442 - v10) >> 1; + v13 = 0; + if ( v9 > 0 ) + { + do + { + v14 = fontframe[fontidx[(unsigned char)tempstr[v13]]]; + if ( v14 ) + CPrintString(v8, (char *)v14, 3); + ++v13; + v8 += fontkern[v14] + 1; + } + while ( v13 < v17 ); + } + v15 = msgdelay == 0; + if ( msgdelay > 0 ) + v15 = --msgdelay == 0; + if ( v15 ) + { + v15 = msgcnt-- == 1; + msgdelay = 70; + if ( v15 ) + msgflag = 0; + else + msgflag = msgtable[msgcnt]; + } +} +// 52B9F0: using guessed type char msgdelay; +// 52B9F1: using guessed type char msgflag; +// 52B9F2: using guessed type char msgcnt; + +//----- (004182AD) -------------------------------------------------------- +void __cdecl exception_cpp_init() +{ + exception_install_filter(); + j_exception_init_filter(); +} + +//----- (004182B7) -------------------------------------------------------- +int *__cdecl exception_install_filter() +{ + int *result; // eax + + exception_set_filter(); + return result; +} + +//----- (004182C1) -------------------------------------------------------- +void __cdecl j_exception_init_filter() +{ + atexit(exception_init_filter); +} + +//----- (004182CD) -------------------------------------------------------- +void __cdecl exception_init_filter() +{ + exception_set_filter_ptr(); +} + +//----- (004182D7) -------------------------------------------------------- +LONG __fastcall TopLevelExceptionFilter(struct _EXCEPTION_POINTERS *ExceptionInfo) +{ + DWORD *v1; // esi + int v2; // eax + PCONTEXT v3; // esi + LONG result; // eax + CHAR v5[260]; // [esp+Ch] [ebp-210h] + char String1[260]; // [esp+110h] [ebp-10Ch] + int a5; // [esp+214h] [ebp-8h] + int a4; // [esp+218h] [ebp-4h] + struct _EXCEPTION_POINTERS *ExceptionInfoa; // [esp+224h] [ebp+8h] + + log_dump_computer_info(); + v1 = &ExceptionInfoa->ExceptionRecord->ExceptionCode; + v2 = exception_get_error_type(ExceptionInfoa->ExceptionRecord->ExceptionCode, v5, 0x104u); + log_printf("Exception code: %08X %s\r\n", *v1, v2); + exception_unknown_module((LPCVOID)v1[3], String1, 260, (int)&a4, (int)&a5); + log_printf("Fault address:\t%08X %02X:%08X %s\r\n", v1[3], a4, a5, String1); + v3 = ExceptionInfoa->ContextRecord; + log_printf("\r\nRegisters:\r\n"); + log_printf( + "EAX:%08X\r\nEBX:%08X\r\nECX:%08X\r\nEDX:%08X\r\nESI:%08X\r\nEDI:%08X\r\n", + v3->Eax, + v3->Ebx, + v3->Ecx, + v3->Edx, + v3->Esi, + v3->Edi); + log_printf("CS:EIP:%04X:%08X\r\n", v3->SegCs, v3->Eip); + log_printf("SS:ESP:%04X:%08X EBP:%08X\r\n", v3->SegSs, v3->Esp, v3->Ebp); + log_printf("DS:%04X ES:%04X FS:%04X GS:%04X\r\n", v3->SegDs, v3->SegEs, v3->SegFs, v3->SegGs); + log_printf("Flags:%08X\r\n", v3->EFlags); + exception_call_stack((void *)v3->Eip, (LPVOID)v3->Ebp); + log_printf("Stack bytes:\r\n"); + exception_hex_format((char *)v3->Esp, 0); + log_printf("Code bytes:\r\n"); + exception_hex_format((char *)v3->Eip, 16); + log_printf("\r\n"); + log_flush(1); + if ( lpTopLevelExceptionFilter ) + result = lpTopLevelExceptionFilter(ExceptionInfoa); + else + result = 0; + return result; +} + +//----- (00418455) -------------------------------------------------------- +int __fastcall exception_hex_format(char *a1, char a2) +{ + unsigned int v2; // ebp + char *v3; // edi + UINT_PTR v4; // ebx + unsigned int v5; // esi + char *v6; // eax + int v7; // ST04_4 + UINT_PTR v8; // esi + unsigned char v9; // al + int result; // eax + + v2 = a2; + v3 = a1; + if ( a2 ) + { + do + { + v4 = 16; + if ( v2 < 0x10 ) + v4 = v2; + if ( IsBadReadPtr(v3, v4) ) + break; + log_printf("0x%08x: "); + v5 = 0; + do + { + v6 = "%02x "; + if ( v5 >= v4 ) + v6 = " "; + v7 = (unsigned char)v3[v5]; + log_printf(v6); + if ( (v5 & 3) == 3 ) + log_printf(" "); + ++v5; + } + while ( v5 < 0x10 ); + v8 = 0; + if ( v4 ) + { + do + { + if ( isprint((unsigned char)v3[v8]) ) + v9 = v3[v8]; + else + v9 = 46; + log_printf("%c", v9); + ++v8; + } + while ( v8 < v4 ); + } + log_printf("\r\n"); + v3 += v4; + v2 -= v4; + } + while ( v2 ); + } + log_printf("\r\n"); + return result; +} + +//----- (00418518) -------------------------------------------------------- +int __fastcall exception_unknown_module(LPCVOID lpAddress, LPSTR lpString1, int iMaxLength, int a4, int a5) +{ + LPCVOID v5; // esi + int result; // eax + unsigned int v7; // edi + unsigned int v8; // esi + int v9; // edx + unsigned int v10; // ecx + struct _MEMORY_BASIC_INFORMATION Buffer; // [esp+Ch] [ebp-24h] + LPSTR lpFilename; // [esp+28h] [ebp-8h] + HMODULE hModule; // [esp+2Ch] [ebp-4h] + unsigned int iMaxLengtha; // [esp+38h] [ebp+8h] + + lpFilename = lpString1; + v5 = lpAddress; + lstrcpynA(lpString1, "*unknown*", iMaxLength); + *(_DWORD *)a4 = 0; + *(_DWORD *)a5 = 0; + result = VirtualQuery(v5, &Buffer, 0x1Cu); + if ( result ) + { + hModule = (HMODULE)Buffer.AllocationBase; + if ( !Buffer.AllocationBase ) + hModule = GetModuleHandleA(0); + result = GetModuleFileNameA(hModule, lpFilename, iMaxLength); + if ( result ) + { + if ( hModule ) + { + if ( *(_WORD *)hModule == 23117 ) + { + result = *((_DWORD *)hModule + 15); + if ( result ) + { + result += (int)hModule; + if ( *(_DWORD *)result == 17744 ) + { + v7 = *(unsigned short *)(result + 6); + iMaxLengtha = 0; + v8 = (_BYTE *)v5 - (_BYTE *)hModule; + if ( *(_WORD *)(result + 6) ) + { + result += *(unsigned short *)(result + 20) + 40; + while ( 1 ) + { + v9 = *(_DWORD *)result; + v10 = *(_DWORD *)(result - 4); + if ( *(_DWORD *)result <= *(_DWORD *)(result - 8) ) + v9 = *(_DWORD *)(result - 8); + if ( v8 >= v10 && v8 <= v10 + v9 ) + break; + ++iMaxLengtha; + result += 40; + if ( iMaxLengtha >= v7 ) + return result; + } + *(_DWORD *)a4 = iMaxLengtha + 1; + result = a5; + *(_DWORD *)a5 = v8 - v10; + } + } + } + } + } + } + else + { + result = (int)lstrcpynA(lpFilename, "*unknown*", iMaxLength); + } + } + return result; +} + +//----- (004185FF) -------------------------------------------------------- +void __fastcall exception_call_stack(void *a1, LPVOID lp) +{ + _DWORD *v2; // ebx + void *v3; // edi + _DWORD *v4; // eax + char String1[260]; // [esp+Ch] [ebp-10Ch] + int a5; // [esp+110h] [ebp-8h] + int a4; // [esp+114h] [ebp-4h] + + v2 = (unsigned int *)lp; + v3 = a1; + log_printf("Call stack:\r\nAddress Frame Logical addr Module\r\n"); + do + { + exception_unknown_module(v3, String1, 260, (int)&a4, (int)&a5); + log_printf("%08X %08X %04X:%08X %s\r\n", v3, v2, a4, a5, String1); + if ( IsBadWritePtr(v2, 8u) ) + break; + v3 = (void *)v2[1]; + v4 = v2; + v2 = (_DWORD *)*v2; + if ( (unsigned char)v2 & 3 ) + break; + } + while ( v2 > v4 && !IsBadWritePtr(v2, 8u) ); + log_printf("\r\n"); +} + +//----- (00418688) -------------------------------------------------------- +int __fastcall exception_get_error_type(DWORD dwMessageId, LPSTR lpString1, DWORD nSize) +{ + CHAR *v3; // esi + const CHAR *v4; // eax + CHAR *v5; // ST10_4 + DWORD v6; // ST08_4 + HMODULE v7; // eax + + v3 = lpString1; + if ( dwMessageId > EXCEPTION_FLT_DENORMAL_OPERAND ) + { + if ( dwMessageId <= EXCEPTION_STACK_OVERFLOW ) + { + if ( dwMessageId == EXCEPTION_STACK_OVERFLOW ) + { + v4 = "STACK_OVERFLOW"; + goto LABEL_42; + } + switch ( dwMessageId ) + { + case EXCEPTION_FLT_DIVIDE_BY_ZERO: + v4 = "FLT_DIVIDE_BY_ZERO"; + goto LABEL_42; + case EXCEPTION_FLT_INEXACT_RESULT: + v4 = "FLT_INEXACT_RESULT"; + goto LABEL_42; + case EXCEPTION_FLT_INVALID_OPERATION: + v4 = "FLT_INVALID_OPERATION"; + goto LABEL_42; + case EXCEPTION_FLT_OVERFLOW: + v4 = "FLT_OVERFLOW"; + goto LABEL_42; + case EXCEPTION_FLT_STACK_CHECK: + v4 = "FLT_STACK_CHECK"; + goto LABEL_42; + case EXCEPTION_FLT_UNDERFLOW: + v4 = "FLT_UNDERFLOW"; + goto LABEL_42; + case EXCEPTION_INT_DIVIDE_BY_ZERO: + v4 = "INT_DIVIDE_BY_ZERO"; + goto LABEL_42; + case EXCEPTION_INT_OVERFLOW: + v4 = "INT_OVERFLOW"; + goto LABEL_42; + case EXCEPTION_PRIV_INSTRUCTION: + v4 = "PRIV_INSTRUCTION"; + goto LABEL_42; + default: + break; + } + } + } + else + { + if ( dwMessageId == EXCEPTION_FLT_DENORMAL_OPERAND ) + { + v4 = "FLT_DENORMAL_OPERAND"; + goto LABEL_42; + } + if ( dwMessageId > EXCEPTION_IN_PAGE_ERROR ) + { + switch ( dwMessageId ) + { + case EXCEPTION_INVALID_HANDLE: + v4 = "INVALID_HANDLE"; + goto LABEL_42; + case EXCEPTION_ILLEGAL_INSTRUCTION: + v4 = "ILLEGAL_INSTRUCTION"; + goto LABEL_42; + case EXCEPTION_NONCONTINUABLE_EXCEPTION: + v4 = "NONCONTINUABLE_EXCEPTION"; + goto LABEL_42; + case EXCEPTION_INVALID_DISPOSITION: + v4 = "INVALID_DISPOSITION"; + goto LABEL_42; + case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: + v4 = "ARRAY_BOUNDS_EXCEEDED"; + goto LABEL_42; + } + } + else + { + switch ( dwMessageId ) + { + case EXCEPTION_IN_PAGE_ERROR: + v4 = "IN_PAGE_ERROR"; + goto LABEL_42; + case EXCEPTION_GUARD_PAGE: + v4 = "GUARD_PAGE"; + goto LABEL_42; + case EXCEPTION_DATATYPE_MISALIGNMENT: + v4 = "DATATYPE_MISALIGNMENT"; + goto LABEL_42; + case EXCEPTION_BREAKPOINT: + v4 = "BREAKPOINT"; + goto LABEL_42; + case EXCEPTION_SINGLE_STEP: + v4 = "SINGLE_STEP"; + goto LABEL_42; + case EXCEPTION_ACCESS_VIOLATION: + v4 = "ACCESS_VIOLATION"; +LABEL_42: + lstrcpynA(v3, v4, nSize); + return (int)v3; + } + } + } + v5 = lpString1; + v6 = dwMessageId; + v7 = GetModuleHandleA("NTDLL.DLL"); + if ( !FormatMessageA(0xA00u, v7, v6, 0, v5, nSize, 0) ) + { + v4 = "*unknown*"; + goto LABEL_42; + } + return (int)v3; +} + +//----- (0041883C) -------------------------------------------------------- +void __fastcall exception_set_filter() +{ + lpTopLevelExceptionFilter = SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)TopLevelExceptionFilter); +} + +//----- (00418853) -------------------------------------------------------- +LPTOP_LEVEL_EXCEPTION_FILTER __cdecl exception_set_filter_ptr() +{ + return SetUnhandledExceptionFilter(lpTopLevelExceptionFilter); +} + +//----- (00418860) -------------------------------------------------------- +LPTOP_LEVEL_EXCEPTION_FILTER __cdecl exception_get_filter() +{ + return lpTopLevelExceptionFilter; +} + +//----- (00418866) -------------------------------------------------------- +void __cdecl gamemenu_previous() +{ + void (__cdecl *v0)(); // edx + TMenuItem *v1; // ecx + + if ( gbMaxPlayers == 1 ) + { + v0 = gamemenu_enable_single; + v1 = sgSingleMenu; + } + else + { + v0 = gamemenu_enable_multi; + v1 = sgMultiMenu; + } + gmenu_call_proc((int)v1, v0); + PressEscKey(); +} +// 679660: using guessed type char gbMaxPlayers; + +//----- (0041888F) -------------------------------------------------------- +void __cdecl gamemenu_enable_single() +{ + bool v0; // dl + + gmenu_enable(&sgSingleMenu[3], gbValidSaveFile); + v0 = 0; + if ( plr[myplr]._pmode != PM_DEATH && !*(_DWORD *)&deathflag ) + v0 = 1; + gmenu_enable(sgSingleMenu, v0); +} + +//----- (004188C8) -------------------------------------------------------- +void __cdecl gamemenu_enable_multi() +{ + gmenu_enable(&sgMultiMenu[2], deathflag); +} + +//----- (004188D8) -------------------------------------------------------- +void __cdecl gamemenu_off() +{ + gmenu_call_proc(0, 0); +} + +//----- (004188E1) -------------------------------------------------------- +void __cdecl gamemenu_handle_previous() +{ + int v0; // eax + + _LOBYTE(v0) = gmenu_exception(); + if ( v0 ) + gamemenu_off(); + else + gamemenu_previous(); +} + +//----- (004188F9) -------------------------------------------------------- +void __cdecl gamemenu_new_game() +{ + char *v0; // eax + + v0 = &plr[0]._pInvincible; + do + { + *(_DWORD *)(v0 - 317) = 11; + *v0 = 1; + v0 += 21720; + } + while ( (signed int)v0 < (signed int)&plr_msgs[1].msg[112] ); + *(_DWORD *)&deathflag = 0; + force_redraw = 255; + scrollrt_455E65(1); + gbRunGame = 0; + gamemenu_off(); +} +// 525650: using guessed type int gbRunGame; +// 52571C: using guessed type int force_redraw; + +//----- (0041893B) -------------------------------------------------------- +void __cdecl gamemenu_quit_game() +{ + gamemenu_new_game(); + gbRunGameResult = 0; +} +// 525698: using guessed type int gbRunGameResult; + +//----- (00418948) -------------------------------------------------------- +void __cdecl gamemenu_load_game() +{ + LRESULT (__stdcall *v0)(HWND, UINT, WPARAM, LPARAM); // edi + int v1; // ecx + + v0 = SetWindowProc(DisableInputWndProc); + gamemenu_off(); + SetCursor(0); + _LOBYTE(v1) = 10; + InitDiabloMsg(v1); + force_redraw = 255; + DrawAndBlit(); + LoadGame(0); + ClrDiabloMsg(); + PaletteFadeOut(8); + *(_DWORD *)&deathflag = 0; + force_redraw = 255; + DrawAndBlit(); + PaletteFadeIn(8); + SetCursor(1); + interface_msg_pump(); + SetWindowProc(v0); +} +// 52571C: using guessed type int force_redraw; + +//----- (004189BE) -------------------------------------------------------- +void __cdecl gamemenu_save_game() +{ + LRESULT (__stdcall *v0)(HWND, UINT, WPARAM, LPARAM); // edi + int v1; // ecx + + if ( pcurs == CURSOR_HAND ) + { + if ( plr[myplr]._pmode == 8 || *(_DWORD *)&deathflag ) + { + gamemenu_off(); + } + else + { + v0 = SetWindowProc(DisableInputWndProc); + SetCursor(0); + gamemenu_off(); + _LOBYTE(v1) = 11; + InitDiabloMsg(v1); + force_redraw = 255; + DrawAndBlit(); + SaveGame(); + ClrDiabloMsg(); + force_redraw = 255; + SetCursor(1); + interface_msg_pump(); + SetWindowProc(v0); + } + } +} +// 52571C: using guessed type int force_redraw; + +//----- (00418A42) -------------------------------------------------------- +void __cdecl gamemenu_restart_town() +{ + NetSendCmd(1u, CMD_RETOWN); +} + +//----- (00418A4C) -------------------------------------------------------- +void __cdecl gamemenu_options() +{ + gamemenu_get_music(); + gamemenu_get_sound(); + gamemenu_get_gamma(); + gamemenu_get_color_cycling(); + gmenu_call_proc((int)sgOptionMenu, 0); +} + +//----- (00418A6C) -------------------------------------------------------- +void __cdecl gamemenu_get_music() +{ + sound_get_or_set_music_volume(1); + gamemenu_sound_music_toggle(music_toggle_names, sgOptionMenu); +} + +//----- (00418A85) -------------------------------------------------------- +void __fastcall gamemenu_sound_music_toggle(char **names, TMenuItem *menu_item) +{ + TMenuItem *v2; // esi + int gamma; // [esp+8h] [ebp+4h] + + v2 = menu_item; + if ( gbSndInited ) + { + _HIBYTE(menu_item->dwFlags) |= 0xC0u; + menu_item->pszStr = *names; + gmenu_slider_3(&menu_item->dwFlags, 17); + gmenu_slider_1(&v2->dwFlags, -1600, 0, gamma); + } + else + { + _HIBYTE(menu_item->dwFlags) &= 0x3Fu; + menu_item->pszStr = names[1]; + } +} + +//----- (00418AC6) -------------------------------------------------------- +void __cdecl gamemenu_get_sound() +{ + sound_get_or_set_sound_volume(1); + gamemenu_sound_music_toggle(sound_toggle_names, &sgOptionMenu[1]); +} + +//----- (00418ADF) -------------------------------------------------------- +void __cdecl gamemenu_get_color_cycling() +{ + sgOptionMenu[3].pszStr = color_cycling_toggle_names[palette_get_colour_cycling()]; +} + +//----- (00418AF4) -------------------------------------------------------- +void __cdecl gamemenu_get_gamma() +{ + int v0; // eax + + gmenu_slider_3(&sgOptionMenu[2].dwFlags, 15); + v0 = palette_update_gamma(0); + gmenu_slider_1(&sgOptionMenu[2].dwFlags, 30, 100, v0); +} + +//----- (00418B1A) -------------------------------------------------------- +void __cdecl gamemenu_music_volume() +{ + int v0; // ecx + int v1; // esi + + if ( v0 ) + { + if ( gbMusicOn ) + { + gbMusicOn = 0; + music_stop(); + sound_get_or_set_music_volume(-1600); + goto LABEL_11; + } + gbMusicOn = 1; + sound_get_or_set_music_volume(0); +LABEL_10: + music_start((unsigned char)leveltype); + goto LABEL_11; + } + v1 = gamemenu_slider_music_sound(sgOptionMenu); + sound_get_or_set_music_volume(v1); + if ( v1 != -1600 ) + { + if ( gbMusicOn ) + goto LABEL_11; + gbMusicOn = 1; + goto LABEL_10; + } + if ( gbMusicOn ) + { + gbMusicOn = 0; + music_stop(); + } +LABEL_11: + gamemenu_get_music(); +} +// 4A22D4: using guessed type char gbMusicOn; +// 5BB1ED: using guessed type char leveltype; + +//----- (00418BA3) -------------------------------------------------------- +int __fastcall gamemenu_slider_music_sound(TMenuItem *menu_item) +{ + return gmenu_slider_get(menu_item, -1600, 0); +} + +//----- (00418BB0) -------------------------------------------------------- +void __cdecl gamemenu_sound_volume() +{ + int v0; // ecx + int v1; // ecx + int v2; // esi + + if ( v0 ) + { + if ( gbSoundOn ) + { + gbSoundOn = 0; + FreeMonsterSnd(); + v1 = -1600; + } + else + { + gbSoundOn = 1; + v1 = 0; + } + sound_get_or_set_sound_volume(v1); + } + else + { + v2 = gamemenu_slider_music_sound(&sgOptionMenu[1]); + sound_get_or_set_sound_volume(v2); + if ( v2 == -1600 ) + { + if ( gbSoundOn ) + { + gbSoundOn = 0; + FreeMonsterSnd(); + } + } + else if ( !gbSoundOn ) + { + gbSoundOn = 1; + } + } + PlaySFX(IS_TITLEMOV); + gamemenu_get_sound(); +} +// 4A22D5: using guessed type char gbSoundOn; + +//----- (00418C30) -------------------------------------------------------- +void __cdecl gamemenu_gamma() +{ + int v0; // ecx + int v1; // eax + int v2; // eax + + if ( v0 ) + { + v1 = -(palette_update_gamma(0) != 30); + _LOBYTE(v1) = v1 & 0xBA; + v2 = v1 + 100; + } + else + { + v2 = gamemenu_slider_gamma(); + } + palette_update_gamma(v2); + gamemenu_get_gamma(); +} + +//----- (00418C5A) -------------------------------------------------------- +int __cdecl gamemenu_slider_gamma() +{ + return gmenu_slider_get(&sgOptionMenu[2], 30, 100); +} + +//----- (00418C6A) -------------------------------------------------------- +void __cdecl gamemenu_color_cycling() +{ + int v0; // eax + char v1; // al + + _LOBYTE(v0) = palette_get_colour_cycling(); + palette_set_color_cycling(v0 == 0); + sgOptionMenu[3].pszStr = color_cycling_toggle_names[v1 & 1]; +} + +//----- (00418C8B) -------------------------------------------------------- +void __cdecl FillSolidBlockTbls() +{ + unsigned char *v0; // eax + char *v1; // ecx + unsigned char *v2; // esi + int v3; // edx + unsigned char v4; // bl + int size; // [esp+8h] [ebp-4h] + + memset(nBlockTable, 0, 0x801u); + memset(nSolidTable, 0, 0x801u); + memset(nTransTable, 0, 0x801u); + memset(nMissileTable, 0, 0x801u); + memset(nTrapTable, 0, 0x801u); + if ( leveltype ) + { + switch ( leveltype ) + { + case DTYPE_CATHEDRAL: + v1 = "Levels\\L1Data\\L1.SOL"; + break; + case DTYPE_CATACOMBS: + v1 = "Levels\\L2Data\\L2.SOL"; + break; + case DTYPE_CAVES: + v1 = "Levels\\L3Data\\L3.SOL"; + break; + case DTYPE_HELL: + v1 = "Levels\\L4Data\\L4.SOL"; + break; + default: + TermMsg("FillSolidBlockTbls"); + v0 = (unsigned char *)size; + goto LABEL_13; + } + } + else + { + v1 = "Levels\\TownData\\Town.SOL"; + } + v0 = LoadFileInMem(v1, &size); +LABEL_13: + v2 = v0; + if ( (unsigned int)size >= 1 ) + { + v3 = 0; + do + { + v4 = *v2++; + if ( v4 & 1 ) + nSolidTable[v3 + 1] = 1; + if ( v4 & 2 ) + nBlockTable[v3 + 1] = 1; + if ( v4 & 4 ) + nMissileTable[v3 + 1] = 1; + if ( v4 & 8 ) + nTransTable[v3 + 1] = 1; + if ( (v4 & 0x80u) != 0 ) + nTrapTable[v3 + 1] = 1; + block_lvid[v3++ + 1] = (v4 >> 4) & 7; + } + while ( v3 + 1 <= (unsigned int)size ); + } + mem_free_dbg(v0); +} +// 5BB1ED: using guessed type char leveltype; + +//----- (00418D91) -------------------------------------------------------- +void __cdecl gendung_418D91() +{ + signed int v0; // edx + short (*v1)[112][112]; // edi + short (*v2)[112][112]; // esi + signed int v3; // ebx + int i; // edx + short v5; // ax + int v6; // ecx + signed int v7; // edx + int v8; // eax + int v9; // edi + char *v10; // esi + int j; // ecx + unsigned char v12; // al + unsigned char *v13; // esi + int v14; // ecx + signed int v15; // edx + int v16; // eax + int v17; // ecx + unsigned char v18; // al + signed int v19; // ecx + int v20; // edi + int v21; // edx + int v22; // edi + int v23; // eax + int v24; // eax + bool v25; // zf + int v26; // edx + char *v27; // esi + char *v28; // edi + int k; // ecx + char *v33; // esi + char *v34; // edi + int v36; // ecx + signed int v37; // edx + int v38; // eax + int v39; // ecx + short (*v42)[112][112]; // esi + short v43; // ax + unsigned short v44; // dx + short v45; // ax + int v46; // [esp-4h] [ebp-38h] + int v47; // [esp-4h] [ebp-38h] + int v48; // [esp+Ch] [ebp-28h] + int (*v49)[128]; // [esp+10h] [ebp-24h] + int (*v50)[112]; // [esp+10h] [ebp-24h] + int v51; // [esp+14h] [ebp-20h] + short (*v52)[112][112]; // [esp+14h] [ebp-20h] + signed int v53; // [esp+18h] [ebp-1Ch] + int v54; // [esp+18h] [ebp-1Ch] + short (*v55)[112][112]; // [esp+18h] [ebp-1Ch] + int v56; // [esp+1Ch] [ebp-18h] + int (*v57)[112]; // [esp+1Ch] [ebp-18h] + signed int v58; // [esp+20h] [ebp-14h] + int v59; // [esp+20h] [ebp-14h] + int v60; // [esp+24h] [ebp-10h] + signed int v61; // [esp+24h] [ebp-10h] + int v62; // [esp+28h] [ebp-Ch] + int v63; // [esp+2Ch] [ebp-8h] + signed int v64; // [esp+30h] [ebp-4h] + signed int v65; // [esp+30h] [ebp-4h] + + v0 = 0; + memset(level_frame_types, 0, sizeof(level_frame_types)); + memset(level_frame_count, 0, 0x2000u); + do + { + *((_DWORD *)&tile_defs[0].top + v0) = v0; + ++v0; + } + while ( v0 < 2048 ); + v1 = dpiece_defs_map_2; + v48 = 2 * (leveltype == 4) + 10; + do + { + v2 = v1; + v3 = 112; + do + { + for ( i = 0; i < v48; ++i ) + { + v5 = (*v2)[0][i]; + if ( (*v2)[0][i] ) + { + v6 = v5 & 0xFFF; + ++level_frame_count[v6]; + level_frame_types[v6] = v5 & 0x7000; + } + } + v2 = (short (*)[112][112])((char *)v2 + 3584); + --v3; + } + while ( v3 ); + v1 = (short (*)[112][112])((char *)v1 + 32); + } + while ( (signed int)v1 < (signed int)dpiece_defs_map_2[0][16] ); + v7 = 1; + nlevel_frames = *(_DWORD *)pDungeonCels & 0xFFFF; + v8 = nlevel_frames; + if ( nlevel_frames > 1 ) + { + do + { + level_frame_sizes[v7] = (*((_DWORD *)pDungeonCels + v7 + 1) - *((_DWORD *)pDungeonCels + v7)) & 0xFFFF; + v8 = nlevel_frames; + ++v7; + } + while ( v7 < nlevel_frames ); + } + v9 = 0; + level_frame_sizes[0] = 0; + if ( leveltype == 4 && v8 > 0 ) + { + do + { + if ( !v9 ) + level_frame_count[0] = 0; + v53 = 1; + if ( level_frame_count[v9] ) + { + if ( level_frame_types[v9] == 4096 ) + { + v13 = (unsigned char *)pDungeonCels + *((_DWORD *)pDungeonCels + v9); + v14 = 32; + do + { + v46 = v14; + v15 = 32; + do + { + while ( 1 ) + { + v16 = *v13++; + if ( (v16 & 0x80u) == 0 ) + break; + _LOBYTE(v16) = -(char)v16; + v15 -= v16; + if ( !v15 ) + goto LABEL_36; + } + v15 -= v16; + v17 = v16; + do + { + v18 = *v13++; + if ( v18 && v18 < 0x20u ) + v53 = 0; + --v17; + } + while ( v17 ); + } + while ( v15 ); +LABEL_36: + v14 = v46 - 1; + } + while ( v46 != 1 ); + } + else + { + v10 = (char *)pDungeonCels + *((_DWORD *)pDungeonCels + v9); + for ( j = level_frame_sizes[v9]; j; --j ) + { + v12 = *v10++; + if ( v12 && v12 < 0x20u ) + v53 = 0; + } + } + if ( !v53 ) + level_frame_count[v9] = 0; + } + ++v9; + } + while ( v9 < nlevel_frames ); + } + gendung_4191BF(2047); + v19 = 0; + v20 = 0; + if ( light4flag ) + { + do + { + v21 = level_frame_sizes[v20++]; + v19 += 2 * v21; + } + while ( v19 < 0x100000 ); + } + else + { + do + v19 += 14 * level_frame_sizes[v20++]; + while ( v19 < 0x100000 ); + } + v22 = v20 - 1; + v58 = v22; + if ( v22 > 128 ) + { + v58 = 128; + v22 = 128; + } + v23 = -(light4flag != 0); + v63 = 0; + _LOBYTE(v23) = v23 & 0xF4; + v54 = 0; + v60 = v23 + 15; + if ( v22 > 0 ) + { + v56 = 0; + v49 = speed_cel_frame_num_from_light_index_frame_num; + do + { + v24 = v54; + v25 = level_frame_types[v54] == 4096; + v62 = *((_DWORD *)&tile_defs[0].top + v54); + (*v49)[0] = v62; + if ( v25 ) + { + v65 = 1; + if ( v60 > 1 ) + { +/* do + { + speed_cel_frame_num_from_light_index_frame_num[0][v65 + v56] = v63; + v33 = (char *)pDungeonCels + *((_DWORD *)pDungeonCels + v62); + v34 = (char *)pSpeedCels + v63; + _EBX = dword_646A20 + (v65 << 8); + v36 = 32; + do + { + v47 = v36; + v37 = 32; + do + { + while ( 1 ) + { + v38 = (unsigned char)*v33++; + *v34++ = v38; + if ( (v38 & 0x80u) == 0 ) + break; + _LOBYTE(v38) = -(char)v38; + v37 -= v38; + if ( !v37 ) + goto LABEL_63; + } + v37 -= v38; + v39 = v38; + do + { + _AL = *v33++; + __asm { xlat } + *v34++ = _AL; + --v39; + } + while ( v39 ); + } + while ( v37 ); +LABEL_63: + v36 = v47 - 1; + } + while ( v47 != 1 ); + v63 += level_frame_sizes[v54]; + ++v65; + } + while ( v65 < v60 ); + */ +LABEL_63: + goto LABEL_65; + } + } + else + { + v26 = level_frame_sizes[v24]; + v51 = level_frame_sizes[v24]; + v64 = 1; + if ( v60 > 1 ) + { + do + { + speed_cel_frame_num_from_light_index_frame_num[0][v64 + v56] = v63; + v27 = (char *)pDungeonCels + *((_DWORD *)pDungeonCels + v62); + v28 = (char *)pSpeedCels + v63; +/* _EBX = dword_646A20 + (v64 << 8); + for ( k = v51; k; --k ) + { + _AL = *v27++; + __asm { xlat } + *v28++ = _AL; + } + v63 += v26; + ++v64;*/ + } + while ( v64 < v60 ); +LABEL_65: + v22 = v58; + goto LABEL_66; + } + } +LABEL_66: + ++v54; + v49 = (int (*)[128])((char *)v49 + 64); + v56 += 16; + } + while ( v54 < v22 ); + } + v57 = dPiece; + v55 = dpiece_defs_map_2; + do + { + v61 = 112; + v52 = v55; + v50 = v57; + do + { + if ( (*v50)[0] && v48 > 0 ) + { + v42 = v52; + v59 = v48; + do + { + v43 = *(_WORD *)v42; + if ( *(_WORD *)v42 ) + { + v44 = 0; + if ( v22 > 0 ) + { + do + { + if ( (v43 & 0xFFF) == *((_DWORD *)&tile_defs[0].top + v44) ) + { + v45 = v44 + level_frame_types[v44]; + v44 = v22; + v43 = v45 + -32768; + } + ++v44; + } + while ( v44 < v22 ); + *(_WORD *)v42 = v43; + } + } + v42 = (short (*)[112][112])((char *)v42 + 2); + --v59; + } + while ( v59 ); + } + ++v50; + v52 = (short (*)[112][112])((char *)v52 + 3584); + --v61; + } + while ( v61 ); + v55 = (short (*)[112][112])((char *)v55 + 32); + v57 = (int (*)[112])((char *)v57 + 4); + } + while ( (signed int)v55 < (signed int)dpiece_defs_map_2[0][16] ); +} +// 525728: using guessed type int light4flag; +// 53CD4C: using guessed type int nlevel_frames; +// 5BB1ED: using guessed type char leveltype; + +//----- (004191BF) -------------------------------------------------------- +void __fastcall gendung_4191BF(int frames) +{ + int v1; // edi + signed int v2; // eax + int i; // esi + + v1 = frames; + v2 = 0; + while ( v1 > 0 && !v2 ) + { + v2 = 1; + for ( i = 0; i < v1; ++i ) + { + if ( level_frame_count[i] < level_frame_count[i + 1] ) + { + gendung_4191FB(i, i + 1); + v2 = 0; + } + } + --v1; + } +} + +//----- (004191FB) -------------------------------------------------------- +void __fastcall gendung_4191FB(int a1, int a2) +{ + int v2; // esi + int *v3; // edi + short *v4; // edx + int v5; // ST10_4 + int *v6; // edi + int *v7; // eax + int v8; // ST10_4 + short *v9; // ecx + int v10; // edx + + v2 = a2; + v3 = &level_frame_count[a1]; + v4 = &level_frame_types[a2]; + v2 *= 4; + v5 = *v3; + *v3 = *(int *)((char *)level_frame_count + v2); + v6 = (int *)((char *)tile_defs + 4 * a1); + *(int *)((char *)level_frame_count + v2) = v5; + v7 = &level_frame_sizes[a1]; + v8 = *v6; + *v6 = *(_DWORD *)((char *)&tile_defs[0].top + v2); + *(_DWORD *)((char *)&tile_defs[0].top + v2) = v8; + v9 = &level_frame_types[a1]; + _LOWORD(v6) = *v9; + *v9 = *v4; + *v4 = (signed short)v6; + v10 = *v7; + *v7 = *(int *)((char *)level_frame_sizes + v2); + *(int *)((char *)level_frame_sizes + v2) = v10; +} + +//----- (0041927A) -------------------------------------------------------- +int __fastcall gendung_41927A(int x, int y) +{ + __int64 v3; // rax + + if ( x < 112 - y ) + return (y * (y + 1) + x * (x + 2 * y + 3)) / 2; + v3 = (111 - y) * (111 - y + 1) + (111 - x) * (111 - x + 2 * (111 - y) + 3); + return 12543 - (((signed int)v3 - HIDWORD(v3)) >> 1); +} + +//----- (004192C2) -------------------------------------------------------- +void __cdecl gendung_4192C2() +{ + short (*v0)[112][112]; // ebx + int v1; // ebp + short (*v2)[112][112]; // esi + char *v3; // edi + int x; // [esp+10h] [ebp-4h] + + x = 0; + v0 = dpiece_defs_map_2; + do + { + v1 = 0; + do + { + v2 = v0; + v3 = (char *)dpiece_defs_map_1 + 32 * gendung_41927A(x, v1++); + v0 = (short (*)[112][112])((char *)v0 + 32); + qmemcpy(v3, v2, 0x20u); + } + while ( v1 < 112 ); + ++x; + } + while ( (signed int)v0 < (signed int)&optbar_cel ); +} + +//----- (0041930B) -------------------------------------------------------- +void __cdecl SetDungeonMicros() +{ + signed int v0; // esi + short (*v1)[112][112]; // edx + int (*v2)[112]; // ebp + int v3; // eax + int v4; // eax + signed int i; // ecx + _WORD *v6; // edi + int j; // ecx + short (*v8)[112][112]; // [esp+8h] [ebp-Ch] + int (*v9)[112]; // [esp+Ch] [ebp-8h] + signed int v10; // [esp+10h] [ebp-4h] + + if ( leveltype == 4 ) + { + dword_5A5594 = 12; + v0 = 16; + } + else + { + dword_5A5594 = 10; + v0 = 10; + } + v9 = dPiece; + v8 = dpiece_defs_map_2; + do + { + v1 = v8; + v2 = v9; + v10 = 112; + do + { + if ( (*v2)[0] ) + { + v3 = (*v2)[0] - 1; + if ( leveltype == 4 ) + v4 = *(_DWORD *)&dpiece_defs[0].blocks + 32 * v3; + else + v4 = *(_DWORD *)&dpiece_defs[0].blocks + 20 * v3; + for ( i = 0; i < v0; ++i ) + (*v1)[0][i] = *(_WORD *)(v4 + 2 * (v0 + (i & 1) - (i & 0xE)) - 4); + } + else if ( v0 > 0 ) + { + memset(v1, 0, 4 * ((unsigned int)v0 >> 1)); + v6 = (_WORD *)((char *)v1 + 4 * ((unsigned int)v0 >> 1)); + for ( j = v0 & 1; j; --j ) + { + *v6 = 0; + ++v6; + } + } + ++v2; + v1 = (short (*)[112][112])((char *)v1 + 3584); + --v10; + } + while ( v10 ); + v8 = (short (*)[112][112])((char *)v8 + 32); + v9 = (int (*)[112])((char *)v9 + 4); + } + while ( (signed int)v8 < (signed int)dpiece_defs_map_2[0][16] ); + gendung_418D91(); + gendung_4192C2(); + if ( zoomflag ) + { + scr_pix_width = 640; + scr_pix_height = 352; + dword_5C2FF8 = 10; + dword_5C2FFC = 11; + } + else + { + scr_pix_width = 384; + scr_pix_height = 224; + dword_5C2FF8 = 6; + dword_5C2FFC = 7; + } +} +// 52569C: using guessed type int zoomflag; +// 5BB1ED: using guessed type char leveltype; +// 5C2FF8: using guessed type int dword_5C2FF8; +// 5C2FFC: using guessed type int dword_5C2FFC; +// 5C3000: using guessed type int scr_pix_width; +// 5C3004: using guessed type int scr_pix_height; + +//----- (0041944A) -------------------------------------------------------- +void __cdecl DRLG_InitTrans() +{ + memset(dung_map, 0, 0x3100u); + memset(TransList, 0, 0x100u); + TransVal = 1; +} +// 5A5590: using guessed type char TransVal; + +//----- (00419477) -------------------------------------------------------- +void __fastcall Make_RectTrans(int tx_start, int ty_start, int tx_end, int ty_end) +{ + int v4; // esi + int v5; // edi + int v6; // eax + char *v7; // edx + int v8; // ecx + int ty_enda; // [esp+10h] [ebp+8h] + + v4 = 2 * tx_start + 17; + v5 = 2 * tx_end + 16; + v6 = 2 * ty_start + 17; + for ( ty_enda = 2 * ty_end + 16; v6 <= ty_enda; ++v6 ) + { + if ( v4 <= v5 ) + { + v7 = &dung_map[v4][v6]; + v8 = v5 - v4 + 1; + do + { + *v7 = TransVal; + v7 += 112; + --v8; + } + while ( v8 ); + } + } + ++TransVal; +} +// 5A5590: using guessed type char TransVal; + +//----- (004194D0) -------------------------------------------------------- +void __fastcall DRLG_RectTrans(int x_start, int y_start, int x_end, int y_end) +{ + int i; // esi + char *v5; // edx + int v6; // eax + + for ( i = y_start; i <= y_end; ++i ) + { + if ( x_start <= x_end ) + { + v5 = &dung_map[x_start][i]; + v6 = x_end - x_start + 1; + do + { + *v5 = TransVal; + v5 += 112; + --v6; + } + while ( v6 ); + } + } + ++TransVal; +} +// 5A5590: using guessed type char TransVal; + +//----- (00419515) -------------------------------------------------------- +void __fastcall DRLG_CopyTrans(int src_x, int src_y, int dst_x, int dst_y) +{ + dung_map[dst_x][dst_y] = dung_map[src_x][src_y]; +} + +//----- (00419534) -------------------------------------------------------- +void __fastcall DRLG_ListTrans(int num, unsigned char *List) +{ + unsigned char *v2; // esi + int v3; // edi + unsigned char v4; // al + unsigned char *v5; // esi + unsigned char v6; // cl + unsigned char v7; // dl + unsigned char v8; // bl + + v2 = List; + if ( num > 0 ) + { + v3 = num; + do + { + v4 = *v2; + v5 = v2 + 1; + v6 = *v5++; + v7 = *v5++; + v8 = *v5; + v2 = v5 + 1; + DRLG_RectTrans(v4, v6, v7, v8); + --v3; + } + while ( v3 ); + } +} + +//----- (00419565) -------------------------------------------------------- +void __fastcall DRLG_AreaTrans(int num, unsigned char *List) +{ + unsigned char *v2; // esi + int v3; // edi + unsigned char v4; // al + unsigned char *v5; // esi + unsigned char v6; // cl + unsigned char v7; // dl + unsigned char v8; // bl + + v2 = List; + if ( num > 0 ) + { + v3 = num; + do + { + v4 = *v2; + v5 = v2 + 1; + v6 = *v5++; + v7 = *v5++; + v8 = *v5; + v2 = v5 + 1; + DRLG_RectTrans(v4, v6, v7, v8); + --TransVal; + --v3; + } + while ( v3 ); + } + ++TransVal; +} +// 5A5590: using guessed type char TransVal; + +//----- (004195A2) -------------------------------------------------------- +void __cdecl DRLG_InitSetPC() +{ + setpc_x = 0; + setpc_y = 0; + setpc_w = 0; + setpc_h = 0; +} +// 5CF330: using guessed type int setpc_h; +// 5CF334: using guessed type int setpc_w; + +//----- (004195B9) -------------------------------------------------------- +void __cdecl DRLG_SetPC() +{ + int v0; // ebx + int v1; // edx + int v2; // ecx + int v3; // esi + int i; // eax + int v5; // ebp + char *v6; // edi + + v0 = 0; + v1 = 2 * setpc_w; + v2 = 2 * setpc_h; + v3 = 2 * setpc_x + 16; + for ( i = 2 * setpc_y + 16; v0 < v2; ++v0 ) + { + if ( v1 > 0 ) + { + v5 = v1; + v6 = &dFlags[v3][v0 + i]; + do + { + *v6 |= 8u; + v6 += 112; + --v5; + } + while ( v5 ); + } + } +} +// 5CF330: using guessed type int setpc_h; +// 5CF334: using guessed type int setpc_w; + +//----- (0041960C) -------------------------------------------------------- +void __fastcall Make_SetPC(int x, int y, int w, int h) +{ + int v4; // eax + int v5; // esi + int v6; // ebx + int i; // eax + int v8; // edx + char *v9; // ecx + int wa; // [esp+14h] [ebp+8h] + + v4 = w; + wa = 0; + v5 = 2 * v4; + v6 = 2 * x + 16; + for ( i = 2 * y + 16; wa < 2 * h; ++wa ) + { + if ( v5 > 0 ) + { + v8 = v5; + v9 = &dFlags[v6][wa + i]; + do + { + *v9 |= 8u; + v9 += 112; + --v8; + } + while ( v8 ); + } + } +} + +//----- (0041965B) -------------------------------------------------------- +unsigned char __fastcall DRLG_WillThemeRoomFit(int floor, int x, int y, int minSize, int maxSize, int *width, int *height) +{ + int v7; // esi + int v8; // edi + int v9; // eax + int v10; // ebx + int v11; // edx + unsigned char *v12; // eax + int v13; // eax + int i; // eax + int v15; // eax + int v16; // esi + int v17; // eax + int v18; // edx + int v19; // ecx + int v21; // eax + int v22; // esi + int v23[20]; // [esp+8h] [ebp-BCh] + int v24[20]; // [esp+58h] [ebp-6Ch] + int v25; // [esp+A8h] [ebp-1Ch] + int v26; // [esp+ACh] [ebp-18h] + int v27; // [esp+B0h] [ebp-14h] + int v28; // [esp+B4h] [ebp-10h] + char *v29; // [esp+B8h] [ebp-Ch] + int v30; // [esp+BCh] [ebp-8h] + int v31; // [esp+C0h] [ebp-4h] + + v28 = 1; + v27 = 1; + v7 = x; + v8 = 0; + v25 = floor; + v31 = 0; + v30 = 0; + if ( x > 40 - maxSize && y > 40 - maxSize ) + return 0; + _LOBYTE(v9) = SkipThemeRoom(x, y); + if ( !v9 ) + return 0; + memset(v24, 0, 0x50u); + memset(v23, 0, 0x50u); + if ( maxSize > 0 ) + { + v10 = 40 * v7; + v26 = 40 * v7; + v29 = dungeon[v7]; + do + { + if ( v27 ) + { + v11 = v7; + if ( v7 < v7 + maxSize ) + { + v12 = (unsigned char *)dungeon + v8 + v10 + y; + do + { + if ( *v12 == v25 ) + { + ++v31; + } + else + { + if ( v11 >= minSize ) + break; + v27 = 0; + } + ++v11; + v12 += 40; + } + while ( v11 < v7 + maxSize ); + v10 = v26; + } + if ( v27 ) + { + v13 = v31; + v31 = 0; + v24[v8] = v13; + } + } + if ( v28 ) + { + for ( i = y; i < y + maxSize; ++i ) + { + if ( (unsigned char)v29[i] == v25 ) + { + ++v30; + } + else + { + if ( i >= minSize ) + break; + v28 = 0; + } + } + if ( v28 ) + { + v15 = v30; + v30 = 0; + v23[v8] = v15; + } + } + v29 += 40; + ++v8; + } + while ( v8 < maxSize ); + v8 = 0; + } + v16 = minSize; + v17 = 0; + if ( minSize > 0 ) + { + while ( v24[v17] >= minSize && v23[v17] >= minSize ) + { + if ( ++v17 >= minSize ) + goto LABEL_32; + } + return 0; + } +LABEL_32: + v18 = v24[0]; + v19 = v23[0]; + if ( maxSize > 0 ) + { + while ( 1 ) + { + v21 = v24[v8]; + if ( v21 < v16 ) + break; + v22 = v23[v8]; + if ( v22 < minSize ) + break; + if ( v21 < v18 ) + v18 = v24[v8]; + if ( v22 < v19 ) + v19 = v23[v8]; + if ( ++v8 >= maxSize ) + break; + v16 = minSize; + } + } + *width = v18 - 2; + *height = v19 - 2; + return 1; +} +// 41965B: using guessed type int var_6C[20]; +// 41965B: using guessed type int var_BC[20]; + +//----- (004197F4) -------------------------------------------------------- +void __fastcall DRLG_CreateThemeRoom(int themeIndex) +{ + int v1; // esi + int v2; // eax + int v3; // edi + int v4; // ebx + int v5; // ecx + int v6; // ecx + int v7; // ebx + int v8; // edx + int v9; // ebx + int v10; // edx + int v11; // ebx + int v12; // edx + int v13; // eax + int v14; // eax + int v15; // eax + int v16; // ecx + char *v17; // eax + int v18; // ecx + char *v19; // eax + int v20; // [esp+Ch] [ebp-8h] + char *v21; // [esp+10h] [ebp-4h] + + v1 = themeIndex; + v2 = themeLoc[themeIndex].y; + v3 = themeLoc[themeIndex].height; + v4 = v2; + v5 = v3 + v2; + if ( v2 < v3 + v2 ) + { + v20 = themeLoc[v1].x + themeLoc[v1].width; + while ( 1 ) + { + v6 = themeLoc[v1].x; + if ( v6 < v20 ) + break; +LABEL_52: + ++v4; + v5 = v3 + v2; + if ( v4 >= v3 + v2 ) + goto LABEL_53; + } + v21 = &dungeon[v6][v4]; + while ( 1 ) + { + if ( leveltype != 2 ) + goto LABEL_21; + if ( v4 == v2 && v6 >= themeLoc[v1].x && v6 <= v20 ) + goto LABEL_12; + if ( v4 != v3 + v2 - 1 ) + goto LABEL_13; + if ( v6 >= themeLoc[v1].x ) + break; +LABEL_16: + if ( v6 == v20 - 1 && v4 >= v2 && v4 <= v3 + v2 ) + goto LABEL_19; + *v21 = 3; +LABEL_21: + if ( leveltype == 3 ) + { + if ( v4 == v2 && v6 >= themeLoc[v1].x && v6 <= v20 ) + { +LABEL_28: + *v21 = -122; + goto LABEL_51; + } + if ( v4 == v3 + v2 - 1 ) + { + if ( v6 >= themeLoc[v1].x ) + { + if ( v6 <= v20 ) + goto LABEL_28; + goto LABEL_29; + } + } + else + { +LABEL_29: + if ( v6 == themeLoc[v1].x && v4 >= v2 && v4 <= v3 + v2 ) + { +LABEL_35: + *v21 = -119; + goto LABEL_51; + } + } + if ( v6 == v20 - 1 && v4 >= v2 && v4 <= v3 + v2 ) + goto LABEL_35; + *v21 = 7; + } + if ( leveltype != 4 ) + goto LABEL_51; + if ( v4 != v2 || v6 < themeLoc[v1].x || v6 > v20 ) + { + if ( v4 != v3 + v2 - 1 ) + goto LABEL_44; + if ( v6 < themeLoc[v1].x ) + goto LABEL_47; + if ( v6 > v20 ) + { +LABEL_44: + if ( v6 != themeLoc[v1].x || v4 < v2 || v4 > v3 + v2 ) + { +LABEL_47: + if ( v6 != v20 - 1 || v4 < v2 || v4 > v3 + v2 ) + { + *v21 = 6; + goto LABEL_51; + } + } +LABEL_19: + *v21 = 1; + goto LABEL_51; + } + } +LABEL_12: + *v21 = 2; +LABEL_51: + v21 += 40; + if ( ++v6 >= v20 ) + goto LABEL_52; + } + if ( v6 <= v20 ) + goto LABEL_12; +LABEL_13: + if ( v6 == themeLoc[v1].x && v4 >= v2 && v4 <= v3 + v2 ) + goto LABEL_19; + goto LABEL_16; + } +LABEL_53: + if ( leveltype == 2 ) + { + v7 = themeLoc[v1].x; + v8 = 10 * (v7 + themeLoc[v1].width); + dungeon[v7][v2] = 8; + v5 = v3 + 40 * v7; + *((_BYTE *)&dMonster[111][v8 + 102] + v2) = 7; + *((_BYTE *)&dMonster[111][111] + v5 + v2 + 3) = 9; + *((_BYTE *)&dMonster[111][101] + v3 + v8 * 4 + v2 + 3) = 6; + } + if ( leveltype == 3 ) + { + v9 = themeLoc[v1].x; + v10 = 10 * (v9 + themeLoc[v1].width); + dungeon[v9][v2] = -106; + v5 = v3 + 40 * v9; + *((_BYTE *)&dMonster[111][v10 + 102] + v2) = -105; + *((_BYTE *)&dMonster[111][111] + v5 + v2 + 3) = -104; + *((_BYTE *)&dMonster[111][101] + v3 + v10 * 4 + v2 + 3) = -118; + } + if ( leveltype == 4 ) + { + v11 = themeLoc[v1].x; + v12 = 10 * (v11 + themeLoc[v1].width); + dungeon[v11][v2] = 9; + v5 = v3 + 40 * v11; + *((_BYTE *)&dMonster[111][v12 + 102] + v2) = 16; + *((_BYTE *)&dMonster[111][111] + v5 + v2 + 3) = 15; + *((_BYTE *)&dMonster[111][101] + v3 + v12 * 4 + v2 + 3) = 12; + } + if ( leveltype == 2 ) + { + _LOBYTE(v5) = 0; + v13 = random(v5, 2); + if ( v13 ) + { + if ( v13 == 1 ) + { + v5 = themeLoc[v1].height; + *((_BYTE *)&dMonster[111][10 * (themeLoc[v1].x + themeLoc[v1].width / 2) + 111] + themeLoc[v1].y + + v5 + + 3) = 5; + } + } + else + { + v5 = themeLoc[v1].y; + *((_BYTE *)&dMonster[111][10 * (themeLoc[v1].x + themeLoc[v1].width) + 102] + themeLoc[v1].height / 2 + v5) = 4; + } + } + if ( leveltype == 3 ) + { + _LOBYTE(v5) = 0; + v14 = random(v5, 2); + if ( v14 ) + { + if ( v14 == 1 ) + { + v5 = themeLoc[v1].height; + *((_BYTE *)&dMonster[111][10 * (themeLoc[v1].x + themeLoc[v1].width / 2) + 111] + themeLoc[v1].y + + v5 + + 3) = -110; + } + } + else + { + v5 = themeLoc[v1].y; + *((_BYTE *)&dMonster[111][10 * (themeLoc[v1].x + themeLoc[v1].width) + 102] + themeLoc[v1].height / 2 + v5) = -109; + } + } + if ( leveltype == 4 ) + { + _LOBYTE(v5) = 0; + v15 = random(v5, 2); + if ( v15 ) + { + if ( v15 == 1 ) + { + v16 = themeLoc[v1].y + 40 * (themeLoc[v1].x + themeLoc[v1].width / 2) + themeLoc[v1].height; + v17 = (char *)dungeon + v16; + *(v17 - 41) = 57; + *(v17 - 1) = 6; + dungeon[0][v16 + 39] = 56; + *(v17 - 2) = 59; + *(v17 - 42) = 58; + } + } + else + { + v18 = themeLoc[v1].height / 2 + 40 * (themeLoc[v1].x + themeLoc[v1].width) + themeLoc[v1].y; + v19 = (char *)dungeon + v18; + *(v19 - 41) = 53; + *(v19 - 40) = 6; + *((_BYTE *)&dMonster[111][102] + v18 + 1) = 52; + *(v19 - 81) = 54; + } + } +} +// 5BB1ED: using guessed type char leveltype; + +//----- (00419C10) -------------------------------------------------------- +void __fastcall DRLG_PlaceThemeRooms(int min_size, int max_size, int floor, int frequency, int rnd_size) +{ + int v5; // ebx + int v6; // ecx + int v7; // eax + int v8; // esi + int v9; // edi + int v10; // eax + int v11; // ecx + int v12; // eax + int v13; // ecx + int v14; // eax + int v15; // ecx + int v16; // eax + int v17; // edi + int v18; // esi + int v19; // ecx + int v20; // ecx + int v21; // eax + int minSize; // [esp+10h] [ebp-1Ch] + int maxSize; // [esp+14h] [ebp-18h] + unsigned char *v24; // [esp+18h] [ebp-14h] + signed int x_start; // [esp+1Ch] [ebp-10h] + int x; // [esp+20h] [ebp-Ch] + int width; // [esp+24h] [ebp-8h] + int height; // [esp+28h] [ebp-4h] + + v5 = 0; + maxSize = max_size; + minSize = min_size; + themeCount = 0; + memset(themeLoc, 0, 0x14u); + do + { + x = 0; + x_start = 20; + v24 = (unsigned char *)dungeon + v5; + do + { + if ( *v24 == floor ) + { + _LOBYTE(v6) = 0; + if ( !random(v6, frequency) ) + { + _LOBYTE(v7) = DRLG_WillThemeRoomFit(floor, x, v5, minSize, maxSize, &width, &height); + if ( v7 ) + { + if ( rnd_size ) + { + v8 = minSize - 2; + v9 = maxSize - 2; + _LOBYTE(v6) = 0; + v10 = random(v6, width - (minSize - 2) + 1); + _LOBYTE(v11) = 0; + v12 = minSize - 2 + random(v11, v10); + if ( v12 < minSize - 2 || (width = v12, v12 > v9) ) + width = minSize - 2; + _LOBYTE(v13) = 0; + v14 = random(v13, height - v8 + 1); + _LOBYTE(v15) = 0; + v16 = v8 + random(v15, v14); + if ( v16 < v8 || v16 > v9 ) + v16 = minSize - 2; + height = v16; + } + else + { + v16 = height; + } + v17 = themeCount; + v18 = themeCount; + themeLoc[v18].x = x + 1; + themeLoc[v18].y = v5 + 1; + v19 = width; + themeLoc[v18].width = width; + themeLoc[v18].height = v16; + v20 = x + v19; + v21 = v5 + v16; + if ( leveltype == 3 ) + DRLG_RectTrans(x_start, 2 * v5 + 20, 2 * v20 + 15, 2 * v21 + 15); + else + Make_RectTrans(x + 1, v5 + 1, v20, v21); + themeLoc[v18].ttval = TransVal - 1; + DRLG_CreateThemeRoom(v17); + ++themeCount; + } + } + } + x_start += 2; + ++x; + v24 += 40; + } + while ( x_start < 100 ); + ++v5; + } + while ( v5 < 40 ); +} +// 5A5590: using guessed type char TransVal; +// 5BB1ED: using guessed type char leveltype; + +//----- (00419D92) -------------------------------------------------------- +void __cdecl DRLG_HoldThemeRooms() +{ + int *v0; // esi + int v1; // edi + int v2; // edx + int v3; // ebx + int v4; // edi + int v5; // ecx + int v6; // eax + int v7; // [esp+0h] [ebp-Ch] + int v8; // [esp+4h] [ebp-8h] + int v9; // [esp+8h] [ebp-4h] + + if ( themeCount > 0 ) + { + v0 = &themeLoc[0].height; + v8 = themeCount; + do + { + v1 = *(v0 - 3); + if ( v1 < v1 + *v0 - 1 ) + { + v2 = *(v0 - 4); + v3 = 2 * v1 + 16; + v7 = v2 + *(v0 - 1) - 1; + v9 = *v0 - 1; + do + { + if ( v2 < v7 ) + { + v4 = 224 * (v2 + 8); + v5 = v7 - v2; + do + { + v6 = v3 + v4; + v4 += 224; + dFlags[0][v6] |= 8u; + dFlags[1][v6] |= 8u; + dFlags[0][v6 + 1] |= 8u; + dFlags[1][v6 + 1] |= 8u; + --v5; + } + while ( v5 ); + } + v3 += 2; + --v9; + } + while ( v9 ); + } + v0 += 5; + --v8; + } + while ( v8 ); + } +} + +//----- (00419E1F) -------------------------------------------------------- +unsigned char __fastcall SkipThemeRoom(int x, int y) +{ + int v2; // ebx + THEME_LOC *v3; // eax + int v4; // esi + + v2 = 0; + if ( themeCount <= 0 ) + return 1; + v3 = themeLoc; + while ( 1 ) + { + if ( x >= v3->x - 2 && x <= v3->x + v3->width + 2 ) + { + v4 = v3->y; + if ( y >= v4 - 2 && y <= v4 + v3->height + 2 ) + break; + } + ++v2; + ++v3; + if ( v2 >= themeCount ) + return 1; + } + return 0; +} + +//----- (00419E71) -------------------------------------------------------- +void __cdecl InitLevels() +{ + if ( !leveldebug ) + { + currlevel = 0; + leveltype = 0; + setlevel = 0; + } +} +// 52572C: using guessed type int leveldebug; +// 5BB1ED: using guessed type char leveltype; +// 5CF31D: using guessed type char setlevel; + +//----- (00419E8B) -------------------------------------------------------- +void __cdecl gmenu_draw_pause() +{ + if ( currlevel ) + RedBack(); + if ( !dword_634480 ) + { + light_table_index = 0; + gmenu_print_text(316, 336, "Pause"); + } +} +// 69BEF8: using guessed type int light_table_index; + +//----- (00419EBE) -------------------------------------------------------- +int __fastcall gmenu_print_text(int x, int y, char *str) +{ + char *v3; // edi + int v4; // ebp + int v5; // esi + int result; // eax + unsigned char v7; // bl + + v3 = str; + v4 = y; + v5 = x; + for ( _LOBYTE(result) = *str; *v3; _LOBYTE(result) = *v3 ) + { + ++v3; + v7 = lfontframe[fontidx[(unsigned char)result]]; + if ( v7 ) + Cel_light(v5, v4, (char *)BigTGold_cel, v7, 46); + result = lfontkern[v7]; + v5 += result + 2; + } + return result; +} + +//----- (00419F17) -------------------------------------------------------- +void __cdecl FreeGMenu() +{ + void *v0; // ecx + void *v1; // ecx + void *v2; // ecx + void *v3; // ecx + void *v4; // ecx + + v0 = sgpLogo; + sgpLogo = 0; + mem_free_dbg(v0); + v1 = BigTGold_cel; + BigTGold_cel = 0; + mem_free_dbg(v1); + v2 = PentSpin_cel; + PentSpin_cel = 0; + mem_free_dbg(v2); + v3 = option_cel; + option_cel = 0; + mem_free_dbg(v3); + v4 = optbar_cel; + optbar_cel = 0; + mem_free_dbg(v4); +} + +//----- (00419F70) -------------------------------------------------------- +void __cdecl gmenu_init_menu() +{ + byte_634478 = 1; + dword_634480 = 0; + sgpCurrItem = 0; + dword_63447C = 0; + dword_63448C = 0; + byte_634464 = 0; + sgpLogo = LoadFileInMem("Data\\Diabsmal.CEL", 0); + BigTGold_cel = LoadFileInMem("Data\\BigTGold.CEL", 0); + PentSpin_cel = LoadFileInMem("Data\\PentSpin.CEL", 0); + option_cel = LoadFileInMem("Data\\option.CEL", 0); + optbar_cel = LoadFileInMem("Data\\optbar.CEL", 0); +} +// 634464: using guessed type char byte_634464; +// 634478: using guessed type char byte_634478; +// 63448C: using guessed type int dword_63448C; + +//----- (00419FE8) -------------------------------------------------------- +bool __cdecl gmenu_exception() +{ + return dword_634480 != 0; +} + +//----- (00419FF4) -------------------------------------------------------- +void __fastcall gmenu_call_proc(int a1, void (__cdecl *gmFunc)()) +{ + int v2; // eax + int v3; // ecx + _DWORD *v4; // edx + + PauseMode = 0; + byte_634464 = 0; + v2 = a1; + dword_63447C = gmFunc; + dword_634480 = a1; + if ( gmFunc ) + { + gmFunc(); + v2 = dword_634480; + } + v3 = 0; + dword_63448C = 0; + if ( v2 ) + { + v4 = (_DWORD *)(v2 + 8); + while ( *v4 ) + { + ++v3; + v4 += 3; + dword_63448C = v3; + } + } + sgpCurrItem = (void **)(v2 + 12 * v3 - 12); + gmenu_up_down(1); +} +// 525740: using guessed type int PauseMode; +// 634464: using guessed type char byte_634464; +// 63448C: using guessed type int dword_63448C; + +//----- (0041A04E) -------------------------------------------------------- +void __fastcall gmenu_up_down(int a1) +{ + void **v1; // eax + int v2; // edi + + v1 = sgpCurrItem; + if ( sgpCurrItem ) + { + byte_634464 = 0; + v2 = dword_63448C; + while ( v2 ) + { + --v2; + if ( a1 ) + { + v1 += 3; + sgpCurrItem = v1; + if ( v1[2] ) + goto LABEL_10; + v1 = (void **)dword_634480; + } + else + { + if ( v1 == (void **)dword_634480 ) + v1 = (void **)(dword_634480 + 12 * dword_63448C); + v1 -= 3; + } + sgpCurrItem = v1; +LABEL_10: + if ( *((_BYTE *)v1 + 3) < 0 ) + { + if ( v2 ) + PlaySFX(IS_TITLEMOV); + return; + } + } + } +} +// 634464: using guessed type char byte_634464; +// 63448C: using guessed type int dword_63448C; + +//----- (0041A0B6) -------------------------------------------------------- +void __cdecl gmenu_draw() +{ + int v0; // edi + int i; // esi + DWORD v2; // eax + + if ( dword_634480 ) + { + if ( dword_63447C ) + dword_63447C(); + Cel_decode(236, 262, sgpLogo, 1, 296); + v0 = 320; + for ( i = dword_634480; *(_DWORD *)(i + 8); v0 += 45 ) + { + gmenu_spinners(i, v0); + i += 12; + } + v2 = GetTickCount(); + if ( (signed int)(v2 - dword_634474) > 25 ) + { + if ( ++byte_634478 == 9 ) + byte_634478 = 1; + dword_634474 = v2; + } + } +} +// 634474: using guessed type int dword_634474; +// 634478: using guessed type char byte_634478; + +//----- (0041A145) -------------------------------------------------------- +void __fastcall gmenu_spinners(int a1, int a2) +{ + int v2; // edi + int v3; // ebx + unsigned int v4; // eax + unsigned int v5; // ebp + int v6; // esi + unsigned int v7; // ecx + unsigned int v8; // eax + int v9; // ecx + unsigned int v10; // ebp + int v11; // esi + int v12; // eax + int v13; // edi + unsigned int v14; // [esp+10h] [ebp-4h] + + v2 = a2; + v3 = a1; + v4 = gmenu_get_lfont(a1); + v5 = v4; + v14 = v4; + if ( *(_BYTE *)(v3 + 3) & 0x40 ) + { + v6 = (v4 >> 1) + 80; + Cel_decode(v6, v2 - 10, optbar_cel, 1, 287); + v7 = (*(_DWORD *)v3 >> 12) & 0xFFF; + if ( v7 < 2 ) + v7 = 2; + v8 = ((*(_DWORD *)v3 & 0xFFFu) << 8) / v7; + v9 = (v5 >> 1) + 82; + v10 = v8; + gmenu_clear_buffer(v9, v2 - 12, v8 + 13, 28); + Cel_decode(v6 + v10 + 2, v2 - 12, option_cel, 1, 27); + v5 = v14; + } + v11 = 384 - (v5 >> 1); + v12 = -(*(_DWORD *)v3 < 0); + _LOBYTE(v12) = v12 & 0xF1; + light_table_index = v12 + 15; + gmenu_print_text(384 - (v5 >> 1), v2, *(char **)(v3 + 4)); + if ( (void **)v3 == sgpCurrItem ) + { + v13 = v2 + 1; + Cel_decode(v11 - 54, v13, PentSpin_cel, (unsigned char)byte_634478, 48); + Cel_decode(v11 + v5 + 4, v13, PentSpin_cel, (unsigned char)byte_634478, 48); + } +} +// 634478: using guessed type char byte_634478; +// 69BEF8: using guessed type int light_table_index; + +//----- (0041A239) -------------------------------------------------------- +void __fastcall gmenu_clear_buffer(int x, int y, int size, int a4) +{ + int v4; // edi + char *i; // esi + + v4 = a4; + for ( i = (char *)gpBuffer + screen_y_times_768[y] + x; v4; --v4 ) + { + memset(i, 205, size); + i -= 768; + } +} + +//----- (0041A272) -------------------------------------------------------- +int __fastcall gmenu_get_lfont(int a1) +{ + unsigned char *v2; // eax + int i; // edx + unsigned char v4; // cl + + if ( *(_BYTE *)(a1 + 3) & 0x40 ) + return 490; + v2 = *(unsigned char **)(a1 + 4); + for ( i = 0; ; i += lfontkern[lfontframe[fontidx[v4]]] + 2 ) + { + v4 = *v2; + if ( !*v2 ) + break; + ++v2; + } + return i - 2; +} + +//----- (0041A2AE) -------------------------------------------------------- +int __fastcall gmenu_presskeys(int a1) +{ + int v1; // ecx + int v2; // ecx + + if ( !dword_634480 ) + return 0; + switch ( a1 ) + { + case VK_RETURN: + if ( *((_BYTE *)sgpCurrItem + 3) < 0 ) + { + PlaySFX(IS_TITLEMOV); + ((void (__fastcall *)(signed int))sgpCurrItem[2])(1); + } + return 1; + case VK_ESCAPE: + PlaySFX(IS_TITLEMOV); + gmenu_call_proc(0, 0); + return 1; + case VK_SPACE: + return 0; + case VK_LEFT: + v2 = 0; + goto LABEL_12; + case VK_UP: + v1 = 0; + goto LABEL_10; + case VK_RIGHT: + v2 = 1; +LABEL_12: + gmenu_left_right(v2); + return 1; + case VK_DOWN: + v1 = 1; +LABEL_10: + gmenu_up_down(v1); + break; + } + return 1; +} + +//----- (0041A32A) -------------------------------------------------------- +void __fastcall gmenu_left_right(int a1) +{ + signed int v1; // edx + unsigned int v2; // eax + int v3; // eax + + v1 = (signed int)*sgpCurrItem; + if ( (unsigned int)*sgpCurrItem & 0x40000000 ) + { + v2 = (unsigned int)*sgpCurrItem & 0xFFF; + if ( a1 ) + { + if ( v2 == ((v1 >> 12) & 0xFFF) ) + return; + v3 = v2 + 1; + } + else + { + if ( !(v1 & 0xFFF) ) + return; + v3 = v2 - 1; + } + _LOWORD(v1) = v1 & 0xF000; + *sgpCurrItem = (void *)v1; + *sgpCurrItem = (void *)(v3 | (unsigned int)*sgpCurrItem); + ((void (__fastcall *)(_DWORD))sgpCurrItem[2])(0); + } +} + +//----- (0041A37A) -------------------------------------------------------- +int __fastcall gmenu_run_item(LPARAM lParam) +{ + int v2; // edx + int a1; // [esp+0h] [ebp-4h] + + a1 = lParam; + if ( !byte_634464 ) + return 0; + gmenu_valid_mouse_pos((int)&a1); + v2 = a1 * (((signed int)*sgpCurrItem >> 12) & 0xFFF) % 256; + a1 = a1 * (((signed int)*sgpCurrItem >> 12) & 0xFFF) / 256; + *(_WORD *)sgpCurrItem &= 0xF000u; + *sgpCurrItem = (void *)(a1 | (unsigned int)*sgpCurrItem); + ((void (__fastcall *)(_DWORD, int))sgpCurrItem[2])(0, v2); + return 1; +} +// 41A37A: could not find valid save-restore pair for esi +// 634464: using guessed type char byte_634464; + +//----- (0041A3D2) -------------------------------------------------------- +char __fastcall gmenu_valid_mouse_pos(int a1) +{ + *(_DWORD *)a1 = 282; + if ( MouseX < 282 ) + { + *(_DWORD *)a1 = 0; + return 0; + } + if ( MouseX > 538 ) + { + *(_DWORD *)a1 = 256; + return 0; + } + *(_DWORD *)a1 = MouseX - 282; + return 1; +} + +//----- (0041A401) -------------------------------------------------------- +int __fastcall gmenu_left_mouse(int a1) +{ + int result; // eax + unsigned int v2; // eax + int v3; // eax + int v4; // esi + unsigned int v5; // eax + LPARAM v6; // ecx + int a1a; // [esp+4h] [ebp-4h] + + if ( a1 ) + { + if ( !dword_634480 || MouseY >= 352 ) + return 0; + if ( MouseY - 117 >= 0 ) + { + v2 = (MouseY - 117) / 45; + if ( v2 < dword_63448C ) + { + v3 = 3 * v2; + v4 = dword_634480 + 4 * v3; + if ( *(_BYTE *)(v4 + 3) < 0 ) + { + v5 = (unsigned int)gmenu_get_lfont(dword_634480 + 4 * v3) >> 1; + if ( MouseX >= 320 - v5 && MouseX <= v5 + 320 ) + { + sgpCurrItem = (void **)v4; + PlaySFX(IS_TITLEMOV); + if ( *(_BYTE *)(v4 + 3) & 0x40 ) + { + byte_634464 = gmenu_valid_mouse_pos((int)&a1a); + gmenu_run_item(v6); + } + else + { + ((void (__fastcall *)(signed int))sgpCurrItem[2])(1); + } + } + } + } + } + } + else + { + result = 0; + if ( !byte_634464 ) + return result; + byte_634464 = 0; + } + return 1; +} +// 634464: using guessed type char byte_634464; +// 63448C: using guessed type int dword_63448C; + +//----- (0041A4B8) -------------------------------------------------------- +void __fastcall gmenu_enable(TMenuItem *menu_item, bool enable) +{ + if ( enable ) + _HIBYTE(menu_item->dwFlags) |= 0x80u; + else + _HIBYTE(menu_item->dwFlags) &= 0x7Fu; +} + +//----- (0041A4C6) -------------------------------------------------------- +int __fastcall gmenu_slider_1(int *a1, int min, int max, int gamma) +{ + int v4; // esi + int v5; // eax + int result; // eax + + v4 = *a1; + v5 = (*a1 >> 12) & 0xFFF; + if ( v5 < 2 ) + v5 = 2; + _LOWORD(v4) = v4 & 0xF000; + result = v4 | (v5 * (gamma - min) + (max - min - 1) / 2) / (max - min); + *a1 = result; + return result; +} + +//----- (0041A508) -------------------------------------------------------- +int __fastcall gmenu_slider_get(TMenuItem *menu_item, int min, int max) +{ + int v3; // eax + int v4; // ecx + signed int v5; // esi + + v3 = (menu_item->dwFlags >> 12) & 0xFFF; + v4 = menu_item->dwFlags & 0xFFF; + v5 = v3; + if ( v3 < 2 ) + v5 = 2; + return min + (v4 * (max - min) + (v5 - 1) / 2) / v5; +} + +//----- (0041A545) -------------------------------------------------------- +void __fastcall gmenu_slider_3(int *a1, int a2) +{ + *a1 ^= (*a1 ^ (a2 << 12)) & 0xFFF000; +} + +//----- (0041A553) -------------------------------------------------------- +void __cdecl InitHelp() +{ + helpflag = 0; + dword_634494 = 0; + displayinghelp[0] = 0; +} +// 634494: using guessed type int dword_634494; + +//----- (0041A565) -------------------------------------------------------- +void __cdecl DrawHelp() +{ + int v0; // edi + const char *v1; // esi + int v2; // edx + signed int v3; // ecx + char v4; // al + unsigned char v5; // al + _BYTE *i; // eax + int v7; // eax + signed int v8; // edx + char v9; // cl + unsigned char v10; // cl + text_color color; // [esp+Ch] [ebp-8h] + int help_line_nr; // [esp+10h] [ebp-4h] + signed int help_line_nra; // [esp+10h] [ebp-4h] + + DrawSTextHelp(); + DrawQTextBack(); + PrintSString(0, 2, 1u, "Diablo Help", 3, 0); + DrawSLine(5); + v0 = help_select_line; + v1 = "$Keyboard Shortcuts:|F1: Open Help Screen|Esc: Display Main Menu|Tab: Display Auto-map|Space: Hide all i" + "nfo screens|S: Open Speedbook|B: Open Spellbook|I: Open Inventory screen|C: Open Character screen|Q: Open Quest" + " log|F: Reduce screen brightness|G: Increase screen brightness|Z: Zoom Game Screen|+ / -: Zoom Automap|1 - 8: U" + "se Belt item|F5, F6, F7, F8: Set hot key for skill or spell|Shift + Left Click: Attack without moving||$Mov" + "ement:|If you hold the mouse button down while moving, the character will continue to move in that direction.||" + "$Combat:|Holding down the shift key and then left-clicking allows the character to attack without moving.||$Aut" + "o-map:|To access the auto-map, click the 'MAP' button on the Information Bar or press 'TAB' on the keyboard. Zo" + "oming in and out of the map is done with the + and - keys. Scrolling the map uses the arrow keys.||$Picking up " + "Objects:|Useable items that are small in size, such as potions or scrolls, are automatically placed in your 'be" + "lt' located at the top of the Interface bar . When an item is placed in the belt, a small number appears in tha" + "t box. Items may be used by either pressing the corresponding number or right-clicking on the item.||$Gold|You " + "can select a specific amount of gold to drop by right clicking on a pile of gold in your inventory.||$Skills & " + "Spells:|You can access your list of skills and spells by left-clicking on the 'SPELLS' button in the interface " + "bar. Memorized spells and those available through staffs are listed here. Left-clicking on the spell you wish t" + "o cast will ready the spell. A readied spell may be cast by simply right-clicking in the play area.||$Using the" + " Speedbook for Spells|Left-clicking on the 'readied spell' button will open the 'Speedbook' which allows you to" + " select a skill or spell for immediate use. To use a readied skill or spell, simply right-click in the main pl" + "ay area.||$Setting Spell Hotkeys|You can assign up to four Hot Keys for skills, spells or scrolls. Start by op" + "ening the 'speedbook' as described in the section above. Press the F5, F6, F7 or F8 keys after highlighting the" + " spell you wish to assign.||$Spell Books|Reading more than one book increases your knowledge of that spell, all" + "owing you to cast the spell more effectively.|&"; + if ( help_select_line > 0 ) + { + help_line_nr = help_select_line; + do + { + v2 = 0; + v3 = 0; + while ( !*v1 ) + ++v1; + if ( *v1 == 36 ) + ++v1; + v4 = *v1; + if ( *v1 != 38 ) + { + if ( v4 == 124 ) + goto LABEL_47; + while ( v3 < 577 ) + { + if ( !v4 ) + { + do + ++v1; + while ( !*v1 ); + } + v5 = *v1; + tempstr[v2++] = *v1++; + v3 += fontkern[fontframe[fontidx[v5]]] + 1; + v4 = *v1; + if ( *v1 == 124 ) + { + if ( v3 < 577 ) + goto LABEL_18; + break; + } + } + for ( i = (_BYTE *)(v2 + 4950091); *i != 32; --i ) + --v1; +LABEL_18: + if ( *v1 == 124 ) +LABEL_47: + ++v1; + } + --help_line_nr; + } + while ( help_line_nr ); + } + help_line_nra = 7; + do + { + v7 = 0; + v8 = 0; + while ( !*v1 ) + ++v1; + if ( *v1 == 36 ) + { + ++v1; + _LOBYTE(color) = 2; + } + else + { + _LOBYTE(color) = 0; + } + v9 = *v1; + if ( *v1 == 38 ) + { + HelpTop = v0; + } + else + { + if ( v9 == 124 ) + goto LABEL_48; + while ( v8 < 577 ) + { + if ( !v9 ) + { + do + ++v1; + while ( !*v1 ); + } + v10 = *v1; + tempstr[v7++] = *v1++; + v8 += fontkern[fontframe[fontidx[v10]]] + 1; + v9 = *v1; + if ( *v1 == 124 ) + { + if ( v8 < 577 ) + goto LABEL_39; + break; + } + } + while ( tempstr[--v7] != 32 ) + --v1; +LABEL_39: + if ( v7 ) + { + tempstr[v7] = 0; + DrawHelpLine(0, help_line_nra, tempstr, color); + v0 = help_select_line; + } + if ( *v1 == 124 ) +LABEL_48: + ++v1; + } + ++help_line_nra; + } + while ( help_line_nra < 22 ); + PrintSString(0, 23, 1u, "Press ESC to end or the arrow keys to scroll.", 3, 0); +} +// 634490: using guessed type int help_select_line; +// 634960: using guessed type int HelpTop; + +//----- (0041A6FA) -------------------------------------------------------- +void __fastcall DrawHelpLine(int always_0, int help_line_nr, char *text, text_color color) +{ + signed int v4; // ebx + int v5; // edi + unsigned char i; // al + unsigned char v7; // al + int v8; // esi + + v4 = 0; + v5 = screen_y_times_768[SStringY[help_line_nr] + 204] + always_0 + 96; + for ( i = *text; *text; i = *text ) + { + ++text; + v7 = fontframe[fontidx[i]]; + v8 = v7; + v4 += fontkern[v7] + 1; + if ( v7 ) + { + if ( v4 <= 577 ) + CPrintString(v5, (char *)v7, color); + } + v5 += fontkern[v8] + 1; + } +} + +//----- (0041A773) -------------------------------------------------------- +void __cdecl DisplayHelp() +{ + help_select_line = 0; + helpflag = 1; + HelpTop = 5000; +} +// 634490: using guessed type int help_select_line; +// 634960: using guessed type int HelpTop; + +//----- (0041A78F) -------------------------------------------------------- +void __cdecl HelpScrollUp() +{ + if ( help_select_line > 0 ) + --help_select_line; +} +// 634490: using guessed type int help_select_line; + +//----- (0041A79F) -------------------------------------------------------- +void __cdecl HelpScrollDown() +{ + if ( help_select_line < HelpTop ) + ++help_select_line; +} +// 634490: using guessed type int help_select_line; +// 634960: using guessed type int HelpTop; + +//----- (0041A7B8) -------------------------------------------------------- +void __cdecl init_cpp_init() +{ + init_cpp_init_value = init_inf; +} +// 47AE20: using guessed type int init_inf; +// 63497C: using guessed type int init_cpp_init_value; + +//----- (0041A7C3) -------------------------------------------------------- +void __fastcall init_cleanup(bool show_cursor) +{ + int v1; // edi + + v1 = show_cursor; + pfile_flush_W(); + init_disable_screensaver(0); + init_run_office_from_start_menu(); + if ( diabdat_mpq ) + { + SFileCloseArchive(diabdat_mpq); + diabdat_mpq = 0; + } + if ( patch_rt_mpq ) + { + SFileCloseArchive(patch_rt_mpq); + patch_rt_mpq = 0; + } + if ( unused_mpq ) + { + SFileCloseArchive(unused_mpq); + unused_mpq = 0; + } + UiDestroy(); + effects_cleanup_sfx(); + sound_cleanup(); + NetClose(); + dx_cleanup(); + MI_Dummy(v1); + StormDestroy(); + if ( v1 ) + ShowCursor(1); +} + +//----- (0041A84C) -------------------------------------------------------- +void __cdecl init_run_office_from_start_menu() +{ + HWND v0; // eax + char pszPath[256]; // [esp+0h] [ebp-104h] +/* LPITEMIDLIST ppidl; // [esp+100h] [ebp-4h] + + if ( killed_mom_parent ) + { + pszPath[0] = empty_string; + killed_mom_parent = 0; + memset(&pszPath[1], 0, 0xFCu); + *(_WORD *)&pszPath[253] = 0; + pszPath[255] = 0; + ppidl = 0; + v0 = GetDesktopWindow(); + if ( !SHGetSpecialFolderLocation(v0, 11, &ppidl) ) + { + SHGetPathFromIDListA(ppidl, pszPath); + init_run_office(pszPath); + } + }*/ +} +// 634CA0: using guessed type int killed_mom_parent; + +//----- (0041A8B9) -------------------------------------------------------- +void __fastcall init_run_office(char *dir) +{ + char *v1; // esi + HANDLE v2; // ebx + bool v3; // zf + HWND v4; // eax + char Directory[260]; // [esp+8h] [ebp-348h] + char FileName[260]; // [esp+10Ch] [ebp-244h] + struct _WIN32_FIND_DATAA FindFileData; // [esp+210h] [ebp-140h] + +/* v1 = dir; + strcpy(FileName, dir); + if ( FileName[0] && Directory[strlen(FileName) + 259] == 92 ) + strcat(FileName, "*"); + else + strcat(FileName, "\\*"); + v2 = FindFirstFileA(FileName, &FindFileData); + if ( v2 != (HANDLE)-1 ) + { + do + { + if ( FindFileData.dwFileAttributes & 0x10 ) + { + if ( strcmp(FindFileData.cFileName, ".") && strcmp(FindFileData.cFileName, "..") ) + { + Directory[0] = empty_string; + memset(&Directory[1], 0, 0x100u); + v3 = *v1 == 0; + *(_WORD *)&Directory[257] = 0; + Directory[259] = 0; + if ( v3 || v1[strlen(v1) - 1] != 92 ) + sprintf(Directory, "%s\\%s\\", v1, FindFileData.cFileName); + else + sprintf(Directory, "%s%s\\", v1, FindFileData.cFileName); + init_run_office(Directory); + } + } + else if ( !_strcmpi(FindFileData.cFileName, "Microsoft Office Shortcut Bar.lnk") ) + { + v4 = GetDesktopWindow(); + ShellExecuteA(v4, "open", FindFileData.cFileName, &empty_string, v1, 1); + } + } + while ( FindNextFileA(v2, &FindFileData) ); + FindClose(v2); + }*/ +} + +//----- (0041AA2C) -------------------------------------------------------- +void __fastcall init_disable_screensaver(bool disable) +{ + bool v1; // al + BYTE Data; // [esp+4h] [ebp-20h] + char v3; // [esp+5h] [ebp-1Fh] + DWORD Type; // [esp+14h] [ebp-10h] + DWORD cbData; // [esp+18h] [ebp-Ch] + HKEY phkResult; // [esp+1Ch] [ebp-8h] + bool v7; // [esp+20h] [ebp-4h] + + v7 = disable; + if ( !RegOpenKeyExA(HKEY_CURRENT_USER, "Control Panel\\Desktop", 0, 0x2001Fu, &phkResult) ) + { + if ( v7 ) + { + cbData = 16; + if ( !RegQueryValueExA(phkResult, "ScreenSaveActive", 0, &Type, &Data, &cbData) ) + screensaver_enabled_prev = Data != 48; + v1 = 0; + } + else + { + v1 = screensaver_enabled_prev; + } + v3 = 0; + Data = (v1 != 0) + 48; + RegSetValueExA(phkResult, "ScreenSaveActive", 0, 1u, &Data, 2u); + RegCloseKey(phkResult); + } +} + +//----- (0041AAC5) -------------------------------------------------------- +void __cdecl init_create_window() +{ + signed int v0; // eax + HWND v1; // esi + WNDCLASSEXA v2; // [esp+8h] [ebp-34h] + int nWidth; // [esp+38h] [ebp-4h] + + init_kill_mom_parent(); + pfile_init_save_directory(); + memset(&v2, 0, 0x30u); + v2.cbSize = 48; + v2.style = 3; + v2.lpfnWndProc = init_redraw_window; + v2.hInstance = hInstance; + v2.hIcon = LoadIconA(hInstance, (LPCSTR)0x65); + v2.hCursor = LoadCursorA(0, (LPCSTR)0x7F00); + v2.hbrBackground = (HBRUSH)GetStockObject(4); + v2.lpszMenuName = "DIABLO"; + v2.lpszClassName = "DIABLO"; + v2.hIconSm = (HICON)LoadImageA(hInstance, (LPCSTR)0x65, 1u, 16, 16, 0); + if ( !RegisterClassExA(&v2) ) + TermMsg("Unable to register window class"); + if ( GetSystemMetrics(0) >= 640 ) + nWidth = GetSystemMetrics(0); + else + nWidth = 640; + if ( GetSystemMetrics(1) >= 480 ) + v0 = GetSystemMetrics(1); + else + v0 = 480; + v1 = CreateWindowExA(0, "DIABLO", "DIABLO", 0x80000000, 0, 0, nWidth, v0, 0, 0, hInstance, 0); + if ( !v1 ) + TermMsg("Unable to create main window"); + ShowWindow(v1, 1); + UpdateWindow(v1); + init_await_mom_parent_exit(); + dx_init(v1); + BlackPalette(); + snd_init(v1); + init_archives(); + init_disable_screensaver(1); +} + +//----- (0041AC00) -------------------------------------------------------- +void __cdecl init_kill_mom_parent() +{ + HWND v0; // eax + + v0 = init_find_mom_parent(); + if ( v0 ) + { + PostMessageA(v0, 0x10u, 0, 0); + killed_mom_parent = 1; + } +} +// 634CA0: using guessed type int killed_mom_parent; + +//----- (0041AC21) -------------------------------------------------------- +HWND __cdecl init_find_mom_parent() +{ + HWND i; // eax + HWND v1; // esi + char ClassName[256]; // [esp+4h] [ebp-100h] + + for ( i = GetForegroundWindow(); ; i = GetWindow(v1, 2u) ) + { + v1 = i; + if ( !i ) + break; + GetClassNameA(i, ClassName, 255); + if ( !_strcmpi(ClassName, "MOM Parent") ) + break; + } + return v1; +} + +//----- (0041AC71) -------------------------------------------------------- +void __cdecl init_await_mom_parent_exit() +{ + DWORD v0; // edi + + v0 = GetTickCount(); + do + { + if ( !init_find_mom_parent() ) + break; + Sleep(0xFAu); + } + while ( GetTickCount() - v0 <= 0xFA0 ); +} + +//----- (0041ACA1) -------------------------------------------------------- +void __cdecl init_archives() +{ + void *a1; // [esp+8h] [ebp-8h] + int v1; // [esp+Ch] [ebp-4h] + + fileinfo.size = 20; + fileinfo.versionstring = "internal version unknown"; + fileinfo.executablefile = diablo_exe_path; + fileinfo.originalarchivefile = diabdat_mpq_path; + fileinfo.patcharchivefile = patch_rt_mpq_path; + init_get_file_info(); + while ( 1 ) + { + diabdat_mpq = init_test_access(diabdat_mpq_path, "\\diabdat.mpq", "DiabloCD", 1000, 1); + if ( diabdat_mpq ) + break; + UiCopyProtError((int)&v1); + if ( v1 == COPYPROT_CANCEL ) + FileErrDlg("diabdat.mpq"); + } + if ( !wave_open_file((LPARAM)"ui_art\\title.pcx", (DIABFILE *)&a1, 1) ) + FileErrDlg("Main program archive: diabdat.mpq"); + wave_close_file(a1); + patch_rt_mpq = init_test_access(patch_rt_mpq_path, "\\patch_rt.mpq", "DiabloInstall", 2000, 0); +} + +//----- (0041AD72) -------------------------------------------------------- +void *__fastcall init_test_access(char *mpq_path, char *mpq_name, char *reg_loc, int flags, bool on_cd) +{ + char *v5; // esi + int v6; // eax + char *v7; // eax + int v8; // eax + int v9; // eax + int v10; // eax + int v11; // eax + char Filename[260]; // [esp+Ch] [ebp-314h] + char Buffer[260]; // [esp+110h] [ebp-210h] + char v15[260]; // [esp+214h] [ebp-10Ch] + char *mpq_namea; // [esp+318h] [ebp-8h] + void *archive; // [esp+31Ch] [ebp-4h] + + mpq_namea = mpq_name; + v5 = mpq_path; + if ( !GetCurrentDirectoryA(0x104u, Buffer) ) + TermMsg("Can't get program path"); + init_strip_trailing_slash(Buffer); + _LOBYTE(v6) = SFileSetBasePath(Buffer); + if ( !v6 ) + TermMsg("SFileSetBasePath"); + if ( !GetModuleFileNameA(hInstance, Filename, 0x104u) ) + TermMsg("Can't get program name"); + v7 = strrchr(Filename, 92); + if ( v7 ) + *v7 = 0; + init_strip_trailing_slash(Filename); + strcpy(v5, Buffer); + strcat(v5, mpq_namea); + _LOBYTE(v8) = SFileOpenArchive(v5, flags, on_cd, &archive); + if ( v8 ) + return archive; + if ( strcmp(Filename, Buffer) ) + { + strcpy(v5, Filename); + strcat(v5, mpq_namea); + _LOBYTE(v9) = SFileOpenArchive(v5, flags, on_cd, &archive); + if ( v9 ) + return archive; + } + v15[0] = 0; + if ( reg_loc ) + { + _LOBYTE(v10) = SRegLoadString((const char *)"Archives", (const char *)reg_loc, 0, v15, 260); + if ( v10 ) + { + init_strip_trailing_slash(v15); + strcpy(v5, v15); + strcat(v5, mpq_namea); + _LOBYTE(v11) = SFileOpenArchive(v5, flags, on_cd, &archive); + if ( v11 ) + return archive; + } + } + if ( on_cd && init_read_test_file(v15, mpq_namea, flags, &archive) ) + { + strcpy(v5, v15); + return archive; + } + return 0; +} + +//----- (0041AF22) -------------------------------------------------------- +char *__fastcall init_strip_trailing_slash(char *path) +{ + char *result; // eax + + result = strrchr(path, 92); + if ( result ) + { + if ( !result[1] ) + *result = 0; + } + return result; +} + +//----- (0041AF3A) -------------------------------------------------------- +int __fastcall init_read_test_file(char *mpq_path, char *mpq_name, int flags, void **archive) +{ + char *v4; // edi + DWORD v5; // eax + const char *v7; // ebx + const char *v8; // esi + int v9; // eax + char Buffer[260]; // [esp+Ch] [ebp-108h] + char *mpq_patha; // [esp+110h] [ebp-4h] + + v4 = mpq_name; + mpq_patha = mpq_path; + v5 = GetLogicalDriveStringsA(0x104u, Buffer); + if ( !v5 || v5 > 0x104 ) + return 0; + while ( *v4 == 92 ) + ++v4; + v7 = Buffer; + if ( !Buffer[0] ) + return 0; + while ( 1 ) + { + v8 = v7; + v7 += strlen(v7) + 1; + if ( GetDriveTypeA(v8) == 5 ) + { + strcpy(mpq_patha, v8); + strcat(mpq_patha, v4); + _LOBYTE(v9) = SFileOpenArchive(mpq_patha, flags, 1, archive); + if ( v9 ) + break; + } + if ( !*v7 ) + return 0; + } + return 1; +} + +//----- (0041AFCE) -------------------------------------------------------- +void __cdecl init_get_file_info() +{ + int v0; // eax + DWORD v1; // edi + void *v2; // ebx + unsigned int puLen; // [esp+8h] [ebp-Ch] + DWORD dwHandle; // [esp+Ch] [ebp-8h] + LPVOID lpBuffer; // [esp+10h] [ebp-4h] + + if ( GetModuleFileNameA(hInstance, diablo_exe_path, 0x104u) ) + { + v0 = GetFileVersionInfoSizeA(diablo_exe_path, &dwHandle); + v1 = v0; + if ( v0 ) + { + v2 = DiabloAllocPtr(v0); + if ( GetFileVersionInfoA(diablo_exe_path, 0, v1, v2) ) + { + if ( VerQueryValueA(v2, "\\", &lpBuffer, &puLen) ) + sprintf( + "internal version unknown", + "version %d.%d.%d.%d", + *((unsigned short *)lpBuffer + 9), + *((_DWORD *)lpBuffer + 4) & 0xFFFF, + *((unsigned short *)lpBuffer + 11), + *((_DWORD *)lpBuffer + 5) & 0xFFFF); + } + mem_free_dbg(v2); + } + } +} + +//----- (0041B06C) -------------------------------------------------------- +LRESULT __stdcall init_palette(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) +{ + if ( Msg > WM_ERASEBKGND ) + { + if ( Msg == WM_ACTIVATEAPP ) + { + init_activate_window(hWnd, wParam); + } + else + { + if ( Msg == WM_QUERYNEWPALETTE ) + { + SDrawRealizePalette(); + return 1; + } + if ( Msg == WM_PALETTECHANGED && (HWND)wParam != hWnd ) + SDrawRealizePalette(); + } + } + else + { + switch ( Msg ) + { + case WM_ERASEBKGND: + return 0; + case WM_CREATE: + ghMainWnd = hWnd; + break; + case WM_DESTROY: + init_cleanup(1); + ghMainWnd = 0; + PostQuitMessage(0); + break; + case WM_PAINT: + force_redraw = 255; + break; + case WM_CLOSE: + return 0; + } + } + return DefWindowProcA(hWnd, Msg, wParam, lParam); +} +// 52571C: using guessed type int force_redraw; + +//----- (0041B105) -------------------------------------------------------- +void __fastcall init_activate_window(HWND hWnd, bool activated) +{ + HWND v2; // esi + LONG v3; // eax + LONG v4; // eax + + v2 = hWnd; + window_activated = activated; + UiAppActivate(activated); + v3 = GetWindowLongA(v2, -16); + if ( window_activated && exclusive ) + v4 = v3 & 0xFFF7FFFF; + else + v4 = v3 | 0x80000; + SetWindowLongA(v2, -16, v4); + if ( window_activated ) + { + force_redraw = 255; + ResetPal(); + } +} +// 484364: using guessed type int exclusive; +// 52571C: using guessed type int force_redraw; +// 634980: using guessed type int window_activated; + +//----- (0041B15F) -------------------------------------------------------- +LRESULT __stdcall init_redraw_window(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) +{ + LRESULT result; // eax + + if ( CurrentProc ) + result = CurrentProc(hWnd, Msg, wParam, lParam); + else + result = init_palette(hWnd, Msg, wParam, lParam); + return result; +} + +//----- (0041B184) -------------------------------------------------------- +LRESULT (__stdcall *__fastcall SetWindowProc(void *func))(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + LRESULT (__stdcall *result)(HWND, UINT, WPARAM, LPARAM); // eax + + result = CurrentProc; + CurrentProc = (LRESULT (__stdcall *)(HWND, UINT, WPARAM, LPARAM))func; + return result; +} + +//----- (0041B195) -------------------------------------------------------- +void __cdecl interfac_cpp_init() +{ + LODWORD(interfac_cpp_init_value) = interfac_inf; +} +// 47AE40: using guessed type int interfac_inf; + +//----- (0041B1A0) -------------------------------------------------------- +void __cdecl interface_msg_pump() +{ + MSG Msg; // [esp+8h] [ebp-1Ch] + + while ( PeekMessageA(&Msg, 0, 0, 0, 1u) ) + { + if ( Msg.message != WM_QUIT ) + { + TranslateMessage(&Msg); + DispatchMessageA(&Msg); + } + } +} + +//----- (0041B1DF) -------------------------------------------------------- +bool __cdecl IncProgress() +{ + interface_msg_pump(); + sgdwProgress += 15; + if ( (unsigned int)sgdwProgress > 0x216 ) + sgdwProgress = 534; + if ( sgpBackCel ) + DrawCutscene(); + return (unsigned int)sgdwProgress >= 0x216; +} + +//----- (0041B218) -------------------------------------------------------- +void __cdecl DrawCutscene() +{ + unsigned int v0; // esi + + dx_lock_mutex(); + Cel_decode(64, 639, sgpBackCel, 1, 640); + v0 = 0; + if ( sgdwProgress ) + { + do + DrawProgress( + progress_bar_screen_pos[progress_id].x + v0++ + 64, + progress_bar_screen_pos[progress_id].y + 160, + progress_id); + while ( v0 < sgdwProgress ); + } + dx_unlock_mutex(); + force_redraw = 255; + scrollrt_455E65(0); +} +// 52571C: using guessed type int force_redraw; + +//----- (0041B28D) -------------------------------------------------------- +void __fastcall DrawProgress(int screen_x, int screen_y, int progress_id) +{ + _BYTE *v3; // eax + signed int v4; // ecx + + v3 = (unsigned char *)gpBuffer + screen_y_times_768[screen_y] + screen_x; + v4 = 22; + do + { + *v3 = progress_bar_colours[progress_id]; + v3 += 768; + --v4; + } + while ( v4 ); +} + +//----- (0041B2B6) -------------------------------------------------------- +void __fastcall ShowProgress(int uMsg) +{ + int v1; // esi + LRESULT (__stdcall *v2)(HWND, UINT, WPARAM, LPARAM); // edi + bool v3; // cl + int v4; // eax + int v5; // edx + int v6; // ecx + signed int v7; // [esp-4h] [ebp-10h] + + gbSomebodyWonGameKludge = 0; + v1 = uMsg; + plrmsg_delay(1); + v2 = SetWindowProc(DisableInputWndProc); + interface_msg_pump(); + ClearScreenBuffer(); + scrollrt_455E65(1); + InitCutscene(v1); + BlackPalette(); + DrawCutscene(); + PaletteFadeIn(8); + IncProgress(); + stream_update(); + IncProgress(); + switch ( v1 ) + { + case WM_DIABNEXTLVL: + IncProgress(); + if ( gbMaxPlayers == 1 ) + SaveLevel(); + else + DeltaSaveLevel(); + FreeGameMem(); + v4 = ++currlevel; + goto LABEL_38; + case WM_DIABPREVLVL: + IncProgress(); + if ( gbMaxPlayers == 1 ) + SaveLevel(); + else + DeltaSaveLevel(); + IncProgress(); + FreeGameMem(); + leveltype = gnLevelTypeTbl[--currlevel]; + IncProgress(); + v5 = 1; + goto LABEL_33; + case WM_DIABRTNLVL: + if ( gbMaxPlayers == 1 ) + SaveLevel(); + else + DeltaSaveLevel(); + setlevel = 0; + FreeGameMem(); + IncProgress(); + GetReturnLvlPos(); + v7 = 3; + goto LABEL_32; + case WM_DIABSETLVL: + SetReturnLvlPos(); + if ( gbMaxPlayers == 1 ) + SaveLevel(); + else + DeltaSaveLevel(); + setlevel = 1; + leveltype = setlvltype; + FreeGameMem(); + IncProgress(); + v7 = 2; + goto LABEL_32; + case WM_DIABWARPLVL: + IncProgress(); + if ( gbMaxPlayers == 1 ) + SaveLevel(); + else + DeltaSaveLevel(); + FreeGameMem(); + GetPortalLevel(); + IncProgress(); + v7 = 5; + goto LABEL_32; + case WM_DIABTOWNWARP: + IncProgress(); + if ( gbMaxPlayers == 1 ) + SaveLevel(); + else + DeltaSaveLevel(); + FreeGameMem(); + currlevel = plr[myplr].plrlevel; + leveltype = gnLevelTypeTbl[currlevel]; + IncProgress(); + v7 = 6; + goto LABEL_32; + case WM_DIABTWARPUP: + IncProgress(); + if ( gbMaxPlayers == 1 ) + SaveLevel(); + else + DeltaSaveLevel(); + FreeGameMem(); + currlevel = plr[myplr].plrlevel; + leveltype = gnLevelTypeTbl[currlevel]; + IncProgress(); + v7 = 7; +LABEL_32: + v5 = v7; +LABEL_33: + v3 = 0; + goto LABEL_40; + case WM_DIABRETOWN: + IncProgress(); + if ( gbMaxPlayers == 1 ) + SaveLevel(); + else + DeltaSaveLevel(); + FreeGameMem(); + currlevel = plr[myplr].plrlevel; + v4 = currlevel; +LABEL_38: + leveltype = gnLevelTypeTbl[v4]; + IncProgress(); + v3 = 0; + goto LABEL_39; + case WM_DIABNEWGAME: + IncProgress(); + FreeGameMem(); + IncProgress(); + pfile_remove_temp_files(); + v3 = 1; +LABEL_39: + v5 = 0; +LABEL_40: + LoadGameLevel(v3, v5); + goto LABEL_41; + case WM_DIABLOADGAME: + IncProgress(); + LoadGame((void *)1); +LABEL_41: + IncProgress(); + break; + default: + break; + } + PaletteFadeOut(8); + FreeInterface(); + SetWindowProc(v2); + _LOWORD(v6) = plr[myplr].plrlevel; + NetSendCmdLocParam1(1u, CMD_PLAYER_JOINLEVEL, plr[myplr].WorldX, plr[myplr].WorldY, v6); + plrmsg_delay(0); + ResetPal(); + if ( gbSomebodyWonGameKludge && plr[myplr].plrlevel == 16 ) + PrepDoEnding(); + gbSomebodyWonGameKludge = 0; +} +// 5BB1ED: using guessed type char leveltype; +// 5CF31C: using guessed type char setlvltype; +// 5CF31D: using guessed type char setlevel; +// 6761B8: using guessed type char gbSomebodyWonGameKludge; +// 679660: using guessed type char gbMaxPlayers; + +//----- (0041B5F5) -------------------------------------------------------- +void __cdecl FreeInterface() +{ + void *v0; // ecx + + v0 = sgpBackCel; + sgpBackCel = 0; + mem_free_dbg(v0); +} + +//----- (0041B607) -------------------------------------------------------- +void __fastcall InitCutscene(int interface_mode) +{ + int v1; // eax + int v2; // eax + int v3; // eax + int v4; // eax + unsigned char *v5; // eax + char *v6; // ecx + int *v7; // eax + int v8; // eax + int v9; // eax + int v10; // eax + int v11; // eax + int v12; // eax + int v13; // eax + int v14; // eax + + switch ( interface_mode ) + { + case WM_DIABNEXTLVL: + v1 = gnLevelTypeTbl[currlevel]; + if ( !v1 ) + goto LABEL_31; + v2 = v1 - 1; + if ( !v2 ) + goto LABEL_10; + v3 = v2 - 1; + if ( !v3 ) + goto LABEL_9; + v4 = v3 - 1; + if ( !v4 ) + goto LABEL_29; + if ( v4 != 1 ) + goto LABEL_10; + if ( currlevel < 0xFu ) + goto LABEL_28; + v5 = LoadFileInMem("Gendata\\Cutgate.CEL", 0); + v6 = "Gendata\\Cutgate.pal"; + goto LABEL_30; + case WM_DIABPREVLVL: + v7 = &gnLevelTypeTbl[currlevel]; + if ( !*(v7 - 1) ) + goto LABEL_31; + v8 = *v7; + if ( !v8 ) + goto LABEL_31; + v9 = v8 - 1; + if ( !v9 ) + goto LABEL_10; + v10 = v9 - 1; + if ( !v10 ) + { +LABEL_9: + sgpBackCel = LoadFileInMem("Gendata\\Cut2.CEL", 0); + LoadPalette("Gendata\\Cut2.pal"); + progress_id = 2; + goto LABEL_33; + } + v11 = v10 - 1; + if ( !v11 ) + goto LABEL_29; + if ( v11 == 1 ) + goto LABEL_28; +LABEL_10: + sgpBackCel = LoadFileInMem("Gendata\\Cutl1d.CEL", 0); + LoadPalette("Gendata\\Cutl1d.pal"); + progress_id = 0; + goto LABEL_33; + case WM_DIABRTNLVL: + case WM_DIABSETLVL: + if ( setlvlnum == SL_BONECHAMB ) + goto LABEL_21; + if ( setlvlnum != SL_VILEBETRAYER ) + goto LABEL_10; + v5 = LoadFileInMem("Gendata\\Cutportr.CEL", 0); + v6 = "Gendata\\Cutportr.pal"; + goto LABEL_30; + case WM_DIABWARPLVL: + v5 = LoadFileInMem("Gendata\\Cutportl.CEL", 0); + v6 = "Gendata\\Cutportl.pal"; + goto LABEL_30; + case WM_DIABTOWNWARP: + case WM_DIABTWARPUP: + v12 = gnLevelTypeTbl[plr[myplr].plrlevel]; + if ( !v12 ) + goto LABEL_31; + v13 = v12 - 2; + if ( !v13 ) + { +LABEL_21: + sgpBackCel = LoadFileInMem("Gendata\\Cut2.CEL", 0); + LoadPalette("Gendata\\Cut2.pal"); + progress_id = SL_BONECHAMB; + goto LABEL_33; + } + v14 = v13 - 1; + if ( v14 ) + { + if ( v14 != 1 ) + goto LABEL_33; +LABEL_28: + v5 = LoadFileInMem("Gendata\\Cut4.CEL", 0); + v6 = "Gendata\\Cut4.pal"; + } + else + { +LABEL_29: + v5 = LoadFileInMem("Gendata\\Cut3.CEL", 0); + v6 = "Gendata\\Cut3.pal"; + } +LABEL_30: + sgpBackCel = v5; + LoadPalette(v6); + progress_id = 1; +LABEL_33: + sgdwProgress = 0; + return; + case WM_DIABRETOWN: +LABEL_31: + v5 = LoadFileInMem("Gendata\\Cuttt.CEL", 0); + v6 = "Gendata\\Cuttt.pal"; + goto LABEL_30; + case WM_DIABNEWGAME: + case WM_DIABLOADGAME: + v5 = LoadFileInMem("Gendata\\Cutstart.CEL", 0); + v6 = "Gendata\\Cutstart.pal"; + goto LABEL_30; + default: + TermMsg("Unknown progress mode"); + goto LABEL_33; + } +} +// 5CCB10: using guessed type char setlvlnum; + +//----- (0041B814) -------------------------------------------------------- +void __cdecl FreeInvGFX() +{ + void *v0; // ecx + + v0 = pInvCels; + pInvCels = 0; + mem_free_dbg(v0); +} + +//----- (0041B826) -------------------------------------------------------- +void __cdecl InitInv() +{ + char v0; // al + char *v1; // ecx + + v0 = plr[myplr]._pClass; + switch ( v0 ) + { + case UI_WARRIOR: + v1 = "Data\\Inv\\Inv.CEL"; +LABEL_7: + pInvCels = LoadFileInMem(v1, 0); + break; + case UI_ROGUE: + v1 = "Data\\Inv\\Inv_rog.CEL"; + goto LABEL_7; + case UI_SORCERER: + v1 = "Data\\Inv\\Inv_Sor.CEL"; + goto LABEL_7; + } + invflag = 0; + drawsbarflag = 0; +} + +//----- (0041B871) -------------------------------------------------------- +void __fastcall InvDrawSlotBack(int X, int Y, int W, int H) +{ + unsigned char *v4; // edi + int v5; // edx + int v6; // ecx + unsigned char v7; // al + unsigned char v8; // al + + v4 = (unsigned char *)gpBuffer + screen_y_times_768[Y] + X; + v5 = (unsigned short)H; + do + { + v6 = (unsigned short)W; + do + { + v7 = *v4; + if ( *v4 < 0xB0u ) + goto LABEL_9; + if ( v7 > 0xBFu ) + { + if ( v7 < 0xF0u ) + goto LABEL_9; + v8 = v7 - 80; + } + else + { + v8 = v7 - 16; + } + *v4 = v8; +LABEL_9: + ++v4; + --v6; + } + while ( v6 ); + v4 = &v4[-(unsigned short)W - 768]; + --v5; + } + while ( v5 ); +} + +//----- (0041B8C4) -------------------------------------------------------- +void __cdecl DrawInv() +{ + int v0; // ecx + int v1; // eax + int v2; // esi + int v3; // ebp + char v4; // cl + int v5; // ecx + int v6; // eax + int v7; // edi + int v8; // edx + char v9; // cl + int v10; // ecx + int v11; // eax + int v12; // edi + int v13; // edx + char v14; // cl + int v15; // ecx + int v16; // eax + int v17; // esi + int v18; // edx + char v19; // cl + int v20; // ecx + int v21; // eax + int v22; // esi + int v23; // edi + int v24; // ebp + char v25; // cl + char *v26; // ecx + int v27; // ebp + int v28; // eax + int v29; // esi + int v30; // edi + char v31; // cl + int v32; // ecx + int v33; // eax + int v34; // esi + int v35; // edi + char v36; // cl + signed int v37; // esi + signed int v38; // edi + int v39; // ecx + char v40; // al + int v41; // eax + int v42; // ebp + int v43; // ecx + int v44; // esi + char v45; // al + int v46; // ecx + int v47; // edx + int screen_y; // [esp+10h] [ebp-A8h] + int screen_ya; // [esp+10h] [ebp-A8h] + int screen_yb; // [esp+10h] [ebp-A8h] + signed int screen_yc; // [esp+10h] [ebp-A8h] + signed int screen_yd; // [esp+10h] [ebp-A8h] + int screen_ye; // [esp+10h] [ebp-A8h] + signed int screen_x; // [esp+14h] [ebp-A4h] + int v55[40]; // [esp+18h] [ebp-A0h] + + Cel_decode(384, 511, pInvCels, 1, 320); + if ( plr[myplr].InvBody[0]._itype != -1 ) + { + InvDrawSlotBack(517, 219, 56, 56); + v0 = myplr; + v1 = myplr; + v2 = plr[myplr].InvBody[0]._iCurs + 12; + v3 = InvItemWidth[v2]; + if ( !pcursinvitem ) + { + v4 = -59; + if ( plr[v1].InvBody[0]._iMagical ) + v4 = -75; + if ( !plr[v1].InvBody[0]._iStatFlag ) + v4 = -27; + Cel_colour(v4, 517, 219, (char *)pCursCels, v2, v3, 0, 8); + v0 = myplr; + } + if ( plr[v0].InvBody[0]._iStatFlag ) + Cel_header(517, 219, (char *)pCursCels, v2, v3, 0, 8); + else + Cel_header_and_light_not_equipable(517, 219, (char *)pCursCels, v2, v3, 0, 8, 1); + } + if ( plr[myplr].InvBody[1]._itype != -1 ) + { + InvDrawSlotBack(432, 365, 28, 28); + v5 = myplr; + v6 = myplr; + v7 = plr[myplr].InvBody[1]._iCurs + 12; + v8 = InvItemWidth[v7]; + screen_y = InvItemWidth[v7]; + if ( pcursinvitem == 1 ) + { + v9 = -59; + if ( plr[v6].InvBody[1]._iMagical ) + v9 = -75; + if ( !plr[v6].InvBody[1]._iStatFlag ) + v9 = -27; + Cel_colour(v9, 432, 365, (char *)pCursCels, v7, v8, 0, 8); + v5 = myplr; + v8 = screen_y; + } + if ( plr[v5].InvBody[1]._iStatFlag ) + Cel_header(432, 365, (char *)pCursCels, v7, v8, 0, 8); + else + Cel_header_and_light_not_equipable(432, 365, (char *)pCursCels, v7, v8, 0, 8, 1); + } + if ( plr[myplr].InvBody[2]._itype != -1 ) + { + InvDrawSlotBack(633, 365, 28, 28); + v10 = myplr; + v11 = myplr; + v12 = plr[myplr].InvBody[2]._iCurs + 12; + v13 = InvItemWidth[v12]; + screen_ya = InvItemWidth[v12]; + if ( pcursinvitem == 2 ) + { + v14 = -59; + if ( plr[v11].InvBody[2]._iMagical ) + v14 = -75; + if ( !plr[v11].InvBody[2]._iStatFlag ) + v14 = -27; + Cel_colour(v14, 633, 365, (char *)pCursCels, v12, v13, 0, 8); + v10 = myplr; + v13 = screen_ya; + } + if ( plr[v10].InvBody[2]._iStatFlag ) + Cel_header(633, 365, (char *)pCursCels, v12, v13, 0, 8); + else + Cel_header_and_light_not_equipable(633, 365, (char *)pCursCels, v12, v13, 0, 8, 1); + } + if ( plr[myplr].InvBody[3]._itype != -1 ) + { + InvDrawSlotBack(589, 220, 28, 28); + v15 = myplr; + v16 = myplr; + v17 = plr[myplr].InvBody[3]._iCurs + 12; + v18 = InvItemWidth[v17]; + screen_yb = InvItemWidth[v17]; + if ( pcursinvitem == 3 ) + { + v19 = -59; + if ( plr[v16].InvBody[3]._iMagical ) + v19 = -75; + if ( !plr[v16].InvBody[3]._iStatFlag ) + v19 = -27; + Cel_colour(v19, 589, 220, (char *)pCursCels, v17, v18, 0, 8); + v15 = myplr; + v18 = screen_yb; + } + if ( plr[v15].InvBody[3]._iStatFlag ) + Cel_header(589, 220, (char *)pCursCels, v17, v18, 0, 8); + else + Cel_header_and_light_not_equipable(589, 220, (char *)pCursCels, v17, v18, 0, 8, 1); + } + if ( plr[myplr].InvBody[4]._itype != -1 ) + { + InvDrawSlotBack(401, 320, 56, 84); + v20 = myplr; + v21 = myplr; + v22 = plr[myplr].InvBody[4]._iCurs + 12; + v23 = InvItemWidth[v22]; + v24 = v23 != 28 ? 401 : 415; + screen_yc = InvItemHeight[v22] != 84 ? 306 : 320; + if ( pcursinvitem == 4 ) + { + v25 = -59; + if ( plr[v21].InvBody[4]._iMagical ) + v25 = -75; + if ( !plr[v21].InvBody[4]._iStatFlag ) + v25 = -27; + Cel_colour(v25, v24, screen_yc, (char *)pCursCels, v22, v23, 0, 8); + v20 = myplr; + } + if ( plr[v20].InvBody[4]._iStatFlag ) + Cel_header(v24, screen_yc, (char *)pCursCels, v22, v23, 0, 8); + else + Cel_header_and_light_not_equipable(v24, screen_yc, (char *)pCursCels, v22, v23, 0, 8, 1); + if ( plr[myplr].InvBody[4]._iLoc == ILOC_TWOHAND ) + { + InvDrawSlotBack(631, 320, 56, 84); + light_table_index = 0; + cel_transparency_active = 1; + v26 = &gpBuffer->row[160].pixels[581]; + if ( v23 != 28 ) + v26 = &gpBuffer->row[160].pixels[567]; + Cel_header_light_and_trans_into_buf(v26, (char *)pCursCels, v22, v23, 0, 8); + cel_transparency_active = 0; + } + } + if ( plr[myplr].InvBody[5]._itype != -1 ) + { + InvDrawSlotBack(631, 320, 56, 84); + v27 = myplr; + v28 = myplr; + v29 = plr[myplr].InvBody[5]._iCurs + 12; + v30 = InvItemWidth[v29]; + screen_yd = InvItemHeight[v29] != 84 ? 306 : 320; + if ( pcursinvitem == 5 ) + { + v31 = -59; + if ( plr[v28].InvBody[5]._iMagical ) + v31 = -75; + if ( !plr[v28].InvBody[5]._iStatFlag ) + v31 = -27; + Cel_colour(v31, v30 != 28 ? 633 : 645, screen_yd, (char *)pCursCels, v29, v30, 0, 8); + v27 = myplr; + } + screen_x = v30 != 28 ? 633 : 645; + if ( plr[v27].InvBody[5]._iStatFlag ) + Cel_header(screen_x, screen_yd, (char *)pCursCels, v29, v30, 0, 8); + else + Cel_header_and_light_not_equipable(screen_x, screen_yd, (char *)pCursCels, v29, v30, 0, 8, 1); + } + if ( plr[myplr].InvBody[6]._itype != -1 ) + { + InvDrawSlotBack(517, 320, 56, 84); + v32 = myplr; + v33 = myplr; + v34 = plr[myplr].InvBody[6]._iCurs + 12; + v35 = InvItemWidth[v34]; + if ( pcursinvitem == 6 ) + { + v36 = -59; + if ( plr[v33].InvBody[6]._iMagical ) + v36 = -75; + if ( !plr[v33].InvBody[6]._iStatFlag ) + v36 = -27; + Cel_colour(v36, 517, 320, (char *)pCursCels, v34, v35, 0, 8); + v32 = myplr; + } + if ( plr[v32].InvBody[6]._iStatFlag ) + Cel_header(517, 320, (char *)pCursCels, v34, v35, 0, 8); + else + Cel_header_and_light_not_equipable(517, 320, (char *)pCursCels, v34, v35, 0, 8, 1); + } + v37 = 0; + do + { + if ( plr[myplr].InvGrid[v37] ) + InvDrawSlotBack(inv_screen_pos[v37 + 25].x + 64, inv_screen_pos[v37 + 25].y + 159, 28, 28); + ++v37; + } + while ( v37 < 40 ); + v38 = 0; + do + { + v39 = 21720 * myplr; + v40 = plr[myplr].InvGrid[v38]; + if ( v40 > 0 ) + { + v41 = v40 - 1; + v55[v38] = 1; + v42 = v41; + v43 = 368 * v41 + v39; + v44 = *(int *)((char *)&plr[0].InvList[0]._iCurs + v43) + 12; + screen_ye = InvItemWidth[v44]; + if ( pcursinvitem == v41 + 7 ) + { + v45 = -59; + if ( *(&plr[0].InvList[0]._iMagical + v43) ) + v45 = -75; + if ( !*(int *)((char *)&plr[0].InvList[0]._iStatFlag + v43) ) + v45 = -27; + Cel_colour( + v45, + inv_screen_pos[v38 + 25].x + 64, + inv_screen_pos[v38 + 25].y + 159, + (char *)pCursCels, + v44, + screen_ye, + 0, + 8); + } + v46 = inv_screen_pos[v38 + 25].x + 64; + v47 = inv_screen_pos[v38 + 25].y + 159; + if ( plr[myplr].InvList[v42]._iStatFlag ) + Cel_header(v46, v47, (char *)pCursCels, v44, screen_ye, 0, 8); + else + Cel_header_and_light_not_equipable(v46, v47, (char *)pCursCels, v44, screen_ye, 0, 8, 1); + } + ++v38; + } + while ( v38 < 40 ); +} +// 4B8CB8: using guessed type char pcursinvitem; +// 69BEF8: using guessed type int light_table_index; +// 69CF94: using guessed type int cel_transparency_active; +// 41B8C4: using guessed type int var_A0[40]; + +//----- (0041C060) -------------------------------------------------------- +void __cdecl DrawInvBelt() +{ + int v0; // ebx + signed int v1; // esi + int v2; // ecx + int v3; // eax + int v4; // edi + char v5; // cl + int v6; // edx + bool v7; // zf + int v8; // ecx + int v9; // eax + char *v10; // edx + signed int v11; // [esp+4h] [ebp-Ch] + int frame_width; // [esp+8h] [ebp-8h] + int v13; // [esp+Ch] [ebp-4h] + + v0 = 0; + if ( !talkflag ) + { + DrawPanelBox(205, 21, 0xE8u, 0x1Cu, 269, 517); + v11 = 0; + v13 = 0; + do + { + if ( *(int *)((char *)&plr[myplr].SpdList[0]._itype + v0) != -1 ) + { + v1 = v11; + InvDrawSlotBack(inv_screen_pos[v11 + 65].x + 64, inv_screen_pos[v11 + 65].y + 159, 28, 28); + v2 = myplr; + v3 = v0 + 21720 * myplr; + v4 = *(int *)((char *)&plr[0].SpdList[0]._iCurs + v3) + 12; + frame_width = InvItemWidth[v4]; + if ( pcursinvitem == v11 + 47 ) + { + v5 = -59; + if ( *(&plr[0].SpdList[0]._iMagical + v3) ) + v5 = -75; + if ( !*(int *)((char *)&plr[0].SpdList[0]._iStatFlag + v3) ) + v5 = -27; + Cel_colour( + v5, + inv_screen_pos[v1 + 65].x + 64, + inv_screen_pos[v1 + 65].y + 159, + (char *)pCursCels, + v4, + frame_width, + 0, + 8); + v2 = myplr; + } + v0 = v13; + v6 = inv_screen_pos[v1 + 65].y + 159; + v7 = *(int *)((char *)&plr[v2].SpdList[0]._iStatFlag + v13) == 0; + v8 = inv_screen_pos[v1 + 65].x; + if ( v7 ) + Cel_header_and_light_not_equipable(v8 + 64, v6, (char *)pCursCels, v4, frame_width, 0, 8, 1); + else + Cel_header(v8 + 64, v6, (char *)pCursCels, v4, frame_width, 0, 8); + v9 = v13 + 21720 * myplr; + if ( AllItemsList[*(int *)((char *)&plr[0].SpdList[0].IDidx + v9)].iUsable + && *(int *)((char *)&plr[0].SpdList[0]._iStatFlag + v9) + && *(int *)((char *)&plr[0].SpdList[0]._itype + v9) != 11 ) + { + v10 = (char *)fontframe[fontidx[(unsigned char)(v11 + 49)]]; + CPrintString( + screen_y_times_768[inv_screen_pos[v1 + 65].y + 159] + - fontkern[(_DWORD)v10] + + inv_screen_pos[v1 + 65].x + + 92, + v10, + 0); + } + } + ++v11; + v0 += 368; + v13 = v0; + } + while ( v11 < 8 ); + } +} +// 4B8960: using guessed type int talkflag; +// 4B8CB8: using guessed type char pcursinvitem; + +//----- (0041C23F) -------------------------------------------------------- +int __fastcall AutoPlace(int pnum, int ii, int sx, int sy, int saveflag) +{ + __int64 v5; // rax + int v6; // ebx + signed int v7; // edx + signed int v8; // eax + signed int v9; // esi + int j; // edi + int v11; // eax + signed int v12; // esi + signed int v13; // ecx + int v14; // edi + char *v15; // ecx + char v16; // dl + signed int v18; // [esp+Ch] [ebp-Ch] + int p; // [esp+10h] [ebp-8h] + int v20; // [esp+14h] [ebp-4h] + int i; // [esp+14h] [ebp-4h] + + p = pnum; + v5 = ii; + v6 = 1; + v18 = v5 % 10; + v7 = 10 * (unsigned __int64)(v5 / 10); + v8 = v7; + if ( v7 < 0 ) + v8 = 0; + v20 = 0; + if ( sy <= 0 ) + { +LABEL_16: + if ( saveflag ) + { + v11 = pnum; + qmemcpy( + &plr[pnum].InvList[plr[pnum]._pNumInv], + &plr[pnum].HoldItem, + sizeof(plr[pnum].InvList[plr[pnum]._pNumInv])); + ++plr[v11]._pNumInv; + v12 = v7; + if ( v7 < 0 ) + v12 = 0; + for ( i = 0; i < sy; ++i ) + { + v13 = v18; + if ( v18 < 0 ) + v13 = 0; + v14 = 0; + if ( sx > 0 ) + { + v15 = &plr[v11].InvGrid[v13 + v12]; + do + { + if ( v14 || i != sy - 1 ) + v16 = -_LOBYTE(plr[v11]._pNumInv); + else + v16 = plr[v11]._pNumInv; + *v15++ = v16; + ++v14; + } + while ( v14 < sx ); + } + v12 += 10; + } + CalcPlrScrolls(p); + } + } + else + { + while ( v6 ) + { + if ( v8 >= 40 ) + v6 = 0; + v9 = v18; + if ( v18 < 0 ) + v9 = 0; + for ( j = 0; j < sx; ++j ) + { + if ( !v6 ) + break; + v6 = 0; + if ( v9 < 10 ) + _LOBYTE(v6) = plr[pnum].InvGrid[v9 + v8] == 0; + ++v9; + } + v8 += 10; + if ( ++v20 >= sy ) + { + if ( !v6 ) + return v6; + goto LABEL_16; + } + } + } + return v6; +} + +//----- (0041C373) -------------------------------------------------------- +int __fastcall SpecialAutoPlace(int pnum, int ii, int sx, int sy, int saveflag) +{ + __int64 v5; // rax + int v6; // ebx + signed int v7; // edx + signed int v8; // eax + signed int v9; // esi + int j; // edi + signed int v11; // ecx + int *v12; // eax + int v13; // eax + signed int v14; // esi + signed int v15; // ecx + int v16; // edi + char *v17; // ecx + char v18; // dl + signed int v20; // [esp+Ch] [ebp-Ch] + int p; // [esp+10h] [ebp-8h] + int v22; // [esp+14h] [ebp-4h] + int i; // [esp+14h] [ebp-4h] + + p = pnum; + v5 = ii; + v6 = 1; + v20 = v5 % 10; + v7 = 10 * (unsigned __int64)(v5 / 10); + v8 = v7; + if ( v7 < 0 ) + v8 = 0; + v22 = 0; + if ( sy <= 0 ) + { +LABEL_25: + if ( saveflag ) + { + v13 = p; + qmemcpy(&plr[p].InvList[plr[p]._pNumInv], &plr[p].HoldItem, sizeof(plr[p].InvList[plr[p]._pNumInv])); + ++plr[v13]._pNumInv; + v14 = v7; + if ( v7 < 0 ) + v14 = 0; + for ( i = 0; i < sy; ++i ) + { + v15 = v20; + if ( v20 < 0 ) + v15 = 0; + v16 = 0; + if ( sx > 0 ) + { + v17 = &plr[v13].InvGrid[v15 + v14]; + do + { + if ( v16 || i != sy - 1 ) + v18 = -_LOBYTE(plr[v13]._pNumInv); + else + v18 = plr[v13]._pNumInv; + *v17++ = v18; + ++v16; + } + while ( v16 < sx ); + } + v14 += 10; + } + CalcPlrScrolls(p); + } + return v6; + } + while ( v6 ) + { + if ( v8 >= 40 ) + v6 = 0; + v9 = v20; + if ( v20 < 0 ) + v9 = 0; + for ( j = 0; j < sx; ++j ) + { + if ( !v6 ) + break; + v6 = 0; + if ( v9 < 10 ) + _LOBYTE(v6) = plr[pnum].InvGrid[v9 + v8] == 0; + ++v9; + } + v8 += 10; + if ( ++v22 >= sy ) + { + if ( v6 ) + goto LABEL_25; + break; + } + } + if ( sx <= 1 && sy <= 1 ) + { + v11 = 0; + v12 = &plr[p].SpdList[0]._itype; + while ( *v12 != -1 ) + { + ++v11; + v12 += 92; + if ( v11 >= 8 ) + goto LABEL_24; + } + v6 = 1; + goto LABEL_25; + } + v6 = 0; +LABEL_24: + if ( v6 ) + goto LABEL_25; + return v6; +} + +//----- (0041C4E0) -------------------------------------------------------- +int __fastcall GoldAutoPlace(int pnum) +{ + int v1; // ebp + int v2; // edi + int v3; // ecx + int *v4; // esi + int v5; // eax + int v6; // edi + int *v7; // esi + int v8; // eax + signed int v9; // ebx + char *v10; // edx + int v11; // eax + int v12; // ecx + int pnuma; // [esp+10h] [ebp-4h] + + pnuma = pnum; + v1 = pnum; + v2 = 0; + v3 = 0; + if ( plr[v1]._pNumInv <= 0 ) + { +LABEL_14: + v6 = 0; + if ( plr[v1]._pNumInv <= 0 ) + { +LABEL_28: + v9 = 39; + do + { + if ( v3 ) + break; + v10 = &plr[0].InvGrid[10 * (v9 / 10) + v1 * 21720 + v9 % 10]; + if ( !*v10 ) + { + v11 = v1 * 21720 + 368 * plr[v1]._pNumInv; + qmemcpy((char *)plr[0].InvList + v11, &plr[v1].HoldItem, 0x170u); + ++plr[v1]._pNumInv; + *v10 = plr[v1]._pNumInv; + v12 = plr[v1].HoldItem._ivalue; + if ( v12 < 2500 ) + { + if ( v12 > 1000 ) + *(int *)((char *)&plr[0].InvList[0]._iCurs + v11) = 5; + else + *(int *)((char *)&plr[0].InvList[0]._iCurs + v11) = 4; + } + else + { + *(int *)((char *)&plr[0].InvList[0]._iCurs + v11) = 6; + } + plr[v1]._pGold = CalculateGold(pnuma); + v3 = 1; + } + --v9; + } + while ( v9 >= 0 ); + } + else + { + v7 = &plr[v1].InvList[0]._ivalue; + while ( !v3 ) + { + if ( *(v7 - 47) == 11 && *v7 < 5000 ) + { + v8 = plr[v1].HoldItem._ivalue + *v7; + if ( v8 <= 5000 ) + { + *v7 = v8; + if ( v8 < 2500 ) + { + if ( v8 > 1000 ) + *(v7 - 1) = 5; + else + *(v7 - 1) = 4; + } + else + { + *(v7 - 1) = 6; + } + plr[v1]._pGold = CalculateGold(pnuma); + v3 = 1; + } + } + ++v6; + v7 += 92; + if ( v6 >= plr[v1]._pNumInv ) + { + if ( v3 ) + return v3; + goto LABEL_28; + } + } + } + } + else + { + v4 = &plr[v1].InvList[0]._ivalue; + while ( !v3 ) + { + if ( *(v4 - 47) == 11 ) + { + v5 = *v4 + plr[v1].HoldItem._ivalue; + if ( v5 <= 5000 ) + { + *v4 = v5; + if ( v5 < 2500 ) + { + if ( v5 > 1000 ) + *(v4 - 1) = 5; + else + *(v4 - 1) = 4; + } + else + { + *(v4 - 1) = 6; + } + plr[v1]._pGold = CalculateGold(pnuma); + v3 = 1; + } + } + ++v2; + v4 += 92; + if ( v2 >= plr[v1]._pNumInv ) + { + if ( v3 ) + return v3; + goto LABEL_14; + } + } + } + return v3; +} + +//----- (0041C6A9) -------------------------------------------------------- +int __fastcall WeaponAutoPlace(int pnum) +{ + int v1; // edi + int v2; // eax + int v3; // ecx + ItemStruct *v4; // esi + ItemStruct *v5; // edi + int result; // eax + + v1 = pnum; + if ( plr[pnum].HoldItem._iLoc == ILOC_TWOHAND ) + { + if ( plr[v1].InvBody[4]._itype != -1 || plr[v1].InvBody[5]._itype != -1 ) + return 0; +LABEL_12: + NetSendCmdChItem(1u, 4u); + v4 = &plr[v1].HoldItem; + v5 = &plr[v1].InvBody[4]; + goto LABEL_13; + } + v2 = plr[v1].InvBody[4]._itype; + if ( v2 != -1 && plr[v1].InvBody[4]._iClass == 1 ) + return 0; + v3 = plr[v1].InvBody[5]._itype; + if ( v3 != -1 && plr[v1].InvBody[5]._iClass == 1 ) + return 0; + if ( v2 == -1 ) + goto LABEL_12; + if ( v3 == -1 && plr[v1].InvBody[4]._iLoc != ILOC_TWOHAND ) + { + NetSendCmdChItem(1u, 5u); + v4 = &plr[v1].HoldItem; + v5 = &plr[v1].InvBody[5]; +LABEL_13: + result = 1; + qmemcpy(v5, v4, sizeof(ItemStruct)); + return result; + } + return 0; +} + +//----- (0041C746) -------------------------------------------------------- +int __fastcall SwapItem(ItemStruct *a, ItemStruct *b) +{ + int v2; // eax + ItemStruct h; // [esp+8h] [ebp-170h] + + qmemcpy(&h, a, sizeof(h)); + v2 = h._iCurs; + qmemcpy(a, b, sizeof(ItemStruct)); + qmemcpy(b, &h, sizeof(ItemStruct)); + return v2 + 12; +} + +//----- (0041C783) -------------------------------------------------------- +void __fastcall CheckInvPaste(int pnum, int mx, int my) +{ + int v3; // ebx + int v4; // edi + int v5; // eax + int v6; // esi + signed int v7; // edi + int v8; // edx + int v9; // edx + signed int v10; // edi + char v11; // al + signed int v12; // ecx + int v13; // eax + int v14; // eax + char *v15; // edi + int v16; // esi + int v17; // ecx + int v18; // edx + char v19; // al + int v20; // ecx + int v21; // esi + ItemStruct *v22; // edi + ItemStruct *v23; // ecx + int v24; // eax + int v25; // eax + int v26; // edx + ItemStruct *v27; // esi + int v28; // eax + int v29; // ecx + int v30; // esi + int v31; // eax + int v32; // eax + int v33; // ecx + int v34; // eax + int v35; // ecx + char *v36; // eax + int v37; // edx + int v38; // ecx + int v39; // edi + int v40; // esi + int v41; // ebx + int v42; // edx + int v43; // eax + int v44; // eax + signed int v45; // ecx + int v46; // edx + char *v47; // eax + int v48; // edi + int v49; // eax + int v50; // ecx + char *v51; // esi + char v52; // cl + int v53; // ecx + int v54; // eax + int v55; // edi + int v56; // edx + int v57; // esi + int v58; // ebx + int v59; // eax + int v60; // esi + ItemStruct tempitem; // [esp+Ch] [ebp-190h] + int v62; // [esp+17Ch] [ebp-20h] + int p; // [esp+180h] [ebp-1Ch] + int v64; // [esp+184h] [ebp-18h] + int v65; // [esp+188h] [ebp-14h] + int v66; // [esp+18Ch] [ebp-10h] + int v67; // [esp+190h] [ebp-Ch] + int v68; // [esp+194h] [ebp-8h] + int v69; // [esp+198h] [ebp-4h] + char cursor_id; // [esp+1A4h] [ebp+8h] + char cursor_ida; // [esp+1A4h] [ebp+8h] + + p = pnum; + v3 = pnum; + v4 = mx; + SetICursor(plr[pnum].HoldItem._iCurs + 12); + v5 = my + (icursH >> 1); + v6 = v4 + (icursW >> 1); + v64 = icursW28; + v7 = 0; + v67 = icursH28; + v68 = 0; + do + { + if ( v7 ) + goto LABEL_18; + v8 = inv_screen_pos[v68].x; + if ( v6 >= v8 && v6 < v8 + 28 ) + { + v9 = inv_screen_pos[v68].y; + if ( v5 >= v9 - 29 && v5 < v9 ) + { + v7 = 1; + --v68; + } + } + if ( v68 != 24 ) + goto LABEL_13; + if ( !(v64 & 1) ) + v6 -= 14; + if ( !(v67 & 1) ) + { + v5 -= 14; +LABEL_13: + if ( v68 == 64 && !(v67 & 1) ) + v5 += 14; + } + ++v68; + } + while ( (unsigned int)v68 < 0x49 ); + if ( !v7 ) + return; +LABEL_18: + v10 = v68; + v69 = ILOC_UNEQUIPABLE; + if ( v68 >= 0 && v68 <= ILOC_ARMOR ) + v69 = ILOC_HELM; + if ( v68 >= ILOC_HELM && v68 <= ILOC_RING ) + v69 = ILOC_RING; + if ( v68 == ILOC_AMULET ) + v69 = ILOC_AMULET; + if ( v68 >= ILOC_UNEQUIPABLE && v68 <= 18 ) + v69 = ILOC_ONEHAND; + if ( v68 >= 19 && v68 <= 24 ) + v69 = ILOC_ARMOR; + if ( v68 >= 65 && v68 <= 72 ) + v69 = ILOC_BELT; + v11 = plr[v3].HoldItem._iLoc; + v12 = 0; + if ( (char)v11 == v69 ) + v12 = 1; + if ( v69 == 1 && v11 == ILOC_TWOHAND ) + { + v69 = ILOC_TWOHAND; + v12 = 1; + } + if ( v11 != 7 || v69 != ILOC_BELT ) + { +LABEL_50: + if ( v69 != ILOC_UNEQUIPABLE ) + goto LABEL_81; + v66 = 0; + cursor_id = 1; + v13 = (v68 - 25) / 10; + if ( plr[v3].HoldItem._itype == ITYPE_GOLD ) + { + _LOBYTE(v13) = plr[0].InvGrid[10 * v13 + v3 * 21720 + (v68 - 25) % 10]; + if ( !(_BYTE)v13 ) + goto LABEL_93; + v13 = (char)v13; + if ( (char)v13 <= 0 ) + { + v13 = -v13; + } + else if ( *(int *)((char *)&plr[0].InvBody[v13 + 6]._itype + v3 * 21720) == ITYPE_GOLD ) + { + goto LABEL_93; + } + v66 = v13; +LABEL_93: + v21 = p; + if ( p == myplr ) + { + PlaySFX(ItemInvSnds[ItemCAnimTbl[plr[v3].HoldItem._iCurs]]); + v10 = v68; + } + cursor_ida = 1; + switch ( v69 ) + { + case ILOC_ONEHAND: + if ( v10 > 12 ) + { + if ( plr[v3].InvBody[5]._itype == ITYPE_NONE ) + { + v25 = plr[v3].InvBody[4]._itype; + if ( v25 == ITYPE_NONE ) + goto LABEL_232; + if ( plr[v3].InvBody[4]._iLoc == ILOC_TWOHAND ) + { + NetSendCmdDelItem(0, 4u); + NetSendCmdChItem(0, 5u); + SwapItem(&plr[v3].InvBody[5], &plr[v3].InvBody[4]); + v23 = &plr[v3].InvBody[5]; +LABEL_99: + v24 = SwapItem(v23, &plr[v3].HoldItem); +LABEL_172: + cursor_ida = v24; + goto LABEL_226; + } + if ( v25 == ITYPE_NONE || plr[v3].InvBody[4]._iClass != plr[v3].HoldItem._iClass ) + { +LABEL_232: + NetSendCmdChItem(0, 5u); + v22 = &plr[v3].InvBody[5]; +LABEL_158: + qmemcpy(v22, &plr[v3].HoldItem, sizeof(ItemStruct)); + goto LABEL_226; + } + } + else if ( plr[v3].InvBody[4]._itype == ITYPE_NONE + || plr[v3].InvBody[4]._iClass != plr[v3].HoldItem._iClass ) + { + goto LABEL_114; + } + } + else + { + if ( plr[v3].InvBody[4]._itype == ITYPE_NONE ) + { + if ( plr[v3].InvBody[5]._itype != ITYPE_NONE + && plr[v3].InvBody[5]._iClass == plr[v3].HoldItem._iClass ) + { +LABEL_114: + NetSendCmdChItem(0, 5u); + v23 = &plr[v3].InvBody[5]; + goto LABEL_99; + } + NetSendCmdChItem(0, 4u); + v22 = &plr[v3].InvBody[4]; + goto LABEL_158; + } + if ( plr[v3].InvBody[5]._itype != ITYPE_NONE + && plr[v3].InvBody[5]._iClass == plr[v3].HoldItem._iClass ) + { + goto LABEL_114; + } + } + NetSendCmdChItem(0, 4u); + v23 = &plr[v3].InvBody[4]; + goto LABEL_99; + case ILOC_TWOHAND: + NetSendCmdDelItem(0, 5u); + if ( plr[v3].InvBody[4]._itype == ITYPE_NONE ) + goto LABEL_147; + v26 = plr[v3].InvBody[5]._itype; + if ( v26 == -1 ) + goto LABEL_146; + qmemcpy(&tempitem, &plr[v3].HoldItem, sizeof(tempitem)); + v27 = &plr[v3].InvBody[5]; + if ( v26 != 5 ) + v27 = &plr[v3].InvBody[4]; + v28 = p; + qmemcpy(&plr[v3].HoldItem, v27, sizeof(plr[v3].HoldItem)); + v29 = plr[v3].HoldItem._iCurs + 12; + if ( v28 == myplr ) + SetCursor(v29); + else + SetICursor(v29); + v67 = 0; + v30 = 0; + do + { + if ( v67 ) + break; + v31 = AutoPlace(p, v30++, icursW28, icursH28, 1); + v67 = v31; + } + while ( v30 < 40 ); + v32 = p; + qmemcpy(&plr[v3].HoldItem, &tempitem, sizeof(plr[v3].HoldItem)); + v33 = plr[v3].HoldItem._iCurs + 12; + if ( v32 == myplr ) + SetCursor(v33); + else + SetICursor(v33); + if ( !v67 ) + return; + if ( plr[v3].InvBody[5]._itype == ITYPE_SHIELD ) + plr[v3].InvBody[5]._itype = ITYPE_NONE; + else + plr[v3].InvBody[4]._itype = ITYPE_NONE; +LABEL_146: + if ( plr[v3].InvBody[4]._itype != ITYPE_NONE ) + goto LABEL_149; +LABEL_147: + if ( plr[v3].InvBody[5]._itype == ITYPE_NONE ) + { + NetSendCmdChItem(0, 4u); + qmemcpy(&plr[v3].InvBody[4], &plr[v3].HoldItem, sizeof(plr[v3].InvBody[4])); + } + else + { +LABEL_149: + NetSendCmdChItem(0, 4u); + if ( plr[v3].InvBody[4]._itype == ITYPE_NONE ) + SwapItem(&plr[v3].InvBody[4], &plr[v3].InvBody[5]); + cursor_ida = SwapItem(&plr[v3].InvBody[4], &plr[v3].HoldItem); + } + if ( plr[v3].InvBody[4]._itype == ITYPE_STAFF ) + { + v34 = plr[v3].InvBody[4]._iSpell; + if ( v34 ) + { + if ( plr[v3].InvBody[4]._iCharges > 0 ) + { + plr[v3]._pRSpell = v34; + _LOBYTE(plr[v3]._pRSplType) = 3; + force_redraw = 255; + } + } + } + goto LABEL_226; + case ILOC_ARMOR: + NetSendCmdChItem(0, 6u); + if ( plr[v3].InvBody[6]._itype == ITYPE_NONE ) + { + v22 = &plr[v3].InvBody[6]; + goto LABEL_158; + } + v23 = &plr[v3].InvBody[6]; + goto LABEL_99; + case ILOC_HELM: + NetSendCmdChItem(0, 0); + if ( plr[v3].InvBody[0]._itype == ITYPE_NONE ) + { + v22 = plr[v3].InvBody; + goto LABEL_158; + } + v23 = plr[v3].InvBody; + goto LABEL_99; + case ILOC_RING: + if ( v10 == 4 ) + { + NetSendCmdChItem(0, 1u); + if ( plr[v3].InvBody[1]._itype == ITYPE_NONE ) + { + v22 = &plr[v3].InvBody[1]; + goto LABEL_158; + } + v23 = &plr[v3].InvBody[1]; + } + else + { + NetSendCmdChItem(0, 2u); + if ( plr[v3].InvBody[2]._itype == ITYPE_NONE ) + { + v22 = &plr[v3].InvBody[2]; + goto LABEL_158; + } + v23 = &plr[v3].InvBody[2]; + } + goto LABEL_99; + case ILOC_AMULET: + NetSendCmdChItem(0, 3u); + if ( plr[v3].InvBody[3]._itype == ITYPE_NONE ) + { + v22 = &plr[v3].InvBody[3]; + goto LABEL_158; + } + v23 = &plr[v3].InvBody[3]; + goto LABEL_99; + case ILOC_UNEQUIPABLE: + v35 = plr[v3].HoldItem._itype; + if ( v35 == 11 ) + { + if ( !v66 ) + { + v36 = &plr[0].InvGrid[10 * ((v68 - 25) / 10) + v3 * 21720 + (v68 - 25) % 10]; + if ( *v36 <= 0 ) + { + v42 = 368 * plr[v3]._pNumInv + v3 * 21720; + qmemcpy((char *)plr[0].InvList + v42, &plr[v3].HoldItem, 0x170u); + ++plr[v3]._pNumInv; + *v36 = plr[v3]._pNumInv; + v43 = plr[v3].HoldItem._ivalue; + plr[v3]._pGold += v43; + if ( v43 <= 5000 ) + { + if ( v43 < 2500 ) + { + if ( v43 > 1000 ) + *(int *)((char *)&plr[0].InvList[0]._iCurs + v42) = 5; + else + *(int *)((char *)&plr[0].InvList[0]._iCurs + v42) = 4; + } + else + { + *(int *)((char *)&plr[0].InvList[0]._iCurs + v42) = 6; + } + } + goto LABEL_226; + } + v37 = plr[v3].HoldItem._ivalue; + v38 = 368 * (*v36 - 1) + v3 * 21720; + v39 = *(int *)((char *)&plr[0].InvList[0]._ivalue + v38); + v40 = v37 + v39; + if ( v37 + v39 <= 5000 ) + { + *(int *)((char *)&plr[0].InvList[0]._ivalue + v38) = v40; + plr[v3]._pGold += plr[v3].HoldItem._ivalue; + if ( v40 < 2500 ) + { + if ( v40 > 1000 ) + *(int *)((char *)&plr[0].InvList[0]._iCurs + v38) = 5; + else + *(int *)((char *)&plr[0].InvList[0]._iCurs + v38) = 4; + } + else + { + *(int *)((char *)&plr[0].InvList[0]._iCurs + v38) = 6; + } + goto LABEL_226; + } + plr[v3]._pGold += 5000 - v39; + plr[v3].HoldItem._ivalue = v37 - (5000 - v39); + *(int *)((char *)&plr[0].InvList[0]._ivalue + v38) = 5000; + *(int *)((char *)&plr[0].InvList[0]._iCurs + v38) = 6; + v41 = plr[v3].HoldItem._ivalue; + if ( v41 >= 2500 ) + { + cursor_ida = 18; + goto LABEL_226; + } + v24 = (v41 > 1000) + 16; + goto LABEL_172; + } + } + else if ( !v66 ) + { + qmemcpy((char *)&plr[0].InvList[plr[v3]._pNumInv++] + v3 * 21720, &plr[v3].HoldItem, 0x170u); + v66 = plr[v3]._pNumInv; +LABEL_191: + v48 = v67; + v49 = 10 * ((v68 - 25) / 10 - ((v67 - 1) >> 1)); + if ( v49 < 0 ) + v49 = 0; + v65 = 0; + if ( v67 > 0 ) + { + v69 = (v68 - 25) % 10 - ((v64 - 1) >> 1); + do + { + v50 = v69; + if ( v69 < 0 ) + v50 = 0; + v67 = 0; + if ( v64 > 0 ) + { + v51 = &plr[v3].InvGrid[v50 + v49]; + do + { + if ( v67 || v65 != v48 - 1 ) + v52 = -(char)v66; + else + v52 = v66; + *v51++ = v52; + ++v67; + } + while ( v67 < v64 ); + } + v49 += 10; + ++v65; + } + while ( v65 < v48 ); + } + goto LABEL_226; + } + v44 = v66 - 1; + if ( v35 == 11 ) + plr[v3]._pGold += plr[v3].HoldItem._ivalue; + cursor_ida = SwapItem((ItemStruct *)((char *)&plr[0].InvList[v44] + v3 * 21720), &plr[v3].HoldItem); + if ( plr[v3].HoldItem._itype == ITYPE_GOLD ) + plr[v3]._pGold = CalculateGold(v21); + v45 = 0; + v46 = -v66; + do + { + v47 = &plr[v3].InvGrid[v45]; + if ( *v47 == v66 ) + *v47 = 0; + if ( *v47 == v46 ) + *v47 = 0; + ++v45; + } + while ( v45 < 40 ); + goto LABEL_191; + case ILOC_BELT: + v53 = v3 * 21720 + 368 * (v68 - 65); + if ( plr[v3].HoldItem._itype != ITYPE_GOLD ) + { + if ( *(int *)((char *)&plr[0].SpdList[0]._itype + v53) == ITYPE_NONE ) + { + qmemcpy((char *)plr[0].SpdList + v53, &plr[v3].HoldItem, 0x170u); + } + else + { + cursor_ida = SwapItem((ItemStruct *)((char *)plr[0].SpdList + v53), &plr[v3].HoldItem); + if ( plr[v3].HoldItem._itype == ITYPE_GOLD ) + plr[v3]._pGold = CalculateGold(p); + } + goto LABEL_225; + } + v54 = *(int *)((char *)&plr[0].SpdList[0]._itype + v53); + if ( v54 != -1 ) + { + if ( v54 == 11 ) + { + v55 = *(int *)((char *)&plr[0].SpdList[0]._ivalue + v53); + v56 = plr[v3].HoldItem._ivalue; + v57 = v55 + v56; + if ( v55 + v56 <= 5000 ) + { + *(int *)((char *)&plr[0].SpdList[0]._ivalue + v53) = v57; + plr[v3]._pGold += plr[v3].HoldItem._ivalue; + if ( v57 < 2500 ) + { + if ( v57 > 1000 ) + *(int *)((char *)&plr[0].SpdList[0]._iCurs + v53) = 5; + else + *(int *)((char *)&plr[0].SpdList[0]._iCurs + v53) = 4; + } + else + { + *(int *)((char *)&plr[0].SpdList[0]._iCurs + v53) = 6; + } + goto LABEL_225; + } + plr[v3]._pGold += 5000 - v55; + plr[v3].HoldItem._ivalue = v56 - (5000 - v55); + *(int *)((char *)&plr[0].SpdList[0]._ivalue + v53) = 5000; + *(int *)((char *)&plr[0].SpdList[0]._iCurs + v53) = 6; + v58 = plr[v3].HoldItem._ivalue; + if ( v58 >= 2500 ) + { + cursor_ida = 18; + goto LABEL_225; + } + v59 = (v58 > 1000) + 16; + } + else + { + plr[v3]._pGold += plr[v3].HoldItem._ivalue; + v59 = SwapItem((ItemStruct *)((char *)plr[0].SpdList + v53), &plr[v3].HoldItem); + } + cursor_ida = v59; + goto LABEL_225; + } + qmemcpy((char *)plr[0].SpdList + v53, &plr[v3].HoldItem, 0x170u); + plr[v3]._pGold += plr[v3].HoldItem._ivalue; +LABEL_225: + drawsbarflag = 1; +LABEL_226: + v60 = p; + CalcPlrInv(p, 1u); + if ( v60 == myplr ) + { + if ( cursor_ida == 1 ) + SetCursorPos(MouseX + (cursW >> 1), MouseY + (cursH >> 1)); + SetCursor(cursor_ida); + } + return; + default: + goto LABEL_226; + } + } + v62 = (v68 - 25) % 10; + v14 = 10 * (v13 - ((v67 - 1) >> 1)); + if ( v14 < 0 ) + v14 = 0; + v65 = 0; + if ( v67 <= 0 ) + goto LABEL_93; + v15 = &plr[v3].InvGrid[v14]; + while ( 1 ) + { + if ( cursor_id == CURSOR_NONE ) + return; + if ( v14 >= 40 ) + cursor_id = 0; + v16 = v62 - ((v64 - 1) >> 1); + if ( v16 < 0 ) + v16 = 0; + v17 = 0; + if ( v64 > 0 ) + break; +LABEL_79: + v14 += 10; + v15 += 10; + if ( ++v65 >= v67 ) + { + v12 = cursor_id; + v10 = v68; + goto LABEL_81; + } + } + while ( 1 ) + { + if ( cursor_id == CURSOR_NONE ) + goto LABEL_79; + if ( v16 >= 10 ) + goto LABEL_233; + _LOBYTE(v18) = v15[v16]; + if ( (_BYTE)v18 ) + { + v18 = (char)v18; + if ( (v18 & 0x80u) != 0 ) + v18 = -v18; + if ( !v66 ) + { + v66 = v18; + goto LABEL_78; + } + if ( v66 != v18 ) +LABEL_233: + cursor_id = 0; + } +LABEL_78: + ++v16; + if ( ++v17 >= v64 ) + goto LABEL_79; + } + } + if ( v64 == 1 && v67 == 1 ) + { + v12 = 1; + if ( !AllItemsList[plr[v3].HoldItem.IDidx].iUsable ) + v12 = 0; + if ( !plr[v3].HoldItem._iStatFlag ) + v12 = 0; + if ( plr[v3].HoldItem._itype == ITYPE_GOLD ) + { + v12 = 0; + goto LABEL_50; + } + } +LABEL_81: + if ( !v12 ) + return; + if ( v69 == ILOC_UNEQUIPABLE || v69 == ILOC_BELT || plr[v3].HoldItem._iStatFlag ) + goto LABEL_92; + v19 = plr[v3]._pClass; + if ( !v19 ) + { + v20 = PS_WARR13; + goto LABEL_89; + } + if ( v19 != 1 ) + { + if ( v19 != 2 ) + return; + PlaySFX(PS_MAGE13); + v12 = 0; + v10 = v68; +LABEL_92: + if ( !v12 ) + return; + goto LABEL_93; + } + v20 = PS_ROGUE13; +LABEL_89: + PlaySFX(v20); +} +// 4B8C9C: using guessed type int cursH; +// 4B8CB4: using guessed type int icursH; +// 4B8CBC: using guessed type int icursW; +// 52571C: using guessed type int force_redraw; + +//----- (0041D2CF) -------------------------------------------------------- +void __fastcall CheckInvSwap(int pnum, int bLoc, int idx, int wCI, int seed, int bId) +{ + unsigned char v6; // bl + PlayerStruct *v7; // eax + int p; // [esp+Ch] [ebp-4h] + + v6 = bLoc; + p = pnum; + TempItemGeneration(127, idx, wCI, seed, 0); + v7 = &plr[p]; + qmemcpy(&v7->HoldItem, &items[127], sizeof(v7->HoldItem)); + if ( bId ) + v7->HoldItem._iIdentified = 1; + if ( v6 < 7u ) + { + qmemcpy(&v7->InvBody[v6], &v7->HoldItem, sizeof(v7->InvBody[v6])); + if ( v6 == 4 ) + { + if ( v7->HoldItem._iLoc == ILOC_TWOHAND ) + v7->InvBody[5]._itype = ITYPE_NONE; + } + else if ( v6 == 5 && v7->HoldItem._iLoc == ILOC_TWOHAND ) + { + v7->InvBody[4]._itype = ITYPE_NONE; + } + } + CalcPlrInv(p, 1u); +} + +//----- (0041D378) -------------------------------------------------------- +void __fastcall CheckInvCut(int pnum, int mx, int my) +{ + int v3; // ebp + signed int v4; // ecx + signed int v5; // ebx + int v6; // eax + int v7; // eax + char v8; // al + int v9; // edx + signed int v10; // esi + char *v11; // eax + int v12; // ecx + int v13; // edx + int v14; // eax + signed int v15; // esi + char *v16; // eax + int v17; // eax + int v18; // eax + signed int v19; // [esp+Ch] [ebp-Ch] + int p; // [esp+10h] [ebp-8h] + int v21; // [esp+14h] [ebp-4h] + + p = pnum; + v3 = pnum; + v21 = mx; + if ( plr[pnum]._pmode > PM_WALK3 ) + return; + v4 = 0; + if ( dropGoldFlag ) + { + dropGoldFlag = 0; + dropGoldValue = 0; + } + v5 = 0; + v19 = 0; + while ( !v4 ) + { + v6 = inv_screen_pos[v5].x; + if ( mx >= v6 && mx < v6 + 29 ) + { + v7 = inv_screen_pos[v5].y; + if ( my >= v7 - 29 && my < v7 ) + { + v4 = 1; + --v5; + } + } + v19 = ++v5; + if ( (unsigned int)v5 >= 0x49 ) + { + if ( !v4 ) + return; + break; + } + } + plr[v3].HoldItem._itype = ITYPE_NONE; + if ( v5 >= 0 && v5 <= 3 && plr[v3].InvBody[0]._itype != ITYPE_NONE ) + { + NetSendCmdDelItem(0, 0); + qmemcpy(&plr[v3].HoldItem, plr[v3].InvBody, sizeof(plr[v3].HoldItem)); + plr[v3].InvBody[0]._itype = ITYPE_NONE; + } + if ( v5 == 4 ) + { + if ( plr[v3].InvBody[1]._itype == ITYPE_NONE ) + goto LABEL_60; + NetSendCmdDelItem(0, 1u); + qmemcpy(&plr[v3].HoldItem, &plr[v3].InvBody[1], sizeof(plr[v3].HoldItem)); + plr[v3].InvBody[1]._itype = ITYPE_NONE; + } + if ( v5 == 5 ) + { + if ( plr[v3].InvBody[2]._itype == ITYPE_NONE ) + goto LABEL_60; + NetSendCmdDelItem(0, 2u); + qmemcpy(&plr[v3].HoldItem, &plr[v3].InvBody[2], sizeof(plr[v3].HoldItem)); + plr[v3].InvBody[2]._itype = ITYPE_NONE; + } + if ( v5 != 6 ) + goto LABEL_26; + if ( plr[v3].InvBody[3]._itype != ITYPE_NONE ) + { + NetSendCmdDelItem(0, 3u); + qmemcpy(&plr[v3].HoldItem, &plr[v3].InvBody[3], sizeof(plr[v3].HoldItem)); + plr[v3].InvBody[3]._itype = ITYPE_NONE; +LABEL_26: + if ( v5 >= 7 && v5 <= 12 && plr[v3].InvBody[4]._itype != ITYPE_NONE ) + { + NetSendCmdDelItem(0, 4u); + qmemcpy(&plr[v3].HoldItem, &plr[v3].InvBody[4], sizeof(plr[v3].HoldItem)); + plr[v3].InvBody[4]._itype = ITYPE_NONE; + } + if ( v5 >= 13 && v5 <= 18 && plr[v3].InvBody[5]._itype != ITYPE_NONE ) + { + NetSendCmdDelItem(0, 5u); + qmemcpy(&plr[v3].HoldItem, &plr[v3].InvBody[5], sizeof(plr[v3].HoldItem)); + plr[v3].InvBody[5]._itype = ITYPE_NONE; + } + if ( v5 >= 19 && v5 <= 24 && plr[v3].InvBody[6]._itype != ITYPE_NONE ) + { + NetSendCmdDelItem(0, 6u); + qmemcpy(&plr[v3].HoldItem, &plr[v3].InvBody[6], sizeof(plr[v3].HoldItem)); + plr[v3].InvBody[6]._itype = ITYPE_NONE; + } + if ( v5 >= 25 && v5 <= 64 ) + { + v8 = *((_BYTE *)&plr[0].InvList[39]._iVAdd2 + v5 + v3 * 21720 + 3); + if ( v8 ) + { + v9 = v8; + if ( v8 <= 0 ) + v9 = -v8; + v10 = 0; + do + { + v11 = &plr[0].InvGrid[v10 + v3 * 21720]; + v12 = *v11; + if ( v12 == v9 || v12 == -v9 ) + *v11 = 0; + ++v10; + } + while ( v10 < 40 ); + v13 = v9 - 1; + qmemcpy(&plr[v3].HoldItem, (char *)&plr[0].InvList[v13] + v3 * 21720, sizeof(plr[v3].HoldItem)); + v14 = --plr[v3]._pNumInv; + if ( v14 > 0 && v14 != v13 ) + { + qmemcpy( + (char *)&plr[0].InvList[v13] + v3 * 21720, + (char *)&plr[0].InvList[v14] + v3 * 21720, + 0x170u); + v15 = 0; + do + { + v16 = &plr[0].InvGrid[v15 + v3 * 21720]; + if ( *v16 == plr[v3]._pNumInv + 1 ) + *v16 = v13 + 1; + if ( *v16 == -1 - plr[v3]._pNumInv ) + *v16 = -1 - v13; + ++v15; + } + while ( v15 < 40 ); + } + v5 = v19; + } + } + if ( v5 >= 65 ) + { + v17 = v3 * 21720 + 368 * (v5 - 65); + if ( *(int *)((char *)&plr[0].SpdList[0]._itype + v17) != -1 ) + { + qmemcpy(&plr[v3].HoldItem, (char *)plr[0].SpdList + v17, sizeof(plr[v3].HoldItem)); + *(int *)((char *)&plr[0].SpdList[0]._itype + v17) = -1; + drawsbarflag = 1; + } + } + } +LABEL_60: + v18 = plr[v3].HoldItem._itype; + if ( v18 != ITYPE_NONE ) + { + if ( v18 == ITYPE_GOLD ) + plr[v3]._pGold = CalculateGold(p); + CalcPlrInv(p, 1u); + CheckItemStats(p); + if ( p == myplr ) + { + PlaySFX(IS_IGRAB); + SetCursor(plr[v3].HoldItem._iCurs + 12); + SetCursorPos(v21 - (cursW >> 1), MouseY - (cursH >> 1)); + } + } +} +// 4B84DC: using guessed type int dropGoldFlag; +// 4B8C9C: using guessed type int cursH; + +//----- (0041D6EB) -------------------------------------------------------- +void __fastcall inv_update_rem_item(int pnum, int iv) +{ + unsigned char v2; // dl + + if ( (unsigned char)iv < 7u ) + plr[pnum].InvBody[(unsigned char)iv]._itype = -1; + v2 = 0; + if ( plr[pnum]._pmode != PM_DEATH ) + v2 = 1; + CalcPlrInv(pnum, v2); +} + +//----- (0041D722) -------------------------------------------------------- +void __fastcall RemoveInvItem(int pnum, int iv) +{ + int v2; // edx + signed int v3; // ecx + int v4; // ebx + char *v5; // eax + int v6; // esi + int v7; // edx + int v8; // eax + signed int v9; // edi + char *v10; // esi + int v11; // eax + int p; // [esp+Ch] [ebp-4h] + + p = pnum; + v2 = iv + 1; + v3 = 0; + v4 = p; + do + { + v5 = &plr[v4].InvGrid[v3]; + v6 = *v5; + if ( v6 == v2 || v6 == -v2 ) + *v5 = 0; + ++v3; + } + while ( v3 < 40 ); + v7 = v2 - 1; + v8 = --plr[v4]._pNumInv; + if ( v8 > 0 && v8 != v7 ) + { + qmemcpy((char *)&plr[0].InvList[v7] + v4 * 21720, (char *)&plr[0].InvList[v8] + v4 * 21720, 0x170u); + v9 = 0; + do + { + v10 = &plr[v4].InvGrid[v9]; + if ( *v10 == plr[v4]._pNumInv + 1 ) + *v10 = v7 + 1; + if ( *v10 == -1 - plr[v4]._pNumInv ) + *v10 = -1 - v7; + ++v9; + } + while ( v9 < 40 ); + } + CalcPlrScrolls(p); + if ( _LOBYTE(plr[v4]._pRSplType) == 2 ) + { + v11 = plr[v4]._pRSpell; + if ( v11 != -1 ) + { + if ( !(plr[v4]._pScrlSpells[1] & (1 << (v11 - 1) >> 31) | plr[v4]._pScrlSpells[0] & (1 << (v11 - 1))) ) + plr[v4]._pRSpell = -1; + force_redraw = 255; + } + } +} +// 52571C: using guessed type int force_redraw; + +//----- (0041D810) -------------------------------------------------------- +void __fastcall RemoveSpdBarItem(int pnum, int iv) +{ + int v2; // esi + int v3; // eax + + v2 = pnum; + plr[pnum].SpdList[iv]._itype = -1; + CalcPlrScrolls(pnum); + if ( _LOBYTE(plr[v2]._pRSplType) == 2 ) + { + v3 = plr[v2]._pRSpell; + if ( v3 != -1 && !(plr[v2]._pScrlSpells[1] & (1 << (v3 - 1) >> 31) | plr[v2]._pScrlSpells[0] & (1 << (v3 - 1))) ) + plr[v2]._pRSpell = -1; + } + force_redraw = 255; +} +// 52571C: using guessed type int force_redraw; + +//----- (0041D86C) -------------------------------------------------------- +void __cdecl CheckInvItem() +{ + if ( pcurs < CURSOR_FIRSTITEM ) + CheckInvCut(myplr, MouseX, MouseY); + else + CheckInvPaste(myplr, MouseX, MouseY); +} + +//----- (0041D893) -------------------------------------------------------- +void __cdecl CheckInvScrn() +{ + if ( MouseX > 190 && MouseX < 437 && MouseY > 352 && MouseY < 385 ) + CheckInvItem(); +} + +//----- (0041D8BF) -------------------------------------------------------- +void __fastcall CheckItemStats(int pnum) +{ + PlayerStruct *v1; // eax + int v2; // ecx + + v1 = &plr[pnum]; + v2 = v1->HoldItem._iMinStr; + v1->HoldItem._iStatFlag = 0; + if ( v1->_pStrength >= v2 + && v1->_pMagic >= (unsigned char)v1->HoldItem._iMinMag + && v1->_pDexterity >= v1->HoldItem._iMinDex ) + { + v1->HoldItem._iStatFlag = 1; + } +} + +//----- (0041D90B) -------------------------------------------------------- +void __fastcall CheckBookLevel(int pnum) +{ + int v1; // ecx + int v2; // eax + unsigned char v3; // bl + int v4; // edi + + v1 = pnum; + if ( plr[v1].HoldItem._iMiscId == IMISC_BOOK ) + { + v2 = plr[v1].HoldItem._iSpell; + v3 = spelldata[plr[v1].HoldItem._iSpell].sMinInt; + plr[v1].HoldItem._iMinMag = v3; + v4 = plr[0]._pSplLvl[v2 + v1 * 21720]; + if ( plr[0]._pSplLvl[v2 + v1 * 21720] ) + { + do + { + v3 += 20 * v3 / 100; + --v4; + if ( v3 + 20 * v3 / 100 > 255 ) + { + v3 = -1; + v4 = 0; + } + } + while ( v4 ); + plr[v1].HoldItem._iMinMag = v3; + } + } +} + +//----- (0041D97F) -------------------------------------------------------- +void __fastcall CheckQuestItem(int pnum) +{ + int v1; // ecx + int v2; // esi + char v3; // cl + char v4; // cl + char v5; // cl + char v6; // cl + char v7; // al + + v1 = pnum; + v2 = plr[v1].HoldItem.IDidx; + if ( v2 == IDI_OPTAMULET ) + quests[8]._qactive = 3; + if ( v2 == IDI_MUSHROOM && quests[1]._qactive == 2 && quests[1]._qvar1 == 3 ) + { + v3 = plr[v1]._pClass; + sfxdelay = IDI_OPTAMULET; + if ( v3 ) + { + if ( v3 == 1 ) + { + sfxdnum = PS_ROGUE95; + } + else if ( v3 == 2 ) + { + sfxdnum = PS_MAGE95; + } + } + else + { + sfxdnum = PS_WARR95; + } + quests[1]._qvar1 = 4; + } + if ( v2 == IDI_ANVIL ) + { + if ( quests[10]._qactive == 1 ) + { + quests[10]._qactive = 2; + quests[10]._qvar1 = 1; + } + if ( quests[10]._qlog == 1 ) + { + sfxdelay = IDI_OPTAMULET; + v4 = plr[myplr]._pClass; + if ( v4 ) + { + if ( v4 == 1 ) + { + sfxdnum = PS_ROGUE89; + } + else if ( v4 == 2 ) + { + sfxdnum = PS_MAGE89; + } + } + else + { + sfxdnum = PS_WARR89; + } + } + } + if ( v2 == IDI_GLDNELIX ) + { + sfxdelay = 30; + v5 = plr[myplr]._pClass; + if ( v5 ) + { + if ( v5 == 1 ) + { + sfxdnum = PS_ROGUE88; + } + else if ( v5 == 2 ) + { + sfxdnum = PS_MAGE88; + } + } + else + { + sfxdnum = PS_WARR88; + } + } + if ( v2 == IDI_ROCK ) + { + if ( quests[0]._qactive == 1 ) + { + quests[0]._qactive = 2; + quests[0]._qvar1 = 1; + } + if ( quests[0]._qlog == 1 ) + { + sfxdelay = IDI_OPTAMULET; + v6 = plr[myplr]._pClass; + if ( v6 ) + { + if ( v6 == 1 ) + { + sfxdnum = PS_ROGUE87; + } + else if ( v6 == 2 ) + { + sfxdnum = PS_MAGE87; + } + } + else + { + sfxdnum = PS_WARR87; + } + } + } + if ( v2 == IDI_ARMOFVAL ) + { + quests[9]._qactive = 3; + sfxdelay = 20; + v7 = plr[myplr]._pClass; + if ( v7 ) + { + if ( v7 == 1 ) + { + sfxdnum = PS_ROGUE91; + } + else if ( v7 == 2 ) + { + sfxdnum = PS_MAGE91; + } + } + else + { + sfxdnum = PS_WARR91; + } + } +} +// 52A554: using guessed type int sfxdelay; + +//----- (0041DB65) -------------------------------------------------------- +void __fastcall InvGetItem(int pnum, int ii) +{ + int v2; // ebp + int v3; // edx + int v4; // ecx + int v5; // ecx + int pnuma; // [esp+4h] [ebp-8h] + int v7; // [esp+8h] [ebp-4h] + + v7 = ii; + pnuma = pnum; + if ( dropGoldFlag ) + { + dropGoldFlag = 0; + dropGoldValue = 0; + } + v2 = ii; + if ( dItem[items[ii]._ix][items[ii]._iy] ) + { + if ( myplr == pnum && pcurs >= CURSOR_FIRSTITEM ) + NetSendCmdPItem(1u, CMD_SYNCPUTITEM, plr[myplr].WorldX, plr[myplr].WorldY); + _HIBYTE(items[v2]._iCreateInfo) &= 0x7Fu; + qmemcpy(&plr[pnuma].HoldItem, &items[v2], sizeof(plr[pnuma].HoldItem)); + CheckQuestItem(pnuma); + CheckBookLevel(pnuma); + CheckItemStats(pnuma); + v3 = 0; + dItem[items[v2]._ix][items[v2]._iy] = 0; + while ( v3 < numitems ) + { + v4 = itemactive[v3]; + if ( v4 == v7 ) + { + DeleteItem(v4, v3); + v3 = 0; + } + else + { + ++v3; + } + } + v5 = plr[pnuma].HoldItem._iCurs; + pcursitem = -1; + SetCursor(v5 + 12); + } +} +// 4B84DC: using guessed type int dropGoldFlag; +// 4B8CC0: using guessed type char pcursitem; + +//----- (0041DC79) -------------------------------------------------------- +void __fastcall AutoGetItem(int pnum, int ii) +{ + int v2; // ebx + int v3; // ebp + int v4; // eax + int v5; // ecx + int v6; // edi + int v7; // edi + int v8; // edi + int v9; // edi + int v10; // edx + int v11; // ecx + char v12; // al + int v13; // ecx + int iia; // [esp+10h] [ebp-18h] + signed int iib; // [esp+10h] [ebp-18h] + signed int iic; // [esp+10h] [ebp-18h] + signed int iid; // [esp+10h] [ebp-18h] + signed int iie; // [esp+10h] [ebp-18h] + signed int iif; // [esp+10h] [ebp-18h] + signed int iig; // [esp+10h] [ebp-18h] + signed int iih; // [esp+10h] [ebp-18h] + signed int iii; // [esp+10h] [ebp-18h] + signed int iij; // [esp+10h] [ebp-18h] + ItemStruct *v24; // [esp+14h] [ebp-14h] + int *v25; // [esp+14h] [ebp-14h] + int v26; // [esp+18h] [ebp-10h] + int i; // [esp+1Ch] [ebp-Ch] + int v28; // [esp+20h] [ebp-8h] + int v29; // [esp+24h] [ebp-4h] + + v2 = pnum; + i = ii; + if ( dropGoldFlag ) + { + dropGoldFlag = 0; + dropGoldValue = 0; + } + if ( ii == 127 || dItem[items[ii]._ix][items[ii]._iy] ) + { + v3 = pnum; + _HIBYTE(items[ii]._iCreateInfo) &= 0x7Fu; + v28 = ii; + qmemcpy(&plr[pnum].HoldItem, &items[ii], sizeof(plr[pnum].HoldItem)); + CheckQuestItem(pnum); + CheckBookLevel(v2); + CheckItemStats(v2); + SetICursor(plr[v2].HoldItem._iCurs + 12); + if ( plr[v2].HoldItem._itype == ITYPE_GOLD ) + { + v4 = GoldAutoPlace(v2); + } + else + { + v4 = 0; + if ( (!(plr[v3]._pgfxnum & 0xF) || (plr[v3]._pgfxnum & 0xF) == 1) && plr[v3]._pmode <= PM_WALK3 ) + { + if ( plr[v3].HoldItem._iStatFlag ) + { + if ( plr[v3].HoldItem._iClass == 1 ) + { + v4 = WeaponAutoPlace(v2); + if ( v4 ) + { + CalcPlrInv(v2, 1u); + goto LABEL_71; + } + } + } + } + v5 = icursW28; + v29 = icursW28; + v26 = icursH28; + if ( icursW28 == 1 ) + { + if ( icursH28 == 1 ) + { + if ( plr[v3].HoldItem._iStatFlag && AllItemsList[plr[v3].HoldItem.IDidx].iUsable ) + { + iia = 0; + v24 = plr[v3].SpdList; + do + { + if ( v4 ) + break; + if ( v24->_itype == -1 ) + { + qmemcpy(v24, &plr[v3].HoldItem, sizeof(ItemStruct)); + CalcPlrScrolls(v2); + v4 = 1; + drawsbarflag = 1; + } + ++iia; + ++v24; + } + while ( iia < 8 ); + } + v6 = 30; + do + { + if ( v4 ) + break; + v4 = AutoPlace(v2, v6++, 1, 1, 1); + } + while ( v6 <= 39 ); + v7 = 20; + do + { + if ( v4 ) + break; + v4 = AutoPlace(v2, v7++, 1, 1, 1); + } + while ( v7 <= 29 ); + v8 = 10; + do + { + if ( v4 ) + break; + v4 = AutoPlace(v2, v8++, 1, 1, 1); + } + while ( v8 <= 19 ); + v9 = 0; + while ( !v4 ) + { + v4 = AutoPlace(v2, v9++, 1, 1, 1); + if ( v9 > 9 ) + goto LABEL_35; + } + goto LABEL_71; + } +LABEL_35: + if ( v26 == 2 ) + { + iib = 29; + do + { + if ( v4 ) + break; + v4 = AutoPlace(v2, iib--, 1, 2, 1); + } + while ( iib >= 20 ); + iic = 9; + do + { + if ( v4 ) + break; + v4 = AutoPlace(v2, iic--, 1, 2, 1); + } + while ( iic >= 0 ); + iid = 19; + while ( !v4 ) + { + v4 = AutoPlace(v2, iid--, 1, 2, 1); + if ( iid < 10 ) + goto LABEL_45; + } + goto LABEL_71; + } +LABEL_45: + if ( v26 == 3 ) + { + iie = 0; + while ( !v4 ) + { + v4 = AutoPlace(v2, iie++, 1, 3, 1); + if ( iie >= 20 ) + goto LABEL_49; + } + goto LABEL_71; + } + } + else + { +LABEL_49: + if ( v29 == 2 ) + { + if ( v26 == 2 ) + { + v25 = AP2x2Tbl; + do + { + if ( v4 ) + break; + v4 = AutoPlace(v2, *v25, 2, 2, 1); + ++v25; + } + while ( (signed int)v25 < (signed int)"Data\\Inv\\Inv_Sor.CEL" ); + iif = 21; + do + { + if ( v4 ) + break; + v4 = AutoPlace(v2, iif, 2, 2, 1); + iif += 2; + } + while ( iif < 29 ); + iig = 1; + do + { + if ( v4 ) + break; + v4 = AutoPlace(v2, iig, 2, 2, 1); + iig += 2; + } + while ( iig < 9 ); + iih = 10; + while ( !v4 ) + { + v4 = AutoPlace(v2, iih++, 2, 2, 1); + if ( iih >= 19 ) + goto LABEL_63; + } + goto LABEL_71; + } +LABEL_63: + if ( v26 == 3 ) + { + iii = 0; + do + { + if ( v4 ) + break; + v4 = AutoPlace(v2, iii++, 2, 3, 1); + } + while ( iii < 9 ); + iij = 10; + while ( !v4 ) + { + v4 = AutoPlace(v2, iij++, 2, 3, 1); + if ( iij >= 19 ) + goto LABEL_70; + } + goto LABEL_71; + } + } + } + } +LABEL_70: + if ( v4 ) + { +LABEL_71: + v10 = 0; + dItem[items[v28]._ix][items[v28]._iy] = 0; + while ( v10 < numitems ) + { + v11 = itemactive[v10]; + if ( v11 == i ) + { + DeleteItem(v11, v10); + v10 = 0; + } + else + { + ++v10; + } + } + return; + } + if ( v2 == myplr ) + { + v12 = plr[v3]._pClass; + switch ( v12 ) + { + case UI_WARRIOR: + _LOBYTE(v5) = 0; + v13 = random(v5, 3) + PS_WARR14; +LABEL_84: + PlaySFX(v13); + break; + case UI_ROGUE: + _LOBYTE(v5) = 0; + v13 = random(v5, 3) + PS_ROGUE14; + goto LABEL_84; + case UI_SORCERER: + _LOBYTE(v5) = 0; + v13 = random(v5, 3) + PS_MAGE14; + goto LABEL_84; + } + } + qmemcpy(&plr[v3].HoldItem, &items[v28], sizeof(plr[v3].HoldItem)); + RespawnItem(i, 1u); + NetSendCmdPItem(1u, CMD_RESPAWNITEM, items[v28]._ix, items[v28]._iy); + plr[v3].HoldItem._itype = ITYPE_NONE; + } +} +// 48E9A8: using guessed type int AP2x2Tbl[10]; +// 4B84DC: using guessed type int dropGoldFlag; + +//----- (0041E103) -------------------------------------------------------- +void __fastcall FindGetItem(int indx, int ci, int iseed) +{ + int i; // ebx + int v4; // esi + + for ( i = 0; i < numitems; ++i ) + { + v4 = itemactive[i]; + if ( items[v4].IDidx == indx && items[v4]._iSeed == iseed && items[v4]._iCreateInfo == (_WORD)ci ) + break; + } +} + +//----- (0041E158) -------------------------------------------------------- +void __fastcall SyncGetItem(int x, int y, int idx, unsigned short ci, int iseed) +{ + char v5; // cl + int v6; // esi + int v7; // eax + int v8; // eax + int v9; // edx + int v10; // ecx + int v11; // ecx + + v5 = dItem[x][y]; + if ( v5 + && (v6 = v5 - 1, v7 = v6, items[v7].IDidx == idx) + && items[v7]._iSeed == iseed + && items[v7]._iCreateInfo == ci ) + { + FindGetItem(idx, ci, iseed); + } + else + { + FindGetItem(idx, ci, iseed); + v6 = v8; + } + if ( v6 != -1 ) + { + v9 = 0; + dItem[items[v6]._ix][items[v6]._iy] = 0; + while ( v9 < numitems ) + { + v10 = itemactive[v9]; + if ( v10 == v6 ) + { + DeleteItem(v10, v9); + FindGetItem(idx, ci, iseed); + FindGetItem(v11, ci, iseed); + v9 = 0; + } + else + { + ++v9; + } + } + FindGetItem(idx, ci, iseed); + } +} + +//----- (0041E222) -------------------------------------------------------- +int __fastcall CanPut(int i, int j) +{ + int v2; // ecx + int v3; // esi + char v4; // al + int v5; // eax + char v6; // al + bool v7; // sf + char v8; // al + char v9; // cl + + v2 = i; + if ( dItem[v2][j] ) + return 0; + v3 = v2 * 112 + j; + if ( nSolidTable[dPiece[0][v3]] ) + return 0; + v4 = dObject[v2][j]; + if ( v4 ) + { + v5 = v4 <= 0 ? -1 - v4 : v4 - 1; + if ( object[v5]._oSolidFlag ) + return 0; + } + v6 = dObject[v2 + 1][j + 1]; + v7 = v6 < 0; + if ( v6 > 0 ) + { + if ( _LOBYTE(objectavail[30 * v6 + 113]) ) + return 0; + v7 = v6 < 0; + } + if ( v7 && _LOBYTE(object[-(v6 + 1)]._oSelFlag) ) + return 0; + v8 = dObject[v2 + 1][j]; + if ( v8 > 0 ) + { + v9 = dObject[v2][j + 1]; + if ( v9 > 0 && _LOBYTE(objectavail[30 * v8 + 113]) && _LOBYTE(objectavail[30 * v9 + 113]) ) + return 0; + } + if ( !currlevel && (dMonster[0][v3] || dMonster[1][v3 + 1]) ) + return 0; + return 1; +} + +//----- (0041E2F9) -------------------------------------------------------- +int __cdecl TryInvPut() +{ + int result; // eax + int v1; // eax + char v2; // si + int v3; // edi + int v4; // ebx + int v5; // esi + + if ( numitems >= 127 ) + return 0; + v1 = GetDirection(plr[myplr].WorldX, plr[myplr].WorldY, cursmx, cursmy); + v2 = v1; + v3 = plr[myplr].WorldY; + v4 = plr[myplr].WorldX; + if ( CanPut(v4 + offset_x[v1], v3 + offset_y[v1]) + || (v5 = (v2 - 1) & 7, CanPut(v4 + offset_x[v5], v3 + offset_y[v5])) + || CanPut(v4 + offset_x[((_BYTE)v5 + 2) & 7], v3 + offset_y[((_BYTE)v5 + 2) & 7]) ) + { + result = 1; + } + else + { + result = CanPut(v4, v3); + } + return result; +} + +//----- (0041E3BC) -------------------------------------------------------- +void __fastcall DupeInvMsg(char *msg) +{ + char *v1; // esi + int v2; // eax + + v1 = msg; + v2 = GetTickCount(); + if ( (unsigned int)(v2 - dupe_delay) >= 0x1388 ) + { + dupe_delay = v2; + ErrorPlrMsg(v1); + } +} + +//----- (0041E3E4) -------------------------------------------------------- +int __fastcall InvPutItem(int pnum, int x, int y) +{ + int v3; // edi + int *v4; // esi + int v5; // ebx + int v6; // eax + int v7; // esi + int v8; // eax + int v9; // edi + int v10; // esi + int v11; // esi + int v12; // eax + int v13; // edx + int v14; // esi + int v16; // eax + int *v17; // edx + int v18; // edx + ItemStruct *v19; // [esp+Ch] [ebp-1Ch] + int v20; // [esp+10h] [ebp-18h] + signed int v21; // [esp+14h] [ebp-14h] + int v22; // [esp+18h] [ebp-10h] + int v23; // [esp+1Ch] [ebp-Ch] + signed int v24; // [esp+20h] [ebp-8h] + int xa; // [esp+24h] [ebp-4h] + int ya; // [esp+30h] [ebp+8h] + int yb; // [esp+30h] [ebp+8h] + int yc; // [esp+30h] [ebp+8h] + + xa = x; + if ( numitems >= 127 ) + return -1; + v3 = pnum; + _LOWORD(x) = plr[pnum].HoldItem._iCreateInfo; + v4 = &plr[pnum].HoldItem._iSeed; + v19 = &plr[pnum].HoldItem; + FindGetItem(plr[pnum].HoldItem.IDidx, x, plr[pnum].HoldItem._iSeed); + v5 = y; + if ( v6 != -1 ) + { + DupeInvMsg("A duplicate item has been detected. Destroying duplicate..."); + SyncGetItem(xa, y, plr[v3].HoldItem.IDidx, plr[v3].HoldItem._iCreateInfo, *v4); + } + ya = GetDirection(plr[v3].WorldX, plr[v3].WorldY, xa, y); + v7 = v5 - plr[v3].WorldY; + if ( abs(xa - plr[v3].WorldX) > 1 || abs(v7) > 1 ) + { + v5 = plr[v3].WorldY + offset_y[ya]; + xa = plr[v3].WorldX + offset_x[ya]; + } + if ( !CanPut(xa, v5) ) + { + v8 = plr[v3].WorldX; + v9 = plr[v3].WorldY; + v10 = ((_BYTE)ya - 1) & 7; + v20 = v8; + v5 = v9 + offset_y[v10]; + xa = v8 + offset_x[v10]; + if ( !CanPut(xa, v9 + offset_y[v10]) ) + { + v11 = ((_BYTE)v10 + 2) & 7; + v5 = v9 + offset_y[v11]; + xa = v20 + offset_x[v11]; + if ( !CanPut(xa, v9 + offset_y[v11]) ) + { + v24 = 0; + v12 = -1; + yb = 1; + v21 = -1; + while ( !v24 ) + { + v23 = v12; + while ( v12 <= yb && !v24 ) + { + v22 = v21; + v13 = v9 + v23; + v14 = v20 + v21; + do + { + if ( v24 ) + break; + if ( CanPut(v14, v13) ) + { + v24 = 1; + xa = v14; + v5 = v13; + } + ++v22; + ++v14; + } + while ( v22 <= yb ); + v12 = ++v23; + } + ++yb; + v12 = v21-- - 1; + if ( v21 <= -50 ) + { + if ( v24 ) + break; + return -1; + } + } + } + } + } + CanPut(xa, v5); + v16 = itemavail[0]; + dItem[xa][v5] = _LOBYTE(itemavail[0]) + 1; + yc = v16; + v17 = &itemavail[-numitems + 126]; + itemactive[numitems] = v16; + itemavail[0] = *v17; + v18 = v16; + qmemcpy(&items[v16], v19, sizeof(ItemStruct)); + items[v18]._iy = v5; + items[v18]._ix = xa; + RespawnItem(v16, 1u); + ++numitems; + SetCursor(1); + return yc; +} + +//----- (0041E639) -------------------------------------------------------- +int __fastcall SyncPutItem(int pnum, int x, int y, int idx, int icreateinfo, int iseed, int Id, int dur, int mdur, int ch, int mch, int ivalue, unsigned __int32 ibuff) +{ + int v13; // ebx + int v14; // edi + int v15; // esi + int v16; // eax + int v17; // edi + int v18; // ecx + int v19; // edi + int v20; // eax + int v21; // eax + int v22; // eax + int v23; // edx + int v25; // ecx + int *v26; // edx + int v27; // eax + int v28; // eax + int v29; // [esp+Ch] [ebp-18h] + int v30; // [esp+Ch] [ebp-18h] + signed int v31; // [esp+10h] [ebp-14h] + int v32; // [esp+14h] [ebp-10h] + int v33; // [esp+18h] [ebp-Ch] + int o1; // [esp+1Ch] [ebp-8h] + signed int v35; // [esp+20h] [ebp-4h] + int i; // [esp+2Ch] [ebp+8h] + int ia; // [esp+2Ch] [ebp+8h] + int ib; // [esp+2Ch] [ebp+8h] + int ic; // [esp+2Ch] [ebp+8h] + + v13 = x; + v14 = pnum; + if ( numitems >= 127 ) + return -1; + FindGetItem(idx, icreateinfo, iseed); + v15 = y; + if ( v16 != -1 ) + { + DupeInvMsg("A duplicate item has been detected from another player."); + SyncGetItem(v13, y, idx, icreateinfo, iseed); + } + v17 = v14; + i = GetDirection(plr[v17].WorldX, plr[v17].WorldY, v13, y); + v29 = v15 - plr[v17].WorldY; + if ( abs(v13 - plr[v17].WorldX) > 1 || abs(v29) > 1 ) + { + v13 = plr[v17].WorldX + offset_x[i]; + v15 = plr[v17].WorldY + offset_y[i]; + } + if ( !CanPut(v13, v15) ) + { + v18 = plr[v17].WorldX; + v19 = plr[v17].WorldY; + v20 = ((_BYTE)i - 1) & 7; + v30 = v18; + ia = v20; + v20 *= 4; + v13 = v18 + *(int *)((char *)offset_x + v20); + v15 = v19 + *(int *)((char *)offset_y + v20); + if ( !CanPut(v18 + *(int *)((char *)offset_x + v20), v19 + *(int *)((char *)offset_y + v20)) ) + { + v21 = ((_BYTE)ia + 2) & 7; + v13 = v30 + offset_x[v21]; + v15 = v19 + offset_y[v21]; + if ( !CanPut(v30 + offset_x[v21], v19 + offset_y[v21]) ) + { + v35 = 0; + v22 = -1; + ib = 1; + v31 = -1; + while ( !v35 ) + { + v33 = v22; + while ( v22 <= ib && !v35 ) + { + v23 = v19 + v33; + v32 = v31; + o1 = v30 + v31; + do + { + if ( v35 ) + break; + if ( CanPut(o1, v23) ) + { + v13 = o1; + v35 = 1; + v15 = v23; + } + ++v32; + ++o1; + } + while ( v32 <= ib ); + v22 = ++v33; + } + ++ib; + v22 = v31-- - 1; + if ( v31 <= -50 ) + { + if ( v35 ) + break; + return -1; + } + } + } + } + } + CanPut(v13, v15); + v25 = itemavail[0]; + ic = itemavail[0]; + dItem[v13][v15] = _LOBYTE(itemavail[0]) + 1; + v26 = &itemavail[-numitems + 126]; + itemactive[numitems] = v25; + itemavail[0] = *v26; + if ( idx == 23 ) + { + RecreateEar(v25, icreateinfo, iseed, Id, dur, mdur, ch, mch, ivalue, ibuff); + } + else + { + TempItemGeneration(v25, idx, icreateinfo, iseed, ivalue); + if ( Id ) + items[ic]._iIdentified = 1; + v27 = ic; + items[v27]._iDurability = dur; + items[v27]._iMaxDur = mdur; + items[v27]._iCharges = ch; + items[v27]._iMaxCharges = mch; + } + v28 = ic; + items[v28]._ix = v13; + items[v28]._iy = v15; + RespawnItem(ic, 1u); + ++numitems; + return ic; +} + +//----- (0041E8DD) -------------------------------------------------------- +int __cdecl CheckInvHLight() +{ + signed int v0; // ebx + int result; // eax + ItemStruct *v2; // edi + PlayerStruct *v3; // esi + int v4; // eax + int v5; // ebx + int v6; // edi + char *v7; // eax + char v8; // al + char v9; // [esp+Fh] [ebp-1h] + + v0 = 0; + do + { + result = inv_screen_pos[v0].x; + if ( MouseX >= result ) + { + result += 29; + if ( MouseX < result ) + { + result = inv_screen_pos[v0].y; + if ( MouseY >= result - 29 && MouseY < result ) + break; + } + } + ++v0; + } + while ( (unsigned int)v0 < 0x49 ); + if ( (unsigned int)v0 >= 0x49 ) + goto LABEL_37; + v9 = -1; + _LOBYTE(infoclr) = 0; + v2 = 0; + v3 = &plr[myplr]; + ClearPanel(); + if ( v0 >= 0 && v0 <= 3 ) + { + v9 = 0; + v2 = v3->InvBody; + goto LABEL_36; + } + switch ( v0 ) + { + case 4: + v9 = 1; + v2 = &v3->InvBody[1]; + goto LABEL_36; + case 5: + v9 = 2; + v2 = &v3->InvBody[2]; + goto LABEL_36; + case 6: + v9 = 3; + v2 = &v3->InvBody[3]; + goto LABEL_36; + } + if ( v0 >= 7 && v0 <= 12 ) + { + v9 = 4; + v2 = &v3->InvBody[4]; + goto LABEL_36; + } + if ( v0 < 13 || v0 > 18 ) + { + if ( v0 >= 19 && v0 <= 24 ) + { + v9 = 6; + v2 = &v3->InvBody[6]; + goto LABEL_36; + } + if ( v0 < 25 || v0 > 64 ) + { + if ( v0 < 65 ) + goto LABEL_36; + v5 = v0 - 65; + drawsbarflag = 1; + result = 368 * v5; + v2 = &v3->SpdList[v5]; + if ( v3->SpdList[v5]._itype != -1 ) + { + v9 = v5 + 47; + goto LABEL_36; + } + } + else + { + result = abs(*((char *)&v3->InvList[39]._iVAdd2 + v0 + 3)); + if ( result ) + { + v4 = result - 1; + v9 = v4 + 7; + v2 = &v3->InvList[v4]; + goto LABEL_36; + } + } +LABEL_37: + _LOBYTE(result) = -1; + return result; + } + v2 = &v3->InvBody[4]; + if ( v3->InvBody[4]._itype == -1 || v3->InvBody[4]._iLoc != 2 ) + { + v9 = 5; + v2 = &v3->InvBody[5]; + } + else + { + v9 = 4; + } +LABEL_36: + result = v2->_itype; + if ( result == ITYPE_NONE ) + goto LABEL_37; + if ( result == ITYPE_GOLD ) + { + v6 = v2->_ivalue; + v7 = get_pieces_str(v6); + result = sprintf(infostr, "%i gold %s", v6, v7); + } + else + { + v8 = v2->_iMagical; + if ( v8 == 1 ) + { + _LOBYTE(infoclr) = 1; + } + else if ( v8 == 2 ) + { + _LOBYTE(infoclr) = 3; + } + strcpy(infostr, v2->_iName); + if ( v2->_iIdentified ) + { + strcpy(infostr, v2->_iIName); + PrintItemDetails(v2); + } + else + { + PrintItemDur(v2); + } + } + _LOBYTE(result) = v9; + return result; +} +// 4B883C: using guessed type int infoclr; + +//----- (0041EAEA) -------------------------------------------------------- +void __fastcall RemoveScroll(int pnum) +{ + int v1; // eax + int v2; // esi + int v3; // edx + int *v4; // ecx + int v5; // edx + int *v6; // ecx + int p; // [esp+Ch] [ebp-4h] + + p = pnum; + v1 = pnum; + v2 = plr[pnum]._pNumInv; + v3 = 0; + if ( v2 <= 0 ) + { +LABEL_8: + v5 = 0; + v6 = &plr[v1].SpdList[0]._iMiscId; + while ( *(v6 - 53) == -1 || *v6 != IMISC_SCROLL && *v6 != IMISC_SCROLLT || v6[1] != plr[v1]._pSpell ) + { + ++v5; + v6 += 92; + if ( v5 >= 8 ) + return; + } + RemoveSpdBarItem(p, v5); + } + else + { + v4 = &plr[v1].InvList[0]._iMiscId; + while ( *(v4 - 53) == -1 || *v4 != IMISC_SCROLL && *v4 != IMISC_SCROLLT || v4[1] != plr[v1]._pSpell ) + { + ++v3; + v4 += 92; + if ( v3 >= v2 ) + goto LABEL_8; + } + RemoveInvItem(p, v3); + } + CalcPlrScrolls(p); +} + +//----- (0041EB8B) -------------------------------------------------------- +void __cdecl UseScroll() +{ + int v0; // eax + int v1; // esi + int v2; // ecx + int *v3; // edx + signed int v4; // esi + int *v5; // ecx + + if ( pcurs == CURSOR_HAND && (leveltype || *(_DWORD *)&spelldata[plr[myplr]._pRSpell].sTownSpell) ) + { + v0 = myplr; + v1 = 0; + v2 = plr[myplr]._pNumInv; + if ( v2 <= 0 ) + { +LABEL_11: + v4 = 0; + v5 = &plr[v0].SpdList[0]._iMiscId; + do + { + if ( *(v5 - 53) != -1 && (*v5 == IMISC_SCROLL || *v5 == IMISC_SCROLLT) && v5[1] == plr[v0]._pRSpell ) + break; + ++v4; + v5 += 92; + } + while ( v4 < 8 ); + } + else + { + v3 = &plr[v0].InvList[0]._iMiscId; + while ( *(v3 - 53) == -1 || *v3 != IMISC_SCROLL && *v3 != IMISC_SCROLLT || v3[1] != plr[v0]._pRSpell ) + { + ++v1; + v3 += 92; + if ( v1 >= v2 ) + goto LABEL_11; + } + } + } +} +// 5BB1ED: using guessed type char leveltype; + +//----- (0041EC42) -------------------------------------------------------- +void __fastcall UseStaffCharge(int pnum) +{ + int v1; // eax + int *v2; // eax + + v1 = pnum; + if ( plr[pnum].InvBody[4]._itype != ITYPE_NONE + && plr[v1].InvBody[4]._iMiscId == IMISC_STAFF + && plr[v1].InvBody[4]._iSpell == plr[v1]._pRSpell ) + { + v2 = &plr[v1].InvBody[4]._iCharges; + if ( *v2 > 0 ) + { + --*v2; + CalcPlrStaff(pnum); + } + } +} + +//----- (0041EC7F) -------------------------------------------------------- +void __cdecl UseStaff() +{ + int v0; // eax + + if ( pcurs == CURSOR_HAND ) + { + v0 = myplr; + if ( plr[myplr].InvBody[4]._itype != ITYPE_NONE + && plr[v0].InvBody[4]._iMiscId == IMISC_STAFF + && plr[v0].InvBody[4]._iSpell == plr[v0]._pRSpell ) + { + plr[v0].InvBody[4]._iCharges; + } + } +} + +//----- (0041ECC3) -------------------------------------------------------- +void __cdecl StartGoldDrop() +{ + int v0; // eax + + initialDropGoldIndex = pcursinvitem; + if ( pcursinvitem > 46 ) + v0 = plr[myplr].InvBody[pcursinvitem]._iMaxDur; + else + v0 = plr[myplr].InvBody[pcursinvitem]._ivalue; + dropGoldValue = 0; + initialDropGoldValue = v0; + dropGoldFlag = 1; + if ( talkflag ) + control_reset_talk(); +} +// 4B84DC: using guessed type int dropGoldFlag; +// 4B8960: using guessed type int talkflag; +// 4B8CB8: using guessed type char pcursinvitem; + +//----- (0041ED29) -------------------------------------------------------- +int __fastcall UseInvItem(int pnum, int cii) +{ + int v2; // esi + int result; // eax + int v4; // ebx + int v5; // ebp + _DWORD *v6; // edi + char v7; // al + int v8; // ecx + int v9; // eax + int v10; // ecx + char v11; // al + char v12; // al + int p; // [esp+10h] [ebp-8h] + signed int v14; // [esp+14h] [ebp-4h] + + v2 = pnum; + p = pnum; + if ( plr[pnum]._pInvincible && !plr[v2]._pHitPoints && pnum == myplr ) + return 1; + result = 1; + if ( pcurs == 1 && !stextflag ) + { + if ( cii <= 5 ) + return 0; + if ( cii > 46 ) + { + if ( talkflag ) + return result; + v4 = cii - 47; + v14 = 1; + v5 = 368 * (cii - 47) + v2 * 21720; + v6 = (_DWORD *)((char *)plr[0].SpdList + v5); + } + else + { + v4 = cii - 7; + v14 = 0; + v5 = 368 * (cii - 7) + v2 * 21720; + v6 = (_DWORD *)((char *)plr[0].InvList + v5); + } + if ( v6[90] == 17 ) + { + v12 = plr[v2]._pClass; + sfxdelay = 10; + if ( v12 ) + { + if ( v12 == 1 ) + { + sfxdnum = PS_ROGUE95; + } + else if ( v12 == 2 ) + { + sfxdnum = PS_MAGE95; + } + } + else + { + sfxdnum = PS_WARR95; + } + return 1; + } + if ( v6[90] == 19 ) + { + PlaySFX(IS_IBOOK); + v11 = plr[v2]._pClass; + sfxdelay = 10; + if ( v11 ) + { + if ( v11 == 1 ) + { + sfxdnum = PS_ROGUE29; + } + else if ( v11 == 2 ) + { + sfxdnum = PS_MAGE29; + } + } + else + { + sfxdnum = PS_WARR29; + } + return 1; + } + if ( !AllItemsList[v6[90]].iUsable ) + return 0; + if ( !v6[89] ) + { + v7 = plr[v2]._pClass; + if ( v7 ) + { + if ( v7 == 1 ) + { + v8 = PS_ROGUE13; + } + else + { + if ( v7 != 2 ) + return 1; + v8 = PS_MAGE13; + } + } + else + { + v8 = PS_WARR13; + } + PlaySFX(v8); + return 1; + } + v9 = v6[55]; + if ( !v9 && v6[2] == 11 ) + { + StartGoldDrop(); + return 1; + } + if ( dropGoldFlag ) + { + dropGoldFlag = 0; + dropGoldValue = 0; + } + if ( v9 == 21 && !currlevel && !*(_DWORD *)&spelldata[v6[56]].sTownSpell + || v9 == 22 && !currlevel && !*(_DWORD *)&spelldata[v6[56]].sTownSpell ) + { + return 1; + } + if ( v9 == 24 ) + { + v10 = 65; + } + else + { + if ( pnum != myplr ) + goto LABEL_39; + v10 = ItemInvSnds[ItemCAnimTbl[v6[48]]]; + } + PlaySFX(v10); +LABEL_39: + UseItem(p, v6[55], v6[56]); + if ( v14 ) + { + RemoveSpdBarItem(p, v4); + } + else if ( *(int *)((char *)&plr[0].InvList[0]._iMiscId + v5) != IMISC_MAPOFDOOM ) + { + RemoveInvItem(p, v4); + } + return 1; + } + return result; +} +// 4B84DC: using guessed type int dropGoldFlag; +// 4B8960: using guessed type int talkflag; +// 52A554: using guessed type int sfxdelay; +// 6AA705: using guessed type char stextflag; + +//----- (0041EFA1) -------------------------------------------------------- +void __cdecl DoTelekinesis() +{ + if ( pcursobj != -1 ) + NetSendCmdParam1(1u, CMD_OPOBJT, pcursobj); + if ( pcursitem != -1 ) + NetSendCmdGItem(1u, CMD_REQUESTAGITEM, myplr, myplr, pcursitem); + if ( *(_DWORD *)&pcursmonst != -1 && !M_Talker(*(int *)&pcursmonst) && !monster[*(_DWORD *)&pcursmonst].mtalkmsg ) + NetSendCmdParam1(1u, CMD_KNOCKBACK, pcursmonst); + SetCursor(1); +} +// 4B8CC0: using guessed type char pcursitem; +// 4B8CC1: using guessed type char pcursobj; + +//----- (0041F013) -------------------------------------------------------- +int __fastcall CalculateGold(int pnum) +{ + int result; // eax + int v2; // ecx + int *v3; // edx + signed int v4; // esi + int v5; // edx + int *v6; // ecx + + result = 0; + v2 = pnum; + v3 = &plr[v2].SpdList[0]._ivalue; + v4 = 8; + do + { + if ( *(v3 - 47) == 11 ) + { + result += *v3; + force_redraw = 255; + } + v3 += 92; + --v4; + } + while ( v4 ); + v5 = plr[v2]._pNumInv; + if ( v5 > 0 ) + { + v6 = &plr[v2].InvList[0]._ivalue; + do + { + if ( *(v6 - 47) == 11 ) + result += *v6; + v6 += 92; + --v5; + } + while ( v5 ); + } + return result; +} +// 52571C: using guessed type int force_redraw; + +//----- (0041F068) -------------------------------------------------------- +int __cdecl DropItemBeforeTrig() +{ + if ( !TryInvPut() ) + return 0; + NetSendCmdPItem(1u, CMD_PUTITEM, cursmx, cursmy); + SetCursor(1); + return 1; +} + +//----- (0041F096) -------------------------------------------------------- +void __cdecl InitItemGFX() +{ + signed int v0; // esi + char arglist[64]; // [esp+4h] [ebp-40h] + + v0 = 0; + do + { + sprintf(arglist, "Items\\%s.CEL", ItemDropStrs[v0]); + Item2Frm[v0] = (int)LoadFileInMem(arglist, 0); + ++v0; + } + while ( v0 < 35 ); + memset(UniqueItemFlag, 0, 0x200u); +} + +//----- (0041F0E8) -------------------------------------------------------- +bool __fastcall ItemPlace(int x, int y) +{ + int v2; // ecx + int v3; // eax + bool result; // al + + v2 = x; + v3 = v2 * 112 + y; + if ( dMonster[0][v3] || dPlayer[v2][y] || dItem[v2][y] || dObject[v2][y] || dFlags[v2][y] & 8 ) + result = 0; + else + result = nSolidTable[dPiece[0][v3]] == 0; + return result; +} + +//----- (0041F13A) -------------------------------------------------------- +void __cdecl AddInitItems() +{ + int v0; // eax + int v1; // ebx + int *v2; // ecx + int v3; // esi + int v4; // eax + int v5; // eax + int v6; // edx + int v7; // edi + int v8; // eax + int v9; // eax + int v10; // [esp+0h] [ebp-4h] + + v0 = random(11, 3) + 3; + if ( v0 > 0 ) + { + v10 = v0; + do + { + v1 = itemavail[0]; + v2 = &itemavail[-numitems + 126]; + itemactive[numitems] = itemavail[0]; + itemavail[0] = *v2; + do + { + v3 = random(12, 80) + 16; + v4 = random(12, 80); + _LOBYTE(v5) = ItemPlace(v3, v4 + 16); + } + while ( !v5 ); + v7 = v1; + items[v7]._ix = v3; + items[v7]._iy = v6; + dItem[v3][v6] = v1 + 1; + v8 = GetRndSeed(); + items[v7]._iSeed = v8; + SetRndSeed(v8); + if ( random(12, 2) ) + GetItemAttrs(v1, 24, currlevel); + else + GetItemAttrs(v1, 25, currlevel); + items[v7]._iCreateInfo = currlevel + -32768; + SetupItem(v1); + v9 = items[v7]._iAnimLen; + items[v7]._iAnimFlag = 0; + items[v7]._iAnimFrame = v9; + items[v7]._iSelFlag = 1; + DeltaAddItem(v1); + ++numitems; + --v10; + } + while ( v10 ); + } +} + +//----- (0041F24E) -------------------------------------------------------- +void __cdecl InitItems() +{ + int *v0; // eax + int v1; // edx + int v2; // eax + int v3; // eax + + GetItemAttrs(0, 0, 1); + numitems = 0; + qmemcpy(&golditem, items, sizeof(golditem)); + golditem._iStatFlag = 1; + v0 = &items[0]._ix; + do + { + *(v0 - 1) = 0; + *v0 = 0; + v0[1] = 0; + v0[2] = 0; + *((_BYTE *)v0 + 36) = 0; + v0[11] = 0; + v0[10] = 0; + v0 += 92; + } + while ( (signed int)v0 < (signed int)&items[127]._ix ); + v1 = 0; + memset(itemactive, 0, sizeof(itemactive)); + do + { + itemavail[v1] = v1; + ++v1; + } + while ( v1 < 127 ); + if ( !setlevel ) + { + GetRndSeed(); + _LOBYTE(v2) = QuestStatus(0); + if ( v2 ) + SpawnRock(); + _LOBYTE(v3) = QuestStatus(10); + if ( v3 ) + SpawnQuestItem(16, 2 * setpc_x + 27, 2 * setpc_y + 27, 0, 1); + if ( currlevel > 0u && currlevel < 0x10u ) + AddInitItems(); + } + uitemflag = 0; +} +// 5CF31D: using guessed type char setlevel; + +//----- (0041F320) -------------------------------------------------------- +void __fastcall CalcPlrItemVals(int player_num, bool load_gfx) +{ + int v2; // eax + int v3; // ecx + int v4; // ebx + int v5; // esi + int *v6; // edi + int v7; // edx + int v8; // ecx + int v9; // eax + int v10; // edx + int v11; // eax + int *v12; // ecx + int *v13; // eax + int v14; // eax + int v15; // eax + signed int v16; // ecx + bool v17; // zf + signed int v18; // eax + signed int v19; // ecx + signed int v20; // ebx + char v21; // dl + int v22; // eax + int v23; // ecx + int v24; // eax + int v25; // eax + int v26; // edx + int v27; // edx + int v28; // eax + int v29; // ebx + int v30; // ecx + int v31; // eax + int v32; // eax + int v33; // ecx + int i; // edx + int v35; // eax + signed int v36; // [esp-4h] [ebp-84h] + __int64 v37; // [esp+Ch] [ebp-74h] + BOOL v38; // [esp+14h] [ebp-6Ch] + signed int v39; // [esp+18h] [ebp-68h] + int v40; // [esp+1Ch] [ebp-64h] + int v41; // [esp+20h] [ebp-60h] + int v42; // [esp+24h] [ebp-5Ch] + int v43; // [esp+28h] [ebp-58h] + int v44; // [esp+2Ch] [ebp-54h] + int v45; // [esp+30h] [ebp-50h] + int v46; // [esp+34h] [ebp-4Ch] + signed int v47; // [esp+38h] [ebp-48h] + signed int v48; // [esp+3Ch] [ebp-44h] + signed int v49; // [esp+40h] [ebp-40h] + int v50; // [esp+44h] [ebp-3Ch] + char v51; // [esp+48h] [ebp-38h] + int v52; // [esp+4Ch] [ebp-34h] + int v53; // [esp+50h] [ebp-30h] + int v54; // [esp+54h] [ebp-2Ch] + int v55; // [esp+58h] [ebp-28h] + int v56; // [esp+5Ch] [ebp-24h] + int v57; // [esp+60h] [ebp-20h] + int v58; // [esp+64h] [ebp-1Ch] + int v59; // [esp+68h] [ebp-18h] + int v60; // [esp+6Ch] [ebp-14h] + int v61; // [esp+70h] [ebp-10h] + int arglist; // [esp+74h] [ebp-Ch] + int v63; // [esp+78h] [ebp-8h] + int v64; // [esp+78h] [ebp-8h] + signed int r; // [esp+7Ch] [ebp-4h] + + v2 = 0; + arglist = player_num; + v3 = 0; + v4 = 0; + v5 = arglist; + v38 = load_gfx; + v58 = 0; + v57 = 0; + v56 = 0; + v55 = 0; + v59 = 0; + v53 = 0; + v60 = 0; + v52 = 0; + v61 = 0; + v37 = 0i64; + v49 = 0; + v48 = 0; + v47 = 0; + v54 = 0; + r = 10; + v46 = 0; + v63 = 0; + v51 = 0; + v50 = 0; + v45 = 0; + v44 = 0; + v43 = 0; + v42 = 0; + v6 = &plr[arglist].InvBody[0]._iStatFlag; + v39 = 7; + do + { + if ( *(v6 - 87) != -1 && *v6 ) + { + v3 += *(v6 - 38); + v58 += *(v6 - 36); + v2 += *(v6 - 37); + v7 = *(v6 - 33); + v40 = v3; + v41 = v2; + if ( v7 ) + v37 |= 1i64 << ((unsigned char)v7 - 1); + if ( !*((_BYTE *)v6 - 296) || *(v6 - 75) ) + { + v57 += *(v6 - 28); + v56 += *(v6 - 27); + v8 = *(v6 - 26); + if ( v8 ) + { + v9 = v8 * *(v6 - 36) / 100; + if ( !v9 ) + v9 = 1; + v55 += v9; + v2 = v41; + } + v4 += *(v6 - 16); + v59 |= *(v6 - 35); + v53 += *(v6 - 25); + v60 += *(v6 - 24); + v52 += *(v6 - 23); + v61 += *(v6 - 22); + v49 += *(v6 - 21); + v48 += *(v6 - 20); + v47 += *(v6 - 19); + v54 += *(v6 - 15); + r += *(v6 - 14); + v46 += *(v6 - 17); + v63 += *(v6 - 18); + v51 += *((_BYTE *)v6 - 52); + v50 += *(v6 - 7); + v45 += *(v6 - 11); + v44 += *(v6 - 10); + v43 += *(v6 - 9); + v42 += *(v6 - 8); + v3 = v40; + } + } + v6 += 92; + --v39; + } + while ( v39 ); + if ( !v3 && !v2 ) + { + v2 = 1; + v3 = 1; + if ( plr[v5].InvBody[4]._itype == ITYPE_SHIELD && plr[v5].InvBody[4]._iStatFlag ) + v2 = 3; + if ( plr[v5].InvBody[5]._itype == ITYPE_SHIELD && plr[v5].InvBody[5]._iStatFlag ) + v2 = 3; + } + plr[v5]._pIMaxDam = v2; + plr[v5]._pIAC = v58; + plr[v5]._pIBonusDam = v57; + plr[v5]._pIBonusToHit = v56; + plr[v5]._pIBonusAC = v55; + plr[v5]._pIFlags = v59; + plr[v5]._pIGetHit = v54; + plr[v5]._pIMinDam = v3; + plr[v5]._pIBonusDamMod = v4; + if ( r < 2 ) + r = 2; + if ( r > 15 ) + r = 15; + if ( plr[v5]._pLightRad != r && arglist == myplr ) + { + ChangeLightRadius(plr[v5]._plid, r); + v10 = 10; + if ( r >= 10 ) + v10 = r; + ChangeVisionRadius(plr[v5]._pvid, v10); + plr[v5]._pLightRad = r; + } + plr[v5]._pStrength = v53 + plr[v5]._pBaseStr; + v11 = myplr; + v12 = &plr[myplr]._pStrength; + if ( *v12 <= 0 ) + *v12 = 0; + plr[v5]._pMagic = v60 + plr[v5]._pBaseMag; + if ( plr[v11]._pMagic <= 0 ) + plr[v11]._pMagic = 0; + plr[v5]._pDexterity = v52 + plr[v5]._pBaseDex; + if ( plr[v11]._pDexterity <= 0 ) + plr[v11]._pDexterity = 0; + v13 = &plr[v11]._pVitality; + plr[v5]._pVitality = v61 + plr[v5]._pBaseVit; + if ( *v13 <= 0 ) + *v13 = 0; + v14 = plr[v5]._pLevel; + if ( _LOBYTE(plr[v5]._pClass) == 1 ) + { + v15 = (plr[v5]._pStrength + plr[v5]._pDexterity) * v14; + v16 = 200; + } + else + { + v15 = plr[v5]._pStrength * v14; + v16 = 100; + } + v17 = _LOBYTE(plr[v5]._pRSplType) == 3; + plr[v5]._pISpells[0] = v37; + plr[v5]._pISpells[1] = HIDWORD(v37); + plr[v5]._pDamageMod = v15 / v16; + if ( v17 && !(v37 & (1i64 << (_LOBYTE(plr[v5]._pRSpell) - 1))) ) + { + plr[v5]._pRSpell = -1; + _LOBYTE(plr[v5]._pRSplType) = 4; + force_redraw = 255; + } + plr[v5]._pISplLvlAdd = v51; + plr[v5]._pIEnAc = v50; + if ( v59 >= 0 ) + { + v19 = v49; + v20 = v48; + v18 = v47; + } + else + { + v18 = 0; + v19 = 0; + v20 = 0; + } + if ( v18 > 75 ) + _LOBYTE(v18) = 75; + plr[v5]._pMagResist = v18; + if ( v19 > 75 ) + _LOBYTE(v19) = 75; + plr[v5]._pFireResist = v19; + if ( v20 > 75 ) + _LOBYTE(v20) = 75; + v21 = plr[v5]._pClass; + v22 = v61; + plr[v5]._pLghtResist = v20; + if ( !v21 ) + v22 = 2 * v61; + if ( v21 == 1 ) + v22 += v22 >> 1; + v23 = (v22 << 6) + v46; + v24 = v60; + if ( v21 == 2 ) + v24 = 2 * v60; + if ( v21 == 1 ) + v24 += v24 >> 1; + v64 = (v24 << 6) + v63; + v25 = v23 + plr[v5]._pHPBase; + v26 = v23 + plr[v5]._pMaxHPBase; + plr[v5]._pHitPoints = v25; + v17 = arglist == myplr; + plr[v5]._pMaxHP = v26; + if ( v17 && (signed int)(v25 & 0xFFFFFFC0) <= 0 ) + SetPlayerHitPoints(arglist, 0); + plr[v5]._pMana = v64 + plr[v5]._pManaBase; + plr[v5]._pMaxMana = v64 + plr[v5]._pMaxManaBase; + plr[v5]._pIFMinDam = v45; + plr[v5]._pIFMaxDam = v44; + plr[v5]._pILMinDam = v43; + plr[v5]._pILMaxDam = v42; + if ( v59 & 1 ) + plr[v5]._pInfraFlag = 1; + else + plr[v5]._pInfraFlag = 0; + v27 = plr[v5].InvBody[4]._itype; + plr[v5]._pBlockFlag = 0; + v28 = 0; + plr[v5]._pwtype = 0; + if ( v27 != ITYPE_NONE && plr[v5].InvBody[4]._iClass == 1 && plr[v5].InvBody[4]._iStatFlag ) + v28 = v27; + v29 = plr[v5].InvBody[5]._itype; + if ( v29 != ITYPE_NONE && plr[v5].InvBody[5]._iClass == 1 && plr[v5].InvBody[5]._iStatFlag ) + v28 = plr[v5].InvBody[5]._itype; + switch ( v28 ) + { + case ITYPE_SWORD: + v36 = 2; + goto LABEL_86; + case ITYPE_AXE: + v36 = 5; + goto LABEL_86; + case ITYPE_BOW: + plr[v5]._pwtype = 1; + v36 = 4; + goto LABEL_86; + case ITYPE_MACE: + v36 = 6; + goto LABEL_86; + case ITYPE_STAFF: + v36 = 8; +LABEL_86: + v28 = v36; + break; + } + if ( v27 == ITYPE_SHIELD && plr[v5].InvBody[4]._iStatFlag ) + { + plr[v5]._pBlockFlag = 1; + ++v28; + } + if ( v29 == ITYPE_SHIELD && plr[v5].InvBody[5]._iStatFlag ) + { + plr[v5]._pBlockFlag = 1; + ++v28; + } + v30 = plr[v5].InvBody[6]._itype; + if ( v30 == ITYPE_MARMOR && plr[v5].InvBody[6]._iStatFlag ) + v28 += 16; + if ( v30 == ITYPE_HARMOR && plr[v5].InvBody[6]._iStatFlag ) + v28 += 32; + if ( plr[v5]._pgfxnum != v28 && v38 ) + { + plr[v5]._pgfxnum = v28; + plr[v5]._pGFXLoad = 0; + LoadPlrGFX(arglist, 1); + SetPlrAnims(arglist); + v31 = plr[0]._peqN[plr[v5]._pdir + 5430 * arglist]; + plr[v5]._pAnimFrame = 1; + plr[v5]._pAnimData = v31; + plr[v5]._pAnimLen = plr[v5]._pNFrames; + v32 = plr[v5]._pNFNum; + plr[v5]._pAnimWidth = v32; + plr[v5]._pAnimCnt = 0; + plr[v5]._pAnimDelay = 3; + plr[v5]._pAnimWidth2 = (v32 - 64) >> 1; + } + else + { + plr[v5]._pgfxnum = v28; + } + v33 = nummissiles; + for ( i = 0; i < v33; ++i ) + { + v35 = missileactive[i]; + if ( missile[v35]._mitype == 13 && missile[v35]._misource == arglist ) + { + missile[v35]._miVar1 = plr[v5]._pHitPoints; + missile[v35]._miVar2 = plr[v5]._pHPBase; + } + } + drawmanaflag = 1; + drawhpflag = 1; +} +// 52571C: using guessed type int force_redraw; + +//----- (0041F953) -------------------------------------------------------- +void __fastcall CalcPlrScrolls(int p) +{ + int v1; // esi + int v2; // eax + int *v3; // edi + int v4; // ebx + signed __int64 v5; // rax + int *v6; // edi + signed int v7; // ebx + signed __int64 v8; // rax + __int64 v9; // rax + + v1 = p; + v2 = plr[p]._pNumInv; + plr[v1]._pScrlSpells[0] = 0; + plr[v1]._pScrlSpells[1] = 0; + if ( v2 > 0 ) + { + v3 = &plr[v1].InvList[0]._iMiscId; + v4 = v2; + do + { + if ( *(v3 - 53) != -1 && (*v3 == IMISC_SCROLL || *v3 == IMISC_SCROLLT) && v3[34] ) + { + v5 = 1i64 << (*((_BYTE *)v3 + 4) - 1); + plr[v1]._pScrlSpells[0] |= v5; + plr[v1]._pScrlSpells[1] |= HIDWORD(v5); + } + v3 += 92; + --v4; + } + while ( v4 ); + } + v6 = &plr[v1].SpdList[0]._iMiscId; + v7 = 8; + do + { + if ( *(v6 - 53) != -1 && (*v6 == IMISC_SCROLL || *v6 == IMISC_SCROLLT) && v6[34] ) + { + v8 = 1i64 << (*((_BYTE *)v6 + 4) - 1); + plr[v1]._pScrlSpells[0] |= v8; + plr[v1]._pScrlSpells[1] |= HIDWORD(v8); + } + v6 += 92; + --v7; + } + while ( v7 ); + if ( _LOBYTE(plr[v1]._pRSplType) == 2 ) + { + v9 = 1 << (_LOBYTE(plr[v1]._pRSpell) - 1); + if ( !(plr[v1]._pScrlSpells[1] & HIDWORD(v9) | plr[v1]._pScrlSpells[0] & (unsigned int)v9) ) + { + plr[v1]._pRSpell = -1; + _LOBYTE(plr[v1]._pRSplType) = 4; + force_redraw = 255; + } + } +} +// 52571C: using guessed type int force_redraw; + +//----- (0041FA4A) -------------------------------------------------------- +void __fastcall CalcPlrStaff(int pnum) +{ + int v1; // esi + bool v2; // zf + signed __int64 v3; // rax + + v1 = pnum; + v2 = plr[pnum].InvBody[4]._itype == ITYPE_NONE; + plr[v1]._pISpells[0] = 0; + plr[v1]._pISpells[1] = 0; + if ( !v2 && plr[v1].InvBody[4]._iStatFlag && plr[v1].InvBody[4]._iCharges > 0 ) + { + v3 = 1i64 << (_LOBYTE(plr[v1].InvBody[4]._iSpell) - 1); + plr[v1]._pISpells[0] = v3; + plr[v1]._pISpells[1] = HIDWORD(v3); + } +} + +//----- (0041FA97) -------------------------------------------------------- +void __fastcall CalcSelfItems(int pnum) +{ + PlayerStruct *v1; // ecx + int v2; // edx + int v3; // esi + int v4; // edi + int *v5; // eax + signed int v6; // ebx + bool v7; // zf + char *v8; // eax + signed int v9; // [esp+Ch] [ebp-10h] + signed int v10; // [esp+10h] [ebp-Ch] + int v11; // [esp+14h] [ebp-8h] + signed int v12; // [esp+18h] [ebp-4h] + + v1 = &plr[pnum]; + v2 = 0; + v3 = 0; + v4 = 0; + v5 = &v1->InvBody[0]._iStatFlag; + v6 = 7; + do + { + if ( *(v5 - 87) != -1 ) + { + v7 = *(v5 - 75) == 0; + *v5 = 1; + if ( !v7 ) + { + v2 += *(v5 - 25); + v3 += *(v5 - 24); + v4 += *(v5 - 23); + } + } + v5 += 92; + --v6; + } + while ( v6 ); + v11 = v4; + do + { + v9 = 0; + v8 = &v1->InvBody[0]._iMinStr; + v10 = 7; + do + { + if ( *((_DWORD *)v8 - 86) != -1 && *((_DWORD *)v8 + 1) ) + { + v12 = 1; + if ( v2 + v1->_pBaseStr < *v8 ) + v12 = 0; + if ( v3 + v1->_pBaseMag < (unsigned char)v8[1] ) + v12 = 0; + if ( v11 + v1->_pBaseDex < v8[2] ) + v12 = 0; + if ( !v12 ) + { + v7 = *((_DWORD *)v8 - 74) == 0; + v9 = 1; + *((_DWORD *)v8 + 1) = 0; + if ( !v7 ) + { + v2 -= *((_DWORD *)v8 - 24); + v3 -= *((_DWORD *)v8 - 23); + v11 -= *((_DWORD *)v8 - 22); + } + } + } + v8 += 368; + --v10; + } + while ( v10 ); + } + while ( v9 ); +} + +//----- (0041FB91) -------------------------------------------------------- +void __fastcall CalcPlrItemMin(int pnum) +{ + PlayerStruct *v1; // ecx + PlayerStruct *v2; // esi + ItemStruct *v3; // edi + int v4; // ebp + int v5; // eax + ItemStruct *v6; // edi + signed int v7; // ebp + int v8; // eax + + v1 = &plr[pnum]; + v2 = v1; + v3 = v1->InvList; + if ( v1->_pNumInv ) + { + v4 = v1->_pNumInv; + do + { + _LOBYTE(v5) = ItemMinStats(v2, v3); + v3->_iStatFlag = v5; + ++v3; + --v4; + } + while ( v4 ); + } + v6 = v2->SpdList; + v7 = 8; + do + { + if ( v6->_itype != -1 ) + { + _LOBYTE(v8) = ItemMinStats(v2, v6); + v6->_iStatFlag = v8; + } + ++v6; + --v7; + } + while ( v7 ); +} + +//----- (0041FBF6) -------------------------------------------------------- +unsigned char __fastcall ItemMinStats(PlayerStruct *p, ItemStruct *x) +{ + unsigned char result; // al + + if ( p->_pMagic < (unsigned char)x->_iMinMag || p->_pStrength < x->_iMinStr ) + result = 0; + else + result = p->_pDexterity >= x->_iMinDex; + return result; +} + +//----- (0041FC2C) -------------------------------------------------------- +void __fastcall CalcPlrBookVals(int p) +{ + int v1; // esi + int v2; // ebx + int *v3; // edi + int v4; // eax + int v5; // esi + int *v6; // edi + int v7; // eax + unsigned char v8; // cl + unsigned char v9; // cl + int v10; // eax + int v11; // eax + int v12; // [esp+Ch] [ebp-Ch] + int v13; // [esp+10h] [ebp-8h] + unsigned char v14; // [esp+17h] [ebp-1h] + + v1 = p; + if ( !currlevel ) + { + v2 = 1; + if ( witchitem[1]._itype != -1 ) + { + v3 = &witchitem[1]._iStatFlag; + do + { + WitchBookLevel(v2); + _LOBYTE(v4) = StoreStatOk((ItemStruct *)(v3 - 89)); + *v3 = v4; + v3 += 92; + ++v2; + } + while ( *(v3 - 87) != -1 ); + } + } + v5 = v1; + v12 = 0; + if ( plr[v5]._pNumInv > 0 ) + { + v6 = &plr[v5].InvList[0]._iSpell; + do + { + if ( !*(v6 - 54) && *(v6 - 1) == 24 ) + { + v7 = *v6; + v8 = spelldata[*v6].sMinInt; + *((_BYTE *)v6 + 129) = v8; + v13 = plr[0]._pSplLvl[v7 + v5 * 21720]; + if ( plr[0]._pSplLvl[v7 + v5 * 21720] ) + { + do + { + v9 = 20 * v8 / 100 + v8; + --v13; + v14 = v9; + v10 = v9 + 20 * v9 / 100; + v8 = -1; + if ( v10 <= 255 ) + v8 = v14; + else + v13 = 0; + } + while ( v13 ); + *((_BYTE *)v6 + 129) = v8; + } + _LOBYTE(v11) = ItemMinStats(&plr[v5], (ItemStruct *)(v6 - 56)); + v6[33] = v11; + } + ++v12; + v6 += 92; + } + while ( v12 < plr[v5]._pNumInv ); + } +} + +//----- (0041FD3E) -------------------------------------------------------- +void __fastcall CalcPlrInv(int p, unsigned char Loadgfx) +{ + unsigned char v2; // di + int v3; // esi + + v2 = Loadgfx; + v3 = p; + CalcPlrItemMin(p); + CalcSelfItems(v3); + CalcPlrItemVals(v3, v2); + CalcPlrItemMin(v3); + if ( v3 == myplr ) + { + CalcPlrBookVals(v3); + CalcPlrScrolls(v3); + CalcPlrStaff(v3); + if ( v3 == myplr && !currlevel ) + RecalcStoreStats(); + } +} + +//----- (0041FD98) -------------------------------------------------------- +void __fastcall SetPlrHandItem(ItemStruct *item, int item_id) +{ + int v2; // ebx + ItemStruct *v3; // esi + ItemDataStruct *v4; // edi + int v5; // eax + + v2 = item_id; + v3 = item; + v4 = &AllItemsList[item_id]; + memset(item, 0, 0x170u); + v3->_itype = (char)v4->itype; + v3->_iCurs = v4->iCurs; + strcpy(v3->_iName, v4->iName); + strcpy(v3->_iIName, v4->iName); + v3->_iLoc = v4->iLoc; + v3->_iClass = v4->iClass; + v3->_iMinDam = v4->iMinDam; + v3->_iMaxDam = v4->iMaxDam; + v3->_iAC = v4->iMinAC; + v3->_iMiscId = v4->iMiscId; + v3->_iSpell = v4->iSpell; + if ( v4->iMiscId == IMISC_STAFF ) + v3->_iCharges = 40; + v3->_iMaxCharges = v3->_iCharges; + v3->_iDurability = v4->iDurability; + v3->_iMaxDur = v4->iDurability; + v3->_iMinStr = v4->iMinStr; + v3->_iMinMag = v4->iMinMag; + v3->_iMinDex = v4->iMinDex; + v3->_ivalue = v4->iValue; + v5 = v4->iValue; + v3->_iPrePower = -1; + v3->_iSufPower = -1; + v3->_iMagical = 0; + v3->_iIvalue = v5; + v3->IDidx = v2; +} + +//----- (0041FE98) -------------------------------------------------------- +void __fastcall GetPlrHandSeed(ItemStruct *item) +{ + item->_iSeed = GetRndSeed(); +} + +//----- (0041FEA4) -------------------------------------------------------- +void __fastcall GetGoldSeed(int player_num, int *item_seed) +{ + int *v2; // ebx + int v3; // edi + signed int v4; // esi + int v5; // eax + int i; // ecx + int v7; // edx + ItemStruct *v8; // ecx + + v2 = item_seed; + v3 = player_num; + do + { + v4 = 1; + v5 = GetRndSeed(); + for ( i = 0; i < numitems; ++i ) + { + if ( items[itemactive[i]]._iSeed == v5 ) + v4 = 0; + } + if ( v3 == myplr ) + { + v7 = plr[v3]._pNumInv; + if ( v7 > 0 ) + { + v8 = plr[v3].InvList; + do + { + if ( v8->_iSeed == v5 ) + v4 = 0; + ++v8; + --v7; + } + while ( v7 ); + } + } + } + while ( !v4 ); + *v2 = v5; +} + +//----- (0041FF16) -------------------------------------------------------- +void __fastcall SetPlrHandSeed(ItemStruct *h, int iseed) +{ + h->_iSeed = iseed; +} + +//----- (0041FF19) -------------------------------------------------------- +void __fastcall SetPlrHandGoldCurs(ItemStruct *h) +{ + int v1; // eax + + v1 = h->_ivalue; + if ( v1 < 2500 ) + { + if ( v1 > 1000 ) + h->_iCurs = 5; + else + h->_iCurs = 4; + } + else + { + h->_iCurs = 6; + } +} + +//----- (0041FF4E) -------------------------------------------------------- +void __fastcall CreatePlrItems(int player_num) +{ + int v1; // ebx + int *v2; // eax + signed int v3; // ecx + int *v4; // eax + signed int v5; // ecx + int *v6; // eax + signed int v7; // ecx + int player_numa; // [esp+Ch] [ebp-4h] + + player_numa = player_num; + v1 = player_num; + v2 = &plr[player_num].InvBody[0]._itype; + v3 = 7; + do + { + *v2 = -1; + v2 += 92; + --v3; + } + while ( v3 ); + memset(plr[v1].InvGrid, 0, 0x28u); + v4 = &plr[v1].InvList[0]._itype; + v5 = 40; + do + { + *v4 = -1; + v4 += 92; + --v5; + } + while ( v5 ); + plr[v1]._pNumInv = 0; + v6 = &plr[v1].SpdList[0]._itype; + v7 = 8; + do + { + *v6 = -1; + v6 += 92; + --v7; + } + while ( v7 ); + switch ( _LOBYTE(plr[v1]._pClass) ) + { + case UI_WARRIOR: + SetPlrHandItem(&plr[v1].InvBody[4], 1); + GetPlrHandSeed(&plr[v1].InvBody[4]); + SetPlrHandItem(&plr[v1].InvBody[5], 2); + GetPlrHandSeed(&plr[v1].InvBody[5]); + SetPlrHandItem(&plr[v1].HoldItem, 3); + GetPlrHandSeed(&plr[v1].HoldItem); + AutoPlace(player_numa, 0, 1, 3, 1); + goto LABEL_13; + case UI_ROGUE: + SetPlrHandItem(&plr[v1].InvBody[4], 4); + GetPlrHandSeed(&plr[v1].InvBody[4]); +LABEL_13: + SetPlrHandItem(plr[v1].SpdList, 24); + GetPlrHandSeed(plr[v1].SpdList); + SetPlrHandItem(&plr[v1].SpdList[1], 24); + goto LABEL_14; + case UI_SORCERER: + SetPlrHandItem(&plr[v1].InvBody[4], 5); + GetPlrHandSeed(&plr[v1].InvBody[4]); + SetPlrHandItem(plr[v1].SpdList, 25); + GetPlrHandSeed(plr[v1].SpdList); + SetPlrHandItem(&plr[v1].SpdList[1], 25); +LABEL_14: + GetPlrHandSeed(&plr[v1].SpdList[1]); + break; + } + SetPlrHandItem(&plr[v1].HoldItem, 0); + GetPlrHandSeed(&plr[v1].HoldItem); + plr[v1].HoldItem._iCurs = 4; + plr[v1].HoldItem._ivalue = 100; + plr[v1]._pGold = 100; + qmemcpy((char *)&plr[0].InvList[plr[v1]._pNumInv++] + v1 * 21720, &plr[v1].HoldItem, 0x170u); + plr[v1].InvGrid[30] = plr[v1]._pNumInv; + CalcPlrItemVals(player_numa, 0); +} + +//----- (004200F8) -------------------------------------------------------- +unsigned char __fastcall ItemSpaceOk(int i, int j) +{ + int v2; // eax + int v3; // esi + char v4; // cl + int v5; // ecx + char v6; // cl + bool v7; // sf + char v8; // cl + char v9; // al + + if ( i < 0 ) + return 0; + if ( i >= 112 ) + return 0; + if ( j < 0 ) + return 0; + if ( j >= 112 ) + return 0; + v2 = i; + v3 = 112 * i + j; + if ( dMonster[0][v3] || dPlayer[v2][j] || dItem[v2][j] ) + return 0; + v4 = dObject[v2][j]; + if ( v4 ) + { + v5 = v4 <= 0 ? -1 - v4 : v4 - 1; + if ( object[v5]._oSolidFlag ) + return 0; + } + v6 = dObject[v2 + 1][j + 1]; + v7 = v6 < 0; + if ( v6 > 0 ) + { + if ( _LOBYTE(objectavail[30 * v6 + 113]) ) + return 0; + v7 = v6 < 0; + } + if ( !v7 || !_LOBYTE(object[-(v6 + 1)]._oSelFlag) ) + { + v8 = dObject[v2 + 1][j]; + if ( v8 <= 0 ) + return nSolidTable[dPiece[0][v3]] == 0; + v9 = dObject[v2][j + 1]; + if ( v9 <= 0 || !_LOBYTE(objectavail[30 * v8 + 113]) || !_LOBYTE(objectavail[30 * v9 + 113]) ) + return nSolidTable[dPiece[0][v3]] == 0; + } + return 0; +} + +//----- (004201F2) -------------------------------------------------------- +unsigned char __fastcall GetItemSpace(int x, int y, char inum) +{ + int v3; // eax + int v4; // edx + char (*v5)[3]; // edi + int v6; // ebx + char (*v7)[3]; // esi + int v8; // eax + signed int v9; // esi + char (*v10)[3]; // eax + int v11; // ecx + int v12; // eax + int v14; // ecx + int v15; // edx + int v16; // eax + int v17; // esi + int v18; // ecx + int v19; // [esp+8h] [ebp-Ch] + int v20; // [esp+Ch] [ebp-8h] + char (*v21)[3]; // [esp+10h] [ebp-4h] + + v3 = y; + v19 = y; + v4 = y - 1; + v20 = x; + v5 = itemhold; + if ( v4 <= v19 + 1 ) + { + v21 = itemhold; + do + { + v6 = x - 1; + if ( (unsigned char)(__OFSUB__(x - 1, x + 1) ^ 1) | (x - 1 == x + 1) ) + { + v7 = v21; + do + { + _LOBYTE(v8) = ItemSpaceOk(v6, v4); + *(_DWORD *)v7 = v8; + v7 += 4; + ++v6; + } + while ( v6 <= v20 + 1 ); + v3 = v19; + x = v20; + } + v21 = (char (*)[3])((char *)v21 + 4); + ++v4; + } + while ( v4 <= v3 + 1 ); + } + v9 = 0; + do + { + v10 = v5; + v11 = 3; + do + { + if ( *(_DWORD *)v10 ) + v9 = 1; + v10 += 4; + --v11; + } + while ( v11 ); + v5 = (char (*)[3])((char *)v5 + 4); + } + while ( (signed int)v5 < (signed int)byte_641234 ); + _LOBYTE(v11) = 13; + v12 = random(v11, 15) + 1; + if ( !v9 ) + return 0; + v14 = 0; + v15 = 0; + if ( v12 > 0 ) + { + while ( 1 ) + { + if ( *(_DWORD *)&itemhold[0][4 * (v15 + 2 * v14 + v14)] ) + --v12; + if ( v12 <= 0 ) + break; + if ( ++v14 == 3 ) + { + v14 = 0; + if ( ++v15 == 3 ) + v15 = 0; + } + } + } + v16 = v14 + v20 - 1; + v17 = v15 + v19 - 1; + v18 = inum; + items[v18]._ix = v16; + dItem[v16][v17] = inum + 1; + items[v18]._iy = v17; + return 1; +} + +//----- (004202E8) -------------------------------------------------------- +void __fastcall GetSuperItemSpace(int x, int y, char inum) +{ + int v3; // eax + signed int v4; // edi + signed int v5; // ebx + int v6; // edx + int v7; // esi + int v8; // eax + int v9; // eax + int v10; // [esp+Ch] [ebp-10h] + int v11; // [esp+10h] [ebp-Ch] + signed int v12; // [esp+14h] [ebp-8h] + signed int v13; // [esp+18h] [ebp-4h] + + v11 = y; + v10 = x; + _LOBYTE(v3) = GetItemSpace(x, y, inum); + if ( !v3 ) + { + v13 = 2; + v4 = -2; + do + { + v5 = v4; + if ( v4 <= v13 ) + { + while ( 2 ) + { + v12 = v4; + v6 = v5 + v11; + v7 = v4 + v10; + do + { + _LOBYTE(v8) = ItemSpaceOk(v7, v6); + if ( v8 ) + { + v9 = inum; + items[v9]._ix = v7; + items[v9]._iy = v6; + dItem[v7][v6] = inum + 1; + return; + } + ++v12; + ++v7; + } + while ( v12 <= v13 ); + if ( ++v5 <= v13 ) + continue; + break; + } + } + ++v13; + --v4; + } + while ( v4 > -50 ); + } +} + +//----- (00420376) -------------------------------------------------------- +void __fastcall GetSuperItemLoc(int x, int y, int *xx, int *yy) +{ + signed int v4; // edi + signed int v5; // ebx + int v6; // esi + int v7; // eax + int v8; // [esp+Ch] [ebp-10h] + int v9; // [esp+10h] [ebp-Ch] + signed int v10; // [esp+14h] [ebp-8h] + signed int v11; // [esp+18h] [ebp-4h] + + v9 = y; + v8 = x; + v11 = 1; + v4 = -1; + while ( 1 ) + { + v5 = v4; + if ( v4 <= v11 ) + break; +LABEL_7: + ++v11; + if ( --v4 <= -50 ) + return; + } +LABEL_3: + v10 = v4; + *yy = v5 + v9; + v6 = v4 + v8; + while ( 1 ) + { + *xx = v6; + _LOBYTE(v7) = ItemSpaceOk(v6, *yy); + if ( v7 ) + break; + ++v10; + ++v6; + if ( v10 > v11 ) + { + if ( ++v5 <= v11 ) + goto LABEL_3; + goto LABEL_7; + } + } +} + +//----- (004203E0) -------------------------------------------------------- +void __fastcall CalcItemValue(int i) +{ + int v1; // ecx + int v2; // esi + bool v3; // sf + int v4; // esi + + v1 = i; + v2 = items[v1]._iVMult1 + items[v1]._iVMult2; + v3 = v2 < 0; + if ( v2 > 0 ) + { + v2 *= items[v1]._ivalue; + v3 = v2 < 0; + } + if ( v3 ) + v2 = items[v1]._ivalue / v2; + v4 = items[v1]._iVAdd1 + items[v1]._iVAdd2 + v2; + if ( v4 <= 0 ) + v4 = 1; + items[v1]._iIvalue = v4; +} + +//----- (0042042C) -------------------------------------------------------- +void __fastcall GetBookSpell(int i, int lvl) +{ + int v2; // edi + int v3; // esi + int v4; // eax + int v5; // edx + signed int v6; // ecx + int v7; // esi + const char **v8; // ebx + int v9; // eax + char v10; // al + int v11; // [esp+8h] [ebp-4h] + + v2 = lvl; + v3 = i; + if ( !lvl ) + v2 = lvl + 1; + _LOBYTE(i) = 14; + v4 = random(i, 37) + 1; +LABEL_13: + v6 = 1; + while ( v4 > 0 ) + { + v5 = spelldata[v6].sBookLvl; + if ( v5 != -1 && v2 >= v5 ) + { + --v4; + v11 = v6; + } + ++v6; + if ( gbMaxPlayers == 1 ) + { + if ( v6 == 32 ) + v6 = 33; + if ( v6 == 34 ) + v6 = 35; + } + if ( v6 == 37 ) + goto LABEL_13; + } + v7 = v3; + v8 = (const char **)&spelldata[v11].sNameText; + strcat(items[v7]._iName, *v8); + strcat(items[v7]._iIName, *v8); + items[v7]._iSpell = v11; + items[v7]._iMinMag = spelldata[v11].sMinInt; + v9 = spelldata[v11].sBookCost; + items[v7]._ivalue += v9; + items[v7]._iIvalue += v9; + v10 = spelldata[v11].sType; + if ( v10 == STYPE_FIRE ) + items[v7]._iCurs = 87; + if ( v10 == 1 ) + items[v7]._iCurs = 88; + if ( v10 == 2 ) + items[v7]._iCurs = 86; +} +// 679660: using guessed type char gbMaxPlayers; + +//----- (00420514) -------------------------------------------------------- +void __fastcall GetStaffPower(int i, int lvl, int bs, unsigned char onlygood) +{ + int v4; // esi + int v5; // ebx + int v6; // edx + int v7; // ecx + int *v8; // eax + int v9; // edi + int v10; // ecx + int v11; // ST14_4 + int v12; // esi + char *v13; // edi + int v14[256]; // [esp+Ch] [ebp-484h] + char v15[128]; // [esp+40Ch] [ebp-84h] + int ia; // [esp+48Ch] [ebp-4h] + char *v17; // [esp+49Ch] [ebp+Ch] + + v4 = lvl; + ia = i; + _LOBYTE(i) = 15; + v5 = -1; + if ( !random(i, 10) || onlygood ) + { + v6 = 0; + v7 = 0; + if ( *(_DWORD *)&PL_Prefix[0].PLPower != -1 ) + { + v8 = &PL_Prefix[0].PLMinLvl; + do + { + if ( *((_BYTE *)v8 + 5) & 1 && *(char *)v8 <= v4 && (!onlygood || v8[4]) ) + { + v14[v6++] = v7; + if ( v8[3] ) + v14[v6++] = v7; + } + v8 += 12; + ++v7; + } + while ( *(v8 - 3) != -1 ); + if ( v6 ) + { + _LOBYTE(v7) = 16; + v5 = v14[random(v7, v6)]; + v9 = ia; + v17 = items[ia]._iIName; + sprintf(v15, "%s %s", PL_Prefix[v5].PLName, items[ia]._iIName); + strcpy(v17, v15); + v10 = ia; + v11 = PL_Prefix[v5].PLMultVal; + items[v9]._iMagical = 1; + SaveItemPower( + v10, + *(_DWORD *)&PL_Prefix[v5].PLPower, + PL_Prefix[v5].PLParam1, + PL_Prefix[v5].PLParam2, + PL_Prefix[v5].PLMinVal, + PL_Prefix[v5].PLMaxVal, + v11); + items[v9]._iPrePower = PL_Prefix[v5].PLPower; + } + } + } + v12 = ia; + v13 = items[ia]._iIName; + if ( !control_WriteStringToBuffer(items[ia]._iIName) ) + { + strcpy(v13, AllItemsList[items[v12].IDidx].iSName); + if ( v5 != -1 ) + { + sprintf(v15, "%s %s", PL_Prefix[v5].PLName, v13); + strcpy(v13, v15); + } + sprintf(v15, "%s of %s", v13, spelldata[bs].sNameText); + strcpy(v13, v15); + if ( !items[v12]._iMagical ) + strcpy(items[v12]._iName, v13); + } + CalcItemValue(ia); +} +// 420514: using guessed type int var_484[256]; + +//----- (004206E5) -------------------------------------------------------- +void __fastcall GetStaffSpell(int i, int lvl, unsigned char onlygood) +{ + int v3; // esi + int v4; // ecx + signed int v5; // esi + int v6; // eax + int v7; // edx + int v8; // ecx + int v9; // edi + int v10; // esi + char *v11; // ebx + int v12; // ebx + int v13; // edx + int v14; // ecx + int v15; // eax + int v16; // ecx + int v17; // eax + int v18; // edx + int v19; // ecx + int v20; // ST08_4 + char v21[64]; // [esp+4h] [ebp-4Ch] + int lvla; // [esp+44h] [ebp-Ch] + int ia; // [esp+48h] [ebp-8h] + int bs; // [esp+4Ch] [ebp-4h] + + v3 = lvl; + ia = i; + _LOBYTE(i) = 17; + lvla = lvl; + if ( random(i, 4) ) + { + v5 = v3 >> 1; + if ( !v5 ) + v5 = 1; + _LOBYTE(v4) = 18; + v6 = random(v4, 37) + 1; +LABEL_15: + v8 = 1; + while ( v6 > 0 ) + { + v7 = spelldata[v8].sStaffLvl; + if ( v7 != -1 && v5 >= v7 ) + { + --v6; + bs = v8; + } + ++v8; + if ( gbMaxPlayers == 1 ) + { + if ( v8 == 32 ) + v8 = 33; + if ( v8 == 34 ) + v8 = 35; + } + if ( v8 == 37 ) + goto LABEL_15; + } + v9 = bs; + v10 = ia; + v11 = items[ia]._iName; + sprintf(v21, "%s of %s", items[ia]._iName, spelldata[bs].sNameText); + if ( !control_WriteStringToBuffer(v21) ) + sprintf(v21, "Staff of %s", spelldata[v9].sNameText); + strcpy(v11, v21); + strcpy(items[v10]._iIName, v21); + v12 = spelldata[v9].sStaffMin; + v13 = spelldata[v9].sStaffMax - v12 + 1; + _LOBYTE(v14) = 19; + items[v10]._iSpell = bs; + v15 = random(v14, v13); + v16 = v15 + v12; + items[v10]._iMinMag = spelldata[v9].sMinInt; + v17 = (v15 + v12) * spelldata[v9].sStaffCost; + items[v10]._iCharges = v16; + items[v10]._iMaxCharges = v16; + v17 /= 5; + v18 = lvla; + v19 = ia; + v20 = bs; + items[v10]._ivalue += v17; + items[v10]._iIvalue += v17; + GetStaffPower(v19, v18, v20, onlygood); + } + else + { + GetItemPower(ia, v3 >> 1, v3, 256, onlygood); + } +} +// 679660: using guessed type char gbMaxPlayers; + +//----- (0042084A) -------------------------------------------------------- +void __fastcall GetItemAttrs(int i, int idata, int lvl) +{ + int v3; // ST20_4 + int v4; // edi + const char **v5; // ebx + int v6; // esi + const char *v7; // ST0C_4 + int v8; // edx + int v9; // edx + int v10; // ecx + int v11; // eax + int v12; // ecx + int v13; // eax + int v14; // eax + int v15; // eax + int v16; // eax + int v17; // eax + int ia; // [esp+Ch] [ebp-8h] + + v3 = idata; + v4 = idata; + v5 = (const char **)&AllItemsList[idata].iName; + ia = i; + v6 = i; + v7 = *v5; + items[v6]._itype = (char)AllItemsList[idata].itype; + items[v6]._iCurs = AllItemsList[idata].iCurs; + strcpy(items[i]._iName, v7); + strcpy(items[v6]._iIName, *v5); + v8 = AllItemsList[v4].iMaxAC; + items[v6]._iLoc = AllItemsList[v4].iLoc; + items[v6]._iClass = AllItemsList[v4].iClass; + v9 = v8 - AllItemsList[v4].iMinAC; + items[v6]._iMinDam = AllItemsList[v4].iMinDam; + _LOBYTE(v10) = 20; + items[v6]._iMaxDam = AllItemsList[v4].iMaxDam; + v11 = AllItemsList[v4].iMinAC + random(v10, v9 + 1); + v12 = AllItemsList[v4].iMiscId; + items[v6]._iMiscId = v12; + items[v6]._iAC = v11; + items[v6]._iFlags = AllItemsList[v4].iFlags; + items[v6]._iSpell = AllItemsList[v4].iSpell; + v13 = AllItemsList[v4].iValue; + items[v6]._ivalue = v13; + items[v6]._iIvalue = v13; + v14 = AllItemsList[v4].iDurability; + items[v6]._iMagical = 0; + items[v6]._iDurability = v14; + items[v6]._iMaxDur = v14; + _LOBYTE(v14) = AllItemsList[v4].iMinStr; + items[v6]._iVAdd1 = 0; + items[v6]._iMinStr = v14; + items[v6]._iMinMag = AllItemsList[v4].iMinMag; + items[v6]._iMinDex = AllItemsList[v4].iMinDex; + items[v6]._iVMult1 = 0; + items[v6]._iVAdd2 = 0; + items[v6]._iVMult2 = 0; + items[v6]._iPLDam = 0; + items[v6]._iPLToHit = 0; + items[v6]._iPLAC = 0; + items[v6]._iPLStr = 0; + items[v6]._iPLMag = 0; + items[v6]._iPLDex = 0; + items[v6]._iPLVit = 0; + items[v6]._iCharges = 0; + items[v6]._iMaxCharges = 0; + items[v6]._iPLFR = 0; + items[v6]._iPLLR = 0; + items[v6]._iPLMR = 0; + items[v6].IDidx = v3; + items[v6]._iPLDamMod = 0; + items[v6]._iPLGetHit = 0; + items[v6]._iPLLight = 0; + items[v6]._iSplLvlAdd = 0; + items[v6]._iPrePower = -1; + items[v6]._iSufPower = -1; + items[v6]._iRequest = 0; + items[v6]._iFMinDam = 0; + items[v6]._iFMaxDam = 0; + items[v6]._iLMinDam = 0; + items[v6]._iLMaxDam = 0; + items[v6]._iPLEnAc = 0; + items[v6]._iPLMana = 0; + items[v6]._iPLHP = 0; + if ( v12 == 24 ) + GetBookSpell(ia, lvl); + if ( items[v6]._itype == ITYPE_GOLD ) + { + if ( gnDifficulty ) + { + v16 = lvl; + } + else + { + _LOBYTE(v12) = 21; + v15 = random(v12, 10 * currlevel); + v12 = 5 * currlevel; + v16 = v12 + v15; + } + if ( gnDifficulty == DIFF_NIGHTMARE ) + { + _LOBYTE(v12) = 21; + v17 = random(v12, 10 * (currlevel + 16)); + v12 = 5 * (currlevel + 16); + v16 = v12 + v17; + } + if ( gnDifficulty == DIFF_HELL ) + { + _LOBYTE(v12) = 21; + v16 = 5 * (currlevel + 32) + random(v12, 10 * (currlevel + 32)); + } + if ( leveltype == 4 ) + v16 += v16 >> 3; + if ( v16 > 5000 ) + v16 = 5000; + items[v6]._ivalue = v16; + if ( v16 < 2500 ) + items[v6]._iCurs = (v16 > 1000) + 4; + else + items[v6]._iCurs = 6; + } +} +// 5BB1ED: using guessed type char leveltype; + +//----- (00420B17) -------------------------------------------------------- +int __fastcall RndPL(int param1, int param2) +{ + int v2; // esi + int v3; // edx + + v2 = param1; + v3 = param2 - param1; + _LOBYTE(param1) = 22; + return v2 + random(param1, v3 + 1); +} + +//----- (00420B28) -------------------------------------------------------- +int __fastcall PLVal(int pv, int p1, int p2, int minv, int maxv) +{ + if ( p1 == p2 ) + return minv; + if ( minv == maxv ) + return minv; + return minv + (maxv - minv) * (100 * (pv - p1) / (p2 - p1)) / 100; +} + +//----- (00420B68) -------------------------------------------------------- +void __fastcall SaveItemPower(int i, int power, int param1, int param2, int minval, int maxval, int multval) +{ + int v7; // edi + int v8; // esi + int v9; // eax + int v10; // ebx + int *v11; // eax + int *v12; // eax + int v13; // edi + int v14; // eax + int v15; // edi + int v16; // eax + int v17; // eax + int v18; // ecx + int v19; // edx + int v20; // edi + int *v21; // edx + int v22; // eax + int v23; // eax + int v24; // eax + int v25; // eax + int v26; // eax + int v27; // eax + int v28; // ecx + int *v29; // eax + int v30; // ecx + int *v31; // eax + int v32; // ecx + int v33; // eax + int v34; // ST18_4 + int v35; // eax + int v36; // ecx + int v37; // edx + signed int v38; // ecx + int v39; // eax + int v40; // eax + int v41; // ecx + int *v42; // eax + int v43; // esi + + v7 = power; + v8 = i; + v9 = RndPL(param1, param2); + v10 = v9; + switch ( v7 ) + { + case IPL_TOHIT: + v11 = &items[v8]._iPLToHit; + goto LABEL_115; + case IPL_TOHIT_CURSE: + v12 = &items[v8]._iPLToHit; + goto LABEL_62; + case IPL_DAMP: + v11 = &items[v8]._iPLDam; + goto LABEL_115; + case IPL_DAMP_CURSE: + v12 = &items[v8]._iPLDam; + goto LABEL_62; + case IPL_TOHIT_DAMP: + v10 = RndPL(param1, param2); + v13 = v8; + items[v13]._iPLDam += v10; + if ( param1 == 20 ) + v14 = RndPL(1, 5); + else + v14 = param1; + if ( param1 == 36 ) + v14 = RndPL(6, 10); + if ( param1 == 51 ) + v14 = RndPL(11, 15); + if ( param1 == 66 ) + v14 = RndPL(16, 20); + if ( param1 == 81 ) + v14 = RndPL(21, 30); + if ( param1 == 96 ) + v14 = RndPL(31, 40); + if ( param1 == 111 ) + v14 = RndPL(41, 50); + if ( param1 == 126 ) + v14 = RndPL(51, 75); + if ( param1 == 151 ) + v14 = RndPL(76, 100); + items[v13]._iPLToHit += v14; + break; + case IPL_TOHIT_DAMP_CURSE: + v15 = v8; + items[v15]._iPLDam -= v9; + if ( param1 == 25 ) + v16 = RndPL(1, 5); + else + v16 = param1; + if ( param1 == 50 ) + v16 = RndPL(6, 10); + items[v15]._iPLToHit -= v16; + break; + case IPL_ACP: + v11 = &items[v8]._iPLAC; + goto LABEL_115; + case IPL_ACP_CURSE: + v12 = &items[v8]._iPLAC; + goto LABEL_62; + case IPL_FIRERES: + v11 = &items[v8]._iPLFR; + goto LABEL_115; + case IPL_LIGHTRES: + v11 = &items[v8]._iPLLR; + goto LABEL_115; + case IPL_MAGICRES: + v11 = &items[v8]._iPLMR; + goto LABEL_115; + case IPL_ALLRES: + v17 = v8; + items[v17]._iPLFR += v10; + v18 = items[v8]._iPLFR; + items[v17]._iPLLR += v10; + items[v17]._iPLMR += v10; + v19 = items[v8]._iPLLR; + v20 = items[v8]._iPLMR; + if ( v18 < 0 ) + items[v17]._iPLFR = 0; + if ( v19 < 0 ) + items[v17]._iPLLR = 0; + if ( v20 < 0 ) + items[v17]._iPLMR = 0; + break; + case IPL_SPLLVLADD: + items[v8]._iSplLvlAdd = v9; + break; + case IPL_CHARGES: + v21 = &items[v8]._iCharges; + v22 = param1 * *v21; + *v21 = v22; + items[v8]._iMaxCharges = v22; + break; + case IPL_FIREDAM: + v24 = v8; + items[v24]._iFlags |= 0x10u; + goto LABEL_77; + case IPL_LIGHTDAM: + v25 = v8; + items[v25]._iFlags |= 0x20u; + goto LABEL_79; + case IPL_STR: + v11 = &items[v8]._iPLStr; + goto LABEL_115; + case IPL_STR_CURSE: + v12 = &items[v8]._iPLStr; + goto LABEL_62; + case IPL_MAG: + v11 = &items[v8]._iPLMag; + goto LABEL_115; + case IPL_MAG_CURSE: + v12 = &items[v8]._iPLMag; + goto LABEL_62; + case IPL_DEX: + v11 = &items[v8]._iPLDex; + goto LABEL_115; + case IPL_DEX_CURSE: + v12 = &items[v8]._iPLDex; + goto LABEL_62; + case IPL_VIT: + v11 = &items[v8]._iPLVit; + goto LABEL_115; + case IPL_VIT_CURSE: + v12 = &items[v8]._iPLVit; + goto LABEL_62; + case IPL_ATTRIBS: + v26 = v8; + items[v26]._iPLStr += v10; + items[v26]._iPLMag += v10; + items[v26]._iPLDex += v10; + items[v26]._iPLVit += v10; + break; + case IPL_ATTRIBS_CURSE: + v27 = v8; + items[v27]._iPLStr -= v10; + items[v27]._iPLMag -= v10; + items[v27]._iPLDex -= v10; + items[v27]._iPLVit -= v10; + break; + case IPL_GETHIT: + v11 = &items[v8]._iPLGetHit; + goto LABEL_115; + case IPL_GETHIT_CURSE: + v12 = &items[v8]._iPLGetHit; + goto LABEL_62; + case IPL_LIFE: + v28 = v9 << 6; + v29 = &items[v8]._iPLHP; + goto LABEL_73; + case IPL_LIFE_CURSE: + v30 = v9 << 6; + v31 = &items[v8]._iPLHP; + goto LABEL_75; + case IPL_MANA: + items[v8]._iPLMana += v9 << 6; + goto LABEL_92; + case IPL_MANA_CURSE: + items[v8]._iPLMana -= v9 << 6; + goto LABEL_92; + case IPL_DUR: + v32 = v8; + v33 = items[v8]._iMaxDur; + v34 = v33; + v35 = v10 * v33 / 100; + items[v32]._iDurability += v35; + items[v32]._iMaxDur = v35 + v34; + break; + case IPL_DUR_CURSE: + v36 = v8; + v37 = items[v8]._iMaxDur - v9 * items[v8]._iMaxDur / 100; + items[v8]._iMaxDur = v37; + if ( v37 < 1 ) + items[v36]._iMaxDur = 1; + items[v36]._iDurability = items[v36]._iMaxDur; + break; + case IPL_INDESTRUCTIBLE: + v38 = 255; + goto LABEL_119; + case IPL_LIGHT: + v28 = param1; + v29 = &items[v8]._iPLLight; +LABEL_73: + *v29 += v28; + break; + case IPL_LIGHT_CURSE: + v30 = param1; + v31 = &items[v8]._iPLLight; +LABEL_75: + *v31 -= v30; + break; + case IPL_FIRE_ARROWS: + v24 = v8; + items[v24]._iFlags |= 8u; +LABEL_77: + items[v24]._iFMinDam = param1; + items[v24]._iFMaxDam = param2; + break; + case IPL_LIGHT_ARROWS: + v25 = v8; + _HIBYTE(items[v8]._iFlags) |= 2u; +LABEL_79: + items[v25]._iLMinDam = param1; + items[v25]._iLMaxDam = param2; + break; + case IPL_INVCURS: + items[v8]._iCurs = param1; + break; + case IPL_THORNS: + _HIBYTE(items[v8]._iFlags) |= 4u; + break; + case IPL_NOMANA: + _HIBYTE(items[v8]._iFlags) |= 8u; + goto LABEL_92; + case IPL_NOHEALPLR: + BYTE1(items[v8]._iFlags) |= 1u; + break; + case IPL_ABSHALFTRAP: + _HIBYTE(items[v8]._iFlags) |= 0x10u; + break; + case IPL_KNOCKBACK: + BYTE1(items[v8]._iFlags) |= 8u; + break; + case IPL_NOHEALMON: + BYTE1(items[v8]._iFlags) |= 0x10u; + break; + case IPL_STEALMANA: + if ( param1 == 3 ) + BYTE1(items[v8]._iFlags) |= 0x20u; + if ( param1 == 5 ) + BYTE1(items[v8]._iFlags) |= 0x40u; +LABEL_92: + drawmanaflag = 1; + break; + case IPL_STEALLIFE: + if ( param1 == 3 ) + BYTE1(items[v8]._iFlags) |= 0x80u; + if ( param1 == 5 ) + BYTE2(items[v8]._iFlags) |= 1u; + drawhpflag = 1; + break; + case IPL_TARGAC: + v11 = &items[v8]._iPLEnAc; + goto LABEL_115; + case IPL_FASTATTACK: + if ( param1 == 1 ) + BYTE2(items[v8]._iFlags) |= 2u; + if ( param1 == 2 ) + BYTE2(items[v8]._iFlags) |= 4u; + if ( param1 == 3 ) + BYTE2(items[v8]._iFlags) |= 8u; + if ( param1 == 4 ) + BYTE2(items[v8]._iFlags) |= 0x10u; + break; + case IPL_FASTRECOVER: + if ( param1 == 1 ) + BYTE2(items[v8]._iFlags) |= 0x20u; + if ( param1 == 2 ) + BYTE2(items[v8]._iFlags) |= 0x40u; + if ( param1 == 3 ) + BYTE2(items[v8]._iFlags) |= 0x80u; + break; + case IPL_FASTBLOCK: + _HIBYTE(items[v8]._iFlags) |= 1u; + break; + case IPL_DAMMOD: + v11 = &items[v8]._iPLDamMod; +LABEL_115: + *v11 += v10; + break; + case IPL_RNDARROWVEL: + items[v8]._iFlags |= 4u; + break; + case IPL_SETDAM: + v39 = v8; + items[v39]._iMinDam = param1; + items[v39]._iMaxDam = param2; + break; + case IPL_SETDUR: + v38 = param1; +LABEL_119: + v40 = v8; + items[v40]._iDurability = v38; + items[v40]._iMaxDur = v38; + break; + case IPL_NOMINSTR: + items[v8]._iMinStr = 0; + break; + case IPL_SPELL: + v23 = v8; + items[v23]._iSpell = param1; + items[v23]._iCharges = param1; + items[v23]._iMaxCharges = param2; + break; + case IPL_FASTSWING: + BYTE2(items[v8]._iFlags) |= 8u; + break; + case IPL_ONEHAND: + items[v8]._iLoc = ILOC_ONEHAND; + break; + case IPL_3XDAMVDEM: + _HIBYTE(items[v8]._iFlags) |= 0x40u; + break; + case IPL_ALLRESZERO: + _HIBYTE(items[v8]._iFlags) |= 0x80u; + break; + case IPL_DRAINLIFE: + items[v8]._iFlags |= 0x40u; + break; + case IPL_RNDSTEALLIFE: + items[v8]._iFlags |= 2u; + break; + case IPL_INFRAVISION: + items[v8]._iFlags |= 1u; + break; + case IPL_SETAC: + items[v8]._iAC = v9; + break; + case IPL_ADDACLIFE: + items[v8]._iPLHP = (plr[myplr]._pIBonusAC + plr[myplr]._pIAC + plr[myplr]._pDexterity / 5) << 6; + break; + case IPL_ADDMANAAC: + items[v8]._iAC += (plr[myplr]._pMaxManaBase >> 6) / 10; + break; + case IPL_FIRERESCLVL: + v41 = 30 - plr[myplr]._pLevel; + v42 = &items[v8]._iPLFR; + *v42 = v41; + if ( v41 < 0 ) + *v42 = 0; + break; + case IPL_AC_CURSE: + v12 = &items[v8]._iAC; +LABEL_62: + *v12 -= v10; + break; + default: + break; + } + v43 = v8; + if ( items[v43]._iVAdd1 || items[v43]._iVMult1 ) + { + items[v43]._iVAdd2 = PLVal(v10, param1, param2, minval, maxval); + items[v43]._iVMult2 = multval; + } + else + { + items[v43]._iVAdd1 = PLVal(v10, param1, param2, minval, maxval); + items[v43]._iVMult1 = multval; + } +} + +//----- (004215EF) -------------------------------------------------------- +void __fastcall GetItemPower(int i, int minlvl, int maxlvl, __int32 flgs, int onlygood) +{ + int v5; // eax + int v6; // ecx + int v7; // esi + int v8; // eax + int v9; // ecx + unsigned char v10; // bl + int v11; // edx + int v12; // edi + int *v13; // eax + __int32 v14; // ecx + int v15; // eax + int v16; // edi + char *v17; // ebx + int v18; // esi + int v19; // ecx + int v20; // ST14_4 + int v21; // edi + int v22; // esi + int *v23; // eax + __int32 v24; // ecx + int v25; // eax + int v26; // edi + int v27; // esi + char *v28; // ebx + int v29; // ecx + int v30; // ST14_4 + int v31; // esi + char *v32; // edi + int v33; // ebx + int v34; // esi + int v35[256]; // [esp+4h] [ebp-494h] + char v36[128]; // [esp+404h] [ebp-94h] + int v37; // [esp+484h] [ebp-14h] + int v38; // [esp+488h] [ebp-10h] + int v39; // [esp+48Ch] [ebp-Ch] + int v40; // [esp+490h] [ebp-8h] + int ia; // [esp+494h] [ebp-4h] + + v37 = minlvl; + ia = i; + _LOBYTE(i) = 23; + v5 = random(i, 4); + _LOBYTE(v6) = 23; + v7 = v5; + v8 = random(v6, 3); + v38 = v8; + if ( v7 && !v8 ) + { + _LOBYTE(v9) = 23; + if ( random(v9, 2) ) + v38 = 1; + else + v7 = 0; + } + v40 = -1; + v39 = -1; + v10 = 0; + if ( !onlygood ) + { + _LOBYTE(v9) = 0; + if ( random(v9, 3) ) + onlygood = 1; + } + if ( !v7 ) + { + v11 = 0; + if ( *(_DWORD *)&PL_Prefix[0].PLPower != -1 ) + { + v12 = *(_DWORD *)&PL_Prefix[0].PLPower; + v13 = &PL_Prefix[0].PLMinLvl; + do + { + v14 = flgs; + if ( flgs & v13[1] ) + { + v14 = *(char *)v13; + if ( v14 >= v37 && v14 <= maxlvl && (!onlygood || v13[4]) && (flgs != 256 || v12 != 15) ) + { + v35[v11++] = v7; + if ( v13[3] ) + v35[v11++] = v7; + } + } + v12 = v13[9]; + v13 += 12; + ++v7; + } + while ( v12 != -1 ); + if ( v11 ) + { + _LOBYTE(v14) = 23; + v15 = random(v14, v11); + v16 = ia; + v40 = v35[v15]; + v17 = items[ia]._iIName; + v18 = v40; + sprintf(v36, "%s %s", PL_Prefix[v40].PLName, items[ia]._iIName); + strcpy(v17, v36); + v19 = ia; + v20 = PL_Prefix[v18].PLMultVal; + items[v16]._iMagical = 1; + SaveItemPower( + v19, + *(_DWORD *)&PL_Prefix[v18].PLPower, + PL_Prefix[v18].PLParam1, + PL_Prefix[v18].PLParam2, + PL_Prefix[v18].PLMinVal, + PL_Prefix[v18].PLMaxVal, + v20); + v10 = PL_Prefix[v18].PLGOE; + items[v16]._iPrePower = PL_Prefix[v18].PLPower; + } + } + } + v21 = 0; + if ( v38 ) + { + v22 = 0; + if ( *(_DWORD *)&PL_Suffix[0].PLPower != -1 ) + { + v23 = &PL_Suffix[0].PLMinLvl; + do + { + v24 = flgs; + if ( flgs & v23[1] ) + { + v24 = *(char *)v23; + if ( v24 >= v37 && v24 <= maxlvl && (v10 | *((_BYTE *)v23 + 8)) != 17 && (!onlygood || v23[4]) ) + v35[v22++] = v21; + } + v23 += 12; + ++v21; + } + while ( *(v23 - 3) != -1 ); + if ( v22 ) + { + _LOBYTE(v24) = 23; + v25 = random(v24, v22); + v26 = ia; + v39 = v35[v25]; + v27 = v39; + v28 = items[ia]._iIName; + sprintf(v36, "%s of %s", items[ia]._iIName, PL_Suffix[v39].PLName); + strcpy(v28, v36); + v29 = ia; + v30 = PL_Suffix[v27].PLMultVal; + items[v26]._iMagical = 1; + SaveItemPower( + v29, + *(_DWORD *)&PL_Suffix[v27].PLPower, + PL_Suffix[v27].PLParam1, + PL_Suffix[v27].PLParam2, + PL_Suffix[v27].PLMinVal, + PL_Suffix[v27].PLMaxVal, + v30); + items[v26]._iSufPower = PL_Suffix[v27].PLPower; + } + } + } + v31 = ia; + v32 = items[ia]._iIName; + if ( control_WriteStringToBuffer(items[ia]._iIName) ) + { + v33 = v40; + v34 = v39; + } + else + { + strcpy(v32, AllItemsList[items[v31].IDidx].iSName); + v33 = v40; + if ( v40 != -1 ) + { + sprintf(v36, "%s %s", PL_Prefix[v40].PLName, v32); + strcpy(v32, v36); + } + v34 = v39; + if ( v39 != -1 ) + { + sprintf(v36, "%s of %s", v32, PL_Suffix[v39].PLName); + strcpy(v32, v36); + } + } + if ( v33 != -1 || v34 != -1 ) + CalcItemValue(ia); +} +// 4215EF: using guessed type int var_494[256]; + +//----- (0042191C) -------------------------------------------------------- +void __fastcall GetItemBonus(int i, int idata, int minlvl, int maxlvl, int onlygood) +{ + signed int v5; // edx + + if ( items[i]._iClass != 4 ) + { + v5 = minlvl; + if ( minlvl > 25 ) + v5 = 25; + switch ( items[i]._itype ) + { + case ITYPE_SWORD: + case ITYPE_AXE: + case ITYPE_MACE: + GetItemPower(i, v5, maxlvl, 4096, onlygood); + break; + case ITYPE_BOW: + GetItemPower(i, v5, maxlvl, 16, onlygood); + break; + case ITYPE_SHIELD: + GetItemPower(i, v5, maxlvl, 0x10000, onlygood); + break; + case ITYPE_LARMOR: + case ITYPE_HELM: + case ITYPE_MARMOR: + case ITYPE_HARMOR: + GetItemPower(i, v5, maxlvl, 0x100000, onlygood); + break; + case ITYPE_STAFF: + GetStaffSpell(i, maxlvl, onlygood); + break; + case ITYPE_RING: + case ITYPE_AMULET: + GetItemPower(i, v5, maxlvl, 1, onlygood); + break; + default: + return; + } + } +} + +//----- (004219C1) -------------------------------------------------------- +void __fastcall SetupItem(int i) +{ + int v1; // ecx + int v2; // esi + int v3; // eax + int v4; // edx + int v5; // eax + bool v6; // zf + + v1 = i; + v2 = myplr; + v3 = ItemCAnimTbl[items[v1]._iCurs]; + items[v1]._iAnimWidth = 96; + items[v1]._iAnimXOff = 16; + v4 = Item2Frm[v3]; + v5 = ItemAnimLs[v3]; + items[v1].ItemFrame = v4; + v6 = plr[v2].pLvlLoad == 0; + items[v1]._iAnimLen = v5; + items[v1]._iIdentified = 0; + items[v1]._iPostDraw = 0; + if ( v6 ) + { + items[v1]._iSelFlag = 0; + v5 = 1; + items[v1]._iAnimFlag = 1; + } + else + { + items[v1]._iAnimFlag = 0; + items[v1]._iSelFlag = 1; + } + items[v1]._iAnimFrame = v5; +} + +//----- (00421A4B) -------------------------------------------------------- +int __fastcall RndItem(int monster_num) +{ + int v1; // edi + int v3; // ecx + int v4; // ecx + int v5; // esi + int v6; // edx + int *v7; // eax + int v8; // ecx + int v9[512]; // [esp+4h] [ebp-800h] + + v1 = monster_num; + _LOWORD(monster_num) = monster[monster_num].MData->mTreasure; + if ( (monster_num & 0x8000) != 0 ) + return -1 - (monster_num & 0xFFF); + if ( monster_num & 0x4000 ) + return 0; + _LOBYTE(monster_num) = 24; + if ( random(monster_num, 100) > 40 ) + return 0; + _LOBYTE(v3) = 24; + if ( random(v3, 100) > 25 ) + return 1; + v5 = 0; + v6 = 0; + if ( AllItemsList[0].iLoc != ILOC_INVALID ) + { + v7 = &AllItemsList[0].iMinMLvl; + do + { + v8 = *(v7 - 6); + if ( v8 == 2 && SLOBYTE(monster[v1].mLevel) >= *(_BYTE *)v7 ) + v9[v5++] = v6; + if ( v8 && SLOBYTE(monster[v1].mLevel) >= *(_BYTE *)v7 ) + v9[v5++] = v6; + v4 = v7[9]; + if ( v4 == 32 && gbMaxPlayers == 1 ) + --v5; + if ( v4 == 34 && gbMaxPlayers == 1 ) + --v5; + v7 += 19; + ++v6; + } + while ( *((_BYTE *)v7 - 19) != -1 ); + } + _LOBYTE(v4) = 24; + return v9[random(v4, v5)] + 1; +} +// 679660: using guessed type char gbMaxPlayers; +// 421A4B: using guessed type int var_800[512]; + +//----- (00421B32) -------------------------------------------------------- +int __fastcall RndUItem(int m) +{ + short v1; // dx + int v3; // edx + int v4; // ebp + unsigned char *v5; // esi + signed int v6; // edi + char v7; // al + bool v8; // sf + unsigned char v9; // of + int v10; // ebx + int v11; // eax + unsigned char v12; // bl + int v13; // ebx + int v14[512]; // [esp+0h] [ebp-800h] + + if ( m != -1 ) + { + v1 = monster[m].MData->mTreasure; + if ( v1 < 0 && gbMaxPlayers == 1 ) + return -1 - (v1 & 0xFFF); + } + v3 = 0; + v4 = 0; + if ( AllItemsList[0].iLoc != -1 ) + { + v5 = &AllItemsList[0].itype; + do + { + v6 = 1; + if ( !*((_DWORD *)v5 - 3) ) + v6 = 0; + if ( m == -1 ) + { + v10 = (char)v5[12]; + v11 = 2 * currlevel; + v9 = __OFSUB__(v11, v10); + v8 = v11 - v10 < 0; + } + else + { + v7 = monster[m].mLevel; + v9 = __OFSUB__(v7, v5[12]); + v8 = (char)(v7 - v5[12]) < 0; + } + if ( v8 ^ v9 ) + v6 = 0; + v12 = *v5; + if ( !*v5 ) + v6 = 0; + if ( v12 == 11 ) + v6 = 0; + if ( v12 == 14 ) + v6 = 0; + if ( *((_DWORD *)v5 + 11) == 24 ) + v6 = 1; + v13 = *((_DWORD *)v5 + 12); + if ( v13 == 32 && gbMaxPlayers == 1 ) + v6 = 0; + if ( v13 == 34 && gbMaxPlayers == 1 ) + v6 = 0; + if ( v6 ) + v14[v3++] = v4; + v5 += 76; + ++v4; + } + while ( *(v5 - 7) != -1 ); + } + _LOBYTE(m) = 25; + return v14[random(m, v3)]; +} +// 679660: using guessed type char gbMaxPlayers; +// 421B32: using guessed type int var_800[512]; + +//----- (00421C2A) -------------------------------------------------------- +int __cdecl RndAllItems() +{ + int v1; // esi + int v2; // edi + char v3; // dl + int *v4; // eax + int v5[512]; // [esp+0h] [ebp-800h] + + if ( random(26, 100) > 25 ) + return 0; + v1 = 0; + v2 = 0; + if ( AllItemsList[0].iLoc != ILOC_INVALID ) + { + v3 = gbMaxPlayers; + v4 = &AllItemsList[0].iSpell; + do + { + if ( *(v4 - 15) && 2 * currlevel >= *((char *)v4 - 36) ) + v5[v1++] = v2; + if ( *v4 == 32 && v3 == 1 ) + --v1; + if ( *v4 == 34 && v3 == 1 ) + --v1; + v4 += 19; + ++v2; + } + while ( *((_BYTE *)v4 - 55) != -1 ); + } + return v5[random(26, v1)]; +} +// 679660: using guessed type char gbMaxPlayers; +// 421C2A: using guessed type int var_800[512]; + +//----- (00421CB7) -------------------------------------------------------- +int __fastcall RndTypeItems(int itype, int imid) +{ + int v2; // edi + int *v3; // eax + signed int v4; // esi + int v6[512]; // [esp+4h] [ebp-80Ch] + int v7; // [esp+804h] [ebp-Ch] + int v8; // [esp+808h] [ebp-8h] + int max; // [esp+80Ch] [ebp-4h] + + max = 0; + v2 = 0; + v7 = itype; + if ( AllItemsList[0].iLoc != ILOC_INVALID ) + { + v8 = 2 * currlevel; + v3 = &AllItemsList[0].iMinMLvl; + do + { + v4 = 1; + if ( !*(v3 - 6) ) + v4 = 0; + if ( v8 < *(char *)v3 ) + v4 = 0; + itype = *((char *)v3 - 12); + if ( itype != v7 ) + v4 = 0; + if ( imid != -1 && v3[8] != imid ) + v4 = 0; + if ( v4 ) + { + itype = max++; + v6[itype] = v2; + } + v3 += 19; + ++v2; + } + while ( *((_BYTE *)v3 - 19) != -1 ); + } + _LOBYTE(itype) = 27; + return v6[random(itype, max)]; +} +// 421CB7: using guessed type int var_80C[512]; + +//----- (00421D41) -------------------------------------------------------- +void __fastcall GetUniqueItem(int i, int uid) +{ + int v2; // esi + int v3; // ebx + char v4; // al + int *v5; // edi + int v6; // ecx + char *v7; // esi + char v8; // dl + char *v9; // ecx + int v10; // eax + char v11[128]; // [esp+8h] [ebp-84h] + int v12; // [esp+88h] [ebp-4h] + int v13; // [esp+94h] [ebp+8h] + int v14; // [esp+98h] [ebp+Ch] + + v12 = uid; + v2 = i; + _LOBYTE(i) = 28; + if ( random(i, 100) <= v13 ) + { + v3 = 0; + memset(v11, 0, 0x80u); + v4 = UniqueItemList[0].UIItemId; + if ( UniqueItemList[0].UIItemId != -1 ) + { + v5 = UniqueItemFlag; + v6 = items[v2].IDidx; + v7 = &UniqueItemList[0].UIItemId; + v8 = AllItemsList[v6].iItemId; + v9 = v11; + do + { + if ( v4 == v8 && v12 >= *((char *)v7 + 1) && (v14 || !*v5 || gbMaxPlayers != 1) ) + { + *v9 = 1; + ++v3; + } + v7 += 84; + ++v5; + ++v9; + v4 = *v7; + } + while ( *v7 != -1 ); + if ( v3 ) + { + _LOBYTE(v9) = 29; + random((int)v9, 10); + v10 = 0; + if ( v3 > 0 ) + { + while ( 1 ) + { + if ( v11[v10] ) + --v3; + if ( v3 <= 0 ) + break; + if ( ++v10 == 128 ) + v10 = 0; + } + } + } + } + } +} +// 679660: using guessed type char gbMaxPlayers; +// 421D41: using guessed type char var_84[128]; + +//----- (00421E11) -------------------------------------------------------- +void __fastcall SpawnUnique(int uid, int x, int y) +{ + int v3; // esi + int v4; // ST04_4 + int v5; // edi + int v6; // edi + bool v7; // zf + int v8; // [esp+10h] [ebp-4h] + + v3 = x; + v8 = x; + v4 = UniqueItemList[x].UIParam2; + UniqueItemFlag[x] = 1; + v5 = uid; + SaveItemPower(uid, (char)UniqueItemList[x].UIPower1, UniqueItemList[x].UIParam1, v4, 0, 0, 1); + if ( UniqueItemList[v3].UINumPL > 1 ) + SaveItemPower( + v5, + (char)UniqueItemList[v3].UIPower2, + UniqueItemList[v3].UIParam3, + UniqueItemList[v3].UIParam4, + 0, + 0, + 1); + if ( UniqueItemList[v3].UINumPL > 2 ) + SaveItemPower( + v5, + (char)UniqueItemList[v3].UIPower3, + UniqueItemList[v3].UIParam5, + UniqueItemList[v3].UIParam6, + 0, + 0, + 1); + if ( UniqueItemList[v3].UINumPL > 3 ) + SaveItemPower( + v5, + (char)UniqueItemList[v3].UIPower4, + UniqueItemList[v3].UIParam7, + UniqueItemList[v3].UIParam8, + 0, + 0, + 1); + if ( UniqueItemList[v3].UINumPL > 4 ) + SaveItemPower( + v5, + (char)UniqueItemList[v3].UIPower5, + UniqueItemList[v3].UIParam9, + UniqueItemList[v3].UIParam10, + 0, + 0, + 1); + if ( UniqueItemList[v3].UINumPL > 5 ) + SaveItemPower( + v5, + (char)UniqueItemList[v3].UIPower6, + UniqueItemList[v3].UIParam11, + UniqueItemList[v3].UIParam12, + 0, + 0, + 1); + v6 = v5; + strcpy(items[v6]._iIName, UniqueItemList[v3].UIName); + v7 = items[v6]._iMiscId == IMISC_UNIQUE; + items[v6]._iIvalue = UniqueItemList[v3].UIValue; + if ( v7 ) + items[v6]._iSeed = v8; + _HIBYTE(items[v6]._iCreateInfo) |= 2u; + items[v6]._iUid = v8; + items[v6]._iMagical = 2; +} + +//----- (00421F5C) -------------------------------------------------------- +int __fastcall CheckUnique(int i, int lvl, int uper, unsigned char recreate) +{ + int v4; // esi + int result; // eax + int v6; // edi + int v7; // esi + int *v8; // ecx + int v9; // edx + char v10; // al + char *v11; // ecx + int v12; // [esp-8h] [ebp-Ch] + int retaddr; // [esp+4h] [ebp+0h] + + result = lvl; + v6 = i; + if ( numitems < 127 ) + { + v12 = v4; + v7 = itemavail[0]; + GetSuperItemSpace(lvl, retaddr, itemavail[0]); + v8 = &itemavail[-numitems + 126]; + v9 = 0; + itemactive[numitems] = v7; + v10 = UniqueItemList[v6].UIItemId; + itemavail[0] = *v8; + if ( AllItemsList[0].iItemId != v10 ) + { + v11 = &AllItemsList[0].iItemId; + do + { + v11 += 76; + ++v9; + } + while ( *v11 != v10 ); + } + GetItemAttrs(v7, v9, currlevel); + SpawnUnique(v7, v6, v12); + SetupItem(v7); + ++numitems; + } + return result; +} +// 421F5C: could not find valid save-restore pair for esi + +//----- (00421FE6) -------------------------------------------------------- +void __fastcall ItemRndDur(int ii) +{ + int v1; // esi + int v2; // eax + + v1 = ii; + v2 = items[ii]._iDurability; + if ( v2 ) + { + if ( v2 != 255 ) + { + _LOBYTE(ii) = 0; + items[v1]._iDurability = random(ii, items[v1]._iMaxDur >> 1) + (items[v1]._iMaxDur >> 2) + 1; + } + } +} + +//----- (00422024) -------------------------------------------------------- +void __fastcall SetupAllItems(int ii, int idx, int iseed, int lvl, int uper, int onlygood, int recreate, int pregen) +{ + int v8; // esi + int v9; // ecx + int v10; // edi + int v11; // ecx + int v12; // eax + int v13; // eax + int v14; // [esp-4h] [ebp-18h] + int idata; // [esp+Ch] [ebp-8h] + int i; // [esp+10h] [ebp-4h] + + i = ii; + v8 = ii; + idata = idx; + items[ii]._iSeed = iseed; + SetRndSeed(iseed); + GetItemAttrs(i, idata, lvl >> 1); + items[v8]._iCreateInfo = lvl; + if ( pregen ) + items[v8]._iCreateInfo = lvl | 0x8000; + if ( onlygood ) + _LOBYTE(items[v8]._iCreateInfo) |= 0x40u; + if ( uper == 15 ) + { + _LOBYTE(items[v8]._iCreateInfo) |= 0x80u; + } + else if ( uper == 1 ) + { + _HIBYTE(items[v8]._iCreateInfo) |= 1u; + } + if ( items[v8]._iMiscId == IMISC_UNIQUE ) + { + if ( items[v8]._iLoc != ILOC_UNEQUIPABLE ) + SpawnUnique(i, iseed, v14); + } + else + { + _LOBYTE(v9) = 32; + v10 = -1; + if ( random(v9, 100) > 10 && (_LOBYTE(v11) = 33, random(v11, 100) > lvl) || (v10 = lvl, lvl == -1) ) + { + v12 = items[v8]._iMiscId; + if ( v12 != IMISC_STAFF || (v10 = lvl, lvl == -1) ) + { + if ( v12 != IMISC_RING || (v10 = lvl, lvl == -1) ) + { + if ( v12 == IMISC_AMULET ) + v10 = lvl; + } + } + } + if ( onlygood ) + v10 = lvl; + if ( uper == 15 ) + v10 = lvl + 4; + if ( v10 != -1 ) + { + GetUniqueItem(i, v10); + if ( v13 == -1 ) + { + GetItemBonus(i, idata, v10 >> 1, v10, onlygood); + } + else + { + SpawnUnique(i, v13, uper); + _HIBYTE(items[v8]._iCreateInfo) |= 2u; + } + } + if ( items[v8]._iMagical != 2 ) + ItemRndDur(i); + } + SetupItem(i); +} + +//----- (0042217A) -------------------------------------------------------- +void __fastcall SpawnItem(int m, int x, int y, unsigned char sendmsg) +{ + int v4; // esi + int v5; // eax + int v6; // edi + int *v7; // ecx + bool v8; // zf + MonsterData *v9; // eax + int v10; // eax + int v11; // ST04_4 + int v12; // eax + int v13; // [esp-10h] [ebp-28h] + unsigned char v14; // [esp+0h] [ebp-18h] + char *v15; // [esp+Ch] [ebp-Ch] + int xa; // [esp+10h] [ebp-8h] + int idx; // [esp+14h] [ebp-4h] + + v4 = m; + xa = x; + if ( !monster[m]._uniqtype && (monster[v4].MData->mTreasure >= 0 || gbMaxPlayers == 1) ) + { + if ( quests[1]._qactive == 2 && quests[1]._qvar1 == 5 ) + { + idx = 18; + quests[1]._qvar1 = 6; + goto LABEL_13; + } + v5 = RndItem(m); + if ( !v5 ) + return; + if ( v5 > 0 ) + { + v15 = 0; + idx = v5 - 1; + goto LABEL_13; + } +LABEL_10: + CheckUnique(-1 - v5, xa, y, v14); + return; + } + v5 = RndUItem(m); + idx = v5; + if ( v5 < 0 ) + goto LABEL_10; + v15 = (char *)1; +LABEL_13: + if ( numitems < 127 ) + { + v6 = itemavail[0]; + GetSuperItemSpace(xa, y, itemavail[0]); + v7 = &itemavail[-numitems + 126]; + v8 = monster[v4]._uniqtype == 0; + itemactive[numitems] = v6; + v9 = monster[v4].MData; + itemavail[0] = *v7; + v10 = (char)v9->mLevel; + if ( v8 ) + v13 = 1; + else + v13 = 15; + v11 = v10; + v12 = GetRndSeed(); + SetupAllItems(v6, idx, v12, v11, v13, (int)v15, 0, 0); + ++numitems; + if ( sendmsg ) + NetSendCmdDItem(0, v6); + } +} +// 679660: using guessed type char gbMaxPlayers; + +//----- (00422290) -------------------------------------------------------- +void __fastcall CreateItem(int uid, int x, int y) +{ + int v3; // esi + int v4; // edi + int v5; // esi + int *v6; // ecx + int v7; // edx + char v8; // al + char *v9; // ecx + int v10; // [esp-8h] [ebp-Ch] + int retaddr; // [esp+4h] [ebp+0h] + + v4 = uid; + if ( numitems < 127 ) + { + v10 = v3; + v5 = itemavail[0]; + GetSuperItemSpace(x, retaddr, itemavail[0]); + v6 = &itemavail[-numitems + 126]; + v7 = 0; + itemactive[numitems] = v5; + v8 = UniqueItemList[v4].UIItemId; + itemavail[0] = *v6; + if ( AllItemsList[0].iItemId != v8 ) + { + v9 = &AllItemsList[0].iItemId; + do + { + v9 += 76; + ++v7; + } + while ( *v9 != v8 ); + } + GetItemAttrs(v5, v7, currlevel); + SpawnUnique(v5, v4, v10); + SetupItem(v5); + ++numitems; + items[v5]._iMagical = 2; + } +} +// 422290: could not find valid save-restore pair for esi + +//----- (0042232B) -------------------------------------------------------- +void __fastcall CreateRndItem(int x, int y, unsigned char onlygood, unsigned char sendmsg, int delta) +{ + int v5; // ebx + int v6; // eax + int v7; // edi + int v8; // esi + int *v9; // ecx + int v10; // ST04_4 + int v11; // eax + int xa; // [esp+8h] [ebp-4h] + + v5 = y; + xa = x; + if ( onlygood ) + v6 = RndUItem(-1); + else + v6 = RndAllItems(); + v7 = v6; + if ( numitems < 127 ) + { + v8 = itemavail[0]; + GetSuperItemSpace(xa, v5, itemavail[0]); + v9 = &itemavail[-numitems + 126]; + itemactive[numitems] = v8; + v10 = 2 * currlevel; + itemavail[0] = *v9; + v11 = GetRndSeed(); + SetupAllItems(v8, v7, v11, v10, 1, onlygood, 0, delta); + if ( sendmsg ) + NetSendCmdDItem(0, v8); + if ( delta ) + DeltaAddItem(v8); + ++numitems; + } +} + +//----- (004223D0) -------------------------------------------------------- +void __fastcall SetupAllUseful(int ii, int iseed, int lvl) +{ + int v3; // ebx + int v4; // edi + int v5; // ecx + int v6; // ecx + int v7; // esi + + v3 = ii; + v4 = ii; + items[ii]._iSeed = iseed; + SetRndSeed(iseed); + _LOBYTE(v5) = 34; + v7 = 25 - (random(v5, 2) != 0); + if ( lvl > 1 ) + { + _LOBYTE(v6) = 34; + if ( !random(v6, 3) ) + v7 = 27; + } + GetItemAttrs(v3, v7, lvl); + items[v4]._iCreateInfo = lvl + 384; + SetupItem(v3); +} + +//----- (0042243D) -------------------------------------------------------- +void __fastcall CreateRndUseful(int pnum, int x, int y, unsigned char sendmsg) +{ + int v4; // esi + int *v5; // ecx + int v6; // ST00_4 + int v7; // eax + + if ( numitems < 127 ) + { + v4 = itemavail[0]; + GetSuperItemSpace(x, y, itemavail[0]); + v5 = &itemavail[-numitems + 126]; + itemactive[numitems] = v4; + v6 = currlevel; + itemavail[0] = *v5; + v7 = GetRndSeed(); + SetupAllUseful(v4, v7, v6); + if ( sendmsg ) + NetSendCmdDItem(0, v4); + ++numitems; + } +} + +//----- (004224A6) -------------------------------------------------------- +void __fastcall CreateTypeItem(int x, int y, unsigned char onlygood, int itype, int imisc, int sendmsg, int delta) +{ + int v7; // ebx + int v8; // edi + int v9; // esi + int *v10; // ecx + int v11; // ST04_4 + int v12; // eax + int xa; // [esp+8h] [ebp-4h] + + xa = x; + v7 = y; + if ( itype == ITYPE_GOLD ) + v8 = 0; + else + v8 = RndTypeItems(itype, imisc); + if ( numitems < 127 ) + { + v9 = itemavail[0]; + GetSuperItemSpace(xa, v7, itemavail[0]); + v10 = &itemavail[-numitems + 126]; + itemactive[numitems] = v9; + v11 = 2 * currlevel; + itemavail[0] = *v10; + v12 = GetRndSeed(); + SetupAllItems(v9, v8, v12, v11, 1, onlygood, 0, delta); + if ( sendmsg ) + NetSendCmdDItem(0, v9); + if ( delta ) + DeltaAddItem(v9); + ++numitems; + } +} + +//----- (0042254A) -------------------------------------------------------- +void __fastcall TempItemGeneration(int ii, int idx, int wCI, int seed, int value) +{ + int v5; // esi + ItemStruct *v6; // edi + ItemStruct *v7; // esi + int v8; // esi + int v9; // edx + int v10; // ebx + int v11; // edi + int idxa; // [esp+8h] [ebp-4h] + + idxa = idx; + if ( idx ) + { + if ( (_WORD)wCI ) + { + if ( wCI & 0x7C00 ) + { + RecreateTownItem(ii, idx, wCI, seed, value); + } + else if ( (wCI & 0x180) == 384 ) + { + SetupAllUseful(ii, seed, wCI & 0x3F); + } + else + { + v8 = 0; + v9 = 0; + v10 = 0; + v11 = 0; + if ( wCI & 0x100 ) + v8 = 1; + if ( (wCI & 0x80u) != 0 ) + v8 = 15; + if ( wCI & 0x40 ) + v9 = 1; + if ( wCI & 0x200 ) + v10 = 1; + if ( (wCI & 0x8000) != 0 ) + v11 = 1; + SetupAllItems(ii, idxa, seed, wCI & 0x3F, v8, v9, v10, v11); + } + } + else + { + v7 = &items[ii]; + SetPlrHandItem(&items[ii], idx); + SetPlrHandSeed(v7, seed); + } + } + else + { + v5 = ii; + v6 = &items[ii]; + SetPlrHandItem(&items[ii], 0); + v6->_iSeed = seed; + items[v5]._iCreateInfo = wCI; + items[v5]._ivalue = value; + if ( value < 2500 ) + { + if ( value > 1000 ) + items[v5]._iCurs = 5; + else + items[v5]._iCurs = 4; + } + else + { + items[v5]._iCurs = 6; + } + } +} + +//----- (0042265C) -------------------------------------------------------- +void __fastcall RecreateEar(int ii, unsigned short ic, int iseed, unsigned char Id, int dur, int mdur, int ch, int mch, int ivalue, int ibuff) +{ + int v10; // esi + short v11; // ST18_2 + ItemStruct *v12; // ebx + + v10 = ii; + v11 = ic; + v12 = &items[ii]; + SetPlrHandItem(&items[ii], 23); + tempstr[16] = 0; + tempstr[0] = _HIBYTE(v11) & 0x7F; + tempstr[1] = v11 & 0x7F; + tempstr[2] = _HIBYTE(iseed) & 0x7F; + tempstr[3] = BYTE2(iseed) & 0x7F; + tempstr[5] = iseed & 0x7F; + tempstr[6] = Id & 0x7F; + tempstr[7] = dur & 0x7F; + tempstr[8] = mdur & 0x7F; + tempstr[9] = ch & 0x7F; + tempstr[10] = mch & 0x7F; + tempstr[11] = BYTE1(ivalue) & 0x7F; + tempstr[4] = BYTE1(iseed) & 0x7F; + tempstr[12] = _HIBYTE(ibuff) & 0x7F; + tempstr[13] = BYTE2(ibuff) & 0x7F; + tempstr[14] = BYTE1(ibuff) & 0x7F; + tempstr[15] = ibuff & 0x7F; + sprintf(items[v10]._iName, "Ear of %s", tempstr); + items[v10]._iCurs = ((ivalue >> 6) & 3) + 19; + items[v10]._iCreateInfo = v11; + items[v10]._ivalue = ivalue & 0x3F; + v12->_iSeed = iseed; +} + +//----- (00422795) -------------------------------------------------------- +void __fastcall SpawnQuestItem(int itemid, int x, int y, int randarea, int selflag) +{ + int v5; // edi + int v6; // eax + int v7; // ecx + int v8; // ebx + BOOL v9; // eax + int v10; // esi + int v11; // eax + int v12; // ebx + int v13; // esi + unsigned int v14; // eax + int v15; // ecx + int idata; // [esp+Ch] [ebp-8h] + int v17; // [esp+10h] [ebp-4h] + + v5 = x; + idata = itemid; + if ( randarea ) + { + v17 = 0; + while ( 1 ) + { +LABEL_3: + if ( ++v17 > 1000 && randarea > 1 ) + --randarea; + _LOBYTE(itemid) = 0; + v6 = random(itemid, 112); + _LOBYTE(v7) = 0; + v5 = v6; + y = random(v7, 112); + v8 = 0; + v9 = 0; + if ( randarea <= 0 ) + break; + while ( !v9 ) + { + v10 = 0; + do + { + if ( v9 ) + break; + _LOBYTE(v11) = ItemSpaceOk(v8 + v5, v10 + y); + v9 = v11 == 0; + ++v10; + } + while ( v10 < randarea ); + if ( ++v8 >= randarea ) + { + if ( v9 ) + goto LABEL_3; + goto LABEL_13; + } + } + } + } +LABEL_13: + if ( numitems < 127 ) + { + v12 = itemavail[0]; + v13 = itemavail[0]; + v14 = 4 * numitems; + items[v13]._ix = v5; + itemactive[v14 / 4] = v12; + v15 = itemavail[v14 / 0xFFFFFFFC + 126]; + items[v13]._iy = y; + itemavail[0] = v15; + dItem[v5][y] = v12 + 1; + GetItemAttrs(v12, idata, currlevel); + SetupItem(v12); + items[v13]._iPostDraw = 1; + if ( selflag ) + { + items[v13]._iAnimFlag = 0; + items[v13]._iSelFlag = selflag; + items[v13]._iAnimFrame = items[v13]._iAnimLen; + } + ++numitems; + } +} + +//----- (004228B1) -------------------------------------------------------- +void __cdecl SpawnRock() +{ + BOOL v0; // edx + int v1; // eax + int v2; // ecx + BOOL v3; // ebx + int v4; // ebx + int v5; // ecx + int v6; // esi + int *v7; // edx + int v8; // eax + int v9; // edi + int v10; // ST04_4 + int v11; // [esp+8h] [ebp-4h] + + v0 = 0; + v1 = 0; + if ( nobjects > 0 ) + { + v2 = v11; + while ( !v0 ) + { + v2 = objectactive[v1]; + v3 = object[objectactive[v1++]]._otype == OBJ_STAND; + v0 = v3; + if ( v1 >= nobjects ) + { + if ( !v3 ) + return; + break; + } + } + v4 = itemavail[0]; + v5 = v2; + v6 = itemavail[0]; + v7 = &itemavail[-numitems + 126]; + itemactive[numitems] = itemavail[0]; + v8 = object[v5]._ox; + items[v6]._ix = v8; + v9 = object[v5]._oy; + itemavail[0] = *v7; + dItem[v8][v9] = v4 + 1; + v10 = currlevel; + items[v6]._iy = v9; + GetItemAttrs(v4, 9, v10); + SetupItem(v4); + ++numitems; + items[v6]._iSelFlag = 2; + items[v6]._iPostDraw = 1; + items[v6]._iAnimFrame = 11; + } +} + +//----- (00422989) -------------------------------------------------------- +void __fastcall RespawnItem(int i, unsigned char FlipFlag) +{ + int v2; // esi + int v3; // edi + int v4; // eax + int v5; // ecx + int v6; // eax + int v7; // ecx + int v8; // ST00_4 + int v9; // edx + int v10; // ecx + int v11; // eax + + v2 = i; + v3 = items[i]._iCurs; + items[v2]._iAnimWidth = 96; + items[v2]._iAnimXOff = 16; + v4 = ItemCAnimTbl[v3]; + v5 = v4; + v6 = ItemAnimLs[v4]; + v7 = v5; + items[v2]._iAnimLen = v6; + items[v2].ItemFrame = Item2Frm[v7]; + items[v2]._iPostDraw = 0; + items[v2]._iRequest = 0; + if ( FlipFlag ) + { + items[v2]._iSelFlag = 0; + v6 = 1; + items[v2]._iAnimFlag = 1; + } + else + { + items[v2]._iAnimFlag = 0; + items[v2]._iSelFlag = 1; + } + items[v2]._iAnimFrame = v6; + if ( v3 == 76 ) + { + v8 = items[v2]._iy; + v9 = items[v2]._ix; + v10 = ItemDropSnds[v7]; + items[v2]._iSelFlag = 1; + PlaySfxLoc(v10, v9, v8); + } + v11 = items[v2]._iCurs; + if ( v11 == 126 ) + items[v2]._iSelFlag = 1; + if ( v11 == 140 ) + items[v2]._iSelFlag = 1; +} + +//----- (00422A50) -------------------------------------------------------- +void __fastcall DeleteItem(int ii, int i) +{ + int v2; // eax + bool v3; // zf + bool v4; // sf + + v2 = numitems - 1; + v3 = numitems == 1; + v4 = numitems - 1 < 0; + itemavail[-numitems + 127] = ii; + numitems = v2; + if ( !v4 && !v3 && i != v2 ) + itemactive[i] = itemactive[v2]; +} + +//----- (00422A84) -------------------------------------------------------- +void __cdecl ItemDoppel() +{ + int v0; // eax + signed int v1; // esi + char *v2; // ecx + ItemStruct *v3; // edx + + if ( gbMaxPlayers != 1 ) + { + v0 = idoppely; + v1 = 16; + v2 = &dItem[16][idoppely]; + do + { + if ( *v2 ) + { + v3 = &item_stru_6358B8 + *v2; + if ( v3->_ix != v1 || v3->_iy != v0 ) + *v2 = 0; + } + ++v1; + v2 += 112; + } + while ( v1 < 96 ); + idoppely = v0 + 1; + if ( v0 == 95 ) + idoppely = 16; + } +} +// 492EAC: using guessed type int idoppely; +// 679660: using guessed type char gbMaxPlayers; + +//----- (00422ADE) -------------------------------------------------------- +void __cdecl ProcessItems() +{ + int i; // edi + int v1; // esi + int v2; // eax + int v3; // ecx + char v4; // al + int v5; // eax + + for ( i = 0; i < numitems; ++i ) + { + v1 = itemactive[i]; + if ( items[v1]._iAnimFlag ) + { + v2 = items[v1]._iCurs; + v3 = ++items[v1]._iAnimFrame; + if ( v2 == 76 ) + { + v4 = items[v1]._iSelFlag; + if ( v4 == 1 && v3 == 11 ) + items[v1]._iAnimFrame = 1; + if ( v4 == 2 && items[v1]._iAnimFrame == 21 ) + items[v1]._iAnimFrame = 11; + } + else + { + if ( v3 == items[v1]._iAnimLen >> 1 ) + PlaySfxLoc(ItemDropSnds[ItemCAnimTbl[v2]], items[v1]._ix, items[v1]._iy); + v5 = items[v1]._iAnimLen; + if ( items[v1]._iAnimFrame >= v5 ) + { + items[v1]._iAnimFlag = 0; + items[v1]._iAnimFrame = v5; + items[v1]._iSelFlag = 1; + } + } + } + } + ItemDoppel(); +} + +//----- (00422BB2) -------------------------------------------------------- +void __cdecl FreeItemGFX() +{ + int *v0; // esi + void *v1; // ecx + + v0 = Item2Frm; + do + { + v1 = (void *)*v0; + *v0 = 0; + mem_free_dbg(v1); + ++v0; + } + while ( (signed int)v0 < (signed int)UniqueItemFlag ); +} + +//----- (00422BCF) -------------------------------------------------------- +void __fastcall items_get_drop_cel(int i) +{ + items[i].ItemFrame = Item2Frm[ItemCAnimTbl[items[i]._iCurs]]; +} + +//----- (00422BF0) -------------------------------------------------------- +void __fastcall GetItemStr(int i) +{ + int v1; // esi + const char *v2; // eax + char v3; // al + int v4; // esi + char *v5; // eax + + v1 = i; + if ( items[i]._itype == ITYPE_GOLD ) + { + v4 = items[v1]._ivalue; + v5 = get_pieces_str(v4); + sprintf(infostr, "%i gold %s", v4, v5); + } + else + { + v2 = items[v1]._iIName; + if ( !items[v1]._iIdentified ) + v2 = items[v1]._iName; + strcpy(infostr, v2); + v3 = items[v1]._iMagical; + if ( v3 == 1 ) + _LOBYTE(infoclr) = 1; + if ( v3 == 2 ) + _LOBYTE(infoclr) = 3; + } +} +// 4B883C: using guessed type int infoclr; + +//----- (00422C63) -------------------------------------------------------- +void __fastcall CheckIdentify(int pnum, int cii) +{ + int v2; // esi + + v2 = pnum; + plr[pnum].InvBody[cii]._iIdentified = 1; + CalcPlrInv(pnum, 1u); + if ( v2 == myplr ) + SetCursor(1); +} + +//----- (00422C9C) -------------------------------------------------------- +void __fastcall DoRepair(int pnum, int cii) +{ + int v2; // ebx + PlayerStruct *v3; // esi + int v4; // edi + + v2 = pnum; + v3 = &plr[pnum]; + v4 = cii; + PlaySfxLoc(IS_REPAIR, v3->WorldX, v3->WorldY); + RepairItem(&v3->InvBody[v4], v3->_pLevel); + CalcPlrInv(v2, 1u); + if ( v2 == myplr ) + SetCursor(1); +} + +//----- (00422CF6) -------------------------------------------------------- +void __fastcall RepairItem(ItemStruct *i, int lvl) +{ + ItemStruct *v2; // esi + int v3; // ebx + int v4; // eax + int v5; // edi + int v6; // ebp + int v7; // eax + bool v8; // zf + signed int v9; // eax + + v2 = i; + v3 = lvl; + v4 = i->_iMaxDur; + if ( i->_iDurability != v4 ) + { + if ( v4 > 0 ) + { + v5 = 0; + v6 = lvl + 9; + while ( 1 ) + { + _LOBYTE(i) = 37; + v5 += v3 + random((int)i, v3); + v7 = v2->_iMaxDur / v6; + if ( v7 < 1 ) + v7 = 1; + v8 = v2->_iMaxDur == v7; + v2->_iMaxDur -= v7; + v9 = v2->_iMaxDur; + if ( v8 ) + break; + i = (ItemStruct *)(v5 + v2->_iDurability); + if ( (signed int)i >= v9 ) + { + v2->_iDurability += v5; + if ( v2->_iDurability > v9 ) + v2->_iDurability = v9; + return; + } + } + } + v2->_itype = -1; + } +} + +//----- (00422D6C) -------------------------------------------------------- +void __fastcall DoRecharge(int pnum, int cii) +{ + int v2; // edi + int v3; // edx + PlayerStruct *v4; // eax + ItemStruct *v5; // esi + int v6; // ecx + int v7; // ecx + int v8; // eax + int v9; // eax + + v2 = pnum; + v3 = cii; + v4 = &plr[pnum]; + v5 = &v4->InvBody[v3]; + if ( v4->InvBody[v3]._itype == ITYPE_STAFF ) + { + v6 = v4->InvBody[v3]._iSpell; + if ( v6 ) + { + v7 = spelldata[v6].sBookLvl; + v8 = v4->_pLevel / v7; + _LOBYTE(v7) = 38; + v9 = random(v7, v8); + RechargeItem(v5, v9 + 1); + CalcPlrInv(v2, 1u); + } + } + if ( v2 == myplr ) + SetCursor(1); +} + +//----- (00422DDD) -------------------------------------------------------- +void __fastcall RechargeItem(ItemStruct *i, int r) +{ + bool v2; // zf + int v3; // esi + int v4; // eax + + if ( i->_iCharges != i->_iMaxCharges ) + { + while ( 1 ) + { + v2 = i->_iMaxCharges-- == 1; + v3 = i->_iMaxCharges; + if ( v2 ) + break; + i->_iCharges += r; + v4 = i->_iCharges; + if ( v4 >= v3 ) + { + if ( v4 > v3 ) + i->_iCharges = v3; + return; + } + } + } +} + +//----- (00422E14) -------------------------------------------------------- +void __fastcall PrintItemOil(char IDidx) +{ + switch ( IDidx ) + { + case IMISC_FULLHEAL: + strcpy(tempstr, "fully recover life"); + goto LABEL_17; + case IMISC_HEAL: + strcpy(tempstr, "recover partial life"); + goto LABEL_17; + case IMISC_OLDHEAL: + strcpy(tempstr, "recover life"); + goto LABEL_17; + case IMISC_DEADHEAL: + strcpy(tempstr, "deadly heal"); + goto LABEL_17; + case IMISC_MANA: + strcpy(tempstr, "recover mana"); + goto LABEL_17; + case IMISC_FULLMANA: + strcpy(tempstr, "fully recover mana"); + goto LABEL_17; + case IMISC_ELIXSTR: + strcpy(tempstr, "increase strength"); + goto LABEL_17; + case IMISC_ELIXMAG: + strcpy(tempstr, "increase magic"); + goto LABEL_17; + case IMISC_ELIXDEX: + strcpy(tempstr, "increase dexterity"); + goto LABEL_17; + case IMISC_ELIXVIT: + strcpy(tempstr, "increase vitality"); + goto LABEL_17; + case IMISC_ELIXWEAK: + case IMISC_ELIXDIS: + strcpy(tempstr, "decrease strength"); + goto LABEL_17; + case IMISC_ELIXCLUM: + strcpy(tempstr, "decrease dexterity"); + goto LABEL_17; + case IMISC_ELIXSICK: + strcpy(tempstr, "decrease vitality"); + goto LABEL_17; + case IMISC_REJUV: + strcpy(tempstr, "recover life and mana"); + goto LABEL_17; + case IMISC_FULLREJUV: + strcpy(tempstr, "fully recover life and mana"); +LABEL_17: + AddPanelString(tempstr, 1); + break; + default: + return; + } +} + +//----- (00422EF4) -------------------------------------------------------- +void __fastcall PrintItemPower(char plidx, ItemStruct *x) +{ + ItemStruct *v2; // esi + int *v3; // esi + int *v4; // esi + int v5; // esi + const char *v6; // [esp-4h] [ebp-Ch] + const char *v7; // [esp-4h] [ebp-Ch] + const char *v8; // [esp-4h] [ebp-Ch] + const char *v9; // [esp-4h] [ebp-Ch] + + v2 = x; + switch ( plidx ) + { + case IPL_TOHIT: + case IPL_TOHIT_CURSE: + sprintf(tempstr, "chance to hit : %+i%%", x->_iPLToHit); + return; + case IPL_DAMP: + case IPL_DAMP_CURSE: + sprintf(tempstr, "%+i%% damage", x->_iPLDam); + return; + case IPL_TOHIT_DAMP: + case IPL_TOHIT_DAMP_CURSE: + sprintf(tempstr, "to hit: %+i%%, %+i%% damage", x->_iPLToHit, x->_iPLDam); + return; + case IPL_ACP: + case IPL_ACP_CURSE: + sprintf(tempstr, "%+i%% armor", x->_iPLAC); + return; + case IPL_FIRERES: + if ( x->_iPLFR < 75 ) + sprintf(tempstr, "Resist Fire : %+i%%", x->_iPLFR); + if ( v2->_iPLFR >= 75 ) + { + v6 = "Resist Fire : 75%% MAX"; + goto LABEL_11; + } + return; + case IPL_LIGHTRES: + if ( x->_iPLLR < 75 ) + sprintf(tempstr, "Resist Lightning : %+i%%", x->_iPLLR); + if ( v2->_iPLLR >= 75 ) + { + v6 = "Resist Lightning : 75%% MAX"; + goto LABEL_11; + } + return; + case IPL_MAGICRES: + if ( x->_iPLMR < 75 ) + sprintf(tempstr, "Resist Magic : %+i%%", x->_iPLMR); + if ( v2->_iPLMR >= 75 ) + { + v6 = "Resist Magic : 75%% MAX"; + goto LABEL_11; + } + return; + case IPL_ALLRES: + if ( x->_iPLFR < 75 ) + sprintf(tempstr, "Resist All : %+i%%", x->_iPLFR); + if ( v2->_iPLFR >= 75 ) + { + v6 = "Resist All : 75%% MAX"; +LABEL_11: + sprintf(tempstr, v6); + } + return; + case IPL_SPLLVLADD: + if ( x->_iSplLvlAdd == 1 ) + strcpy(tempstr, "spells are increased 1 level"); + if ( v2->_iSplLvlAdd == 2 ) + strcpy(tempstr, "spells are increased 2 levels"); + if ( v2->_iSplLvlAdd < 1 ) + { + v7 = "spells are decreased 1 level"; + goto LABEL_81; + } + return; + case IPL_CHARGES: + v8 = "Extra charges"; + goto LABEL_104; + case IPL_FIREDAM: + sprintf(tempstr, "Fire hit damage: %i-%i", x->_iFMinDam, x->_iFMaxDam); + return; + case IPL_LIGHTDAM: + sprintf(tempstr, "Lightning hit damage: %i-%i", x->_iLMinDam, x->_iLMaxDam); + return; + case IPL_STR: + case IPL_STR_CURSE: + sprintf(tempstr, "%+i to strength", x->_iPLStr); + return; + case IPL_MAG: + case IPL_MAG_CURSE: + sprintf(tempstr, "%+i to magic", x->_iPLMag); + return; + case IPL_DEX: + case IPL_DEX_CURSE: + sprintf(tempstr, "%+i to dexterity", x->_iPLDex); + return; + case IPL_VIT: + case IPL_VIT_CURSE: + sprintf(tempstr, "%+i to vitality", x->_iPLVit); + return; + case IPL_ATTRIBS: + case IPL_ATTRIBS_CURSE: + sprintf(tempstr, "%+i to all attributes", x->_iPLStr); + return; + case IPL_GETHIT: + case IPL_GETHIT_CURSE: + sprintf(tempstr, "%+i damage from enemies", x->_iPLGetHit); + return; + case IPL_LIFE: + case IPL_LIFE_CURSE: + sprintf(tempstr, "Hit Points : %+i", x->_iPLHP >> 6); + return; + case IPL_MANA: + case IPL_MANA_CURSE: + sprintf(tempstr, "Mana : %+i", x->_iPLMana >> 6); + return; + case IPL_DUR: + v8 = "high durability"; + goto LABEL_104; + case IPL_DUR_CURSE: + v8 = "decreased durability"; + goto LABEL_104; + case IPL_INDESTRUCTIBLE: + v8 = "indestructible"; + goto LABEL_104; + case IPL_LIGHT: + sprintf(tempstr, "+%i%% light radius", 10 * x->_iPLLight); + return; + case IPL_LIGHT_CURSE: + sprintf(tempstr, "-%i%% light radius", -10 * x->_iPLLight); + return; + case IPL_FIRE_ARROWS: + sprintf(tempstr, "fire arrows damage: %i-%i", x->_iFMinDam, x->_iFMaxDam); + return; + case IPL_LIGHT_ARROWS: + sprintf(tempstr, "lightning arrows damage %i-%i", x->_iLMinDam, x->_iLMaxDam); + return; + case IPL_INVCURS: + v8 = " "; + goto LABEL_104; + case IPL_THORNS: + v8 = "attacker takes 1-3 damage"; + goto LABEL_104; + case IPL_NOMANA: + v8 = "user loses all mana"; + goto LABEL_104; + case IPL_NOHEALPLR: + v8 = "you can't heal"; + goto LABEL_104; + case IPL_ABSHALFTRAP: + v8 = "absorbs half of trap damage"; + goto LABEL_104; + case IPL_KNOCKBACK: + v8 = "knocks target back"; + goto LABEL_104; + case IPL_NOHEALMON: + v8 = "hit monster doesn't heal"; + goto LABEL_104; + case IPL_STEALMANA: + v3 = &x->_iFlags; + if ( x->_iFlags & 0x2000 ) + strcpy(tempstr, "hit steals 3% mana"); + if ( !(*((_BYTE *)v3 + 1) & 0x40) ) + return; + v7 = "hit steals 5% mana"; + goto LABEL_81; + case IPL_STEALLIFE: + v4 = &x->_iFlags; + if ( (x->_iFlags & 0x8000) != 0 ) + strcpy(tempstr, "hit steals 3% life"); + if ( !(*((_BYTE *)v4 + 2) & 1) ) + return; + v7 = "hit steals 5% life"; + goto LABEL_81; + case IPL_TARGAC: + v8 = "damages target's armor"; + goto LABEL_104; + case IPL_FASTATTACK: + if ( x->_iFlags & 0x20000 ) + strcpy(tempstr, "quick attack"); + if ( v2->_iFlags & 0x40000 ) + strcpy(tempstr, "fast attack"); + if ( v2->_iFlags & 0x80000 ) + strcpy(tempstr, "faster attack"); + if ( !(v2->_iFlags & 0x100000) ) + return; + v7 = "fastest attack"; + goto LABEL_81; + case IPL_FASTRECOVER: + if ( x->_iFlags & 0x200000 ) + strcpy(tempstr, "fast hit recovery"); + if ( v2->_iFlags & 0x400000 ) + strcpy(tempstr, "faster hit recovery"); + if ( (v2->_iFlags & 0x800000) != 0 ) + { + v7 = "fastest hit recovery"; +LABEL_81: + strcpy(tempstr, v7); + } + return; + case IPL_FASTBLOCK: + v8 = "fast block"; + goto LABEL_104; + case IPL_DAMMOD: + sprintf(tempstr, "adds %i points to damage", x->_iPLDamMod); + return; + case IPL_RNDARROWVEL: + v8 = "fires random speed arrows"; + goto LABEL_104; + case IPL_SETDAM: + v9 = "unusual item damage"; + goto LABEL_98; + case IPL_SETDUR: + v8 = "altered durability"; + goto LABEL_104; + case IPL_NOMINSTR: + v8 = "no strength requirement"; + goto LABEL_104; + case IPL_SPELL: + sprintf(tempstr, "%i %s charges", x->_iMaxCharges, spelldata[x->_iSpell].sNameText); + return; + case IPL_FASTSWING: + v8 = "Faster attack swing"; + goto LABEL_104; + case IPL_ONEHAND: + v8 = "one handed sword"; + goto LABEL_104; + case IPL_3XDAMVDEM: + v8 = "+200% damage vs. demons"; + goto LABEL_104; + case IPL_ALLRESZERO: + v8 = "All Resistance equals 0"; + goto LABEL_104; + case IPL_DRAINLIFE: + v8 = "constantly lose hit points"; + goto LABEL_104; + case IPL_RNDSTEALLIFE: + v8 = "life stealing"; + goto LABEL_104; + case IPL_INFRAVISION: + v8 = "see with infravision"; + goto LABEL_104; + case IPL_SETAC: + case IPL_AC_CURSE: + sprintf(tempstr, "armor class: %i", x->_iAC); + return; + case IPL_ADDACLIFE: + v8 = "Armor class added to life"; + goto LABEL_104; + case IPL_ADDMANAAC: + v8 = "10% of mana added to armor"; + goto LABEL_104; + case IPL_FIRERESCLVL: + v5 = x->_iPLFR; + if ( v5 > 0 ) + { + if ( v5 >= 1 ) + sprintf(tempstr, "Resist Fire : %+i%%", v5); + } + else + { + v9 = " "; +LABEL_98: + sprintf(tempstr, v9); + } + break; + default: + v8 = "Another ability (NW)"; +LABEL_104: + strcpy(tempstr, v8); + break; + } +} + +//----- (00423530) -------------------------------------------------------- +void __cdecl items_unique_info_cel() +{ + char *v0; // edi + signed int v1; // edx + signed int v2; // ecx + int v3; // edi + signed int v4; // ecx + _BYTE *v5; // edi + signed int v6; // ecx + + Cel_decode(88, 487, pSTextBoxCels, 1, 271); + v0 = &gpBuffer->row[324].pixels[27]; + v1 = 148; + do + { + v2 = 132; + do + { + *v0 = 0; + v0 += 2; + --v2; + } + while ( v2 ); + *v0 = 0; + v3 = (int)(v0 - 1032); + v4 = 132; + do + { + v5 = (_BYTE *)(v3 + 1); + *v5 = 0; + v3 = (int)(v5 + 1); + --v4; + } + while ( v4 ); + v0 = (char *)(v3 - 1032); + --v1; + } + while ( v1 ); + v6 = 132; + do + { + *v0 = 0; + v0 += 2; + --v6; + } + while ( v6 ); + *v0 = 0; +} + +//----- (0042358C) -------------------------------------------------------- +void __fastcall PrintUString(int x, int y, int cjustflag, char *str, int col) +{ + char *v5; // edi + int v6; // ebx + size_t v7; // eax + int v8; // esi + int v9; // ecx + signed int v10; // eax + int v11; // edx + int v12; // eax + unsigned char v13; // al + int v14; // edi + int v15; // [esp+Ch] [ebp-4h] + int a3; // [esp+18h] [ebp+8h] + + v5 = str; + v6 = screen_y_times_768[SStringY[y] + 204] + x + 96; + v7 = strlen(str); + v8 = 0; + v9 = 0; + v15 = v7; + if ( cjustflag ) + { + v10 = 0; + if ( v15 <= 0 ) + goto LABEL_16; + do + { + v11 = (unsigned char)str[v9++]; + v10 += fontkern[fontframe[fontidx[v11]]] + 1; + } + while ( v9 < v15 ); + if ( v10 < 257 ) +LABEL_16: + v8 = (257 - v10) >> 1; + v6 += v8; + } + v12 = 0; + a3 = 0; + if ( v15 > 0 ) + { + while ( 1 ) + { + v13 = fontframe[fontidx[(unsigned char)v5[v12]]]; + v14 = v13; + v8 += fontkern[v13] + 1; + if ( v13 ) + { + if ( v8 <= 257 ) + CPrintString(v6, (char *)v13, col); + } + v6 += fontkern[v14] + 1; + v12 = a3++ + 1; + if ( a3 >= v15 ) + break; + v5 = str; + } + } +} + +//----- (0042365B) -------------------------------------------------------- +void __fastcall items_unique_info_box(int y) +{ + char *v1; // esi + char *v2; // edi + signed int v3; // edx + _WORD *v4; // edi + _WORD *v5; // esi + + v1 = &gpBuffer->row[25].pixels[26]; + v2 = &gpBuffer->row_unused_1[0].pixels[screen_y_times_768[SStringY[y] + 198] + 26]; + v3 = 3; + do + { + qmemcpy(v2, v1, 0x108u); + v5 = (unsigned short *)v1 + 264; + v4 = (unsigned short *)v2 + 264; + *v4 = *v5; + v1 = (char *)(v5 + 252); + v2 = (char *)(v4 + 252); + --v3; + } + while ( v3 ); +} + +//----- (004236A6) -------------------------------------------------------- +void __cdecl DrawUniqueInfo() +{ + int v0; // esi + int v1; // esi + int v2; // edi + + if ( !chrflag && !questlog ) + { + v0 = curruitem._iUid; + items_unique_info_cel(); + v1 = v0; + PrintUString(0, 2, 1, UniqueItemList[v1].UIName, 3); + items_unique_info_box(5); + PrintItemPower(UniqueItemList[v1].UIPower1, &curruitem); + v2 = 14 - (char)UniqueItemList[v1].UINumPL; + PrintUString(0, v2, 1, tempstr, 0); + if ( UniqueItemList[v1].UINumPL > 1 ) + { + PrintItemPower(UniqueItemList[v1].UIPower2, &curruitem); + PrintUString(0, v2 + 2, 1, tempstr, 0); + } + if ( UniqueItemList[v1].UINumPL > 2 ) + { + PrintItemPower(UniqueItemList[v1].UIPower3, &curruitem); + PrintUString(0, v2 + 4, 1, tempstr, 0); + } + if ( UniqueItemList[v1].UINumPL > 3 ) + { + PrintItemPower(UniqueItemList[v1].UIPower4, &curruitem); + PrintUString(0, v2 + 6, 1, tempstr, 0); + } + if ( UniqueItemList[v1].UINumPL > 4 ) + { + PrintItemPower(UniqueItemList[v1].UIPower5, &curruitem); + PrintUString(0, v2 + 8, 1, tempstr, 0); + } + if ( UniqueItemList[v1].UINumPL > 5 ) + { + PrintItemPower(UniqueItemList[v1].UIPower6, &curruitem); + PrintUString(0, v2 + 10, 1, tempstr, 0); + } + } +} +// 69BD04: using guessed type int questlog; + +//----- (004237DC) -------------------------------------------------------- +void __fastcall PrintItemMisc(ItemStruct *x) +{ + ItemStruct *v1; // edi + signed int v2; // eax + + v1 = x; + if ( x->_iMiscId == IMISC_SCROLL ) + { + strcpy(tempstr, "Right-click to read"); + AddPanelString(tempstr, 1); + } + if ( v1->_iMiscId == IMISC_SCROLLT ) + { + strcpy(tempstr, "Right-click to read, then"); + AddPanelString(tempstr, 1); + strcpy(tempstr, "left-click to target"); + AddPanelString(tempstr, 1); + } + v2 = v1->_iMiscId; + if ( v2 >= 1 && v2 <= (signed int)IMISC_USELAST ) + { + PrintItemOil(v1->_iMiscId); + strcpy(tempstr, "Right click to use"); + AddPanelString(tempstr, 1); + } + if ( v1->_iMiscId == IMISC_BOOK ) + { + strcpy(tempstr, "Right click to read"); + AddPanelString(tempstr, 1); + } + if ( v1->_iMiscId == IMISC_MAPOFDOOM ) + { + strcpy(tempstr, "Right click to view"); + AddPanelString(tempstr, 1); + } + if ( v1->_iMiscId == IMISC_EAR ) + { + sprintf(tempstr, "Level : %i", v1->_ivalue); + AddPanelString(tempstr, 1); + } +} + +//----- (004238D4) -------------------------------------------------------- +void __fastcall PrintItemDetails(ItemStruct *x) +{ + ItemStruct *v1; // ebp + char v2; // cl + char v3; // cl + char v4; // al + unsigned char v5; // al + char v6; // al + + v1 = x; + if ( x->_iClass == 1 ) + { + if ( x->_iMaxDur == 255 ) + sprintf(tempstr, "damage: %i-%i Indestructible", x->_iMinDam, x->_iMaxDam); + else + sprintf(tempstr, "damage: %i-%i Dur: %i/%i", x->_iMinDam, x->_iMaxDam, x->_iDurability, x->_iMaxDur); + AddPanelString(tempstr, 1); + } + if ( v1->_iClass == 2 ) + { + if ( v1->_iMaxDur == 255 ) + sprintf(tempstr, "armor: %i Indestructible", v1->_iAC); + else + sprintf(tempstr, "armor: %i Dur: %i/%i", v1->_iAC, v1->_iDurability, v1->_iMaxDur); + AddPanelString(tempstr, 1); + } + if ( v1->_iMiscId == IMISC_STAFF && v1->_iMaxCharges ) + { + sprintf(tempstr, "dam: %i-%i Dur: %i/%i", v1->_iMinDam, v1->_iMaxDam, v1->_iDurability, v1->_iMaxDur); + sprintf(tempstr, "Charges: %i/%i", v1->_iCharges, v1->_iMaxCharges); + AddPanelString(tempstr, 1); + } + v2 = v1->_iPrePower; + if ( v2 != -1 ) + { + PrintItemPower(v2, v1); + AddPanelString(tempstr, 1); + } + v3 = v1->_iSufPower; + if ( v3 != -1 ) + { + PrintItemPower(v3, v1); + AddPanelString(tempstr, 1); + } + if ( v1->_iMagical == 2 ) + { + AddPanelString("unique item", 1); + uitemflag = 1; + qmemcpy(&curruitem, v1, sizeof(curruitem)); + } + PrintItemMisc(v1); + if ( (unsigned char)v1->_iMinMag + v1->_iMinDex + v1->_iMinStr ) + { + strcpy(tempstr, "Required:"); + v4 = v1->_iMinStr; + if ( v4 ) + sprintf(tempstr, "%s %i Str", tempstr, v4); + v5 = v1->_iMinMag; + if ( v5 ) + sprintf(tempstr, "%s %i Mag", tempstr, v5); + v6 = v1->_iMinDex; + if ( v6 ) + sprintf(tempstr, "%s %i Dex", tempstr, v6); + AddPanelString(tempstr, 1); + } + pinfoflag = 1; +} +// 4B8824: using guessed type int pinfoflag; + +//----- (00423AE1) -------------------------------------------------------- +void __fastcall PrintItemDur(ItemStruct *x) +{ + ItemStruct *v1; // esi + int v2; // eax + char v3; // al + unsigned char v4; // al + char v5; // al + + v1 = x; + if ( x->_iClass == 1 ) + { + if ( x->_iMaxDur == 255 ) + sprintf(tempstr, "damage: %i-%i Indestructible", x->_iMinDam, x->_iMaxDam); + else + sprintf(tempstr, "damage: %i-%i Dur: %i/%i", x->_iMinDam, x->_iMaxDam, x->_iDurability, x->_iMaxDur); + AddPanelString(tempstr, 1); + if ( v1->_iMiscId == IMISC_STAFF && v1->_iMaxCharges ) + { + sprintf(tempstr, "Charges: %i/%i", v1->_iCharges, v1->_iMaxCharges); + AddPanelString(tempstr, 1); + } + if ( v1->_iMagical ) + AddPanelString("Not Identified", 1); + } + if ( v1->_iClass == 2 ) + { + if ( v1->_iMaxDur == 255 ) + sprintf(tempstr, "armor: %i Indestructible", v1->_iAC); + else + sprintf(tempstr, "armor: %i Dur: %i/%i", v1->_iAC, v1->_iDurability, v1->_iMaxDur); + AddPanelString(tempstr, 1); + if ( v1->_iMagical ) + AddPanelString("Not Identified", 1); + if ( v1->_iMiscId == IMISC_STAFF && v1->_iMaxCharges ) + { + sprintf(tempstr, "Charges: %i/%i", v1->_iCharges, v1->_iMaxCharges); + AddPanelString(tempstr, 1); + } + } + v2 = v1->_itype; + if ( v2 == ITYPE_RING || v2 == ITYPE_AMULET ) + AddPanelString("Not Identified", 1); + PrintItemMisc(v1); + if ( (unsigned char)v1->_iMinMag + v1->_iMinDex + v1->_iMinStr ) + { + strcpy(tempstr, "Required:"); + v3 = v1->_iMinStr; + if ( v3 ) + sprintf(tempstr, "%s %i Str", tempstr, v3); + v4 = v1->_iMinMag; + if ( v4 ) + sprintf(tempstr, "%s %i Mag", tempstr, v4); + v5 = v1->_iMinDex; + if ( v5 ) + sprintf(tempstr, "%s %i Dex", tempstr, v5); + AddPanelString(tempstr, 1); + } + pinfoflag = 1; +} +// 4B8824: using guessed type int pinfoflag; + +//----- (00423CE0) -------------------------------------------------------- +void __fastcall UseItem(int p, int Mid, int spl) +{ + int v3; // esi + int v4; // edx + int v5; // edx + int v6; // edx + int v7; // edx + int v8; // edx + int v9; // esi + int v10; // esi + int v11; // edi + unsigned int v12; // edi + char v13; // al + int v14; // edi + int v15; // ecx + int *v16; // eax + int *v17; // eax + int v18; // esi + int v19; // esi + int v20; // edx + int v21; // edx + int v22; // edx + int v23; // edx + int v24; // edx + int v25; // edi + char *v26; // eax + int v27; // edx + int *v28; // ecx + int v29; // eax + int *v30; // ecx + int v31; // edi + int v32; // edi + int v33; // eax + int v34; // ecx + int v35; // eax + bool v36; // zf + int v37; // ecx + int v38; // eax + int v39; // edx + int v40; // eax + int v41; // edx + int v42; // esi + int v43; // edi + unsigned int v44; // edi + char v45; // al + int v46; // edi + int v47; // ecx + int *v48; // eax + int v49; // ecx + int *v50; // eax + int v51; // edi + int v52; // edx + unsigned int v53; // edi + char v54; // al + int v55; // edi + int v56; // ecx + int *v57; // eax + int *v58; // eax + int v59; // esi + int v60; // edx + int v61; // esi + int v62; // edi + unsigned int v63; // edi + char v64; // al + int v65; // edi + int v66; // ecx + int *v67; // eax + int *v68; // eax + int v69; // esi + int v70; // edx + int pa; // [esp+Ch] [ebp-4h] + + v3 = p; + pa = p; + if ( Mid > 28 ) + { + v70 = Mid - 42; + if ( !v70 ) + { + doom_init(); + return; + } + if ( v70 != 2 ) + return; + ModifyPlrStr(p, 3); + ModifyPlrMag(v3, 3); + ModifyPlrDex(v3, 3); + v60 = 3; +LABEL_82: + ModifyPlrVit(v3, v60); + return; + } + if ( Mid == 28 ) + goto LABEL_71; + if ( Mid <= 12 ) + { + if ( Mid == 12 ) + { + ModifyPlrDex(p, 1); + return; + } + v4 = Mid - 2; + if ( !v4 ) + { + v19 = p; + plr[v19]._pHitPoints = plr[v19]._pMaxHP; + plr[v19]._pHPBase = plr[p]._pMaxHPBase; +LABEL_25: + drawhpflag = 1; + return; + } + v5 = v4 - 1; + if ( v5 ) + { + v6 = v5 - 3; + if ( v6 ) + { + v7 = v6 - 1; + if ( v7 ) + { + v8 = v7 - 3; + if ( v8 ) + { + if ( v8 == 1 ) + ModifyPlrMag(p, 1); + } + else + { + ModifyPlrStr(p, 1); + } + return; + } + v9 = p; + if ( plr[p]._pIFlags & 0x8000000 ) + return; + plr[v9]._pMana = plr[v9]._pMaxMana; + plr[v9]._pManaBase = plr[v9]._pMaxManaBase; +LABEL_41: + drawmanaflag = 1; + return; + } + v10 = p; + _LOBYTE(p) = 40; + v11 = plr[v10]._pMaxMana >> 8; + v12 = (v11 & 0xFFFFFFFE) + 2 * random(p, v11); + v13 = plr[v10]._pClass; + v14 = 32 * v12; + if ( v13 == 2 ) + v14 *= 2; + if ( v13 == 1 ) + v14 += v14 >> 1; + if ( !(*(_BYTE *)(v10 * 21720 + 6863003) & 8) ) + { + v15 = plr[v10]._pMaxMana; + v16 = &plr[v10]._pMana; + *v16 += v14; + if ( plr[v10]._pMana > v15 ) + *v16 = v15; + v17 = &plr[v10]._pManaBase; + v18 = plr[v10]._pMaxManaBase; + *v17 += v14; + if ( *v17 > v18 ) + *v17 = v18; + goto LABEL_41; + } + return; + } +LABEL_71: + v61 = p; + _LOBYTE(p) = 39; + v62 = plr[v61]._pMaxHP >> 8; + v63 = (v62 & 0xFFFFFFFE) + 2 * random(p, v62); + v64 = plr[v61]._pClass; + v65 = 32 * v63; + if ( !v64 ) + v65 *= 2; + if ( v64 == 1 ) + v65 += v65 >> 1; + v66 = plr[v61]._pMaxHP; + v67 = &plr[v61]._pHitPoints; + *v67 += v65; + if ( plr[v61]._pHitPoints > v66 ) + *v67 = v66; + v68 = &plr[v61]._pHPBase; + v69 = plr[v61]._pMaxHPBase; + *v68 += v65; + if ( *v68 > v69 ) + *v68 = v69; + goto LABEL_25; + } + v20 = Mid - 13; + if ( !v20 ) + { + v60 = 1; + goto LABEL_82; + } + v21 = v20 - 5; + if ( v21 ) + { + v22 = v21 - 1; + if ( v22 ) + { + v23 = v22 - 2; + if ( v23 ) + { + v24 = v23 - 1; + if ( v24 ) + { + if ( v24 != 2 ) + return; + v25 = p; + *(_QWORD *)plr[p]._pMemSpells |= 1i64 << ((unsigned char)spl - 1); + v26 = &plr[p]._pSplLvl[spl]; + if ( *v26 < 15 ) + ++*v26; + v27 = plr[v25]._pMaxMana; + v28 = &plr[v25]._pMana; + v29 = spelldata[spl].sManaCost << 6; + *v28 += v29; + if ( plr[v25]._pMana > v27 ) + *v28 = v27; + v30 = &plr[v25]._pManaBase; + v31 = plr[v25]._pMaxManaBase; + *v30 += v29; + if ( *v30 > v31 ) + *v30 = v31; + if ( pa == myplr ) + CalcPlrBookVals(pa); + goto LABEL_41; + } + v32 = spl; + if ( !spelldata[spl].sTargeted ) + { + ClrPlrPath(p); + v33 = v3; + plr[v33].destParam1 = cursmx; + v34 = cursmy; + plr[v33]._pSpell = spl; + plr[v33]._pSplType = 4; + plr[v33]._pSplFrom = 3; + plr[v33].destAction = 12; + plr[v33].destParam2 = v34; + return; + } + } + else + { + v32 = spl; + if ( !spelldata[spl].sTargeted ) + { + ClrPlrPath(p); + v37 = cursmx; + v38 = v3; + v39 = cursmy; + v36 = v3 == myplr; + plr[v38]._pSpell = spl; + plr[v38]._pSplType = 4; + plr[v38]._pSplFrom = 3; + plr[v38].destAction = 12; + plr[v38].destParam1 = v37; + plr[v38].destParam2 = v39; + if ( v36 && spl == 18 ) + NetSendCmdLoc(1u, CMD_NOVA, v37, v39); + return; + } + } + v35 = p; + v36 = p == myplr; + plr[v35]._pTSpell = v32; + _LOBYTE(plr[v35]._pTSplType) = 4; + if ( v36 ) + SetCursor(9); + return; + } + v40 = p; + plr[v40]._pHitPoints = plr[p]._pMaxHP; + plr[v40]._pHPBase = plr[p]._pMaxHPBase; + v36 = (plr[p]._pIFlags & 0x8000000) == 0; + drawhpflag = 1; + if ( v36 ) + { + v41 = plr[v40]._pMaxMana; + drawmanaflag = 1; + plr[v40]._pMana = v41; + plr[v40]._pManaBase = plr[v40]._pMaxManaBase; + } + } + else + { + v42 = p; + _LOBYTE(p) = 39; + v43 = plr[v42]._pMaxHP >> 8; + v44 = (v43 & 0xFFFFFFFE) + 2 * random(p, v43); + v45 = plr[v42]._pClass; + v46 = 32 * v44; + if ( !v45 ) + v46 *= 2; + if ( v45 == 1 ) + v46 += v46 >> 1; + v47 = plr[v42]._pMaxHP; + v48 = &plr[v42]._pHitPoints; + *v48 += v46; + if ( plr[v42]._pHitPoints > v47 ) + *v48 = v47; + v49 = plr[v42]._pMaxHPBase; + v50 = &plr[v42]._pHPBase; + *v50 += v46; + if ( plr[v42]._pHPBase > v49 ) + *v50 = v49; + v51 = plr[v42]._pMaxMana >> 8; + v52 = plr[v42]._pMaxMana >> 8; + _LOBYTE(v49) = 40; + drawhpflag = 1; + v53 = (v51 & 0xFFFFFFFE) + 2 * random(v49, v52); + v54 = plr[v42]._pClass; + v55 = 32 * v53; + if ( v54 == 2 ) + v55 *= 2; + if ( v54 == 1 ) + v55 += v55 >> 1; + if ( !(plr[v42]._pIFlags & 0x8000000) ) + { + v56 = plr[v42]._pMaxMana; + v57 = &plr[v42]._pMana; + *v57 += v55; + if ( plr[v42]._pMana > v56 ) + *v57 = v56; + v58 = &plr[v42]._pManaBase; + v59 = plr[v42]._pMaxManaBase; + *v58 += v55; + if ( *v58 > v59 ) + *v58 = v59; + drawmanaflag = 1; + } + } +} + +//----- (004241D7) -------------------------------------------------------- +bool __fastcall StoreStatOk(ItemStruct *h) +{ + int v1; // edx + bool result; // al + + v1 = myplr; + result = 1; + if ( plr[myplr]._pStrength < h->_iMinStr ) + result = 0; + if ( plr[v1]._pMagic < (unsigned char)h->_iMinMag ) + result = 0; + if ( plr[v1]._pDexterity < h->_iMinDex ) + result = 0; + return result; +} + +//----- (0042421C) -------------------------------------------------------- +int __fastcall SmithItemOk(int i) +{ + unsigned char v1; // cl + int result; // eax + + v1 = AllItemsList[i].itype; + result = 1; + if ( !v1 ) + result = 0; + if ( v1 == ITYPE_GOLD ) + result = 0; + if ( v1 == ITYPE_0E ) + result = 0; + if ( v1 == ITYPE_STAFF ) + result = 0; + if ( v1 == ITYPE_RING ) + result = 0; + if ( v1 == ITYPE_AMULET ) + result = 0; + return result; +} + +//----- (00424252) -------------------------------------------------------- +int __fastcall RndSmithItem(int lvl) +{ + int v1; // edx + int v2; // edi + ItemDataStruct *v3; // esi + int v4; // ebx + int v6[512]; // [esp+4h] [ebp-804h] + int v7; // [esp+804h] [ebp-4h] + + v1 = 0; + v2 = 1; + v7 = lvl; + if ( AllItemsList[1].iLoc != ILOC_INVALID ) + { + v3 = &AllItemsList[1]; + do + { + v4 = v3->iRnd; + if ( v3->iRnd ) + { + if ( SmithItemOk(v2) ) + { + if ( v7 >= SLOBYTE(v3->iMinMLvl) ) + { + v6[v1++] = v2; + if ( v4 == 2 ) + v6[v1++] = v2; + } + } + } + ++v3; + ++v2; + } + while ( v3->iLoc != -1 ); + } + _LOBYTE(lvl) = 50; + return v6[random(lvl, v1)] + 1; +} +// 424252: using guessed type int var_804[512]; + +//----- (004242C1) -------------------------------------------------------- +void __fastcall BubbleSwapItem(ItemStruct *a, ItemStruct *b) +{ + ItemStruct h; // [esp+8h] [ebp-170h] + + qmemcpy(&h, a, sizeof(h)); + qmemcpy(a, b, sizeof(ItemStruct)); + qmemcpy(b, &h, sizeof(ItemStruct)); +} + +//----- (004242F5) -------------------------------------------------------- +void __cdecl SortSmith() +{ + int v0; // esi + int *v1; // eax + signed int v2; // ecx + int *v3; // eax + int v4; // ebx + int v5; // edi + + v0 = 0; + if ( smithitem[1]._itype != -1 ) + { + v1 = &smithitem[1]._itype; + do + { + v1 += 92; + ++v0; + } + while ( *v1 != -1 ); + } + v2 = 0; + while ( v0 > 0 && !v2 ) + { + v2 = 1; + if ( v0 > 0 ) + { + v3 = &smithitem[0].IDidx; + v4 = v0; + do + { + v5 = (int)(v3 + 92); + if ( *v3 > v3[92] ) + { + BubbleSwapItem((ItemStruct *)(v3 - 90), (ItemStruct *)(v3 + 2)); + v2 = 0; + } + --v4; + v3 = (int *)v5; + } + while ( v4 ); + } + --v0; + } +} + +//----- (00424351) -------------------------------------------------------- +void __fastcall SpawnSmith(int lvl) +{ + int v1; // esi + int v2; // eax + int v3; // ebp + ItemStruct *v4; // ebx + int v5; // eax + int v6; // eax + int *v7; // ebp + short v8; // [esp+8h] [ebp-Ch] + int v9; // [esp+Ch] [ebp-8h] + int v10; // [esp+10h] [ebp-4h] + + v1 = lvl; + _LOBYTE(lvl) = 50; + v10 = v1; + v2 = random(lvl, 10); + v3 = v2 + 10; + if ( v2 + 10 > 0 ) + { + v8 = v1 | 0x400; + v4 = smithitem; + v9 = v2 + 10; + while ( 1 ) + { + do + { + items[0]._iSeed = GetRndSeed(); + SetRndSeed(items[0]._iSeed); + v5 = RndSmithItem(v1); + GetItemAttrs(0, v5 - 1, v1); + } + while ( items[0]._iIvalue > 140000 ); + qmemcpy(v4, items, sizeof(ItemStruct)); + v4->_iCreateInfo = v8; + v4->_iIdentified = 1; + _LOBYTE(v6) = StoreStatOk(v4); + v4->_iStatFlag = v6; + ++v4; + if ( !--v9 ) + break; + v1 = v10; + } + } + if ( v3 < 20 ) + { + v7 = &smithitem[v3]._itype; + do + { + *v7 = -1; + v7 += 92; + } + while ( (signed int)v7 < (signed int)sync_word_6AA708 ); + } + SortSmith(); +} + +//----- (00424420) -------------------------------------------------------- +int __fastcall PremiumItemOk(int i) +{ + unsigned char v1; // cl + int result; // eax + + v1 = AllItemsList[i].itype; + result = 1; + if ( !v1 ) + result = 0; + if ( v1 == ITYPE_GOLD ) + result = 0; + if ( v1 == ITYPE_0E ) + result = 0; + if ( v1 == ITYPE_STAFF ) + result = 0; + if ( gbMaxPlayers != 1 ) + { + if ( v1 == ITYPE_RING ) + result = 0; + if ( v1 == ITYPE_AMULET ) + result = 0; + } + return result; +} +// 679660: using guessed type char gbMaxPlayers; + +//----- (0042445F) -------------------------------------------------------- +int __fastcall RndPremiumItem(int minlvl, int maxlvl) +{ + int v2; // edx + int v3; // edi + int v4; // ebx + int *v5; // esi + int v6; // eax + int ril[512]; // [esp+8h] [ebp-804h] + int v9; // [esp+808h] [ebp-4h] + + v9 = maxlvl; + v2 = 0; + v3 = 1; + v4 = minlvl; + if ( AllItemsList[1].iLoc != ILOC_INVALID ) + { + v5 = &AllItemsList[1].iMinMLvl; + do + { + if ( *(v5 - 6) ) + { + if ( PremiumItemOk(v3) ) + { + v6 = *(char *)v5; + if ( v6 >= v4 && v6 <= v9 ) + ril[v2++] = v3; + } + } + v5 += 19; + ++v3; + } + while ( *((_BYTE *)v5 - 19) != -1 ); + } + _LOBYTE(minlvl) = 50; + return ril[random(minlvl, v2)] + 1; +} +// 42445F: using guessed type int ril[512]; + +//----- (004244C6) -------------------------------------------------------- +void __fastcall SpawnOnePremium(int i, int plvl) +{ + int v2; // edi + int v3; // ebx + int v4; // esi + int v5; // ebx + ItemStruct *v6; // edx + short v7; // ax + int v8; // eax + char v9[368]; // [esp+Ch] [ebp-178h] + int v10; // [esp+17Ch] [ebp-8h] + int lvl; // [esp+180h] [ebp-4h] + + v10 = i; + lvl = plvl; + qmemcpy(v9, items, sizeof(v9)); + if ( plvl > 30 ) + lvl = 30; + if ( lvl < 1 ) + lvl = 1; + v2 = lvl >> 2; + v3 = lvl >> 1; + do + { + items[0]._iSeed = GetRndSeed(); + SetRndSeed(items[0]._iSeed); + v4 = RndPremiumItem(v2, lvl) - 1; + GetItemAttrs(0, v4, lvl); + GetItemBonus(0, v4, v3, lvl, 1); + } + while ( items[0]._iIvalue > 140000 ); + v7 = lvl | 0x800; + v5 = v10; + v6 = &premiumitem[v10]; + qmemcpy(&premiumitem[v10], items, sizeof(ItemStruct)); + premiumitem[v5]._iCreateInfo = v7; + premiumitem[v5]._iIdentified = 1; + _LOBYTE(v8) = StoreStatOk(v6); + premiumitem[v5]._iStatFlag = v8; + qmemcpy(items, v9, 0x170u); +} + +//----- (004245A0) -------------------------------------------------------- +void __fastcall SpawnPremium(int lvl) +{ + int v1; // edi + int *v2; // esi + int i; // eax + int v4; // [esp+Ch] [ebp-4h] + + v4 = lvl; + if ( numpremium < 6 ) + { + v1 = 0; + v2 = &premiumitem[0]._itype; + do + { + if ( *v2 == -1 ) + SpawnOnePremium(v1, premiumlevel + premiumlvladd[v1]); + v2 += 92; + ++v1; + } + while ( (signed int)v2 < (signed int)&talker ); + numpremium = 6; + } + for ( i = premiumlevel; premiumlevel < v4; i = premiumlevel ) + { + qmemcpy(premiumitem, &premiumitem[2], 0x170u); + qmemcpy(&premiumitem[1], &premiumitem[3], sizeof(ItemStruct)); + qmemcpy(&premiumitem[2], &premiumitem[4], sizeof(ItemStruct)); + premiumlevel = i + 1; + SpawnOnePremium(3, premiumlvladd[3] + i + 1); + qmemcpy(&premiumitem[4], &premiumitem[5], sizeof(ItemStruct)); + SpawnOnePremium(5, premiumlvladd[5] + premiumlevel); + } +} +// 69FB38: using guessed type int talker; + +//----- (0042466C) -------------------------------------------------------- +int __fastcall WitchItemOk(int i) +{ + int v1; // ecx + int result; // eax + unsigned char v3; // dl + int v4; // edx + int v5; // ecx + + v1 = i; + result = 0; + v3 = AllItemsList[v1].itype; + if ( !v3 ) + result = 1; + if ( v3 == ITYPE_STAFF ) + result = 1; + v4 = AllItemsList[v1].iMiscId; + if ( v4 == IMISC_MANA ) + result = 0; + if ( v4 == IMISC_FULLMANA ) + result = 0; + v5 = AllItemsList[v1].iSpell; + if ( v5 == SPL_TOWN ) + result = 0; + if ( v4 == SPL_HEAL ) + result = 0; + if ( v4 == SPL_LIGHTNING ) + result = 0; + if ( v5 == SPL_RESURRECT && gbMaxPlayers == 1 ) + result = 0; + if ( v5 == SPL_HEALOTHER && gbMaxPlayers == 1 ) + result = 0; + return result; +} +// 679660: using guessed type char gbMaxPlayers; + +//----- (004246D2) -------------------------------------------------------- +int __fastcall RndWitchItem(int lvl) +{ + int v1; // ebx + int v2; // edi + int *v3; // esi + int v5[512]; // [esp+8h] [ebp-804h] + int v6; // [esp+808h] [ebp-4h] + + v1 = 0; + v2 = 1; + v6 = lvl; + if ( AllItemsList[1].iLoc != ILOC_INVALID ) + { + v3 = &AllItemsList[1].iMinMLvl; + do + { + if ( *(v3 - 6) && WitchItemOk(v2) && v6 >= *(char *)v3 ) + v5[v1++] = v2; + v3 += 19; + ++v2; + } + while ( *((_BYTE *)v3 - 19) != -1 ); + } + _LOBYTE(lvl) = 51; + return v5[random(lvl, v1)] + 1; +} +// 4246D2: using guessed type int var_804[512]; + +//----- (00424735) -------------------------------------------------------- +void __cdecl SortWitch() +{ + signed int v0; // esi + int *v1; // eax + signed int v2; // ecx + int *v3; // eax + int v4; // ebx + int v5; // edi + + v0 = 3; + if ( witchitem[4]._itype != -1 ) + { + v1 = &witchitem[4]._itype; + do + { + v1 += 92; + ++v0; + } + while ( *v1 != -1 ); + } + v2 = 0; + while ( v0 > 3 && !v2 ) + { + v2 = 1; + if ( v0 > 3 ) + { + v3 = &witchitem[3].IDidx; + v4 = v0 - 3; + do + { + v5 = (int)(v3 + 92); + if ( *v3 > v3[92] ) + { + BubbleSwapItem((ItemStruct *)(v3 - 90), (ItemStruct *)(v3 + 2)); + v2 = 0; + } + --v4; + v3 = (int *)v5; + } + while ( v4 ); + } + --v0; + } +} + +//----- (00424795) -------------------------------------------------------- +void __fastcall WitchBookLevel(int ii) +{ + int v1; // ecx + int v2; // eax + unsigned char v3; // bl + int v4; // edx + int v5; // edi + + v1 = ii; + if ( witchitem[v1]._iMiscId == IMISC_BOOK ) + { + v2 = witchitem[v1]._iSpell; + v3 = spelldata[witchitem[v1]._iSpell].sMinInt; + v4 = myplr; + witchitem[v1]._iMinMag = v3; + v5 = plr[v4]._pSplLvl[v2]; + if ( plr[v4]._pSplLvl[v2] ) + { + do + { + v3 += 20 * v3 / 100; + --v5; + if ( v3 + 20 * v3 / 100 > 255 ) + { + v3 = -1; + v5 = 0; + } + } + while ( v5 ); + witchitem[v1]._iMinMag = v3; + } + } +} + +//----- (00424815) -------------------------------------------------------- +void __fastcall SpawnWitch(int lvl) +{ + int v1; // ebx + int v2; // ebp + int v3; // esi + int v4; // ecx + int v5; // eax + int v6; // eax + int *v7; // ebp + signed int ii; // [esp+10h] [ebp-8h] + ItemStruct *item; // [esp+14h] [ebp-4h] + + v1 = lvl; + GetItemAttrs(0, 25, 1); + qmemcpy(witchitem, items, 0x170u); + witchitem[0]._iCreateInfo = v1; + witchitem[0]._iStatFlag = 1; + GetItemAttrs(0, 30, 1); + qmemcpy(&witchitem[1], items, sizeof(ItemStruct)); + witchitem[1]._iCreateInfo = v1; + witchitem[1]._iStatFlag = 1; + GetItemAttrs(0, 27, 1); + qmemcpy(&witchitem[2], items, sizeof(ItemStruct)); + witchitem[2]._iCreateInfo = v1; + witchitem[2]._iStatFlag = 1; + v2 = random(51, 8) + 10; + ii = 3; + if ( v2 > 3 ) + { + item = &witchitem[3]; + while ( 1 ) + { + items[0]._iSeed = GetRndSeed(); + SetRndSeed(items[0]._iSeed); + v3 = RndWitchItem(v1) - 1; + GetItemAttrs(0, v3, v1); + _LOBYTE(v4) = 51; + if ( random(v4, 100) > 5 || (v5 = 2 * v1, 2 * v1 == -1) ) + { + if ( items[0]._iMiscId != IMISC_STAFF ) + continue; + v5 = 2 * v1; + if ( 2 * v1 == -1 ) + continue; + } + GetItemBonus(0, v3, v5 >> 1, v5, 1); + if ( items[0]._iIvalue <= 140000 ) + { + qmemcpy(item, items, sizeof(ItemStruct)); + item->_iIdentified = 1; + item->_iCreateInfo = v1 | 0x2000; + WitchBookLevel(ii); + _LOBYTE(v6) = StoreStatOk(item); + ++ii; + item->_iStatFlag = v6; + ++item; + if ( ii >= v2 ) + break; + } + } + } + if ( v2 < 20 ) + { + v7 = &witchitem[v2]._itype; + do + { + *v7 = -1; + v7 += 92; + } + while ( (signed int)v7 < (signed int)healitem ); + } + SortWitch(); +} + +//----- (004249A4) -------------------------------------------------------- +int __fastcall RndBoyItem(int lvl) +{ + int v1; // edx + int v2; // edi + int v3; // ebx + int *v4; // esi + int v6[512]; // [esp+8h] [ebp-800h] + + v1 = 0; + v2 = 1; + v3 = lvl; + if ( AllItemsList[1].iLoc != ILOC_INVALID ) + { + v4 = &AllItemsList[1].iMinMLvl; + do + { + if ( *(v4 - 6) && PremiumItemOk(v2) && v3 >= *(char *)v4 ) + v6[v1++] = v2; + v4 += 19; + ++v2; + } + while ( *((_BYTE *)v4 - 19) != -1 ); + } + _LOBYTE(lvl) = 49; + return v6[random(lvl, v1)] + 1; +} +// 4249A4: using guessed type int var_800[512]; + +//----- (00424A03) -------------------------------------------------------- +void __fastcall SpawnBoy(int lvl) +{ + int v1; // ebx + int v2; // ebp + int v3; // esi + int v4; // eax + + v1 = lvl; + v2 = lvl >> 1; + if ( boylevel < lvl >> 1 || boyitem._itype == -1 ) + { + do + { + items[0]._iSeed = GetRndSeed(); + SetRndSeed(items[0]._iSeed); + v3 = RndBoyItem(v1) - 1; + GetItemAttrs(0, v3, v1); + GetItemBonus(0, v3, v1, 2 * v1, 1); + } + while ( items[0]._iIvalue > 90000 ); + BYTE1(v1) |= 0x10u; + qmemcpy(&boyitem, items, sizeof(boyitem)); + boyitem._iCreateInfo = v1; + boyitem._iIdentified = 1; + _LOBYTE(v4) = StoreStatOk(&boyitem); + boyitem._iStatFlag = v4; + boylevel = v2; + } +} +// 6A8A3C: using guessed type int boylevel; + +//----- (00424A9B) -------------------------------------------------------- +int __fastcall HealerItemOk(int i) +{ + int v1; // ecx + int result; // eax + int v3; // esi + + v1 = i; + result = 0; + if ( AllItemsList[v1].itype ) + return 0; + v3 = AllItemsList[v1].iMiscId; + if ( v3 == IMISC_SCROLL && AllItemsList[v1].iSpell == SPL_HEAL ) + result = 1; + if ( v3 != IMISC_SCROLLT ) + goto LABEL_12; + if ( AllItemsList[v1].iSpell == SPL_RESURRECT && gbMaxPlayers != 1 ) + result = 0; + if ( AllItemsList[v1].iSpell != SPL_HEALOTHER ) + { +LABEL_12: + if ( gbMaxPlayers != 1 ) + goto LABEL_21; + goto LABEL_13; + } + if ( gbMaxPlayers != 1 ) + { + result = 1; + goto LABEL_12; + } +LABEL_13: + if ( v3 == IMISC_ELIXSTR ) + result = 1; + if ( v3 == IMISC_ELIXMAG ) + result = 1; + if ( v3 == IMISC_ELIXDEX ) + result = 1; + if ( v3 == IMISC_ELIXVIT ) + result = 1; +LABEL_21: + if ( v3 == IMISC_FULLHEAL ) + result = 1; + if ( v3 == IMISC_REJUV ) + result = 1; + if ( v3 == IMISC_FULLREJUV ) + result = 1; + if ( v3 == IMISC_HEAL ) + result = 0; + if ( v3 == IMISC_FULLHEAL ) + result = 0; + if ( v3 == IMISC_MANA ) + result = 0; + if ( v3 == IMISC_FULLMANA ) + return 0; + return result; +} +// 679660: using guessed type char gbMaxPlayers; + +//----- (00424B49) -------------------------------------------------------- +int __fastcall RndHealerItem(int lvl) +{ + int v1; // ebx + int v2; // edi + int *v3; // esi + int v5[512]; // [esp+8h] [ebp-804h] + int v6; // [esp+808h] [ebp-4h] + + v1 = 0; + v2 = 1; + v6 = lvl; + if ( AllItemsList[1].iLoc != ILOC_INVALID ) + { + v3 = &AllItemsList[1].iMinMLvl; + do + { + if ( *(v3 - 6) && HealerItemOk(v2) && v6 >= *(char *)v3 ) + v5[v1++] = v2; + v3 += 19; + ++v2; + } + while ( *((_BYTE *)v3 - 19) != -1 ); + } + _LOBYTE(lvl) = 50; + return v5[random(lvl, v1)] + 1; +} +// 424B49: using guessed type int var_804[512]; + +//----- (00424BAC) -------------------------------------------------------- +void __cdecl SortHealer() +{ + signed int v0; // esi + int *v1; // eax + signed int v2; // ecx + int *v3; // eax + int v4; // ebx + int v5; // edi + + v0 = 2; + if ( healitem[3]._itype != -1 ) + { + v1 = &healitem[3]._itype; + do + { + v1 += 92; + ++v0; + } + while ( *v1 != -1 ); + } + v2 = 0; + while ( v0 > 2 && !v2 ) + { + v2 = 1; + if ( v0 > 2 ) + { + v3 = &healitem[2].IDidx; + v4 = v0 - 2; + do + { + v5 = (int)(v3 + 92); + if ( *v3 > v3[92] ) + { + BubbleSwapItem((ItemStruct *)(v3 - 90), (ItemStruct *)(v3 + 2)); + v2 = 0; + } + --v4; + v3 = (int *)v5; + } + while ( v4 ); + } + --v0; + } +} + +//----- (00424C0C) -------------------------------------------------------- +void __fastcall SpawnHealer(int lvl) +{ + int v1; // ebx + int v2; // ecx + int v3; // eax + ItemStruct *v4; // ebp + int v5; // eax + int v6; // eax + int *v7; // eax + signed int v8; // [esp-4h] [ebp-20h] + short v9; // [esp+10h] [ebp-Ch] + int v10; // [esp+14h] [ebp-8h] + int v11; // [esp+18h] [ebp-4h] + + v1 = lvl; + GetItemAttrs(0, 24, 1); + qmemcpy(healitem, items, 0x170u); + healitem[0]._iCreateInfo = v1; + healitem[0]._iStatFlag = 1; + GetItemAttrs(0, 29, 1); + qmemcpy(&healitem[1], items, sizeof(ItemStruct)); + v2 = 0; + healitem[1]._iCreateInfo = v1; + healitem[1]._iStatFlag = 1; + if ( gbMaxPlayers == 1 ) + { + v8 = 2; + } + else + { + GetItemAttrs(0, 34, 1); + qmemcpy(&healitem[2], items, sizeof(ItemStruct)); + v2 = 0; + healitem[2]._iCreateInfo = v1; + healitem[2]._iStatFlag = 1; + v8 = 3; + } + _LOBYTE(v2) = 50; + v3 = random(v2, 8) + 10; + v11 = v3; + if ( v8 < v3 ) + { + _LOBYTE(v9) = v1; + v4 = &healitem[v8]; + v10 = v3 - v8; + do + { + items[0]._iSeed = GetRndSeed(); + SetRndSeed(items[0]._iSeed); + v5 = RndHealerItem(v1); + GetItemAttrs(0, v5 - 1, v1); + qmemcpy(v4, items, sizeof(ItemStruct)); + _HIBYTE(v9) = BYTE1(v1) | 0x40; + v4->_iCreateInfo = v9; + v4->_iIdentified = 1; + _LOBYTE(v6) = StoreStatOk(v4); + v4->_iStatFlag = v6; + ++v4; + --v10; + } + while ( v10 ); + v3 = v11; + } + if ( v3 < 20 ) + { + v7 = &healitem[v3]._itype; + do + { + *v7 = -1; + v7 += 92; + } + while ( (signed int)v7 < (signed int)&golditem._itype ); + } + SortHealer(); +} +// 679660: using guessed type char gbMaxPlayers; + +//----- (00424D57) -------------------------------------------------------- +void __cdecl SpawnStoreGold() +{ + GetItemAttrs(0, 0, 1); + qmemcpy(&golditem, items, sizeof(golditem)); + golditem._iStatFlag = 1; +} + +//----- (00424D80) -------------------------------------------------------- +void __fastcall RecreateSmithItem(int ii, int idx, int plvl, int iseed) +{ + int v4; // ebx + int v5; // eax + int v6; // eax + + v4 = ii; + SetRndSeed(iseed); + v5 = RndSmithItem(plvl); + GetItemAttrs(v4, v5 - 1, plvl); + v6 = v4; + items[v6]._iSeed = iseed; + items[v6]._iCreateInfo = plvl | 0x400; + items[v6]._iIdentified = 1; +} + +//----- (00424DD1) -------------------------------------------------------- +void __fastcall RecreatePremiumItem(int ii, int idx, int lvl, int iseed) +{ + int v4; // ebx + int v5; // edi + int v6; // eax + + v4 = ii; + SetRndSeed(iseed); + v5 = RndPremiumItem(lvl >> 2, lvl) - 1; + GetItemAttrs(v4, v5, lvl); + GetItemBonus(v4, v5, lvl >> 1, lvl, 1); + v6 = v4; + items[v6]._iCreateInfo = lvl | 0x800; + items[v6]._iSeed = iseed; + items[v6]._iIdentified = 1; +} + +//----- (00424E3C) -------------------------------------------------------- +void __fastcall RecreateBoyItem(int ii, int idx, int lvl, int iseed) +{ + int v4; // ebx + int v5; // edi + int v6; // eax + + v4 = ii; + SetRndSeed(iseed); + v5 = RndBoyItem(lvl) - 1; + GetItemAttrs(v4, v5, lvl); + GetItemBonus(v4, v5, lvl, 2 * lvl, 1); + v6 = v4; + items[v6]._iCreateInfo = lvl | 0x1000; + items[v6]._iSeed = iseed; + items[v6]._iIdentified = 1; +} + +//----- (00424EA1) -------------------------------------------------------- +void __fastcall RecreateWitchItem(int ii, int idx, int lvl, int iseed) +{ + int v4; // ebx + short v5; // si + int v6; // edi + int v7; // ecx + int v8; // eax + int v9; // eax + + v4 = ii; + if ( idx == 25 || idx == 30 || idx == 27 ) + { + v5 = lvl; + GetItemAttrs(ii, idx, lvl); + } + else + { + SetRndSeed(iseed); + v5 = lvl; + v6 = RndWitchItem(lvl) - 1; + GetItemAttrs(v4, v6, lvl); + _LOBYTE(v7) = 51; + if ( random(v7, 100) <= 5 && (v8 = 2 * lvl, 2 * lvl != -1) + || items[v4]._iMiscId == IMISC_STAFF && (v8 = 2 * lvl, 2 * lvl != -1) ) + { + GetItemBonus(v4, v6, v8 >> 1, v8, 1); + } + } + v9 = v4; + items[v9]._iCreateInfo = v5 | 0x2000; + items[v9]._iSeed = iseed; + items[v9]._iIdentified = 1; +} + +//----- (00424F52) -------------------------------------------------------- +void __fastcall RecreateHealerItem(int ii, int idx, int lvl, int iseed) +{ + int v4; // edi + int v5; // esi + int v6; // eax + + v4 = ii; + if ( idx == 24 || idx == 29 || idx == 34 ) + { + v5 = lvl; + } + else + { + SetRndSeed(iseed); + v5 = lvl; + idx = RndHealerItem(lvl) - 1; + } + GetItemAttrs(v4, idx, v5); + v6 = v4; + items[v6]._iCreateInfo = v5 | 0x4000; + items[v6]._iSeed = iseed; + items[v6]._iIdentified = 1; +} + +//----- (00424FB8) -------------------------------------------------------- +void __fastcall RecreateTownItem(int ii, int idx, unsigned short icreateinfo, int iseed, int ivalue) +{ + if ( icreateinfo & 0x400 ) + { + RecreateSmithItem(ii, idx, icreateinfo & 0x3F, iseed); + } + else if ( icreateinfo & 0x800 ) + { + RecreatePremiumItem(ii, idx, icreateinfo & 0x3F, iseed); + } + else if ( icreateinfo & 0x1000 ) + { + RecreateBoyItem(ii, idx, icreateinfo & 0x3F, iseed); + } + else if ( icreateinfo & 0x2000 ) + { + RecreateWitchItem(ii, idx, icreateinfo & 0x3F, iseed); + } + else if ( icreateinfo & 0x4000 ) + { + RecreateHealerItem(ii, idx, icreateinfo & 0x3F, iseed); + } +} + +//----- (0042501F) -------------------------------------------------------- +void __cdecl RecalcStoreStats() +{ + ItemStruct *v0; // esi + int v1; // eax + ItemStruct *v2; // esi + int v3; // eax + ItemStruct *v4; // esi + int v5; // eax + ItemStruct *v6; // esi + int v7; // eax + int v8; // eax + + v0 = smithitem; + do + { + if ( v0->_itype != -1 ) + { + _LOBYTE(v1) = StoreStatOk(v0); + v0->_iStatFlag = v1; + } + ++v0; + } + while ( (signed int)v0 < (signed int)&stextdown ); + v2 = premiumitem; + do + { + if ( v2->_itype != -1 ) + { + _LOBYTE(v3) = StoreStatOk(v2); + v2->_iStatFlag = v3; + } + ++v2; + } + while ( (signed int)v2 < (signed int)&pSTextBoxCels ); + v4 = witchitem; + do + { + if ( v4->_itype != -1 ) + { + _LOBYTE(v5) = StoreStatOk(v4); + v4->_iStatFlag = v5; + } + ++v4; + } + while ( (signed int)v4 < (signed int)&stextscrl ); + v6 = healitem; + do + { + if ( v6->_itype != -1 ) + { + _LOBYTE(v7) = StoreStatOk(v6); + v6->_iStatFlag = v7; + } + ++v6; + } + while ( (signed int)v6 < (signed int)&golditem ); + _LOBYTE(v8) = StoreStatOk(&boyitem); + boyitem._iStatFlag = v8; +} +// 6A6BB8: using guessed type int stextscrl; +// 6AA700: using guessed type int stextdown; + +//----- (004250C0) -------------------------------------------------------- +void __cdecl ItemNoFlippy() +{ + int v0; // ecx + int v1; // edx + + v0 = *(&dupe_delay + numitems); + v1 = items[v0]._iAnimLen; + items[v0]._iAnimFlag = 0; + items[v0]._iAnimFrame = v1; + items[v0]._iSelFlag = 1; +} + +//----- (004250EF) -------------------------------------------------------- +void __fastcall CreateSpellBook(int x, int y, int ispell, unsigned char sendmsg, int delta) +{ + int v5; // esi + int v6; // ebx + int v7; // edi + int v8; // esi + int v9; // ecx + int v10; // ST04_4 + int v11; // eax + int idx; // [esp+8h] [ebp-8h] + signed int v13; // [esp+Ch] [ebp-4h] + + v13 = 0; + v5 = y; + v6 = x; + idx = RndTypeItems(0, 24); + if ( numitems < 127 ) + { + v7 = itemavail[0]; + GetSuperItemSpace(v6, v5, itemavail[0]); + v8 = v7; + v9 = itemavail[-numitems + 126]; + itemactive[numitems] = v7; + itemavail[0] = v9; + do + { + v10 = 2 * currlevel; + v11 = GetRndSeed(); + SetupAllItems(v7, idx, v11, v10, 1, 1, 0, delta); + if ( items[v8]._iMiscId == IMISC_BOOK && items[v8]._iSpell == ispell ) + v13 = 1; + } + while ( !v13 ); + if ( sendmsg ) + NetSendCmdDItem(0, v7); + if ( delta ) + DeltaAddItem(v7); + ++numitems; + } +} + +//----- (004251B8) -------------------------------------------------------- +void __fastcall CreateMagicItem(int x, int y, int imisc, int icurs, int sendmsg, int delta) +{ + int v6; // esi + int *v7; // ecx + int i; // ebx + int v9; // ST04_4 + int v10; // eax + + if ( numitems < 127 ) + { + v6 = itemavail[0]; + GetSuperItemSpace(x, y, itemavail[0]); + v7 = &itemavail[-numitems + 126]; + itemactive[numitems] = v6; + itemavail[0] = *v7; + for ( i = RndTypeItems(imisc, 0); ; i = RndTypeItems(imisc, 0) ) + { + v9 = 2 * currlevel; + v10 = GetRndSeed(); + SetupAllItems(v6, i, v10, v9, 1, 1, 0, delta); + if ( items[v6]._iCurs == icurs ) + break; + } + if ( sendmsg ) + NetSendCmdDItem(0, v6); + if ( delta ) + DeltaAddItem(v6); + ++numitems; + } +} + +//----- (0042526E) -------------------------------------------------------- +int __fastcall GetItemRecord(int dwSeed, int CI, int indx) +{ + int v3; // edi + int *v4; // ebx + int v6; // [esp+Ch] [ebp-18h] + DWORD v7; // [esp+10h] [ebp-14h] + int *v8; // [esp+14h] [ebp-10h] + short *v9; // [esp+18h] [ebp-Ch] + ItemGetRecordStruct *v10; // [esp+1Ch] [ebp-8h] + short v11; // [esp+20h] [ebp-4h] + + v11 = CI; + v6 = dwSeed; + v3 = 0; + v7 = GetTickCount(); + if ( gnNumGetRecords <= 0 ) + return 1; + v8 = &itemrecords[0].nIndex; + v9 = &itemrecords[0].wCI; + v10 = itemrecords; + v4 = &itemrecords[0].dwTimestamp; + while ( v7 - *v4 > 0x1770 ) + { + NextItemRecord(v3); + --v10; + v9 -= 8; + --v3; + v4 -= 4; + v8 -= 4; +LABEL_8: + ++v10; + v9 += 8; + v8 += 4; + ++v3; + v4 += 4; + if ( v3 >= gnNumGetRecords ) + return 1; + } + if ( v6 != v10->nSeed || v11 != *v9 || indx != *v8 ) + goto LABEL_8; + return 0; +} + +//----- (00425311) -------------------------------------------------------- +void __fastcall NextItemRecord(int a1) +{ + int v1; // eax + int v2; // eax + int v3; // ecx + + v1 = gnNumGetRecords-- - 1; + if ( gnNumGetRecords ) + { + v2 = v1; + v3 = a1; + itemrecords[v3].nIndex = itemrecords[v2].nIndex; + itemrecords[v3].nSeed = itemrecords[v2].nSeed; + itemrecords[v3].wCI = itemrecords[v2].wCI; + itemrecords[v3].dwTimestamp = itemrecords[v2].dwTimestamp; + } +} + +//----- (00425357) -------------------------------------------------------- +void __fastcall SetItemRecord(int dwSeed, int CI, int indx) +{ + short v3; // si + int v4; // edi + int v5; // eax + int v6; // ecx + + v3 = CI; + v4 = dwSeed; + v5 = GetTickCount(); + if ( gnNumGetRecords != 127 ) + { + v6 = gnNumGetRecords++; + itemrecords[v6].dwTimestamp = v5; + itemrecords[v6].nSeed = v4; + itemrecords[v6].wCI = v3; + itemrecords[v6].nIndex = indx; + } +} + +//----- (0042539E) -------------------------------------------------------- +void __fastcall PutItemRecord(int seed, int ci, int index) +{ + int v3; // edi + int *v4; // ebx + int v5; // [esp+Ch] [ebp-18h] + DWORD v6; // [esp+10h] [ebp-14h] + int *v7; // [esp+14h] [ebp-10h] + short *v8; // [esp+18h] [ebp-Ch] + ItemGetRecordStruct *v9; // [esp+1Ch] [ebp-8h] + short v10; // [esp+20h] [ebp-4h] + + v10 = ci; + v5 = seed; + v3 = 0; + v6 = GetTickCount(); + if ( gnNumGetRecords > 0 ) + { + v7 = &itemrecords[0].nIndex; + v8 = &itemrecords[0].wCI; + v9 = itemrecords; + v4 = &itemrecords[0].dwTimestamp; + do + { + if ( v6 - *v4 <= 0x1770 ) + { + if ( v5 == v9->nSeed && v10 == *v8 && index == *v7 ) + { + NextItemRecord(v3); + return; + } + } + else + { + NextItemRecord(v3); + --v9; + v8 -= 8; + --v3; + v4 -= 4; + v7 -= 4; + } + ++v9; + v8 += 8; + v7 += 4; + ++v3; + v4 += 4; + } + while ( v3 < gnNumGetRecords ); + } +} + +//----- (00425443) -------------------------------------------------------- +void __fastcall SetLightFX(int x, int y, short s_r, short s_g, int s_b, int d_r, int d_g, int d_b) +{ + _DWORD *v8; // eax + int v9; // edx + _DWORD *v10; // [esp+Ch] [ebp-4h] + int s_ra; // [esp+18h] [ebp+8h] + + *(_DWORD *)d_g = 0; + *(_DWORD *)d_b = 0; + v8 = (_DWORD *)s_r; + v10 = (_DWORD *)y; + v9 = *(_DWORD *)s_r; + *(_DWORD *)s_r = 7 - *(_DWORD *)s_g; + *(_DWORD *)s_g = v9; + s_ra = *(_DWORD *)s_b; + *(_DWORD *)s_b = 7 - *(_DWORD *)d_r; + *(_DWORD *)d_r = s_ra; + *(_DWORD *)x = *v8 - *(_DWORD *)s_b; + *v10 = *(_DWORD *)s_g - *(_DWORD *)d_r; + if ( *(_DWORD *)x < 0 ) + { + *(_DWORD *)x += 8; + *(_DWORD *)d_g = 1; + } + if ( *v10 < 0 ) + { + *v10 += 8; + *(_DWORD *)d_b = 1; + } +} + +//----- (004254BA) -------------------------------------------------------- +void __fastcall DoLighting(int nXPos, int nYPos, int nRadius, int Lnum) +{ + int v4; // edi + int v5; // ebx + int v6; // ecx + int v7; // eax + int v8; // edx + int v9; // esi + int v10; // eax + char *v11; // edi + signed int v12; // ecx + int v13; // edx + _BYTE *v14; // ecx + int v15; // ebx + bool v16; // sf + unsigned char v17; // of + int v18; // esi + int v19; // ecx + char *v20; // edi + signed int v21; // eax + int v22; // edx + _BYTE *v23; // eax + int v24; // ebx + int v25; // eax + int v26; // esi + char *v27; // edi + signed int v28; // ecx + int v29; // edx + _BYTE *v30; // ecx + int v31; // ebx + signed int v32; // ebx + int v33; // ecx + char *v34; // esi + signed int v35; // eax + int v36; // edx + _BYTE *v37; // eax + int v38; // edi + short s_r[2]; // [esp+Ch] [ebp-44h] + short s_g[2]; // [esp+10h] [ebp-40h] + int s_b; // [esp+14h] [ebp-3Ch] + int d_r; // [esp+18h] [ebp-38h] + int v43; // [esp+1Ch] [ebp-34h] + int v44; // [esp+20h] [ebp-30h] + int v45; // [esp+24h] [ebp-2Ch] + int v46; // [esp+28h] [ebp-28h] + int v47; // [esp+2Ch] [ebp-24h] + int v48; // [esp+30h] [ebp-20h] + int d_g; // [esp+34h] [ebp-1Ch] + int d_b; // [esp+38h] [ebp-18h] + int v51; // [esp+3Ch] [ebp-14h] + int v52; // [esp+40h] [ebp-10h] + int y; // [esp+44h] [ebp-Ch] + int x; // [esp+48h] [ebp-8h] + int v55; // [esp+4Ch] [ebp-4h] + int Lnuma; // [esp+5Ch] [ebp+Ch] + int Lnumb; // [esp+5Ch] [ebp+Ch] + int Lnumc; // [esp+5Ch] [ebp+Ch] + int Lnumd; // [esp+5Ch] [ebp+Ch] + + v4 = nYPos; + v5 = nXPos; + v6 = 0; + v7 = 0; + v48 = nYPos; + v52 = v5; + x = 0; + y = 0; + s_b = 0; + d_r = 0; + d_g = 0; + d_b = 0; + if ( Lnum >= 0 ) + { + v7 = LightList[Lnum]._yoff; + x = LightList[Lnum]._xoff; + v6 = x; + y = v7; + if ( x < 0 ) + { + v6 = x + 8; + --v5; + x += 8; + v52 = v5; + } + if ( v7 < 0 ) + { + v7 += 8; + v4 = nYPos - 1; + y = v7; + v48 = nYPos - 1; + } + } + *(_DWORD *)s_r = v6; + *(_DWORD *)s_g = v7; + v8 = 15; + if ( v5 - 15 >= 0 ) + v44 = 15; + else + v44 = v5 + 1; + if ( v5 + 15 <= 112 ) + v46 = 15; + else + v46 = 112 - v5; + if ( v4 - 15 >= 0 ) + v43 = 15; + else + v43 = v4 + 1; + if ( v4 + 15 > 112 ) + v8 = 112 - v4; + v45 = v8; + if ( v5 >= 0 && v5 < 112 && v4 >= 0 && v4 < 112 ) + dTransVal[v5][v4] = 0; + v55 = 0; + v51 = v6 + 8 * v7; + if ( v43 > 0 ) + { + v47 = v4; + do + { + Lnuma = 1; + if ( v46 > 1 ) + { + v9 = v5 + 1; + v10 = 112 * (v5 + 1); + v11 = &dung_map_rgba[16 * (v55 + 16 * v51)]; + do + { + v12 = (unsigned char)v11[Lnuma]; + if ( v12 < 128 ) + { + v13 = (unsigned char)dung_map_radius[128 * nRadius + v12]; + if ( v9 >= 0 && v9 < 112 && v47 >= 0 && v47 < 112 ) + { + v14 = (unsigned char *)dTransVal + v47 + v10; + v15 = (char)*v14; + v17 = __OFSUB__(v13, v15); + v16 = v13 - v15 < 0; + v5 = v52; + if ( v16 ^ v17 ) + *v14 = v13; + } + } + ++Lnuma; + v10 += 112; + ++v9; + } + while ( Lnuma < v46 ); + v4 = v48; + } + ++v55; + ++v47; + } + while ( v55 < v43 ); + } + SetLightFX((int)&x, (int)&y, (unsigned int)s_r, (unsigned int)s_g, (int)&s_b, (int)&d_r, (int)&d_g, (int)&d_b); + v18 = 0; + v51 = x + 8 * y; + if ( v45 > 0 ) + { + v47 = 112 * v5; + do + { + Lnumb = 1; + if ( v46 > 1 ) + { + v19 = v4 - 1; + v20 = &dung_map_rgba[16 * (d_b + v18 + 16 * v51) + d_g]; + do + { + v21 = (unsigned char)v20[Lnumb]; + if ( v21 < 128 ) + { + v22 = (unsigned char)dung_map_radius[128 * nRadius + v21]; + if ( v18 + v5 >= 0 && v18 + v5 < 112 && v19 >= 0 && v19 < 112 ) + { + v23 = (unsigned char *)dTransVal + v47 + v19; + v24 = (char)*v23; + v17 = __OFSUB__(v22, v24); + v16 = v22 - v24 < 0; + v5 = v52; + if ( v16 ^ v17 ) + *v23 = v22; + } + } + ++Lnumb; + --v19; + } + while ( Lnumb < v46 ); + v4 = v48; + } + v47 += 112; + ++v18; + } + while ( v18 < v45 ); + } + SetLightFX((int)&x, (int)&y, (unsigned int)s_r, (unsigned int)s_g, (int)&s_b, (int)&d_r, (int)&d_g, (int)&d_b); + v55 = 0; + v51 = x + 8 * y; + if ( v45 > 0 ) + { + v46 = v4; + do + { + Lnumc = 1; + if ( v44 > 1 ) + { + v25 = 112 * v5 - 112; + v26 = v5 - 1; + v27 = &dung_map_rgba[16 * (d_b + v55 + 16 * v51) + d_g]; + do + { + v28 = (unsigned char)v27[Lnumc]; + if ( v28 < 128 ) + { + v29 = (unsigned char)dung_map_radius[128 * nRadius + v28]; + if ( v26 >= 0 && v26 < 112 && v46 >= 0 && v46 < 112 ) + { + v30 = (unsigned char *)dTransVal + v46 + v25; + v31 = (char)*v30; + v17 = __OFSUB__(v29, v31); + v16 = v29 - v31 < 0; + v5 = v52; + if ( v16 ^ v17 ) + *v30 = v29; + } + } + ++Lnumc; + v25 -= 112; + --v26; + } + while ( Lnumc < v44 ); + v4 = v48; + } + ++v55; + --v46; + } + while ( v55 < v45 ); + } + SetLightFX((int)&x, (int)&y, (unsigned int)s_r, (unsigned int)s_g, (int)&s_b, (int)&d_r, (int)&d_g, (int)&d_b); + v55 = 0; + v51 = x + 8 * y; + if ( v43 > 0 ) + { + Lnumd = v5; + *(_DWORD *)s_r = 112 * v5; + do + { + v32 = 1; + if ( v44 > 1 ) + { + v33 = v4 + 1; + v34 = &dung_map_rgba[16 * (d_b + v55 + 16 * v51) + d_g]; + do + { + v35 = (unsigned char)v34[v32]; + if ( v35 < 128 ) + { + v36 = (unsigned char)dung_map_radius[128 * nRadius + v35]; + if ( Lnumd >= 0 && Lnumd < 112 && v33 >= 0 && v33 < 112 ) + { + v37 = (unsigned char *)dTransVal + v33 + *(_DWORD *)s_r; + v38 = (char)*v37; + v17 = __OFSUB__(v36, v38); + v16 = v36 - v38 < 0; + v4 = v48; + if ( v16 ^ v17 ) + *v37 = v36; + } + } + ++v32; + ++v33; + } + while ( v32 < v44 ); + } + ++v55; + --Lnumd; + *(_DWORD *)s_r -= 112; + } + while ( v55 < v43 ); + } +} + +//----- (004258B0) -------------------------------------------------------- +void __fastcall DoUnLight(int nXPos, int nYPos, int nRadius) +{ + int v3; // ebx + int v4; // esi + int v5; // edx + int v6; // edi + signed int v7; // esi + int v8; // eax + int nRadiusa; // [esp+14h] [ebp+8h] + + v3 = nYPos + nRadius + 1; + v4 = nYPos - (nRadius + 1); + v5 = nXPos - (nRadius + 1); + v6 = nXPos + nRadius + 1; + if ( v4 < 0 ) + v4 = 0; + if ( v3 > 112 ) + v3 = 112; + if ( v5 < 0 ) + v5 = 0; + if ( v6 > 112 ) + v6 = 112; + for ( nRadiusa = v4; nRadiusa < v3; ++nRadiusa ) + { + v7 = v5; + if ( v5 < v6 ) + { + v8 = nRadiusa + 112 * v5; + do + { + if ( v7 >= 0 && v7 < 112 && nRadiusa >= 0 && nRadiusa < 112 ) + dTransVal[0][v8] = dTransVal2[0][v8]; + ++v7; + v8 += 112; + } + while ( v7 < v6 ); + } + } +} + +//----- (00425930) -------------------------------------------------------- +void __fastcall DoUnVision(int nXPos, int nYPos, int nRadius) +{ + int v3; // edi + int v4; // esi + int v5; // edx + int v6; // ecx + char *v7; // eax + int v8; // ecx + int i; // edx + + v3 = nYPos + nRadius + 1; + v4 = nYPos - (nRadius + 1); + v5 = nXPos - (nRadius + 1); + v6 = nRadius + 1 + nXPos; + if ( v4 < 0 ) + v4 = 0; + if ( v3 > 112 ) + v3 = 112; + if ( v5 < 0 ) + v5 = 0; + if ( v6 > 112 ) + v6 = 112; + if ( v5 < v6 ) + { + v7 = dFlags[v5]; + v8 = v6 - v5; + do + { + for ( i = v4; i < v3; ++i ) + v7[i] &= 0xBDu; + v7 += 112; + --v8; + } + while ( v8 ); + } +} + +//----- (0042598A) -------------------------------------------------------- +void __fastcall DoVision(int nXPos, int nYPos, int nRadius, unsigned char doautomap, int visible) +{ + char *v5; // esi + int v6; // esi + int v7; // edi + unsigned char *v8; // eax + int v9; // ebx + int v10; // ecx + unsigned char v11; // dl + int v12; // ecx + int v13; // ecx + unsigned char v14; // cl + unsigned char v15; // dl + int v16; // ecx + int v17; // ecx + int i; // [esp+Ch] [ebp-34h] + unsigned char *v19; // [esp+10h] [ebp-30h] + int v20; // [esp+14h] [ebp-2Ch] + int v21; // [esp+18h] [ebp-28h] + int v22; // [esp+1Ch] [ebp-24h] + signed int v23; // [esp+20h] [ebp-20h] + signed int v24; // [esp+24h] [ebp-1Ch] + signed int v25; // [esp+28h] [ebp-18h] + signed int v26; // [esp+2Ch] [ebp-14h] + signed int v27; // [esp+30h] [ebp-10h] + int v28; // [esp+34h] [ebp-Ch] + int v29; // [esp+38h] [ebp-8h] + unsigned char v30; // [esp+3Fh] [ebp-1h] + unsigned char v31; // [esp+3Fh] [ebp-1h] + + v28 = nYPos; + v29 = nXPos; + if ( nXPos >= 0 && nXPos <= 112 && nYPos >= 0 && nYPos <= 112 ) + { + if ( doautomap ) + { + v5 = &dFlags[nXPos][nYPos]; + if ( *v5 >= 0 ) + { + SetAutomapView(nXPos, nXPos); + nYPos = v28; + nXPos = v29; + } + *v5 |= 0x80u; + } + if ( visible ) + dFlags[nXPos][nYPos] |= 0x40u; + dFlags[nXPos][nYPos] |= 2u; + } + v27 = 0; + v6 = doautomap; + v7 = doautomap; + do + { + v20 = 0; + v8 = &vCrawlTable[0][1]; + v19 = &vCrawlTable[0][1]; + do + { + v9 = 0; + v21 = 0; + for ( i = 2 * (nRadius - RadiusAdj[21][v20 + 10]); v9 < i; v9 += 2 ) + { + if ( v21 ) + break; + v26 = 0; + v24 = 0; + v25 = 0; + v23 = 0; + if ( v27 ) + { + switch ( v27 ) + { + case 1: + v13 = v8[v9 - 1]; + v6 = v29 - (unsigned char)v13; + v31 = v8[v9]; + v7 = v28 - v31; + if ( (_BYTE)v13 && v31 ) + { + v25 = 1; + v24 = 1; + } + break; + case 2: + v12 = v8[v9 - 1]; + v30 = v8[v9]; + v6 = v29 + (unsigned char)v12; + v7 = v28 - v30; + if ( (_BYTE)v12 && v30 ) + { + v26 = -1; + v23 = 1; + } + break; + case 3: + v10 = v8[v9 - 1]; + v6 = v29 - (unsigned char)v10; + v11 = v8[v9]; + v7 = v28 + v11; + if ( (_BYTE)v10 ) + { + if ( v11 ) + { + v25 = -1; + v24 = 1; + } + } + break; + } + } + else + { + v14 = v8[v9 - 1]; + v15 = v8[v9]; + v6 = v29 + v14; + v7 = v28 + v15; + if ( v14 && v15 ) + { + v26 = -1; + v23 = -1; + } + } + if ( v6 >= 0 && v6 <= 112 && v7 >= 0 && v7 <= 112 ) + { + v22 = v7 + 112 * v6; + v21 = (unsigned char)nBlockTable[dPiece[0][v22]]; + if ( !nBlockTable[dPiece[0][v25 + v7 + 112 * (v6 + v26)]] + || !nBlockTable[dPiece[0][v23 + v7 + 112 * (v6 + v24)]] ) + { + v16 = v7 + 112 * v6; + if ( doautomap ) + { + if ( dFlags[0][v22] >= 0 ) + { + SetAutomapView(v6, v7); + v16 = v7 + 112 * v6; + v8 = v19; + } + dFlags[0][v16] |= 0x80u; + } + if ( visible ) + dFlags[0][v16] |= 0x40u; + dFlags[0][v16] |= 2u; + if ( !v21 ) + { + v17 = dung_map[0][v16]; + if ( v17 ) + TransList[v17] = 1; + } + } + } + } + ++v20; + v8 += 30; + v19 = v8; + } + while ( (signed int)v8 < (signed int)RadiusAdj ); + ++v27; + } + while ( v27 < 4 ); +} + +//----- (00425C13) -------------------------------------------------------- +void __cdecl FreeLightTable() +{ + void *v0; // ecx + + v0 = (void *)dword_646A20; + dword_646A20 = 0; + mem_free_dbg(v0); +} + +//----- (00425C25) -------------------------------------------------------- +void __cdecl InitLightTable() +{ + dword_646A20 = (int)DiabloAllocPtr(6912); +} + +//----- (00425C35) -------------------------------------------------------- +void __cdecl MakeLightTable() +{ + char *v0; // ebx + signed int v1; // esi + unsigned char v2; // al + unsigned char v3; // cl + signed int v4; // edi + int v5; // edx + signed int v6; // edi + unsigned char v7; // cl + unsigned char v8; // al + signed int v9; // edx + unsigned char v10; // cl + unsigned char v11; // al + char *v12; // ebx + _BYTE *v13; // ebx + int v14; // ecx + signed int v15; // esi + char v16; // al + int v17; // edx + int v18; // ebx + signed int v19; // esi + _BYTE *v20; // ebx + char *v21; // ebx + int v22; // edi + unsigned char *v23; // esi + signed int v24; // edx + unsigned char *v25; // esi + signed int v26; // edx + signed int v27; // ecx + char v28; // al + _BYTE *v29; // ebx + signed int v30; // edx + char v31; // al + signed int v32; // ecx + signed int v33; // ecx + char v34; // al + int v35; // eax + signed int v36; // esi + char *v37; // eax + signed int v38; // ebx + int v39; // esi + double v40; // st7 + double v41; // st6 + int v42; // ecx + char *v43; // ecx + bool v44; // zf + char v45; // [esp+14h] [ebp-2Ch] + int v46; // [esp+15h] [ebp-2Bh] + int v47; // [esp+19h] [ebp-27h] + int v48; // [esp+1Dh] [ebp-23h] + short v49; // [esp+21h] [ebp-1Fh] + char v50; // [esp+23h] [ebp-1Dh] + int v51; // [esp+24h] [ebp-1Ch] + int v52; // [esp+28h] [ebp-18h] + char *v53; // [esp+2Ch] [ebp-14h] + int v54; // [esp+30h] [ebp-10h] + int v55; // [esp+34h] [ebp-Ch] + int v56; // [esp+38h] [ebp-8h] + int v57; // [esp+3Ch] [ebp-4h] + + v56 = 0; + v0 = (char *)dword_646A20; + v1 = light4flag != 0 ? 3 : 15; + v55 = light4flag != 0 ? 3 : 15; + if ( v1 > 0 ) + { + v54 = light4flag != 0 ? 3 : 15; + do + { + *v0++ = 0; + v57 = 0; + do + { + v2 = 16 * v57 + 15; + v3 = v56 + 16 * v57; + v4 = 0; + do + { + if ( v4 || v57 ) + *v0++ = v3; + if ( v3 >= v2 ) + { + v2 = 0; + v3 = 0; + } + else + { + ++v3; + } + ++v4; + } + while ( v4 < 16 ); + ++v57; + } + while ( v57 < 8 ); + v57 = 16; + v5 = v56 >> 1; + do + { + v6 = 8; + v7 = v5 + 8 * v57; + v8 = 8 * v57 + 7; + do + { + *v0++ = v7; + if ( v7 >= v8 ) + { + v8 = 0; + v7 = 0; + } + else + { + ++v7; + } + --v6; + } + while ( v6 ); + ++v57; + } + while ( v57 < 20 ); + v57 = 10; + do + { + v9 = 16; + v10 = v56 + 16 * v57; + v11 = 16 * v57 + 15; + do + { + *v0++ = v10; + if ( v10 >= v11 ) + { + v11 = 0; + v10 = 0; + } + else + { + ++v10; + } + if ( v10 == -1 ) + { + v11 = 0; + v10 = 0; + } + --v9; + } + while ( v9 ); + ++v57; + } + while ( v57 < 16 ); + if ( light4flag ) + v56 += 5; + else + ++v56; + --v54; + } + while ( v54 ); + } + memset(v0, 0, 0x100u); + v12 = v0 + 256; + if ( leveltype == 4 ) + { + v13 = (_BYTE *)dword_646A20; + if ( v1 > 0 ) + { + v14 = v55; + v54 = v55; + do + { + v57 = 0; + v45 = 0; + v56 = v14; + v15 = 1; + v53 = (char *)(v55 / v14); + v52 = v55 % v14; + v16 = 1; + do + { + v17 = v56; + *(&v45 + v15) = v16; + v56 = v52 + v17; + if ( v52 + v17 > v14 && v15 < 15 ) + { + ++v15; + v56 -= v14; + *(&v45 + v15) = v16; + } + if ( (char *)++v57 == v53 ) + { + ++v16; + v57 = 0; + } + ++v15; + } + while ( v15 < 16 ); + *v13 = 0; + v18 = (int)(v13 + 1); + *(_DWORD *)v18 = v46; + *(_DWORD *)(v18 + 4) = v47; + *(_DWORD *)(v18 + 8) = v48; + *(_WORD *)(v18 + 12) = v49; + *(_BYTE *)(v18 + 14) = v50; + v19 = 15; + v20 = (_BYTE *)(v18 + 15); + do + *v20++ = *(&v45 + v19--); + while ( v19 > 0 ); + *v20 = 1; + v13 = v20 + 225; + --v14; + --v54; + } + while ( v54 ); + } + *v13 = 0; + v21 = (char *)v13 + 1; + memset(v21, 1u, 0x1Cu); + v22 = (int)(v21 + 28); + *(_WORD *)v22 = 257; + *(_BYTE *)(v22 + 2) = 1; + v12 = v21 + 255; + } + v23 = LoadFileInMem("PlrGFX\\Infra.TRN", 0); + v24 = 0; + do + *v12++ = v23[v24++]; + while ( v24 < 256 ); + mem_free_dbg(v23); + v25 = LoadFileInMem("PlrGFX\\Stone.TRN", 0); + v26 = 0; + do + *v12++ = v25[v26++]; + while ( v26 < 256 ); + mem_free_dbg(v25); + v27 = 0; + do + { + v28 = -30; + do + { + if ( v27 || v28 != -30 ) + *v12 = v28; + else + *v12 = 0; + ++v12; + ++v28; + } + while ( (unsigned char)v28 < 0xEFu ); + *v12 = 0; + v29 = (unsigned char *)v12 + 1; + *v29++ = 0; + *v29 = 0; + v12 = (char *)v29 + 1; + ++v27; + } + while ( v27 < 8 ); + v30 = 4; + do + { + v31 = -32; + v32 = 8; + do + { + *v12++ = v31; + v31 += 2; + --v32; + } + while ( v32 ); + --v30; + } + while ( v30 ); + v33 = 6; + do + { + v34 = -32; + do + *v12++ = v34++; + while ( (unsigned char)v34 < 0xEFu ); + *v12++ = 0; + --v33; + } + while ( v33 ); + v35 = 0; + v56 = (int)dung_map_radius; + v57 = 8; + do + { + v36 = 0; + v54 = 0; + v55 = v35 + 1; + do + { + if ( v36 <= v57 ) + *(_BYTE *)(v56 + v36) = (signed __int64)((double)v54 * 15.0 / ((double)v55 * 8.0) + 0.5); + else + *(_BYTE *)(v56 + v36) = 15; + v54 = ++v36; + } + while ( v36 < 128 ); + v57 += 8; + v56 += 128; + v35 = v55; + } + while ( v57 < 136 ); + v54 = 0; + v37 = dung_map_rgba; + do + { + v57 = 0; + do + { + v53 = v37; + v55 = v54; + v52 = 16; + do + { + v38 = 0; + v39 = v55 * v55; + v56 = v57; + do + { + v51 = v39 + v56 * v56; + v51 = (unsigned char)(signed __int64)sqrt((double)v51); + v40 = (double)v51; + if ( v40 >= 0.0 ) + v41 = 0.5; + else + v41 = -0.5; + v42 = (int)v53; + v56 += 8; + v53[v38++] = (signed __int64)(v41 + v40); + } + while ( v38 < 16 ); + v55 += 8; + v43 = (char *)(v42 + 16); + v44 = v52-- == 1; + v53 = v43; + } + while ( !v44 ); + --v57; + v37 = v43; + } + while ( v57 > -8 ); + --v54; + } + while ( (signed int)v43 < (signed int)&visionid ); +} +// 525728: using guessed type int light4flag; +// 5BB1ED: using guessed type char leveltype; + +//----- (00425FB8) -------------------------------------------------------- +void __cdecl InitLightMax() +{ + lightmax = light4flag == 0 ? 15 : 3; +} +// 525728: using guessed type int light4flag; +// 642A14: using guessed type char lightmax; + +//----- (00425FCE) -------------------------------------------------------- +void __cdecl InitLighting() +{ + signed int v0; // eax + + v0 = 0; + numlights = 0; + dword_642A18 = 0; + lightflag = 0; + do + { + lightactive[v0] = v0; + ++v0; + } + while ( v0 < 32 ); +} +// 642A18: using guessed type int dword_642A18; +// 646A28: using guessed type int lightflag; + +//----- (00425FEC) -------------------------------------------------------- +int __fastcall AddLight(int x, int y, int r) +{ + int result; // eax + int v4; // esi + + result = -1; + if ( !lightflag && numlights < 32 ) + { + result = (unsigned char)lightactive[numlights]; + dword_642A18 = 1; + ++numlights; + v4 = result; + LightList[v4]._lx = x; + LightList[v4]._ly = y; + LightList[v4]._lradius = r; + LightList[v4]._xoff = 0; + LightList[v4]._yoff = 0; + LightList[v4]._ldel = 0; + LightList[v4]._lunflag = 0; + } + return result; +} +// 642A18: using guessed type int dword_642A18; +// 646A28: using guessed type int lightflag; + +//----- (00426056) -------------------------------------------------------- +void __fastcall AddUnLight(int i) +{ + if ( !lightflag && i != -1 ) + { + LightList[i]._ldel = 1; + dword_642A18 = 1; + } +} +// 642A18: using guessed type int dword_642A18; +// 646A28: using guessed type int lightflag; + +//----- (00426076) -------------------------------------------------------- +void __fastcall ChangeLightRadius(int i, int r) +{ + int v2; // eax + int v3; // edi + + if ( !lightflag && i != -1 ) + { + v2 = i; + LightList[v2]._lunx = LightList[v2]._lx; + LightList[v2]._luny = LightList[v2]._ly; + v3 = LightList[i]._lradius; + LightList[v2]._lunflag = 1; + LightList[v2]._lunr = v3; + dword_642A18 = 1; + LightList[v2]._lradius = r; + } +} +// 642A18: using guessed type int dword_642A18; +// 646A28: using guessed type int lightflag; + +//----- (004260C5) -------------------------------------------------------- +void __fastcall ChangeLightXY(int i, int x, int y) +{ + int v3; // eax + + if ( !lightflag && i != -1 ) + { + v3 = i; + LightList[v3]._lunx = LightList[v3]._lx; + LightList[v3]._lunflag = 1; + dword_642A18 = 1; + LightList[v3]._luny = LightList[v3]._ly; + LightList[v3]._lunr = LightList[v3]._lradius; + LightList[i]._ly = y; + LightList[i]._lx = x; + } +} +// 642A18: using guessed type int dword_642A18; +// 646A28: using guessed type int lightflag; + +//----- (00426120) -------------------------------------------------------- +void __fastcall ChangeLightOff(int i, int x, int y) +{ + int v3; // eax + int v4; // esi + + if ( !lightflag && i != -1 ) + { + v3 = i; + v4 = LightList[i]._lx; + LightList[v3]._xoff = x; + LightList[v3]._lunx = v4; + LightList[v3]._luny = LightList[v3]._ly; + LightList[v3]._lunr = LightList[v3]._lradius; + LightList[v3]._lunflag = 1; + LightList[v3]._yoff = y; + dword_642A18 = 1; + } +} +// 642A18: using guessed type int dword_642A18; +// 646A28: using guessed type int lightflag; + +//----- (0042617B) -------------------------------------------------------- +void __fastcall ChangeLight(int i, int x, int y, int r) +{ + int v4; // eax + + if ( !lightflag && i != -1 ) + { + v4 = i; + LightList[v4]._lunx = LightList[v4]._lx; + LightList[v4]._luny = LightList[v4]._ly; + LightList[v4]._lunr = LightList[v4]._lradius; + LightList[v4]._lunflag = 1; + LightList[v4]._lx = x; + LightList[v4]._ly = y; + LightList[i]._lradius = r; + dword_642A18 = 1; + } +} +// 642A18: using guessed type int dword_642A18; +// 646A28: using guessed type int lightflag; + +//----- (004261E7) -------------------------------------------------------- +void __cdecl ProcessLightList() +{ + int v0; // ebp + int v1; // edi + int v2; // esi + int i; // esi + int v4; // eax + int v5; // ecx + unsigned char v6; // bl + char v7; // dl + + v0 = 0; + if ( !lightflag ) + { + if ( dword_642A18 ) + { + v1 = numlights; + if ( numlights > 0 ) + { + do + { + v2 = (unsigned char)lightactive[v0]; + if ( LightList[v2]._ldel ) + DoUnLight(LightList[v2]._lx, LightList[v2]._ly, LightList[v2]._lradius); + if ( LightList[v2]._lunflag ) + { + DoUnLight(LightList[v2]._lunx, LightList[v2]._luny, LightList[v2]._lunr); + LightList[v2]._lunflag = 0; + } + ++v0; + } + while ( v0 < v1 ); + } + for ( i = 0; i < v1; ++i ) + { + v4 = (unsigned char)lightactive[i]; + if ( !LightList[v4]._ldel ) + DoLighting( + LightList[v4]._lx, + LightList[v4]._ly, + LightList[v4]._lradius, + (unsigned char)lightactive[i]); + } + v5 = 0; + if ( v1 > 0 ) + { + do + { + v6 = lightactive[v5]; + if ( LightList[v6]._ldel ) + { + v7 = lightactive[--v1]; + lightactive[v1] = v6; + lightactive[v5] = v7; + } + else + { + ++v5; + } + } + while ( v5 < v1 ); + numlights = v1; + } + } + dword_642A18 = 0; + } +} +// 642A18: using guessed type int dword_642A18; +// 646A28: using guessed type int lightflag; + +//----- (004262E0) -------------------------------------------------------- +void __cdecl SavePreLighting() +{ + memcpy(dTransVal2, dTransVal, 0x3100u); +} + +//----- (004262F8) -------------------------------------------------------- +void __cdecl InitVision() +{ + numvision = 0; + dovision = 0; + visionid = 1; + if ( TransVal > 0 ) + memset(TransList, 0, TransVal); +} +// 5A5590: using guessed type char TransVal; +// 642A0C: using guessed type int dovision; + +//----- (00426333) -------------------------------------------------------- +int __fastcall AddVision(int x, int y, int r, unsigned char mine) +{ + int result; // eax + int v5; // esi + + result = r; + if ( numvision < 32 ) + { + v5 = numvision; + dovision = 1; + VisionList[v5]._lx = x; + VisionList[v5]._ly = y; + VisionList[v5]._lradius = r; + result = visionid++; + VisionList[v5]._lid = result; + VisionList[v5]._ldel = 0; + ++numvision; + VisionList[v5]._lunflag = 0; + VisionList[v5]._lflags = mine != 0; + } + return result; +} +// 642A0C: using guessed type int dovision; + +//----- (004263A0) -------------------------------------------------------- +void __fastcall ChangeVisionRadius(int id, int r) +{ + int v2; // esi + int *v3; // eax + int v4; // ebx + + v2 = numvision; + if ( numvision > 0 ) + { + v3 = &VisionList[0]._lunflag; + do + { + if ( *(v3 - 2) == id ) + { + v4 = *(v3 - 5); + *v3 = 1; + v3[2] = v4; + v3[3] = *(v3 - 4); + v3[4] = *(v3 - 3); + *(v3 - 3) = r; + dovision = 1; + } + v3 += 13; + --v2; + } + while ( v2 ); + } +} +// 642A0C: using guessed type int dovision; + +//----- (004263E1) -------------------------------------------------------- +void __fastcall ChangeVisionXY(int id, int x, int y) +{ + int v3; // esi + int *v4; // eax + int v5; // ebx + + v3 = numvision; + if ( numvision > 0 ) + { + v4 = &VisionList[0]._lunflag; + do + { + if ( *(v4 - 2) == id ) + { + v5 = *(v4 - 5); + *v4 = 1; + v4[2] = v5; + v4[3] = *(v4 - 4); + v4[4] = *(v4 - 3); + *(v4 - 5) = x; + *(v4 - 4) = y; + dovision = 1; + } + v4 += 13; + --v3; + } + while ( v3 ); + } +} +// 642A0C: using guessed type int dovision; + +//----- (0042642B) -------------------------------------------------------- +void __cdecl ProcessVisionList() +{ + int v0; // ebx + int *v1; // esi + int v2; // edi + int v3; // edi + int *v4; // esi + signed int v5; // ecx + int v6; // ebp + LightListStruct *v7; // edx + LightListStruct *v8; // eax + + if ( dovision ) + { + v0 = numvision; + if ( numvision > 0 ) + { + v1 = &VisionList[0]._lradius; + v2 = numvision; + do + { + if ( v1[2] ) + DoUnVision(*(v1 - 2), *(v1 - 1), *v1); + if ( v1[3] ) + { + DoUnVision(v1[5], v1[6], v1[7]); + v1[3] = 0; + } + v1 += 13; + --v2; + } + while ( v2 ); + } + if ( TransVal > 0 ) + memset(TransList, 0, TransVal); + v3 = 0; + if ( v0 > 0 ) + { + v4 = &VisionList[0]._lflags; + do + { + if ( !*(v4 - 8) ) + { + DoVision(*(v4 - 12), *(v4 - 11), *(v4 - 10), *(_BYTE *)v4 & 1, *v4 & 1); + v0 = numvision; + } + ++v3; + v4 += 13; + } + while ( v3 < v0 ); + } + do + { + v5 = 0; + v6 = 0; + if ( v0 <= 0 ) + break; + v7 = VisionList; + v8 = &VisionList[v0]; + do + { + if ( v7->_ldel ) + { + --v0; + --v8; + if ( v0 > 0 && v6 != v0 ) + qmemcpy(v7, v8, sizeof(LightListStruct)); + v5 = 1; + } + ++v6; + ++v7; + } + while ( v6 < v0 ); + } + while ( v5 ); + numvision = v0; + } + dovision = 0; +} +// 5A5590: using guessed type char TransVal; +// 642A0C: using guessed type int dovision; + +//----- (0042651F) -------------------------------------------------------- +void __cdecl lighting_color_cycling() +{ + int v0; // eax + signed int v1; // ebx + char *v2; // eax + char *v3; // edi + char v4; // dl + const void *v5; // esi + + if ( leveltype == 4 ) + { + v0 = dword_646A20; + if ( (light4flag != 0 ? 4 : 16) > 0 ) + { + v1 = light4flag != 0 ? 4 : 16; + do + { + v2 = (char *)(v0 + 1); + v3 = v2; + v4 = *v2; + v5 = v2 + 1; + v2 += 30; + qmemcpy(v3, v5, 0x1Eu); + *v2 = v4; + v0 = (int)(v2 + 225); + --v1; + } + while ( v1 ); + } + } +} +// 525728: using guessed type int light4flag; +// 5BB1ED: using guessed type char leveltype; + +//----- (00426564) -------------------------------------------------------- +void __fastcall LoadGame(void *a1) +{ + int v1; // esi + int v2; // edi + int v3; // eax + int v4; // eax + int v5; // ebx + int v6; // eax + int v7; // eax + int v8; // ecx + bool v9; // sf + unsigned char v10; // of + int *v11; // esi + int *v12; // esi + int i; // esi + int *v14; // esi + int *v15; // esi + int j; // esi + int *v17; // esi + int *v18; // esi + int k; // esi + int l; // esi + signed int v21; // esi + int m; // esi + int v23; // esi + int *v24; // esi + int *v25; // esi + int n; // esi + int *v27; // esi + int v28; // eax + char *v29; // edi + char *v30; // edi + char *v31; // edi + char *v32; // edi + int (*v33)[112]; // ebx + _DWORD *v34; // edi + char *v35; // edi + char *v36; // edi + char *v37; // edi + char *v38; // edi + signed int v39; // ebx + bool *v40; // edi + char *v41; // edi + int v42; // esi + int v43; // eax + char dst; // [esp+0h] [ebp-120h] + int len; // [esp+104h] [ebp-1Ch] + int v46; // [esp+108h] [ebp-18h] + int v47; // [esp+10Ch] [ebp-14h] + void *ptr; // [esp+110h] [ebp-10h] + int v49; // [esp+114h] [ebp-Ch] + bool from_save[4]; // [esp+118h] [ebp-8h] + int quest_num; // [esp+11Ch] [ebp-4h] + + *(_DWORD *)from_save = (unsigned int)a1; + FreeGameMem(); + pfile_remove_temp_files(); + pfile_get_game_name(&dst); + ptr = pfile_read(&dst, &len); + tbuff = ptr; + if ( ILoad_2() != 'RETL' ) + TermMsg("Invalid save file"); + setlevel = OLoad(); + setlvlnum = ILoad(); + currlevel = ILoad(); + leveltype = ILoad(); + v1 = ILoad(); + v2 = ILoad(); + _LOBYTE(v3) = OLoad(); + invflag = v3; + _LOBYTE(v4) = OLoad(); + chrflag = v4; + v5 = ILoad(); + v47 = ILoad(); + v49 = ILoad(); + v6 = ILoad(); + quest_num = 0; + v46 = v6; + do + { + *(int *)((char *)glSeedTbl + quest_num) = ILoad_2(); + v7 = ILoad(); + v8 = quest_num; + quest_num += 4; + v10 = __OFSUB__(quest_num, 68); + v9 = quest_num - 68 < 0; + *(int *)((char *)gnLevelTypeTbl + v8) = v7; + } + while ( v9 ^ v10 ); + LoadPlayer(myplr); + quest_num = 0; + do + LoadQuest(quest_num++); + while ( quest_num < 16 ); + quest_num = 0; + do + LoadPortal(quest_num++); + while ( quest_num < 4 ); + LoadGameLevel(from_save[0], 4); + SyncInitPlr(myplr); + SyncPlrAnim(myplr); + ViewX = v1; + numitems = v47; + nummissiles = v49; + ViewY = v2; + nummonsters = v5; + nobjects = v46; + v11 = monstkills; + do + { + *v11 = ILoad_2(); + ++v11; + } + while ( (signed int)v11 < (signed int)monstactive ); + if ( leveltype ) + { + v12 = monstactive; + do + { + *v12 = ILoad(); + ++v12; + } + while ( (signed int)v12 < (signed int)&nummonsters ); + for ( i = 0; i < nummonsters; ++i ) + LoadMonster(monstactive[i]); + v14 = missileactive; + do + { + *v14 = BLoad(); + ++v14; + } + while ( (signed int)v14 < (signed int)missileavail ); + v15 = missileavail; + do + { + *v15 = BLoad(); + ++v15; + } + while ( (signed int)v15 < (signed int)missile ); + for ( j = 0; j < nummissiles; ++j ) + LoadMissile(missileactive[j]); + v17 = objectactive; + do + { + *v17 = BLoad(); + ++v17; + } + while ( (signed int)v17 < (signed int)&nobjects ); + v18 = objectavail; + do + { + *v18 = BLoad(); + ++v18; + } + while ( (signed int)v18 < (signed int)object ); + for ( k = 0; k < nobjects; ++k ) + LoadObject(objectactive[k]); + for ( l = 0; l < nobjects; ++l ) + SyncObjectAnim(objectactive[l]); + numlights = ILoad(); + v21 = 0; + do + lightactive[v21++] = BLoad(); + while ( v21 < 32 ); + for ( m = 0; m < numlights; ++m ) + LoadLighting((unsigned char)lightactive[m]); + visionid = ILoad(); + v23 = 0; + numvision = ILoad(); + if ( numvision > 0 ) + { + do + LoadVision(v23++); + while ( v23 < numvision ); + } + } + v24 = itemactive; + do + { + *v24 = BLoad(); + ++v24; + } + while ( (signed int)v24 < (signed int)&uitemflag ); + v25 = itemavail; + do + { + *v25 = BLoad(); + ++v25; + } + while ( (signed int)v25 < (signed int)&itemavail[127] ); + for ( n = 0; n < numitems; ++n ) + LoadItem(itemactive[n]); + v27 = UniqueItemFlag; + do + { + _LOBYTE(v28) = OLoad(); + *v27 = v28; + ++v27; + } + while ( (signed int)v27 < (signed int)&numitems ); + quest_num = 0; + do + { + *(_DWORD *)from_save = 112; + v29 = (char *)dTransVal + quest_num; + do + { + *v29 = BLoad(); + v29 += 112; + --*(_DWORD *)from_save; + } + while ( *(_DWORD *)from_save ); + ++quest_num; + } + while ( quest_num < 112 ); + quest_num = 0; + do + { + *(_DWORD *)from_save = 112; + v30 = (char *)dFlags + quest_num; + do + { + *v30 = BLoad(); + v30 += 112; + --*(_DWORD *)from_save; + } + while ( *(_DWORD *)from_save ); + ++quest_num; + } + while ( quest_num < 112 ); + quest_num = 0; + do + { + *(_DWORD *)from_save = 112; + v31 = (char *)dPlayer + quest_num; + do + { + *v31 = BLoad(); + v31 += 112; + --*(_DWORD *)from_save; + } + while ( *(_DWORD *)from_save ); + ++quest_num; + } + while ( quest_num < 112 ); + quest_num = 0; + do + { + *(_DWORD *)from_save = 112; + v32 = (char *)dItem + quest_num; + do + { + *v32 = BLoad(); + v32 += 112; + --*(_DWORD *)from_save; + } + while ( *(_DWORD *)from_save ); + ++quest_num; + } + while ( quest_num < 112 ); + if ( leveltype ) + { + v33 = dMonster; + do + { + v34 = (unsigned int *)v33; + *(_DWORD *)from_save = 112; + do + { + *v34 = ILoad(); + v34 += 112; + --*(_DWORD *)from_save; + } + while ( *(_DWORD *)from_save ); + v33 = (int (*)[112])((char *)v33 + 4); + } + while ( (signed int)v33 < (signed int)dMonster[1] ); + quest_num = 0; + do + { + *(_DWORD *)from_save = 112; + v35 = (char *)dDead + quest_num; + do + { + *v35 = BLoad(); + v35 += 112; + --*(_DWORD *)from_save; + } + while ( *(_DWORD *)from_save ); + ++quest_num; + } + while ( quest_num < 112 ); + quest_num = 0; + do + { + *(_DWORD *)from_save = 112; + v36 = (char *)dObject + quest_num; + do + { + *v36 = BLoad(); + v36 += 112; + --*(_DWORD *)from_save; + } + while ( *(_DWORD *)from_save ); + ++quest_num; + } + while ( quest_num < 112 ); + quest_num = 0; + do + { + *(_DWORD *)from_save = 112; + v37 = (char *)dTransVal + quest_num; + do + { + *v37 = BLoad(); + v37 += 112; + --*(_DWORD *)from_save; + } + while ( *(_DWORD *)from_save ); + ++quest_num; + } + while ( quest_num < 112 ); + quest_num = 0; + do + { + *(_DWORD *)from_save = 112; + v38 = (char *)dTransVal2 + quest_num; + do + { + *v38 = BLoad(); + v38 += 112; + --*(_DWORD *)from_save; + } + while ( *(_DWORD *)from_save ); + ++quest_num; + } + while ( quest_num < 112 ); + v39 = 0; + do + { + v40 = (bool *)automapview + v39; + *(_DWORD *)from_save = 40; + do + { + *v40 = OLoad(); + v40 += 40; + --*(_DWORD *)from_save; + } + while ( *(_DWORD *)from_save ); + ++v39; + } + while ( v39 < 40 ); + quest_num = 0; + do + { + *(_DWORD *)from_save = 112; + v41 = (char *)dMissile + quest_num; + do + { + *v41 = BLoad(); + v41 += 112; + --*(_DWORD *)from_save; + } + while ( *(_DWORD *)from_save ); + ++quest_num; + } + while ( quest_num < 112 ); + } + numpremium = ILoad(); + premiumlevel = ILoad(); + v42 = 0; + do + LoadPremium(v42++); + while ( v42 < 6 ); + _LOBYTE(v43) = OLoad(); + *(_DWORD *)&automapflag = v43; + AutoMapScale = ILoad(); + mem_free_dbg(ptr); + AutomapZoomReset(); + ResyncQuests(); + if ( leveltype ) + ProcessLightList(); + RedoPlayerVision(); + ProcessVisionList(); + missiles_process_charge(); + ResetPal(); + SetCursor(1); + gbProcessPlayers = 1; +} +// 5256A0: using guessed type int gbProcessPlayers; +// 5BB1ED: using guessed type char leveltype; +// 5CCB10: using guessed type char setlvlnum; +// 5CF31D: using guessed type char setlevel; + +//----- (00426AE2) -------------------------------------------------------- +char __cdecl BLoad() +{ + char result; // al + + result = *(_BYTE *)tbuff; + tbuff = (char *)tbuff + 1; + return result; +} + +//----- (00426AF0) -------------------------------------------------------- +int __cdecl ILoad() +{ + int v0; // eax + int v1; // eax + unsigned short v2; // dx + int result; // eax + + v0 = *(unsigned char *)tbuff << 24; + tbuff = (char *)tbuff + 1; + v1 = (*(unsigned char *)tbuff << 16) | v0; + _LOBYTE(v2) = 0; + tbuff = (char *)tbuff + 1; + _HIBYTE(v2) = *(_BYTE *)tbuff; + tbuff = (char *)tbuff + 1; + result = *(unsigned char *)tbuff | v2 | v1; + tbuff = (char *)tbuff + 1; + return result; +} + +//----- (00426B2C) -------------------------------------------------------- +int __cdecl ILoad_2() +{ + int v0; // eax + int v1; // eax + unsigned short v2; // dx + int result; // eax + + v0 = *(unsigned char *)tbuff << 24; + tbuff = (char *)tbuff + 1; + v1 = (*(unsigned char *)tbuff << 16) | v0; + _LOBYTE(v2) = 0; + tbuff = (char *)tbuff + 1; + _HIBYTE(v2) = *(_BYTE *)tbuff; + tbuff = (char *)tbuff + 1; + result = *(unsigned char *)tbuff | v2 | v1; + tbuff = (char *)tbuff + 1; + return result; +} + +//----- (00426B68) -------------------------------------------------------- +bool __cdecl OLoad() +{ + char v0; // cl + bool result; // al + + v0 = *(_BYTE *)tbuff; + tbuff = (char *)tbuff + 1; + result = 1; + if ( v0 != 1 ) + result = 0; + return result; +} + +//----- (00426B7F) -------------------------------------------------------- +void __fastcall LoadPlayer(int player_num) +{ + memcpy(&plr[player_num], tbuff, 0x54B0u); + tbuff = (char *)tbuff + 21680; +} + +//----- (00426BA9) -------------------------------------------------------- +void __fastcall LoadMonster(int monster_num) +{ + int v1; // edi + + v1 = monster_num; + memcpy(&monster[monster_num], tbuff, 0xD8u); + tbuff = (char *)tbuff + 216; + SyncMonsterAnim(v1); +} + +//----- (00426BDE) -------------------------------------------------------- +void __fastcall LoadMissile(int missile_num) +{ + memcpy(&missile[missile_num], tbuff, 0xB0u); + tbuff = (char *)tbuff + 176; +} + +//----- (00426C08) -------------------------------------------------------- +void __fastcall LoadObject(int object_num) +{ + memcpy(&object[object_num], tbuff, 0x78u); + tbuff = (char *)tbuff + 120; +} + +//----- (00426C2A) -------------------------------------------------------- +void __fastcall LoadItem(int item_num) +{ + int v1; // edi + + v1 = item_num; + memcpy(&items[item_num], tbuff, 0x170u); + tbuff = (char *)tbuff + 368; + items_get_drop_cel(v1); +} + +//----- (00426C5F) -------------------------------------------------------- +void __fastcall LoadPremium(int griswold_premium_item_num) +{ + memcpy(&premiumitem[griswold_premium_item_num], tbuff, 0x170u); + tbuff = (char *)tbuff + 368; +} + +//----- (00426C89) -------------------------------------------------------- +void __fastcall LoadQuest(int i) +{ + memcpy(&quests[i], tbuff, 0x18u); + tbuff = (char *)tbuff + 24; + ReturnLvlX = ILoad(); + ReturnLvlY = ILoad(); + ReturnLvl = ILoad(); + ReturnLvlT = ILoad(); + dword_525760 = ILoad(); +} + +//----- (00426CDE) -------------------------------------------------------- +void __fastcall LoadLighting(int light_num) +{ + memcpy(&LightList[light_num], tbuff, 0x34u); + tbuff = (char *)tbuff + 52; +} + +//----- (00426D00) -------------------------------------------------------- +void __fastcall LoadVision(int vision_num) +{ + memcpy(&VisionList[vision_num], tbuff, 0x34u); + tbuff = (char *)tbuff + 52; +} + +//----- (00426D22) -------------------------------------------------------- +void __fastcall LoadPortal(int portal_num) +{ + memcpy(&portal[portal_num], tbuff, 0x18u); + tbuff = (char *)tbuff + 24; +} + +//----- (00426D45) -------------------------------------------------------- +void __cdecl SaveGame() +{ + int v0; // eax + signed int v1; // ebx + signed int v2; // esi + int v3; // esi + int v4; // esi + int *v5; // esi + int *v6; // esi + int i; // esi + int *v8; // esi + int *v9; // esi + int j; // esi + int *v11; // esi + int *v12; // esi + int k; // esi + signed int v14; // esi + int l; // esi + int m; // esi + int *v17; // esi + int *v18; // esi + int n; // esi + int *v20; // esi + char *v21; // edi + signed int v22; // ebx + _BYTE *v23; // edi + signed int v24; // ebx + char *v25; // edi + signed int v26; // ebx + char *v27; // edi + int (*v28)[112]; // ebx + int *v29; // edi + signed int v30; // ebx + char *v31; // edi + signed int v32; // ebx + char *v33; // edi + signed int v34; // ebx + char *v35; // edi + signed int v36; // ebx + char *v37; // edi + signed int v38; // ebx + unsigned char *v39; // edi + signed int v40; // ebx + char *v41; // edi + int v42; // esi + void *v43; // esi + int v44; // eax + char v45[260]; // [esp+Ch] [ebp-10Ch] + void *ptr; // [esp+110h] [ebp-8h] + int v47; // [esp+114h] [ebp-4h] + + v0 = codec_get_encoded_len(262147); + ptr = DiabloAllocPtr(v0); + tbuff = ptr; + ISave_2('RETL'); + OSave(setlevel); + ISave((unsigned char)setlvlnum); + ISave(currlevel); + ISave((unsigned char)leveltype); + ISave(ViewX); + ISave(ViewY); + OSave(invflag); + OSave(chrflag); + ISave(nummonsters); + ISave(numitems); + ISave(nummissiles); + ISave(nobjects); + v1 = 0; + v2 = 0; + do + { + ISave_2(glSeedTbl[v2]); + ISave(gnLevelTypeTbl[v2]); + ++v2; + } + while ( v2 < 17 ); + SavePlayer(myplr); + v3 = 0; + do + SaveQuest(v3++); + while ( v3 < 16 ); + v4 = 0; + do + SavePortal(v4++); + while ( v4 < 4 ); + v5 = monstkills; + do + { + ISave_2(*v5); + ++v5; + } + while ( (signed int)v5 < (signed int)monstactive ); + if ( leveltype ) + { + v6 = monstactive; + do + { + ISave(*v6); + ++v6; + } + while ( (signed int)v6 < (signed int)&nummonsters ); + for ( i = 0; i < nummonsters; ++i ) + SaveMonster(monstactive[i]); + v8 = missileactive; + do + { + BSave(*(_BYTE *)v8); + ++v8; + } + while ( (signed int)v8 < (signed int)missileavail ); + v9 = missileavail; + do + { + BSave(*(_BYTE *)v9); + ++v9; + } + while ( (signed int)v9 < (signed int)missile ); + for ( j = 0; j < nummissiles; ++j ) + SaveMissile(missileactive[j]); + v11 = objectactive; + do + { + BSave(*(_BYTE *)v11); + ++v11; + } + while ( (signed int)v11 < (signed int)&nobjects ); + v12 = objectavail; + do + { + BSave(*(_BYTE *)v12); + ++v12; + } + while ( (signed int)v12 < (signed int)object ); + for ( k = 0; k < nobjects; ++k ) + SaveObject(objectactive[k]); + ISave(numlights); + v14 = 0; + do + BSave(lightactive[v14++]); + while ( v14 < 32 ); + for ( l = 0; l < numlights; ++l ) + SaveLighting((unsigned char)lightactive[l]); + ISave(visionid); + ISave(numvision); + for ( m = 0; m < numvision; ++m ) + SaveVision(m); + } + v17 = itemactive; + do + { + BSave(*(_BYTE *)v17); + ++v17; + } + while ( (signed int)v17 < (signed int)&uitemflag ); + v18 = itemavail; + do + { + BSave(*(_BYTE *)v18); + ++v18; + } + while ( (signed int)v18 < (signed int)&itemavail[127] ); + for ( n = 0; n < numitems; ++n ) + SaveItem(itemactive[n]); + v20 = UniqueItemFlag; + do + { + OSave(*v20); + ++v20; + } + while ( (signed int)v20 < (signed int)&numitems ); + do + { + v21 = (char *)dTransVal + v1; + v47 = 112; + do + { + BSave(*v21); + v21 += 112; + --v47; + } + while ( v47 ); + ++v1; + } + while ( v1 < 112 ); + v22 = 0; + do + { + v23 = (unsigned char *)dFlags + v22; + v47 = 112; + do + { + BSave(*v23 & 0xF8); + v23 += 112; + --v47; + } + while ( v47 ); + ++v22; + } + while ( v22 < 112 ); + v24 = 0; + do + { + v25 = (char *)dPlayer + v24; + v47 = 112; + do + { + BSave(*v25); + v25 += 112; + --v47; + } + while ( v47 ); + ++v24; + } + while ( v24 < 112 ); + v26 = 0; + do + { + v27 = (char *)dItem + v26; + v47 = 112; + do + { + BSave(*v27); + v27 += 112; + --v47; + } + while ( v47 ); + ++v26; + } + while ( v26 < 112 ); + if ( leveltype ) + { + v28 = dMonster; + do + { + v29 = (int *)v28; + v47 = 112; + do + { + ISave(*v29); + v29 += 112; + --v47; + } + while ( v47 ); + v28 = (int (*)[112])((char *)v28 + 4); + } + while ( (signed int)v28 < (signed int)dMonster[1] ); + v30 = 0; + do + { + v31 = (char *)dDead + v30; + v47 = 112; + do + { + BSave(*v31); + v31 += 112; + --v47; + } + while ( v47 ); + ++v30; + } + while ( v30 < 112 ); + v32 = 0; + do + { + v33 = (char *)dObject + v32; + v47 = 112; + do + { + BSave(*v33); + v33 += 112; + --v47; + } + while ( v47 ); + ++v32; + } + while ( v32 < 112 ); + v34 = 0; + do + { + v35 = (char *)dTransVal + v34; + v47 = 112; + do + { + BSave(*v35); + v35 += 112; + --v47; + } + while ( v47 ); + ++v34; + } + while ( v34 < 112 ); + v36 = 0; + do + { + v37 = (char *)dTransVal2 + v36; + v47 = 112; + do + { + BSave(*v37); + v37 += 112; + --v47; + } + while ( v47 ); + ++v36; + } + while ( v36 < 112 ); + v38 = 0; + do + { + v39 = (unsigned char *)automapview + v38; + v47 = 40; + do + { + OSave(*v39); + v39 += 40; + --v47; + } + while ( v47 ); + ++v38; + } + while ( v38 < 40 ); + v40 = 0; + do + { + v41 = (char *)dMissile + v40; + v47 = 112; + do + { + BSave(*v41); + v41 += 112; + --v47; + } + while ( v47 ); + ++v40; + } + while ( v40 < 112 ); + } + ISave(numpremium); + ISave(premiumlevel); + v42 = 0; + do + SavePremium(v42++); + while ( v42 < 6 ); + OSave(automapflag); + ISave(AutoMapScale); + pfile_get_game_name(v45); + v43 = ptr; + v44 = codec_get_encoded_len((_BYTE *)tbuff - (_BYTE *)ptr); + pfile_write_save_file(v45, v43, (_BYTE *)tbuff - (_BYTE *)v43, v44); + mem_free_dbg(v43); + *(_DWORD *)&gbValidSaveFile = 1; + pfile_rename_temp_to_perm(); + pfile_write_hero(); +} +// 5BB1ED: using guessed type char leveltype; +// 5CCB10: using guessed type char setlvlnum; +// 5CF31D: using guessed type char setlevel; + +//----- (00427203) -------------------------------------------------------- +void __fastcall BSave(char v) +{ + *(_BYTE *)tbuff = v; + tbuff = (char *)tbuff + 1; +} + +//----- (00427211) -------------------------------------------------------- +void __fastcall ISave(int v) +{ + *(_BYTE *)tbuff = _HIBYTE(v); + tbuff = (char *)tbuff + 1; + *(_BYTE *)tbuff = BYTE2(v); + tbuff = (char *)tbuff + 1; + *(_BYTE *)tbuff = BYTE1(v); + tbuff = (char *)tbuff + 1; + *(_BYTE *)tbuff = v; + tbuff = (char *)tbuff + 1; +} + +//----- (00427258) -------------------------------------------------------- +void __fastcall ISave_2(int v) +{ + *(_BYTE *)tbuff = _HIBYTE(v); + tbuff = (char *)tbuff + 1; + *(_BYTE *)tbuff = BYTE2(v); + tbuff = (char *)tbuff + 1; + *(_BYTE *)tbuff = BYTE1(v); + tbuff = (char *)tbuff + 1; + *(_BYTE *)tbuff = v; + tbuff = (char *)tbuff + 1; +} + +//----- (0042729F) -------------------------------------------------------- +void __fastcall OSave(unsigned char v) +{ + if ( v ) + *(_BYTE *)tbuff = 1; + else + *(_BYTE *)tbuff = 0; + tbuff = (char *)tbuff + 1; +} + +//----- (004272B7) -------------------------------------------------------- +void __fastcall SavePlayer(int i) +{ + memcpy(tbuff, &plr[i], 0x54B0u); + tbuff = (char *)tbuff + 21680; +} + +//----- (004272E1) -------------------------------------------------------- +void __fastcall SaveMonster(int i) +{ + memcpy(tbuff, &monster[i], 0xD8u); + tbuff = (char *)tbuff + 216; +} + +//----- (0042730B) -------------------------------------------------------- +void __fastcall SaveMissile(int i) +{ + memcpy(tbuff, &missile[i], 0xB0u); + tbuff = (char *)tbuff + 176; +} + +//----- (00427335) -------------------------------------------------------- +void __fastcall SaveObject(int i) +{ + memcpy(tbuff, &object[i], 0x78u); + tbuff = (char *)tbuff + 120; +} + +//----- (00427357) -------------------------------------------------------- +void __fastcall SaveItem(int i) +{ + memcpy(tbuff, &items[i], 0x170u); + tbuff = (char *)tbuff + 368; +} + +//----- (00427381) -------------------------------------------------------- +void __fastcall SavePremium(int i) +{ + memcpy(tbuff, &premiumitem[i], 0x170u); + tbuff = (char *)tbuff + 368; +} + +//----- (004273AB) -------------------------------------------------------- +void __fastcall SaveQuest(int i) +{ + memcpy(tbuff, &quests[i], 0x18u); + tbuff = (char *)tbuff + 24; + ISave(ReturnLvlX); + ISave(ReturnLvlY); + ISave(ReturnLvl); + ISave(ReturnLvlT); + ISave(dword_525760); +} + +//----- (00427404) -------------------------------------------------------- +void __fastcall SaveLighting(int i) +{ + memcpy(tbuff, &LightList[i], 0x34u); + tbuff = (char *)tbuff + 52; +} + +//----- (00427426) -------------------------------------------------------- +void __fastcall SaveVision(int i) +{ + memcpy(tbuff, &VisionList[i], 0x34u); + tbuff = (char *)tbuff + 52; +} + +//----- (00427448) -------------------------------------------------------- +void __fastcall SavePortal(int i) +{ + memcpy(tbuff, &portal[i], 0x18u); + tbuff = (char *)tbuff + 24; +} + +//----- (0042746B) -------------------------------------------------------- +void __cdecl SaveLevel() +{ + int v0; // eax + signed int v1; // esi + char *v2; // edx + signed int v3; // ebx + int v4; // edx + int *v5; // esi + int i; // esi + int *v7; // edx + int v8; // edx + int *v9; // edx + int v10; // edx + int j; // esi + int *v12; // edx + int v13; // edx + int *v14; // edx + int v15; // edx + int k; // esi + signed int v17; // esi + _BYTE *v18; // edx + signed int v19; // ebx + int v20; // edx + signed int v21; // esi + char *v22; // edx + signed int v23; // ebx + int v24; // edx + int (*v25)[112]; // ebx + int *v26; // esi + signed int v27; // esi + char *v28; // edx + signed int v29; // ebx + int v30; // edx + signed int v31; // esi + char *v32; // edx + signed int v33; // ebx + int v34; // edx + signed int v35; // esi + char *v36; // edx + signed int v37; // ebx + int v38; // edx + signed int v39; // esi + unsigned char *v40; // edx + signed int v41; // ebx + int v42; // edx + signed int v43; // esi + char *v44; // edx + signed int v45; // ebx + int v46; // edx + void *v47; // esi + int v48; // eax + int v49; // eax + char v50[260]; // [esp+0h] [ebp-10Ch] + void *ptr; // [esp+104h] [ebp-8h] + int v52; // [esp+108h] [ebp-4h] + + if ( !currlevel ) + glSeedTbl[0] = GetRndSeed(); + v0 = codec_get_encoded_len(262147); + ptr = DiabloAllocPtr(v0); + tbuff = ptr; + if ( leveltype ) + { + v1 = 0; + do + { + v2 = (char *)dDead + v1; + v3 = 112; + do + { + BSave(*v2); + v2 = (char *)(v4 + 112); + --v3; + } + while ( v3 ); + ++v1; + } + while ( v1 < 112 ); + } + ISave(nummonsters); + ISave(numitems); + ISave(nobjects); + if ( leveltype ) + { + v5 = monstactive; + do + { + ISave(*v5); + ++v5; + } + while ( (signed int)v5 < (signed int)&nummonsters ); + for ( i = 0; i < nummonsters; ++i ) + SaveMonster(monstactive[i]); + v7 = objectactive; + do + { + BSave(*(_BYTE *)v7); + v7 = (int *)(v8 + 4); + } + while ( (signed int)v7 < (signed int)&nobjects ); + v9 = objectavail; + do + { + BSave(*(_BYTE *)v9); + v9 = (int *)(v10 + 4); + } + while ( (signed int)v9 < (signed int)object ); + for ( j = 0; j < nobjects; ++j ) + SaveObject(objectactive[j]); + } + v12 = itemactive; + do + { + BSave(*(_BYTE *)v12); + v12 = (int *)(v13 + 4); + } + while ( (signed int)v12 < (signed int)&uitemflag ); + v14 = itemavail; + do + { + BSave(*(_BYTE *)v14); + v14 = (int *)(v15 + 4); + } + while ( (signed int)v14 < (signed int)&itemavail[127] ); + for ( k = 0; k < numitems; ++k ) + SaveItem(itemactive[k]); + v17 = 0; + do + { + v18 = (unsigned char *)dFlags + v17; + v19 = 112; + do + { + BSave(*v18 & 0xF8); + v18 = (_BYTE *)(v20 + 112); + --v19; + } + while ( v19 ); + ++v17; + } + while ( v17 < 112 ); + v21 = 0; + do + { + v22 = (char *)dItem + v21; + v23 = 112; + do + { + BSave(*v22); + v22 = (char *)(v24 + 112); + --v23; + } + while ( v23 ); + ++v21; + } + while ( v21 < 112 ); + if ( leveltype ) + { + v25 = dMonster; + do + { + v26 = (int *)v25; + v52 = 112; + do + { + ISave(*v26); + v26 += 112; + --v52; + } + while ( v52 ); + v25 = (int (*)[112])((char *)v25 + 4); + } + while ( (signed int)v25 < (signed int)dMonster[1] ); + v27 = 0; + do + { + v28 = (char *)dObject + v27; + v29 = 112; + do + { + BSave(*v28); + v28 = (char *)(v30 + 112); + --v29; + } + while ( v29 ); + ++v27; + } + while ( v27 < 112 ); + v31 = 0; + do + { + v32 = (char *)dTransVal + v31; + v33 = 112; + do + { + BSave(*v32); + v32 = (char *)(v34 + 112); + --v33; + } + while ( v33 ); + ++v31; + } + while ( v31 < 112 ); + v35 = 0; + do + { + v36 = (char *)dTransVal2 + v35; + v37 = 112; + do + { + BSave(*v36); + v36 = (char *)(v38 + 112); + --v37; + } + while ( v37 ); + ++v35; + } + while ( v35 < 112 ); + v39 = 0; + do + { + v40 = (unsigned char *)automapview + v39; + v41 = 40; + do + { + OSave(*v40); + v40 = (unsigned char *)(v42 + 40); + --v41; + } + while ( v41 ); + ++v39; + } + while ( v39 < 40 ); + v43 = 0; + do + { + v44 = (char *)dMissile + v43; + v45 = 112; + do + { + BSave(*v44); + v44 = (char *)(v46 + 112); + --v45; + } + while ( v45 ); + ++v43; + } + while ( v43 < 112 ); + } + pfile_get_temp_level_name(v50); + v47 = ptr; + v48 = codec_get_encoded_len((_BYTE *)tbuff - (_BYTE *)ptr); + pfile_write_save_file(v50, v47, (_BYTE *)tbuff - (_BYTE *)v47, v48); + mem_free_dbg(v47); + v49 = myplr; + if ( setlevel ) + plr[v49]._pSLvlVisited[(unsigned char)setlvlnum] = 1; + else + plr[v49]._pLvlVisited[currlevel] = 1; +} +// 5BB1ED: using guessed type char leveltype; +// 5CCB10: using guessed type char setlvlnum; +// 5CF31D: using guessed type char setlevel; + +//----- (0042772F) -------------------------------------------------------- +void __cdecl LoadLevel() +{ + signed int v0; // esi + char v1; // al + int v2; // edx + char *v3; // ecx + int v4; // esi + int *v5; // edi + int v6; // edi + char v7; // al + _DWORD *v8; // ecx + char v9; // al + _DWORD *v10; // ecx + int i; // esi + int j; // esi + char v13; // al + _DWORD *v14; // ecx + char v15; // al + _DWORD *v16; // ecx + int k; // esi + signed int v18; // esi + char v19; // al + int v20; // edx + char *v21; // ecx + signed int v22; // esi + char v23; // al + int v24; // edx + char *v25; // ecx + int (*v26)[112]; // edi + _DWORD *v27; // esi + signed int v28; // ebx + signed int v29; // esi + char v30; // al + int v31; // edx + char *v32; // ecx + signed int v33; // esi + char v34; // al + int v35; // edx + char *v36; // ecx + signed int v37; // esi + char v38; // al + int v39; // edx + char *v40; // ecx + signed int v41; // esi + signed int v42; // edi + bool v43; // al + bool *v44; // edx + signed int v45; // ecx + _BYTE *v46; // eax + signed int v47; // edx + int *v48; // eax + char dst[260]; // [esp+Ch] [ebp-10Ch] + int len; // [esp+110h] [ebp-8h] + void *ptr; // [esp+114h] [ebp-4h] + + pfile_get_perm_level_name(dst); + ptr = pfile_read(dst, &len); + tbuff = ptr; + if ( leveltype ) + { + do + { + v0 = 112; + do + { + v1 = BLoad(); + *v3 = v1; + --v0; + } + while ( v0 ); + } + while ( v2 + 1 < 112 ); + SetDead(); + } + v4 = ILoad(); + nummonsters = v4; + numitems = ILoad(); + nobjects = ILoad(); + if ( leveltype ) + { + v5 = monstactive; + do + { + *v5 = ILoad(); + ++v5; + } + while ( (signed int)v5 < (signed int)&nummonsters ); + v6 = 0; + if ( v4 > 0 ) + { + do + LoadMonster(monstactive[v6++]); + while ( v6 < nummonsters ); + } + do + { + v7 = BLoad(); + *v8 = v7; + } + while ( (signed int)(v8 + 1) < (signed int)&nobjects ); + do + { + v9 = BLoad(); + *v10 = v9; + } + while ( (signed int)(v10 + 1) < (signed int)object ); + for ( i = 0; i < nobjects; ++i ) + LoadObject(objectactive[i]); + for ( j = 0; j < nobjects; ++j ) + SyncObjectAnim(objectactive[j]); + } + do + { + v13 = BLoad(); + *v14 = v13; + } + while ( (signed int)(v14 + 1) < (signed int)&uitemflag ); + do + { + v15 = BLoad(); + *v16 = v15; + } + while ( (signed int)(v16 + 1) < (signed int)&itemavail[127] ); + for ( k = 0; k < numitems; ++k ) + LoadItem(itemactive[k]); + do + { + v18 = 112; + do + { + v19 = BLoad(); + *v21 = v19; + --v18; + } + while ( v18 ); + } + while ( v20 + 1 < 112 ); + do + { + v22 = 112; + do + { + v23 = BLoad(); + *v25 = v23; + --v22; + } + while ( v22 ); + } + while ( v24 + 1 < 112 ); + if ( leveltype ) + { + v26 = dMonster; + do + { + v27 = (unsigned int *)v26; + v28 = 112; + do + { + *v27 = ILoad(); + v27 += 112; + --v28; + } + while ( v28 ); + v26 = (int (*)[112])((char *)v26 + 4); + } + while ( (signed int)v26 < (signed int)dMonster[1] ); + do + { + v29 = 112; + do + { + v30 = BLoad(); + *v32 = v30; + --v29; + } + while ( v29 ); + } + while ( v31 + 1 < 112 ); + do + { + v33 = 112; + do + { + v34 = BLoad(); + *v36 = v34; + --v33; + } + while ( v33 ); + } + while ( v35 + 1 < 112 ); + do + { + v37 = 112; + do + { + v38 = BLoad(); + *v40 = v38; + --v37; + } + while ( v37 ); + } + while ( v39 + 1 < 112 ); + v41 = 0; + do + { + v42 = 40; + do + { + v43 = OLoad(); + *v44 = v43; + --v42; + } + while ( v42 ); + ++v41; + } + while ( v41 < 40 ); + v45 = 0; + do + { + v46 = (unsigned char *)dMissile + v45; + v47 = 112; + do + { + *v46 = 0; + v46 += 112; + --v47; + } + while ( v47 ); + ++v45; + } + while ( v45 < 112 ); + } + AutomapZoomReset(); + ResyncQuests(); + SyncPortals(); + v48 = &plr[0].plrlevel; + dword_642A18 = 1; + do + { + if ( *((_BYTE *)v48 - 23) && currlevel == *v48 ) + LightList[v48[26]]._lunflag = 1; + v48 += 5430; + } + while ( (signed int)v48 < (signed int)&plr_msgs[0].player ); + mem_free_dbg(ptr); +} +// 5BB1ED: using guessed type char leveltype; +// 642A18: using guessed type int dword_642A18; + +//----- (004279F7) -------------------------------------------------------- +void __cdecl log_cpp_init_1() +{ + dword_646A30 = log_inf; +} +// 47F070: using guessed type int log_inf; +// 646A30: using guessed type int dword_646A30; + +//----- (00427A02) -------------------------------------------------------- +void __cdecl log_cpp_init_2() +{ + log_init_mutex(); + j_log_cleanup_mutex(); +} + +//----- (00427A0C) -------------------------------------------------------- +void __cdecl log_init_mutex() +{ + InitializeCriticalSection(&stru_646A38); +} + +//----- (00427A18) -------------------------------------------------------- +void __cdecl j_log_cleanup_mutex() +{ + atexit(log_cleanup_mutex); +} + +//----- (00427A24) -------------------------------------------------------- +void __cdecl log_cleanup_mutex() +{ + DeleteCriticalSection(&stru_646A38); +} + +//----- (00427A30) -------------------------------------------------------- +void __cdecl log_flush(bool force_close) +{ + void *v1; // eax + DWORD NumberOfBytesWritten; // [esp+8h] [ebp-4h] + + EnterCriticalSection(&stru_646A38); + if ( nNumberOfBytesToWrite ) + { + if ( log_file == (HANDLE)-1 ) + { + v1 = log_create(); + log_file = v1; + if ( v1 == (void *)-1 ) + { + nNumberOfBytesToWrite = 0; + return; + } + SetFilePointer(v1, 0, 0, 2u); + } + WriteFile(log_file, lpAddress, nNumberOfBytesToWrite, &NumberOfBytesWritten, 0); + nNumberOfBytesToWrite = 0; + } + if ( force_close && log_file != (HANDLE)-1 ) + { + CloseHandle(log_file); + log_file = (HANDLE)-1; + } + LeaveCriticalSection(&stru_646A38); +} + +//----- (00427AC2) -------------------------------------------------------- +void *__cdecl log_create() +{ + char *v0; // eax + void *v1; // ebx + HANDLE v2; // eax + char *v3; // edx + char Filename[260]; // [esp+Ch] [ebp-15Ch] + VS_FIXEDFILEINFO file_info; // [esp+110h] [ebp-58h] + char Buffer[32]; // [esp+144h] [ebp-24h] + DWORD pcbBuffer; // [esp+164h] [ebp-4h] + + if ( log_not_created ) + { + if ( GetModuleFileNameA(0, Filename, 0x104u) && (v0 = strrchr(Filename, 92)) != 0 ) + v0[1] = 0; + else + Filename[0] = 0; + pcbBuffer = 32; + if ( !GetUserNameA(Buffer, &pcbBuffer) ) + Buffer[0] = 0; + log_get_version(&file_info); + _snprintf( + FileName, + 0x104u, + "%s%s%02u%02u%02u.ERR", + Filename, + Buffer, + _LOWORD(file_info.dwProductVersionMS), + file_info.dwProductVersionLS >> 16, + _LOWORD(file_info.dwProductVersionLS)); + } + v1 = (void *)-1; + for ( pcbBuffer = log_not_created == 0; (signed int)pcbBuffer < 2; ++pcbBuffer ) + { + v2 = CreateFileA(FileName, 0x40000000u, 1u, 0, 4u, 0x80u, 0); + v1 = v2; + if ( v2 != (HANDLE)-1 ) + { + if ( GetFileSize(v2, 0) > 0x10000 ) + SetEndOfFile(v1); + break; + } + v3 = strrchr(FileName, 92); + if ( !v3 ) + v3 = FileName; + strcpy(Filename, "c:\\"); + memset(&Filename[4], 0, 0x100u); + strcat(Filename, v3); + strcpy(FileName, Filename); + } + log_not_created = 0; + return v1; +} +// 4947D4: using guessed type int log_not_created; + +//----- (00427C18) -------------------------------------------------------- +void __fastcall log_get_version(VS_FIXEDFILEINFO *file_info) +{ + DWORD v1; // eax + DWORD v2; // esi + void *v3; // ebx + unsigned int v4; // eax + char Filename[260]; // [esp+8h] [ebp-114h] + DWORD dwHandle; // [esp+10Ch] [ebp-10h] + LPVOID lpBuffer; // [esp+110h] [ebp-Ch] + unsigned int puLen; // [esp+114h] [ebp-8h] + void *v9; // [esp+118h] [ebp-4h] + + v9 = file_info; + memset(file_info, 0, 0x34u); + if ( GetModuleFileNameA(0, Filename, 0x104u) ) + { + v1 = GetFileVersionInfoSizeA(Filename, &dwHandle); + v2 = v1; + if ( v1 ) + { + v3 = VirtualAlloc(0, v1, 0x1000u, 4u); + if ( GetFileVersionInfoA(Filename, 0, v2, v3) && VerQueryValueA(v3, "\\", &lpBuffer, &puLen) ) + { + v4 = puLen; + if ( puLen >= 0x34 ) + v4 = 52; + memcpy(v9, lpBuffer, v4); + } + VirtualFree(v3, 0, 0x8000u); + } + } +} + +//----- (00427CC9) -------------------------------------------------------- +void log_printf(char *format, ...) +{ + size_t v1; // edi + char *v2; // eax + char v3[512]; // [esp+Ch] [ebp-200h] + va_list va; // [esp+218h] [ebp+Ch] + + va_start(va, format); + EnterCriticalSection(&stru_646A38); + _vsnprintf(v3, 0x200u, format, va); + v3[511] = 0; + v1 = strlen(v3); + if ( v1 + nNumberOfBytesToWrite > 0x1000 ) + log_flush(0); + v2 = (char *)lpAddress; + if ( lpAddress + || (v2 = (char *)VirtualAlloc((LPVOID)lpAddress, 0x1000u, 0x1000u, 4u), + nNumberOfBytesToWrite = 0, + (lpAddress = v2) != 0) ) + { + memcpy(&v2[nNumberOfBytesToWrite], v3, v1); + nNumberOfBytesToWrite += v1; + } + LeaveCriticalSection(&stru_646A38); +} + +//----- (00427D75) -------------------------------------------------------- +void __cdecl log_dump_computer_info() +{ + char Buffer[64]; // [esp+0h] [ebp-88h] + VS_FIXEDFILEINFO file_info; // [esp+40h] [ebp-48h] + struct _SYSTEMTIME SystemTime; // [esp+74h] [ebp-14h] + DWORD pcbBuffer; // [esp+84h] [ebp-4h] + + GetLocalTime(&SystemTime); + pcbBuffer = 64; + if ( !GetUserNameA(Buffer, &pcbBuffer) ) + Buffer[0] = 0; + log_get_version(&file_info); + log_printf( + "\r\n" + "------------------------------------------------------\r\n" + "PROGRAM VERSION: %d.%d.%d.%d\r\n" + "COMPUTER NAME: %s\r\n" + "TIME: %02u/%02u/%02u %02u:%02u:%02u\r\n" + "INFO: %s\r\n" + "\r\n", + file_info.dwProductVersionMS >> 16, + _LOWORD(file_info.dwProductVersionMS), + file_info.dwProductVersionLS >> 16, + _LOWORD(file_info.dwProductVersionLS), + Buffer, + SystemTime.wMonth, + SystemTime.wDay, + SystemTime.wYear % 100, + SystemTime.wHour, + SystemTime.wMinute, + SystemTime.wSecond, + log_buffer); +} + +//----- (00427E13) -------------------------------------------------------- +void __cdecl mainmenu_cpp_init() +{ + mainmenu_cpp_init_value = mainmenu_inf; +} +// 47F074: using guessed type int mainmenu_inf; +// 646CE0: using guessed type int mainmenu_cpp_init_value; + +//----- (00427E1E) -------------------------------------------------------- +void __cdecl mainmenu_refresh_music() +{ + int v0; // eax + + music_start(menu_music_track_id); + v0 = menu_music_track_id; + do + { + if ( ++v0 == 6 ) + v0 = 0; + } + while ( !v0 || v0 == 1 ); + menu_music_track_id = v0; +} + +//----- (00427E45) -------------------------------------------------------- +void __stdcall mainmenu_create_hero(char *a1, char *a2) +{ + char *v2; // [esp-14h] [ebp-14h] + + if ( UiValidPlayerName(v2) ) + pfile_create_save_file(a1, a2); +} + +//----- (00427E62) -------------------------------------------------------- +int __stdcall mainmenu_select_hero_dialog(int u1, int u2, int u3, int u4, int mode, char *cname, int clen, char *cdesc, int cdlen, int *multi) +{ + int v10; // eax + int a6; // [esp+8h] [ebp-8h] + int a5; // [esp+Ch] [ebp-4h] + + a6 = 1; + a5 = 0; + if ( gbMaxPlayers == 1 ) + { + if ( !UiSelHeroSingDialog( + pfile_ui_set_hero_infos, + pfile_ui_save_create, + pfile_delete_save, + pfile_ui_set_class_stats, + &a5, + chr_name_str, + &gnDifficulty) ) + TermMsg("Unable to display SelHeroSing"); + if ( a5 == 2 ) + { + dword_5256E8 = 1; + goto LABEL_6; + } + dword_5256E8 = 0; + } + else if ( !UiSelHeroMultDialog( + pfile_ui_set_hero_infos, + pfile_ui_save_create, + pfile_delete_save, + pfile_ui_set_class_stats, + &a5, + &a6, + chr_name_str) ) + { + TermMsg("Can't load multiplayer dialog"); + } + if ( a5 == 4 ) + { + SErrSetLastError(1223); + return 0; + } +LABEL_6: + pfile_create_player_description(cdesc, cdlen); + if ( multi ) + { + if ( mode == 'BNET' ) + v10 = a6 || !plr[myplr].pBattleNet; + else + v10 = a6; + *multi = v10; + } + if ( cname ) + { + if ( clen ) + SStrCopy(cname, chr_name_str, clen); + } + return 1; +} +// 5256E8: using guessed type int dword_5256E8; +// 679660: using guessed type char gbMaxPlayers; + +//----- (00427F76) -------------------------------------------------------- +void __fastcall mainmenu_action(int option) +{ + int v1; // eax + int a2; // [esp+0h] [ebp-4h] + + a2 = option; + mainmenu_refresh_music(); + do + { + while ( 1 ) + { + a2 = 0; + if ( !UiMainMenuDialog("Diablo v1.09", &a2, effects_play_sound, 30) ) + TermMsg("Unable to display mainmenu"); + if ( a2 == 1 ) + break; + switch ( a2 ) + { + case MAINMENU_MULTIPLAYER: + mainmenu_multi_player(); + goto LABEL_15; + case MAINMENU_REPLAY_INTRO: + goto LABEL_10; + case MAINMENU_SHOW_CREDITS: + UiCreditsDialog(16); + break; + case MAINMENU_EXIT_DIABLO: + goto LABEL_16; + case MAINMENU_ATTRACT_MODE: +LABEL_10: + if ( window_activated ) + mainmenu_play_intro(); + break; + } + } + v1 = mainmenu_single_player(); +LABEL_15: + ; + } + while ( v1 ); +LABEL_16: + music_stop(); +} +// 634980: using guessed type int window_activated; + +//----- (00427FEC) -------------------------------------------------------- +int __cdecl mainmenu_single_player() +{ + gbMaxPlayers = 1; + return mainmenu_init_menu(1); +} +// 679660: using guessed type char gbMaxPlayers; + +//----- (00427FFA) -------------------------------------------------------- +int __fastcall mainmenu_init_menu(int a1) +{ + int v1; // esi + int v3; // esi + + v1 = a1; + if ( a1 == 4 ) + return 1; + music_stop(); + v3 = diablo_init_menu(v1 != 2, v1 != 3); + if ( v3 ) + mainmenu_refresh_music(); + return v3; +} + +//----- (00428030) -------------------------------------------------------- +void __cdecl mainmenu_multi_player() +{ + gbMaxPlayers = 4; + mainmenu_init_menu(3); +} +// 679660: using guessed type char gbMaxPlayers; + +//----- (0042803F) -------------------------------------------------------- +void __cdecl mainmenu_play_intro() +{ + music_stop(); + play_movie("gendata\\diablo1.smk", 1); + mainmenu_refresh_music(); +} + +//----- (00428056) -------------------------------------------------------- +void __cdecl FreeQuestText() +{ + void *v0; // ecx + void *v1; // ecx + + v0 = pMedTextCels; + pMedTextCels = 0; + mem_free_dbg(v0); + v1 = pTextBoxCels; + pTextBoxCels = 0; + mem_free_dbg(v1); +} + +//----- (0042807A) -------------------------------------------------------- +void __cdecl InitQuestText() +{ + unsigned char *v0; // eax + + pMedTextCels = LoadFileInMem("Data\\MedTextS.CEL", 0); + v0 = LoadFileInMem("Data\\TextBox.CEL", 0); + qtextflag = 0; + pTextBoxCels = v0; +} +// 646D00: using guessed type char qtextflag; + +//----- (004280A4) -------------------------------------------------------- +void __fastcall InitQTextMsg(int m) +{ + int v1; // ecx + int v2; // esi + char *v3; // eax + int v4; // eax + + v1 = m; + v2 = v1 * 16; + if ( alltext[v1].scrlltxt ) + { + v3 = alltext[v1].txtstr; + questlog = 0; + qtextptr = v3; + v4 = alltext[v1].txtspd; + qtextflag = 1; + qtexty = 500; + sgLastScroll = *(_DWORD *)&aUnableToDisp_0[4 * v4 + 24]; + scrolltexty = sgLastScroll; + qtextSpd = GetTickCount(); + } + PlaySFX(*(_sfx_id *)((char *)&alltext[0].sfxnr + v2)); +} +// 646CF4: using guessed type int qtexty; +// 646CFC: using guessed type int qtextSpd; +// 646D00: using guessed type char qtextflag; +// 646D04: using guessed type int scrolltexty; +// 646D08: using guessed type int sgLastScroll; +// 69BD04: using guessed type int questlog; + +//----- (00428104) -------------------------------------------------------- +void __cdecl DrawQTextBack() +{ + char *v0; // edi + signed int v1; // edx + signed int v2; // ecx + int v3; // edi + signed int v4; // ecx + _BYTE *v5; // edi + signed int v6; // ecx + + Cel_decode(88, 487, pTextBoxCels, 1, 591); + v0 = &gpBuffer->row[324].pixels[27]; + v1 = 148; + do + { + v2 = 292; + do + { + *v0 = 0; + v0 += 2; + --v2; + } + while ( v2 ); + *v0 = 0; + v3 = (int)(v0 - 1352); + v4 = 292; + do + { + v5 = (_BYTE *)(v3 + 1); + *v5 = 0; + v3 = (int)(v5 + 1); + --v4; + } + while ( v4 ); + v0 = (char *)(v3 - 1352); + --v1; + } + while ( v1 ); + v6 = 292; + do + { + *v0 = 0; + v0 += 2; + --v6; + } + while ( v6 ); + *v0 = 0; +} + +//----- (00428160) -------------------------------------------------------- +void __fastcall PrintQTextChr(int screen_x, int screen_y, char *cel_buf, int frame) +{ + char *v4; // ebx + char *v5; // esi + char *v6; // edi + int v7; // ebx + signed int v8; // edx + unsigned int v9; // eax + unsigned int v10; // ecx + char v11; // cf + unsigned int v12; // ecx + char *v13; // [esp+14h] [ebp-8h] + char *v14; // [esp+18h] [ebp-4h] + + v13 = (char *)gpBuffer + screen_y_times_768[209]; + v14 = (char *)gpBuffer + screen_y_times_768[469]; + v4 = &cel_buf[4 * frame]; + v5 = &cel_buf[*(_DWORD *)v4]; + v6 = (char *)gpBuffer + screen_y_times_768[screen_y] + screen_x; + v7 = (int)&v5[*((_DWORD *)v4 + 1) - *(_DWORD *)v4]; + do + { + v8 = 22; + do + { + while ( 1 ) + { + v9 = (unsigned char)*v5++; + if ( (v9 & 0x80u) == 0 ) + break; + _LOBYTE(v9) = -(char)v9; + v6 += v9; + v8 -= v9; + if ( !v8 ) + goto LABEL_15; + } + v8 -= v9; + if ( v6 < v13 || v6 > v14 ) + { + v5 += v9; + v6 += v9; + } + else + { + v10 = v9 >> 1; + if ( !(v9 & 1) || (*v6 = *v5, ++v5, ++v6, v10) ) + { + v11 = v10 & 1; + v12 = v9 >> 2; + if ( !v11 || (*(_WORD *)v6 = *(_WORD *)v5, v5 += 2, v6 += 2, v12) ) + { + qmemcpy(v6, v5, 4 * v12); + v5 += 4 * v12; + v6 += 4 * v12; + } + } + } + } + while ( v8 ); +LABEL_15: + v6 -= 790; + } + while ( (char *)v7 != v5 ); +} + +//----- (00428202) -------------------------------------------------------- +void __cdecl DrawQText() +{ + char *v0; // edi + signed int v1; // edx + int v2; // ecx + char *i; // esi + unsigned char v4; // al + unsigned char v5; // al + char v6; // dl + char *v7; // eax + unsigned char v8; // al + char *v9; // esi + unsigned char v10; // bl + DWORD v11; // eax + char tempstr[128]; // [esp+8h] [ebp-90h] + char *v13; // [esp+88h] [ebp-10h] + int v14; // [esp+8Ch] [ebp-Ch] + int screen_y; // [esp+90h] [ebp-8h] + int screen_x; // [esp+94h] [ebp-4h] + + DrawQTextBack(); + v0 = qtextptr; + screen_x = 112; + v13 = 0; + screen_y = qtexty; + v14 = 0; + do + { + v1 = 0; + v2 = 0; + for ( i = v0; *i != 10; ++v2 ) + { + if ( *i == 124 || v1 >= 543 ) + break; + v4 = *i++; + v5 = fontidx[v4]; + if ( v5 ) + { + tempstr[v2] = v5; + v1 += mfontkern[mfontframe[v5]] + 2; + } + else + { + --v2; + } + } + v6 = *i; + v7 = &tempstr[v2]; + tempstr[v2] = 0; + if ( v6 == 124 ) + { + *v7 = 0; + v14 = 1; + } + else if ( v6 != 10 ) + { + while ( *v7 != 32 && v2 > 0 ) + { + *v7 = 0; + v7 = &tempstr[--v2]; + } + } + v8 = tempstr[0]; + if ( tempstr[0] ) + { + v9 = tempstr; + do + { + ++v0; + v10 = mfontframe[fontidx[v8]]; + if ( *v0 == 10 ) + ++v0; + if ( v10 ) + PrintQTextChr(screen_x, screen_y, (char *)pMedTextCels, v10); + ++v9; + screen_x += mfontkern[v10] + 2; + v8 = *v9; + } + while ( *v9 ); + } + if ( !v13 ) + v13 = v0; + screen_y += 38; + screen_x = 112; + if ( screen_y > 501 ) + v14 = 1; + } + while ( !v14 ); + v11 = GetTickCount(); + while ( 1 ) + { + if ( sgLastScroll <= 0 ) + { + qtexty = qtexty + sgLastScroll - 1; + goto LABEL_33; + } + if ( --scrolltexty ) + { + --qtexty; +LABEL_33: + if ( scrolltexty ) + goto LABEL_35; + } + scrolltexty = sgLastScroll; +LABEL_35: + if ( qtexty <= 209 ) + break; + qtextSpd += 50; + if ( v11 - qtextSpd >= 0x7FFFFFFF ) + return; + } + qtexty += 38; + qtextptr = v13; + if ( *v13 == 124 ) + qtextflag = 0; +} +// 646CF4: using guessed type int qtexty; +// 646CFC: using guessed type int qtextSpd; +// 646D00: using guessed type char qtextflag; +// 646D04: using guessed type int scrolltexty; +// 646D08: using guessed type int sgLastScroll; +// 428202: using guessed type char tempstr[128]; + +//----- (004283C0) -------------------------------------------------------- +void __fastcall GetDamageAmt(int i, int *mind, int *maxd) +{ + int v3; // eax + int v4; // esi + int v5; // eax + int v6; // ecx + int v7; // eax + int *v8; // eax + signed int v9; // ecx + int v10; // eax + int v11; // ecx + int v12; // eax + int v13; // eax + int v14; // eax + int v15; // ecx + int *v16; // ecx + int v17; // eax + int v18; // ecx + int v19; // eax + int v20; // ecx + int v21; // eax + signed int v22; // eax + signed int v23; // ecx + int v24; // eax + int v25; // ecx + int v26; // ecx + int v27; // eax + signed int v28; // ecx + + v3 = myplr; + v4 = plr[myplr]._pISplLvlAdd + plr[myplr]._pSplLvl[i]; + switch ( i ) + { + case SPL_FIREBOLT: + *mind = (plr[v3]._pMagic >> 3) + v4 + 1; + v5 = (plr[myplr]._pMagic >> 3) + v4 + 10; + goto LABEL_73; + case SPL_HEAL: + v6 = plr[v3]._pLevel + v4 + 1; + *mind = v6; + v7 = myplr; + if ( !_LOBYTE(plr[myplr]._pClass) ) + { + *mind = 2 * v6; + v7 = myplr; + } + if ( _LOBYTE(plr[v7]._pClass) == 1 ) + *mind += *mind >> 1; + v8 = maxd; + v9 = 0; + *maxd = 10; + if ( plr[myplr]._pLevel > 0 ) + { + do + { + *maxd += 4; + ++v9; + } + while ( v9 < plr[myplr]._pLevel ); + } + goto LABEL_65; + case SPL_LIGHTNING: + v10 = 2; + *mind = 2; + v11 = plr[myplr]._pLevel; + goto LABEL_43; + case SPL_FLASH: + v12 = plr[v3]._pLevel; + *mind = v12; + if ( v4 > 0 ) + { + do + { + v12 += v12 >> 3; + --v4; + } + while ( v4 ); + *mind = v12; + } + v13 = (*mind >> 1) + *mind; + *mind = v13; + goto LABEL_33; + case SPL_IDENTIFY: + case SPL_TOWN: + case SPL_STONE: + case SPL_INFRA: + case SPL_RNDTELEPORT: + case SPL_MANASHIELD: + case SPL_DOOMSERP: + case SPL_BLODRIT: + case SPL_INVISIBIL: + case SPL_BLODBOIL: + case SPL_TELEPORT: + case SPL_ETHEREALIZE: + case SPL_REPAIR: + case SPL_RECHARGE: + case SPL_DISARM: + case SPL_RESURRECT: + case SPL_TELEKINESIS: + case SPL_BONESPIRIT: + v8 = maxd; + goto LABEL_71; + case SPL_FIREWALL: + *mind = (4 * plr[v3]._pLevel + 8) >> 1; + v5 = (4 * plr[myplr]._pLevel + 80) >> 1; + goto LABEL_73; + case SPL_FIREBALL: + v14 = 2 * plr[v3]._pLevel + 4; + *mind = v14; + if ( v4 > 0 ) + { + v15 = v4; + do + { + v14 += v14 >> 3; + --v15; + } + while ( v15 ); + *mind = v14; + } + v16 = maxd; + v5 = 2 * plr[myplr]._pLevel + 40; + *maxd = v5; + if ( v4 <= 0 ) + return; + do + { + v5 += v5 >> 3; + --v4; + } + while ( v4 ); + goto LABEL_74; + case SPL_GUARDIAN: + v17 = (plr[v3]._pLevel >> 1) + 1; + *mind = v17; + if ( v4 > 0 ) + { + v18 = v4; + do + { + v17 += v17 >> 3; + --v18; + } + while ( v18 ); + *mind = v17; + } + v16 = maxd; + v5 = (plr[myplr]._pLevel >> 1) + 10; + *maxd = v5; + if ( v4 <= 0 ) + return; + do + { + v5 += v5 >> 3; + --v4; + } + while ( v4 ); + goto LABEL_74; + case SPL_CHAIN: + *mind = 4; + v5 = 2 * plr[myplr]._pLevel + 4; + goto LABEL_73; + case SPL_WAVE: + *mind = 6 * (plr[v3]._pLevel + 1); + v13 = 3 * (plr[myplr]._pLevel + 10); +LABEL_33: + v5 = 2 * v13; + goto LABEL_73; + case SPL_NOVA: + v19 = (plr[v3]._pLevel + 5) >> 1; + *mind = v19; + if ( v4 > 0 ) + { + v20 = v4; + do + { + v19 += v19 >> 3; + --v20; + } + while ( v20 ); + *mind = v19; + } + v16 = maxd; + *mind *= 5; + v21 = (plr[myplr]._pLevel + 30) >> 1; + *maxd = v21; + if ( v4 > 0 ) + { + do + { + v21 += v21 >> 3; + --v4; + } + while ( v4 ); + *maxd = v21; + } + v5 = 5 * *maxd; + goto LABEL_74; + case SPL_FLAME: + *mind = 3; + v10 = plr[myplr]._pLevel + 4; + v11 = v10 >> 1; +LABEL_43: + *maxd = v10 + v11; + return; + case SPL_GOLEM: + *mind = 11; + *maxd = 17; + return; + case SPL_APOCA: + *mind = 0; + v22 = 0; + if ( plr[myplr]._pLevel > 0 ) + { + do + { + ++*mind; + ++v22; + } + while ( v22 < plr[myplr]._pLevel ); + } + v23 = 0; + *maxd = 0; + if ( plr[myplr]._pLevel > 0 ) + { + do + { + *maxd += 6; + ++v23; + } + while ( v23 < plr[myplr]._pLevel ); + } + return; + case SPL_ELEMENT: + v24 = 2 * plr[v3]._pLevel + 4; + *mind = v24; + if ( v4 > 0 ) + { + v25 = v4; + do + { + v24 += v24 >> 3; + --v25; + } + while ( v25 ); + *mind = v24; + } + v16 = maxd; + v5 = 2 * plr[myplr]._pLevel + 40; + *maxd = v5; + if ( v4 <= 0 ) + return; + do + { + v5 += v5 >> 3; + --v4; + } + while ( v4 ); + goto LABEL_74; + case SPL_CBOLT: + *mind = 1; + v5 = (plr[myplr]._pMagic >> 2) + 1; + goto LABEL_73; + case SPL_HBOLT: + *mind = plr[v3]._pLevel + 9; + v5 = plr[myplr]._pLevel + 18; + goto LABEL_73; + case SPL_HEALOTHER: + v26 = plr[v3]._pLevel + v4 + 1; + *mind = v26; + v27 = myplr; + if ( !_LOBYTE(plr[myplr]._pClass) ) + { + *mind = 2 * v26; + v27 = myplr; + } + if ( _LOBYTE(plr[v27]._pClass) == 1 ) + *mind += *mind >> 1; + v8 = maxd; + v28 = 0; + *maxd = 10; + if ( plr[myplr]._pLevel > 0 ) + { + do + { + *maxd += 4; + ++v28; + } + while ( v28 < plr[myplr]._pLevel ); + } +LABEL_65: + if ( v4 > 0 ) + *v8 += 6 * v4; + if ( !_LOBYTE(plr[myplr]._pClass) ) + *v8 *= 2; + if ( _LOBYTE(plr[myplr]._pClass) == 1 ) + *v8 += *v8 >> 1; +LABEL_71: + *mind = -1; + *v8 = -1; + break; + case SPL_FLARE: + v5 = 3 * v4 + (plr[v3]._pMagic >> 1) - (plr[v3]._pMagic >> 3); + *mind = v5; +LABEL_73: + v16 = maxd; +LABEL_74: + *v16 = v5; + break; + default: + return; + } +} + +//----- (00428921) -------------------------------------------------------- +int __fastcall CheckBlock(int fx, int fy, int tx, int ty) +{ + int v4; // edi + int v5; // esi + int v6; // ebx + int v7; // eax + + v4 = fy; + v5 = fx; + v6 = 0; + while ( v5 != tx || v4 != ty ) + { + v7 = GetDirection(v5, v4, tx, ty); + v5 += XDirAdd[v7]; + v4 += YDirAdd[v7]; + if ( nSolidTable[dPiece[0][v4 + 112 * v5]] ) + v6 = 1; + } + return v6; +} + +//----- (0042897A) -------------------------------------------------------- +int __fastcall FindClosest(int sx, int sy, int rad) +{ + int v3; // eax + int v4; // eax + int v5; // ebx + unsigned char *v6; // esi + int v7; // eax + int v8; // ecx + int v9; // edi + int CrawlNum[19]; // [esp+0h] [ebp-58h] + int fy; // [esp+4Ch] [ebp-Ch] + int v13; // [esp+50h] [ebp-8h] + int fx; // [esp+54h] [ebp-4h] + + CrawlNum[0] = 0; + fy = sy; + fx = sx; + CrawlNum[1] = 3; + CrawlNum[2] = 12; + CrawlNum[3] = 45; + CrawlNum[4] = 94; + CrawlNum[5] = 159; + CrawlNum[6] = 240; + CrawlNum[7] = 337; + CrawlNum[8] = 450; + CrawlNum[9] = 579; + CrawlNum[10] = 724; + CrawlNum[11] = 885; + CrawlNum[12] = 1062; + CrawlNum[13] = 1255; + CrawlNum[14] = 1464; + CrawlNum[15] = 1689; + CrawlNum[16] = 1930; + CrawlNum[17] = 2187; + CrawlNum[18] = 2460; + if ( rad > 19 ) + rad = 19; + v3 = 1; + v13 = 1; + if ( rad <= 1 ) + return -1; + while ( 1 ) + { + v4 = CrawlNum[v3]; + v5 = *(&CrawlTable.n_1 + v4); + if ( v5 > 0 ) + break; +LABEL_13: + v3 = v13++ + 1; + if ( v13 >= rad ) + return -1; + } + v6 = &CrawlTable.delta_1[0].y + v4; + while ( 1 ) + { + v7 = fx + (char)*(v6 - 1); + v8 = fy + (char)*v6; + if ( v7 > 0 && v7 < 112 && v8 > 0 && v8 < 112 ) + { + v9 = dMonster[0][v8 + 112 * v7]; + if ( v9 > 0 && !CheckBlock(fx, fy, v7, fy + (char)*v6) ) + return v9 - 1; + } + v6 += 2; + if ( --v5 <= 0 ) + goto LABEL_13; + } +} + +//----- (00428A99) -------------------------------------------------------- +int __fastcall GetSpellLevel(int id, int sn) +{ + int result; // eax + + if ( id == myplr ) + result = plr[id]._pISplLvlAdd + plr[id]._pSplLvl[sn]; + else + result = 1; + if ( result < 0 ) + result = 0; + return result; +} + +//----- (00428AC4) -------------------------------------------------------- +int __fastcall GetDirection8(int x1, int y1, int x2, int y2) +{ + int v4; // edi + int v5; // esi + int v6; // eax + int v7; // eax + int result; // eax + int v9; // [esp+8h] [ebp-110h] + char Dirs[16][16]; // [esp+Ch] [ebp-10Ch] + char lrtoul[3]; // [esp+10Ch] [ebp-Ch] + char urtoll[3]; // [esp+10Fh] [ebp-9h] + char lltour[3]; // [esp+112h] [ebp-6h] + char ultolr[3]; // [esp+115h] [ebp-3h] + + v9 = y1; + v4 = x1; + strcpy((char *)Dirs, "c"); + *(_QWORD *)&Dirs[0][2] = 0i64; + *(_DWORD *)&Dirs[0][10] = 0; + *(_WORD *)&Dirs[0][14] = 0; + *(_QWORD *)&Dirs[1][0] = 0x1010102i64; + *(_QWORD *)&Dirs[1][8] = 0i64; + *(_QWORD *)&Dirs[2][0] = 0x1010101010102i64; + *(_QWORD *)&Dirs[2][8] = 0i64; + *(_QWORD *)&Dirs[3][0] = 0x101010101010102i64; + *(_QWORD *)&Dirs[3][8] = 1i64; + *(_QWORD *)&Dirs[4][0] = 0x101010101010202i64; + *(_QWORD *)&Dirs[4][8] = 0x1010101i64; + *(_QWORD *)&Dirs[5][0] = 0x101010101010202i64; + *(_QWORD *)&Dirs[5][8] = 0x10101010101i64; + *(_QWORD *)&Dirs[6][0] = 0x101010101010202i64; + *(_QWORD *)&Dirs[6][8] = 0x101010101010101i64; + *(_QWORD *)&Dirs[7][0] = 0x101010101020202i64; + *(_QWORD *)&Dirs[7][8] = 0x101010101010101i64; + *(_QWORD *)&Dirs[8][0] = 0x101010101020202i64; + *(_QWORD *)&Dirs[8][8] = 0x101010101010101i64; + *(_QWORD *)&Dirs[9][0] = 0x101010102020202i64; + *(_QWORD *)&Dirs[9][8] = 0x101010101010101i64; + *(_QWORD *)&Dirs[10][0] = 0x101010102020202i64; + *(_QWORD *)&Dirs[10][8] = 0x101010101010101i64; + *(_QWORD *)&Dirs[11][0] = 0x101010102020202i64; + *(_QWORD *)&Dirs[11][8] = 0x101010101010101i64; + *(_QWORD *)&Dirs[12][0] = 0x101010202020202i64; + *(_QWORD *)&Dirs[12][8] = 0x101010101010101i64; + *(_QWORD *)&Dirs[13][0] = 0x101010202020202i64; + *(_QWORD *)&Dirs[13][8] = 0x101010101010101i64; + *(_QWORD *)&Dirs[14][0] = 0x101020202020202i64; + *(_QWORD *)&Dirs[14][8] = 0x101010101010101i64; + lltour[1] = 0; + *(_QWORD *)&Dirs[15][0] = 0x101020202020202i64; + *(_QWORD *)&Dirs[15][8] = 0x101010101010101i64; + lrtoul[0] = 3; + lrtoul[1] = 4; + lrtoul[2] = 5; + urtoll[0] = 3; + urtoll[1] = 2; + urtoll[2] = 1; + ultolr[0] = 7; + ultolr[1] = 6; + ultolr[2] = 5; + lltour[0] = 7; + lltour[2] = 1; + v5 = abs(x2 - x1); + if ( v5 > 15 ) + v5 = 15; + v6 = abs(y2 - v9); + if ( v6 > 15 ) + v6 = 15; + v7 = (unsigned char)Dirs[v6][v5]; + if ( v4 <= x2 ) + { + if ( v9 <= y2 ) + result = (unsigned char)lltour[v7]; + else + result = (unsigned char)ultolr[v7]; + } + else if ( v9 <= y2 ) + { + result = (unsigned char)urtoll[v7]; + } + else + { + result = (unsigned char)lrtoul[v7]; + } + return result; +} + +//----- (004290EE) -------------------------------------------------------- +int __fastcall GetDirection16(int x1, int y1, int x2, int y2) +{ + int v4; // edi + int v5; // esi + int v6; // eax + int v7; // eax + int result; // eax + int v9; // [esp+8h] [ebp-124h] + char Dirs[16][16]; // [esp+Ch] [ebp-120h] + char lrtoul[8]; // [esp+10Ch] [ebp-20h] + char urtoll[8]; // [esp+114h] [ebp-18h] + char lltour[8]; // [esp+11Ch] [ebp-10h] + char ultolr[8]; // [esp+124h] [ebp-8h] + + v9 = y1; + v4 = x1; + strcpy((char *)Dirs, "c"); + *(_QWORD *)&Dirs[0][2] = 0i64; + *(_DWORD *)&Dirs[0][10] = 0; + *(_WORD *)&Dirs[0][14] = 0; + *(_QWORD *)&Dirs[1][0] = 0x1010204i64; + *(_QWORD *)&Dirs[1][8] = 0i64; + *(_QWORD *)&Dirs[2][0] = 0x101010101020304i64; + *(_QWORD *)&Dirs[2][8] = 0i64; + *(_QWORD *)&Dirs[3][0] = 0x101010202030304i64; + *(_QWORD *)&Dirs[3][8] = 0x1010101i64; + *(_QWORD *)&Dirs[4][0] = 0x101010202030404i64; + *(_QWORD *)&Dirs[4][8] = 0x101010101010101i64; + *(_QWORD *)&Dirs[5][0] = 0x102020203030404i64; + *(_QWORD *)&Dirs[5][8] = 0x101010101010101i64; + *(_QWORD *)&Dirs[6][0] = 0x202020203030404i64; + *(_QWORD *)&Dirs[6][8] = 0x101010101010102i64; + *(_QWORD *)&Dirs[7][0] = 0x202030303030404i64; + *(_QWORD *)&Dirs[7][8] = 0x101010101010202i64; + *(_QWORD *)&Dirs[8][0] = 0x202030303040404i64; + *(_QWORD *)&Dirs[8][8] = 0x101010101020202i64; + *(_QWORD *)&Dirs[9][0] = 0x203030303040404i64; + *(_QWORD *)&Dirs[9][8] = 0x101010102020202i64; + *(_QWORD *)&Dirs[10][0] = 0x303030303040404i64; + *(_QWORD *)&Dirs[10][8] = 0x101020202020202i64; + *(_QWORD *)&Dirs[11][0] = 0x303030303040404i64; + *(_QWORD *)&Dirs[11][8] = 0x102020202020203i64; + *(_QWORD *)&Dirs[12][0] = 0x303030304040404i64; + *(_QWORD *)&Dirs[12][8] = 0x202020202020303i64; + *(_QWORD *)&Dirs[13][0] = 0x303030304040404i64; + *(_QWORD *)&Dirs[13][8] = 0x202020202020303i64; + *(_QWORD *)&Dirs[14][0] = 0x303030304040404i64; + *(_QWORD *)&Dirs[14][8] = 0x202020202030303i64; + lrtoul[2] = 0; + *(_QWORD *)&Dirs[15][0] = 0x303030304040404i64; + *(_QWORD *)&Dirs[15][8] = 0x202020203030303i64; + urtoll[0] = 6; + urtoll[1] = 7; + urtoll[2] = 8; + urtoll[3] = 9; + urtoll[4] = 10; + ultolr[0] = 6; + ultolr[1] = 5; + ultolr[2] = 4; + ultolr[3] = 3; + ultolr[4] = 2; + lltour[0] = 14; + lltour[1] = 13; + lltour[2] = 12; + lltour[3] = 11; + lltour[4] = 10; + lrtoul[0] = 14; + lrtoul[1] = 15; + lrtoul[3] = 1; + lrtoul[4] = 2; + v5 = abs(x2 - x1); + if ( v5 > 15 ) + v5 = 15; + v6 = abs(y2 - v9); + if ( v6 > 15 ) + v6 = 15; + v7 = (unsigned char)Dirs[v6][v5]; + if ( v4 <= x2 ) + { + if ( v9 <= y2 ) + result = (unsigned char)lrtoul[v7]; + else + result = (unsigned char)lltour[v7]; + } + else if ( v9 <= y2 ) + { + result = (unsigned char)ultolr[v7]; + } + else + { + result = (unsigned char)urtoll[v7]; + } + return result; +} + +//----- (0042977E) -------------------------------------------------------- +void __fastcall DeleteMissile(int mi, int i) +{ + int v2; // edi + int v3; // ebx + int v4; // esi + int v5; // eax + bool v6; // zf + bool v7; // sf + + v2 = mi; + v3 = i; + if ( missile[mi]._mitype == MIS_MANASHIELD ) + { + v4 = missile[mi]._misource; + if ( v4 == myplr ) + NetSendCmd(1u, CMD_REMSHIELD); + plr[v4].pManaShield = 0; + } + v5 = nummissiles - 1; + v6 = nummissiles == 1; + v7 = nummissiles - 1 < 0; + *(&missile[0]._mitype - nummissiles) = v2; + nummissiles = v5; + if ( !v7 && !v6 && v3 != v5 ) + missileactive[v3] = missileactive[v5]; +} + +//----- (004297EE) -------------------------------------------------------- +void __fastcall GetMissileVel(int i, int sx, int sy, int dx, int dy, int v) +{ + int v6; // eax + double v7; // ST18_8 + double v8; // ST10_8 + int v9; // esi + double v10; // st7 + + if ( dx != sx || dy != sy ) + { + v7 = (double)((dx + sy - sx - dy) << 21); + v8 = (double)((dy + dx - sx - sy) << 21); + v9 = i; + v10 = 1.0 / sqrt(v8 * v8 + v7 * v7); + missile[v9]._mixvel = (signed __int64)((double)(v << 16) * v7 * v10); + missile[v9]._miyvel = (signed __int64)((double)(v << 15) * v8 * v10); + } + else + { + v6 = i; + missile[v6]._mixvel = 0; + missile[v6]._miyvel = 0; + } +} + +//----- (004298AD) -------------------------------------------------------- +void __fastcall PutMissile(int i) +{ + int v1; // eax + int v2; // edx + int v3; // esi + int v4; // edx + _BYTE *v5; // edx + + v1 = i; + v2 = missile[i]._mix; + v3 = missile[i]._miy; + if ( v2 <= 0 || v3 <= 0 || v2 >= 112 || v3 >= 112 ) + missile[v1]._miDelFlag = 1; + if ( !missile[v1]._miDelFlag ) + { + v4 = v3 + 112 * v2; + dFlags[0][v4] |= 1u; + v5 = (unsigned char *)dMissile + v4; + if ( *v5 ) + *v5 = -1; + else + *v5 = i + 1; + if ( missile[v1]._miPreFlag ) + MissilePreFlag = 1; + } +} +// 64CCD4: using guessed type int MissilePreFlag; + +//----- (00429918) -------------------------------------------------------- +void __fastcall GetMissilePos(int i) +{ + int v1; // ecx + int v2; // eax + int v3; // esi + int v4; // edi + int v5; // edx + int v6; // edi + int v7; // esi + int v8; // edi + int v9; // edx + int v10; // esi + int v11; // edx + int v12; // [esp+Ch] [ebp-8h] + + v1 = i; + v2 = SHIWORD(missile[v1]._mityoff); + v3 = SHIWORD(missile[v1]._mitxoff); + v4 = 2 * v2 + v3; + v5 = 2 * v2 - v3; + if ( v4 >= 0 ) + { + v7 = v4 >> 3; + v8 = v4 >> 6; + } + else + { + v6 = -v4; + v7 = -(v6 >> 3); + v8 = -(v6 >> 6); + } + v12 = v7; + if ( v5 >= 0 ) + { + v10 = v5 >> 3; + v11 = v5 >> 6; + } + else + { + v9 = -v5; + v10 = -(v9 >> 3); + v11 = -(v9 >> 6); + } + missile[v1]._mix = v8 + missile[v1]._misx; + missile[v1]._miy = v11 + missile[v1]._misy; + missile[v1]._mixoff = SHIWORD(missile[v1]._mitxoff) + 32 * v11 - 32 * v8; + missile[v1]._miyoff = v2 - 16 * v11 - 16 * v8; + ChangeLightOff(missile[v1]._mlid, v12 - 8 * v8, v10 - 8 * v11); +} + +//----- (004299EA) -------------------------------------------------------- +void __fastcall MoveMissilePos(int i) +{ + int v1; // esi + signed int v2; // ebx + signed int v3; // edi + signed int v4; // [esp+Ch] [ebp-4h] + + v1 = i; + switch ( missile[i]._mimfnum ) + { + case 0: + case 1: + case 7: + v2 = 1; + goto LABEL_3; + case 2: + v2 = 0; +LABEL_3: + v3 = 1; + break; + case 3: + case 4: + case 5: + v2 = 0; + goto LABEL_7; + case 6: + v2 = 1; +LABEL_7: + v3 = 0; + break; + default: + v2 = v4; + v3 = v4; + break; + } + if ( PosOkMonst(missile[v1]._misource, v2 + missile[v1]._mix, v3 + missile[v1]._miy) ) + { + missile[v1]._mix += v2; + missile[v1]._miy += v3; + missile[v1]._mixoff += 32 * v3 - 32 * v2; + missile[v1]._miyoff -= 16 * v2 + 16 * v3; + } +} + +//----- (00429A99) -------------------------------------------------------- +unsigned char __fastcall MonsterTrapHit(int m, int mindam, int maxdam, int dist, int t, int shift) +{ + int v6; // esi + int v8; // ecx + int v9; // eax + int v10; // edi + int v11; // eax + int v12; // ecx + int v13; // eax + int v14; // [esp+Ch] [ebp-10h] + int v15; // [esp+10h] [ebp-Ch] + signed int v16; // [esp+14h] [ebp-8h] + signed int arglist; // [esp+18h] [ebp-4h] + + v16 = 0; + arglist = m; + v6 = m; + v15 = mindam; + if ( monster[m].mtalkmsg + || (signed int)(monster[v6]._mhitpoints & 0xFFFFFFC0) <= 0 + || monster[v6].MType->mtype == MON_SNEAKD && _LOBYTE(monster[v6]._mgoal) == 2 ) + { + return 0; + } + if ( monster[v6]._mmode == MM_CHARGE ) + return 0; + v8 = _LOWORD(monster[v6].mMagicRes); + v9 = missiledata[t].mResist; + if ( v8 & 8 ) + { + if ( v9 == 3 ) + return 0; + } + if ( v8 & 0x10 && v9 == 1 || v8 & 0x20 && v9 == 2 ) + return 0; + if ( v8 & 1 && v9 == 3 || v8 & 2 && v9 == 1 || v8 & 4 && v9 == 2 ) + v16 = 1; + _LOBYTE(v8) = 68; + v14 = random(v8, 100); + v10 = 90 - (unsigned char)monster[v6].mArmorClass - dist; + if ( v10 < 5 ) + v10 = 5; + if ( v10 > 95 ) + v10 = 95; + _LOBYTE(v11) = CheckMonsterHit(arglist, (unsigned char *)&t); + if ( v11 ) + return t; + if ( v14 >= v10 && monster[v6]._mmode != MM_STONE ) + return 0; + _LOBYTE(v12) = 68; + v13 = v15 + random(v12, maxdam - v15 + 1); + if ( !(_BYTE)shift ) + v13 <<= 6; + if ( v16 ) + monster[v6]._mhitpoints -= v13 >> 2; + else + monster[v6]._mhitpoints -= v13; + if ( (signed int)(monster[v6]._mhitpoints & 0xFFFFFFC0) > 0 ) + { + if ( v16 ) + { + PlayEffect(arglist, 1); + return 1; + } + if ( monster[v6]._mmode != MM_STONE ) + { + if ( arglist > 3 ) + M_StartHit(arglist, -1, v13); + return 1; + } + if ( arglist > 3 ) + M_StartHit(arglist, -1, v13); + } + else + { + if ( monster[v6]._mmode != MM_STONE ) + { + M_StartKill(arglist, -1); + return 1; + } + M_StartKill(arglist, -1); + } + monster[v6]._mmode = MM_STONE; + return 1; +} + +//----- (00429C3B) -------------------------------------------------------- +unsigned char __fastcall MonsterMHit(int pnum, int m, int mindam, int maxdam, int dist, int t, int shift) +{ + int v7; // edi + bool v8; // zf + short v9; // ax + int v10; // ecx + int v11; // eax + int v12; // esi + int v13; // ebx + char v14; // al + int v15; // eax + int v16; // eax + int v17; // ecx + int v19; // ebx + int v20; // ebx + int v21; // edx + int v22; // eax + int v23; // [esp+Ch] [ebp-18h] + unsigned char ret[4]; // [esp+10h] [ebp-14h] + int v25; // [esp+14h] [ebp-10h] + int v26; // [esp+18h] [ebp-Ch] + int pnuma; // [esp+1Ch] [ebp-8h] + char arglist[4]; // [esp+20h] [ebp-4h] + unsigned char dist_3; // [esp+37h] [ebp+13h] + + *(_DWORD *)arglist = m; + v7 = m; + v26 = 0; + v8 = monster[m].mtalkmsg == 0; + pnuma = pnum; + if ( !v8 + || (signed int)(monster[v7]._mhitpoints & 0xFFFFFFC0) <= 0 + || t == 53 && monster[v7].MType->mtype != MON_DIABLO && monster[v7].MData->mMonstClass ) + { + return 0; + } + if ( monster[v7].MType->mtype == MON_SNEAKD && _LOBYTE(monster[v7]._mgoal) == 2 ) + return 0; + if ( monster[v7]._mmode == MM_CHARGE ) + return 0; + v9 = monster[v7].mMagicRes; + v10 = missiledata[t].mResist; + v23 = t; + if ( v9 & 8 ) + { + if ( v10 == 3 ) + return 0; + } + if ( v9 & 0x10 && v10 == 1 || v9 & 0x20 && v10 == 2 || (v9 & 0x80u) != 0 && v10 == 4 ) + return 0; + if ( v9 & 1 && v10 == 3 || v9 & 2 && v10 == 1 || v9 & 4 && v10 == 2 ) + v26 = 1; + _LOBYTE(v10) = 69; + v11 = random(v10, 100); + v8 = missiledata[t].mType == 0; + v25 = v11; + if ( v8 ) + { + v12 = pnuma; + v13 = plr[v12]._pDexterity + + plr[v12]._pIBonusToHit + + plr[v12]._pLevel + - (unsigned char)monster[v7].mArmorClass + - (dist * dist >> 1) + + plr[pnuma]._pIEnAc + + 50; + v14 = plr[pnuma]._pClass; + if ( v14 == 1 ) + v13 = plr[v12]._pDexterity + + plr[v12]._pIBonusToHit + + plr[v12]._pLevel + - (unsigned char)monster[v7].mArmorClass + - (dist * dist >> 1) + + plr[pnuma]._pIEnAc + + 70; + if ( !v14 ) + v13 += 10; + } + else + { + v12 = pnuma; + v15 = 2 * SLOBYTE(monster[v7].mLevel); + v13 = plr[pnuma]._pMagic - v15 - dist + 50; + if ( _LOBYTE(plr[pnuma]._pClass) == 2 ) + v13 = plr[v12]._pMagic - v15 - dist + 70; + } + if ( v13 < 5 ) + v13 = 5; + if ( v13 > 95 ) + v13 = 95; + if ( monster[v7]._mmode == MM_STONE ) + v25 = 0; + _LOBYTE(v16) = CheckMonsterHit(*(int *)arglist, ret); + if ( v16 ) + return ret[0]; + if ( v25 >= v13 ) + return 0; + if ( t == 63 ) + { + v19 = monster[v7]._mhitpoints / 3 >> 6; + } + else + { + _LOBYTE(v17) = 70; + v19 = mindam + random(v17, maxdam - mindam + 1); + } + dist_3 = missiledata[v23].mType; + if ( !missiledata[v23].mType ) + { + v20 = plr[v12]._pIBonusDamMod + v19 * plr[v12]._pIBonusDam / 100 + v19; + if ( _LOBYTE(plr[v12]._pClass) == 1 ) + v19 = plr[v12]._pDamageMod + v20; + else + v19 = (plr[v12]._pDamageMod >> 1) + v20; + } + if ( !(_BYTE)shift ) + v19 <<= 6; + if ( v26 ) + v19 >>= 2; + v21 = pnuma; + if ( pnuma == myplr ) + monster[v7]._mhitpoints -= v19; + v22 = plr[v12]._pIFlags; + if ( v22 & 8 ) + monster[v7]._mFlags |= 8u; + if ( (signed int)(monster[v7]._mhitpoints & 0xFFFFFFC0) > 0 ) + { + if ( v26 ) + { + PlayEffect(*(int *)arglist, 1); + } + else if ( monster[v7]._mmode == MM_STONE ) + { + if ( *(_DWORD *)arglist > 3 ) + M_StartHit(*(int *)arglist, v21, v19); + monster[v7]._mmode = MM_STONE; + } + else + { + if ( !dist_3 && v22 & 0x800 ) + { + M_GetKnockback(*(int *)arglist); + v21 = pnuma; + } + if ( *(_DWORD *)arglist > 3 ) + M_StartHit(*(int *)arglist, v21, v19); + } + } + else if ( monster[v7]._mmode == MM_STONE ) + { + M_StartKill(*(int *)arglist, v21); + monster[v7]._mmode = MM_STONE; + } + else + { + M_StartKill(*(int *)arglist, v21); + } + if ( !_LOBYTE(monster[v7]._msquelch) ) + { + _LOBYTE(monster[v7]._msquelch) = -1; + monster[v7]._lastx = plr[v12].WorldX; + monster[v7]._lasty = plr[v12].WorldY; + } + return 1; +} + +//----- (00429F4E) -------------------------------------------------------- +unsigned char __fastcall PlayerMHit(int pnum, int m, int dist, int mind, int maxd, int mtype, int shift, int earflag) +{ + int v8; // ebx + int v9; // esi + int v10; // edi + int v11; // ecx + int v12; // eax + int v13; // edi + int v14; // edi + int v15; // eax + int v16; // eax + int v17; // ebx + int v18; // ebx + unsigned char v19; // al + int v20; // eax + int v21; // ecx + int v22; // ecx + int v23; // ecx + int v24; // edi + int v25; // ecx + int v26; // eax + char v27; // al + int v28; // ecx + int v29; // eax + int v30; // eax + int v32; // [esp+Ch] [ebp-14h] + int arglist; // [esp+14h] [ebp-Ch] + int v34; // [esp+18h] [ebp-8h] + int v35; // [esp+1Ch] [ebp-4h] + int dista; // [esp+28h] [ebp+8h] + + v8 = m; + arglist = pnum; + v9 = pnum; + v34 = m; + if ( (signed int)(plr[pnum]._pHitPoints & 0xFFFFFFC0) <= 0 + || plr[v9]._pInvincible + || plr[v9]._pSpellFlags & 1 && !missiledata[mtype].mType ) + { + return 0; + } + _LOBYTE(pnum) = 72; + v10 = 100; + v32 = random(pnum, 100); + if ( !missiledata[mtype].mType ) + { + v11 = 5; + v12 = plr[v9]._pIAC + plr[v9]._pIBonusAC + plr[v9]._pDexterity / 5; + if ( v8 != -1 ) + { + v11 = 2 * dist; + v13 = (unsigned char)monster[v8].mHit + + 2 * (SLOBYTE(monster[v8].mLevel) - plr[v9]._pLevel) + + 30 + - 2 * dist; +LABEL_8: + v14 = v13 - v12; + goto LABEL_14; + } + v15 = v12 >> 1; +LABEL_12: + v13 = v10 - v15; + v12 = 2 * dist; + goto LABEL_8; + } + if ( v8 != -1 ) + { + v10 = 2 * SLOBYTE(monster[v8].mLevel) + 40; + v15 = 2 * plr[v9]._pLevel; + goto LABEL_12; + } + v14 = 40; +LABEL_14: + if ( v14 < 10 ) + v14 = 10; + if ( currlevel == 14 ) + { + if ( v14 >= 20 ) + goto LABEL_25; + v14 = 20; + } + if ( currlevel == 15 ) + { + if ( v14 >= 25 ) + goto LABEL_25; + v14 = 25; + } + if ( currlevel == 16 && v14 < 30 ) + v14 = 30; +LABEL_25: + v16 = plr[v9]._pmode; + if ( v16 && v16 != 4 || !plr[v9]._pBlockFlag ) + { + v35 = 100; + } + else + { + _LOBYTE(v11) = 73; + v35 = random(v11, 100); + } + if ( (_BYTE)shift == 1 ) + v35 = 100; + if ( mtype == 59 ) + v35 = 100; + if ( v8 == -1 ) + v17 = plr[v9]._pBaseToBlk; + else + v17 = plr[v9]._pBaseToBlk + 2 * plr[v9]._pLevel - 2 * SLOBYTE(monster[v8].mLevel); + v18 = plr[v9]._pDexterity + v17; + if ( v18 < 0 ) + v18 = 0; + if ( v18 > 100 ) + v18 = 100; + v19 = missiledata[mtype].mResist; + if ( v19 == 1 ) + { + v20 = plr[v9]._pFireResist; + } + else if ( v19 == 2 ) + { + v20 = plr[v9]._pLghtResist; + } + else + { + if ( v19 <= 2u || v19 > 4u ) + { + dista = 0; + goto LABEL_50; + } + v20 = plr[v9]._pMagResist; + } + dista = v20; +LABEL_50: + if ( v32 < v14 ) + { + if ( mtype == 63 ) + { + v21 = plr[v9]._pHitPoints / 3; + } + else + { + _LOBYTE(v11) = 75; + if ( (_BYTE)shift ) + { + v23 = mind + random(v11, maxd - mind + 1); + if ( v34 == -1 && plr[v9]._pIFlags & 0x10000000 ) + v23 >>= 1; + v21 = plr[v9]._pIGetHit + v23; + } + else + { + v22 = (mind << 6) + random(v11, (maxd - mind + 1) << 6); + if ( v34 == -1 && plr[v9]._pIFlags & 0x10000000 ) + v22 >>= 1; + v21 = (plr[v9]._pIGetHit << 6) + v22; + } + if ( v21 < 64 ) + v21 = 64; + } + if ( dista <= 0 ) + { + if ( v35 < v18 ) + { + if ( v34 == -1 ) + v29 = plr[v9]._pdir; + else + v29 = GetDirection(plr[v9].WorldX, plr[v9].WorldY, monster[v34]._mx, monster[v34]._my); + StartPlrBlock(arglist, v29); + return 1; + } + v24 = arglist; + if ( arglist == myplr ) + { + plr[v9]._pHitPoints -= v21; + plr[v9]._pHPBase -= v21; + } + v30 = plr[v9]._pMaxHP; + if ( plr[v9]._pHitPoints > v30 ) + { + plr[v9]._pHitPoints = v30; + plr[v9]._pHPBase = plr[v9]._pMaxHPBase; + } + if ( (signed int)(plr[v9]._pHitPoints & 0xFFFFFFC0) > 0 ) + { + StartPlrHit(arglist, v21, 0); + return 1; + } + goto LABEL_70; + } + v24 = arglist; + v25 = dista * v21 / -100 + v21; + if ( arglist == myplr ) + { + plr[v9]._pHitPoints -= v25; + plr[v9]._pHPBase -= v25; + } + v26 = plr[v9]._pMaxHP; + if ( plr[v9]._pHitPoints > v26 ) + { + plr[v9]._pHitPoints = v26; + plr[v9]._pHPBase = plr[v9]._pMaxHPBase; + } + if ( (signed int)(plr[v9]._pHitPoints & 0xFFFFFFC0) <= 0 ) + { +LABEL_70: + SyncPlrKill(v24, earflag); + return 1; + } + v27 = plr[v9]._pClass; + if ( v27 ) + { + if ( v27 == 1 ) + { + v28 = PS_ROGUE69; + } + else + { + if ( v27 != 2 ) + { +LABEL_78: + drawhpflag = 1; + return 1; + } + v28 = PS_MAGE69; + } + } + else + { + v28 = PS_WARR69; + } + PlaySfxLoc(v28, plr[v9].WorldX, plr[v9].WorldY); + goto LABEL_78; + } + return 0; +} + +//----- (0042A307) -------------------------------------------------------- +unsigned char __fastcall Plr2PlrMHit(int pnum, int p, int mindam, int maxdam, int dist, int mtype, int shift) +{ + int v7; // edi + unsigned char v8; // al + int v9; // eax + int v10; // esi + int v11; // eax + int v12; // ecx + int v13; // eax + int v14; // ecx + bool v15; // sf + int v16; // ecx + int v17; // ebx + char v18; // al + int v19; // ecx + int v20; // eax + int v22; // [esp+Ch] [ebp-14h] + int v23; // [esp+10h] [ebp-10h] + int v24; // [esp+10h] [ebp-10h] + int arglist; // [esp+14h] [ebp-Ch] + int v26; // [esp+18h] [ebp-8h] + int v27; // [esp+1Ch] [ebp-4h] + int dista; // [esp+30h] [ebp+10h] + + arglist = p; + v7 = p; + v26 = pnum; + if ( plr[p]._pInvincible || mtype == 53 || plr[v7]._pSpellFlags & 1 && !missiledata[mtype].mType ) + return 0; + v22 = mtype; + v8 = missiledata[mtype].mResist; + if ( v8 == 1 ) + { + v9 = plr[v7]._pFireResist; + } + else if ( v8 == 2 ) + { + v9 = plr[v7]._pLghtResist; + } + else + { + if ( v8 <= 2u || v8 > 4u ) + { + v27 = 0; + goto LABEL_14; + } + v9 = plr[v7]._pMagResist; + } + v27 = v9; +LABEL_14: + _LOBYTE(pnum) = 69; + v23 = random(pnum, 100); + if ( missiledata[mtype].mType ) + { + v10 = v26; + v12 = 2 * plr[v7]._pLevel; + v11 = plr[v26]._pMagic - v12 - dist + 50; + if ( _LOBYTE(plr[v26]._pClass) == 2 ) + v11 = plr[v10]._pMagic - v12 - dist + 70; + } + else + { + v10 = v26; + v12 = plr[v10]._pIBonusToHit + + plr[v10]._pLevel + - (dist * dist >> 1) + - plr[v7]._pDexterity / 5 + - plr[v7]._pIBonusAC + - plr[v7]._pIAC; + v11 = v12 + plr[v26]._pDexterity + 50; + _LOBYTE(v12) = plr[v26]._pClass; + if ( (_BYTE)v12 == 1 ) + v11 += 20; + if ( !(_BYTE)v12 ) + v11 += 10; + } + if ( v11 < 5 ) + v11 = 5; + if ( v11 > 95 ) + v11 = 95; + if ( v23 < v11 ) + { + v13 = plr[v7]._pmode; + if ( v13 && v13 != 4 || !plr[v7]._pBlockFlag ) + { + v24 = 100; + } + else + { + _LOBYTE(v12) = 73; + v24 = random(v12, 100); + } + if ( (_BYTE)shift == 1 ) + v24 = 100; + v14 = plr[v7]._pBaseToBlk + 2 * plr[v7]._pLevel - 2 * plr[v10]._pLevel; + v15 = plr[v7]._pDexterity + v14 < 0; + v16 = plr[v7]._pDexterity + v14; + dista = v16; + if ( v15 ) + { + dista = 0; + v16 = 0; + } + if ( v16 > 100 ) + { + dista = 100; + v16 = 100; + } + if ( mtype == 63 ) + { + v17 = plr[v7]._pHitPoints / 3; + } + else + { + _LOBYTE(v16) = 70; + v17 = mindam + random(v16, maxdam - mindam + 1); + if ( !missiledata[v22].mType ) + v17 += plr[v10]._pIBonusDamMod + plr[v10]._pDamageMod + v17 * plr[v10]._pIBonusDam / 100; + v16 = dista; + if ( !(_BYTE)shift ) + v17 <<= 6; + } + if ( missiledata[v22].mType ) + v17 >>= 1; + if ( v27 <= 0 ) + { + if ( v24 >= v16 ) + { + if ( v26 == myplr ) + NetSendCmdDamage(1u, arglist, v17); + StartPlrHit(arglist, v17, 0); + } + else + { + v20 = GetDirection(plr[v7].WorldX, plr[v7].WorldY, plr[v10].WorldX, plr[v10].WorldY); + StartPlrBlock(arglist, v20); + } + return 1; + } + if ( v26 == myplr ) + NetSendCmdDamage(1u, arglist, v17 - v27 * v17 / 100); + v18 = plr[v10]._pClass; + if ( v18 ) + { + if ( v18 == 1 ) + { + v19 = PS_ROGUE69; + } + else + { + if ( v18 != 2 ) + return 1; + v19 = PS_MAGE69; + } + } + else + { + v19 = PS_WARR69; + } + PlaySfxLoc(v19, plr[v10].WorldX, plr[v10].WorldY); + return 1; + } + return 0; +} + +//----- (0042A5DB) -------------------------------------------------------- +void __fastcall CheckMissileCol(int i, int mindam, int maxdam, unsigned char shift, int mx, int my, int nodel, bool HurtPlr) +{ + int v8; // ebx + int v9; // esi + char v10; // dl + int v11; // ecx + int v12; // edi + int v13; // eax + int v14; // eax + char v15; // al + int v16; // ecx + int v17; // edx + int v18; // eax + int v19; // eax + int v20; // eax + char v21; // al + int v22; // eax + int v23; // eax + char v24; // al + char v25; // al + int v26; // edx + int v27; // ecx + int v28; // [esp-Ch] [ebp-1Ch] + int v29; // [esp-8h] [ebp-18h] + int mindama; // [esp+Ch] [ebp-4h] + + v8 = mindam; + v9 = i; + mindama = mindam; + v10 = missile[i]._miAnimType; + if ( v10 == 4 || (v11 = missile[v9]._misource, v11 == -1) ) + { + v12 = 112 * mx + my; + v22 = dMonster[0][v12]; + if ( v22 > 0 ) + { + v29 = missile[v9]._mitype; + v28 = missile[v9]._midist; + _LOBYTE(v23) = v10 == 4 ? MonsterMHit(missile[v9]._misource, v22 - 1, v8, maxdam, v28, v29, shift) : MonsterTrapHit(v22 - 1, v8, maxdam, v28, v29, shift); + if ( v23 ) + { + if ( !(_BYTE)nodel ) + missile[v9]._mirange = 0; + missile[v9]._miHitFlag = 1; + } + } + v24 = dPlayer[0][v12]; + if ( v24 > 0 ) + { + _LOBYTE(v18) = PlayerMHit( + v24 - 1, + -1, + missile[v9]._midist, + v8, + maxdam, + missile[v9]._mitype, + shift, + _LOBYTE(missile[v9]._miAnimType) == 4); +LABEL_35: + if ( v18 ) + { + if ( !(_BYTE)nodel ) + missile[v9]._mirange = 0; + missile[v9]._miHitFlag = 1; + } + goto LABEL_39; + } + } + else + { + if ( !missile[v9]._micaster ) + { + v12 = 112 * mx + my; + v13 = dMonster[0][v12]; + if ( v13 <= 0 ) + { + if ( v13 >= 0 || monster[-(v13 + 1)]._mmode != MM_STONE ) + { +LABEL_13: + v15 = dPlayer[0][v12]; + if ( v15 <= 0 ) + goto LABEL_39; + v16 = missile[v9]._misource; + v17 = v15 - 1; + if ( v17 == v16 ) + goto LABEL_39; + _LOBYTE(v18) = Plr2PlrMHit( + v16, + v17, + mindama, + maxdam, + missile[v9]._midist, + missile[v9]._mitype, + shift); + goto LABEL_35; + } + _LOBYTE(v14) = MonsterMHit( + v11, + -1 - v13, + mindama, + maxdam, + missile[v9]._midist, + missile[v9]._mitype, + shift); + } + else + { + _LOBYTE(v14) = MonsterMHit(v11, v13 - 1, v8, maxdam, missile[v9]._midist, missile[v9]._mitype, shift); + } + if ( v14 ) + { + if ( !(_BYTE)nodel ) + missile[v9]._mirange = 0; + missile[v9]._miHitFlag = 1; + } + goto LABEL_13; + } + if ( monster[v11]._mFlags & 0x10 ) + { + v19 = dMonster[0][my + 112 * mx]; + if ( v19 > 0 ) + { + if ( monstactive[57 * v19 + 184] & 0x20 ) + { + _LOBYTE(v20) = MonsterTrapHit( + v19 - 1, + mindama, + maxdam, + missile[v9]._midist, + missile[v9]._mitype, + shift); + if ( v20 ) + { + if ( !(_BYTE)nodel ) + missile[v9]._mirange = 0; + missile[v9]._miHitFlag = 1; + } + } + } + } + v12 = my + 112 * mx; + v21 = dPlayer[0][v12]; + if ( v21 > 0 ) + { + _LOBYTE(v18) = PlayerMHit( + v21 - 1, + missile[v9]._misource, + missile[v9]._midist, + mindama, + maxdam, + missile[v9]._mitype, + shift, + 0); + goto LABEL_35; + } + } +LABEL_39: + v25 = dObject[0][v12]; + if ( v25 ) + { + v26 = v25 <= 0 ? -1 - v25 : v25 - 1; + if ( !object[v26]._oMissFlag ) + { + if ( _LOBYTE(object[v26]._oBreak) == 1 ) + BreakObject(-1, v26); + if ( !(_BYTE)nodel ) + missile[v9]._mirange = 0; + missile[v9]._miHitFlag = 0; + } + } + if ( nMissileTable[dPiece[0][v12]] ) + { + if ( !(_BYTE)nodel ) + missile[v9]._mirange = 0; + missile[v9]._miHitFlag = 0; + } + if ( !missile[v9]._mirange ) + { + v27 = missiledata[missile[v9]._mitype].miSFX; + if ( v27 != -1 ) + PlaySfxLoc(v27, missile[v9]._mix, missile[v9]._miy); + } +} + +//----- (0042A8D5) -------------------------------------------------------- +void __fastcall SetMissAnim(int mi, int animtype) +{ + int v2; // ecx + int v3; // esi + int v4; // edi + int v5; // eax + int v6; // edx + int v7; // esi + int v8; // eax + int v9; // eax + int v10; // edi + int v11; // eax + + v2 = mi; + v3 = missile[v2]._mimfnum; + _LOBYTE(missile[v2]._miAnimType) = animtype; + v4 = misfiledata[animtype].mFlags; + v5 = v3 + 236 * animtype; + v6 = v3 + 59 * animtype; + v7 = misfiledata[0].mAnimDelay[v5]; + v8 = misfiledata[0].mAnimLen[v5]; + missile[v2]._miAnimCnt = 0; + missile[v2]._miAnimLen = v8; + v9 = misfiledata[0].mAnimWidth[v6]; + missile[v2]._miAnimFlags = v4; + v10 = misfiledata[0].mAnimCel[v6]; + missile[v2]._miAnimWidth = v9; + v11 = misfiledata[0].mAnimWidth2[v6]; + missile[v2]._miAnimCel = v10; + missile[v2]._miAnimDelay = v7; + missile[v2]._miAnimWidth2 = v11; + missile[v2]._miAnimFrame = 1; +} + +//----- (0042A959) -------------------------------------------------------- +void __fastcall SetMissDir(int mi, int dir) +{ + missile[mi]._mimfnum = dir; + SetMissAnim(mi, _LOBYTE(missile[mi]._miAnimType)); +} + +//----- (0042A973) -------------------------------------------------------- +void __fastcall LoadMissileGFX(int mi) +{ + MisFileData *v1; // esi + unsigned char *v2; // eax + signed int v3; // ecx + int *v4; // edx + int v5; // edi + unsigned char v6; // cl + int v7; // eax + _DWORD *v8; // edi + int v9; // ebx + char arglist[256]; // [esp+8h] [ebp-100h] + + v1 = &misfiledata[(unsigned char)mi]; + if ( v1->mFlags & 4 ) + { + sprintf(arglist, "Missiles\\%s.CL2", v1->mName); + v2 = LoadFileInMem(arglist, 0); + v3 = 0; + if ( v1->mAnimFAmt ) + { + v4 = v1->mAnimCel; + do + { + v5 = (int)&v2[*(_DWORD *)&v2[4 * v3++]]; + *v4 = v5; + ++v4; + } + while ( v3 < v1->mAnimFAmt ); + } + } + else + { + v6 = v1->mAnimFAmt; + if ( v6 == 1 ) + { + sprintf(arglist, "Missiles\\%s.CL2", v1->mName); + if ( !v1->mAnimCel[0] ) + v1->mAnimCel[0] = (int)LoadFileInMem(arglist, 0); + } + else + { + v7 = 0; + if ( v6 ) + { + v8 = (unsigned int *)v1->mAnimCel; + do + { + v9 = v7 + 1; + sprintf(arglist, "Missiles\\%s%i.CL2", v1->mName, v7 + 1); + if ( !*v8 ) + *v8 = (unsigned int)LoadFileInMem(arglist, 0); + v7 = v9; + ++v8; + } + while ( v9 < v1->mAnimFAmt ); + } + } + } +} + +//----- (0042AA5C) -------------------------------------------------------- +void __cdecl InitMissileGFX() +{ + char v0; // bl + unsigned char *v1; // esi + + v0 = 0; + if ( misfiledata[0].mAnimFAmt ) + { + v1 = &misfiledata[0].mAnimFAmt; + do + { + if ( !(v1[7] & 1) ) + LoadMissileGFX(v0); + v1 += 236; + ++v0; + } + while ( *v1 ); + } +} + +//----- (0042AA89) -------------------------------------------------------- +void __fastcall FreeMissileGFX(int mi) +{ + int v1; // esi + int v2; // ecx + signed int v3; // ebx + void **v4; // edi + void *v5; // ecx + + v1 = mi; + if ( misfiledata[mi].mFlags & 4 ) + { + v2 = misfiledata[v1].mAnimCel[0]; + if ( v2 ) + { + mem_free_dbg((void *)(v2 - 4 * misfiledata[v1].mAnimFAmt)); + misfiledata[v1].mAnimCel[0] = 0; + } + } + else + { + v3 = 0; + if ( misfiledata[v1].mAnimFAmt ) + { + v4 = (void **)misfiledata[v1].mAnimCel; + do + { + v5 = *v4; + if ( *v4 ) + { + *v4 = 0; + mem_free_dbg(v5); + } + ++v3; + ++v4; + } + while ( v3 < misfiledata[v1].mAnimFAmt ); + } + } +} + +//----- (0042AAF2) -------------------------------------------------------- +void __cdecl FreeMissiles() +{ + int v0; // edi + unsigned char *v1; // esi + + v0 = 0; + if ( misfiledata[0].mAnimFAmt ) + { + v1 = &misfiledata[0].mAnimFAmt; + do + { + if ( !(v1[7] & 1) ) + FreeMissileGFX(v0); + v1 += 236; + ++v0; + } + while ( *v1 ); + } +} + +//----- (0042AB20) -------------------------------------------------------- +void __cdecl FreeMissiles2() +{ + int v0; // edi + unsigned char *v1; // esi + + v0 = 0; + if ( misfiledata[0].mAnimFAmt ) + { + v1 = &misfiledata[0].mAnimFAmt; + do + { + if ( v1[7] & 1 ) + FreeMissileGFX(v0); + v1 += 236; + ++v0; + } + while ( *v1 ); + } +} + +//----- (0042AB4E) -------------------------------------------------------- +void __cdecl InitMissiles() +{ + int v0; // eax + int i; // esi + int v2; // eax + int v3; // eax + int v4; // edx + int *v5; // eax + signed int v6; // ecx + _BYTE *v7; // eax + signed int v8; // edx + + v0 = myplr; + _LOBYTE(plr[v0]._pSpellFlags) &= 0xFEu; + if ( plr[v0]._pInfraFlag == 1 ) + { + for ( i = 0; i < nummissiles; ++i ) + { + v2 = missileactive[i]; + if ( missile[v2]._mitype == MIS_INFRA ) + { + v3 = missile[v2]._misource; + if ( v3 == myplr ) + CalcPlrItemVals(v3, 1); + } + } + } + v4 = 0; + memset(missileactive, 0, sizeof(missileactive)); + nummissiles = 0; + do + { + missileavail[v4] = v4; + ++v4; + } + while ( v4 < 125 ); + END_unkmis_126 = 0; + v5 = &misflagstruct_unknown[0].field_4; + do + { + *(v5 - 1) = -1; + *v5 = 0; + v5[1] = 0; + v5 += 3; + } + while ( (signed int)v5 < (signed int)&END_unkmis_126 ); + v6 = 0; + do + { + v7 = (unsigned char *)dFlags + v6; + v8 = 112; + do + { + *v7 &= 0xFEu; + v7 += 112; + --v8; + } + while ( v8 ); + ++v6; + } + while ( v6 < 112 ); +} +// 64CCD8: using guessed type int END_unkmis_126; + +//----- (0042AC0C) -------------------------------------------------------- +void __fastcall AddLArrow(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam) +{ + int v9; // esi + int v10; // ebx + int v11; // edi + int v12; // eax + char v13; // dl + int v14; // eax + int v15; // esi + int v16; // [esp-4h] [ebp-14h] + int mia; // [esp+Ch] [ebp-4h] + + v9 = dx; + v10 = sx; + v11 = dy; + mia = mi; + if ( sx == dx && sy == dy ) + { + v9 = XDirAdd[midir] + dx; + v11 = YDirAdd[midir] + dy; + } + if ( (_BYTE)mienemy ) + { + v16 = 32; + goto LABEL_11; + } + v12 = id; + v13 = plr[id]._pClass; + if ( v13 == 1 ) + { + v16 = (plr[v12]._pLevel >> 2) + 31; +LABEL_11: + GetMissileVel(mi, v10, sy, v9, v11, v16); + goto LABEL_12; + } + if ( v13 ) + GetMissileVel(mi, v10, sy, v9, v11, 32); + else + GetMissileVel(mi, v10, sy, v9, v11, (plr[v12]._pLevel >> 3) + 31); +LABEL_12: + v14 = GetDirection16(v10, sy, v9, v11); + SetMissDir(mia, v14); + v15 = mia; + missile[v15]._mirange = 256; + missile[v15]._miVar1 = v10; + missile[v15]._miVar2 = sy; + missile[v15]._mlid = AddLight(v10, sy, 5); +} + +//----- (0042ACD9) -------------------------------------------------------- +void __fastcall AddArrow(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam) +{ + int v9; // ebx + int v10; // esi + int v11; // edi + int v12; // eax + char v13; // cl + int v14; // esi + int v15; // eax + int x1; // [esp+8h] [ebp-8h] + int i; // [esp+Ch] [ebp-4h] + + v9 = dy; + v10 = dx; + x1 = sx; + i = mi; + if ( sx == dx && sy == dy ) + { + v10 = XDirAdd[midir] + dx; + v9 = YDirAdd[midir] + dy; + dx += XDirAdd[midir]; + } + if ( (_BYTE)mienemy ) + { + GetMissileVel(mi, sx, sy, v10, v9, 32); + } + else + { + v11 = id; + v12 = 32; + if ( plr[id]._pIFlags & 4 ) + { + _LOBYTE(mi) = 64; + v12 = random(mi, 32) + 16; + } + v13 = plr[v11]._pClass; + if ( v13 == 1 ) + v12 += (plr[v11]._pLevel - 1) >> 2; + if ( !v13 ) + v12 += (plr[v11]._pLevel - 1) >> 3; + GetMissileVel(i, x1, sy, v10, v9, v12); + } + v14 = i; + v15 = GetDirection16(x1, sy, dx, v9); + missile[v14]._mirange = 256; + missile[v14]._miAnimFrame = v15 + 1; +} + +//----- (0042ADAA) -------------------------------------------------------- +void __fastcall GetVileMissPos(int mi, int dx, int dy) +{ + signed int v3; // edi + int v4; // ebx + int v5; // esi + int v6; // eax + int v7; // eax + int v8; // [esp+Ch] [ebp-14h] + int v9; // [esp+10h] [ebp-10h] + signed int v10; // [esp+14h] [ebp-Ch] + signed int v11; // [esp+18h] [ebp-8h] + signed int v12; // [esp+1Ch] [ebp-4h] + + v8 = dx; + v9 = mi; + v12 = 1; + v3 = -1; + do + { + v11 = v3; + if ( v3 <= v12 ) + { + while ( 2 ) + { + v10 = v3; + v4 = v11 + dy; + v5 = v3 + v8; + do + { + if ( PosOkPlayer(myplr, v5, v4) ) + { + v7 = v9; + missile[v7]._mix = v5; + missile[v7]._miy = v4; + return; + } + ++v10; + ++v5; + } + while ( v10 <= v12 ); + if ( ++v11 <= v12 ) + continue; + break; + } + } + ++v12; + --v3; + } + while ( v3 > -50 ); + v6 = v9; + missile[v6]._mix = v8; + missile[v6]._miy = dy; +} + +//----- (0042AE48) -------------------------------------------------------- +void __fastcall AddRndTeleport(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam) +{ + int v9; // eax + int v10; // ecx + int v11; // esi + int v12; // eax + int v13; // ecx + int v14; // edi + int v15; // ecx + int v16; // eax + bool v17; // zf + int v18; // ecx + int v19; // ecx + int v20; // [esp+Ch] [ebp-Ch] + int mia; // [esp+10h] [ebp-8h] + int v22; // [esp+14h] [ebp-4h] + + v22 = 0; + v20 = sx; + mia = mi; + while ( ++v22 <= 500 ) + { + _LOBYTE(mi) = 58; + v9 = random(mi, 3); + _LOBYTE(v10) = 58; + v11 = v9 + 4; + v12 = random(v10, 3); + _LOBYTE(v13) = 58; + v14 = v12 + 4; + if ( random(v13, 2) == 1 ) + v11 = -v11; + _LOBYTE(v15) = 58; + if ( random(v15, 2) == 1 ) + v14 = -v14; + mi = 4 * (sy + v14 + 112 * (v11 + v20)); + if ( !nSolidTable[dPiece[0][mi / 4u]] && !dObject[v11 + v20][sy + v14] && !dMonster[0][mi / 4u] ) + goto LABEL_12; + } + v11 = 0; + v14 = 0; +LABEL_12: + v16 = mia; + missile[v16]._miVar1 = 0; + v17 = setlevel == 0; + missile[v16]._mirange = 2; + if ( v17 || setlvlnum != SL_VILEBETRAYER ) + { + missile[v16]._mix = v20 + v11; + missile[v16]._miy = sy + v14; + if ( !(_BYTE)mienemy ) + UseMana(id, 10); + } + else + { + v18 = object[dObject[dx][dy] - 1]._otype; + if ( v18 == OBJ_MCIRCLE1 || v18 == OBJ_MCIRCLE2 ) + { + v19 = myplr; + missile[v16]._mix = dx; + missile[v16]._miy = dy; + if ( !PosOkPlayer(v19, dx, dy) ) + GetVileMissPos(mia, dx, dy); + } + } +} +// 5CCB10: using guessed type char setlvlnum; +// 5CF31D: using guessed type char setlevel; + +//----- (0042AF8B) -------------------------------------------------------- +void __fastcall AddFirebolt(int mi, int sx, int sy, int dx, int dy, int midir, int micaster, int id, int dam) +{ + int v9; // ebx + int v10; // esi + int v11; // edi + int v12; // eax + int v13; // eax + int v14; // eax + int v15; // esi + signed int v16; // [esp-4h] [ebp-14h] + int i; // [esp+Ch] [ebp-4h] + int micastera; // [esp+28h] [ebp+18h] + + v9 = dx; + v10 = dy; + v11 = sx; + i = mi; + if ( sx == dx && sy == dy ) + { + v9 = XDirAdd[midir] + dx; + v10 = YDirAdd[midir] + dy; + } + if ( (_BYTE)micaster ) + { + v16 = 26; + goto LABEL_17; + } + for ( micastera = 0; micastera < nummissiles; ++micastera ) + { + v12 = missileactive[micastera]; + if ( missile[v12]._mitype == 2 && missile[v12]._misource == id && missile[v12]._miVar3 == mi ) + break; + } + if ( micastera == nummissiles ) + UseMana(id, 1); + if ( id == -1 ) + { + v16 = 16; + goto LABEL_17; + } + v13 = 2 * missile[i]._mispllvl + 16; + if ( v13 >= 63 ) + { + v16 = 63; +LABEL_17: + v13 = v16; + } + GetMissileVel(i, v11, sy, v9, v10, v13); + v14 = GetDirection16(v11, sy, v9, v10); + SetMissDir(i, v14); + v15 = i; + missile[v15]._mirange = 256; + missile[v15]._miVar1 = v11; + missile[v15]._miVar2 = sy; + missile[v15]._mlid = AddLight(v11, sy, 8); +} + +//----- (0042B09A) -------------------------------------------------------- +void __fastcall AddMagmaball(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam) +{ + int v9; // esi + int v10; // edi + int i; // ST1C_4 + + v9 = mi; + v10 = sx; + i = mi; + GetMissileVel(mi, sx, sy, dx, dy, 16); + v9 *= 176; + *(int *)((char *)&missile[0]._mitxoff + v9) += 3 * *(int *)((char *)&missile[0]._mixvel + v9); + *(int *)((char *)&missile[0]._mityoff + v9) += 3 * *(int *)((char *)&missile[0]._miyvel + v9); + GetMissilePos(i); + *(int *)((char *)&missile[0]._mirange + v9) = 256; + *(int *)((char *)&missile[0]._miVar1 + v9) = v10; + *(int *)((char *)&missile[0]._miVar2 + v9) = sy; + *(int *)((char *)&missile[0]._mlid + v9) = AddLight(v10, sy, 8); +} + +//----- (0042B113) -------------------------------------------------------- +void __fastcall miss_null_33(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam) +{ + int v9; // esi + int v10; // edi + int v11; // eax + + v9 = sx; + v10 = mi; + GetMissileVel(mi, sx, sy, dx, dy, 16); + v11 = v10; + missile[v11]._mirange = 256; + missile[v11]._miVar1 = v9; + missile[v11]._miVar2 = sy; + PutMissile(v10); +} + +//----- (0042B159) -------------------------------------------------------- +void __fastcall AddTeleport(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam) +{ + int v9; // esi + int v10; // eax + int v11; // ecx + unsigned char *v12; // edx + int v13; // ecx + int v14; // eax + int v15; // edx + int v16; // ebx + int v17; // edi + int v18; // edx + int v19; // [esp+Ch] [ebp-28h] + int v20; // [esp+10h] [ebp-24h] + int v21; // [esp+14h] [ebp-20h] + int v22; // [esp+18h] [ebp-1Ch] + int v23; // [esp+1Ch] [ebp-18h] + int v24; // [esp+20h] [ebp-14h] + int v25; // [esp+24h] [ebp-10h] + unsigned char *v26; // [esp+28h] [ebp-Ch] + int v27; // [esp+2Ch] [ebp-8h] + int v28; // [esp+30h] [ebp-4h] + + v19 = 0; + v9 = mi; + v28 = 0; + v20 = 3; + v21 = 12; + v22 = 45; + v23 = 94; + v24 = 159; + missile[mi]._miDelFlag = 1; + do + { + v10 = *(&v19 + v28); + v11 = *(&CrawlTable.n_1 + v10); + v27 = *(&CrawlTable.n_1 + v10); + if ( v11 <= 0 ) + goto LABEL_13; + v12 = &CrawlTable.delta_1[0].y + v10; + v26 = &CrawlTable.delta_1[0].y + v10; + while ( 1 ) + { + v13 = dx + (char)*(v12 - 1); + v14 = dy + (char)*v12; + if ( v13 <= 0 || v13 >= 112 || v14 <= 0 || v14 >= 112 ) + goto LABEL_10; + v15 = v14 + 112 * v13; + v16 = dPlayer[0][v15]; + v17 = v15; + v18 = dObject[0][v15]; + v25 = v17 * 4; + if ( !(dMonster[0][v17] | v18 | v16 | (unsigned char)nSolidTable[dPiece[0][v17]]) ) + break; + v12 = v26; +LABEL_10: + v12 += 2; + --v27; + v26 = v12; + if ( v27 <= 0 ) + goto LABEL_13; + } + missile[v9]._miDelFlag = 0; + missile[v9]._mix = v13; + missile[v9]._miy = v14; + missile[v9]._misx = v13; + missile[v9]._misy = v14; + v28 = 6; +LABEL_13: + ++v28; + } + while ( v28 < 6 ); + if ( !missile[v9]._miDelFlag ) + { + UseMana(id, 23); + missile[v9]._mirange = 2; + } +} + +//----- (0042B284) -------------------------------------------------------- +void __fastcall AddLightball(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam) +{ + int v9; // edi + int v10; // esi + int v11; // esi + int v12; // ecx + int v13; // eax + int v14; // eax + + v9 = sx; + v10 = mi; + GetMissileVel(mi, sx, sy, dx, dy, 16); + v11 = v10; + _LOBYTE(v12) = 63; + missile[v11]._midam = dam; + v13 = random(v12, 8); + missile[v11]._mirange = 255; + missile[v11]._miAnimFrame = v13 + 1; + if ( id >= 0 ) + { + v14 = plr[id].WorldY; + missile[v11]._miVar1 = plr[id].WorldX; + missile[v11]._miVar2 = v14; + } + else + { + missile[v11]._miVar1 = v9; + missile[v11]._miVar2 = sy; + } +} + +//----- (0042B303) -------------------------------------------------------- +void __fastcall AddFirewall(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam) +{ + int v9; // ST20_4 + int i; // ST1C_4 + int v11; // esi + int v12; // eax + int v13; // ecx + int v14; // eax + int v15; // eax + int v16; // eax + + v9 = sx; + i = mi; + _LOBYTE(mi) = 53; + v11 = i; + v12 = random(mi, 10); + _LOBYTE(v13) = 53; + missile[v11]._midam = 16 * (random(v13, 10) + v12 + plr[id]._pLevel + 2) >> 1; + GetMissileVel(i, v9, sy, dx, dy, 16); + v14 = missile[i]._mispllvl; + missile[v11]._mirange = 10; + if ( v14 > 0 ) + missile[v11]._mirange = 2 * (5 * v14 + 5); + v15 = ((missile[v11]._mirange * plr[id]._pISplDur >> 3) & 0xFFFFFFF0) + 16 * missile[v11]._mirange; + missile[v11]._mirange = v15; + v16 = v15 - missile[v11]._miAnimLen; + missile[v11]._miVar2 = 0; + missile[v11]._miVar1 = v16; +} + +//----- (0042B3C0) -------------------------------------------------------- +void __fastcall AddFireball(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam) +{ + int v9; // edi + int v10; // eax + int v11; // ecx + int v12; // ecx + int v13; // edx + int v14; // esi + int v15; // eax + int v16; // esi + int i; // [esp+Ch] [ebp-4h] + int mienemya; // [esp+28h] [ebp+18h] + + v9 = sx; + i = mi; + if ( sx == dx ) + { + mi = dy; + if ( sy == dy ) + { + mi = YDirAdd[midir] + dy; + dx += XDirAdd[midir]; + dy += YDirAdd[midir]; + } + } + if ( (_BYTE)mienemy ) + { + v14 = 16; + } + else + { + _LOBYTE(mi) = 60; + v10 = random(mi, 10); + _LOBYTE(v11) = 60; + v12 = 2 * (plr[id]._pLevel + random(v11, 10) + v10) + 4; + v13 = missile[i]._mispllvl; + missile[i]._midam = v12; + if ( v13 > 0 ) + { + mienemya = v13; + do + { + v12 += v12 >> 3; + --mienemya; + } + while ( mienemya ); + missile[i]._midam = v12; + } + v14 = 2 * v13 + 16; + if ( v14 > 50 ) + v14 = 50; + UseMana(id, 12); + } + GetMissileVel(i, v9, sy, dx, dy, v14); + v15 = GetDirection16(v9, sy, dx, dy); + SetMissDir(i, v15); + v16 = i; + missile[v16]._miVar3 = 0; + missile[v16]._mirange = 256; + missile[v16]._miVar1 = v9; + missile[v16]._miVar2 = sy; + missile[v16]._miVar4 = v9; + missile[v16]._miVar5 = sy; + missile[v16]._mlid = AddLight(v9, sy, 8); +} + +//----- (0042B4E7) -------------------------------------------------------- +void __fastcall AddLightctrl(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam) +{ + int v9; // edi + int v10; // ebx + int v11; // esi + int v12; // ecx + int v13; // eax + + v9 = sx; + v10 = mi; + if ( !dam && !(_BYTE)mienemy ) + UseMana(id, 3); + v11 = v10; + missile[v11]._miVar1 = v9; + missile[v11]._miVar2 = sy; + GetMissileVel(v10, v9, sy, dx, dy, 32); + _LOBYTE(v12) = 52; + v13 = random(v12, 8); + missile[v11]._mirange = 256; + missile[v11]._miAnimFrame = v13 + 1; +} + +//----- (0042B553) -------------------------------------------------------- +void __fastcall AddLightning(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam) +{ + int v9; // esi + + v9 = mi; + missile[v9]._misx = dx; + missile[v9]._misy = dy; + if ( midir >= 0 ) + { + missile[v9]._mixoff = missile[midir]._mixoff; + missile[v9]._miyoff = missile[midir]._miyoff; + mi = missile[midir]._mitxoff; + missile[v9]._mitxoff = mi; + missile[v9]._mityoff = missile[midir]._mityoff; + } + _LOBYTE(mi) = 52; + missile[v9]._miAnimFrame = random(mi, 8) + 1; + if ( midir < 0 ) + goto LABEL_9; + if ( (_BYTE)mienemy == 1 ) + { + if ( id != -1 ) + { + missile[v9]._mirange = 10; + goto LABEL_10; + } +LABEL_9: + missile[v9]._mirange = 8; + goto LABEL_10; + } + if ( id == -1 ) + goto LABEL_9; + missile[v9]._mirange = (missile[v9]._mispllvl >> 1) + 6; +LABEL_10: + missile[v9]._mlid = AddLight(missile[v9]._mix, missile[v9]._miy, 4); +} + +//----- (0042B620) -------------------------------------------------------- +void __fastcall AddMisexp(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam) +{ + int v9; // edi + CMonster *v10; // esi + int v11; // eax + int v12; // ecx + + v9 = mi; + if ( (_BYTE)mienemy && id > 0 ) + { + v10 = monster[id].MType; + if ( v10->mtype == MON_SUCCA ) + SetMissAnim(mi, MFILE_FLAREEXP); + if ( v10->mtype == MON_SUCCB ) + SetMissAnim(v9, MFILE_SCBSEXPB); + if ( v10->mtype == MON_SUCCC ) + SetMissAnim(v9, MFILE_SCBSEXPD); + if ( v10->mtype == MON_SUCCD ) + SetMissAnim(v9, MFILE_SCBSEXPC); + } + v11 = v9; + missile[v11]._mix = missile[dx]._mix; + missile[v11]._miy = missile[dx]._miy; + missile[v11]._misx = missile[dx]._misx; + missile[v11]._misy = missile[dx]._misy; + missile[v11]._mixoff = missile[dx]._mixoff; + missile[v11]._miyoff = missile[dx]._miyoff; + missile[v11]._mitxoff = missile[dx]._mitxoff; + v12 = missile[dx]._mityoff; + missile[v11]._mixvel = 0; + missile[v11]._miyvel = 0; + missile[v11]._miVar1 = 0; + missile[v11]._mityoff = v12; + missile[v11]._mirange = missile[v9]._miAnimLen; +} + +//----- (0042B711) -------------------------------------------------------- +void __fastcall AddWeapexp(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam) +{ + int v9; // esi + + v9 = mi; + missile[v9]._miy = sy; + missile[v9]._misy = sy; + missile[v9]._mix = sx; + missile[v9]._misx = sx; + missile[v9]._mixvel = 0; + missile[v9]._miyvel = 0; + missile[v9]._miVar1 = 0; + missile[v9]._miVar2 = dx; + missile[v9]._mimfnum = 0; + if ( dx == 1 ) + SetMissAnim(mi, 5); + else + SetMissAnim(mi, MFILE_MINILTNG); + missile[v9]._mirange = missile[v9]._miAnimLen - 1; +} + +//----- (0042B77C) -------------------------------------------------------- +unsigned char __fastcall CheckIfTrig(int x, int y) +{ + int v2; // edi + int v3; // ebx + int *v4; // esi + int v5; // eax + int v7; // [esp+Ch] [ebp-4h] + + v7 = 0; + v2 = y; + v3 = x; + if ( trigflag[4] <= 0 ) + return 0; + v4 = &trigs[0]._ty; + while ( 1 ) + { + v5 = *(v4 - 1); + if ( v3 == v5 && v2 == *v4 ) + break; + if ( abs(v5 - v3) < 2 && abs(*v4 - v2) < 2 ) + break; + ++v7; + v4 += 4; + if ( v7 >= trigflag[4] ) + return 0; + } + return 1; +} + +//----- (0042B7DF) -------------------------------------------------------- +void __fastcall AddTown(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam) +{ + int v9; // ebx + int v10; // esi + int v11; // edi + int v12; // eax + int v13; // ecx + unsigned char *v14; // eax + int v15; // eax + int v16; // eax + int v17; // ecx + int v18; // eax + int v19; // eax + int v20; // ecx + int v21; // eax + int v22; // ST0C_4 + int v23; // [esp+Ch] [ebp-28h] + int v24; // [esp+10h] [ebp-24h] + int v25; // [esp+14h] [ebp-20h] + int v26; // [esp+18h] [ebp-1Ch] + int v27; // [esp+1Ch] [ebp-18h] + int v28; // [esp+20h] [ebp-14h] + int i; // [esp+24h] [ebp-10h] + unsigned char *v30; // [esp+28h] [ebp-Ch] + int v31; // [esp+2Ch] [ebp-8h] + int v32; // [esp+30h] [ebp-4h] + int x; // [esp+40h] [ebp+Ch] + + _LOBYTE(v9) = dx; + i = mi; + v10 = mi; + v23 = 0; + v24 = 3; + v25 = 12; + v26 = 45; + v27 = 94; + v28 = 159; + if ( currlevel ) + { + _LOBYTE(v11) = dx; + missile[v10]._miDelFlag = 1; + v31 = 0; + do + { + v12 = *(&v23 + v31); + v13 = *(&CrawlTable.n_1 + v12); + v32 = *(&CrawlTable.n_1 + v12); + if ( v13 > 0 ) + { + v14 = &CrawlTable.delta_1[0].y + v12; + v30 = v14; + while ( 1 ) + { + v9 = dx + (char)*(v14 - 1); + v11 = dy + (char)*v14; + if ( v9 > 0 && v9 < 112 && v11 > 0 && v11 < 112 ) + { + v15 = v11 + 112 * v9; + if ( !(dObject[0][v15] | dPlayer[0][v15] | dMissile[0][v15] | (unsigned char)nSolidTable[dPiece[0][v15]] | (unsigned char)nMissileTable[dPiece[0][v15]]) ) + { + _LOBYTE(v16) = CheckIfTrig(v9, v11); + if ( !v16 ) + break; + } + } + v14 = v30 + 2; + --v32; + v30 += 2; + if ( v32 <= 0 ) + goto LABEL_14; + } + missile[v10]._miDelFlag = 0; + missile[v10]._mix = v9; + missile[v10]._miy = v11; + missile[v10]._misx = v9; + missile[v10]._misy = v11; + v31 = 6; + } +LABEL_14: + ++v31; + } + while ( v31 < 6 ); + } + else + { + _LOBYTE(v11) = dy; + missile[v10]._mix = dx; + missile[v10]._miy = dy; + missile[v10]._misx = dx; + missile[v10]._misy = dy; + missile[v10]._miDelFlag = 0; + } + v17 = nummissiles; + missile[v10]._miVar2 = 0; + v32 = 0; + missile[v10]._mirange = 100; + for ( missile[v10]._miVar1 = 100 - missile[v10]._miAnimLen; v32 < v17; ++v32 ) + { + v18 = missileactive[v32]; + x = v18; + v19 = v18; + if ( missile[v19]._mitype == 10 && x != i && missile[v19]._misource == id ) + missile[v19]._mirange = 0; + } + PutMissile(i); + _HIWORD(v21) = _HIWORD(id); + if ( id == myplr && !missile[v10]._miDelFlag && currlevel ) + { + if ( setlevel ) + { + _LOWORD(v21) = (unsigned char)leveltype; + v22 = v21; + _LOWORD(v21) = (unsigned char)setlvlnum; + NetSendCmdLocParam3(1u, CMD_ACTIVATEPORTAL, v9, v11, v21, v22, 1); + } + else + { + _LOWORD(v20) = (unsigned char)leveltype; + _LOWORD(v21) = currlevel; + NetSendCmdLocParam3(1u, CMD_ACTIVATEPORTAL, v9, v11, v21, v20, 0); + } + } +} +// 5BB1ED: using guessed type char leveltype; +// 5CCB10: using guessed type char setlvlnum; +// 5CF31D: using guessed type char setlevel; + +//----- (0042B9FC) -------------------------------------------------------- +void __fastcall AddFlash(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam) +{ + int v9; // esi + signed int v10; // ebx + char *v11; // edi + int v12; // ecx + int v13; // eax + int v14; // eax + + v9 = mi; + if ( (_BYTE)mienemy ) + { + v14 = 2 * SLOBYTE(monster[id].mLevel); + goto LABEL_12; + } + if ( id == -1 ) + { + v14 = (unsigned int)currlevel >> 1; +LABEL_12: + missile[v9]._midam = v14; + goto LABEL_13; + } + v10 = 0; + v11 = &plr[id]._pLevel; + missile[v9]._midam = 0; + if ( *v11 >= 0 ) + { + do + { + _LOBYTE(mi) = 55; + missile[v9]._midam += random(mi, 20) + 1; + ++v10; + } + while ( v10 <= *v11 ); + } + v12 = missile[v9]._mispllvl; + if ( v12 > 0 ) + { + v13 = missile[v9]._midam; + do + { + v13 += v13 >> 3; + --v12; + } + while ( v12 ); + missile[v9]._midam = v13; + } + missile[v9]._midam += missile[v9]._midam >> 1; +LABEL_13: + missile[v9]._mirange = 19; +} + +//----- (0042BAC1) -------------------------------------------------------- +void __fastcall AddFlash2(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam) +{ + int v9; // esi + char *v10; // edi + signed int v11; // ebx + int v12; // ecx + int v13; // eax + int v14; // eax + int v15; // [esp+4h] [ebp-4h] + + v15 = mi; + if ( !(_BYTE)mienemy ) + { + if ( id == -1 ) + { + missile[mi]._midam = (unsigned int)currlevel >> 1; + } + else + { + v9 = mi; + v10 = &plr[id]._pLevel; + v11 = 0; + for ( missile[mi]._midam = 0; v11 <= *v10; ++v11 ) + { + _LOBYTE(mi) = 56; + missile[v9]._midam += random(mi, 2) + 1; + } + v12 = missile[v9]._mispllvl; + if ( v12 > 0 ) + { + v13 = missile[v9]._midam; + do + { + v13 += v13 >> 3; + --v12; + } + while ( v12 ); + missile[v9]._midam = v13; + } + missile[v9]._midam += missile[v9]._midam >> 1; + } + } + v14 = v15; + missile[v14]._miPreFlag = 1; + missile[v14]._mirange = 19; +} + +//----- (0042BB83) -------------------------------------------------------- +void __fastcall AddManashield(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam) +{ + int v9; // eax + + v9 = mi; + missile[v9]._miVar8 = -1; + missile[v9]._mirange = 48 * plr[id]._pLevel; + missile[v9]._miVar1 = plr[id]._pHitPoints; + missile[v9]._miVar2 = plr[id]._pHPBase; + if ( !(_BYTE)mienemy ) + UseMana(id, 11); + if ( id == myplr ) + NetSendCmd(1u, CMD_SETSHIELD); + plr[id].pManaShield = 1; +} + +//----- (0042BBFA) -------------------------------------------------------- +void __fastcall AddFiremove(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam) +{ + int v9; // edi + int v10; // ebx + int v11; // esi + + v9 = mi; + v10 = sx; + v11 = mi; + _LOBYTE(mi) = 59; + v11 *= 176; + *(int *)((char *)&missile[0]._midam + v11) = random(mi, 10) + plr[id]._pLevel + 1; + GetMissileVel(v9, v10, sy, dx, dy, 16); + *(int *)((char *)&missile[0]._miVar1 + v11) = 0; + *(int *)((char *)&missile[0]._miVar2 + v11) = 0; + ++*(int *)((char *)&missile[0]._mix + v11); + ++*(int *)((char *)&missile[0]._miy + v11); + *(int *)((char *)&missile[0]._miyoff + v11) -= 32; + *(int *)((char *)&missile[0]._mirange + v11) = 255; +} + +//----- (0042BC76) -------------------------------------------------------- +void __fastcall AddGuardian(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam) +{ + int v9; // edi + int v10; // esi + int v11; // esi + int v12; // eax + int v13; // ecx + int v14; // eax + int v15; // ecx + unsigned char *v16; // eax + int v17; // ebx + int v18; // edi + int v19; // eax + int v20; // edx + int v21; // ecx + int v22; // eax + int v23; // ecx + int v24; // eax + int v25; // eax + int v26; // eax + int v27; // eax + int v28; // [esp+8h] [ebp-38h] + int v29; // [esp+Ch] [ebp-34h] + int v30; // [esp+10h] [ebp-30h] + int v31; // [esp+14h] [ebp-2Ch] + int v32; // [esp+18h] [ebp-28h] + int v33; // [esp+1Ch] [ebp-24h] + unsigned int v34; // [esp+20h] [ebp-20h] + int v35; // [esp+24h] [ebp-1Ch] + int v36; // [esp+28h] [ebp-18h] + int x1; // [esp+2Ch] [ebp-14h] + int v38; // [esp+30h] [ebp-10h] + unsigned char *v39; // [esp+34h] [ebp-Ch] + int v40; // [esp+38h] [ebp-8h] + int v41; // [esp+3Ch] [ebp-4h] + + v28 = 0; + v9 = 21720 * id; + x1 = sx; + v10 = mi; + _LOBYTE(mi) = 62; + v29 = 3; + v30 = 12; + v31 = 45; + v32 = 94; + v33 = 159; + v38 = 21720 * id; + v11 = v10; + v12 = random(mi, 10) + (plr[id]._pLevel >> 1) + 1; + v13 = missile[v11]._mispllvl; + missile[v11]._midam = v12; + if ( v13 > 0 ) + { + do + { + v12 += v12 >> 3; + --v13; + } + while ( v13 ); + missile[v11]._midam = v12; + } + v41 = 0; + missile[v11]._miDelFlag = 1; + do + { + v14 = *(&v28 + v41); + v15 = *(&CrawlTable.n_1 + v14); + v40 = *(&CrawlTable.n_1 + v14); + if ( v15 <= 0 ) + goto LABEL_18; + v16 = &CrawlTable.delta_1[0].y + v14; + v39 = v16; + while ( 1 ) + { + v17 = dx + (char)*(v16 - 1); + v18 = dy + (char)*v16; + v35 = v18 + 112 * (dx + (char)*(v16 - 1)); + v34 = 4 * v35; + v36 = dPiece[0][v35]; + if ( v17 <= 0 || v17 >= 112 || v18 <= 0 || v18 >= 112 ) + goto LABEL_14; + _LOBYTE(v19) = LineClear(x1, sy, v17, v18); + if ( v19 ) + { + if ( !(dMonster[0][v34 / 4] | dObject[0][v35] | dMissile[0][v35] | (unsigned char)nSolidTable[v36] | (unsigned char)nMissileTable[v36]) ) + break; + } + v16 = v39; +LABEL_14: + v16 += 2; + --v40; + v39 = v16; + if ( v40 <= 0 ) + goto LABEL_17; + } + missile[v11]._miDelFlag = 0; + missile[v11]._mix = v17; + missile[v11]._miy = v18; + missile[v11]._misx = v17; + missile[v11]._misy = v18; + UseMana(id, 13); + v41 = 6; +LABEL_17: + v9 = v38; +LABEL_18: + ++v41; + } + while ( v41 < 6 ); + if ( missile[v11]._miDelFlag != 1 ) + { + v20 = missile[v11]._miy; + v21 = missile[v11]._mix; + missile[v11]._misource = id; + v22 = AddLight(v21, v20, 1); + v23 = missile[v11]._mispllvl; + missile[v11]._mlid = v22; + v24 = v23 + (*(&plr[0]._pLevel + v9) >> 1); + v25 = (v24 * *(int *)((char *)&plr[0]._pISplDur + v9) >> 7) + v24; + missile[v11]._mirange = v25; + if ( v25 > 30 ) + missile[v11]._mirange = 30; + missile[v11]._mirange *= 16; + if ( missile[v11]._mirange < 30 ) + missile[v11]._mirange = 30; + v26 = missile[v11]._mirange; + missile[v11]._miVar3 = 1; + v27 = v26 - missile[v11]._miAnimLen; + missile[v11]._miVar2 = 0; + missile[v11]._miVar1 = v27; + } +} + +//----- (0042BE98) -------------------------------------------------------- +void __fastcall AddChain(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam) +{ + int v9; // ecx + + v9 = mi; + missile[v9]._miVar1 = dx; + missile[v9]._miVar2 = dy; + missile[v9]._mirange = 1; +} + +//----- (0042BECB) -------------------------------------------------------- +void __fastcall miss_null_11(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam) +{ + int v9; // esi + int v10; // eax + + v9 = mi; + SetMissDir(mi, dx); + v10 = v9; + missile[v10]._midam = 0; + missile[v10]._miLightFlag = 1; + missile[v10]._mirange = 250; +} + +//----- (0042BEFE) -------------------------------------------------------- +void __fastcall miss_null_12(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam) +{ + signed int v9; // edx + int v10; // esi + int v11; // eax + + v9 = dx; + v10 = mi; + if ( dx > 3 ) + v9 = 2; + SetMissDir(mi, v9); + v11 = v10; + missile[v11]._midam = 0; + missile[v11]._miLightFlag = 1; + missile[v11]._mirange = 250; +} + +//----- (0042BF3B) -------------------------------------------------------- +void __fastcall miss_null_13(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam) +{ + signed int v9; // edx + int v10; // esi + int v11; // eax + int v12; // ecx + + v9 = dx; + v10 = mi; + if ( dx > 3 ) + v9 = 2; + SetMissDir(mi, v9); + v11 = v10; + v12 = missile[v10]._miAnimLen; + missile[v11]._midam = 0; + missile[v11]._miLightFlag = 1; + missile[v11]._mirange = v12; +} + +//----- (0042BF7A) -------------------------------------------------------- +void __fastcall AddRhino(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam) +{ + int v9; // esi + CMonster *v10; // eax + char v11; // cl + int v12; // edi + int v13; // eax + CMonster *v14; // ecx + char v15; // cl + bool v16; // zf + int i; // [esp+8h] [ebp-4h] + + v9 = id; + i = mi; + v10 = monster[id].MType; + v11 = v10->mtype; + if ( v10->mtype < MON_RHINOA || v11 > MON_RHINOD ) + { + if ( v11 < MON_SNAKEA || (v12 = (int)v10->Anims[2].Frames, v11 > MON_SNAKED) ) + v12 = (int)v10->Anims[1].Frames; + } + else + { + v12 = (int)v10->Anims[5].Frames; + } + GetMissileVel(i, sx, sy, dx, dy, 18); + v13 = i; + missile[v13]._miAnimFlags = 0; + missile[v13]._mimfnum = midir; + missile[v13]._miAnimCel = *(_DWORD *)(v12 + 4 * midir + 4); + missile[v13]._miAnimDelay = *(_DWORD *)(v12 + 40); + missile[v13]._miAnimLen = *(_DWORD *)(v12 + 36); + v14 = monster[v9].MType; + missile[v13]._miAnimWidth = v14->flags_1; + missile[v13]._miAnimWidth2 = v14->flags_2; + missile[v13]._miAnimAdd = 1; + v15 = v14->mtype; + if ( v15 >= MON_SNAKEA && v15 <= MON_SNAKED ) + missile[v13]._miAnimFrame = 7; + missile[v13]._miVar1 = 0; + missile[v13]._miVar2 = 0; + v16 = monster[v9]._uniqtype == 0; + missile[v13]._miLightFlag = 1; + if ( !v16 ) + { + missile[v13]._miUniqTrans = (unsigned char)monster[v9]._uniqtrans + 1; + missile[v13]._mlid = (unsigned char)monster[v9].mlid; + } + missile[v13]._mirange = 256; + PutMissile(i); +} + +//----- (0042C08B) -------------------------------------------------------- +void __fastcall miss_null_32(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam) +{ + int v9; // esi + int v10; // ebx + AnimStruct *v11; // edi + int v12; // eax + CMonster *v13; // ecx + bool v14; // zf + int v15; // ecx + + v9 = id; + v10 = mi; + v11 = &monster[id].MType->Anims[1]; + GetMissileVel(mi, sx, sy, dx, dy, 16); + v12 = v10; + missile[v12]._mimfnum = midir; + missile[v12]._miAnimFlags = 0; + missile[v12]._miAnimCel = v11->Frames[midir + 1]; + missile[v12]._miAnimDelay = v11->Delay; + missile[v12]._miAnimLen = v11->Rate; + v13 = monster[id].MType; + missile[v12]._miAnimWidth = v13->flags_1; + missile[v12]._miAnimWidth2 = v13->flags_2; + v14 = monster[id]._uniqtype == 0; + missile[v12]._miAnimAdd = 1; + missile[v12]._miVar1 = 0; + missile[v12]._miVar2 = 0; + missile[v12]._miLightFlag = 1; + if ( !v14 ) + missile[v12]._miUniqTrans = (unsigned char)monster[v9]._uniqtrans + 1; + v15 = monster[v9]._mx; + missile[v12]._mirange = 256; + dMonster[0][monster[v9]._my + 112 * v15] = 0; + PutMissile(v10); +} + +//----- (0042C167) -------------------------------------------------------- +void __fastcall AddFlare(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam) +{ + int v9; // edi + int v10; // edx + int v11; // esi + int v12; // ecx + int v13; // esi + int v14; // eax + CMonster *v15; // esi + int code; // [esp+Ch] [ebp-4h] + + v9 = sx; + v10 = dx; + v11 = mi; + v12 = dy; + code = v11; + if ( v9 == dx && sy == dy ) + { + v10 = XDirAdd[midir] + dx; + v12 = YDirAdd[midir] + dy; + } + GetMissileVel(v11, v9, sy, v10, v12, 16); + v13 = v11; + missile[v13]._mirange = 256; + missile[v13]._miVar1 = v9; + missile[v13]._miVar2 = sy; + missile[v13]._mlid = AddLight(v9, sy, 8); + if ( (_BYTE)mienemy ) + { + if ( id > 0 ) + { + v15 = monster[id].MType; + if ( v15->mtype == MON_SUCCA ) + SetMissAnim(code, MFILE_FLARE); + if ( v15->mtype == MON_SUCCB ) + SetMissAnim(code, MFILE_SCUBMISB); + if ( v15->mtype == MON_SUCCC ) + SetMissAnim(code, MFILE_SCUBMISD); + if ( v15->mtype == MON_SUCCD ) + SetMissAnim(code, MFILE_SCUBMISC); + } + } + else + { + UseMana(id, 35); + v14 = id; + drawhpflag = 1; + plr[v14]._pHPBase -= 320; + plr[v14]._pHitPoints -= 320; + if ( plr[id]._pHitPoints <= 0 ) + SyncPlrKill(id, 0); + } +} + +//----- (0042C276) -------------------------------------------------------- +void __fastcall AddAcid(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam) +{ + int v9; // esi + int v10; // edi + int v11; // eax + int v12; // eax + int v13; // ecx + + v9 = sx; + v10 = mi; + GetMissileVel(mi, sx, sy, dx, dy, 16); + v11 = GetDirection16(v9, sy, dx, dy); + SetMissDir(v10, v11); + v12 = v10; + v13 = (unsigned char)monster[id]._mint; + missile[v12]._mlid = -1; + missile[v12]._miVar1 = v9; + missile[v12]._miVar2 = sy; + missile[v12]._mirange = 5 * (v13 + 4); + PutMissile(v10); +} + +//----- (0042C2EE) -------------------------------------------------------- +void __fastcall miss_null_1D(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam) +{ + int v9; // ecx + int v10; // eax + + v9 = mi; + missile[v9]._midam = dam; + missile[v9]._mirange = 50; + v10 = 50 - missile[v9]._miAnimLen; + missile[v9]._mixvel = 0; + missile[v9]._miyvel = 0; + missile[v9]._miVar1 = v10; + missile[v9]._miVar2 = 0; +} + +//----- (0042C32A) -------------------------------------------------------- +void __fastcall AddAcidpud(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam) +{ + int v9; // esi + int v10; // edi + int v11; // eax + + v9 = mi; + v10 = missile[mi]._misource; + _LOBYTE(mi) = 50; + missile[v9]._mixvel = 0; + missile[v9]._miyvel = 0; + missile[v9]._mixoff = 0; + missile[v9]._miyoff = 0; + missile[v9]._miLightFlag = 1; + v11 = random(mi, 15); + missile[v9]._miPreFlag = 1; + missile[v9]._mirange = v11 + 40 * ((unsigned char)monster[v10]._mint + 1); +} + +//----- (0042C38E) -------------------------------------------------------- +void __fastcall AddStone(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam) +{ + int v9; // eax + int v10; // edx + int v11; // esi + int v12; // edi + int v13; // ecx + unsigned char *v14; // ecx + int v15; // ebx + int v16; // ebx + int v17; // edi + int *v18; // edi + int v19; // ecx + int v20; // edx + int v21; // ecx + int v22; // edx + int *v23; // eax + int v24; // [esp+Ch] [ebp-20h] + int v25; // [esp+10h] [ebp-1Ch] + int v26; // [esp+14h] [ebp-18h] + int v27; // [esp+18h] [ebp-14h] + int v28; // [esp+1Ch] [ebp-10h] + int v29; // [esp+20h] [ebp-Ch] + int v30; // [esp+24h] [ebp-8h] + int v31; // [esp+28h] [ebp-4h] + + v9 = mi; + v24 = 0; + v31 = 0; + v10 = id; + v11 = id; + v25 = 3; + v26 = 12; + v27 = 45; + v28 = 94; + v29 = 159; + missile[mi]._misource = id; + do + { + v12 = *(&v24 + v31); + v13 = *(&CrawlTable.n_1 + v12); + v30 = *(&CrawlTable.n_1 + v12); + if ( v13 > 0 ) + { + v14 = &CrawlTable.delta_1[0].y + v12; + while ( 1 ) + { + v10 = dx + (char)*(v14 - 1); + v11 = dy + (char)*v14; + if ( v10 > 0 && v10 < 112 && v11 > 0 && v11 < 112 ) + { + v15 = dMonster[0][v11 + 112 * v10]; + v16 = v15 <= 0 ? -1 - v15 : v15 - 1; + if ( v16 > 3 && monster[v16]._mAi != MG_DIABLO ) + { + v17 = monster[v16]._mmode; + if ( v17 != MM_FADEIN && v17 != MM_FADEOUT && v17 != MM_CHARGE ) + break; + } + } + v14 += 2; + if ( --v30 <= 0 ) + goto LABEL_19; + } + v30 = -99; + v31 = 6; + missile[v9]._miVar2 = v16; + v18 = (int *)&monster[v16]._mmode; + v19 = *v18; + *v18 = MM_STONE; + missile[v9]._miVar1 = v19; + } +LABEL_19: + ++v31; + } + while ( v31 < 6 ); + if ( v30 == -99 ) + { + missile[v9]._mix = v10; + missile[v9]._misx = v10; + v20 = missile[v9]._mispllvl + 6; + v21 = v20 * plr[id]._pISplDur >> 7; + missile[v9]._miy = v11; + missile[v9]._misy = v11; + v22 = v21 + v20; + v23 = &missile[v9]._mirange; + *v23 = v22; + if ( v22 > 15 ) + *v23 = 15; + *v23 *= 16; + UseMana(id, 8); + } + else + { + missile[v9]._miDelFlag = 1; + } +} + +//----- (0042C518) -------------------------------------------------------- +void __fastcall AddGolem(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam) +{ + int v9; // eax + int v10; // ebx + int v11; // edi + int v12; // ecx + bool v13; // zf + bool v14; // sf + int v15; // esi + int v16; // esi + int v17; // [esp+Ch] [ebp-8h] + int v18; // [esp+10h] [ebp-4h] + + v18 = mi; + v9 = mi; + v10 = id; + v11 = nummissiles; + v12 = 0; + v13 = nummissiles == 0; + v14 = nummissiles < 0; + missile[v9]._miDelFlag = 0; + if ( v14 || v13 ) + { +LABEL_6: + missile[v9]._miVar1 = sx; + missile[v9]._miVar2 = sy; + missile[v9]._miVar4 = dx; + missile[v9]._miVar5 = dy; + if ( (monster[v10]._mx != 1 || monster[v10]._my) && v10 == myplr ) + M_StartKill(v10, v10); + } + else + { + while ( 1 ) + { + v15 = missileactive[v12]; + v17 = v15; + v16 = v15; + if ( missile[v16]._mitype == 33 ) + { + v10 = id; + if ( v17 != v18 && missile[v16]._misource == id ) + break; + } + if ( ++v12 >= v11 ) + goto LABEL_6; + } + missile[v9]._miDelFlag = 1; + } +} + +//----- (0042C5DA) -------------------------------------------------------- +void __fastcall AddEtherealize(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam) +{ + int v9; // edx + int v10; // eax + int v11; // ecx + int v12; // esi + int v13; // esi + int v14; // ecx + + v9 = id; + v10 = mi; + v11 = missile[mi]._mispllvl; + v12 = 16 * plr[id]._pLevel >> 1; + missile[v10]._mirange = v12; + if ( v11 > 0 ) + { + do + { + v12 += v12 >> 3; + --v11; + } + while ( v11 ); + missile[v10]._mirange = v12; + } + v13 = missile[v10]._mirange + (missile[v10]._mirange * plr[v9]._pISplDur >> 7); + missile[v10]._miVar1 = plr[v9]._pHitPoints; + v14 = plr[v9]._pHPBase; + missile[v10]._mirange = v13; + missile[v10]._miVar2 = v14; + if ( !(_BYTE)mienemy ) + UseMana(id, 25); +} + +//----- (0042C664) -------------------------------------------------------- +void __fastcall miss_null_1F(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam) +{ + missile[mi]._miDelFlag = 1; +} + +//----- (0042C677) -------------------------------------------------------- +void __fastcall miss_null_23(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam) +{ + int v9; // esi + int v10; // edx + int v11; // eax + + v9 = mi; + missile[v9]._mix = sx; + missile[v9]._miy = sy; + missile[v9]._misx = sx; + missile[v9]._misy = sy; + v10 = 0; + missile[v9]._midam = dam; + missile[v9]._misource = id; + if ( dam != 1 ) + v10 = 1; + SetMissDir(mi, v10); + v11 = missile[v9]._miAnimLen; + missile[v9]._miLightFlag = 1; + missile[v9]._mirange = v11; +} + +//----- (0042C6D9) -------------------------------------------------------- +void __fastcall AddBoom(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam) +{ + int v9; // ecx + int v10; // edx + + v9 = mi; + missile[v9]._miy = dy; + missile[v9]._misy = dy; + missile[v9]._mix = dx; + missile[v9]._misx = dx; + missile[v9]._midam = dam; + v10 = missile[v9]._miAnimLen; + missile[v9]._mixvel = 0; + missile[v9]._miyvel = 0; + missile[v9]._mirange = v10; + missile[v9]._miVar1 = 0; +} + +//----- (0042C72C) -------------------------------------------------------- +void __fastcall AddHeal(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam) +{ + int v9; // esi + signed int v10; // ebx + int v11; // ecx + int v12; // edi + int i; // ebx + char v14; // al + int v15; // ecx + int *v16; // eax + int *v17; // eax + int v18; // esi + int v19; // [esp+Ch] [ebp-8h] + int v20; // [esp+10h] [ebp-4h] + + v19 = mi; + _LOBYTE(mi) = 57; + v9 = id; + v10 = 0; + v12 = (random(mi, 10) + 1) << 6; + if ( plr[id]._pLevel > 0 ) + { + do + { + _LOBYTE(v11) = 57; + v12 += (random(v11, 4) + 1) << 6; + ++v10; + } + while ( v10 < plr[v9]._pLevel ); + } + v20 = 0; + for ( i = v19; v20 < missile[i]._mispllvl; ++v20 ) + { + _LOBYTE(v11) = 57; + v12 += (random(v11, 6) + 1) << 6; + } + v14 = plr[v9]._pClass; + if ( !v14 ) + v12 *= 2; + if ( v14 == 1 ) + v12 += v12 >> 1; + v15 = plr[v9]._pMaxHP; + v16 = &plr[v9]._pHitPoints; + *v16 += v12; + if ( plr[v9]._pHitPoints > v15 ) + *v16 = v15; + v17 = &plr[v9]._pHPBase; + v18 = plr[v9]._pMaxHPBase; + *v17 += v12; + if ( *v17 > v18 ) + *v17 = v18; + missile[i]._miDelFlag = 1; + drawhpflag = 1; +} + +//----- (0042C80C) -------------------------------------------------------- +void __fastcall AddHealOther(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam) +{ + missile[mi]._miDelFlag = 1; + UseMana(mienemy, 34); + if ( mienemy == myplr ) + SetCursor(10); +} + +//----- (0042C83F) -------------------------------------------------------- +void __fastcall AddElement(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam) +{ + int v9; // ebx + int v10; // edi + int v11; // eax + int v12; // ecx + int v13; // eax + int v14; // esi + int v15; // ecx + int v16; // eax + int x; // [esp+Ch] [ebp-8h] + int i; // [esp+10h] [ebp-4h] + + v9 = dx; + v10 = dy; + x = sx; + i = mi; + if ( sx == dx && sy == dy ) + { + v9 = XDirAdd[midir] + dx; + v10 = YDirAdd[midir] + dy; + } + _LOBYTE(mi) = 60; + v11 = random(mi, 10); + _LOBYTE(v12) = 60; + v13 = 2 * (plr[id]._pLevel + random(v12, 10) + v11) + 4; + v14 = i; + v15 = missile[i]._mispllvl; + missile[i]._midam = v13; + if ( v15 > 0 ) + { + do + { + v13 += v13 >> 3; + --v15; + } + while ( v15 ); + missile[v14]._midam = v13; + } + missile[v14]._midam >>= 1; + GetMissileVel(i, x, sy, v9, v10, 16); + v16 = GetDirection8(x, sy, v9, v10); + SetMissDir(i, v16); + missile[v14]._miVar3 = 0; + missile[v14]._mirange = 256; + missile[v14]._miVar1 = x; + missile[v14]._miVar2 = sy; + missile[v14]._miVar4 = v9; + missile[v14]._miVar5 = v10; + missile[v14]._mlid = AddLight(x, sy, 8); +} + +//----- (0042C942) -------------------------------------------------------- +void __fastcall AddIdentify(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam) +{ + missile[mi]._miDelFlag = 1; + UseMana(mienemy, 5); + if ( mienemy == myplr ) + { + if ( sbookflag ) + sbookflag = 0; + if ( !invflag ) + invflag = 1; + SetCursor(2); + } +} +// 4B8968: using guessed type int sbookflag; + +//----- (0042C993) -------------------------------------------------------- +void __fastcall AddFirewallC(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam) +{ + int v9; // esi + int v10; // eax + int v11; // ecx + unsigned char *v12; // eax + int v13; // ebx + int v14; // edi + int v15; // eax + int v16; // [esp+Ch] [ebp-30h] + int v17; // [esp+10h] [ebp-2Ch] + int v18; // [esp+14h] [ebp-28h] + int v19; // [esp+18h] [ebp-24h] + int v20; // [esp+1Ch] [ebp-20h] + int v21; // [esp+20h] [ebp-1Ch] + int v22; // [esp+24h] [ebp-18h] + int v23; // [esp+28h] [ebp-14h] + unsigned char *v24; // [esp+2Ch] [ebp-10h] + int x1; // [esp+30h] [ebp-Ch] + int v26; // [esp+34h] [ebp-8h] + int v27; // [esp+38h] [ebp-4h] + + v16 = 0; + v9 = mi; + v27 = 0; + x1 = sx; + v17 = 3; + v18 = 12; + v19 = 45; + v20 = 94; + v21 = 159; + missile[mi]._miDelFlag = 1; + do + { + v10 = *(&v16 + v27); + v11 = *(&CrawlTable.n_1 + v10); + v26 = *(&CrawlTable.n_1 + v10); + if ( v11 <= 0 ) + goto LABEL_16; + v12 = &CrawlTable.delta_1[0].y + v10; + v24 = v12; + while ( 1 ) + { + v13 = dx + (char)*(v12 - 1); + v14 = dy + (char)*v12; + if ( v13 <= 0 || v13 >= 112 || v14 <= 0 || v14 >= 112 ) + goto LABEL_13; + v23 = v14 + 112 * v13; + v22 = dPiece[0][v23]; + _LOBYTE(v15) = LineClear(x1, sy, v13, v14); + if ( v15 ) + { + if ( (x1 != v13 || sy != v14) && !((unsigned char)nSolidTable[v22] | dObject[0][v23]) ) + break; + } + v12 = v24; +LABEL_13: + v12 += 2; + --v26; + v24 = v12; + if ( v26 <= 0 ) + goto LABEL_16; + } + missile[v9]._miDelFlag = 0; + missile[v9]._miVar1 = v13; + missile[v9]._miVar2 = v14; + missile[v9]._miVar5 = v13; + missile[v9]._miVar6 = v14; + v27 = 6; +LABEL_16: + ++v27; + } + while ( v27 < 6 ); + if ( missile[v9]._miDelFlag != 1 ) + { + missile[v9]._miVar7 = 0; + missile[v9]._miVar8 = 0; + missile[v9]._miVar3 = (midir - 2) & 7; + missile[v9]._mirange = 7; + missile[v9]._miVar4 = (midir + 2) & 7; + UseMana(id, 6); + } +} + +//----- (0042CAF5) -------------------------------------------------------- +void __fastcall AddInfra(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam) +{ + int v9; // ecx + int v10; // eax + int v11; // edx + + v9 = mi; + v10 = 1584; + v11 = missile[v9]._mispllvl; + missile[v9]._mirange = 1584; + if ( v11 > 0 ) + { + do + { + v10 += v10 >> 3; + --v11; + } + while ( v11 ); + missile[v9]._mirange = v10; + } + missile[v9]._mirange += missile[v9]._mirange * plr[id]._pISplDur >> 7; + if ( !(_BYTE)mienemy ) + UseMana(id, 9); +} + +//----- (0042CB5C) -------------------------------------------------------- +void __fastcall AddWave(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam) +{ + int v9; // ecx + + v9 = mi; + missile[v9]._miVar3 = 0; + missile[v9]._miVar4 = 0; + missile[v9]._miVar1 = dx; + missile[v9]._miVar2 = dy; + missile[v9]._mirange = 1; + missile[v9]._miAnimFrame = 4; +} + +//----- (0042CBA7) -------------------------------------------------------- +void __fastcall AddNova(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam) +{ + int v9; // esi + int v10; // eax + int v11; // ecx + int v12; // ebx + int v13; // eax + int v14; // ecx + int v15; // ebx + int v16; // eax + int v17; // ecx + int v18; // ebx + int v19; // eax + int v20; // ecx + int v21; // ebx + int v22; // eax + int v23; // ecx + int v24; // eax + int v25; // eax + int v26; // ecx + int v27; // edi + int v28; // eax + int v29; // ecx + + v9 = mi; + missile[v9]._miVar1 = dx; + missile[v9]._miVar2 = dy; + _LOBYTE(mi) = 66; + if ( id == -1 ) + { + v25 = random(mi, 3); + _LOBYTE(v26) = 66; + v27 = v25; + v28 = random(v26, 3); + _LOBYTE(v29) = 66; + missile[v9]._midam = ((unsigned int)currlevel >> 1) + random(v29, 3) + v28 + v27; + } + else + { + v10 = random(mi, 6); + _LOBYTE(v11) = 66; + v12 = v10; + v13 = random(v11, 6); + _LOBYTE(v14) = 66; + v15 = v13 + v12; + v16 = random(v14, 6); + _LOBYTE(v17) = 66; + v18 = v16 + v15; + v19 = random(v17, 6); + _LOBYTE(v20) = 66; + v21 = v19 + v18; + v22 = random(v20, 6); + v23 = missile[v9]._mispllvl; + v24 = (v22 + v21 + plr[id]._pLevel + 5) >> 1; + missile[v9]._midam = v24; + if ( v23 > 0 ) + { + do + { + v24 += v24 >> 3; + --v23; + } + while ( v23 ); + missile[v9]._midam = v24; + } + if ( !(_BYTE)mienemy ) + UseMana(id, 18); + } + missile[v9]._mirange = 1; +} + +//----- (0042CC98) -------------------------------------------------------- +void __fastcall AddRepair(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam) +{ + missile[mi]._miDelFlag = 1; + UseMana(mienemy, 26); + if ( mienemy == myplr ) + { + if ( sbookflag ) + sbookflag = 0; + if ( !invflag ) + invflag = 1; + SetCursor(3); + } +} +// 4B8968: using guessed type int sbookflag; + +//----- (0042CCE9) -------------------------------------------------------- +void __fastcall AddRecharge(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam) +{ + missile[mi]._miDelFlag = 1; + UseMana(mienemy, 27); + if ( mienemy == myplr ) + { + if ( sbookflag ) + sbookflag = 0; + if ( !invflag ) + invflag = 1; + SetCursor(4); + } +} +// 4B8968: using guessed type int sbookflag; + +//----- (0042CD3A) -------------------------------------------------------- +void __fastcall AddDisarm(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam) +{ + missile[mi]._miDelFlag = 1; + UseMana(mienemy, 28); + if ( mienemy == myplr ) + SetCursor(5); +} + +//----- (0042CD6D) -------------------------------------------------------- +void __fastcall AddApoca(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam) +{ + int v9; // esi + int v10; // eax + int v11; // edx + int v12; // ecx + signed int v13; // ebx + char *v14; // edi + + v9 = mi; + v10 = sx - 8; + v11 = sx + 8; + missile[v9]._miVar1 = 8; + missile[v9]._miVar2 = sy - 8; + missile[v9]._miVar3 = sy + 8; + missile[v9]._miVar4 = v10; + missile[v9]._miVar5 = v11; + missile[v9]._miVar6 = v10; + if ( sy - 8 <= 0 ) + missile[v9]._miVar2 = 1; + v12 = 111; + if ( sy + 8 >= 112 ) + missile[v9]._miVar3 = 111; + if ( v10 <= 0 ) + missile[v9]._miVar4 = 1; + if ( v11 >= 112 ) + missile[v9]._miVar5 = 111; + v13 = 0; + v14 = &plr[id]._pLevel; + if ( *v14 > 0 ) + { + do + { + _LOBYTE(v12) = 67; + missile[v9]._midam += random(v12, 6) + 1; + ++v13; + } + while ( v13 < *v14 ); + } + missile[v9]._miDelFlag = 0; + missile[v9]._mirange = 255; +} + +//----- (0042CE32) -------------------------------------------------------- +void __fastcall AddFlame(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam) +{ + int v9; // esi + int v10; // ecx + int v11; // eax + int v12; // ecx + int v13; // edi + int v14; // eax + + v9 = mi; + missile[mi]._miVar2 = 0; + if ( dam > 0 ) + missile[v9]._miVar2 = 5 * dam; + missile[v9]._misx = dx; + missile[v9]._misy = dy; + missile[v9]._mixoff = missile[midir]._mixoff; + missile[v9]._miyoff = missile[midir]._miyoff; + missile[v9]._mitxoff = missile[midir]._mitxoff; + missile[v9]._mityoff = missile[midir]._mityoff; + missile[v9]._mirange = missile[v9]._miVar2 + 20; + missile[v9]._mlid = AddLight(sx, sy, 1); + if ( (_BYTE)mienemy ) + { + _LOBYTE(v10) = 77; + missile[v9]._midam = (unsigned char)monster[id].mMinDamage + + random( + v10, + (unsigned char)monster[id].mMaxDamage - (unsigned char)monster[id].mMinDamage + 1); + } + else + { + _LOBYTE(v10) = 79; + v11 = random(v10, plr[id]._pLevel); + _LOBYTE(v12) = 79; + v13 = v11; + v14 = random(v12, 2); + missile[v9]._midam = 8 * (v14 + v13) + 16 + ((8 * (v14 + v13) + 16) >> 1); + } +} + +//----- (0042CF35) -------------------------------------------------------- +void __fastcall AddFlamec(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam) +{ + int v9; // esi + int v10; // edx + int v11; // ebx + int v12; // ecx + int v13; // eax + + v9 = sx; + v10 = dx; + v11 = mi; + v12 = dy; + if ( v9 == dx && sy == dy ) + { + v10 = XDirAdd[midir] + dx; + v12 = YDirAdd[midir] + dy; + } + GetMissileVel(v11, v9, sy, v10, v12, 32); + if ( !(_BYTE)mienemy ) + UseMana(id, 20); + v13 = v11; + missile[v13]._miVar3 = 0; + missile[v13]._miVar2 = sy; + missile[v13]._miVar1 = v9; + missile[v13]._mirange = 256; +} + +//----- (0042CFAD) -------------------------------------------------------- +void __fastcall AddCbolt(int mi, int sx, int sy, int dx, int dy, int midir, int micaster, int id, int dam) +{ + int v9; // esi + int v10; // eax + int v11; // ecx + int v12; // edx + int v13; // eax + int v14; // ecx + int i; // [esp+Ch] [ebp-8h] + int x; // [esp+10h] [ebp-4h] + + i = mi; + v9 = mi; + x = sx; + _LOBYTE(mi) = 63; + if ( (_BYTE)micaster ) + { + v13 = random(mi, 15); + missile[v9]._midam = 15; + missile[v9]._mirnd = v13 + 1; + } + else + { + v10 = random(mi, 15); + _LOBYTE(v11) = 68; + v12 = plr[id]._pMagic; + missile[v9]._mirnd = v10 + 1; + missile[v9]._midam = random(v11, v12 >> 2) + 1; + } + v14 = dx; + if ( x == dx && sy == dy ) + { + v14 = XDirAdd[midir] + dx; + dx += XDirAdd[midir]; + dy += YDirAdd[midir]; + } + _LOBYTE(v14) = 63; + missile[v9]._miAnimFrame = random(v14, 8) + 1; + missile[v9]._mlid = AddLight(x, sy, 5); + GetMissileVel(i, x, sy, dx, dy, 8); + missile[v9]._miVar3 = 0; + missile[v9]._miVar1 = 5; + missile[v9]._miVar2 = midir; + missile[v9]._mirange = 256; +} + +//----- (0042D098) -------------------------------------------------------- +void __fastcall AddHbolt(int mi, int sx, int sy, int dx, int dy, int midir, int micaster, int id, int dam) +{ + int v9; // esi + int v10; // ecx + int v11; // edi + int v12; // eax + int v13; // eax + int v14; // esi + int v15; // eax + int v16; // ecx + signed int v17; // [esp-4h] [ebp-14h] + int i; // [esp+Ch] [ebp-4h] + + v9 = dy; + i = mi; + v10 = dx; + v11 = sx; + if ( sx == dx && sy == dy ) + { + v10 = XDirAdd[midir] + dx; + v9 = YDirAdd[midir] + dy; + dx += XDirAdd[midir]; + } + if ( id == -1 ) + { + v17 = 16; + goto LABEL_8; + } + v12 = 2 * missile[i]._mispllvl + 16; + if ( v12 >= 63 ) + { + v17 = 63; +LABEL_8: + v12 = v17; + } + GetMissileVel(i, sx, sy, v10, v9, v12); + v13 = GetDirection16(v11, sy, dx, v9); + SetMissDir(i, v13); + v14 = i; + missile[v14]._mirange = 256; + missile[v14]._miVar1 = v11; + missile[v14]._miVar2 = sy; + v15 = AddLight(v11, sy, 8); + _LOBYTE(v16) = 69; + missile[v14]._mlid = v15; + missile[v14]._midam = random(v16, 10) + plr[id]._pLevel + 9; +} + +//----- (0042D178) -------------------------------------------------------- +void __fastcall AddResurrect(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam) +{ + int v9; // esi + + v9 = mi; + UseMana(mienemy, 32); + if ( mienemy == myplr ) + SetCursor(8); + missile[v9]._miDelFlag = 1; +} + +//----- (0042D1AF) -------------------------------------------------------- +void __fastcall AddResurrectBeam(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam) +{ + int v9; // ecx + int v10; // eax + + v9 = mi; + missile[v9]._mixvel = 0; + missile[v9]._miyvel = 0; + missile[v9]._mix = dx; + missile[v9]._misx = dx; + v10 = misfiledata[36].mAnimLen[0]; + missile[v9]._miy = dy; + missile[v9]._misy = dy; + missile[v9]._mirange = v10; +} + +//----- (0042D1F3) -------------------------------------------------------- +void __fastcall AddTelekinesis(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam) +{ + missile[mi]._miDelFlag = 1; + UseMana(mienemy, 33); + if ( mienemy == myplr ) + SetCursor(7); +} + +//----- (0042D226) -------------------------------------------------------- +void __fastcall AddBoneSpirit(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam) +{ + int v9; // ebx + int v10; // edi + int v11; // esi + int v12; // eax + int v13; // eax + int mia; // [esp+Ch] [ebp-8h] + int x; // [esp+10h] [ebp-4h] + + v9 = dx; + v10 = dy; + x = sx; + mia = mi; + if ( sx == dx && sy == dy ) + { + v9 = XDirAdd[midir] + dx; + v10 = YDirAdd[midir] + dy; + } + v11 = mi; + missile[mi]._midam = 0; + GetMissileVel(mi, sx, sy, v9, v10, 16); + v12 = GetDirection8(x, sy, v9, v10); + SetMissDir(mia, v12); + missile[v11]._miVar3 = 0; + missile[v11]._mirange = 256; + missile[v11]._miVar1 = x; + missile[v11]._miVar2 = sy; + missile[v11]._miVar4 = v9; + missile[v11]._miVar5 = v10; + missile[v11]._mlid = AddLight(x, sy, 8); + if ( !(_BYTE)mienemy ) + { + UseMana(id, 36); + v13 = id; + drawhpflag = 1; + plr[v13]._pHPBase -= 384; + plr[v13]._pHitPoints -= 384; + if ( plr[id]._pHitPoints <= 0 ) + SyncPlrKill(id, 0); + } +} + +//----- (0042D311) -------------------------------------------------------- +void __fastcall AddRportal(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam) +{ + int v9; // eax + int v10; // edx + + v9 = mi; + missile[v9]._miVar2 = 0; + missile[v9]._mix = sx; + missile[v9]._misx = sx; + missile[v9]._mirange = 100; + v10 = 100 - missile[mi]._miAnimLen; + missile[v9]._miy = sy; + missile[v9]._misy = sy; + missile[v9]._miVar1 = v10; + PutMissile(mi); +} + +//----- (0042D35B) -------------------------------------------------------- +void __fastcall AddDiabApoca(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam) +{ + signed int v9; // edi + int *v10; // esi + int v11; // eax + int x1; // [esp+4h] [ebp-8h] + int v13; // [esp+8h] [ebp-4h] + + v9 = 0; + x1 = sx; + v13 = mi; + if ( gbMaxPlayers ) + { + v10 = &plr[0]._py; + do + { + if ( *((_BYTE *)v10 - 39) ) + { + _LOBYTE(v11) = LineClear(x1, sy, *(v10 - 1), *v10); + if ( v11 ) + AddMissile(0, 0, *(v10 - 1), *v10, 0, 66, mienemy, id, dam, 0); + mi = v13; + } + ++v9; + v10 += 5430; + } + while ( v9 < (unsigned char)gbMaxPlayers ); + } + missile[mi]._miDelFlag = 1; +} +// 679660: using guessed type char gbMaxPlayers; + +//----- (0042D3DA) -------------------------------------------------------- +int __fastcall AddMissile(int sx, int sy, int v1, int v2, int midir, int mitype, int micaster, int id, int v3, int spllvl) +{ + int v10; // esi + int v11; // ecx + int v12; // ecx + int v13; // ebx + int v14; // esi + int v15; // esi + int v16; // edi + int v17; // ecx + char v18; // al + int v19; // edx + int v20; // ecx + int v21; // eax + int sya; // [esp+8h] [ebp-8h] + int sxa; // [esp+Ch] [ebp-4h] + + sya = sy; + sxa = sx; + if ( nummissiles >= 125 ) + return -1; + if ( mitype != 13 || plr[id].pManaShield != 1 ) + goto LABEL_9; + if ( currlevel != plr[id].plrlevel ) + return -1; + v10 = 0; + if ( nummissiles > 0 ) + { + do + { + v11 = missileactive[v10]; + if ( missile[v11]._mitype == 13 && missile[v11]._misource == id ) + return -1; + } + while ( ++v10 < nummissiles ); + } +LABEL_9: + v12 = nummissiles; + v13 = missileavail[0]; + v14 = missileavail[-nummissiles++ + 124]; + missileavail[0] = v14; + v15 = v13; + missile[v15]._mitype = mitype; + v16 = mitype; + missileactive[v12] = v13; + v17 = missiledata[mitype].mDraw; + missile[v15]._micaster = (char)micaster; + v18 = missiledata[mitype].mFileNum; + missile[v15]._misource = id; + v19 = midir; + missile[v15]._miDrawFlag = v17; + _LOBYTE(missile[v15]._miAnimType) = v18; + missile[v15]._mispllvl = spllvl; + missile[v15]._mimfnum = midir; + if ( v18 == -1 || misfiledata[(unsigned char)v18].mAnimFAmt < 8u ) + v19 = 0; + SetMissDir(v13, v19); + v20 = sya; + missile[v15]._mlid = -1; + missile[v15]._mixoff = 0; + missile[v15]._miyoff = 0; + missile[v15]._mitxoff = 0; + missile[v15]._mityoff = 0; + missile[v15]._miDelFlag = 0; + missile[v15]._miLightFlag = 0; + missile[v15]._miPreFlag = 0; + missile[v15]._miUniqTrans = 0; + missile[v15]._miHitFlag = 0; + missile[v15]._midist = 0; + missile[v15]._mirnd = 0; + v21 = missiledata[v16].mlSFX; + missile[v15]._mix = sxa; + missile[v15]._misx = sxa; + missile[v15]._miy = sya; + missile[v15]._misy = sya; + missile[v15]._miAnimAdd = 1; + missile[v15]._midam = v3; + if ( v21 != -1 ) + { + PlaySfxLoc(v21, sxa, sya); + v20 = sya; + } + missiledata[v16].mAddProc(v13, sxa, v20, v1, v2, midir, micaster, id, v3); + return v13; +} + +//----- (0042D5A3) -------------------------------------------------------- +int __fastcall Sentfire(int i, int sx, int sy) +{ + int v3; // esi + int v4; // ebx + int v5; // edi + int v6; // eax + int v7; // eax + int v8; // eax + int v9; // edi + int midir; // ST30_4 + int v11; // ecx + int v12; // eax + int v13; // edx + int mi; // [esp+Ch] [ebp-8h] + + mi = i; + v3 = i; + v4 = sx; + v5 = 0; + _LOBYTE(v6) = LineClear(missile[i]._mix, missile[i]._miy, sx, sy); + if ( v6 ) + { + v7 = dMonster[0][sy + 112 * v4]; + if ( v7 > 0 && (signed int)(monstactive[57 * v7 + 182] & 0xFFFFFFC0) > 0 && v7 - 1 > 3 ) + { + v8 = GetDirection(missile[v3]._mix, missile[v3]._miy, v4, sy); + v9 = missile[v3]._misource; + midir = v8; + v11 = missile[v3]._misource; + missile[v3]._miVar3 = missileavail[0]; + v12 = GetSpellLevel(v11, 1); + AddMissile(missile[v3]._mix, missile[v3]._miy, v4, sy, midir, v13, 0, v9, missile[v3]._midam, v12); + v5 = -1; + SetMissDir(mi, 2); + missile[v3]._miVar2 = 3; + } + } + return v5; +} + +void __fastcall MI_Dummy(int i) +{ + return; +} + +//----- (0042D680) -------------------------------------------------------- +void __fastcall MI_Golem(int i) +{ + int v1; // esi + int v2; // eax + int v3; // eax + bool v4; // zf + int v5; // eax + int v6; // ecx + unsigned char *v7; // eax + int v8; // ebx + int v9; // edi + int v10; // edx + int v11; // ecx + int v12; // eax + int v13; // [esp+4h] [ebp-38h] + int v14; // [esp+8h] [ebp-34h] + int v15; // [esp+Ch] [ebp-30h] + int v16; // [esp+10h] [ebp-2Ch] + int v17; // [esp+14h] [ebp-28h] + int v18; // [esp+18h] [ebp-24h] + char arglist[4]; // [esp+1Ch] [ebp-20h] + int mi; // [esp+20h] [ebp-1Ch] + unsigned int v21; // [esp+24h] [ebp-18h] + int v22; // [esp+28h] [ebp-14h] + int v23; // [esp+2Ch] [ebp-10h] + unsigned char *v24; // [esp+30h] [ebp-Ch] + int v25; // [esp+34h] [ebp-8h] + int v26; // [esp+38h] [ebp-4h] + + mi = i; + v1 = i; + v2 = missile[i]._misource; + *(_DWORD *)arglist = v2; + v3 = v2; + v4 = monster[v3]._mx == 1; + v13 = 0; + v14 = 3; + v15 = 12; + v16 = 45; + v17 = 94; + v18 = 159; + if ( !v4 || monster[v3]._my ) + goto LABEL_17; + v26 = 0; + do + { + v5 = *(&v13 + v26); + v6 = *(&CrawlTable.n_1 + v5); + v25 = *(&CrawlTable.n_1 + v5); + if ( v6 <= 0 ) + goto LABEL_16; + v7 = &CrawlTable.delta_1[0].y + v5; + v24 = v7; + while ( 1 ) + { + v8 = missile[v1]._miVar4 + (char)*(v7 - 1); + v9 = missile[v1]._miVar5 + (char)*v7; + if ( v8 <= 0 || v8 >= 112 || v9 <= 0 || v9 >= 112 ) + goto LABEL_13; + v10 = missile[v1]._miVar2; + v11 = missile[v1]._miVar1; + v23 = v9 + 112 * v8; + v21 = 4 * v23; + v22 = dPiece[0][v23]; + _LOBYTE(v12) = LineClear(v11, v10, v8, v9); + if ( v12 ) + { + if ( !(dMonster[0][v21 / 4] | (unsigned char)nSolidTable[v22] | dObject[0][v23]) ) + break; + } + v7 = v24; +LABEL_13: + v7 += 2; + --v25; + v24 = v7; + if ( v25 <= 0 ) + goto LABEL_16; + } + v26 = 6; + SpawnGolum(*(int *)arglist, v8, v9, mi); +LABEL_16: + ++v26; + } + while ( v26 < 6 ); +LABEL_17: + missile[v1]._miDelFlag = 1; +} + +//----- (0042D7C7) -------------------------------------------------------- +void __fastcall MI_SetManashield(int i) +{ + ManashieldFlag = 1; +} + +//----- (0042D7D2) -------------------------------------------------------- +void __fastcall MI_LArrow(int i) +{ + int v1; // esi + char v2; // al + int v3; // ebx + int v4; // eax + int v5; // ecx + int v6; // edi + int v7; // ecx + int v8; // eax + int v9; // ecx + int v10; // edx + int v11; // ST0C_4 + unsigned char *v12; // eax + unsigned char v13; // bl + int v14; // eax + int v15; // edx + int v16; // ecx + int v17; // ST10_4 + int v18; // ecx + int v19; // edi + int v20; // eax + int v21; // eax + int v22; // ecx + int v23; // ST0C_4 + int v24; // edi + int v25; // eax + int v26; // eax + int v27; // ecx + int v28; // ST10_4 + int v29; // ecx + bool v30; // [esp-8h] [ebp-1Ch] + bool v31; // [esp-4h] [ebp-18h] + unsigned char v32; // [esp+Ch] [ebp-8h] + int ia; // [esp+10h] [ebp-4h] + + v1 = i; + ia = i; + v2 = missile[i]._miAnimType; + --missile[v1]._mirange; + v3 = missile[i]._misource; + if ( v2 == 26 || v2 == 5 ) + { + ChangeLight(missile[v1]._mlid, missile[v1]._mix, missile[v1]._miy, missile[v1]._miAnimFrame + 5); + v18 = missiledata[missile[v1]._mitype].mResist; + v32 = missiledata[missile[v1]._mitype].mResist; + if ( missile[v1]._mitype == 56 ) + { + if ( v3 == -1 ) + { + _LOBYTE(v18) = 68; + v21 = random(v18, 10); + v22 = currlevel; + v19 = v21 + currlevel + 1; + _LOBYTE(v22) = 68; + v20 = random(v22, 10) + 2 * currlevel + 1; + } + else + { + v19 = plr[v3]._pILMinDam; + v20 = plr[v3]._pILMaxDam; + } + v23 = missile[v1]._miy; + missiledata[56].mResist = 2; + CheckMissileCol(ia, v19, v20, 0, missile[v1]._mix, v23, 1, v30); + } + if ( missile[v1]._mitype == 27 ) + { + if ( v3 == -1 ) + { + _LOBYTE(v18) = 68; + v26 = random(v18, 10); + v27 = currlevel; + v24 = v26 + currlevel + 1; + _LOBYTE(v27) = 68; + v25 = random(v27, 10) + 2 * currlevel + 1; + } + else + { + v24 = plr[v3]._pIFMinDam; + v25 = plr[v3]._pIFMaxDam; + } + v28 = missile[v1]._miy; + missiledata[27].mResist = 1; + CheckMissileCol(ia, v24, v25, 0, missile[v1]._mix, v28, 1, v31); + } + missiledata[missile[v1]._mitype].mResist = v32; + } + else + { + v4 = missile[v1]._mixvel; + ++missile[v1]._midist; + missile[v1]._mitxoff += v4; + missile[v1]._mityoff += missile[v1]._miyvel; + GetMissilePos(i); + if ( v3 == -1 ) + { + _LOBYTE(v5) = 68; + v8 = random(v5, 10); + v9 = currlevel; + v6 = v8 + currlevel + 1; + _LOBYTE(v9) = 68; + v7 = random(v9, 10) + 2 * currlevel + 1; + } + else if ( missile[v1]._micaster ) + { + v6 = (unsigned char)monster[v3].mMinDamage; + v7 = (unsigned char)monster[v3].mMaxDamage; + } + else + { + v6 = plr[v3]._pIMinDam; + v7 = plr[v3]._pIMaxDam; + } + v10 = missile[v1]._mix; + if ( v10 != missile[v1]._misx || missile[v1]._miy != missile[v1]._misy ) + { + v11 = missile[v1]._miy; + v12 = &missiledata[missile[v1]._mitype].mResist; + v13 = *v12; + *v12 = 0; + CheckMissileCol(ia, v6, v7, 0, v10, v11, 0, v30); + missiledata[missile[v1]._mitype].mResist = v13; + } + if ( missile[v1]._mirange ) + { + v15 = missile[v1]._mix; + if ( v15 != missile[v1]._miVar1 || missile[v1]._miy != missile[v1]._miVar2 ) + { + v16 = missile[v1]._mlid; + missile[v1]._miVar1 = v15; + v17 = missile[v1]._miy; + missile[v1]._miVar2 = v17; + ChangeLight(v16, v15, v17, 5); + } + } + else + { + missile[v1]._mitxoff -= missile[v1]._mixvel; + v14 = missile[v1]._miyvel; + missile[v1]._mimfnum = 0; + missile[v1]._mityoff -= v14; + GetMissilePos(ia); + if ( missile[v1]._mitype == 56 ) + SetMissAnim(ia, 26); + else + SetMissAnim(ia, MFILE_MAGBLOS); + missile[v1]._mirange = missile[v1]._miAnimLen - 1; + } + } + if ( !missile[v1]._mirange ) + { + v29 = missile[v1]._mlid; + missile[v1]._miDelFlag = 1; + AddUnLight(v29); + } + PutMissile(ia); +} + +//----- (0042DAD0) -------------------------------------------------------- +void __fastcall MI_Arrow(int i) +{ + int v1; // esi + int v2; // eax + int v3; // eax + int v4; // eax + int v5; // eax + int v6; // edx + int v7; // eax + int v8; // eax + int v9; // ecx + bool v10; // [esp-4h] [ebp-Ch] + int ia; // [esp+4h] [ebp-4h] + + v1 = i; + ia = i; + v2 = missile[i]._mixvel; + --missile[v1]._mirange; + missile[v1]._mitxoff += v2; + v3 = missile[i]._miyvel; + ++missile[v1]._midist; + missile[v1]._mityoff += v3; + GetMissilePos(i); + v4 = missile[v1]._misource; + if ( v4 == -1 ) + { + v6 = currlevel; + v7 = 2 * currlevel; + } + else if ( missile[v1]._micaster ) + { + v8 = v4; + v6 = (unsigned char)monster[v8].mMinDamage; + v7 = (unsigned char)monster[v8].mMaxDamage; + } + else + { + v5 = v4; + v6 = plr[v5]._pIMinDam; + v7 = plr[v5]._pIMaxDam; + } + v9 = missile[v1]._mix; + if ( v9 != missile[v1]._misx || missile[v1]._miy != missile[v1]._misy ) + CheckMissileCol(ia, v6, v7, 0, v9, missile[v1]._miy, 0, v10); + if ( !missile[v1]._mirange ) + missile[v1]._miDelFlag = 1; + PutMissile(ia); +} + +//----- (0042DBA1) -------------------------------------------------------- +void __fastcall MI_Firebolt(int i) +{ + int v1; // edi + int v2; // esi + int v3; // ecx + int v4; // ST1C_4 + int v5; // edx + int v6; // ecx + int v7; // eax + int v8; // ecx + int v9; // edi + int v10; // eax + int v11; // edi + int v12; // eax + int v13; // ecx + int v14; // ecx + int v15; // eax + int v16; // esi + int v17; // edx + int v18; // eax + int v19; // esi + bool v20; // [esp+0h] [ebp-18h] + int v21; // [esp+Ch] [ebp-Ch] + int v22; // [esp+10h] [ebp-8h] + int ia; // [esp+14h] [ebp-4h] + + v1 = i; + ia = i; + v2 = i; + --missile[v2]._mirange; + if ( missile[i]._mitype == 63 && missile[v2]._mimfnum == 8 ) + { + if ( !missile[i]._mirange ) + { + v3 = missile[v2]._mlid; + if ( v3 >= 0 ) + AddUnLight(v3); + v4 = missile[v2]._miy; + v5 = missile[v2]._mix; + missile[v2]._miDelFlag = 1; + PlaySfxLoc(LS_BSIMPCT, v5, v4); + } + goto LABEL_39; + } + v6 = missile[v2]._mityoff; + v22 = missile[v2]._mitxoff; + v21 = v6; + v7 = v6 + missile[v2]._miyvel; + missile[v2]._mitxoff = v22 + missile[v2]._mixvel; + missile[v2]._mityoff = v7; + GetMissilePos(v1); + v9 = missile[v2]._misource; + if ( v9 == -1 ) + { + _LOBYTE(v8) = 78; + v12 = random(v8, 2 * currlevel); + v13 = currlevel; + goto LABEL_17; + } + if ( missile[v2]._micaster ) + { + v11 = v9; + _LOBYTE(v8) = 77; + v12 = random(v8, (unsigned char)monster[v11].mMaxDamage - (unsigned char)monster[v11].mMinDamage + 1); + v13 = (unsigned char)monster[v11].mMinDamage; +LABEL_17: + v10 = v13 + v12; + goto LABEL_19; + } + switch ( missile[v2]._mitype ) + { + case 1: + _LOBYTE(v8) = 75; + v10 = (plr[v9]._pMagic >> 3) + random(v8, 10) + missile[v2]._mispllvl + 1; + break; + case 0x18: + v10 = (plr[v9]._pMagic >> 1) + 3 * missile[v2]._mispllvl - (plr[v9]._pMagic >> 3); + break; + case 0x3F: + v10 = 0; + break; + default: + v10 = v21; + break; + } +LABEL_19: + v14 = missile[v2]._mix; + if ( v14 == missile[v2]._misx && missile[v2]._miy == missile[v2]._misy ) + { + v1 = ia; + } + else + { + v1 = ia; + CheckMissileCol(ia, v10, v10, 0, v14, missile[v2]._miy, 0, v20); + } + if ( missile[v2]._mirange ) + { + v17 = missile[v2]._mix; + if ( v17 != missile[v2]._miVar1 || missile[v2]._miy != missile[v2]._miVar2 ) + { + missile[v2]._miVar1 = v17; + v18 = missile[v2]._miy; + missile[v2]._miVar2 = v18; + v19 = missile[v2]._mlid; + if ( v19 >= 0 ) + ChangeLight(v19, v17, v18, 8); + } + } + else + { + missile[v2]._mitxoff = v22; + missile[v2]._miDelFlag = 1; + missile[v2]._mityoff = v21; + GetMissilePos(v1); + v15 = missile[v2]._mitype - 1; + if ( missile[v2]._mitype == 1 || (v15 = missile[v2]._mitype - 21, missile[v2]._mitype == 21) ) + { + _LOBYTE(v15) = missile[v2]._micaster; + AddMissile( + missile[v2]._mix, + missile[v2]._miy, + v1, + 0, + missile[v2]._mimfnum, + 9, + v15, + missile[v2]._misource, + 0, + 0); + } + else + { + switch ( missile[v2]._mitype ) + { + case 0x18: + AddMissile( + missile[v2]._mix, + missile[v2]._miy, + v1, + 0, + missile[v2]._mimfnum, + 25, + _LOBYTE(missile[v2]._micaster), + missile[v2]._misource, + 0, + 0); + break; + case 0x39: + AddMissile( + missile[v2]._mix, + missile[v2]._miy, + v1, + 0, + missile[v2]._mimfnum, + 58, + _LOBYTE(missile[v2]._micaster), + missile[v2]._misource, + 0, + 0); + break; + case 0x3F: + SetMissDir(v1, 8); + missile[v2]._mirange = 7; + missile[v2]._miDelFlag = 0; + goto LABEL_39; + } + } + v16 = missile[v2]._mlid; + if ( v16 >= 0 ) + AddUnLight(v16); + } +LABEL_39: + PutMissile(v1); +} + +//----- (0042DE5A) -------------------------------------------------------- +void __fastcall MI_Lightball(int i) +{ + int v1; // esi + int v2; // ebx + int v3; // eax + int v4; // edi + char v5; // al + int v6; // eax + int v7; // eax + bool v8; // [esp-4h] [ebp-18h] + int ia; // [esp+Ch] [ebp-8h] + int v10; // [esp+10h] [ebp-4h] + + v1 = i; + ia = i; + v2 = missile[i]._miVar1; + missile[v1]._mitxoff += missile[i]._mixvel; + v3 = missile[i]._miyvel; + v4 = missile[i]._miVar2; + --missile[v1]._mirange; + missile[v1]._mityoff += v3; + GetMissilePos(i); + v10 = missile[v1]._mirange; + CheckMissileCol(ia, missile[v1]._midam, missile[v1]._midam, 0, missile[v1]._mix, missile[v1]._miy, 0, v8); + if ( missile[v1]._miHitFlag == 1 ) + missile[v1]._mirange = v10; + v5 = dObject[v2][v4]; + if ( v5 && v2 == missile[v1]._mix && v4 == missile[v1]._miy ) + { + v6 = v5 <= 0 ? -1 - v5 : v5 - 1; + v7 = object[v6]._otype; + if ( v7 == OBJ_SHRINEL || v7 == OBJ_SHRINER ) + missile[v1]._mirange = v10; + } + if ( !missile[v1]._mirange ) + missile[v1]._miDelFlag = 1; + PutMissile(ia); +} + +//----- (0042DF42) -------------------------------------------------------- +void __fastcall mi_null_33(int i) +{ + int v1; // edi + int v2; // esi + int v3; // eax + bool v4; // [esp-4h] [ebp-Ch] + + v1 = i; + v2 = i; + v3 = missile[i]._mixvel; + --missile[v2]._mirange; + missile[v2]._mitxoff += v3; + missile[v2]._mityoff += missile[i]._miyvel; + GetMissilePos(i); + CheckMissileCol(v1, missile[v2]._midam, missile[v2]._midam, 0, missile[v2]._mix, missile[v2]._miy, 0, v4); + if ( !missile[v2]._mirange ) + missile[v2]._miDelFlag = 1; + PutMissile(v1); +} + +//----- (0042DFAB) -------------------------------------------------------- +void __fastcall MI_Acidpud(int i) +{ + int v1; // ebx + int v2; // esi + int v3; // ST0C_4 + int v4; // edx + int v5; // edi + bool v6; // [esp-4h] [ebp-10h] + + v1 = i; + v2 = i; + v3 = missile[i]._miy; + v4 = missile[i]._midam; + --missile[v2]._mirange; + v5 = missile[i]._mirange; + CheckMissileCol(i, v4, v4, 1u, missile[i]._mix, v3, 0, v6); + missile[v2]._mirange = v5; + if ( !v5 ) + { + if ( missile[v2]._mimfnum ) + { + missile[v2]._miDelFlag = 1; + } + else + { + SetMissDir(v1, 1); + missile[v2]._mirange = missile[v2]._miAnimLen; + } + } + PutMissile(v1); +} + +//----- (0042E01E) -------------------------------------------------------- +void __fastcall MI_Firewall(int i) +{ + int v1; // esi + int v2; // ecx + int v3; // ecx + int v4; // eax + bool v5; // [esp-4h] [ebp-48h] + int r; // [esp+8h] [ebp-3Ch] + int v7; // [esp+Ch] [ebp-38h] + int v8; // [esp+10h] [ebp-34h] + int v9; // [esp+14h] [ebp-30h] + int v10; // [esp+18h] [ebp-2Ch] + int v11; // [esp+1Ch] [ebp-28h] + int v12; // [esp+20h] [ebp-24h] + int v13; // [esp+24h] [ebp-20h] + int v14; // [esp+28h] [ebp-1Ch] + int v15; // [esp+2Ch] [ebp-18h] + int v16; // [esp+30h] [ebp-14h] + int v17; // [esp+34h] [ebp-10h] + int v18; // [esp+38h] [ebp-Ch] + int v19; // [esp+3Ch] [ebp-8h] + int ia; // [esp+40h] [ebp-4h] + + v1 = i; + v9 = 5; + v10 = 5; + v17 = 12; + v18 = 12; + --missile[v1]._mirange; + r = 2; + v7 = 3; + v8 = 4; + v11 = 6; + v12 = 7; + v13 = 8; + v14 = 9; + v15 = 10; + v16 = 11; + ia = i; + v19 = 0; + if ( missile[i]._mirange == missile[i]._miVar1 ) + { + SetMissDir(i, 1); + _LOBYTE(v2) = 83; + missile[v1]._miAnimFrame = random(v2, 11) + 1; + } + if ( missile[v1]._mirange == missile[v1]._miAnimLen - 1 ) + { + SetMissDir(ia, 0); + missile[v1]._miAnimAdd = -1; + missile[v1]._miAnimFrame = 13; + } + CheckMissileCol(ia, missile[v1]._midam, missile[v1]._midam, 1u, missile[v1]._mix, missile[v1]._miy, 1, v5); + if ( !missile[v1]._mirange ) + { + v3 = missile[v1]._mlid; + missile[v1]._miDelFlag = 1; + AddUnLight(v3); + } + if ( missile[v1]._mimfnum ) + { + if ( missile[v1]._mirange ) + { + if ( missile[v1]._miAnimAdd != -1 ) + { + v4 = missile[v1]._miVar2; + if ( v4 < 12 ) + { + if ( !v4 ) + missile[v1]._mlid = AddLight(missile[v1]._mix, missile[v1]._miy, r); + ChangeLight(missile[v1]._mlid, missile[v1]._mix, missile[v1]._miy, *(&r + missile[v1]._miVar2)); + ++missile[v1]._miVar2; + } + } + } + } + PutMissile(ia); +} + +//----- (0042E18F) -------------------------------------------------------- +void __fastcall MI_Fireball(int i) +{ + int v1; // esi + bool v2; // zf + int v3; // eax + int v4; // ecx + int v5; // edi + int v6; // eax + int v7; // edx + int v8; // eax + int v9; // eax + int v10; // ecx + int v11; // eax + int v12; // edx + int v13; // eax + int v14; // ecx + int v15; // ST10_4 + bool v16; // [esp-4h] [ebp-24h] + bool v17; // [esp+0h] [ebp-20h] + bool v18; // [esp+4h] [ebp-1Ch] + bool v19; // [esp+8h] [ebp-18h] + int fx; // [esp+Ch] [ebp-14h] + int fxa; // [esp+Ch] [ebp-14h] + int fxb; // [esp+Ch] [ebp-14h] + int fy; // [esp+10h] [ebp-10h] + int fya; // [esp+10h] [ebp-10h] + int fyb; // [esp+10h] [ebp-10h] + int ia; // [esp+14h] [ebp-Ch] + int ib; // [esp+14h] [ebp-Ch] + int ty; // [esp+18h] [ebp-8h] + int tya; // [esp+18h] [ebp-8h] + int tyb; // [esp+18h] [ebp-8h] + int tx; // [esp+1Ch] [ebp-4h] + int txa; // [esp+1Ch] [ebp-4h] + bool savedregs; // [esp+20h] [ebp+0h] + + ia = i; + v1 = i; + --missile[v1]._mirange; + v2 = missile[i]._micaster == 0; + v3 = missile[i]._misource; + v4 = missile[i]._mirange; + v5 = missile[v1]._midam; + if ( v2 ) + { + v6 = v3; + v7 = plr[v6].WorldX; + v8 = plr[v6].WorldY; + } + else + { + v9 = v3; + v7 = monster[v9]._mx; + v8 = monster[v9]._my; + } + fx = v7; + fy = v8; + if ( _LOBYTE(missile[v1]._miAnimType) == 19 ) + { + if ( !v4 ) + { + v10 = missile[v1]._mlid; + missile[v1]._miDelFlag = 1; + AddUnLight(v10); + } + } + else + { + missile[v1]._mitxoff += missile[v1]._mixvel; + missile[v1]._mityoff += missile[v1]._miyvel; + GetMissilePos(ia); + v11 = missile[v1]._mix; + if ( v11 != missile[v1]._misx || missile[v1]._miy != missile[v1]._misy ) + CheckMissileCol(ia, v5, v5, 0, v11, missile[v1]._miy, 0, v16); + v12 = missile[v1]._mix; + if ( missile[v1]._mirange ) + { + if ( v12 != missile[v1]._miVar1 || missile[v1]._miy != missile[v1]._miVar2 ) + { + v14 = missile[v1]._mlid; + missile[v1]._miVar1 = v12; + v15 = missile[v1]._miy; + missile[v1]._miVar2 = v15; + ChangeLight(v14, v12, v15, 8); + } + } + else + { + tx = missile[v1]._mix; + ty = missile[v1]._miy; + ChangeLight(missile[v1]._mlid, v12, ty, missile[v1]._miAnimFrame); + if ( !CheckBlock(fx, fy, tx, ty) ) + CheckMissileCol(ia, v5, v5, 0, tx, ty, 1, v17); + if ( !CheckBlock(fx, fy, tx, ty + 1) ) + CheckMissileCol(ia, v5, v5, 0, tx, ty + 1, 1, v18); + if ( !CheckBlock(fx, fy, tx, ty - 1) ) + CheckMissileCol(ia, v5, v5, 0, tx, ty - 1, 1, v19); + if ( !CheckBlock(fx, fy, tx + 1, ty) ) + CheckMissileCol(ia, v5, v5, 0, tx + 1, ty, 1, fx); + if ( !CheckBlock(fx, fy, tx + 1, ty - 1) ) + CheckMissileCol(ia, v5, v5, 0, tx + 1, ty - 1, 1, fy); + if ( !CheckBlock(fxa, fy, tx + 1, ty + 1) ) + CheckMissileCol(ia, v5, v5, 0, tx + 1, ty + 1, 1, ia); + if ( !CheckBlock(fxb, fya, tx - 1, ty) ) + CheckMissileCol(ib, v5, v5, 0, tx - 1, ty, 1, ty); + if ( !CheckBlock(fxb, fyb, tx - 1, ty + 1) ) + CheckMissileCol(ia, v5, v5, 0, tx - 1, tya + 1, 1, tx); + if ( !CheckBlock(fxb, fyb, tya - 2, tya - 1) ) + CheckMissileCol(ia, v5, v5, 0, 0, tyb - 1, 1, savedregs); + v13 = 112 * txa + tyb; + if ( !TransList[dung_map[0][v13]] + || missile[v1]._mixvel < 0 + && (TransList[dung_map[0][v13 + 1]] && nSolidTable[dPiece[0][v13 + 1]] + || TransList[*(&byte_5B78EB + v13)] && nSolidTable[*(_DWORD *)&dflags[39][4 * v13 + 36]]) ) + { + ++missile[v1]._mix; + ++missile[v1]._miy; + missile[v1]._miyoff -= 32; + } + if ( missile[v1]._miyvel > 0 + && (TransList[dung_map[txa + 1][tyb]] && nSolidTable[dPiece[1][v13]] + || TransList[block_lvid[v13 + 1940]] && nSolidTable[*(_DWORD *)&dflags[28][4 * v13 + 32]]) ) + { + missile[v1]._miyoff -= 32; + } + if ( missile[v1]._mixvel > 0 + && (TransList[dung_map[0][v13 + 1]] && nSolidTable[dPiece[0][v13 + 1]] + || TransList[*(&byte_5B78EB + v13)] && nSolidTable[*(_DWORD *)&dflags[39][4 * v13 + 36]]) ) + { + missile[v1]._mixoff -= 32; + } + missile[v1]._mimfnum = 0; + SetMissAnim(ia, MFILE_BIGEXP); + missile[v1]._mirange = missile[v1]._miAnimLen - 1; + } + } + PutMissile(ia); +} + +//----- (0042E5A7) -------------------------------------------------------- +void __fastcall MI_Lightctrl(int i) +{ + int v1; // esi + int v2; // eax + int v3; // eax + int v4; // ecx + int v5; // edi + signed int v6; // ebx + signed int v7; // edx + int v8; // ecx + int v9; // eax + int v10; // [esp-10h] [ebp-24h] + int v11; // [esp-Ch] [ebp-20h] + int v12; // [esp-8h] [ebp-1Ch] + int v13; // [esp+Ch] [ebp-8h] + int ia; // [esp+10h] [ebp-4h] + + ia = i; + v1 = i; + v2 = missile[i]._misource; + --missile[v1]._mirange; + if ( v2 == -1 ) + { + _LOBYTE(i) = 81; + v5 = random(i, currlevel) + 2 * currlevel; + } + else if ( missile[v1]._micaster ) + { + _LOBYTE(i) = 80; + v5 = 2 + * ((unsigned char)monster[v2].mMinDamage + + random(i, (unsigned char)monster[v2].mMaxDamage - (unsigned char)monster[v2].mMinDamage + 1)); + } + else + { + _LOBYTE(i) = 79; + v3 = random(i, plr[v2]._pLevel); + _LOBYTE(v4) = 79; + v5 = (v3 + random(v4, 2) + 2) << 6; + } + missile[v1]._mitxoff += missile[v1]._mixvel; + missile[v1]._mityoff += missile[v1]._miyvel; + GetMissilePos(ia); + v6 = missile[v1]._mix; + v7 = missile[v1]._miy; + v8 = missile[v1]._misource; + v13 = missile[v1]._miy; + v9 = dPiece[0][v7 + 112 * missile[v1]._mix]; + if ( v8 != -1 || v6 != missile[v1]._misx || v7 != missile[v1]._misy ) + { + if ( !nMissileTable[v9] ) + goto LABEL_12; + missile[v1]._mirange = 0; + } + if ( !nMissileTable[v9] ) + { +LABEL_12: + if ( v6 == missile[v1]._miVar1 && v7 == missile[v1]._miVar2 || v6 <= 0 || v7 <= 0 || v6 >= 112 || v7 >= 112 ) + goto LABEL_27; + if ( v8 == -1 ) + { + v12 = missile[v1]._mispllvl; + v11 = v5; + v10 = -1; + } + else + { + if ( missile[v1]._micaster == 1 ) + { + v9 = (int)monster[v8].MType; + _LOBYTE(v9) = *(_BYTE *)v9; + if ( (unsigned char)v9 >= MON_THINA && (unsigned char)v9 <= MON_THIND ) + { + _LOBYTE(v9) = missile[v1]._micaster; + AddMissile(v6, v7, missile[v1]._misx, missile[v1]._misy, ia, 23, v9, v8, v5, missile[v1]._mispllvl); +LABEL_26: + v7 = v13; + missile[v1]._miVar1 = missile[v1]._mix; + missile[v1]._miVar2 = missile[v1]._miy; + goto LABEL_27; + } + } + v12 = missile[v1]._mispllvl; + v11 = v5; + v10 = v8; + } + _LOBYTE(v9) = missile[v1]._micaster; + AddMissile(v6, v7, missile[v1]._misx, missile[v1]._misy, ia, 8, v9, v10, v11, v12); + goto LABEL_26; + } +LABEL_27: + if ( !missile[v1]._mirange || v6 <= 0 || v7 <= 0 || v6 >= 112 || v7 > 112 ) + missile[v1]._miDelFlag = 1; +} + +//----- (0042E79B) -------------------------------------------------------- +void __fastcall MI_Lightning(int i) +{ + int v1; // edi + int v2; // esi + int v3; // eax + int v4; // ebx + int v5; // ecx + bool v6; // [esp-4h] [ebp-10h] + + v1 = i; + v2 = i; + v3 = missile[i]._mix; + --missile[v2]._mirange; + v4 = missile[i]._mirange; + if ( v3 != missile[i]._misx || missile[v2]._miy != missile[v2]._misy ) + CheckMissileCol(i, missile[v2]._midam, missile[v2]._midam, 1u, v3, missile[v2]._miy, 0, v6); + if ( missile[v2]._miHitFlag == 1 ) + missile[v2]._mirange = v4; + if ( !missile[v2]._mirange ) + { + v5 = missile[v2]._mlid; + missile[v2]._miDelFlag = 1; + AddUnLight(v5); + } + PutMissile(v1); +} + +//----- (0042E820) -------------------------------------------------------- +void __fastcall MI_Town(int i) +{ + int v1; // esi + int v2; // eax + int *v3; // edi + int v4; // ecx + int r; // [esp+8h] [ebp-4Ch] + int v6; // [esp+Ch] [ebp-48h] + int v7; // [esp+10h] [ebp-44h] + int v8; // [esp+14h] [ebp-40h] + int v9; // [esp+18h] [ebp-3Ch] + int v10; // [esp+1Ch] [ebp-38h] + int v11; // [esp+20h] [ebp-34h] + int v12; // [esp+24h] [ebp-30h] + int v13; // [esp+28h] [ebp-2Ch] + int v14; // [esp+2Ch] [ebp-28h] + int v15; // [esp+30h] [ebp-24h] + int v16; // [esp+34h] [ebp-20h] + int v17; // [esp+38h] [ebp-1Ch] + int v18; // [esp+3Ch] [ebp-18h] + int v19; // [esp+40h] [ebp-14h] + int v20; // [esp+44h] [ebp-10h] + int v21; // [esp+48h] [ebp-Ch] + int ia; // [esp+4Ch] [ebp-8h] + char arglist[4]; // [esp+50h] [ebp-4h] + + v1 = i; + v19 = 15; + v20 = 15; + v21 = 15; + v2 = missile[i]._mirange; + ia = i; + r = 1; + v6 = 2; + v7 = 3; + v8 = 4; + v9 = 5; + v10 = 6; + v11 = 7; + v12 = 8; + v13 = 9; + v14 = 10; + v15 = 11; + v16 = 12; + v17 = 13; + v18 = 14; + if ( v2 > 1 ) + missile[v1]._mirange = v2 - 1; + if ( missile[v1]._mirange == missile[v1]._miVar1 ) + SetMissDir(i, 1); + if ( currlevel && missile[v1]._mimfnum != 1 && missile[v1]._mirange ) + { + if ( !missile[v1]._miVar2 ) + missile[v1]._mlid = AddLight(missile[v1]._mix, missile[v1]._miy, 1); + ChangeLight(missile[v1]._mlid, missile[v1]._mix, missile[v1]._miy, *(&r + missile[v1]._miVar2)); + ++missile[v1]._miVar2; + } + *(_DWORD *)arglist = 0; + v3 = &plr[0].plrlevel; + do + { + if ( *((_BYTE *)v3 - 23) ) + { + if ( currlevel == *v3 + && !*((_BYTE *)v3 + 267) + && !*(v3 - 13) + && v3[1] == missile[v1]._mix + && v3[2] == missile[v1]._miy ) + { + ClrPlrPath(*(int *)arglist); + if ( *(_DWORD *)arglist == myplr ) + { + NetSendCmdParam1(1u, CMD_WARP, missile[v1]._misource); + *(v3 - 13) = 10; + } + } + } + ++*(_DWORD *)arglist; + v3 += 5430; + } + while ( (signed int)v3 < (signed int)&plr_msgs[0].player ); + if ( !missile[v1]._mirange ) + { + v4 = missile[v1]._mlid; + missile[v1]._miDelFlag = 1; + AddUnLight(v4); + } + PutMissile(ia); +} + +//----- (0042E9CB) -------------------------------------------------------- +void __fastcall MI_Flash(int i) +{ + int v1; // edi + int v2; // esi + int v3; // eax + int v4; // eax + bool v5; // zf + int v6; // esi + bool v7; // [esp-18h] [ebp-24h] + bool v8; // [esp-14h] [ebp-20h] + bool v9; // [esp-10h] [ebp-1Ch] + bool v10; // [esp-Ch] [ebp-18h] + bool v11; // [esp-8h] [ebp-14h] + bool v12; // [esp-4h] [ebp-10h] + + v1 = i; + v2 = i; + if ( !missile[i]._micaster ) + { + v3 = missile[v2]._misource; + if ( v3 != -1 ) + plr[v3]._pInvincible = 1; + } + v4 = missile[v2]._mix; + --missile[v2]._mirange; + CheckMissileCol(i, missile[v2]._midam, missile[v2]._midam, 1u, v4 - 1, missile[v2]._miy, 1, v7); + CheckMissileCol(v1, missile[v2]._midam, missile[v2]._midam, 1u, missile[v2]._mix, missile[v2]._miy, 1, v8); + CheckMissileCol(v1, missile[v2]._midam, missile[v2]._midam, 1u, missile[v2]._mix + 1, missile[v2]._miy, 1, v9); + CheckMissileCol(v1, missile[v2]._midam, missile[v2]._midam, 1u, missile[v2]._mix - 1, missile[v2]._miy + 1, 1, v10); + CheckMissileCol(v1, missile[v2]._midam, missile[v2]._midam, 1u, missile[v2]._mix, missile[v2]._miy + 1, 1, v11); + CheckMissileCol(v1, missile[v2]._midam, missile[v2]._midam, 1u, missile[v2]._mix + 1, missile[v2]._miy + 1, 1, v12); + if ( !missile[v2]._mirange ) + { + v5 = missile[v2]._micaster == 0; + missile[v2]._miDelFlag = 1; + if ( v5 ) + { + v6 = missile[v2]._misource; + if ( v6 != -1 ) + plr[v6]._pInvincible = 0; + } + } + PutMissile(v1); +} + +//----- (0042EAF1) -------------------------------------------------------- +void __fastcall MI_Flash2(int i) +{ + int v1; // edi + int v2; // esi + int v3; // eax + int v4; // eax + bool v5; // zf + int v6; // esi + bool v7; // [esp-Ch] [ebp-18h] + bool v8; // [esp-8h] [ebp-14h] + bool v9; // [esp-4h] [ebp-10h] + + v1 = i; + v2 = i; + if ( !missile[i]._micaster ) + { + v3 = missile[v2]._misource; + if ( v3 != -1 ) + plr[v3]._pInvincible = 1; + } + v4 = missile[v2]._miy; + --missile[v2]._mirange; + CheckMissileCol(i, missile[v2]._midam, missile[v2]._midam, 1u, missile[v2]._mix - 1, v4 - 1, 1, v7); + CheckMissileCol(v1, missile[v2]._midam, missile[v2]._midam, 1u, missile[v2]._mix, missile[v2]._miy - 1, 1, v8); + CheckMissileCol(v1, missile[v2]._midam, missile[v2]._midam, 1u, missile[v2]._mix + 1, missile[v2]._miy - 1, 1, v9); + if ( !missile[v2]._mirange ) + { + v5 = missile[v2]._micaster == 0; + missile[v2]._miDelFlag = 1; + if ( v5 ) + { + v6 = missile[v2]._misource; + if ( v6 != -1 ) + plr[v6]._pInvincible = 0; + } + } + PutMissile(v1); +} + +//----- (0042EBBF) -------------------------------------------------------- +void __fastcall MI_Manashield(int i) +{ + int v1; // edi + int v2; // esi + int v3; // edx + int v4; // eax + int v5; // ecx + int v6; // edx + bool v7; // zf + int v8; // eax + int v9; // ecx + int v10; // edx + int v11; // ecx + int v12; // ecx + bool v13; // sf + int v14; // [esp+Ch] [ebp-10h] + int ia; // [esp+14h] [ebp-8h] + int arglist; // [esp+18h] [ebp-4h] + + ia = i; + v1 = i; + arglist = missile[i]._misource; + v2 = arglist; + v3 = plr[arglist]._pxoff; + v4 = plr[arglist].WorldX; + v5 = plr[arglist].WorldY; + missile[v1]._mix = v4; + missile[v1]._mitxoff = v3 << 16; + v6 = plr[arglist]._pyoff << 16; + v7 = plr[arglist]._pmode == PM_WALK3; + missile[v1]._miy = v5; + missile[v1]._mityoff = v6; + if ( v7 ) + { + missile[v1]._misx = plr[v2]._px; + missile[v1]._misy = plr[v2]._py; + } + else + { + missile[v1]._misx = v4; + missile[v1]._misy = v5; + } + GetMissilePos(ia); + if ( plr[v2]._pmode == PM_WALK3 ) + { + if ( plr[v2]._pdir == 2 ) + ++missile[v1]._mix; + else + ++missile[v1]._miy; + } + if ( arglist != myplr ) + { + if ( currlevel != plr[v2].plrlevel ) + missile[v1]._miDelFlag = 1; + goto LABEL_33; + } + v8 = plr[v2]._pMana; + v14 = plr[v2]._pMana; + if ( v8 <= 0 || !plr[v2].plractive[0] ) + missile[v1]._mirange = 0; + v9 = missile[v1]._miVar1; + if ( plr[v2]._pHitPoints >= v9 ) + goto LABEL_26; + v10 = v9 - plr[v2]._pHitPoints; + if ( missile[v1]._mispllvl > 0 ) + { + v10 = v10 / -3 + v9 - plr[v2]._pHitPoints; + v8 = v14; + } + if ( v10 < 0 ) + v10 = 0; + drawmanaflag = 1; + drawhpflag = 1; + if ( v8 >= v10 ) + { + plr[v2]._pHitPoints = v9; + v11 = missile[v1]._miVar2; + plr[v2]._pManaBase -= v10; + plr[v2]._pHPBase = v11; + plr[v2]._pMana = v8 - v10; +LABEL_26: + if ( arglist == myplr && !plr[v2]._pHitPoints && !missile[v1]._miVar1 && plr[v2]._pmode != PM_DEATH ) + { + missile[v1]._mirange = 0; + missile[v1]._miDelFlag = 1; + SyncPlrKill(arglist, -1); + } + goto LABEL_31; + } + missile[v1]._miDelFlag = 1; + plr[v2]._pHitPoints = v8 + v9 - v10; + plr[v2]._pHPBase = v8 + missile[v1]._miVar2 - v10; + v12 = plr[v2]._pMaxManaBase - plr[v2]._pMaxMana; + v13 = plr[v2]._pHitPoints < 0; + plr[v2]._pMana = 0; + missile[v1]._mirange = 0; + plr[v2]._pManaBase = v12; + if ( v13 ) + SetPlayerHitPoints(arglist, 0); + if ( plr[v2]._pHitPoints & 0xFFFFFFC0 ) + goto LABEL_26; + if ( arglist == myplr ) + { + SyncPlrKill(arglist, missile[v1]._miVar8); + goto LABEL_26; + } +LABEL_31: + v7 = missile[v1]._mirange == 0; + missile[v1]._miVar1 = plr[v2]._pHitPoints; + missile[v1]._miVar2 = plr[v2]._pHPBase; + if ( v7 ) + { + missile[v1]._miDelFlag = 1; + NetSendCmd(1u, CMD_ENDSHIELD); + } +LABEL_33: + PutMissile(ia); +} + +//----- (0042EE19) -------------------------------------------------------- +void __fastcall MI_Etherealize(int i) +{ + int v1; // ebx + int v2; // esi + int v3; // edi + int v4; // edi + int v5; // edx + int v6; // eax + int v7; // ecx + int v8; // edx + bool v9; // zf + char v10; // al + + v1 = i; + v2 = i; + v3 = missile[i]._misource; + --missile[v2]._mirange; + v4 = v3; + v5 = plr[v4]._pxoff; + v6 = plr[v4].WorldX; + v7 = plr[v4].WorldY; + missile[v2]._mix = v6; + missile[v2]._mitxoff = v5 << 16; + v8 = plr[v4]._pyoff << 16; + v9 = plr[v4]._pmode == PM_WALK3; + missile[v2]._miy = v7; + missile[v2]._mityoff = v8; + if ( v9 ) + { + missile[v2]._misx = plr[v4]._px; + missile[v2]._misy = plr[v4]._py; + } + else + { + missile[v2]._misx = v6; + missile[v2]._misy = v7; + } + GetMissilePos(v1); + if ( plr[v4]._pmode == PM_WALK3 ) + { + if ( plr[v4]._pdir == 2 ) + ++missile[v2]._mix; + else + ++missile[v2]._miy; + } + _LOBYTE(plr[v4]._pSpellFlags) |= 1u; + v10 = plr[v4]._pSpellFlags; + if ( !missile[v2]._mirange || plr[v4]._pHitPoints <= 0 ) + { + missile[v2]._miDelFlag = 1; + _LOBYTE(plr[v4]._pSpellFlags) = v10 & 0xFE; + } + PutMissile(v1); +} + +//----- (0042EEFD) -------------------------------------------------------- +void __fastcall MI_Firemove(int i) +{ + int v1; // esi + int *v2; // eax + int v3; // ecx + int v4; // ecx + int v5; // ebx + int v6; // ecx + int v7; // edx + int v8; // ecx + int v9; // ST10_4 + int v10; // ecx + bool v11; // [esp-4h] [ebp-4Ch] + int r; // [esp+Ch] [ebp-3Ch] + int v13; // [esp+10h] [ebp-38h] + int v14; // [esp+14h] [ebp-34h] + int v15; // [esp+18h] [ebp-30h] + int v16; // [esp+1Ch] [ebp-2Ch] + int v17; // [esp+20h] [ebp-28h] + int v18; // [esp+24h] [ebp-24h] + int v19; // [esp+28h] [ebp-20h] + int v20; // [esp+2Ch] [ebp-1Ch] + int v21; // [esp+30h] [ebp-18h] + int v22; // [esp+34h] [ebp-14h] + int v23; // [esp+38h] [ebp-10h] + int v24; // [esp+3Ch] [ebp-Ch] + int v25; // [esp+40h] [ebp-8h] + int ia; // [esp+44h] [ebp-4h] + + v1 = i; + v15 = 5; + v16 = 5; + missile[v1]._miyoff += 32; + v23 = 12; + v24 = 12; + --missile[v1]._mix; + --missile[v1]._miy; + r = 2; + v13 = 3; + v14 = 4; + v17 = 6; + v18 = 7; + v19 = 8; + v20 = 9; + v21 = 10; + v22 = 11; + ia = i; + v25 = 0; + v2 = &missile[i]._miVar1; + if ( ++*v2 == missile[i]._miAnimLen ) + { + SetMissDir(i, 1); + _LOBYTE(v3) = 82; + missile[v1]._miAnimFrame = random(v3, 11) + 1; + } + v4 = ia; + missile[v1]._mitxoff += missile[v1]._mixvel; + missile[v1]._mityoff += missile[v1]._miyvel; + GetMissilePos(v4); + v5 = missile[v1]._mirange; + CheckMissileCol(ia, missile[v1]._midam, missile[v1]._midam, 0, missile[v1]._mix, missile[v1]._miy, 0, v11); + if ( missile[v1]._miHitFlag == 1 ) + missile[v1]._mirange = v5; + if ( !missile[v1]._mirange ) + { + v6 = missile[v1]._mlid; + missile[v1]._miDelFlag = 1; + AddUnLight(v6); + } + if ( missile[v1]._mimfnum || !missile[v1]._mirange ) + { + v7 = missile[v1]._mix; + if ( v7 != missile[v1]._miVar3 || missile[v1]._miy != missile[v1]._miVar4 ) + { + v8 = missile[v1]._mlid; + missile[v1]._miVar3 = v7; + v9 = missile[v1]._miy; + missile[v1]._miVar4 = v9; + ChangeLight(v8, v7, v9, 8); + } + } + else + { + if ( !missile[v1]._miVar2 ) + missile[v1]._mlid = AddLight(missile[v1]._mix, missile[v1]._miy, r); + ChangeLight(missile[v1]._mlid, missile[v1]._mix, missile[v1]._miy, *(&r + missile[v1]._miVar2)); + ++missile[v1]._miVar2; + } + ++missile[v1]._mix; + v10 = ia; + ++missile[v1]._miy; + missile[v1]._miyoff -= 32; + PutMissile(v10); +} + +//----- (0042F0C8) -------------------------------------------------------- +void __fastcall MI_Guardian(int i) +{ + int v1; // esi + int v2; // eax + int v3; // ecx + unsigned char *v4; // edi + int v5; // eax + signed int v6; // ecx + unsigned char *v7; // ebx + unsigned char v8; // dl + unsigned char *v9; // edi + int v10; // ecx + int *v11; // eax + int v12; // ecx + int v13; // ecx + signed int v14; // [esp+Ch] [ebp-14h] + int v15; // [esp+10h] [ebp-10h] + int v16; // [esp+14h] [ebp-Ch] + unsigned char *v17; // [esp+18h] [ebp-8h] + int ia; // [esp+1Ch] [ebp-4h] + + ia = i; + v1 = i; + v2 = missile[i]._miVar2; + --missile[v1]._mirange; + v3 = missile[i]._mirange; + v16 = 0; + v15 = 0; + if ( v2 > 0 ) + missile[v1]._miVar2 = v2 - 1; + if ( v3 == missile[v1]._miVar1 || missile[v1]._mimfnum == 2 && !missile[v1]._miVar2 ) + SetMissDir(ia, 1); + if ( !(missile[v1]._mirange % 16) ) + { + v4 = &vCrawlTable[0][1]; + v5 = 0; + v17 = &vCrawlTable[0][1]; + do + { + if ( v5 == -1 ) + break; + v6 = 10; + v14 = 10; + do + { + v7 = &v4[v6 - 1]; + v8 = *v7; + if ( !*v7 && !v4[v6] ) + break; + if ( v16 != v8 || v15 != v4[v6] ) + { + v9 = &v4[v6]; + v5 = Sentfire(ia, v8 + missile[v1]._mix, missile[v1]._miy + *v9); + if ( v5 == -1 + || (v5 = Sentfire(ia, missile[v1]._mix - *v7, missile[v1]._miy - *v9), v5 == -1) + || (v5 = Sentfire(ia, missile[v1]._mix + *v7, missile[v1]._miy - *v9), v5 == -1) + || (v5 = Sentfire(ia, missile[v1]._mix - *v7, missile[v1]._miy + *v9), v5 == -1) ) + { + v4 = v17; + break; + } + v16 = *v7; + v10 = *v9; + v4 = v17; + v15 = v10; + v6 = v14; + } + v6 -= 2; + v14 = v6; + } + while ( v6 >= 0 ); + v4 += 30; + v17 = v4; + } + while ( (signed int)v4 < (signed int)RadiusAdj ); + } + if ( missile[v1]._mirange == 14 ) + { + SetMissDir(ia, 0); + missile[v1]._miAnimAdd = -1; + missile[v1]._miAnimFrame = 15; + } + v11 = &missile[v1]._miVar3; + *v11 += missile[v1]._miAnimAdd; + v12 = missile[v1]._miVar3; + if ( v12 <= 15 ) + { + if ( v12 > 0 ) + ChangeLight(missile[v1]._mlid, missile[v1]._mix, missile[v1]._miy, missile[v1]._miVar3); + } + else + { + *v11 = 15; + } + if ( !missile[v1]._mirange ) + { + v13 = missile[v1]._mlid; + missile[v1]._miDelFlag = 1; + AddUnLight(v13); + } + PutMissile(ia); +} + +//----- (0042F2C2) -------------------------------------------------------- +void __fastcall MI_Chain(int i) +{ + int v1; // esi + int ST1C_4_1; // ST1C_4 + int v3; // edi + int v4; // ebx + int v5; // eax + int v6; // ST18_4 + int v7; // eax + int v8; // edi + int v9; // ecx + int v10; // eax + unsigned char *v11; // ecx + int v12; // ebx + int v13; // eax + int v14; // eax + bool v15; // zf + int v16; // [esp+Ch] [ebp-68h] + int v17; // [esp+10h] [ebp-64h] + int v18; // [esp+14h] [ebp-60h] + int v19; // [esp+18h] [ebp-5Ch] + int v20; // [esp+1Ch] [ebp-58h] + int v21; // [esp+20h] [ebp-54h] + int v22; // [esp+24h] [ebp-50h] + int v23; // [esp+28h] [ebp-4Ch] + int v24; // [esp+2Ch] [ebp-48h] + int v25; // [esp+30h] [ebp-44h] + int v26; // [esp+34h] [ebp-40h] + int v27; // [esp+38h] [ebp-3Ch] + int v28; // [esp+3Ch] [ebp-38h] + int v29; // [esp+40h] [ebp-34h] + int v30; // [esp+44h] [ebp-30h] + int v31; // [esp+48h] [ebp-2Ch] + int v32; // [esp+4Ch] [ebp-28h] + int v33; // [esp+50h] [ebp-24h] + int v34; // [esp+54h] [ebp-20h] + int v2; // [esp+58h] [ebp-1Ch] + int v36; // [esp+5Ch] [ebp-18h] + unsigned char *v37; // [esp+60h] [ebp-14h] + int id; // [esp+64h] [ebp-10h] + int sx; // [esp+68h] [ebp-Ch] + int sy; // [esp+6Ch] [ebp-8h] + int j; // [esp+70h] [ebp-4h] + + v16 = 0; + v1 = i; + v17 = 3; + ST1C_4_1 = missile[i]._miVar2; + v3 = missile[i]._mix; + v4 = missile[i]._miy; + v5 = missile[i]._misource; + v6 = missile[i]._miVar1; + v18 = 12; + v19 = 45; + v20 = 94; + v21 = 159; + v22 = 240; + v23 = 337; + v24 = 450; + v25 = 579; + v26 = 724; + v27 = 885; + v28 = 1062; + v29 = 1255; + v30 = 1464; + v31 = 1689; + v32 = 1930; + v33 = 2187; + v34 = 2460; + id = v5; + sx = v3; + sy = v4; + v7 = GetDirection(v3, v4, v6, ST1C_4_1); + AddMissile(v3, v4, missile[v1]._miVar1, missile[v1]._miVar2, v7, 7, 0, id, 1, missile[v1]._mispllvl); + v8 = missile[v1]._mispllvl + 3; + if ( v8 > 19 ) + v8 = 19; + for ( j = 1; j < v8; ++j ) + { + v9 = *(&v16 + j); + v10 = *(&CrawlTable.n_1 + v9); + if ( v10 > 0 ) + { + v11 = &CrawlTable.delta_1[0].y + v9; + v36 = v10; + v37 = v11; + do + { + v12 = sx + (char)*(v11 - 1); + v13 = sy + (char)*v11; + v2 = sy + (char)*v11; + if ( v12 > 0 && v12 < 112 && v13 > 0 && v13 < 112 && dMonster[0][v13 + 112 * v12] > 0 ) + { + v14 = GetDirection(sx, sy, v12, v13); + AddMissile(sx, sy, v12, v2, v14, 7, 0, id, 1, missile[v1]._mispllvl); + v11 = v37; + } + v11 += 2; + v15 = v36-- == 1; + v37 = v11; + } + while ( !v15 ); + } + } + v15 = missile[v1]._mirange-- == 1; + if ( v15 ) + missile[v1]._miDelFlag = 1; +} + +//----- (0042F475) -------------------------------------------------------- +void __fastcall mi_null_11(int i) +{ + int v1; // eax + bool v2; // zf + + v1 = i; + v2 = missile[i]._mirange == 1; + --missile[v1]._mirange; + if ( v2 ) + missile[v1]._miDelFlag = 1; + if ( missile[v1]._miAnimFrame == missile[v1]._miAnimLen ) + missile[v1]._miPreFlag = 1; + PutMissile(i); +} + +//----- (0042F4A9) -------------------------------------------------------- +void __fastcall MI_Weapexp(int i) +{ + int v1; // esi + int v2; // ecx + int v3; // eax + int v4; // ecx + bool v5; // zf + int v6; // edx + int v7; // eax + int v8; // eax + int v9; // ecx + bool v10; // [esp-4h] [ebp-34h] + int r; // [esp+4h] [ebp-2Ch] + int v12; // [esp+8h] [ebp-28h] + int v13; // [esp+Ch] [ebp-24h] + int v14; // [esp+10h] [ebp-20h] + int v15; // [esp+14h] [ebp-1Ch] + int v16; // [esp+18h] [ebp-18h] + int v17; // [esp+1Ch] [ebp-14h] + int v18; // [esp+20h] [ebp-10h] + int v19; // [esp+24h] [ebp-Ch] + int v20; // [esp+28h] [ebp-8h] + int ia; // [esp+2Ch] [ebp-4h] + + ia = i; + v1 = i; + --missile[v1]._mirange; + r = 9; + v12 = 10; + v16 = 10; + v2 = missile[i]._mitype; + v13 = 11; + v15 = 11; + v3 = missile[v1]._misource; + v4 = v2; + v5 = missile[v1]._miVar2 == 1; + v14 = 12; + v17 = 8; + v18 = 6; + v19 = 4; + v20 = 2; + if ( v5 ) + { + v6 = plr[v3]._pIFMinDam; + v7 = plr[v3]._pIFMaxDam; + missiledata[v4].mResist = 1; + } + else + { + v6 = plr[v3]._pILMinDam; + v7 = plr[v3]._pILMaxDam; + missiledata[v4].mResist = 2; + } + CheckMissileCol(ia, v6, v7, 0, missile[v1]._mix, missile[v1]._miy, 0, v10); + v8 = missile[v1]._miVar1; + if ( v8 ) + { + if ( missile[v1]._mirange ) + ChangeLight(missile[v1]._mlid, missile[v1]._mix, missile[v1]._miy, *(&r + v8)); + } + else + { + missile[v1]._mlid = AddLight(missile[v1]._mix, missile[v1]._miy, 9); + } + ++missile[v1]._miVar1; + if ( missile[v1]._mirange ) + { + PutMissile(ia); + } + else + { + v9 = missile[v1]._mlid; + missile[v1]._miDelFlag = 1; + AddUnLight(v9); + } +} + +//----- (0042F5D6) -------------------------------------------------------- +void __fastcall MI_Misexp(int i) +{ + int v1; // edi + int v2; // esi + bool v3; // zf + int v4; // ecx + int v5; // eax + int r; // [esp+8h] [ebp-28h] + int v7; // [esp+Ch] [ebp-24h] + int v8; // [esp+10h] [ebp-20h] + int v9; // [esp+14h] [ebp-1Ch] + int v10; // [esp+18h] [ebp-18h] + int v11; // [esp+1Ch] [ebp-14h] + int v12; // [esp+20h] [ebp-10h] + int v13; // [esp+24h] [ebp-Ch] + int v14; // [esp+28h] [ebp-8h] + int v15; // [esp+2Ch] [ebp-4h] + + v1 = i; + v2 = i; + r = 9; + v3 = missile[i]._mirange == 1; + --missile[v2]._mirange; + v7 = 10; + v9 = 12; + v8 = 11; + v10 = 11; + v11 = 10; + v12 = 8; + v13 = 6; + v14 = 4; + v15 = 2; + if ( v3 ) + { + v4 = missile[v2]._mlid; + missile[v2]._miDelFlag = 1; + AddUnLight(v4); + } + else + { + v5 = missile[v2]._miVar1; + if ( v5 ) + ChangeLight(missile[v2]._mlid, missile[v2]._mix, missile[v2]._miy, *(&r + v5)); + else + missile[v2]._mlid = AddLight(missile[v2]._mix, missile[v2]._miy, 9); + ++missile[v2]._miVar1; + PutMissile(v1); + } +} + +//----- (0042F692) -------------------------------------------------------- +void __fastcall MI_Acidsplat(int i) +{ + int v1; // eax + int v2; // edx + int v3; // edx + int v4; // edx + int v5; // ST1C_4 + + v1 = i; + v2 = missile[i]._mirange; + if ( v2 == missile[i]._miAnimLen ) + { + ++missile[v1]._mix; + ++missile[v1]._miy; + missile[v1]._miyoff -= 32; + } + v3 = v2 - 1; + missile[v1]._mirange = v3; + if ( v3 ) + { + PutMissile(i); + } + else + { + v4 = missile[v1]._misource; + v5 = missile[v1]._mispllvl; + missile[v1]._miDelFlag = 1; + AddMissile( + missile[v1]._mix, + missile[v1]._miy, + i, + 0, + missile[v1]._mimfnum, + 59, + 1, + v4, + (monster[v4].MData->mLevel >= 2) + 1, + v5); + } +} + +//----- (0042F723) -------------------------------------------------------- +void __fastcall MI_Teleport(int i) +{ + int v1; // edi + int v2; // ebx + int *v3; // eax + int v4; // esi + int v5; // ecx + int v6; // edx + int v7; // ecx + int v8; // edx + int v9; // edx + int v10; // eax + bool v11; // zf + + v1 = i; + v2 = missile[i]._misource; + v3 = &missile[i]._mirange; + if ( --*v3 > 0 ) + { + v4 = v2; + v5 = plr[v2].WorldX; + v6 = plr[v2].WorldY; + dPlayer[plr[v2].WorldX][v6] = 0; + PlrClrTrans(v5, v6); + v7 = missile[v1]._mix; + v8 = missile[v1]._miy; + plr[v4].WorldX = v7; + plr[v4].WorldY = v8; + plr[v4]._px = v7; + plr[v4]._py = v8; + plr[v4]._poldx = v7; + plr[v4]._poldy = v8; + PlrDoTrans(v7, v8); + v9 = plr[v2].WorldX; + missile[v1]._miVar1 = 1; + v10 = plr[v2].WorldY; + v11 = leveltype == 0; + dPlayer[v9][v10] = v2 + 1; + if ( !v11 ) + { + ChangeLightXY(plr[v4]._plid, v9, v10); + ChangeVisionXY(plr[v4]._pvid, plr[v4].WorldX, plr[v4].WorldY); + } + if ( v2 == myplr ) + { + ViewX = plr[v4].WorldX - ScrollInfo._sdx; + ViewY = plr[v4].WorldY - ScrollInfo._sdy; + } + } + else + { + missile[v1]._miDelFlag = 1; + } +} +// 5BB1ED: using guessed type char leveltype; + +//----- (0042F82C) -------------------------------------------------------- +void __fastcall MI_Stone(int i) +{ + int v1; // esi + int v2; // edi + int v3; // edi + bool v4; // zf + bool v5; // sf + int ia; // [esp+Ch] [ebp-4h] + + v1 = i; + ia = i; + v2 = missile[i]._miVar2; + --missile[v1]._mirange; + v3 = v2; + if ( !monster[v3]._mhitpoints && _LOBYTE(missile[v1]._miAnimType) != 18 ) + { + missile[v1]._mimfnum = 0; + missile[v1]._miDrawFlag = 1; + SetMissAnim(i, MFILE_SHATTER1); + missile[v1]._mirange = 11; + } + if ( monster[v3]._mmode == MM_STONE ) + { + if ( !missile[v1]._mirange ) + { + v4 = monster[v3]._mhitpoints == 0; + v5 = monster[v3]._mhitpoints < 0; + missile[v1]._miDelFlag = 1; + if ( v5 || v4 ) + AddDead(monster[v3]._mx, monster[v3]._my, stonendx, (direction)monster[v3]._mdir); + else + monster[v3]._mmode = missile[v1]._miVar1; + } + if ( _LOBYTE(missile[v1]._miAnimType) == 18 ) + PutMissile(ia); + } + else + { + missile[v1]._miDelFlag = 1; + } +} + +//----- (0042F8EE) -------------------------------------------------------- +void __fastcall MI_Boom(int i) +{ + int v1; // edi + int v2; // esi + bool v3; // [esp-4h] [ebp-10h] + + v1 = i; + v2 = i; + --missile[v2]._mirange; + if ( !missile[i]._miVar1 ) + CheckMissileCol(i, missile[v2]._midam, missile[v2]._midam, 0, missile[v2]._mix, missile[v2]._miy, 1, v3); + if ( missile[v2]._miHitFlag == 1 ) + missile[v2]._miVar1 = 1; + if ( !missile[v2]._mirange ) + missile[v2]._miDelFlag = 1; + PutMissile(v1); +} + +//----- (0042F94F) -------------------------------------------------------- +void __fastcall MI_Rhino(int i) +{ + int v1; // ebx + int v2; // esi + int v3; // edi + int v4; // edi + int v5; // eax + int v6; // eax + int v7; // ebx + bool v8; // zf + int x; // [esp+Ch] [ebp-1Ch] + int v10; // [esp+10h] [ebp-18h] + int y; // [esp+14h] [ebp-14h] + int a2; // [esp+18h] [ebp-10h] + int a3; // [esp+1Ch] [ebp-Ch] + int arglist; // [esp+20h] [ebp-8h] + int a1; // [esp+24h] [ebp-4h] + + v1 = i; + v2 = i; + arglist = i; + v3 = missile[i]._misource; + a1 = v3; + v4 = v3; + if ( monster[v4]._mmode != MM_CHARGE ) + goto LABEL_12; + GetMissilePos(i); + v5 = missile[v2]._mix; + x = v5; + v10 = missile[v2]._miy; + dMonster[0][v10 + 112 * v5] = 0; + v6 = missile[v2]._mixvel; + if ( monster[v4]._mAi == MG_SNAKE ) + { + missile[v2]._mitxoff += 2 * v6; + missile[v2]._mityoff += 2 * missile[v2]._miyvel; + GetMissilePos(v1); + a2 = missile[v2]._mix; + a3 = missile[v2]._miy; + missile[v2]._mitxoff -= missile[v2]._mixvel; + missile[v2]._mityoff -= missile[v2]._miyvel; + } + else + { + missile[v2]._mitxoff += v6; + missile[v2]._mityoff += missile[v2]._miyvel; + } + GetMissilePos(v1); + v7 = missile[v2]._mix; + y = missile[v2]._miy; + if ( !PosOkMonst(a1, missile[v2]._mix, missile[v2]._miy) || monster[v4]._mAi == MG_SNAKE && !PosOkMonst(a1, a2, a3) ) + { + MissToMonst(arglist, x, v10); +LABEL_12: + missile[v2]._miDelFlag = 1; + return; + } + v8 = monster[v4]._uniqtype == 0; + monster[v4]._mfutx = v7; + monster[v4]._moldx = v7; + dMonster[0][y + 112 * v7] = -1 - a1; + monster[v4]._mx = v7; + monster[v4]._mfuty = y; + monster[v4]._moldy = y; + monster[v4]._my = y; + if ( !v8 ) + ChangeLightXY(missile[v2]._mlid, v7, y); + MoveMissilePos(arglist); + PutMissile(arglist); +} + +//----- (0042FAD0) -------------------------------------------------------- +void __fastcall mi_null_32(int i) +{ + int v1; // edi + int v2; // esi + int v3; // ebx + int v4; // edi + int v5; // eax + int v6; // eax + int v7; // ecx + int v8; // eax + int v9; // eax + int v10; // ebx + int v11; // eax + int v12; // eax + int v13; // ecx + int v14; // ecx + int v15; // eax + int v16; // [esp+Ch] [ebp-14h] + int arglist; // [esp+10h] [ebp-10h] + int x; // [esp+14h] [ebp-Ch] + int y; // [esp+18h] [ebp-8h] + int a3; // [esp+1Ch] [ebp-4h] + + v1 = i; + arglist = i; + GetMissilePos(i); + v2 = v1; + v3 = missile[v1]._mix; + a3 = missile[v1]._miy; + missile[v2]._mitxoff += missile[v1]._mixvel; + missile[v2]._mityoff += missile[v1]._miyvel; + GetMissilePos(v1); + v4 = missile[v1]._misource; + y = missile[v2]._miy; + v5 = monster[v4]._menemy; + x = missile[v2]._mix; + if ( monster[v4]._mFlags & 0x10 ) + { + v9 = v5; + v7 = monster[v9]._mx; + v8 = monster[v9]._my; + } + else + { + v6 = v5; + v7 = plr[v6].WorldX; + v8 = plr[v6].WorldY; + } + v16 = v8; + if ( (missile[v2]._mix != v3 || y != a3) + && (missile[v2]._miVar1 & 1 && (abs(v3 - v7) >= 4 || abs(a3 - v16) >= 4) || missile[v2]._miVar2 > 1) + && PosOkMonst(missile[v2]._misource, v3, a3) ) + { + MissToMonst(arglist, v3, a3); + v10 = v16; + missile[v2]._miDelFlag = 1; + } + else + { + v11 = x; + if ( monster[v4]._mFlags & 0x10 ) + v10 = dMonster[0][y + v11 * 112]; + else + v10 = dPlayer[v11][y]; + } + _LOBYTE(v12) = PosOkMissile(x, y); + if ( !v12 || v10 > 0 && !(missile[v2]._miVar1 & 1) ) + { + missile[v2]._mixvel = -missile[v2]._mixvel; + v13 = missile[v2]._mimfnum; + missile[v2]._miyvel = -missile[v2]._miyvel; + v14 = opposite[v13]; + missile[v2]._mimfnum = v14; + v15 = monster[v4].MType->Anims[1].Frames[v14 + 1]; + ++missile[v2]._miVar2; + missile[v2]._miAnimCel = v15; + if ( v10 > 0 ) + missile[v2]._miVar1 |= 1u; + } + MoveMissilePos(arglist); + PutMissile(arglist); +} + +//----- (0042FC74) -------------------------------------------------------- +void __fastcall MI_FirewallC(int i) +{ + int v1; // esi + int v2; // edx + bool v3; // zf + int v4; // eax + int v5; // edi + int v6; // ecx + int v7; // ebx + int v8; // eax + int v9; // edi + int v10; // ecx + int v11; // ebx + int id; // [esp+Ch] [ebp-4h] + + v1 = i; + v2 = missile[i]._misource; + v3 = missile[i]._mirange == 1; + --missile[v1]._mirange; + id = v2; + if ( v3 ) + { + missile[v1]._miDelFlag = 1; + } + else + { + v4 = missile[v1]._miVar3; + v5 = missile[v1]._miVar1 + XDirAdd[v4]; + v6 = missile[v1]._miVar2; + v7 = v6 + YDirAdd[v4]; + if ( nMissileTable[dPiece[0][v6 + 112 * missile[v1]._miVar1]] + || missile[v1]._miVar8 + || v5 <= 0 + || v5 >= 112 + || v7 <= 0 + || v7 >= 112 ) + { + missile[v1]._miVar8 = 1; + } + else + { + AddMissile( + missile[v1]._miVar1, + v6, + missile[v1]._miVar1, + v6, + plr[v2]._pdir, + 5, + 0, + v2, + 0, + missile[v1]._mispllvl); + v2 = id; + missile[v1]._miVar1 = v5; + missile[v1]._miVar2 = v7; + } + v8 = missile[v1]._miVar4; + v9 = missile[v1]._miVar5 + XDirAdd[v8]; + v10 = missile[v1]._miVar6; + v11 = v10 + YDirAdd[v8]; + if ( nMissileTable[dPiece[0][v10 + 112 * missile[v1]._miVar5]] + || missile[v1]._miVar7 + || v9 <= 0 + || v9 >= 112 + || v11 <= 0 + || v11 >= 112 ) + { + missile[v1]._miVar7 = 1; + } + else + { + AddMissile( + missile[v1]._miVar5, + v10, + missile[v1]._miVar5, + v10, + plr[v2]._pdir, + 5, + 0, + v2, + 0, + missile[v1]._mispllvl); + missile[v1]._miVar5 = v9; + missile[v1]._miVar6 = v11; + } + } +} + +//----- (0042FDE3) -------------------------------------------------------- +void __fastcall MI_Infra(int i) +{ + int v1; // eax + int *v2; // ecx + int v3; // esi + int v4; // ecx + + v1 = i; + v2 = &missile[i]._mirange; + v3 = --*v2; + v4 = missile[v1]._misource; + plr[missile[v1]._misource]._pInfraFlag = 1; + if ( !v3 ) + { + missile[v1]._miDelFlag = 1; + CalcPlrItemVals(v4, 1); + } +} + +//----- (0042FE20) -------------------------------------------------------- +void __fastcall MI_Apoca(int i) +{ + int v1; // esi + int v2; // edi + signed int v3; // eax + int v4; // ecx + int v5; // ebx + int id; // [esp+8h] [ebp-8h] + int v7; // [esp+Ch] [ebp-4h] + + v1 = i; + v2 = missile[i]._miVar2; + id = missile[i]._misource; + v3 = 0; + if ( v2 >= missile[i]._miVar3 ) + goto LABEL_18; + do + { + if ( v3 ) + break; + v4 = missile[v1]._miVar4; + v7 = missile[v1]._miVar4; + if ( v4 >= missile[v1]._miVar5 ) + { +LABEL_11: + missile[v1]._miVar4 = missile[v1]._miVar6; + } + else + { + v5 = v2 + 112 * v4; + while ( !v3 ) + { + if ( dMonster[0][v5] > 3 && !nSolidTable[dPiece[0][v5]] ) + { + AddMissile(v4, v2, v4, v2, plr[id]._pdir, 36, 0, id, missile[v1]._midam, 0); + v4 = v7; + v3 = 1; + } + ++v4; + v5 += 112; + v7 = v4; + if ( v4 >= missile[v1]._miVar5 ) + { + if ( v3 ) + break; + goto LABEL_11; + } + } + } + ++v2; + } + while ( v2 < missile[v1]._miVar3 ); + if ( v3 != 1 ) + { +LABEL_18: + missile[v1]._miDelFlag = 1; + } + else + { + missile[v1]._miVar2 = v2 - 1; + missile[v1]._miVar4 = v7; + } +} + +//----- (0042FF0B) -------------------------------------------------------- +void __fastcall MI_Wave(int i) +{ + int v1; // esi + int v2; // ebx + int v3; // eax + int v4; // edi + int v5; // ecx + int v6; // eax + int v7; // ebx + int v8; // eax + int v9; // ebx + int v10; // eax + int v11; // ebx + bool v12; // zf + int v13; // [esp+Ch] [ebp-2Ch] + int v14; // [esp+10h] [ebp-28h] + int v15; // [esp+14h] [ebp-24h] + int v16; // [esp+14h] [ebp-24h] + signed int v17; // [esp+18h] [ebp-20h] + int *v18; // [esp+1Ch] [ebp-1Ch] + signed int v19; // [esp+20h] [ebp-18h] + int v20; // [esp+24h] [ebp-14h] + int v21; // [esp+24h] [ebp-14h] + int v22; // [esp+28h] [ebp-10h] + int j; // [esp+28h] [ebp-10h] + int id; // [esp+2Ch] [ebp-Ch] + int sx; // [esp+30h] [ebp-8h] + int sy; // [esp+34h] [ebp-4h] + int sya; // [esp+34h] [ebp-4h] + + v19 = 0; + v1 = i; + v17 = 0; + v2 = missile[i]._mix; + id = missile[i]._misource; + v14 = v2; + v20 = missile[i]._miy; + v3 = GetDirection(v2, v20, missile[i]._miVar1, missile[i]._miVar2); + v22 = ((_BYTE)v3 - 2) & 7; + v4 = v3; + v15 = ((_BYTE)v3 + 2) & 7; + v5 = YDirAdd[v3]; + v6 = XDirAdd[v3]; + v7 = v6 + v2; + sy = v5 + v20; + if ( !nMissileTable[dPiece[0][v5 + v20 + 112 * v7]] ) + { + v18 = &plr[id]._pdir; + AddMissile(v7, sy, v7 + v6, sy + v5, *v18, 14, 0, id, 0, missile[v1]._mispllvl); + v13 = v22; + sya = YDirAdd[v22] + sy; + v8 = v15; + sx = XDirAdd[v22] + v7; + v16 = v8 * 4; + v9 = XDirAdd[v8]; + v10 = v20 + YDirAdd[v4] + YDirAdd[v8]; + v11 = v14 + XDirAdd[v4] + v9; + v21 = 0; + for ( j = v10; v21 < (missile[v1]._mispllvl >> 1) + 2; ++v21 ) + { + if ( nMissileTable[dPiece[0][sya + 112 * sx]] || v19 || sx <= 0 || sx >= 112 || sya <= 0 || sya >= 112 ) + { + v19 = 1; + } + else + { + AddMissile(sx, sya, sx + XDirAdd[v4], sya + YDirAdd[v4], *v18, 14, 0, id, 0, missile[v1]._mispllvl); + sx += XDirAdd[v13]; + sya += YDirAdd[v13]; + v10 = j; + } + if ( nMissileTable[dPiece[0][v10 + 112 * v11]] || v17 || v11 <= 0 || v11 >= 112 || v10 <= 0 || v10 >= 112 ) + { + v17 = 1; + } + else + { + AddMissile(v11, v10, v11 + XDirAdd[v4], v10 + YDirAdd[v4], *v18, 14, 0, id, 0, missile[v1]._mispllvl); + v11 += *(int *)((char *)XDirAdd + v16); + j += *(int *)((char *)YDirAdd + v16); + v10 = j; + } + } + } + v12 = missile[v1]._mirange-- == 1; + if ( v12 ) + missile[v1]._miDelFlag = 1; +} + +//----- (00430154) -------------------------------------------------------- +void __fastcall MI_Nova(int i) +{ + int v1; // edi + int v2; // edx + int eax1; // eax + int v4; // ebx + unsigned char *v5; // esi + int v6; // eax + bool v7; // zf + int v8; // [esp+Ch] [ebp-18h] + int sy; // [esp+10h] [ebp-14h] + int id; // [esp+14h] [ebp-10h] + int v3; // [esp+18h] [ebp-Ch] + int midir; // [esp+1Ch] [ebp-8h] + signed int micaster; // [esp+20h] [ebp-4h] + + v1 = i; + v2 = 0; + eax1 = missile[i]._misource; + v4 = missile[i]._mix; + v3 = missile[i]._midam; + v8 = 0; + id = missile[i]._misource; + sy = missile[i]._miy; + if ( eax1 == -1 ) + { + midir = 0; + micaster = 1; + } + else + { + micaster = 0; + midir = plr[eax1]._pdir; + } + v5 = &vCrawlTable[0][7]; + do + { + v6 = *(v5 - 1); + if ( v2 != v6 || v8 != *v5 ) + { + AddMissile(v4, sy, v4 + v6, sy + *v5, midir, 4, micaster, id, v3, missile[v1]._mispllvl); + AddMissile(v4, sy, v4 - *(v5 - 1), sy - *v5, midir, 4, micaster, id, v3, missile[v1]._mispllvl); + AddMissile(v4, sy, v4 - *(v5 - 1), sy + *v5, midir, 4, micaster, id, v3, missile[v1]._mispllvl); + AddMissile(v4, sy, v4 + *(v5 - 1), sy - *v5, midir, 4, micaster, id, v3, missile[v1]._mispllvl); + v2 = *(v5 - 1); + v8 = *v5; + } + v5 += 30; + } + while ( (signed int)v5 < (signed int)&RadiusAdj[0][6] ); + v7 = missile[v1]._mirange-- == 1; + if ( v7 ) + missile[v1]._miDelFlag = 1; +} + +//----- (004302A7) -------------------------------------------------------- +void __fastcall MI_Blodboil(int i) +{ + missile[i]._miDelFlag = 1; +} + +//----- (004302B8) -------------------------------------------------------- +void __fastcall MI_Flame(int i) +{ + int v1; // ebx + int v2; // esi + int v3; // ST0C_4 + int v4; // edx + int v5; // edi + int v6; // ST08_4 + int v7; // eax + int v8; // eax + int v9; // ecx + bool v10; // [esp-4h] [ebp-10h] + + v1 = i; + v2 = i; + v3 = missile[i]._miy; + v4 = missile[i]._midam; + --missile[v2]._mirange; + v5 = missile[i]._mirange; + v6 = missile[i]._mix; + --missile[v2]._miVar2; + CheckMissileCol(i, v4, v4, 1u, v6, v3, 0, v10); + if ( !missile[v2]._mirange && missile[v2]._miHitFlag == 1 ) + missile[v2]._mirange = v5; + v7 = missile[v2]._miVar2; + if ( !v7 ) + missile[v2]._miAnimFrame = 20; + if ( v7 <= 0 ) + { + v8 = missile[v2]._miAnimFrame; + if ( v8 > 11 ) + v8 = 24 - v8; + ChangeLight(missile[v2]._mlid, missile[v2]._mix, missile[v2]._miy, v8); + } + if ( !missile[v2]._mirange ) + { + v9 = missile[v2]._mlid; + missile[v2]._miDelFlag = 1; + AddUnLight(v9); + } + if ( missile[v2]._miVar2 <= 0 ) + PutMissile(v1); +} + +//----- (0043037E) -------------------------------------------------------- +void __fastcall MI_Flamec(int i) +{ + int v1; // edi + int v2; // esi + int v3; // eax + int v4; // ebx + int v5; // ecx + int v6; // edx + int v7; // eax + int v8; // eax + + v1 = i; + v2 = i; + v3 = missile[i]._mixvel; + --missile[v2]._mirange; + missile[v2]._mitxoff += v3; + v4 = missile[i]._misource; + missile[v2]._mityoff += missile[i]._miyvel; + GetMissilePos(i); + v5 = missile[v2]._mix; + if ( v5 != missile[v2]._miVar1 || missile[v2]._miy != missile[v2]._miVar2 ) + { + v6 = missile[v2]._miy; + v7 = dPiece[0][v6 + 112 * v5]; + if ( nMissileTable[v7] ) + { + missile[v2]._mirange = 0; + } + else + { + _LOBYTE(v7) = missile[v2]._micaster; + AddMissile( + v5, + v6, + missile[v2]._misx, + missile[v2]._misy, + v1, + 48, + v7, + v4, + missile[v2]._miVar3, + missile[v2]._mispllvl); + } + v8 = missile[v2]._mix; + ++missile[v2]._miVar3; + missile[v2]._miVar1 = v8; + missile[v2]._miVar2 = missile[v2]._miy; + } + if ( !missile[v2]._mirange || missile[v2]._miVar3 == 3 ) + missile[v2]._miDelFlag = 1; +} + +//----- (0043045C) -------------------------------------------------------- +void __fastcall MI_Cbolt(int i) +{ + int v1; // esi + bool v2; // zf + int v3; // eax + int v4; // edx + int v5; // eax + int v6; // ecx + int v7; // ecx + int v8; // ecx + int v9; // ecx + bool v10; // [esp-4h] [ebp-54h] + int v11; // [esp+Ch] [ebp-44h] + int v12; // [esp+10h] [ebp-40h] + int v13; // [esp+14h] [ebp-3Ch] + int v14; // [esp+18h] [ebp-38h] + int v15; // [esp+1Ch] [ebp-34h] + int v16; // [esp+20h] [ebp-30h] + int v17; // [esp+24h] [ebp-2Ch] + int v18; // [esp+28h] [ebp-28h] + int v19; // [esp+2Ch] [ebp-24h] + int v20; // [esp+30h] [ebp-20h] + int v21; // [esp+34h] [ebp-1Ch] + int v22; // [esp+38h] [ebp-18h] + int v23; // [esp+3Ch] [ebp-14h] + int v24; // [esp+40h] [ebp-10h] + int v25; // [esp+44h] [ebp-Ch] + int v26; // [esp+48h] [ebp-8h] + int ia; // [esp+4Ch] [ebp-4h] + + ia = i; + v1 = i; + --missile[v1]._mirange; + v2 = _LOBYTE(missile[i]._miAnimType) == 3; + v11 = -1; + v12 = 0; + v13 = 1; + v14 = -1; + v15 = 0; + v16 = 1; + v17 = -1; + v18 = -1; + v19 = 0; + v20 = 0; + v21 = 1; + v22 = 1; + v23 = 0; + v24 = 1; + v25 = -1; + v26 = 0; + if ( !v2 ) + { + v3 = missile[v1]._miVar3; + if ( v3 ) + { + missile[v1]._miVar3 = v3 - 1; + } + else + { + v4 = missile[v1]._mirnd; + v5 = (missile[v1]._miVar2 + *(&v11 + v4)) & 7; + missile[v1]._mirnd = ((_BYTE)v4 + 1) & 0xF; + GetMissileVel( + ia, + missile[v1]._mix, + missile[v1]._miy, + missile[v1]._mix + XDirAdd[v5], + missile[v1]._miy + YDirAdd[v5], + 8); + missile[v1]._miVar3 = 16; + } + v6 = ia; + missile[v1]._mitxoff += missile[v1]._mixvel; + missile[v1]._mityoff += missile[v1]._miyvel; + GetMissilePos(v6); + CheckMissileCol(ia, missile[v1]._midam, missile[v1]._midam, 0, missile[v1]._mix, missile[v1]._miy, 0, v10); + if ( missile[v1]._miHitFlag == 1 ) + { + v7 = ia; + missile[v1]._miVar1 = 8; + missile[v1]._mimfnum = 0; + missile[v1]._mixoff = 0; + missile[v1]._miyoff = 0; + SetMissAnim(v7, MFILE_LGHNING); + v8 = ia; + missile[v1]._mirange = missile[v1]._miAnimLen; + GetMissilePos(v8); + } + ChangeLight(missile[v1]._mlid, missile[v1]._mix, missile[v1]._miy, missile[v1]._miVar1); + } + if ( !missile[v1]._mirange ) + { + v9 = missile[v1]._mlid; + missile[v1]._miDelFlag = 1; + AddUnLight(v9); + } + PutMissile(ia); +} + +//----- (004305E2) -------------------------------------------------------- +void __fastcall MI_Hbolt(int i) +{ + int v1; // edi + int v2; // esi + int v3; // eax + int v4; // edx + int v5; // ecx + int v6; // ST10_4 + int v7; // ecx + bool v8; // [esp+0h] [ebp-8h] + + v1 = i; + v2 = i; + --missile[v2]._mirange; + if ( _LOBYTE(missile[i]._miAnimType) == 28 ) + { + ChangeLight(missile[v2]._mlid, missile[v2]._mix, missile[v2]._miy, missile[v2]._miAnimFrame + 7); + if ( !missile[v2]._mirange ) + { + v7 = missile[v2]._mlid; + missile[v2]._miDelFlag = 1; + AddUnLight(v7); + } + } + else + { + missile[v2]._mitxoff += missile[v2]._mixvel; + missile[v2]._mityoff += missile[v2]._miyvel; + GetMissilePos(i); + v3 = missile[v2]._mix; + if ( v3 != missile[v2]._misx || missile[v2]._miy != missile[v2]._misy ) + CheckMissileCol(v1, missile[v2]._midam, missile[v2]._midam, 0, v3, missile[v2]._miy, 0, v8); + if ( missile[v2]._mirange ) + { + v4 = missile[v2]._mix; + if ( v4 != missile[v2]._miVar1 || missile[v2]._miy != missile[v2]._miVar2 ) + { + v5 = missile[v2]._mlid; + missile[v2]._miVar1 = v4; + v6 = missile[v2]._miy; + missile[v2]._miVar2 = v6; + ChangeLight(v5, v4, v6, 8); + } + } + else + { + missile[v2]._mitxoff -= missile[v2]._mixvel; + missile[v2]._mityoff -= missile[v2]._miyvel; + GetMissilePos(v1); + missile[v2]._mimfnum = 0; + SetMissAnim(v1, MFILE_HOLYEXPL); + missile[v2]._mirange = missile[v2]._miAnimLen - 1; + } + } + PutMissile(v1); +} + +//----- (0043071F) -------------------------------------------------------- +void __fastcall MI_Element(int i) +{ + int v1; // esi + int v2; // edi + int v3; // eax + int v4; // ebx + int v5; // ebx + int v6; // ecx + int v7; // ebx + int v8; // eax + int v9; // edi + int v10; // eax + int v11; // edi + int v12; // ecx + bool v13; // [esp-4h] [ebp-28h] + bool v14; // [esp+0h] [ebp-24h] + bool v15; // [esp+4h] [ebp-20h] + bool v16; // [esp+8h] [ebp-1Ch] + int ty; // [esp+Ch] [ebp-18h] + int tya; // [esp+Ch] [ebp-18h] + int tyb; // [esp+Ch] [ebp-18h] + int my; // [esp+10h] [ebp-14h] + int mya; // [esp+10h] [ebp-14h] + int myb; // [esp+10h] [ebp-14h] + int fx; // [esp+14h] [ebp-10h] + int fxa; // [esp+14h] [ebp-10h] + int fy; // [esp+18h] [ebp-Ch] + int ia; // [esp+1Ch] [ebp-8h] + int y; // [esp+20h] [ebp-4h] + int ya; // [esp+20h] [ebp-4h] + + v1 = i; + ia = i; + --missile[v1]._mirange; + v2 = missile[i]._midam; + ty = missile[i]._misource; + if ( _LOBYTE(missile[i]._miAnimType) == 19 ) + { + v3 = missile[i]._misource; + v4 = missile[v1]._mix; + y = missile[v1]._miy; + fx = plr[v3].WorldX; + fy = plr[v3].WorldY; + ChangeLight(missile[v1]._mlid, v4, y, missile[v1]._miAnimFrame); + if ( !CheckBlock(fx, fy, v4, y) ) + CheckMissileCol(ia, v2, v2, 1u, v4, y, 1, v13); + my = y + 1; + if ( !CheckBlock(fx, fy, v4, y + 1) ) + CheckMissileCol(ia, v2, v2, 1u, v4, my, 1, v14); + tya = y - 1; + if ( !CheckBlock(fx, fy, v4, y - 1) ) + CheckMissileCol(ia, v2, v2, 1u, v4, tya, 1, v15); + if ( !CheckBlock(fx, fy, v4 + 1, y) ) + CheckMissileCol(ia, v2, v2, 1u, v4 + 1, y, 1, v16); + if ( !CheckBlock(fx, fy, v4 + 1, tya) ) + CheckMissileCol(ia, v2, v2, 1u, v4 + 1, tya, 1, tya); + if ( !CheckBlock(fx, fy, v4 + 1, my) ) + CheckMissileCol(ia, v2, v2, 1u, v4 + 1, my, 1, my); + v5 = v4 - 1; + if ( !CheckBlock(fx, fy, v5, y) ) + CheckMissileCol(ia, v2, v2, 1u, v5, y, 1, fx); + if ( !CheckBlock(mya, fy, v5, mya) ) + CheckMissileCol(ia, v2, v2, 1u, v5, myb, 1, fy); + if ( !CheckBlock(fxa, tyb, v5, tyb) ) + CheckMissileCol(ia, v2, v2, 1u, v5, tyb, 1, ia); + if ( !missile[v1]._mirange ) + { + v6 = missile[v1]._mlid; + missile[v1]._miDelFlag = 1; + AddUnLight(v6); + } + } + else + { + missile[v1]._mitxoff += missile[v1]._mixvel; + missile[v1]._mityoff += missile[v1]._miyvel; + GetMissilePos(i); + v7 = missile[v1]._mix; + ya = missile[v1]._miy; + CheckMissileCol(ia, v2, v2, 0, missile[v1]._mix, ya, 0, v13); + if ( !missile[v1]._miVar3 && v7 == missile[v1]._miVar4 && ya == missile[v1]._miVar5 ) + missile[v1]._miVar3 = 1; + if ( missile[v1]._miVar3 == 1 ) + { + missile[v1]._miVar3 = 2; + missile[v1]._mirange = 255; + v8 = FindClosest(v7, ya, 19); + if ( v8 <= 0 ) + { + v11 = plr[ty]._pdir; + SetMissDir(ia, plr[ty]._pdir); + GetMissileVel(ia, v7, ya, v7 + XDirAdd[v11], ya + YDirAdd[v11], 16); + } + else + { + v9 = v8; + v10 = GetDirection8(v7, ya, monster[v8]._mx, monster[v8]._my); + SetMissDir(ia, v10); + GetMissileVel(ia, v7, ya, monster[v9]._mx, monster[v9]._my, 16); + } + } + if ( v7 != missile[v1]._miVar1 || ya != missile[v1]._miVar2 ) + { + missile[v1]._miVar2 = ya; + v12 = missile[v1]._mlid; + missile[v1]._miVar1 = v7; + ChangeLight(v12, v7, ya, 8); + } + if ( !missile[v1]._mirange ) + { + missile[v1]._mimfnum = 0; + SetMissAnim(ia, MFILE_BIGEXP); + missile[v1]._mirange = missile[v1]._miAnimLen - 1; + } + } + PutMissile(ia); +} + +//----- (00430A98) -------------------------------------------------------- +void __fastcall MI_Bonespirit(int i) +{ + int v1; // ebx + int v2; // esi + int v3; // eax + int v4; // ecx + int v5; // ecx + int v6; // edi + int v7; // ebx + int v8; // eax + int v9; // edi + int v10; // ST14_4 + int v11; // ST10_4 + int v12; // eax + int v13; // ST24_4 + int v14; // ecx + bool v15; // [esp-4h] [ebp-20h] + int v16; // [esp+Ch] [ebp-10h] + int maxdam; // [esp+10h] [ebp-Ch] + int y1; // [esp+14h] [ebp-8h] + int ia; // [esp+18h] [ebp-4h] + + v1 = i; + v2 = i; + ia = i; + v3 = missile[i]._midam; + --missile[v2]._mirange; + maxdam = v3; + v16 = missile[i]._misource; + if ( missile[i]._mimfnum == 8 ) + { + ChangeLight(missile[v2]._mlid, missile[v2]._mix, missile[v2]._miy, missile[v2]._miAnimFrame); + if ( !missile[v2]._mirange ) + { + v4 = missile[v2]._mlid; + missile[v2]._miDelFlag = 1; + AddUnLight(v4); + } + v5 = v1; + } + else + { + missile[v2]._mitxoff += missile[v2]._mixvel; + missile[v2]._mityoff += missile[v2]._miyvel; + GetMissilePos(i); + v6 = missile[v2]._miy; + v7 = missile[v2]._mix; + y1 = missile[v2]._miy; + CheckMissileCol(ia, maxdam, maxdam, 0, missile[v2]._mix, v6, 0, v15); + if ( !missile[v2]._miVar3 && v7 == missile[v2]._miVar4 && v6 == missile[v2]._miVar5 ) + missile[v2]._miVar3 = 1; + if ( missile[v2]._miVar3 == 1 ) + { + missile[v2]._miVar3 = 2; + missile[v2]._mirange = 255; + v8 = FindClosest(v7, v6, 19); + if ( v8 <= 0 ) + { + v13 = plr[v16]._pdir; + SetMissDir(ia, v13); + GetMissileVel(ia, v7, v6, v7 + XDirAdd[v13], v6 + YDirAdd[v13], 16); + } + else + { + v9 = v8; + v10 = monster[v8]._my; + v11 = monster[v8]._mx; + missile[v2]._midam = monster[v8]._mhitpoints >> 7; + v12 = GetDirection8(v7, y1, v11, v10); + SetMissDir(ia, v12); + GetMissileVel(ia, v7, y1, monster[v9]._mx, monster[v9]._my, 16); + v6 = y1; + } + } + if ( v7 != missile[v2]._miVar1 || v6 != missile[v2]._miVar2 ) + { + v14 = missile[v2]._mlid; + missile[v2]._miVar1 = v7; + missile[v2]._miVar2 = v6; + ChangeLight(v14, v7, v6, 8); + } + if ( !missile[v2]._mirange ) + { + SetMissDir(ia, 8); + missile[v2]._mirange = 7; + } + v5 = ia; + } + PutMissile(v5); +} + +//----- (00430C8D) -------------------------------------------------------- +void __fastcall MI_ResurrectBeam(int i) +{ + int v1; // eax + bool v2; // zf + + v1 = i; + v2 = missile[i]._mirange == 1; + --missile[v1]._mirange; + if ( v2 ) + missile[v1]._miDelFlag = 1; + PutMissile(i); +} + +//----- (00430CAC) -------------------------------------------------------- +void __fastcall MI_Rportal(int i) +{ + int v1; // esi + int v2; // eax + int v3; // ecx + int r; // [esp+8h] [ebp-48h] + int v5; // [esp+Ch] [ebp-44h] + int v6; // [esp+10h] [ebp-40h] + int v7; // [esp+14h] [ebp-3Ch] + int v8; // [esp+18h] [ebp-38h] + int v9; // [esp+1Ch] [ebp-34h] + int v10; // [esp+20h] [ebp-30h] + int v11; // [esp+24h] [ebp-2Ch] + int v12; // [esp+28h] [ebp-28h] + int v13; // [esp+2Ch] [ebp-24h] + int v14; // [esp+30h] [ebp-20h] + int v15; // [esp+34h] [ebp-1Ch] + int v16; // [esp+38h] [ebp-18h] + int v17; // [esp+3Ch] [ebp-14h] + int v18; // [esp+40h] [ebp-10h] + int v19; // [esp+44h] [ebp-Ch] + int v20; // [esp+48h] [ebp-8h] + int ia; // [esp+4Ch] [ebp-4h] + + v1 = i; + v18 = 15; + v19 = 15; + v20 = 15; + v2 = missile[i]._mirange; + ia = i; + r = 1; + v5 = 2; + v6 = 3; + v7 = 4; + v8 = 5; + v9 = 6; + v10 = 7; + v11 = 8; + v12 = 9; + v13 = 10; + v14 = 11; + v15 = 12; + v16 = 13; + v17 = 14; + if ( v2 > 1 ) + missile[v1]._mirange = v2 - 1; + if ( missile[v1]._mirange == missile[v1]._miVar1 ) + SetMissDir(i, 1); + if ( currlevel && missile[v1]._mimfnum != 1 ) + { + if ( !missile[v1]._mirange ) + { +LABEL_12: + v3 = missile[v1]._mlid; + missile[v1]._miDelFlag = 1; + AddUnLight(v3); + goto LABEL_13; + } + if ( !missile[v1]._miVar2 ) + missile[v1]._mlid = AddLight(missile[v1]._mix, missile[v1]._miy, 1); + ChangeLight(missile[v1]._mlid, missile[v1]._mix, missile[v1]._miy, *(&r + missile[v1]._miVar2)); + ++missile[v1]._miVar2; + } + if ( !missile[v1]._mirange ) + goto LABEL_12; +LABEL_13: + PutMissile(ia); +} + +//----- (00430DDA) -------------------------------------------------------- +void __cdecl ProcessMissiles() +{ + int v0; // eax + int i; // edx + int v2; // ecx + int v3; // edx + int v4; // edi + int v5; // esi + int *v6; // eax + int v7; // ecx + int *v8; // eax + int v9; // esi + int v10; // esi + int v11; // edx + + v0 = nummissiles; + for ( i = 0; i < v0; dMissile[0][v2] = 0 ) + { + v2 = 112 * missile[missileactive[i]]._mix + missile[missileactive[i]]._miy; + dFlags[0][v2] &= 0xFEu; + ++i; + } + v3 = 0; + while ( v3 < v0 ) + { + if ( missile[missileactive[v3]]._miDelFlag ) + { + DeleteMissile(missileactive[v3], v3); + v0 = nummissiles; + v3 = 0; + } + else + { + ++v3; + } + } + v4 = 0; + MissilePreFlag = 0; + ManashieldFlag = 0; + if ( v0 > 0 ) + { + do + { + v5 = missileactive[v4]; + missiledata[missile[v5]._mitype].mProc(missileactive[v4]); + if ( !(missile[v5]._miAnimFlags & 2) ) + { + v6 = &missile[v5]._miAnimCnt; + ++*v6; + if ( missile[v5]._miAnimCnt >= missile[v5]._miAnimDelay ) + { + v7 = missile[v5]._miAnimAdd; + *v6 = 0; + v8 = &missile[v5]._miAnimFrame; + v9 = missile[v5]._miAnimLen; + *v8 += v7; + if ( *v8 > v9 ) + *v8 = 1; + if ( *v8 < 1 ) + *v8 = v9; + } + } + v0 = nummissiles; + ++v4; + } + while ( v4 < nummissiles ); + if ( ManashieldFlag ) + { + v10 = 0; + if ( nummissiles > 0 ) + { + do + { + if ( missile[missileactive[v10]]._mitype == 13 ) + { + MI_Manashield(missileactive[v10]); + v0 = nummissiles; + } + ++v10; + } + while ( v10 < v0 ); + } + } + } + v11 = 0; + while ( v11 < v0 ) + { + if ( missile[missileactive[v11]]._miDelFlag ) + { + DeleteMissile(missileactive[v11], v11); + v0 = nummissiles; + v11 = 0; + } + else + { + ++v11; + } + } +} +// 64CCD4: using guessed type int MissilePreFlag; + +//----- (00430F35) -------------------------------------------------------- +void __cdecl missiles_process_charge() +{ + int v0; // ebx + int i; // edi + int v2; // ecx + int v3; // esi + bool v4; // zf + CMonster *v5; // eax + char v6; // dl + int v7; // eax + + v0 = nummissiles; + for ( i = 0; i < v0; ++i ) + { + v2 = missileactive[i]; + v3 = missile[v2]._mimfnum; + v4 = missile[v2]._mitype == MIS_RHINO; + missile[v2]._miAnimCel = misfiledata[0].mAnimCel[v3 + 59 * _LOBYTE(missile[v2]._miAnimType)]; + if ( v4 ) + { + v5 = monster[missile[v2]._misource].MType; + v6 = v5->mtype; + if ( v5->mtype < MON_RHINOA || v6 > MON_RHINOD ) + { + if ( v6 < MON_SNAKEA || v6 > MON_SNAKED ) + v7 = (int)v5->Anims[1].Frames; + else + v7 = (int)v5->Anims[2].Frames; + } + else + { + v7 = (int)v5->Anims[5].Frames; + } + missile[v2]._miAnimCel = *(_DWORD *)(v7 + 4 * v3 + 4); + } + } +} + +//----- (00430FB9) -------------------------------------------------------- +void __fastcall ClearMissileSpot(int i) +{ + int v1; // eax + + v1 = missile[i]._miy + 112 * missile[i]._mix; + dFlags[0][v1] &= 0xFEu; + dMissile[0][v1] = 0; +} + +//----- (00430FE4) -------------------------------------------------------- +void __cdecl monster_cpp_init() +{ + monster_cpp_init_value = monster_inf; +} +// 47F130: using guessed type int monster_inf; +// 64CCE4: using guessed type int monster_cpp_init_value; + +//----- (00430FEF) -------------------------------------------------------- +void __fastcall monster_init_special(int mon_id, int special) +{ + int v2; // esi + signed int v3; // ecx + int v4; // esi + _BYTE *v5; // eax + int v6; // ebp + unsigned char v7; // al + int v8; // edi + int *v9; // ebx + signed int v10; // [esp+8h] [ebp-8h] + int v11; // [esp+Ch] [ebp-4h] + + v2 = mon_id; + v3 = 256; + v4 = v2; + v5 = (unsigned char *)Monsters[v4].trans_file; + do + { + if ( *v5 == -1 ) + *v5 = 0; + ++v5; + --v3; + } + while ( v3 ); + v6 = 0; + v11 = (special != 0) + 5; + if ( v11 > 0 ) + { + do + { + if ( v6 != 1 || (v7 = Monsters[v4].mtype, v7 < MON_MAGEA) || v7 > MON_MAGED ) + { + v10 = 8; + v8 = 44 * v6 + v4 * 328; + v9 = (int *)((char *)&Monsters[0].Anims[0].Frames[1] + v8); + do + { + engine_cel_trn(*v9, (int)Monsters[v4].trans_file, *(int *)((char *)&Monsters[0].Anims[0].Rate + v8)); + ++v9; + --v10; + } + while ( v10 ); + } + ++v6; + } + while ( v6 < v11 ); + } +} + +//----- (0043107B) -------------------------------------------------------- +void __cdecl InitLevelMonsters() +{ + char *v0; // eax + int v1; // eax + + nummtypes = 0; + monstimgtot = 0; + MissileFileFlag = 0; + v0 = &Monsters[0].mPlaceFlags; + do + { + *v0 = 0; + v0 += 328; + } + while ( (signed int)v0 < (signed int)&END_Monsters_17 ); + ClrAllMonsters(); + nummonsters = 0; + totalmonsters = 200; + v1 = 0; + do + { + monstactive[v1] = v1; + ++v1; + } + while ( v1 < 200 ); + uniquetrans = 0; +} +// 64CCE0: using guessed type int MissileFileFlag; +// 658550: using guessed type int totalmonsters; +// 6599D9: using guessed type int END_Monsters_17; +// 659AE8: using guessed type int monstimgtot; + +//----- (004310CF) -------------------------------------------------------- +int __fastcall AddMonsterType(int type, int placeflag) +{ + char v2; // bl + int v3; // eax + int v4; // esi + CMonster *v5; // edi + int v6; // eax + int v7; // esi + + v2 = placeflag; + v3 = 0; + v4 = 0; + if ( nummtypes > 0 ) + { + v5 = Monsters; + do + { + if ( v3 ) + break; + v6 = -(type != (unsigned char)v5->mtype); + ++v5; + v3 = v6 + 1; + ++v4; + } + while ( v4 < nummtypes ); + } + v7 = v4 - 1; + if ( !v3 ) + { + v7 = nummtypes++; + Monsters[v7].mtype = type; + monstimgtot += monsterdata[type].mType; + InitMonsterGFX(v7); + InitMonsterSND(v7); + } + Monsters[v7].mPlaceFlags |= v2; + return v7; +} +// 659AE8: using guessed type int monstimgtot; + +//----- (0043114F) -------------------------------------------------------- +void __cdecl GetLevelMTypes() +{ + int v0; // eax + int v1; // eax + int v2; // eax + int v3; // eax + int v4; // eax + int v5; // eax + unsigned char *v6; // esi + int v7; // edi + int v8; // ecx + int v9; // eax + int v10; // eax + int v11; // esi + int v12; // edi + unsigned char *v13; // ecx + int i; // esi + int v15; // ecx + bool v16; // zf + int v17; // edx + int *v18; // eax + int v19; // esi + int *v20; // esi + int v21; // eax + int v22; // [esp+8h] [ebp-328h] + int v23[89]; // [esp+Ch] [ebp-324h] + int v24[111]; // [esp+170h] [ebp-1C0h] + int max; // [esp+32Ch] [ebp-4h] + + AddMonsterType(109, 2); + if ( currlevel == 16 ) + { + AddMonsterType(108, 1); + AddMonsterType(96, 1); + AddMonsterType(110, 2); + } + else if ( setlevel ) + { + if ( setlvlnum == SL_SKELKING ) + AddMonsterType(50, 4); + } + else + { + _LOBYTE(v0) = QuestStatus(6); + if ( v0 ) + AddMonsterType(51, 2); + _LOBYTE(v1) = QuestStatus(2); + if ( v1 ) + AddMonsterType((char)UniqMonst[0].mtype, 4); + _LOBYTE(v2) = QuestStatus(3); + if ( v2 ) + AddMonsterType((char)UniqMonst[2].mtype, 4); + _LOBYTE(v3) = QuestStatus(7); + if ( v3 ) + AddMonsterType((char)UniqMonst[3].mtype, 4); + _LOBYTE(v4) = QuestStatus(4); + if ( v4 ) + AddMonsterType((char)UniqMonst[7].mtype, 4); + _LOBYTE(v5) = QuestStatus(11); + if ( v5 ) + AddMonsterType((char)UniqMonst[8].mtype, 4); + if ( gbMaxPlayers != 1 && currlevel == quests[12]._qlevel ) + { + AddMonsterType(50, 4); + max = 0; + v6 = &monsterdata[8].mMaxDLvl; + v7 = 8; + do + { + if ( IsSkel(v7) ) + { + v8 = currlevel; + if ( currlevel >= 15 * (char)*(v6 - 1) / 30 + 1 + && currlevel <= 15 * (char)*v6 / 30 + 1 + && MonstAvailTbl[v7] & 3 ) + { + v9 = max++; + v24[v9] = v7; + } + } + v6 += 128; + ++v7; + } + while ( (signed int)v6 <= (signed int)&monsterdata[27].mMaxDLvl ); + _LOBYTE(v8) = 88; + v10 = random(v8, max); + AddMonsterType(v24[v10], 1); + } + v11 = currlevel; + v12 = 0; + v13 = &monsterdata[0].mMaxDLvl; + max = 0; + do + { + if ( v11 >= 15 * (char)*(v13 - 1) / 30 + 1 && v11 <= 15 * (char)*v13 / 30 + 1 && MonstAvailTbl[max] & 3 ) + v23[v12++] = max; + ++max; + v13 += 128; + } + while ( (signed int)v13 < (signed int)&monsterdata[111].mMaxDLvl ); + if ( monstdebug ) + { + for ( i = 0; i < debugmonsttypes; ++i ) + AddMonsterType(DebugMonsters[i], 1); + } + else + { + while ( v12 > 0 ) + { + if ( nummtypes >= 16 || monstimgtot >= 4000 ) + break; + v15 = 0; + v16 = v12 == 0; + if ( v12 > 0 ) + { + v17 = 4000 - monstimgtot; + do + { + v18 = &v23[v15]; + if ( monsterdata[*v18].mType <= v17 ) + { + ++v15; + } + else + { + v19 = *(&v22 + v12--); + *v18 = v19; + } + } + while ( v15 < v12 ); + v16 = v12 == 0; + } + if ( !v16 ) + { + _LOBYTE(v15) = 88; + v20 = &v23[random(v15, v12)]; + AddMonsterType(*v20, 1); + v21 = *(&v22 + v12--); + *v20 = v21; + } + } + } + } +} +// 525730: using guessed type int monstdebug; +// 52573C: using guessed type int debugmonsttypes; +// 5CCB10: using guessed type char setlvlnum; +// 5CF31D: using guessed type char setlevel; +// 659AE8: using guessed type int monstimgtot; +// 679660: using guessed type char gbMaxPlayers; +// 43114F: using guessed type int var_1C0[111]; +// 43114F: using guessed type int var_324[89]; + +//----- (004313F9) -------------------------------------------------------- +void __fastcall InitMonsterGFX(int monst) +{ + int v1; // esi + int v2; // ebx + int v3; // ebx + int *v4; // edi + int *v5; // eax + char v6; // cl + unsigned char *v7; // eax + char v8; // cl + int *v9; // ecx + int v10; // edx + int v11; // ecx + int v12; // ecx + bool v13; // zf + int v14; // ecx + void **v15; // esi + unsigned char *v16; // eax + int v17; // edx + int v18; // ecx + void *v19; // ecx + int v20; // ecx + int v21; // ecx + int v22; // ecx + int v23; // ecx + int v24; // ecx + int v25; // ecx + char strBuff[256]; // [esp+Ch] [ebp-114h] + int mon_id; // [esp+10Ch] [ebp-14h] + int *v28; // [esp+110h] [ebp-10h] + int v29; // [esp+114h] [ebp-Ch] + int *v30; // [esp+118h] [ebp-8h] + int v31; // [esp+11Ch] [ebp-4h] + + v29 = 0; + mon_id = monst; + v1 = monst; + v2 = (unsigned char)Monsters[monst].mtype; + v31 = v2; + v3 = v2 << 7; + v4 = &Monsters[monst].Anims[0].Frames[1]; + v5 = (int *)((char *)monsterdata[0].Frames + v3); + v30 = &Monsters[monst].Anims[0].Frames[1]; + v28 = (int *)((char *)monsterdata[0].Frames + v3); + do + { + v6 = animletter[v29]; + if ( (v6 != 's' || *(int *)((char *)&monsterdata[0].has_special + v3)) && *v5 > 0 ) + { + sprintf(strBuff, *(const char **)((char *)&monsterdata[0].GraphicType + v3), v6); + v7 = LoadFileInMem(strBuff, 0); + *(v4 - 1) = (int)v7; + if ( Monsters[v1].mtype != MON_GOLEM || (v8 = animletter[v29], v8 != 's') && v8 != 'd' ) + { + v30 = 0; + v9 = v4; + do + { + v10 = (int)&v7[*(_DWORD *)&v7[4 * (_DWORD)v30]]; + v30 = (int *)((char *)v30 + 1); + *v9 = v10; + ++v9; + } + while ( (signed int)v30 < 8 ); + } + else + { + memset(v4, (int)v7, 8u); + v4 = v30; + } + v5 = v28; + } + v11 = *v5; + ++v29; + v4[8] = v11; + v4[9] = v5[6]; + ++v5; + v4 += 11; + v28 = v5; + v30 = v4; + } + while ( v29 < 6 ); + Monsters[v1].MData = (MonsterData *)((char *)monsterdata + v3); + v12 = *(int *)((char *)&monsterdata[0].flags + v3); + Monsters[v1].flags_1 = v12; + Monsters[v1].flags_2 = (v12 - 64) >> 1; + Monsters[v1].mMinHP = *((_BYTE *)&monsterdata[0].mMinHP + v3); + v13 = *(int *)((char *)&monsterdata[0].has_trans + v3) == 0; + Monsters[v1].mMaxHP = *((_BYTE *)&monsterdata[0].mMaxHP + v3); + v14 = *(int *)((char *)&monsterdata[0].has_special + v3); + Monsters[v1].has_special = v14; + Monsters[v1].mAFNum = *(&monsterdata[0].mAFNum + v3); + if ( !v13 ) + { + v15 = &Monsters[v1].trans_file; + v16 = LoadFileInMem(*(char **)((char *)&monsterdata[0].TransFile + v3), 0); + v17 = *(int *)((char *)&monsterdata[0].has_special + v3); + v18 = mon_id; + *v15 = v16; + monster_init_special(v18, v17); + v19 = *v15; + *v15 = 0; + mem_free_dbg(v19); + } + if ( v31 >= MON_MAGMAA && v31 <= MON_MAGMAD && !(MissileFileFlag & 1) ) + { + MissileFileFlag |= 1u; + _LOBYTE(v14) = MFILE_MAGBALL; + LoadMissileGFX(v14); + } + if ( v31 >= MON_THINA && v31 <= MON_THIND && !(MissileFileFlag & 2) ) + { + MissileFileFlag |= 2u; + _LOBYTE(v14) = MFILE_THINLGHT; + LoadMissileGFX(v14); + } + if ( v31 == MON_SUCCA ) + { + if ( MissileFileFlag & 4 ) + return; + MissileFileFlag |= 4u; + _LOBYTE(v14) = MFILE_FLARE; + LoadMissileGFX(v14); + _LOBYTE(v20) = MFILE_FLAREEXP; + LoadMissileGFX(v20); + } + if ( v31 == MON_SUCCB ) + { + if ( MissileFileFlag & 0x20 ) + return; + MissileFileFlag |= 0x20u; + _LOBYTE(v14) = MFILE_SCUBMISB; + LoadMissileGFX(v14); + _LOBYTE(v21) = MFILE_SCBSEXPB; + LoadMissileGFX(v21); + } + if ( v31 == MON_SUCCC ) + { + if ( MissileFileFlag & 0x40 ) + return; + MissileFileFlag |= 0x40u; + _LOBYTE(v14) = MFILE_SCUBMISD; + LoadMissileGFX(v14); + _LOBYTE(v22) = MFILE_SCBSEXPD; + LoadMissileGFX(v22); + } + if ( v31 == MON_SUCCD ) + { + if ( (MissileFileFlag & 0x80u) != 0 ) + return; + _LOBYTE(MissileFileFlag) = MissileFileFlag | 0x80; + _LOBYTE(v14) = MFILE_SCUBMISC; + LoadMissileGFX(v14); + _LOBYTE(v23) = MFILE_SCBSEXPC; + LoadMissileGFX(v23); + } + if ( v31 >= MON_FIREMANA && v31 <= MON_FIREMAND && !(MissileFileFlag & 8) ) + { + MissileFileFlag |= 8u; + _LOBYTE(v14) = MFILE_KRULL; + LoadMissileGFX(v14); + } + if ( v31 >= MON_ACIDA && v31 <= MON_ACIDD && !(MissileFileFlag & 0x10) ) + { + MissileFileFlag |= 0x10u; + _LOBYTE(v14) = MFILE_ACIDBF; + LoadMissileGFX(v14); + _LOBYTE(v24) = MFILE_ACIDSPLA; + LoadMissileGFX(v24); + _LOBYTE(v25) = MFILE_ACIDPUD; + LoadMissileGFX(v25); + } + if ( v31 == MON_DIABLO ) + { + _LOBYTE(v14) = MFILE_FIREPLAR; + LoadMissileGFX(v14); + } +} +// 64CCE0: using guessed type int MissileFileFlag; + +//----- (004316AE) -------------------------------------------------------- +void __fastcall ClearMVars(int i) +{ + int v1; // ecx + + v1 = i; + monster[v1]._mVar1 = 0; + monster[v1]._mVar2 = 0; + monster[v1]._mVar3 = 0; + monster[v1]._mVar4 = 0; + monster[v1]._mVar5 = 0; + monster[v1]._mVar6 = 0; + monster[v1]._mVar7 = 0; + monster[v1]._mVar8 = 0; +} + +//----- (004316E7) -------------------------------------------------------- +void __fastcall InitMonster(int i, int rd, int mtype, int x, int y) +{ + int v5; // ebx + int v6; // esi + CMonster *v7; // edi + MonsterData *v8; // eax + char *v9; // ecx + int v10; // eax + int v11; // eax + int v12; // ecx + int v13; // eax + bool v14; // zf + int v15; // ecx + int v16; // eax + MonsterData *v17; // eax + int v18; // eax + MonsterData *v19; // eax + short v20; // cx + int v21; // edx + int v22; // edx + int v23; // edi + int v24; // ecx + int v25; // ecx + char v26; // dl + int v27; // ecx + char v28; // dl + + v5 = rd; + v6 = i; + monster[v6]._mmode = MM_STAND; + v7 = &Monsters[mtype]; + monster[v6]._mx = x; + monster[v6]._mfutx = x; + monster[v6]._moldx = x; + v8 = v7->MData; + monster[v6]._mdir = rd; + monster[v6]._my = y; + monster[v6]._mfuty = y; + monster[v6]._moldy = y; + monster[v6]._mMTidx = mtype; + v9 = v8->mName; + monster[v6].mName = v9; + monster[v6].MType = v7; + monster[v6].MData = v8; + monster[v6]._mAFNum = v7->Anims[0].Frames[rd + 1]; + v10 = v7->Anims[0].Delay; + _LOBYTE(v9) = 88; + monster[v6]._mAnimDelay = v10; + monster[v6]._mAnimCnt = random((int)v9, v10 - 1); + v11 = v7->Anims[0].Rate; + _LOBYTE(v12) = 88; + monster[v6]._mAnimLen = v11; + v13 = random(v12, v11 - 1); + v14 = v7->mtype == 110; + monster[v6]._mAnimFrame = v13 + 1; + _LOBYTE(v15) = 88; + if ( v14 ) + v16 = random(v15, 1) + 1666; + else + v16 = (unsigned char)v7->mMinHP + random(v15, (unsigned char)v7->mMaxHP - (unsigned char)v7->mMinHP + 1); + v14 = gbMaxPlayers == 1; + monster[v6]._mmaxhp = v16 << 6; + if ( v14 ) + { + monster[v6]._mmaxhp >>= 1; + if ( monster[v6]._mmaxhp < 64 ) + monster[v6]._mmaxhp = 64; + } + monster[v6]._mhitpoints = monster[v6]._mmaxhp; + v17 = v7->MData; + monster[v6]._mAi = v17->mAi; + monster[v6]._mint = v17->mInt; + _LOBYTE(monster[v6]._pathcount) = 0; + monster[v6]._uniqtype = 0; + _LOBYTE(monster[v6]._msquelch) = 0; + _LOBYTE(monster[v6]._mgoal) = 1; + monster[v6]._mgoalvar1 = 0; + monster[v6]._mgoalvar2 = 0; + monster[v6]._mgoalvar3 = 0; + monster[v6].field_18 = 0; + monster[v6]._mDelFlag = 0; + monster[v6]._mRndSeed = GetRndSeed(); + v18 = GetRndSeed(); + monster[v6].mWhoHit = 0; + monster[v6]._mAISeed = v18; + v19 = v7->MData; + _LOBYTE(monster[v6].mLevel) = v19->mLevel; + monster[v6].mExp = v19->mExp; + monster[v6].mHit = v19->mHit; + monster[v6].mMinDamage = v19->mMinDamage; + monster[v6].mMaxDamage = v19->mMaxDamage; + monster[v6].mHit2 = v19->mHit2; + monster[v6].mMinDamage2 = v19->mMinDamage2; + monster[v6].mMaxDamage2 = v19->mMaxDamage2; + monster[v6].mArmorClass = v19->mArmorClass; + v20 = v19->mMagicRes; + monster[v6].leader = 0; + monster[v6].leaderflag = 0; + _LOWORD(monster[v6].mMagicRes) = v20; + v21 = v19->mFlags; + monster[v6].mtalkmsg = 0; + v14 = monster[v6]._mAi == MG_GARG; + monster[v6]._mFlags = v21; + if ( v14 ) + { + v22 = v7->Anims[5].Frames[v5 + 1]; + monster[v6]._mFlags |= 4u; + monster[v6]._mAFNum = v22; + monster[v6]._mAnimFrame = 1; + monster[v6]._mmode = MM_SATTACK; + } + v23 = gnDifficulty; + if ( gnDifficulty == DIFF_NIGHTMARE ) + { + v24 = monster[v6]._mmaxhp; + _LOBYTE(monster[v6].mLevel) += 15; + monster[v6].mHit += 85; + monster[v6].mHit2 += 85; + v25 = 3 * v24 + 64; + monster[v6]._mmaxhp = v25; + monster[v6]._mhitpoints = v25; + monster[v6].mExp = 2 * (monster[v6].mExp + 1000); + monster[v6].mMinDamage = 2 * (monster[v6].mMinDamage + DIFF_HELL); + monster[v6].mMaxDamage = 2 * (monster[v6].mMaxDamage + DIFF_HELL); + monster[v6].mMinDamage2 = 2 * (monster[v6].mMinDamage2 + DIFF_HELL); + _LOBYTE(v25) = 2 * (monster[v6].mMaxDamage2 + DIFF_HELL); + monster[v6].mArmorClass += 50; + monster[v6].mMaxDamage2 = v25; + } + if ( v23 == DIFF_HELL ) + { + v26 = 4 * monster[v6].mMinDamage; + v27 = 4 * monster[v6]._mmaxhp + 192; + _LOBYTE(monster[v6].mLevel) += 30; + monster[v6]._mmaxhp = v27; + monster[v6]._mhitpoints = v27; + _LOWORD(v27) = monster[v6].mExp; + monster[v6].mHit += 120; + monster[v6].mHit2 += 120; + monster[v6].mExp = 4 * (v27 + 1000); + monster[v6].mMinDamage = v26 + 6; + monster[v6].mMaxDamage = 4 * monster[v6].mMaxDamage + 6; + monster[v6].mMinDamage2 = 4 * monster[v6].mMinDamage2 + 6; + v28 = 4 * monster[v6].mMaxDamage2 + 6; + monster[v6].mArmorClass += 80; + monster[v6].mMaxDamage2 = v28; + _LOWORD(monster[v6].mMagicRes) = v19->mMagicRes2; + } +} +// 679660: using guessed type char gbMaxPlayers; + +//----- (00431A6B) -------------------------------------------------------- +void __cdecl ClrAllMonsters() +{ + int v0; // edi + int *v1; // esi + int v2; // ecx + int v3; // eax + int v4; // edx + int v5; // ecx + int v6; // eax + char v7; // cl + + v0 = 0; + v1 = &monster[0]._mgoal; + do + { + ClearMVars(v0); + _LOBYTE(v2) = 89; + v1[52] = (int)"Invalid Monster"; + *(_BYTE *)v1 = 0; + *(v1 - 1) = 0; + v1[26] = 0; + v1[27] = 0; + v1[6] = 0; + v1[7] = 0; + v1[8] = 0; + v1[9] = 0; + v1[10] = 0; + v1[11] = 0; + v3 = random(v2, 8); + v4 = (unsigned char)gbActivePlayers; + _LOBYTE(v5) = 89; + v1[16] = v3; + v1[14] = 0; + v1[15] = 0; + v1[19] = 0; + v1[20] = 0; + v1[21] = 0; + v1[22] = 0; + v1[23] = 0; + v1[37] = 0; + v1[25] = 0; + v6 = random(v5, v4); + v1[17] = v6; + v6 *= 21720; + v7 = *((_BYTE *)&plr[0]._px + v6); + _LOBYTE(v6) = *((_BYTE *)&plr[0]._py + v6); + *((_BYTE *)v1 + 72) = v7; + *((_BYTE *)v1 + 73) = v6; + v1 += 57; + ++v0; + } + while ( (signed int)v1 < (signed int)Monsters ); +} +// 67862C: using guessed type char gbActivePlayers; + +//----- (00431B10) -------------------------------------------------------- +int __fastcall MonstPlace(int xp, int yp) +{ + int v2; // eax + char v3; // al + int result; // eax + + if ( xp < 0 + || xp >= 112 + || yp < 0 + || yp >= 112 + || (v2 = xp, dMonster[0][112 * xp + yp]) + || dPlayer[v2][yp] + || (v3 = dFlags[v2][yp], v3 & 2) + || v3 & 8 ) + { + result = 0; + } + else + { + result = SolidLoc(xp, yp) == 0; + } + return result; +} + +//----- (00431B5D) -------------------------------------------------------- +void __fastcall PlaceMonster(int i, int mtype, int x, int y) +{ + int v4; // esi + int v5; // ecx + int v6; // edi + int v7; // eax + + v4 = i; + v5 = y + 112 * x; + v6 = mtype; + dMonster[0][v5] = v4 + 1; + _LOBYTE(v5) = 90; + v7 = random(v5, 8); + InitMonster(v4, v7, v6, x, y); +} + +//----- (00431B99) -------------------------------------------------------- +void __fastcall PlaceUniqueMonst(int uniqindex, int miniontype, int unpackfilesize) +{ + MonsterStruct *v3; // esi + CMonster *v4; // ecx + int v5; // edx + int v6; // eax + int v7; // ecx + int v8; // edi + int v9; // eax + int v10; // ebx + int v11; // eax + int i; // edx + int v13; // edx + BOOL v14; // edx + int (*v15)[112]; // ecx + int (*v16)[112]; // eax + int v17; // edi + char v18; // al + char *v19; // eax + int v20; // eax + bool v21; // zf + signed int v22; // eax + char v23; // cl + char v24; // al + int v25; // edx + int v26; // eax + int v27; // ecx + char v28; // al + char v29; // al + int v30; // ecx + int v31; // eax + int v32; // eax + int v33; // eax + int v34; // eax + char v35; // al + short v36; // cx + char v37; // al + int v38; // ecx + int v39; // eax + int v40; // edx + int v41; // eax + char arglist[64]; // [esp+4h] [ebp-60h] + int v43; // [esp+44h] [ebp-20h] + CMonster *v44; // [esp+48h] [ebp-1Ch] + int v45; // [esp+4Ch] [ebp-18h] + int *v46; // [esp+50h] [ebp-14h] + int v47; // [esp+54h] [ebp-10h] + int v48; // [esp+58h] [ebp-Ch] + int mtype; // [esp+5Ch] [ebp-8h] + int xp; // [esp+60h] [ebp-4h] + + v46 = 0; + v48 = uniqindex; + v3 = &monster[nummonsters]; + v4 = (CMonster *)&UniqMonst[uniqindex]; + v43 = miniontype; + v44 = v4; + if ( (uniquetrans + 19) << 8 < 6912 ) + { + mtype = 0; + if ( nummtypes > 0 ) + { + v5 = v4->mtype; + v4 = Monsters; + do + { + if ( (unsigned char)v4->mtype == v5 ) + break; + ++mtype; + ++v4; + } + while ( mtype < nummtypes ); + } + do + { + do + { + _LOBYTE(v4) = 91; + v6 = random((int)v4, 80); + _LOBYTE(v7) = 91; + v8 = v6 + 16; + v9 = random(v7, 80); + v47 = 0; + v4 = (CMonster *)(v8 - 3); + v10 = v9 + 16; + xp = v8 - 3; + if ( __OFSUB__(v8 - 3, v8 + 3) ^ 1 ) + { + v11 = v9 + 19; + do + { + for ( i = v10 - 3; ; i = v45 + 1 ) + { + v45 = i; + if ( i >= v11 ) + break; + if ( i >= 0 && i < 112 && xp >= 0 && xp < 112 && MonstPlace(xp, i) ) + ++v47; + v11 = v10 + 3; + } + ++xp; + v4 = (CMonster *)(v8 + 3); + } + while ( xp < v8 + 3 ); + if ( v47 >= 9 ) + break; + } + v46 = (int *)((char *)v46 + 1); + } + while ( (signed int)v46 < 1000 ); + } + while ( !MonstPlace(v8, v10) ); + v13 = v48; + if ( v48 == 3 ) + { + v8 = 2 * setpc_x + 24; + v10 = 2 * setpc_y + 28; + } + if ( v48 == 8 ) + { + v8 = 2 * setpc_x + 22; + v10 = 2 * setpc_y + 23; + } + if ( v48 == 2 ) + { + xp = 0; + v45 = 1; + if ( themeCount > 0 ) + { + v46 = &themeLoc[0].y; + do + { + if ( xp == zharlib && v45 == 1 ) + { + v45 = 0; + v8 = 2 * *(v46 - 1) + 20; + v10 = 2 * *v46 + 20; + } + ++xp; + v46 += 5; + } + while ( xp < themeCount ); + } + v13 = v48; + } + if ( gbMaxPlayers == 1 ) + { + if ( v13 == 4 ) + { + v8 = 32; + v10 = 46; + } + if ( v13 == 5 ) + { + v8 = 40; + v10 = 45; + } + if ( v13 == 6 ) + { + v8 = 38; + v10 = 49; + } + if ( v13 == 1 ) + { + v8 = 35; + v10 = 47; + } + } + else + { + if ( v13 == 4 ) + { + v8 = 2 * setpc_x + 19; + v10 = 2 * setpc_y + 22; + } + if ( v13 == 5 ) + { + v8 = 2 * setpc_x + 21; + v10 = 2 * setpc_y + 19; + } + if ( v13 == 6 ) + { + v8 = 2 * setpc_x + 21; + v10 = 2 * setpc_y + 25; + } + } + if ( v13 == 9 ) + { + v14 = 0; + v10 = 0; + v15 = dPiece; + do + { + if ( v14 ) + break; + v8 = 0; + v16 = v15; + do + { + if ( v14 ) + break; + v14 = (*v16)[0] == 367; + ++v8; + ++v16; + } + while ( v8 < 112 ); + v15 = (int (*)[112])((char *)v15 + 4); + ++v10; + } + while ( (signed int)v15 < (signed int)dPiece[1] ); + } + PlaceMonster(nummonsters, mtype, v8, v10); + v17 = (int)v44; + v3->_uniqtype = v48 + 1; + v18 = *(_BYTE *)(v17 + 12); + if ( v18 ) + _LOBYTE(v3->mLevel) = 2 * v18; + else + _LOBYTE(v3->mLevel) += 5; + v19 = *(char **)(v17 + 4); + v3->mExp *= 2; + v3->mName = v19; + v20 = *(unsigned short *)(v17 + 14) << 6; + v21 = gbMaxPlayers == 1; + v3->_mmaxhp = v20; + if ( v21 ) + { + v22 = v20 >> 1; + v3->_mmaxhp = v22; + if ( v22 < 64 ) + v3->_mmaxhp = 64; + } + v23 = *(_BYTE *)(v17 + 19); + v3->_mhitpoints = v3->_mmaxhp; + v3->_mAi = *(_BYTE *)(v17 + 16); + v3->_mint = *(_BYTE *)(v17 + 17); + v24 = *(_BYTE *)(v17 + 18); + v25 = v3->_my; + v3->mMinDamage = v24; + v3->mMinDamage2 = v24; + _LOWORD(v3->mMagicRes) = *(_WORD *)(v17 + 20); + v26 = *(_DWORD *)(v17 + 28); + v3->mMaxDamage = v23; + v3->mMaxDamage2 = v23; + v27 = v3->_mx; + v3->mtalkmsg = v26; + v28 = AddLight(v27, v25, 3); + v21 = gbMaxPlayers == 1; + v3->mlid = v28; + if ( v21 ) + goto LABEL_83; + v29 = v3->_mAi; + if ( v29 == 29 ) + v3->mtalkmsg = 0; + if ( v29 != 28 || quests[15]._qvar1 <= 3u ) + { +LABEL_83: + if ( v3->mtalkmsg ) + _LOBYTE(v3->_mgoal) = 6; + } + else + { + _LOBYTE(v3->_mgoal) = 1; + } + v30 = gnDifficulty; + if ( gnDifficulty == DIFF_NIGHTMARE ) + { + v31 = v3->_mmaxhp; + _LOBYTE(v3->mLevel) += 15; + v32 = 3 * v31 + 64; + v3->_mmaxhp = v32; + v3->_mhitpoints = v32; + v3->mExp = 2 * (v3->mExp + 1000); + v3->mMinDamage = 2 * (v3->mMinDamage + 2); + v3->mMaxDamage = 2 * (v3->mMaxDamage + 2); + v3->mMinDamage2 = 2 * (v3->mMinDamage2 + 2); + v3->mMaxDamage2 = 2 * (v3->mMaxDamage2 + 2); + } + if ( v30 == DIFF_HELL ) + { + v33 = v3->_mmaxhp; + _LOBYTE(v3->mLevel) += 30; + v34 = 4 * v33 + 192; + v3->_mmaxhp = v34; + v3->_mhitpoints = v34; + v3->mExp = 4 * (v3->mExp + 1000); + v3->mMinDamage = 4 * v3->mMinDamage + 6; + v3->mMaxDamage = 4 * v3->mMaxDamage + 6; + v3->mMinDamage2 = 4 * v3->mMinDamage2 + 6; + v3->mMaxDamage2 = 4 * v3->mMaxDamage2 + 6; + } + sprintf(arglist, "Monsters\\Monsters\\%s.TRN", *(_DWORD *)(v17 + 8)); + LoadFileWithMem(arglist, (void *)(dword_646A20 + ((uniquetrans + 19) << 8))); + v35 = uniquetrans; + v36 = *(_WORD *)(v17 + 22); + ++uniquetrans; + v3->_uniqtrans = v35; + if ( v36 & 4 ) + { + v37 = *(_BYTE *)(v17 + 24); + v3->mHit = v37; + v3->mHit2 = v37; + } + if ( v36 & 8 ) + v3->mArmorClass = *(_BYTE *)(v17 + 24); + ++nummonsters; + if ( v36 & 1 ) + PlaceGroup(v43, unpackfilesize, v36, nummonsters - 1); + if ( v3->_mAi != 12 ) + { + v38 = (int)v3->MType; + v39 = *(_DWORD *)(v38 + 4 * v3->_mdir + 8); + v40 = v3->_mAnimLen - 1; + _LOBYTE(v38) = 88; + v3->_mAFNum = v39; + v41 = random(v38, v40); + v3->_mFlags &= 0xFFFFFFFB; + v3->_mmode = 0; + v3->_mAnimFrame = v41 + 1; + } + } +} +// 679660: using guessed type char gbMaxPlayers; +// 6AAA64: using guessed type int zharlib; + +//----- (00432088) -------------------------------------------------------- +void __cdecl PlaceQuestMonsters() +{ + int v0; // eax + int v1; // esi + CMonster *v2; // edi + int v3; // eax + unsigned char *v4; // esi + int v5; // eax + unsigned char *v6; // esi + int v7; // eax + unsigned char *v8; // esi + int v9; // eax + unsigned char *v10; // esi + int v11; // eax + unsigned char *v12; // esi + int v13; // eax + int v14; // eax + unsigned char *v15; // esi + + if ( setlevel ) + { + if ( setlvlnum == SL_SKELKING ) + PlaceUniqueMonst(1, 0, 0); + } + else + { + _LOBYTE(v0) = QuestStatus(6); + if ( v0 ) + PlaceUniqueMonst(9, 0, 0); + if ( currlevel == quests[12]._qlevel && gbMaxPlayers != 1 ) + { + v1 = 0; + if ( nummtypes > 0 ) + { + v2 = Monsters; + do + { + if ( IsSkel((unsigned char)v2->mtype) ) + break; + ++v1; + ++v2; + } + while ( v1 < nummtypes ); + } + PlaceUniqueMonst(1, v1, 30); + } + _LOBYTE(v3) = QuestStatus(7); + if ( v3 ) + { + v4 = LoadFileInMem("Levels\\L1Data\\Banner1.DUN", 0); + SetMapMonsters((char *)v4, 2 * setpc_x, 2 * setpc_y); + mem_free_dbg(v4); + } + _LOBYTE(v5) = QuestStatus(9); + if ( v5 ) + { + v6 = LoadFileInMem("Levels\\L2Data\\Blood2.DUN", 0); + SetMapMonsters((char *)v6, 2 * setpc_x, 2 * setpc_y); + mem_free_dbg(v6); + } + _LOBYTE(v7) = QuestStatus(8); + if ( v7 ) + { + v8 = LoadFileInMem("Levels\\L2Data\\Blind2.DUN", 0); + SetMapMonsters((char *)v8, 2 * setpc_x, 2 * setpc_y); + mem_free_dbg(v8); + } + _LOBYTE(v9) = QuestStatus(10); + if ( v9 ) + { + v10 = LoadFileInMem("Levels\\L3Data\\Anvil.DUN", 0); + SetMapMonsters((char *)v10, 2 * setpc_x + 2, 2 * setpc_y + 2); + mem_free_dbg(v10); + } + _LOBYTE(v11) = QuestStatus(11); + if ( v11 ) + { + v12 = LoadFileInMem("Levels\\L4Data\\Warlord.DUN", 0); + SetMapMonsters((char *)v12, 2 * setpc_x, 2 * setpc_y); + mem_free_dbg(v12); + AddMonsterType((char)UniqMonst[8].mtype, 1); + } + _LOBYTE(v13) = QuestStatus(4); + if ( v13 ) + AddMonsterType((char)UniqMonst[7].mtype, 1); + _LOBYTE(v14) = QuestStatus(3); + if ( v14 && zharlib == -1 ) + quests[3]._qactive = 0; + if ( currlevel == quests[15]._qlevel && gbMaxPlayers != 1 ) + { + AddMonsterType((char)UniqMonst[4].mtype, 4); + AddMonsterType((char)UniqMonst[5].mtype, 4); + PlaceUniqueMonst(4, 0, 0); + PlaceUniqueMonst(5, 0, 0); + PlaceUniqueMonst(6, 0, 0); + v15 = LoadFileInMem("Levels\\L4Data\\Vile1.DUN", 0); + SetMapMonsters((char *)v15, 2 * setpc_x, 2 * setpc_y); + mem_free_dbg(v15); + } + } +} +// 5CCB10: using guessed type char setlvlnum; +// 5CF31D: using guessed type char setlevel; +// 679660: using guessed type char gbMaxPlayers; +// 6AAA64: using guessed type int zharlib; + +//----- (004322FA) -------------------------------------------------------- +void __fastcall PlaceGroup(int mtype, int num, unsigned char leaderf, int leader) +{ + int v4; // ecx + int *v5; // eax + int v6; // edx + int v7; // eax + int v8; // edi + int v9; // esi + int v10; // eax + int v11; // ecx + int v12; // eax + int v13; // ecx + int v14; // eax + int v15; // ST04_4 + int v16; // eax + int v17; // ST04_4 + int v18; // eax + int *v19; // edx + int v20; // ecx + int v21; // ebx + int v22; // ecx + int v23; // ecx + int mtypea; // [esp+Ch] [ebp-24h] + signed int v25; // [esp+14h] [ebp-1Ch] + int v26; // [esp+18h] [ebp-18h] + signed int i; // [esp+1Ch] [ebp-14h] + int v28; // [esp+20h] [ebp-10h] + int v29; // [esp+24h] [ebp-Ch] + int v30; // [esp+28h] [ebp-8h] + int v31; // [esp+2Ch] [ebp-4h] + + mtypea = mtype; + v4 = 0; + v31 = num; + v30 = 0; + v25 = 0; + do + { + if ( v4 ) + { + v30 = 0; + v5 = &monster[nummonsters]._my; + nummonsters -= v4; + do + { + v6 = *(v5 - 58); + v5 -= 57; + --v4; + dMonster[0][*v5 + 112 * v6] = 0; + } + while ( v4 ); + } + if ( leaderf & 1 ) + { + _LOBYTE(v4) = 92; + v7 = random(v4, 8); + v8 = monster[leader]._mx + offset_x[v7]; + v9 = monster[leader]._my + offset_y[v7]; + v29 = monster[leader]._mx + offset_x[v7]; + v28 = monster[leader]._my + offset_y[v7]; + } + else + { + do + { + _LOBYTE(v4) = 93; + v10 = random(v4, 80); + _LOBYTE(v11) = 93; + v8 = v10 + 16; + v29 = v10 + 16; + v12 = random(v11, 80); + v9 = v12 + 16; + v28 = v12 + 16; + } + while ( !MonstPlace(v8, v12 + 16) ); + } + if ( nummonsters + v31 > totalmonsters ) + v31 = totalmonsters - nummonsters; + v26 = 0; + for ( i = 0; v26 < v31; v9 += offset_x[random(v23, 8)] ) + { + if ( i >= 100 ) + break; + if ( !MonstPlace(v8, v9) + || (v13 = 112 * v29, dung_map[v8][v9] != dung_map[v29][v28]) + || leaderf & 2 + && ((v14 = abs(v8 - v29), v13 = v15, v14 >= 4) || (v16 = abs(v9 - v28), v13 = v17, v16 >= 4)) ) + { + ++i; + } + else + { + PlaceMonster(nummonsters, mtypea, v8, v9); + if ( leaderf & 1 ) + { + v18 = nummonsters; + v19 = &monster[nummonsters]._mmaxhp; + v20 = 2 * *v19; + *v19 = v20; + monster[v18]._mhitpoints = v20; + v13 = 228 * leader; + monster[v18]._mint = monster[leader]._mint; + if ( leaderf & 2 ) + { + monster[v18].leader = leader; + monster[v18].leaderflag = 1; + monster[v18]._mAi = *(&monster[0]._mAi + v13); + } + if ( monster[v18]._mAi != MG_GARG ) + { + v21 = nummonsters; + v22 = monster[v18].MType->Anims[0].Frames[monster[v18]._mdir + 1]; + monster[v18]._mAFNum = v22; + _LOBYTE(v22) = 88; + monster[v21]._mAnimFrame = random(v22, monster[v21]._mAnimLen - 1) + 1; + monster[v21]._mFlags &= 0xFFFFFFFB; + monster[v21]._mmode = MM_STAND; + } + } + ++nummonsters; + ++v30; + ++v26; + } + _LOBYTE(v13) = 94; + v8 += offset_x[random(v13, 8)]; + _LOBYTE(v23) = 94; + } + v4 = v30; + if ( v30 >= v31 ) + break; + ++v25; + } + while ( v25 < 10 ); + if ( leaderf & 2 ) + monster[leader].unpackfilesize = v30; +} +// 658550: using guessed type int totalmonsters; + +//----- (00432585) -------------------------------------------------------- +void __cdecl LoadDiabMonsts() +{ + unsigned char *v0; // esi + unsigned char *v1; // esi + unsigned char *v2; // esi + unsigned char *v3; // esi + + v0 = LoadFileInMem("Levels\\L4Data\\diab1.DUN", 0); + SetMapMonsters((char *)v0, 2 * diabquad1x, 2 * diabquad1y); + mem_free_dbg(v0); + v1 = LoadFileInMem("Levels\\L4Data\\diab2a.DUN", 0); + SetMapMonsters((char *)v1, 2 * diabquad2x, 2 * diabquad2y); + mem_free_dbg(v1); + v2 = LoadFileInMem("Levels\\L4Data\\diab3a.DUN", 0); + SetMapMonsters((char *)v2, 2 * diabquad3x, 2 * diabquad3y); + mem_free_dbg(v2); + v3 = LoadFileInMem("Levels\\L4Data\\diab4a.DUN", 0); + SetMapMonsters((char *)v3, 2 * diabquad4x, 2 * diabquad4y); + mem_free_dbg(v3); +} +// 5289C4: using guessed type int diabquad1x; +// 5289C8: using guessed type int diabquad1y; + +//----- (00432637) -------------------------------------------------------- +void __cdecl InitMonsters() +{ + int v0; // ebp + int v1; // ebx + TriggerStruct *v2; // esi + signed int v3; // ebp + signed int v4; // edi + int v5; // edi + int v6; // esi + int v7; // eax + int v8; // ecx + int v9; // edx + int v10; // eax + int v11; // esi + char *v12; // edi + int v13; // ebx + int v14; // ecx + int v15; // esi + int v16; // ecx + int v17; // eax + int v18; // eax + int v19; // ebx + TriggerStruct *v20; // esi + signed int v21; // ebp + signed int v22; // edi + int max; // [esp+10h] [ebp-1C4h] + int v24; // [esp+14h] [ebp-1C0h] + int v25[111]; // [esp+18h] [ebp-1BCh] + + v0 = 0; + max = 0; + if ( gbMaxPlayers != 1 ) + CheckClearDbg(); + if ( !setlevel ) + { + AddMonster(1, 0, 0, 0, 0); + AddMonster(1, 0, 0, 0, 0); + AddMonster(1, 0, 0, 0, 0); + AddMonster(1, 0, 0, 0, 0); + if ( !setlevel && currlevel == 16 ) + LoadDiabMonsts(); + } + v24 = trigflag[4]; + if ( currlevel == 15 ) + v24 = 1; + v1 = v24; + if ( v24 > 0 ) + { + v2 = trigs; + do + { + v3 = -2; + do + { + v4 = -2; + do + DoVision(v3 + v2->_tx, v4++ + v2->_ty, 15, 0, 0); + while ( v4 < 2 ); + ++v3; + } + while ( v3 < 2 ); + ++v2; + --v1; + } + while ( v1 ); + v0 = 0; + } + PlaceQuestMonsters(); + if ( !setlevel ) + { + PlaceUniques(); + v5 = 16; + do + { + v6 = 16; + do + { + if ( !SolidLoc(v5, v6) ) + ++v0; + ++v6; + } + while ( v6 < 96 ); + ++v5; + } + while ( v5 < 96 ); + v7 = v0 / 30; + if ( gbMaxPlayers != 1 ) + v7 += v7 >> 1; + v8 = nummonsters; + if ( nummonsters + v7 > 190 ) + v7 = 190 - nummonsters; + v9 = nummtypes; + v10 = nummonsters + v7; + v11 = 0; + totalmonsters = v10; + if ( nummtypes > 0 ) + { + v12 = &Monsters[0].mPlaceFlags; + do + { + if ( *v12 & 1 ) + { + v13 = max++; + v25[v13] = v11; + } + ++v11; + v12 += 328; + } + while ( v11 < v9 ); + } + if ( v8 < v10 ) + { + while ( 1 ) + { + _LOBYTE(v8) = 95; + v15 = v25[random(v8, max)]; + if ( currlevel == 1 ) + break; + _LOBYTE(v14) = 95; + if ( !random(v14, 2) ) + break; + _LOBYTE(v16) = 95; + if ( currlevel == 2 ) + { + v17 = random(v16, 2) + 1; +LABEL_40: + v18 = v17 + 1; + goto LABEL_41; + } + v18 = random(v16, 3) + 3; +LABEL_41: + PlaceGroup(v15, v18, 0, 0); + if ( nummonsters >= totalmonsters ) + goto LABEL_42; + } + v17 = 0; + goto LABEL_40; + } + } +LABEL_42: + v19 = v24; + if ( v24 > 0 ) + { + v20 = trigs; + do + { + v21 = -2; + do + { + v22 = -2; + do + DoUnVision(v21 + v20->_tx, v22++ + v20->_ty, 15); + while ( v22 < 2 ); + ++v21; + } + while ( v21 < 2 ); + ++v20; + --v19; + } + while ( v19 ); + } +} +// 5CF31D: using guessed type char setlevel; +// 658550: using guessed type int totalmonsters; +// 679660: using guessed type char gbMaxPlayers; +// 432637: using guessed type int var_1BC[111]; + +//----- (0043283D) -------------------------------------------------------- +void __cdecl PlaceUniques() +{ + int v0; // edi + int v1; // eax + UniqMonstStruct *v2; // ecx + int v3; // eax + int v4; // edx + CMonster *v5; // esi + int v6; // eax + int v7; // edx + + v0 = 0; + if ( UniqMonst[0].mtype != -1 ) + { + v1 = 0; + v2 = UniqMonst; + while ( UniqMonst[v1].mlevel != currlevel ) + { +LABEL_25: + v1 = ++v0; + v2 = &UniqMonst[v0]; + if ( v2->mtype == -1 ) + return; + } + v3 = 0; + v4 = 0; + if ( nummtypes > 0 ) + { + v5 = Monsters; + do + { + if ( v3 ) + break; + v6 = -((char)v2->mtype != (unsigned char)v5->mtype); + ++v5; + v3 = v6 + 1; + ++v4; + } + while ( v4 < nummtypes ); + } + v7 = v4 - 1; + if ( !v0 ) + { + if ( quests[2]._qactive ) + goto LABEL_23; + v3 = 0; + } + if ( v0 == 2 ) + { + if ( quests[3]._qactive ) + goto LABEL_23; + v3 = 0; + } + if ( v0 == 3 ) + { + if ( quests[7]._qactive ) + goto LABEL_23; + v3 = 0; + } + if ( v0 != 7 ) + { +LABEL_20: + if ( v0 == 8 && !quests[11]._qactive ) + v3 = 0; + goto LABEL_23; + } + if ( !quests[4]._qactive ) + { + v3 = 0; + goto LABEL_20; + } +LABEL_23: + if ( v3 ) + PlaceUniqueMonst(v0, v7, 8); + goto LABEL_25; + } +} + +//----- (0043290E) -------------------------------------------------------- +void __fastcall SetMapMonsters(char *pMap, int startx, int starty) +{ + char *v3; // esi + unsigned short v4; // cx + int v5; // edx + int v6; // edi + int v7; // ecx + char *v8; // edx + int i; // esi + int v10; // eax + int v11; // ecx + int v12; // [esp+Ch] [ebp-Ch] + int v13; // [esp+10h] [ebp-8h] + char *v14; // [esp+14h] [ebp-4h] + int startya; // [esp+20h] [ebp+8h] + + v12 = startx; + v3 = pMap; + AddMonsterType(109, 2); + AddMonster(1, 0, 0, 0, 0); + AddMonster(1, 0, 0, 0, 0); + AddMonster(1, 0, 0, 0, 0); + AddMonster(1, 0, 0, 0, 0); + if ( setlevel && setlvlnum == SL_VILEBETRAYER ) + { + AddMonsterType((char)UniqMonst[4].mtype, 4); + AddMonsterType((char)UniqMonst[5].mtype, 4); + AddMonsterType((char)UniqMonst[6].mtype, 4); + PlaceUniqueMonst(4, 0, 0); + PlaceUniqueMonst(5, 0, 0); + PlaceUniqueMonst(6, 0, 0); + } + v4 = *((_WORD *)v3 + 1); + v5 = *(unsigned short *)v3 * v4; + v6 = (unsigned short)(2 * *(_WORD *)v3); + v7 = (unsigned short)(2 * v4); + v8 = &v3[2 * v5 + 4 + 2 * v7 * v6]; + v14 = v8; + if ( v7 > 0 ) + { + v13 = v7; + startya = starty + 16; + do + { + for ( i = 0; i < v6; v14 += 2 ) + { + if ( *(_WORD *)v8 ) + { + v10 = AddMonsterType(*((char *)&monsterdata[111].mExp + *(unsigned short *)v8 + 3), 2); + v11 = nummonsters++; + PlaceMonster(v11, v10, i + v12 + 16, startya); + } + v8 = v14 + 2; + ++i; + } + ++startya; + --v13; + } + while ( v13 ); + } +} +// 5CCB10: using guessed type char setlvlnum; +// 5CF31D: using guessed type char setlevel; + +//----- (00432A4D) -------------------------------------------------------- +void __fastcall DeleteMonster(int i) +{ + int *v1; // ecx + int *v2; // eax + int v3; // edx + + --nummonsters; + v1 = &monstactive[i]; + v2 = &monstactive[nummonsters]; + v3 = *v2; + *v2 = *v1; + *v1 = v3; +} + +//----- (00432A71) -------------------------------------------------------- +int __fastcall AddMonster(int x, int y, int dir, int mtype, int InMap) +{ + int v5; // esi + + if ( nummonsters >= 200 ) + return -1; + v5 = monstactive[nummonsters++]; + if ( InMap ) + dMonster[0][y + 112 * x] = v5 + 1; + InitMonster(v5, dir, mtype, x, y); + return v5; +} + +//----- (00432AC1) -------------------------------------------------------- +void __fastcall NewMonsterAnim(int i, AnimStruct *anim, int md) +{ + MonsterStruct *v3; // eax + int v4; // esi + int v5; // edx + + v3 = &monster[i]; + v3->_mAFNum = anim->Frames[md + 1]; + v4 = anim->Rate; + v3->_mAnimCnt = 0; + v3->_mAnimLen = v4; + v3->_mAnimFrame = 1; + v5 = anim->Delay; + v3->_mFlags &= 0xFFFFFFF9; + v3->_mAnimDelay = v5; + v3->_mdir = md; +} + +//----- (00432AFF) -------------------------------------------------------- +int __fastcall M_Ranged(int i) +{ + char v1; // cl + + v1 = monster[i]._mAi; + return v1 == MG_SKELBOW || v1 == MG_GOATBOW || v1 == MG_SUCC || v1 == MG_LAZHELP; +} + +//----- (00432B26) -------------------------------------------------------- +int __fastcall M_Talker(int i) +{ + char v1; // cl + + v1 = monster[i]._mAi; + return v1 == MG_LAZURUS + || v1 == MG_WARLORD + || v1 == MG_GARBUD + || v1 == MG_ZHAR + || v1 == MG_SNOTSPIL + || v1 == MG_LACHDANAN + || v1 == MG_LAZHELP; +} + +//----- (00432B5C) -------------------------------------------------------- +void __fastcall M_Enemy(int i) +{ + MonsterStruct *v1; // esi + int *v2; // edi + int v3; // eax + int v4; // ecx + int v5; // ebx + int v6; // eax + int v7; // eax + int v8; // eax + int v9; // ecx + int v10; // edi + int v11; // edx + int v12; // eax + int v13; // ecx + int v14; // ebx + int v15; // eax + int v16; // eax + int v17; // [esp+Ch] [ebp-20h] + int v18; // [esp+10h] [ebp-1Ch] + BOOL v19; // [esp+14h] [ebp-18h] + BOOL v20; // [esp+14h] [ebp-18h] + signed int v21; // [esp+18h] [ebp-14h] + int j; // [esp+18h] [ebp-14h] + signed int v23; // [esp+1Ch] [ebp-10h] + signed int v24; // [esp+20h] [ebp-Ch] + BOOL v25; // [esp+24h] [ebp-8h] + char v26; // [esp+2Ah] [ebp-2h] + char v27; // [esp+2Bh] [ebp-1h] + + v24 = -1; + v18 = i; + v23 = -1; + v1 = &monster[i]; + v25 = 0; + if ( !(v1->_mFlags & 0x20) ) + { + v21 = 0; + v2 = &plr[0].plrlevel; + do + { + if ( !*((_BYTE *)v2 - 23) || currlevel != *v2 || *((_BYTE *)v2 + 267) || !v2[89] && gbMaxPlayers != 1 ) + goto LABEL_18; + v3 = v1->_my; + v4 = v2[2]; + v19 = dung_map[v2[1]][v4] == dung_map[v1->_mx][v3]; + v5 = abs(v3 - v4); + if ( abs(v1->_mx - v2[1]) <= v5 ) + v6 = v1->_my - v2[2]; + else + v6 = v1->_mx - v2[1]; + v7 = abs(v6); + if ( v19 ) + { + if ( !v25 ) + goto LABEL_17; + } + else if ( v25 ) + { + goto LABEL_16; + } + if ( v7 < v23 ) + goto LABEL_17; +LABEL_16: + if ( v24 == -1 ) + { +LABEL_17: + v1->_mFlags &= 0xFFFFFFEF; + v24 = v21; + v27 = *((_BYTE *)v2 + 12); + v26 = *((_BYTE *)v2 + 16); + v23 = v7; + v25 = v19; + } +LABEL_18: + ++v21; + v2 += 5430; + } + while ( (signed int)v2 < (signed int)&plr_msgs[0].player ); + } + v8 = 0; + for ( j = 0; j < nummonsters; v8 = j++ + 1 ) + { + v9 = monstactive[v8]; + v17 = monstactive[v8]; + if ( v9 == v18 ) + continue; + v10 = v9; + if ( monster[v9]._mx == 1 && !monster[v10]._my ) + continue; + if ( M_Talker(v9) && monster[v10].mtalkmsg ) + continue; + if ( !(v1->_mFlags & 0x20) + && ((abs(v11 - v1->_mx) >= 2 || abs(monster[v10]._my - v1->_my) >= 2) && !M_Ranged(v18) + || !(v1->_mFlags & 0x20) && !(monster[v10]._mFlags & 0x20)) ) + { + continue; + } + v12 = v1->_my; + v13 = monster[v10]._my; + v20 = dung_map[monster[v10]._mx][v13] == dung_map[v1->_mx][v12]; + v14 = abs(v12 - v13); + if ( abs(v1->_mx - monster[v10]._mx) <= v14 ) + v15 = v1->_my - monster[v10]._my; + else + v15 = v1->_mx - monster[v10]._mx; + v16 = abs(v15); + if ( v20 ) + { + if ( !v25 ) + goto LABEL_40; + } + else if ( v25 ) + { + goto LABEL_39; + } + if ( v16 < v23 ) + goto LABEL_40; +LABEL_39: + if ( v24 == -1 ) + { +LABEL_40: + v1->_mFlags |= 0x10u; + v24 = v17; + v27 = monster[v10]._mfutx; + v26 = monster[v10]._mfuty; + v23 = v16; + v25 = v20; + } + } + if ( v24 == -1 ) + { + BYTE1(v1->_mFlags) |= 4u; + } + else + { + BYTE1(v1->_mFlags) &= 0xFBu; + v1->_menemy = v24; + v1->_menemyx = v27; + v1->_menemyy = v26; + } +} +// 679660: using guessed type char gbMaxPlayers; + +//----- (00432E15) -------------------------------------------------------- +int __fastcall M_GetDir(int i) +{ + return GetDirection( + monster[i]._mx, + monster[i]._my, + (unsigned char)monster[i]._menemyx, + (unsigned char)monster[i]._menemyy); +} + +//----- (00432E3D) -------------------------------------------------------- +void __fastcall M_CheckEFlag(int i) +{ + int v1; // ecx + int v2; // edi + char *v3; // eax + signed int v4; // edx + + v1 = i; + v2 = 0; + v3 = (char *)dpiece_defs_map_2 + 32 * (112 * (monster[v1]._mx - 1) + monster[v1]._my + 1); + if ( v3 < (char *)dpiece_defs_map_2 ) + goto LABEL_9; + v4 = 2; + do + v2 |= *(unsigned short *)&v3[2 * v4++]; + while ( v4 < 10 ); + if ( v2 | dArch[monster[v1]._mx - 1][monster[v1]._my + 1] ) + monster[v1]._meflag = 1; + else +LABEL_9: + monster[v1]._meflag = 0; +} + +//----- (00432E9D) -------------------------------------------------------- +void __fastcall M_StartStand(int i, int md) +{ + int v2; // ebx + int v3; // edi + int v4; // esi + CMonster *v5; // eax + AnimStruct *v6; // edx + int v7; // eax + int v8; // ecx + + v2 = md; + v3 = i; + ClearMVars(i); + v4 = v3; + v5 = monster[v3].MType; + v6 = &v5->Anims[1]; + if ( v5->mtype != MON_GOLEM ) + v6 = v5->Anims; + NewMonsterAnim(v3, v6, v2); + monster[v4]._mdir = v2; + monster[v4]._mVar1 = monster[v4]._mmode; + monster[v4]._mVar2 = 0; + monster[v4]._mmode = 0; + v7 = monster[v4]._mx; + monster[v4]._mxoff = 0; + monster[v4]._myoff = 0; + v8 = monster[v4]._my; + monster[v4]._mfuty = v8; + monster[v4]._moldy = v8; + monster[v4]._mfutx = v7; + monster[v4]._moldx = v7; + M_CheckEFlag(v3); + M_Enemy(v3); +} + +//----- (00432F29) -------------------------------------------------------- +void __fastcall M_StartDelay(int i, int len) +{ + int v2; // eax + + if ( len > 0 ) + { + v2 = i; + if ( monster[i]._mAi != MG_LAZURUS ) + { + monster[v2]._mVar2 = len; + monster[v2]._mmode = MM_DELAY; + } + } +} + +//----- (00432F4F) -------------------------------------------------------- +void __fastcall M_StartSpStand(int i, int md) +{ + int v2; // ebx + int v3; // esi + int v4; // edi + int v5; // eax + int v6; // ecx + + v2 = i; + v3 = i; + v4 = md; + NewMonsterAnim(i, &monster[i].MType->Anims[5], md); + v5 = monster[v3]._mx; + v6 = monster[v3]._my; + monster[v3]._mxoff = 0; + monster[v3]._myoff = 0; + monster[v3]._mdir = v4; + monster[v3]._mmode = MM_SPSTAND; + monster[v3]._mfutx = v5; + monster[v3]._mfuty = v6; + monster[v3]._moldx = v5; + monster[v3]._moldy = v6; + M_CheckEFlag(v2); +} + +//----- (00432FBC) -------------------------------------------------------- +void __fastcall M_StartWalk(int i, int xvel, int yvel, int xadd, int yadd, int EndDir) +{ + int v6; // ST18_4 + int v7; // esi + int v8; // eax + int v9; // ecx + CMonster *v10; // edx + + v6 = i; + v7 = i; + v8 = monster[i]._mx; + monster[v7]._moldx = v8; + v9 = monster[i]._my; + monster[v7]._mfuty = v9 + yadd; + monster[v7]._mxvel = xvel; + monster[v7]._myvel = yvel; + monster[v7]._mVar1 = xadd; + monster[v7]._mVar2 = yadd; + dMonster[0][v9 + yadd + 112 * (v8 + xadd)] = -1 - v6; + v10 = monster[v7].MType; + monster[v7]._moldy = v9; + monster[v7]._mmode = MM_WALK; + monster[v7]._mfutx = v8 + xadd; + monster[v7]._mVar3 = EndDir; + monster[v7]._mdir = EndDir; + NewMonsterAnim(v6, &v10->Anims[1], EndDir); + monster[v7]._mVar6 = 0; + monster[v7]._mVar7 = 0; + monster[v7]._mVar8 = 0; + M_CheckEFlag(v6); +} + +//----- (0043308F) -------------------------------------------------------- +void __fastcall M_StartWalk2(int i, int xvel, int yvel, int a4, int a5, int a6, int a7, int EndDir) +{ + int v8; // esi + int v9; // edx + int v10; // ecx + int v11; // eax + int v12; // eax + bool v13; // zf + CMonster *v14; // edx + int v15; // [esp+Ch] [ebp-8h] + int ia; // [esp+10h] [ebp-4h] + int EndDira; // [esp+28h] [ebp+14h] + + v15 = xvel; + ia = i; + v8 = i; + v9 = a6 + monster[i]._mx; + EndDira = monster[i]._mx; + v10 = monster[i]._my; + v11 = monster[v8]._my; + monster[v8]._mVar2 = v10; + dMonster[0][v10 + 112 * EndDira] = -1 - ia; + monster[v8]._mVar1 = EndDira; + monster[v8]._moldx = EndDira; + v12 = a7 + v11; + monster[v8]._moldy = v10; + v13 = monster[v8]._uniqtype == 0; + monster[v8]._mx = v9; + monster[v8]._my = v12; + monster[v8]._mfutx = v9; + monster[v8]._mfuty = v12; + dMonster[0][v12 + 112 * v9] = ia + 1; + if ( !v13 ) + ChangeLightXY((unsigned char)monster[v8].mlid, v9, v12); + v14 = monster[v8].MType; + monster[v8]._mxvel = v15; + monster[v8]._myvel = yvel; + monster[v8]._mxoff = a4; + monster[v8]._myoff = a5; + monster[v8]._mmode = MM_WALK2; + monster[v8]._mVar3 = EndDir; + monster[v8]._mdir = EndDir; + NewMonsterAnim(ia, &v14->Anims[1], EndDir); + monster[v8]._mVar8 = 0; + monster[v8]._mVar6 = 16 * a4; + monster[v8]._mVar7 = 16 * a5; + M_CheckEFlag(ia); +} + +//----- (004331AA) -------------------------------------------------------- +void __fastcall M_StartWalk3(int i, int xvel, int yvel, int a4, int a5, int a6, int a7, int a8, int a9, int EndDir) +{ + int v10; // esi + int v11; // ebx + int v12; // edi + int v13; // edi + int v14; // ebx + int v15; // ecx + CMonster *v16; // edx + int v17; // [esp+Ch] [ebp-8h] + int ia; // [esp+10h] [ebp-4h] + int a6a; // [esp+28h] [ebp+14h] + int a7a; // [esp+2Ch] [ebp+18h] + + ia = i; + v10 = i; + v11 = monster[i]._my; + v12 = monster[i]._mx; + v17 = xvel; + a6a = v12 + a6; + a7a = v11 + a7; + v13 = a8 + v12; + v14 = a9 + v11; + if ( monster[i]._uniqtype ) + ChangeLightXY((unsigned char)monster[v10].mlid, v13, v14); + v15 = monster[v10]._my + 112 * monster[v10]._mx; + monster[v10]._mVar4 = v13; + dMonster[0][v15] = -1 - ia; + monster[v10]._mVar5 = v14; + dMonster[0][a7a + 112 * a6a] = -1 - ia; + monster[v10]._moldx = monster[v10]._mx; + monster[v10]._moldy = monster[v10]._my; + monster[v10]._mfutx = a6a; + monster[v10]._mxvel = v17; + dFlags[v13][v14] |= 0x10u; + v16 = monster[v10].MType; + monster[v10]._myvel = yvel; + monster[v10]._mfuty = a7a; + monster[v10]._mVar1 = a6a; + monster[v10]._mVar2 = a7a; + monster[v10]._mxoff = a4; + monster[v10]._myoff = a5; + monster[v10]._mmode = MM_WALK3; + monster[v10]._mVar3 = EndDir; + monster[v10]._mdir = EndDir; + NewMonsterAnim(ia, &v16->Anims[1], EndDir); + monster[v10]._mVar8 = 0; + monster[v10]._mVar6 = 16 * a4; + monster[v10]._mVar7 = 16 * a5; + M_CheckEFlag(ia); +} + +//----- (004332F6) -------------------------------------------------------- +void __fastcall M_StartAttack(int i) +{ + int v1; // edi + int v2; // ebx + int v3; // esi + int v4; // ecx + int v5; // eax + + v1 = i; + v2 = M_GetDir(i); + v3 = v1; + NewMonsterAnim(v1, &monster[v1].MType->Anims[2], v2); + v4 = monster[v1]._my; + v5 = monster[v1]._mx; + monster[v3]._mxoff = 0; + monster[v3]._myoff = 0; + monster[v3]._mfuty = v4; + monster[v3]._moldy = v4; + monster[v3]._mmode = MM_ATTACK; + monster[v3]._mfutx = v5; + monster[v3]._moldx = v5; + monster[v3]._mdir = v2; + M_CheckEFlag(v1); +} + +//----- (00433367) -------------------------------------------------------- +void __fastcall M_StartRAttack(int i, int missile_type, int dam) +{ + int v3; // ebp + int v4; // edi + int v5; // ebx + int v6; // esi + int v7; // ecx + int v8; // eax + + v3 = missile_type; + v4 = i; + v5 = M_GetDir(i); + v6 = v4; + NewMonsterAnim(v4, &monster[v4].MType->Anims[2], v5); + v7 = monster[v4]._my; + monster[v6]._mxoff = 0; + monster[v6]._myoff = 0; + monster[v6]._mVar2 = dam; + v8 = monster[v4]._mx; + monster[v6]._mfuty = v7; + monster[v6]._moldy = v7; + monster[v6]._mmode = MM_RATTACK; + monster[v6]._mVar1 = v3; + monster[v6]._mfutx = v8; + monster[v6]._moldx = v8; + monster[v6]._mdir = v5; + M_CheckEFlag(v4); +} + +//----- (004333EF) -------------------------------------------------------- +void __fastcall M_StartRSpAttack(int i, int missile_type, int dam) +{ + int v3; // ebp + int v4; // edi + int v5; // ebx + int v6; // esi + int v7; // ecx + int v8; // eax + + v3 = missile_type; + v4 = i; + v5 = M_GetDir(i); + v6 = v4; + NewMonsterAnim(v4, &monster[v4].MType->Anims[5], v5); + monster[v6]._mmode = MM_RSPATTACK; + monster[v6]._mVar2 = 0; + monster[v6]._mVar3 = dam; + v7 = monster[v4]._my; + monster[v6]._mxoff = 0; + monster[v6]._myoff = 0; + v8 = monster[v4]._mx; + monster[v6]._mfuty = v7; + monster[v6]._moldy = v7; + monster[v6]._mVar1 = v3; + monster[v6]._mfutx = v8; + monster[v6]._moldx = v8; + monster[v6]._mdir = v5; + M_CheckEFlag(v4); +} + +//----- (00433480) -------------------------------------------------------- +void __fastcall M_StartSpAttack(int i) +{ + int v1; // edi + int v2; // ebx + int v3; // esi + int v4; // ecx + int v5; // eax + + v1 = i; + v2 = M_GetDir(i); + v3 = v1; + NewMonsterAnim(v1, &monster[v1].MType->Anims[5], v2); + v4 = monster[v1]._my; + v5 = monster[v1]._mx; + monster[v3]._mxoff = 0; + monster[v3]._myoff = 0; + monster[v3]._mfuty = v4; + monster[v3]._moldy = v4; + monster[v3]._mmode = MM_SATTACK; + monster[v3]._mfutx = v5; + monster[v3]._moldx = v5; + monster[v3]._mdir = v2; + M_CheckEFlag(v1); +} + +//----- (004334F4) -------------------------------------------------------- +void __fastcall M_StartEat(int i) +{ + int v1; // edi + int v2; // esi + int v3; // ecx + int v4; // eax + + v1 = i; + v2 = i; + NewMonsterAnim(i, &monster[i].MType->Anims[5], monster[i]._mdir); + v3 = monster[v2]._my; + v4 = monster[v2]._mx; + monster[v2]._mxoff = 0; + monster[v2]._myoff = 0; + monster[v2]._mfuty = v3; + monster[v2]._moldy = v3; + monster[v2]._mmode = MM_SATTACK; + monster[v2]._mfutx = v4; + monster[v2]._moldx = v4; + M_CheckEFlag(v1); +} + +//----- (0043355C) -------------------------------------------------------- +void __fastcall M_ClearSquares(int i) +{ + int v1; // edx + int v2; // eax + int v3; // esi + int v4; // ecx + int v5; // edi + int v6; // [esp+8h] [ebp-Ch] + _DWORD *v7; // [esp+Ch] [ebp-8h] + int v8; // [esp+10h] [ebp-4h] + + v1 = monster[i]._moldx; + v2 = monster[i]._moldy; + v3 = -1 - i; + v6 = i + 1; + v4 = v2 - 1; + v5 = v2 + 1; + if ( (unsigned char)(__OFSUB__(v2 - 1, v2 + 1) ^ 1) | (v2 - 1 == v2 + 1) ) + { + do + { + if ( v4 >= 0 && v4 < 112 ) + { + v8 = v1 - 1; + if ( (unsigned char)(__OFSUB__(v1 - 1, v1 + 1) ^ 1) | (v1 - 1 == v1 + 1) ) + { + v7 = (_DWORD *)((char *)dMonster + 4 * (v4 + 112 * (v1 - 1))); + do + { + if ( v8 >= 0 && v8 < 112 && (*v7 == v3 || *v7 == v6) ) + *v7 = 0; + ++v8; + v7 += 112; + } + while ( v8 <= v1 + 1 ); + } + } + ++v4; + v5 = v2 + 1; + } + while ( v4 <= v2 + 1 ); + } + if ( v1 + 1 < 112 ) + dFlags[v1 + 1][v2] &= 0xEFu; + if ( v5 < 112 ) + dFlags[v1][v2 + 1] &= 0xEFu; +} + +//----- (0043361B) -------------------------------------------------------- +void __fastcall M_GetKnockback(int i) +{ + int v1; // edi + int v2; // esi + int v3; // ebx + int v4; // eax + int v5; // ST00_4 + AnimStruct *v6; // edx + int v7; // eax + int v8; // ecx + int v9; // eax + + v1 = i; + v2 = i; + v3 = ((unsigned char)monster[i]._mdir - 4) & 7; + _LOBYTE(v4) = DirOK(i, v3); + if ( v4 ) + { + M_ClearSquares(v1); + v5 = monster[v2]._mdir; + v6 = &monster[v2].MType->Anims[3]; + v7 = offset_y[v3]; + monster[v2]._moldx += offset_x[v3]; + monster[v2]._moldy += v7; + NewMonsterAnim(v1, v6, v5); + v8 = monster[v2]._moldy; + v9 = monster[v2]._moldx; + monster[v2]._mxoff = 0; + monster[v2]._myoff = 0; + monster[v2]._my = v8; + monster[v2]._mfuty = v8; + monster[v2]._mmode = MM_GOTHIT; + monster[v2]._mx = v9; + monster[v2]._mfutx = v9; + M_CheckEFlag(v1); + M_ClearSquares(v1); + dMonster[0][monster[v2]._my + 112 * monster[v2]._mx] = v1 + 1; + } +} + +//----- (004336E5) -------------------------------------------------------- +void __fastcall M_StartHit(int i, int pnum, int dam) +{ + int v3; // ebx + int v4; // edi + int v5; // esi + unsigned char v6; // al + char v7; // al + unsigned char v8; // al + int v9; // ecx + int v10; // eax + + v3 = pnum; + v4 = i; + if ( pnum >= 0 ) + monster[i].mWhoHit |= 1 << pnum; + if ( pnum == myplr ) + { + delta_monster_hp(i, monster[i]._mhitpoints, currlevel); + NetSendCmdParam2(0, CMD_MONSTDAMAGE, v4, dam); + } + PlayEffect(v4, 1); + v5 = v4; + v6 = monster[v4].MType->mtype; + if ( v6 >= MON_SNEAKA && v6 <= MON_SNEAKD || dam >> 6 >= SLOBYTE(monster[v5].mLevel) + 3 ) + { + if ( v3 >= 0 ) + { + monster[v5]._mFlags &= 0xFFFFFFEF; + monster[v5]._menemy = v3; + v7 = plr[v3]._py; + monster[v5]._menemyx = plr[v3]._px; + monster[v5]._menemyy = v7; + monster[v5]._mdir = M_GetDir(v4); + } + v8 = monster[v5].MType->mtype; + if ( v8 == MON_BATB ) + { + M_Teleport(v4); + } + else if ( v8 >= MON_SCAVA && v8 <= MON_SCAVD ) + { + _LOBYTE(monster[v5]._mgoal) = 1; + } + if ( monster[v5]._mmode != MM_STONE ) + { + NewMonsterAnim(v4, &monster[v5].MType->Anims[3], monster[v5]._mdir); + v9 = monster[v5]._moldy; + v10 = monster[v5]._moldx; + monster[v5]._mxoff = 0; + monster[v5]._myoff = 0; + monster[v5]._my = v9; + monster[v5]._mfuty = v9; + monster[v5]._mmode = MM_GOTHIT; + monster[v5]._mx = v10; + monster[v5]._mfutx = v10; + M_CheckEFlag(v4); + M_ClearSquares(v4); + dMonster[0][monster[v5]._my + 112 * monster[v5]._mx] = v4 + 1; + } + } +} + +//----- (0043385A) -------------------------------------------------------- +void __fastcall M_DiabloDeath(int i, unsigned char sendmsg) +{ + int v2; // esi + int v3; // edi + int v4; // eax + int v5; // ebx + int v6; // esi + int v7; // ecx + int v8; // eax + int v9; // esi + int v10; // eax + double v11; // st7 + int v12; // eax + int v13; // ecx + int v14; // esi + int v15; // [esp+8h] [ebp-8h] + int j; // [esp+Ch] [ebp-4h] + int v17; // [esp+Ch] [ebp-4h] + + v15 = i; + v2 = sendmsg; + v3 = i; + PlaySFX(USFX_DIABLOD); + quests[5]._qactive = 3; + if ( v2 ) + NetSendCmdQuest(1u, 5u); + gbProcessPlayers = 0; + _LOBYTE(sgbSaveSoundOn) = gbSoundOn; + v4 = 0; + for ( j = 0; j < nummonsters; ++j ) + { + v5 = monstactive[v4]; + if ( v5 != v15 && _LOBYTE(monster[v3]._msquelch) ) + { + v6 = v5; + NewMonsterAnim(monstactive[v4], &monster[v5].MType->Anims[4], monster[v5]._mdir); + v7 = monster[v5]._moldy; + monster[v6]._mxoff = 0; + monster[v6]._myoff = 0; + monster[v6]._mVar1 = 0; + v8 = monster[v5]._moldx; + monster[v6]._my = v7; + monster[v6]._mfuty = v7; + monster[v6]._mmode = MM_DEATH; + monster[v6]._mx = v8; + monster[v6]._mfutx = v8; + M_CheckEFlag(v5); + M_ClearSquares(v5); + dMonster[0][monster[v6]._my + 112 * monster[v6]._mx] = v5 + 1; + } + v4 = j + 1; + } + AddLight(monster[v3]._mx, monster[v3]._my, 8); + DoVision(monster[v3]._mx, monster[v3]._my, 8, 0, 1); + v9 = abs(ViewY - monster[v3]._my); + if ( abs(ViewX - monster[v3]._mx) <= v9 ) + v10 = ViewY - monster[v3]._my; + else + v10 = ViewX - monster[v3]._mx; + v17 = abs(v10); + if ( v17 > 20 ) + v17 = 20; + v11 = (double)v17; + v12 = ViewX << 16; + v13 = monster[v3]._mx << 16; + monster[v3]._mVar3 = ViewX << 16; + v14 = ViewY << 16; + monster[v3]._mVar4 = ViewY << 16; + monster[v3]._mVar5 = (signed __int64)((double)(v12 - v13) / v11); + monster[v3]._mVar6 = (signed __int64)((double)(v14 - (monster[v3]._my << 16)) / v11); +} +// 4A22D5: using guessed type char gbSoundOn; +// 5256A0: using guessed type int gbProcessPlayers; +// 64D32C: using guessed type int sgbSaveSoundOn; + +//----- (00433A4C) -------------------------------------------------------- +void __fastcall M2MStartHit(int mid, int i, int dam) +{ + int v3; // edi + int v4; // ebx + int v5; // esi + CMonster *v6; // eax + char v7; // al + CMonster *v8; // eax + int v9; // ecx + int v10; // eax + int v11; // [esp+Ch] [ebp-4h] + + v3 = mid; + v4 = i; + v11 = i; + if ( (unsigned int)mid >= 0xC8 ) + TermMsg("Invalid monster %d getting hit by monster", mid); + v5 = v3; + if ( !monster[v3].MType ) + TermMsg("Monster %d \"%s\" getting hit by monster: MType NULL", v3, monster[v5].mName); + if ( v4 >= 0 ) + monster[v4].mWhoHit |= 1 << v4; + delta_monster_hp(v3, monster[v5]._mhitpoints, currlevel); + NetSendCmdParam2(0, CMD_MONSTDAMAGE, v3, dam); + PlayEffect(v3, 1); + v6 = monster[v5].MType; + if ( v6->mtype >= MON_SNEAKA && v6->mtype <= MON_SNEAKD || dam >> 6 >= SLOBYTE(monster[v5].mLevel) + 3 ) + { + if ( v11 >= 0 ) + monster[v5]._mdir = ((unsigned char)monster[v11]._mdir - 4) & 7; + v7 = v6->mtype; + if ( v7 == 39 ) + { + M_Teleport(v3); + } + else if ( v7 >= MON_SCAVA && v7 <= MON_SCAVD ) + { + _LOBYTE(monster[v5]._mgoal) = 1; + } + if ( monster[v5]._mmode != MM_STONE ) + { + v8 = monster[v5].MType; + if ( v8->mtype != MON_GOLEM ) + { + NewMonsterAnim(v3, &v8->Anims[3], monster[v5]._mdir); + monster[v5]._mmode = MM_GOTHIT; + } + v9 = monster[v5]._moldy; + v10 = monster[v5]._moldx; + monster[v5]._mxoff = 0; + monster[v5]._myoff = 0; + monster[v5]._my = v9; + monster[v5]._mfuty = v9; + monster[v5]._mx = v10; + monster[v5]._mfutx = v10; + M_CheckEFlag(v3); + M_ClearSquares(v3); + dMonster[0][monster[v5]._my + 112 * monster[v5]._mx] = v3 + 1; + } + } +} + +//----- (00433BCC) -------------------------------------------------------- +void __fastcall MonstStartKill(int i, int pnum, unsigned char sendmsg) +{ + signed int v3; // edi + int v4; // ebx + signed int v5; // esi + int v6; // ecx + int v7; // eax + int v8; // eax + int v9; // eax + AnimStruct *v10; // edx + int v11; // ecx + int v12; // eax + unsigned char v13; // al + + v3 = i; + v4 = pnum; + if ( (unsigned int)i >= 0xC8 ) + TermMsg("MonstStartKill: Invalid monster %d", i); + v5 = v3; + if ( !monster[v3].MType ) + TermMsg("MonstStartKill: Monster %d \"%s\" MType NULL", v3, monster[v5].mName); + if ( v4 >= 0 ) + monster[v5].mWhoHit |= 1 << v4; + if ( v4 < 4 && v3 > 4 ) + AddPlrMonstExper(SLOBYTE(monster[v5].mLevel), (unsigned short)monster[v5].mExp, monster[v5].mWhoHit); + v6 = monster[v5]._mRndSeed; + v7 = monster[v5].MType->mtype; + monster[v5]._mhitpoints = 0; + ++monstkills[v7]; + SetRndSeed(v6); + _LOBYTE(v8) = QuestStatus(2); + if ( v8 && monster[v5].mName == UniqMonst[0].mName ) + { + CreateTypeItem(monster[v5]._mx + 1, monster[v5]._my + 1, 1u, 4, 0, 1, 0); + } + else if ( v3 > 3 ) + { + SpawnItem(v3, monster[v5]._mx, monster[v5]._my, sendmsg); + } + if ( monster[v5].MType->mtype == MON_DIABLO ) + M_DiabloDeath(v3, 1u); + else + PlayEffect(v3, 2); + if ( v4 < 0 ) + v9 = monster[v5]._mdir; + else + v9 = M_GetDir(v3); + v10 = &monster[v5].MType->Anims[4]; + monster[v5]._mdir = v9; + NewMonsterAnim(v3, v10, v9); + v11 = monster[v5]._moldy; + v12 = monster[v5]._moldx; + monster[v5]._my = v11; + monster[v5]._mfuty = v11; + monster[v5]._mmode = MM_DEATH; + monster[v5]._mxoff = 0; + monster[v5]._myoff = 0; + monster[v5]._mVar1 = 0; + monster[v5]._mx = v12; + monster[v5]._mfutx = v12; + M_CheckEFlag(v3); + M_ClearSquares(v3); + dMonster[0][monster[v5]._my + 112 * monster[v5]._mx] = v3 + 1; + CheckQuestKill(v3, sendmsg); + M_FallenFear(monster[v5]._mx, monster[v5]._my); + v13 = monster[v5].MType->mtype; + if ( v13 >= MON_ACIDA && v13 <= MON_ACIDD ) + AddMissile(monster[v5]._mx, monster[v5]._my, 0, 0, 0, 59, 1, v3, (unsigned char)monster[v5]._mint + 1, 0); +} + +//----- (00433DC2) -------------------------------------------------------- +void __fastcall M2MStartKill(int i, int mid) +{ + signed int v2; // ebx + signed int v3; // edi + signed int v4; // esi + int v5; // ecx + int v6; // eax + CMonster *v7; // ecx + int v8; // eax + int v9; // ecx + int v10; // eax + unsigned char v11; // al + + v2 = i; + v3 = mid; + if ( (unsigned int)i >= 0xC8 ) + { + TermMsg("M2MStartKill: Invalid monster (attacker) %d", i); + TermMsg("M2MStartKill: Invalid monster (killed) %d", v3); + } + if ( !monster[v2].MType ) + TermMsg("M2MStartKill: Monster %d \"%s\" MType NULL", v3, monster[v3].mName); + v4 = v3; + delta_kill_monster(v3, monster[v3]._mx, monster[v3]._my, currlevel); + NetSendCmdLocParam1(0, CMD_MONSTDEATH, monster[v4]._mx, monster[v4]._my, v3); + monster[v4].mWhoHit |= 1 << v2; + if ( v2 < 4 ) + AddPlrMonstExper(SLOBYTE(monster[v4].mLevel), (unsigned short)monster[v4].mExp, monster[v3].mWhoHit); + v5 = monster[v4]._mRndSeed; + v6 = monster[v4].MType->mtype; + monster[v4]._mhitpoints = 0; + ++monstkills[v6]; + SetRndSeed(v5); + if ( v3 >= 4 ) + SpawnItem(v3, monster[v4]._mx, monster[v4]._my, 1u); + if ( monster[v4].MType->mtype == MON_DIABLO ) + M_DiabloDeath(v3, 1u); + else + PlayEffect(v2, 2); + PlayEffect(v3, 2); + v7 = monster[v4].MType; + v8 = ((unsigned char)monster[v2]._mdir - 4) & 7; + if ( v7->mtype == MON_GOLEM ) + v8 = 0; + monster[v4]._mdir = v8; + NewMonsterAnim(v3, &v7->Anims[4], v8); + v9 = monster[v4]._moldy; + v10 = monster[v4]._moldx; + monster[v4]._my = v9; + monster[v4]._mfuty = v9; + monster[v4]._mmode = MM_DEATH; + monster[v4]._mxoff = 0; + monster[v4]._myoff = 0; + monster[v4]._mx = v10; + monster[v4]._mfutx = v10; + M_CheckEFlag(v3); + M_ClearSquares(v3); + dMonster[0][monster[v4]._my + 112 * monster[v4]._mx] = v3 + 1; + CheckQuestKill(v3, 1u); + M_FallenFear(monster[v4]._mx, monster[v4]._my); + v11 = monster[v4].MType->mtype; + if ( v11 >= MON_ACIDA && v11 <= MON_ACIDD ) + AddMissile(monster[v4]._mx, monster[v4]._my, 0, 0, 0, 59, 1, v3, (unsigned char)monster[v4]._mint + 1, 0); +} + +//----- (00433FC7) -------------------------------------------------------- +void __fastcall M_StartKill(int i, int pnum) +{ + int v2; // edi + int v3; // ebx + int v4; // esi + int v5; // eax + + v2 = i; + v3 = pnum; + if ( (unsigned int)i >= 0xC8 ) + TermMsg("M_StartKill: Invalid monster %d", i); + if ( myplr == v3 ) + { + v4 = v2; + delta_kill_monster(v2, monster[v2]._mx, monster[v2]._my, currlevel); + if ( v2 == v3 ) + { + _LOWORD(v5) = currlevel; + NetSendCmdLocParam1(0, CMD_KILLGOLEM, monster[v4]._mx, monster[v4]._my, v5); + } + else + { + NetSendCmdLocParam1(0, CMD_MONSTDEATH, monster[v4]._mx, monster[v4]._my, v2); + } + } + MonstStartKill(v2, v3, 1u); +} + +//----- (00434045) -------------------------------------------------------- +void __fastcall M_SyncStartKill(int i, int x, int y, int pnum) +{ + int v4; // esi + int v5; // ebx + int v6; // esi + int arglist; // [esp+Ch] [ebp-4h] + + v4 = i; + v5 = x; + arglist = i; + if ( (unsigned int)i >= 0xC8 ) + TermMsg("M_SyncStartKill: Invalid monster %d", i); + v6 = v4; + if ( monster[v6]._mhitpoints && monster[v6]._mmode != MM_DEATH ) + { + if ( !dMonster[0][y + 112 * v5] ) + { + M_ClearSquares(arglist); + monster[v6]._mx = v5; + monster[v6]._my = y; + monster[v6]._moldx = v5; + monster[v6]._moldy = y; + } + if ( monster[v6]._mmode == MM_STONE ) + { + MonstStartKill(arglist, pnum, 0); + monster[v6]._mmode = MM_STONE; + } + else + { + MonstStartKill(arglist, pnum, 0); + } + } +} + +//----- (004340E0) -------------------------------------------------------- +void __fastcall M_StartFadein(int i, int md, unsigned char backwards) +{ + int v3; // esi + int v4; // ebx + int v5; // esi + int v6; // ecx + int v7; // eax + int *v8; // eax + int arglist; // [esp+Ch] [ebp-4h] + + v3 = i; + v4 = md; + arglist = i; + if ( (unsigned int)i >= 0xC8 ) + TermMsg("M_StartFadein: Invalid monster %d", i); + v5 = v3; + if ( !monster[v5].MType ) + TermMsg("M_StartFadein: Monster %d \"%s\" MType NULL", arglist, monster[v5].mName); + NewMonsterAnim(arglist, &monster[v5].MType->Anims[5], v4); + v6 = monster[v5]._my; + v7 = monster[v5]._mx; + monster[v5]._mfuty = v6; + monster[v5]._moldy = v6; + monster[v5]._mmode = MM_FADEIN; + monster[v5]._mxoff = 0; + monster[v5]._myoff = 0; + monster[v5]._mfutx = v7; + monster[v5]._moldx = v7; + M_CheckEFlag(arglist); + v8 = &monster[v5]._mFlags; + monster[v5]._mdir = v4; + *v8 &= 0xFFFFFFFE; + if ( backwards ) + { + *v8 = monster[v5]._mFlags | 2; + monster[v5]._mAnimFrame = monster[v5]._mAnimLen; + } +} + +//----- (004341AD) -------------------------------------------------------- +void __fastcall M_StartFadeout(int i, int md, unsigned char backwards) +{ + int v3; // ebx + int v4; // esi + CMonster **v5; // edi + int v6; // ecx + int v7; // eax + int v8; // eax + int mda; // [esp+Ch] [ebp-4h] + + v3 = i; + mda = md; + if ( (unsigned int)i >= 0xC8 ) + TermMsg("M_StartFadeout: Invalid monster %d", i); + v4 = v3; + v5 = &monster[v3].MType; + if ( !*v5 ) + TermMsg("M_StartFadeout: Monster %d \"%s\" MType NULL", v3, monster[v4].mName); + NewMonsterAnim(v3, &(*v5)->Anims[5], mda); + v6 = monster[v4]._my; + v7 = monster[v4]._mx; + monster[v4]._mfuty = v6; + monster[v4]._moldy = v6; + monster[v4]._mmode = MM_FADEOUT; + monster[v4]._mxoff = 0; + monster[v4]._myoff = 0; + monster[v4]._mfutx = v7; + monster[v4]._moldx = v7; + M_CheckEFlag(v3); + monster[v4]._mdir = mda; + if ( backwards ) + { + v8 = monster[v4]._mAnimLen; + monster[v4]._mFlags |= 2u; + monster[v4]._mAnimFrame = v8; + } +} + +//----- (00434272) -------------------------------------------------------- +void __fastcall M_StartHeal(int i) +{ + int v1; // edi + int v2; // esi + CMonster *v3; // eax + int v4; // ecx + int v5; // eax + + v1 = i; + if ( (unsigned int)i >= 0xC8 ) + TermMsg("M_StartHeal: Invalid monster %d", i); + v2 = v1; + if ( !monster[v1].MType ) + TermMsg("M_StartHeal: Monster %d \"%s\" MType NULL", v1, monster[v2].mName); + v3 = monster[v2].MType; + v4 = v3->Anims[5].Frames[monster[v2]._mdir + 1]; + monster[v2]._mAFNum = v4; + v5 = v3->Anims[5].Rate; + monster[v2]._mFlags |= 2u; + _LOBYTE(v4) = 97; + monster[v2]._mAnimFrame = v5; + monster[v2]._mmode = MM_HEAL; + monster[v2]._mVar1 = monster[v2]._mmaxhp / (16 * (random(v4, 5) + 4)); +} + +//----- (0043430A) -------------------------------------------------------- +void __fastcall M_ChangeLightOffset(int monst) +{ + int v1; // esi + int v2; // ecx + int v3; // eax + int v4; // esi + int v5; // edx + int v6; // eax + signed int v7; // esi + int v8; // edx + signed int v9; // esi + + v1 = monst; + if ( (unsigned int)monst >= 0xC8 ) + TermMsg("M_ChangeLightOffset: Invalid monster %d", monst); + v2 = v1; + v3 = monster[v1]._myoff; + v4 = monster[v1]._mxoff; + v3 *= 2; + v5 = v4 + v3; + v6 = v3 - v4; + if ( v5 >= 0 ) + { + v7 = 1; + } + else + { + v7 = -1; + v5 = -v5; + } + v8 = v7 * (v5 >> 3); + if ( v6 >= 0 ) + { + v9 = 1; + } + else + { + v9 = -1; + v6 = -v6; + } + ChangeLightOff((unsigned char)monster[v2].mlid, v8, v9 * (v6 >> 3)); +} + +//----- (00434374) -------------------------------------------------------- +int __fastcall M_DoStand(int i) +{ + int v1; // edi + int v2; // esi + CMonster *v3; // eax + int v4; // ecx + int v5; // eax + + v1 = i; + if ( (unsigned int)i >= 0xC8 ) + TermMsg("M_DoStand: Invalid monster %d", i); + v2 = v1; + if ( !monster[v1].MType ) + TermMsg("M_DoStand: Monster %d \"%s\" MType NULL", v1, monster[v2].mName); + v3 = monster[v2].MType; + v4 = monster[v2]._mdir; + if ( v3->mtype == MON_GOLEM ) + v5 = v3->Anims[1].Frames[v4 + 1]; + else + v5 = v3->Anims[0].Frames[v4 + 1]; + monster[v2]._mAFNum = v5; + if ( monster[v2]._mAnimFrame == monster[v2]._mAnimLen ) + M_Enemy(v1); + ++monster[v2]._mVar2; + return 0; +} + +//----- (004343F3) -------------------------------------------------------- +int __fastcall M_DoWalk(int i) +{ + int v1; // ebx + int v2; // esi + int v3; // edi + int v4; // eax + int v5; // edi + int v6; // ecx + int v7; // edx + int v8; // eax + bool v9; // zf + int v10; // ecx + int v11; // edx + int v12; // eax + int v13; // ecx + + v1 = i; + if ( (unsigned int)i >= 0xC8 ) + TermMsg("M_DoWalk: Invalid monster %d", i); + v2 = v1; + v3 = 0; + if ( !monster[v1].MType ) + TermMsg("M_DoWalk: Monster %d \"%s\" MType NULL", v1, monster[v2].mName); + v4 = monster[v2]._mVar8; + if ( v4 == monster[v2].MType->Anims[1].Rate ) + { + v5 = monster[v2]._my; + v6 = monster[v2]._mx; + dMonster[0][v5 + 112 * monster[v2]._mx] = 0; + v7 = v6 + monster[v2]._mVar1; + monster[v2]._mx = v7; + v8 = v5 + monster[v2]._mVar2; + v9 = monster[v2]._uniqtype == 0; + monster[v2]._my = v8; + dMonster[0][v8 + 112 * v7] = v1 + 1; + if ( !v9 ) + ChangeLightXY((unsigned char)monster[v2].mlid, v7, v8); + M_StartStand(v1, monster[v2]._mdir); + v3 = 1; + } + else if ( !monster[v2]._mAnimCnt ) + { + v10 = monster[v2]._mxvel; + v11 = monster[v2]._myvel; + monster[v2]._mVar8 = v4 + 1; + monster[v2]._mVar6 += v10; + v12 = monster[v2]._mVar6 >> 4; + monster[v2]._mVar7 += v11; + v13 = monster[v2]._mVar7 >> 4; + monster[v2]._mxoff = v12; + monster[v2]._myoff = v13; + } + if ( monster[v2]._uniqtype ) + M_ChangeLightOffset(v1); + return v3; +} + +//----- (00434509) -------------------------------------------------------- +int __fastcall M_DoWalk2(int i) +{ + int v1; // ebp + int v2; // esi + int v3; // eax + bool v4; // zf + int v5; // edi + int v6; // ecx + int v7; // edx + int v8; // eax + int v9; // ecx + + v1 = i; + if ( (unsigned int)i >= 0xC8 ) + TermMsg("M_DoWalk2: Invalid monster %d", i); + v2 = v1; + if ( !monster[v1].MType ) + TermMsg("M_DoWalk2: Monster %d \"%s\" MType NULL", v1, monster[v2].mName); + v3 = monster[v2]._mVar8; + if ( v3 == monster[v2].MType->Anims[1].Rate ) + { + v4 = monster[v2]._uniqtype == 0; + dMonster[0][monster[v2]._mVar2 + 112 * monster[v2]._mVar1] = 0; + if ( !v4 ) + ChangeLightXY((unsigned char)monster[v2].mlid, monster[v2]._mx, monster[v2]._my); + M_StartStand(v1, monster[v2]._mdir); + v5 = 1; + } + else + { + if ( !monster[v2]._mAnimCnt ) + { + v6 = monster[v2]._mxvel; + v7 = monster[v2]._myvel; + monster[v2]._mVar8 = v3 + 1; + monster[v2]._mVar6 += v6; + v8 = monster[v2]._mVar6 >> 4; + monster[v2]._mVar7 += v7; + v9 = monster[v2]._mVar7 >> 4; + monster[v2]._mxoff = v8; + monster[v2]._myoff = v9; + } + v5 = 0; + } + if ( monster[v2]._uniqtype ) + M_ChangeLightOffset(v1); + return v5; +} + +//----- (004345FC) -------------------------------------------------------- +int __fastcall M_DoWalk3(int i) +{ + int v1; // ebp + int v2; // esi + int v3; // eax + int v4; // edi + int v5; // edx + int v6; // ecx + int v7; // edx + char *v8; // eax + bool v9; // zf + int v10; // edi + int v11; // ecx + int v12; // edx + int v13; // eax + int v14; // ecx + + v1 = i; + if ( (unsigned int)i >= 0xC8 ) + TermMsg("M_DoWalk3: Invalid monster %d", i); + v2 = v1; + if ( !monster[v1].MType ) + TermMsg("M_DoWalk3: Monster %d \"%s\" MType NULL", v1, monster[v2].mName); + v3 = monster[v2]._mVar8; + if ( v3 == monster[v2].MType->Anims[1].Rate ) + { + v4 = monster[v2]._mVar2; + v5 = monster[v2]._my + 112 * monster[v2]._mx; + monster[v2]._my = v4; + v6 = monster[v2]._mVar5; + dMonster[0][v5] = 0; + v7 = monster[v2]._mVar1; + monster[v2]._mx = v7; + v8 = &dFlags[monster[v2]._mVar4][v6]; + *v8 &= 0xEFu; + v9 = monster[v2]._uniqtype == 0; + dMonster[0][v4 + 112 * v7] = v1 + 1; + if ( !v9 ) + ChangeLightXY((unsigned char)monster[v2].mlid, v7, v4); + M_StartStand(v1, monster[v2]._mdir); + v10 = 1; + } + else + { + if ( !monster[v2]._mAnimCnt ) + { + v11 = monster[v2]._mxvel; + v12 = monster[v2]._myvel; + monster[v2]._mVar8 = v3 + 1; + monster[v2]._mVar6 += v11; + v13 = monster[v2]._mVar6 >> 4; + monster[v2]._mVar7 += v12; + v14 = monster[v2]._mVar7 >> 4; + monster[v2]._mxoff = v13; + monster[v2]._myoff = v14; + } + v10 = 0; + } + if ( monster[v2]._uniqtype ) + M_ChangeLightOffset(v1); + return v10; +} + +//----- (00434722) -------------------------------------------------------- +void __fastcall M_TryM2MHit(int i, int mid, int hper, int mind, int maxd) +{ + int v5; // edi + int v6; // ST08_4 + int v7; // esi + int v8; // ebx + int v9; // eax + int v10; // ecx + int v11; // eax + unsigned char ret; // [esp+Ch] [ebp-Ch] + char v13[4]; // [esp+10h] [ebp-8h] + char arglist[4]; // [esp+14h] [ebp-4h] + + v5 = mid; + *(_DWORD *)arglist = mid; + *(_DWORD *)v13 = i; + if ( (unsigned int)mid >= 0xC8 ) + { + TermMsg("M_TryM2MHit: Invalid monster %d", mid); + i = v6; + } + v7 = v5; + if ( !monster[v5].MType ) + TermMsg("M_TryM2MHit: Monster %d \"%s\" MType NULL", v5, monster[v7].mName); + if ( (signed int)(monster[v7]._mhitpoints & 0xFFFFFFC0) > 0 + && (monster[v7].MType->mtype != MON_SNEAKD || _LOBYTE(monster[v7]._mgoal) != 2) ) + { + _LOBYTE(i) = 4; + v8 = random(i, 100); + if ( monster[v7]._mmode == MM_STONE ) + v8 = 0; + _LOBYTE(v9) = CheckMonsterHit(*(int *)arglist, &ret); + if ( !v9 && v8 < hper ) + { + _LOBYTE(v10) = 5; + v11 = (mind + random(v10, maxd - mind + 1)) << 6; + monster[v7]._mhitpoints -= v11; + if ( (signed int)(monster[v7]._mhitpoints & 0xFFFFFFC0) > 0 ) + { + if ( monster[v7]._mmode == MM_STONE ) + { + M2MStartHit(*(int *)arglist, *(int *)v13, v11); + goto LABEL_15; + } + M2MStartHit(*(int *)arglist, *(int *)v13, v11); + } + else + { + if ( monster[v7]._mmode == MM_STONE ) + { + M2MStartKill(*(int *)v13, *(int *)arglist); +LABEL_15: + monster[v7]._mmode = MM_STONE; + return; + } + M2MStartKill(*(int *)v13, *(int *)arglist); + } + } + } +} + +//----- (0043482C) -------------------------------------------------------- +void __fastcall M_TryH2HHit(int i, int pnum, int Hit, int MinDam, int MaxDam) +{ + int v5; // esi + int v6; // ebx + int v7; // esi + int v8; // edi + int v9; // eax + int v10; // ST08_4 + int v11; // ecx + int v12; // ecx + int v13; // edi + int v14; // eax + int v15; // eax + int *v16; // ecx + int v17; // eax + int v18; // edi + int v19; // edx + int v20; // eax + int v21; // eax + int v22; // edx + int v23; // eax + bool v24; // zf + bool v25; // sf + unsigned char v26; // of + int v27; // eax + int v28; // ecx + int v29; // edi + int v30; // eax + int v31; // eax + int v32; // eax + int v33; // edi + int v34; // ebx + int v35; // edx + int v36; // [esp+Ch] [ebp-Ch] + int arglist; // [esp+10h] [ebp-8h] + int plr_num; // [esp+14h] [ebp-4h] + int hper; // [esp+20h] [ebp+8h] + + v5 = i; + plr_num = pnum; + arglist = i; + if ( (unsigned int)i >= 0xC8 ) + TermMsg("M_TryH2HHit: Invalid monster %d", i); + v6 = v5; + if ( !monster[v5].MType ) + TermMsg("M_TryH2HHit: Monster %d \"%s\" MType NULL", v5, monster[v6].mName); + if ( monster[v6]._mFlags & 0x10 ) + { + M_TryM2MHit(v5, plr_num, Hit, MinDam, MaxDam); + return; + } + v7 = plr_num; + if ( (signed int)(plr[plr_num]._pHitPoints & 0xFFFFFFC0) > 0 && !plr[v7]._pInvincible && !(plr[v7]._pSpellFlags & 1) ) + { + v8 = abs(monster[v6]._mx - plr[v7].WorldX); + v9 = abs(monster[v6]._my - plr[v7].WorldY); + v11 = v10; + if ( v8 < 2 && v9 < 2 ) + { + _LOBYTE(v11) = 98; + v36 = random(v11, 100); + v12 = 5; + v13 = Hit + + 2 * (SLOBYTE(monster[v6].mLevel) - plr[v7]._pLevel) + + 30 + - plr[v7]._pIBonusAC + - plr[v7]._pIAC + - plr[v7]._pDexterity / 5; + if ( v13 < 15 ) + v13 = 15; + if ( currlevel == 14 ) + { + if ( v13 >= 20 ) + goto LABEL_23; + v13 = 20; + } + if ( currlevel != 15 ) + { +LABEL_20: + if ( currlevel == 16 && v13 < 30 ) + v13 = 30; + goto LABEL_23; + } + if ( v13 < 25 ) + { + v13 = 25; + goto LABEL_20; + } +LABEL_23: + v14 = plr[v7]._pmode; + if ( v14 && v14 != 4 || !plr[v7]._pBlockFlag ) + { + v15 = 100; + } + else + { + _LOBYTE(v12) = 98; + v15 = random(v12, 100); + } + v16 = (int *)(plr[v7]._pDexterity + + plr[v7]._pBaseToBlk + - 2 * SLOBYTE(monster[v6].mLevel) + + 2 * plr[v7]._pLevel); + if ( (signed int)v16 < 0 ) + v16 = 0; + if ( (signed int)v16 > 100 ) + v16 = (int *)100; + if ( v36 < v13 ) + { + if ( v15 >= (signed int)v16 ) + { + if ( monster[v6].MType->mtype == MON_ZOMBIED && plr_num == myplr ) + { + v18 = -1; + v19 = 0; + for ( hper = -1; v19 < nummissiles; ++v19 ) + { + v20 = missileactive[v19]; + if ( missile[v20]._mitype == 13 ) + { + if ( missile[v20]._misource == plr_num ) + { + v18 = missileactive[v19]; + hper = missileactive[v19]; + } + else + { + v18 = hper; + } + } + } + v16 = &plr[v7]._pMaxHP; + v21 = plr[v7]._pMaxHP; + if ( v21 > 64 ) + { + v22 = plr[v7]._pMaxHPBase; + if ( v22 > 64 ) + { + v23 = v21 - 64; + v26 = __OFSUB__(plr[v7]._pHitPoints, v23); + v24 = plr[v7]._pHitPoints == v23; + v25 = plr[v7]._pHitPoints - v23 < 0; + *v16 = v23; + if ( !((unsigned char)(v25 ^ v26) | v24) ) + { + plr[v7]._pHitPoints = v23; + if ( v18 >= 0 ) + missile[v18]._miVar1 = v23; + } + v16 = &plr[v7]._pHPBase; + v27 = v22 - 64; + plr[v7]._pMaxHPBase = v22 - 64; + if ( plr[v7]._pHPBase > v22 - 64 ) + { + *v16 = v27; + if ( v18 >= 0 ) + missile[v18]._miVar2 = v27; + } + } + } + } + _LOBYTE(v16) = 99; + v29 = (plr[v7]._pIGetHit << 6) + (MinDam << 6) + random((int)v16, (MaxDam - MinDam + 1) << 6); + if ( v29 < 64 ) + v29 = 64; + if ( plr_num == myplr ) + { + plr[v7]._pHitPoints -= v29; + plr[v7]._pHPBase -= v29; + } + if ( plr[v7]._pIFlags & 0x4000000 ) + { + _LOBYTE(v28) = 99; + v30 = (random(v28, 3) + 1) << 6; + monster[v6]._mhitpoints -= v30; + if ( (signed int)(monster[v6]._mhitpoints & 0xFFFFFFC0) > 0 ) + M_StartHit(arglist, plr_num, v30); + else + M_StartKill(arglist, plr_num); + } + if ( !(monster[v6]._mFlags & 0x1000) && monster[v6].MType->mtype == MON_SKING && gbMaxPlayers != 1 ) + monster[v6]._mhitpoints += v29; + v31 = plr[v7]._pMaxHP; + if ( plr[v7]._pHitPoints > v31 ) + { + plr[v7]._pHitPoints = v31; + plr[v7]._pHPBase = plr[v7]._pMaxHPBase; + } + if ( (signed int)(plr[v7]._pHitPoints & 0xFFFFFFC0) > 0 ) + { + StartPlrHit(plr_num, v29, 0); + if ( SLOBYTE(monster[v6]._mFlags) < 0 ) + { + if ( plr[v7]._pmode != PM_GOTHIT ) + StartPlrHit(plr_num, 0, 1u); + v32 = monster[v6]._mdir; + v33 = plr[v7].WorldX + offset_x[v32]; + v34 = plr[v7].WorldY + offset_y[v32]; + if ( PosOkPlayer(plr_num, v33, v34) ) + { + v35 = plr[v7]._pdir; + plr[v7].WorldX = v33; + plr[v7].WorldY = v34; + FixPlayerLocation(plr_num, v35); + FixPlrWalkTags(plr_num); + dPlayer[v33][v34] = plr_num + 1; + SetPlayerOld(plr_num); + } + } + } + else + { + SyncPlrKill(plr_num, 0); + } + } + else + { + v17 = GetDirection(plr[v7].WorldX, plr[v7].WorldY, monster[v6]._mx, monster[v6]._my); + StartPlrBlock(plr_num, v17); + } + } + return; + } + } +} +// 679660: using guessed type char gbMaxPlayers; + +//----- (00434C3B) -------------------------------------------------------- +int __fastcall M_DoAttack(int i) +{ + int v1; // edi + int v2; // esi + CMonster **v3; // ebx + unsigned char v4; // al + unsigned char v5; // al + + v1 = i; + if ( (unsigned int)i >= 0xC8 ) + TermMsg("M_DoAttack: Invalid monster %d", i); + v2 = v1; + v3 = &monster[v1].MType; + if ( !*v3 ) + { + TermMsg("M_DoAttack: Monster %d \"%s\" MType NULL", v1, monster[v2].mName); + if ( !*v3 ) + TermMsg("M_DoAttack: Monster %d \"%s\" MData NULL", v1, monster[v2].mName); + } + if ( monster[v2]._mAnimFrame == monster[v2].MData->mAFNum ) + { + M_TryH2HHit( + v1, + monster[v2]._menemy, + (unsigned char)monster[v2].mHit, + (unsigned char)monster[v2].mMinDamage, + (unsigned char)monster[v2].mMaxDamage); + if ( monster[v2]._mAi != MG_SNAKE ) + PlayEffect(v1, 0); + } + v4 = monster[v2].MType->mtype; + if ( v4 >= MON_MAGMAA && v4 <= MON_MAGMAD && monster[v2]._mAnimFrame == 9 ) + { + M_TryH2HHit( + v1, + monster[v2]._menemy, + (unsigned char)monster[v2].mHit + 10, + (unsigned char)monster[v2].mMinDamage - 2, + (unsigned char)monster[v2].mMaxDamage - 2); + PlayEffect(v1, 0); + } + v5 = monster[v2].MType->mtype; + if ( v5 >= MON_THINA && v5 <= MON_THIND && monster[v2]._mAnimFrame == 13 ) + { + M_TryH2HHit( + v1, + monster[v2]._menemy, + (unsigned char)monster[v2].mHit - 20, + (unsigned char)monster[v2].mMinDamage + 4, + (unsigned char)monster[v2].mMaxDamage + 4); + PlayEffect(v1, 0); + } + if ( monster[v2]._mAi == MG_SNAKE && monster[v2]._mAnimFrame == 1 ) + PlayEffect(v1, 0); + if ( monster[v2]._mAnimFrame != monster[v2]._mAnimLen ) + return 0; + M_StartStand(v1, monster[v2]._mdir); + return 1; +} + +//----- (00434DBD) -------------------------------------------------------- +int __fastcall M_DoRAttack(int i) +{ + int v1; // ebx + int v2; // esi + CMonster **v3; // edi + int v4; // eax + int v5; // eax + int v6; // edi + + v1 = i; + if ( (unsigned int)i >= 0xC8 ) + TermMsg("M_DoRAttack: Invalid monster %d", i); + v2 = v1; + v3 = &monster[v1].MType; + if ( !*v3 ) + { + TermMsg("M_DoRAttack: Monster %d \"%s\" MType NULL", v1, monster[v2].mName); + if ( !*v3 ) + TermMsg("M_DoRAttack: Monster %d \"%s\" MData NULL", v1, monster[v2].mName); + } + if ( monster[v2]._mAnimFrame == monster[v2].MData->mAFNum ) + { + v4 = monster[v2]._mVar1; + if ( v4 != -1 ) + { + v5 = 2 * (v4 == 52) + 1; + if ( v5 > 0 ) + { + v6 = v5; + do + { + AddMissile( + monster[v2]._mx, + monster[v2]._my, + (unsigned char)monster[v2]._menemyx, + (unsigned char)monster[v2]._menemyy, + monster[v2]._mdir, + monster[v2]._mVar1, + 1, + v1, + monster[v2]._mVar2, + 0); + --v6; + } + while ( v6 ); + } + } + PlayEffect(v1, 0); + } + if ( monster[v2]._mAnimFrame != monster[v2]._mAnimLen ) + return 0; + M_StartStand(v1, monster[v2]._mdir); + return 1; +} + +//----- (00434EB2) -------------------------------------------------------- +int __fastcall M_DoRSpAttack(int i) +{ + int v1; // ebx + int v2; // esi + CMonster **v3; // edi + bool v4; // zf + int v5; // ecx + + v1 = i; + if ( (unsigned int)i >= 0xC8 ) + TermMsg("M_DoRSpAttack: Invalid monster %d", i); + v2 = v1; + v3 = &monster[v1].MType; + v4 = *v3 == 0; + if ( !*v3 ) + { + TermMsg("M_DoRSpAttack: Monster %d \"%s\" MType NULL", v1, monster[v2].mName); + v4 = *v3 == 0; + } + if ( v4 ) + TermMsg("M_DoRSpAttack: Monster %d \"%s\" MData NULL", v1, monster[v2].mName); + if ( monster[v2]._mAnimFrame == monster[v2].MData->mAFNum2 && !monster[v2]._mAnimCnt ) + { + AddMissile( + monster[v2]._mx, + monster[v2]._my, + (unsigned char)monster[v2]._menemyx, + (unsigned char)monster[v2]._menemyy, + monster[v2]._mdir, + monster[v2]._mVar1, + 1, + v1, + monster[v2]._mVar3, + 0); + PlayEffect(v1, 3); + } + if ( monster[v2]._mAi == MG_MEGA && monster[v2]._mAnimFrame == 3 ) + { + v5 = monster[v2]._mVar2; + monster[v2]._mVar2 = v5 + 1; + if ( v5 ) + { + if ( v5 == 14 ) + monster[v2]._mFlags &= 0xFFFFFFFB; + } + else + { + monster[v2]._mFlags |= 4u; + } + } + if ( monster[v2]._mAnimFrame != monster[v2]._mAnimLen ) + return 0; + M_StartStand(v1, monster[v2]._mdir); + return 1; +} + +//----- (00434FC7) -------------------------------------------------------- +int __fastcall M_DoSAttack(int i) +{ + int v1; // ebx + int v2; // esi + CMonster **v3; // edi + bool v4; // zf + + v1 = i; + if ( (unsigned int)i >= 0xC8 ) + TermMsg("M_DoSAttack: Invalid monster %d", i); + v2 = v1; + v3 = &monster[v1].MType; + v4 = *v3 == 0; + if ( !*v3 ) + { + TermMsg("M_DoSAttack: Monster %d \"%s\" MType NULL", v1, monster[v2].mName); + v4 = *v3 == 0; + } + if ( v4 ) + TermMsg("M_DoSAttack: Monster %d \"%s\" MData NULL", v1, monster[v2].mName); + if ( monster[v2]._mAnimFrame == monster[v2].MData->mAFNum2 ) + M_TryH2HHit( + v1, + monster[v2]._menemy, + (unsigned char)monster[v2].mHit2, + (unsigned char)monster[v2].mMinDamage2, + (unsigned char)monster[v2].mMaxDamage2); + if ( monster[v2]._mAnimFrame != monster[v2]._mAnimLen ) + return 0; + M_StartStand(v1, monster[v2]._mdir); + return 1; +} + +//----- (0043507E) -------------------------------------------------------- +int __fastcall M_DoFadein(int i) +{ + int v1; // edi + int v2; // esi + + v1 = i; + if ( (unsigned int)i >= 0xC8 ) + TermMsg("M_DoFadein: Invalid monster %d", i); + v2 = v1; + if ( (!(monster[v1]._mFlags & 2) || monster[v2]._mAnimFrame != 1) + && (monster[v1]._mFlags & 2 || monster[v2]._mAnimFrame != monster[v2]._mAnimLen) ) + { + return 0; + } + M_StartStand(v1, monster[v2]._mdir); + monster[v2]._mFlags &= 0xFFFFFFFD; + return 1; +} + +//----- (004350E3) -------------------------------------------------------- +int __fastcall M_DoFadeout(int i) +{ + int v1; // esi + int v2; // eax + int v3; // ecx + signed int v4; // edx + int v5; // ecx + int v6; // edx + + v1 = i; + if ( (unsigned int)i >= 0xC8 ) + TermMsg("M_DoFadeout: Invalid monster %d", i); + v2 = v1; + v3 = monster[v1]._mFlags; + if ( (!(monster[v1]._mFlags & 2) || monster[v2]._mAnimFrame != 1) + && (monster[v1]._mFlags & 2 || monster[v2]._mAnimFrame != monster[v2]._mAnimLen) ) + { + return 0; + } + v4 = monster[v2].MType->mtype; + if ( v4 < MON_FIREMANA || v4 > MON_FIREMAND ) + v5 = v3 & 0xFFFFFFFD | 1; + else + v5 = v3 & 0xFFFFFFFD; + v6 = monster[v2]._mdir; + monster[v2]._mFlags = v5; + M_StartStand(v1, v6); + return 1; +} + +//----- (00435165) -------------------------------------------------------- +int __fastcall M_DoHeal(int i) +{ + int v1; // esi + int v2; // eax + int v3; // esi + int *v4; // edx + int v5; // ecx + int v6; // edi + int v7; // edi + int v8; // esi + + v1 = i; + if ( (unsigned int)i >= 0xC8 ) + TermMsg("M_DoHeal: Invalid monster %d", i); + v2 = v1; + if ( monster[v1]._mFlags & 8 ) + { + monster[v2]._mFlags &= 0xFFFFFFFB; + monster[v2]._mmode = MM_SATTACK; + } + else if ( monster[v2]._mAnimFrame == 1 ) + { + v3 = monster[v2]._mVar1; + v4 = &monster[v2]._mhitpoints; + v5 = monster[v2]._mFlags & 0xFFFFFFFD | 4; + v6 = monster[v2]._mhitpoints; + monster[v2]._mFlags = v5; + v7 = v3 + v6; + v8 = monster[v2]._mmaxhp; + if ( v7 >= v8 ) + { + *v4 = v8; + monster[v2]._mFlags = v5 & 0xFFFFFFFB; + monster[v2]._mmode = MM_SATTACK; + } + else + { + *v4 = v7; + } + } + return 0; +} + +//----- (004351F5) -------------------------------------------------------- +int __fastcall M_DoTalk(int i) +{ + int v1; // ebp + int v2; // edi + int v3; // esi + int v4; // eax + int v5; // eax + int v6; // edx + int v7; // ecx + char v8; // bl + int v9; // eax + char *v10; // eax + unsigned char v12; // [esp-8h] [ebp-10h] + + v2 = i; + if ( (unsigned int)i >= 0xC8 ) + TermMsg("M_DoTalk: Invalid monster %d", i); + v3 = v2; + M_StartStand(v2, monster[v2]._mdir); + _LOBYTE(monster[v2]._mgoal) = 7; + _LOBYTE(v4) = effect_is_playing(alltext[monster[v2].mtalkmsg].sfxnr); + if ( !v4 ) + { + v12 = v1; + InitQTextMsg(monster[v3].mtalkmsg); + if ( monster[v3].mName == UniqMonst[0].mName ) + { + v5 = monster[v3].mtalkmsg; + if ( v5 == TEXT_GARBUD1 ) + quests[2]._qactive = 2; + quests[2]._qlog = 1; + if ( v5 == TEXT_GARBUD2 && !(monster[v3]._mFlags & 0x40) ) + { + SpawnItem(v2, monster[v3]._mx + 1, monster[v3]._my + 1, 1u); + monster[v3]._mFlags |= 0x40u; + } + } + if ( monster[v3].mName == UniqMonst[2].mName + && monster[v3].mtalkmsg == TEXT_ZHAR1 + && !(monster[v3]._mFlags & 0x40) ) + { + v6 = monster[v3]._my + 1; + v7 = monster[v3]._mx + 1; + quests[3]._qactive = 2; + quests[3]._qlog = 1; + CreateTypeItem(v7, v6, 0, 0, 24, 1, 0); + monster[v3]._mFlags |= 0x40u; + } + if ( monster[v3].mName == UniqMonst[3].mName ) + { + if ( monster[v3].mtalkmsg == TEXT_SNOT1 && !(monster[v3]._mFlags & 0x40) ) + { + DRLG_MRectTrans(setpc_x, setpc_y, (setpc_w >> 1) + setpc_x + 2, (setpc_h >> 1) + setpc_y - 2); + v8 = TransVal; + TransVal = 9; + Make_RectTrans(setpc_x, setpc_y, (setpc_w >> 1) + setpc_x + 4, setpc_y + (setpc_h >> 1)); + TransVal = v8; + quests[7]._qvar1 = 2; + if ( quests[7]._qactive == 1 ) + quests[7]._qactive = 2; + monster[v3]._mFlags |= 0x40u; + } + if ( quests[7]._qvar1 < 2u ) + { + sprintf(tempstr, "SS Talk = %i, Flags = %i", monster[v3].mtalkmsg, monster[v3]._mFlags, v1); + TermMsg(tempstr); + } + } + if ( monster[v3].mName == UniqMonst[7].mName ) + { + v9 = monster[v3].mtalkmsg; + if ( v9 == TEXT_LACH1 ) + { + quests[4]._qactive = 2; + quests[4]._qlog = 1; + } + if ( v9 == TEXT_LACH3 && !(monster[v3]._mFlags & 0x40) ) + { + CheckUnique(6, monster[v3]._mx + 1, monster[v3]._my + 1, v12); + monster[v3]._mFlags |= 0x40u; + } + } + v10 = monster[v3].mName; + if ( v10 == UniqMonst[8].mName ) + quests[11]._qvar1 = 2; + if ( v10 == UniqMonst[4].mName && gbMaxPlayers != 1 ) + { + _LOBYTE(monster[v3]._msquelch) = -1; + monster[v3].mtalkmsg = 0; + quests[15]._qvar1 = 6; + _LOBYTE(monster[v3]._mgoal) = 1; + } + } + return 0; +} +// 4351F5: could not find valid save-restore pair for ebp +// 5A5590: using guessed type char TransVal; +// 5CF330: using guessed type int setpc_h; +// 5CF334: using guessed type int setpc_w; +// 679660: using guessed type char gbMaxPlayers; + +//----- (0043547A) -------------------------------------------------------- +void __fastcall M_Teleport(int i) +{ + int v1; // ebx + int v2; // ST04_4 + MonsterStruct *v3; // esi + int v4; // eax + int v5; // ecx + int v6; // edi + int v7; // ebx + int v8; // eax + int v9; // [esp+Ch] [ebp-24h] + int v10; // [esp+10h] [ebp-20h] + int v11; // [esp+14h] [ebp-1Ch] + int v12; // [esp+18h] [ebp-18h] + int v13; // [esp+1Ch] [ebp-14h] + int a1; // [esp+20h] [ebp-10h] + signed int v15; // [esp+24h] [ebp-Ch] + signed int v16; // [esp+28h] [ebp-8h] + signed int v17; // [esp+2Ch] [ebp-4h] + + v1 = i; + a1 = i; + if ( (unsigned int)i >= 0xC8 ) + { + TermMsg("M_Teleport: Invalid monster %d", i); + i = v2; + } + v15 = 0; + v3 = &monster[v1]; + if ( v3->_mmode != 15 ) + { + v10 = (unsigned char)v3->_menemyx; + _LOBYTE(i) = 100; + v12 = (unsigned char)v3->_menemyy; + v4 = random(i, 2); + _LOBYTE(v5) = 100; + v11 = 2 * v4 - 1; + v17 = -1; + v6 = v9; + v13 = 2 * random(v5, 2) - 1; + while ( !v15 ) + { + v16 = -1; + v7 = v12 - v13; + do + { + if ( v15 ) + break; + if ( v17 || v16 ) + { + v9 = v7; + v6 = v10 + v11 * v17; + if ( v7 >= 0 && v7 < 112 && v6 >= 0 && v6 < 112 && v6 != v3->_mx && v7 != v3->_my ) + { + if ( PosOkMonst(a1, v10 + v11 * v17, v7) ) + v15 = 1; + } + } + ++v16; + v7 += v13; + } + while ( v16 < 1 ); + if ( ++v17 > 1 ) + { + if ( !v15 ) + return; + v1 = a1; + break; + } + v1 = a1; + } + M_ClearSquares(v1); + v8 = v3->_my + 112 * v3->_mx; + v3->_moldx = v6; + dMonster[0][v8] = 0; + v3->_moldy = v9; + dMonster[0][v9 + 112 * v6] = v1 + 1; + v3->_mdir = M_GetDir(v1); + M_CheckEFlag(v1); + } +} + +//----- (004355BB) -------------------------------------------------------- +int __fastcall M_DoGotHit(int i) +{ + int v1; // edi + int v2; // esi + + v1 = i; + if ( (unsigned int)i >= 0xC8 ) + TermMsg("M_DoGotHit: Invalid monster %d", i); + v2 = v1; + if ( !monster[v1].MType ) + TermMsg("M_DoGotHit: Monster %d \"%s\" MType NULL", v1, monster[v2].mName); + if ( monster[v2]._mAnimFrame != monster[v2]._mAnimLen ) + return 0; + M_StartStand(v1, monster[v2]._mdir); + return 1; +} + +//----- (0043561E) -------------------------------------------------------- +int __fastcall M_UpdateLeader(int i) +{ + int v1; // edi + int v2; // esi + int j; // edx + int v4; // eax + int result; // eax + + v1 = i; + if ( (unsigned int)i >= 0xC8 ) + TermMsg("M_UpdateLeader: Invalid monster %d", i); + v2 = nummonsters; + for ( j = 0; j < v2; ++j ) + { + v4 = monstactive[j]; + if ( monster[v4].leaderflag == 1 && (unsigned char)monster[v4].leader == v1 ) + monster[v4].leaderflag = 0; + } + result = 228 * v1; + if ( monster[v1].leaderflag == 1 ) + { + result = (int)&monster[*((unsigned char *)&monster[0].leader + result)].unpackfilesize; + --*(_BYTE *)result; + } + return result; +} + +//----- (00435697) -------------------------------------------------------- +void __cdecl DoEnding() +{ + char v0; // al + char *v1; // ecx + char v2; // bl + int v3; // esi + + if ( (unsigned char)gbMaxPlayers > 1u ) + SNetLeaveGame(1073741828); + music_stop(); + if ( (unsigned char)gbMaxPlayers > 1u ) + Sleep(0x3E8u); + v0 = plr[myplr]._pClass; + if ( v0 ) + { + v1 = "gendata\\DiabVic1.smk"; + if ( v0 != 2 ) + v1 = "gendata\\DiabVic3.smk"; + } + else + { + v1 = "gendata\\DiabVic2.smk"; + } + play_movie(v1, 0); + play_movie("gendata\\Diabend.smk", 0); + v2 = gbMusicOn; + gbMusicOn = 1; + v3 = sound_get_or_set_music_volume(1); + sound_get_or_set_music_volume(0); + music_start(2); + loop_movie = 1; + play_movie("gendata\\loopdend.smk", 1); + loop_movie = 0; + music_stop(); + sound_get_or_set_music_volume(v3); + gbMusicOn = v2; +} +// 4A22D4: using guessed type char gbMusicOn; +// 659AFC: using guessed type int loop_movie; +// 679660: using guessed type char gbMaxPlayers; + +//----- (0043575C) -------------------------------------------------------- +void __cdecl PrepDoEnding() +{ + int *v0; // eax + int v1; // ecx + int *v2; // eax + bool v3; // cf + bool v4; // zf + + gbSoundOn = sgbSaveSoundOn; + gbRunGame = 0; + *(_DWORD *)&deathflag = 0; + v0 = &plr[myplr].pDiabloKillLevel; + v1 = gnDifficulty + 1; + cineflag = 1; + if ( *v0 > (unsigned int)(gnDifficulty + 1) ) + v1 = *v0; + *v0 = v1; + v2 = &plr[0]._pHitPoints; + do + { + v3 = (unsigned char)gbMaxPlayers < 1u; + v4 = gbMaxPlayers == 1; + *(v2 - 102) = 11; + *((_BYTE *)v2 - 91) = 1; + if ( !v3 && !v4 ) + { + if ( !(*v2 & 0xFFFFFFC0) ) + *v2 = 64; + if ( !(v2[5] & 0xFFFFFFC0) ) + v2[5] = 64; + } + v2 += 5430; + } + while ( (signed int)v2 < (signed int)&plr_msgs[2].msg[51] ); +} +// 4A22D5: using guessed type char gbSoundOn; +// 525650: using guessed type int gbRunGame; +// 525718: using guessed type char cineflag; +// 64D32C: using guessed type int sgbSaveSoundOn; +// 679660: using guessed type char gbMaxPlayers; + +//----- (004357DF) -------------------------------------------------------- +int __fastcall M_DoDeath(int i) +{ + int v1; // edi + int v2; // esi + CMonster *v3; // ecx + int v4; // eax + int v5; // ecx + signed int v6; // ecx + int v7; // esi + int v8; // esi + signed int v9; // ecx + char v10; // al + int v11; // eax + + v1 = i; + if ( (unsigned int)i >= 0xC8 ) + TermMsg("M_DoDeath: Invalid monster %d", i); + v2 = v1; + if ( !monster[v1].MType ) + TermMsg("M_DoDeath: Monster %d \"%s\" MType NULL", v1, monster[v2].mName); + v3 = monster[v2].MType; + v4 = ++monster[v2]._mVar1; + if ( v3->mtype == MON_DIABLO ) + { + v5 = monster[v2]._mx - ViewX; + if ( v5 >= 0 ) + v6 = v5 > 0; + else + v6 = -1; + v7 = monster[v2]._my; + ViewX += v6; + v8 = v7 - ViewY; + if ( v8 >= 0 ) + { + v9 = v8 < 0; + _LOBYTE(v9) = v8 > 0; + } + else + { + v9 = -1; + } + ViewY += v9; + if ( v4 == 140 ) + PrepDoEnding(); + } + else if ( monster[v2]._mAnimFrame == monster[v2]._mAnimLen ) + { + if ( monster[v2]._uniqtype ) + v10 = monster[v2]._udeadval; + else + v10 = v3->mdeadval; + AddDead(monster[v2]._mx, monster[v2]._my, v10, (direction)monster[v2]._mdir); + v11 = monster[v2]._my + 112 * monster[v2]._mx; + monster[v2]._mDelFlag = 1; + dMonster[0][v11] = 0; + M_UpdateLeader(v1); + } + return 0; +} + +//----- (004358EC) -------------------------------------------------------- +int __fastcall M_DoSpStand(int i) +{ + int v1; // ebx + int v2; // esi + + v1 = i; + if ( (unsigned int)i >= 0xC8 ) + TermMsg("M_DoSpStand: Invalid monster %d", i); + v2 = v1; + if ( !monster[v1].MType ) + TermMsg("M_DoSpStand: Monster %d \"%s\" MType NULL", v1, monster[v2].mName); + if ( monster[v2]._mAnimFrame == monster[v2].MData->mAFNum2 ) + PlayEffect(v1, 3); + if ( monster[v2]._mAnimFrame != monster[v2]._mAnimLen ) + return 0; + M_StartStand(v1, monster[v2]._mdir); + return 1; +} + +//----- (0043596B) -------------------------------------------------------- +int __fastcall M_DoDelay(int i) +{ + int v1; // ebp + int v2; // esi + int v3; // eax + bool v4; // zf + int v5; // ecx + int v6; // ecx + int v7; // ebx + + v1 = i; + if ( (unsigned int)i >= 0xC8 ) + TermMsg("M_DoDelay: Invalid monster %d", i); + v2 = v1; + if ( !monster[v1].MType ) + TermMsg("M_DoDelay: Monster %d \"%s\" MType NULL", v1, monster[v2].mName); + v3 = M_GetDir(v1); + v4 = monster[v2]._mAi == MG_LAZURUS; + monster[v2]._mAFNum = monster[v2].MType->Anims[0].Frames[v3 + 1]; + if ( v4 ) + { + v5 = monster[v2]._mVar2; + if ( v5 > 8 || v5 < 0 ) + monster[v2]._mVar2 = 8; + } + v6 = monster[v2]._mVar2; + monster[v2]._mVar2 = v6 - 1; + if ( v6 ) + return 0; + v7 = monster[v2]._mAnimFrame; + M_StartStand(v1, monster[v2]._mdir); + monster[v2]._mAnimFrame = v7; + return 1; +} + +//----- (00435A14) -------------------------------------------------------- +int __fastcall M_DoStone(int i) +{ + int v1; // esi + int v2; // eax + int v3; // ecx + + v1 = i; + if ( (unsigned int)i >= 0xC8 ) + TermMsg("M_DoStone: Invalid monster %d", i); + v2 = v1; + if ( !monster[v1]._mhitpoints ) + { + v3 = monster[v2]._mx; + monster[v2]._mDelFlag = 1; + dMonster[0][monster[v2]._my + 112 * v3] = 0; + } + return 0; +} + +//----- (00435A62) -------------------------------------------------------- +void __fastcall M_WalkDir(int i, int md) +{ + int v2; // esi + int v3; // edi + int v4; // eax + int v5; // eax + int v6; // edx + int v7; // ecx + int v8; // eax + int v9; // edx + int v10; // eax + int v11; // [esp-14h] [ebp-1Ch] + int v12; // [esp-Ch] [ebp-14h] + int v13; // [esp-Ch] [ebp-14h] + int v14; // [esp-8h] [ebp-10h] + int v15; // [esp-8h] [ebp-10h] + int v16; // [esp-4h] [ebp-Ch] + int v17; // [esp-4h] [ebp-Ch] + + v2 = i; + v3 = md; + if ( (unsigned int)i >= 0xC8 ) + TermMsg("M_WalkDir: Invalid monster %d", i); + v4 = monster[v2].MType->Anims[1].Rate - 1; + switch ( v3 ) + { + case DIR_S: + M_StartWalk2(v2, 0, MWVel[v4][1], 0, -32, 1, 1, 0); + return; + case DIR_SW: + v17 = 1; + v8 = v4; + v15 = 1; + v13 = 0; + v11 = 32; + v9 = -MWVel[v8][1]; + goto LABEL_10; + case DIR_W: + M_StartWalk3(v2, -MWVel[v4][2], 0, 32, -16, -1, 1, 0, 1, 2); + return; + case DIR_NW: + v16 = 3; + v10 = v4; + v14 = 0; + v12 = -1; + v7 = -MWVel[v10][0]; + v6 = -MWVel[v10][1]; + goto LABEL_15; + case DIR_N: + M_StartWalk(v2, 0, -MWVel[v4][1], -1, -1, 4); + break; + case DIR_NE: + v16 = 5; + v5 = v4; + v14 = -1; + v12 = 0; + v6 = MWVel[v5][1]; + v7 = -MWVel[v5][0]; +LABEL_15: + M_StartWalk(v2, v6, v7, v12, v14, v16); + break; + case DIR_E: + M_StartWalk3(v2, MWVel[v4][2], 0, -32, -16, 1, -1, 1, 0, 6); + break; + case DIR_SE: + v17 = 7; + v8 = v4; + v15 = 0; + v13 = 1; + v9 = MWVel[v8][1]; + v11 = -32; +LABEL_10: + M_StartWalk2(v2, v9, MWVel[v8][0], v11, -16, v13, v15, v17); + break; + default: + return; + } +} + +//----- (00435BB5) -------------------------------------------------------- +void __fastcall GroupUnity(int i) +{ + int v1; // ebx + int v2; // esi + int v3; // ebp + int v4; // edi + int v5; // eax + int v6; // eax + int v7; // ecx + unsigned char v8; // al + int v9; // ebp + int j; // edi + int v11; // eax + int v12; // ecx + int v13; // [esp+10h] [ebp-4h] + + v1 = i; + if ( (unsigned int)i >= 0xC8 ) + TermMsg("GroupUnity: Invalid monster %d", i); + v2 = v1; + if ( monster[v1].leaderflag ) + { + v3 = (unsigned char)monster[v2].leader; + v4 = v3; + _LOBYTE(v5) = LineClearF( + (unsigned char (__cdecl *)())CheckNoSolid, + monster[v2]._mx, + monster[v2]._my, + monster[v4]._mfutx, + monster[v4]._mfuty); + if ( v5 ) + { + if ( monster[v2].leaderflag == 2 + && abs(monster[v2]._mx - monster[v4]._mfutx) < 4 + && abs(monster[v2]._my - monster[v4]._mfuty) < 4 ) + { + ++monster[v4].unpackfilesize; + monster[v2].leaderflag = 1; + } + } + else + { + if ( monster[v2].leaderflag != 1 ) + goto LABEL_18; + --monster[v4].unpackfilesize; + monster[v2].leaderflag = 2; + } + } + else + { + v3 = v13; + } + if ( monster[v2].leaderflag == 1 ) + { + v6 = v3; + if ( _LOBYTE(monster[v2]._msquelch) > _LOBYTE(monster[v3]._msquelch) ) + { + monster[v6]._lastx = monster[v2]._mx; + monster[v6]._lasty = monster[v2]._my; + _LOBYTE(monster[v6]._msquelch) = _LOBYTE(monster[v2]._msquelch) - 1; + } + if ( monster[v6]._mAi == MG_GARG ) + { + v7 = monster[v6]._mFlags; + if ( v7 & 4 ) + { + monster[v6]._mmode = MM_SATTACK; + monster[v6]._mFlags = v7 & 0xFFFFFFFB; + } + } + return; + } +LABEL_18: + v8 = monster[v2]._uniqtype; + if ( v8 ) + { + if ( MonstAvailTbl[32 * v8 + 102] & 2 ) + { + v9 = nummonsters; + for ( j = 0; j < v9; ++j ) + { + v11 = monstactive[j]; + if ( monster[v11].leaderflag == 1 && (unsigned char)monster[v11].leader == v1 ) + { + if ( _LOBYTE(monster[v2]._msquelch) > _LOBYTE(monster[v11]._msquelch) ) + { + monster[v11]._lastx = monster[v2]._mx; + monster[v11]._lasty = monster[v2]._my; + _LOBYTE(monster[v11]._msquelch) = _LOBYTE(monster[v2]._msquelch) - 1; + } + if ( monster[v11]._mAi == MG_GARG ) + { + v12 = monster[v11]._mFlags; + if ( v12 & 4 ) + { + monster[v11]._mmode = MM_SATTACK; + monster[v11]._mFlags = v12 & 0xFFFFFFFB; + } + } + } + } + } + } +} + +//----- (00435DA8) -------------------------------------------------------- +unsigned char __fastcall M_CallWalk(int i, int md) +{ + int v2; // esi + int v3; // edi + int v4; // ebp + int v5; // eax + int v6; // ecx + int v7; // ebx + int v8; // ecx + int v9; // ebx + int v10; // eax + int v11; // ebx + int v12; // eax + int v13; // eax + signed int v14; // ebx + int v15; // eax + int v16; // eax + int v17; // eax + unsigned char v18; // bl + + v2 = md; + v3 = i; + v4 = md; + _LOBYTE(v5) = DirOK(i, md); + _LOBYTE(v6) = 101; + v7 = v5; + if ( random(v6, 2) ) + { + if ( v7 ) + goto LABEL_10; + v9 = v2; + v2 = left[v2]; + _LOBYTE(v10) = DirOK(v3, v2); + if ( v10 ) + goto LABEL_10; + v2 = right[v9]; + } + else + { + if ( v7 ) + goto LABEL_10; + v11 = v2; + v2 = right[v2]; + _LOBYTE(v12) = DirOK(v3, v2); + if ( v12 ) + goto LABEL_10; + v2 = left[v11]; + } + _LOBYTE(v13) = DirOK(v3, v2); + if ( !v13 ) + { + v14 = 0; + goto LABEL_11; + } +LABEL_10: + v14 = 1; +LABEL_11: + _LOBYTE(v8) = 102; + if ( random(v8, 2) ) + { + if ( v14 ) + goto LABEL_20; + v2 = right[right[v4]]; + _LOBYTE(v15) = DirOK(v3, v2); + if ( v15 ) + goto LABEL_20; + v2 = left[left[v4]]; + } + else + { + if ( v14 ) + goto LABEL_20; + v2 = left[left[v4]]; + _LOBYTE(v16) = DirOK(v3, v2); + if ( v16 ) + goto LABEL_20; + v2 = right[right[v4]]; + } + _LOBYTE(v17) = DirOK(v3, v2); + if ( v17 ) + { +LABEL_20: + v18 = 1; + M_WalkDir(v3, v2); + return v18; + } + return 0; +} + +//----- (00435EB5) -------------------------------------------------------- +int __fastcall M_PathWalk(int i) +{ + int v1; // esi + int (__fastcall *v2)(int, int, int); // ecx + char path[25]; // [esp+4h] [ebp-1Ch] + + v1 = i; + if ( (unsigned int)i >= 0xC8 ) + TermMsg("M_PathWalk: Invalid monster %d", i); + v2 = PosOkMonst3; + if ( !(monster[v1]._mFlags & 0x200) ) + v2 = PosOkMonst; + if ( !FindPath( + v2, + v1, + monster[v1]._mx, + monster[v1]._my, + (unsigned char)monster[v1]._menemyx, + (unsigned char)monster[v1]._menemyy, + path) ) + return 0; + M_CallWalk(v1, (char)plr2monst[path[0]]); + return 1; +} + +//----- (00435F35) -------------------------------------------------------- +unsigned char __fastcall M_CallWalk2(int i, int md) +{ + int v2; // esi + int v3; // ebx + int v4; // eax + int v5; // ecx + int v6; // edi + int v7; // edi + int v8; // eax + int v9; // edi + int v10; // eax + int v11; // eax + unsigned char v12; // di + + v2 = md; + v3 = i; + _LOBYTE(v4) = DirOK(i, md); + _LOBYTE(v5) = 101; + v6 = v4; + if ( random(v5, 2) ) + { + if ( v6 ) + goto LABEL_10; + v7 = v2; + v2 = left[v2]; + _LOBYTE(v8) = DirOK(v3, v2); + if ( v8 ) + goto LABEL_10; + v2 = right[v7]; + } + else + { + if ( v6 ) + goto LABEL_10; + v9 = v2; + v2 = right[v2]; + _LOBYTE(v10) = DirOK(v3, v2); + if ( v10 ) + goto LABEL_10; + v2 = left[v9]; + } + _LOBYTE(v11) = DirOK(v3, v2); + if ( v11 ) + { +LABEL_10: + v12 = 1; + M_WalkDir(v3, v2); + return v12; + } + return 0; +} + +//----- (00435FBA) -------------------------------------------------------- +unsigned char __fastcall M_DumbWalk(int i, int md) +{ + int v2; // esi + int v3; // edi + int v4; // eax + unsigned char v5; // bl + + v2 = md; + v3 = i; + _LOBYTE(v4) = DirOK(i, md); + v5 = v4; + if ( v4 ) + M_WalkDir(v3, v2); + return v5; +} + +//----- (00435FDB) -------------------------------------------------------- +unsigned char __fastcall M_RoundWalk(int i, int md, int *dir) +{ + int *v3; // ebp + int v4; // ebx + int v5; // esi + int v6; // eax + unsigned char v7; // di + int v8; // edi + int v9; // eax + int v10; // eax + int *v11; // ebp + int v12; // eax + int v13; // eax + + v3 = dir; + v4 = i; + if ( *dir ) + v5 = left[left[md]]; + else + v5 = right[right[md]]; + _LOBYTE(v6) = DirOK(i, v5); + v7 = v6; + if ( v6 ) + goto LABEL_12; + v8 = v5; + if ( !*dir ) + { + v11 = &left[v8]; + v5 = left[v8]; + _LOBYTE(v12) = DirOK(v4, left[v8]); + if ( v12 ) + goto LABEL_11; + v5 = left[*v11]; + _LOBYTE(v13) = DirOK(v4, left[*v11]); + if ( v13 ) + goto LABEL_11; + v3 = dir; +LABEL_14: + *v3 = *v3 == 0; + return M_CallWalk(v4, opposite[v8]); + } + v5 = right[v8]; + _LOBYTE(v9) = DirOK(v4, right[v8]); + if ( !v9 ) + { + v5 = right[right[v8]]; + _LOBYTE(v10) = DirOK(v4, v5); + if ( !v10 ) + goto LABEL_14; + } +LABEL_11: + v7 = 1; +LABEL_12: + M_WalkDir(v4, v5); + return v7; +} + +//----- (004360B1) -------------------------------------------------------- +void __fastcall MAI_Zombie(int i) +{ + int v1; // esi + int v2; // ST04_4 + MonsterStruct *v3; // esi + int v4; // edi + int v5; // ebx + int v6; // edi + int v7; // eax + int v8; // ecx + int v9; // eax + int v10; // eax + int v11; // eax + int v12; // ecx + int md; // [esp+Ch] [ebp-Ch] + int v14; // [esp+10h] [ebp-8h] + int arglist; // [esp+14h] [ebp-4h] + + v1 = i; + arglist = i; + if ( (unsigned int)i >= 0xC8 ) + { + TermMsg("MAI_Zombie: Invalid monster %d", i); + i = v2; + } + v3 = &monster[v1]; + if ( v3->_mmode == MM_STAND ) + { + v4 = v3->_my; + if ( dFlags[v3->_mx][v4] & 2 ) + { + v5 = v3->_mx - (unsigned char)v3->_menemyx; + v6 = v4 - (unsigned char)v3->_menemyy; + _LOBYTE(i) = 103; + md = v3->_mdir; + v14 = random(i, 100); + if ( abs(v5) >= 2 || abs(v6) >= 2 ) + { + if ( v14 < 2 * (unsigned char)v3->_mint + 10 ) + { + v7 = abs(v5); + v8 = 2 * (unsigned char)v3->_mint + 4; + if ( v7 >= v8 || (v9 = abs(v6), v8 = 2 * (unsigned char)v3->_mint + 4, v9 >= v8) ) + { + _LOBYTE(v8) = 104; + v11 = random(v8, 100); + v12 = 2 * (unsigned char)v3->_mint + 20; + if ( v11 < v12 ) + { + _LOBYTE(v12) = 104; + md = random(v12, 8); + } + M_DumbWalk(arglist, md); + } + else + { + v10 = M_GetDir(arglist); + M_CallWalk(arglist, v10); + } + } + } + else if ( v14 < 2 * (unsigned char)v3->_mint + 10 ) + { + M_StartAttack(arglist); + } + if ( v3->_mmode == MM_STAND ) + v3->_mAFNum = v3->MType->Anims[0].Frames[v3->_mdir + 1]; + } + } +} + +//----- (004361F7) -------------------------------------------------------- +void __fastcall MAI_SkelSd(int i) +{ + int v1; // esi + MonsterStruct *v2; // esi + int v3; // ecx + int v4; // edx + int v5; // edi + int v6; // ebp + int v7; // ebx + int v8; // eax + int v9; // ST04_4 + int v10; // ecx + int v11; // eax + int v12; // ST04_4 + int v13; // eax + int v14; // ecx + int v15; // edx + int v16; // eax + int v17; // ecx + int arglist; // [esp+8h] [ebp-4h] + + v1 = i; + arglist = i; + if ( (unsigned int)i >= 0xC8 ) + TermMsg("MAI_SkelSd: Invalid monster %d", i); + v2 = &monster[v1]; + if ( v2->_mmode == MM_STAND && _LOBYTE(v2->_msquelch) ) + { + v3 = v2->_mx; + v4 = v2->_my; + v5 = v3 - (unsigned char)v2->_menemyx; + v6 = v4 - (unsigned char)v2->_menemyy; + v7 = GetDirection(v3, v4, v2->_lastx, v2->_lasty); + v2->_mdir = v7; + v8 = abs(v5); + v10 = v9; + if ( v8 >= 2 || (v11 = abs(v6), v10 = v12, v11 >= 2) ) + { + if ( v2->_mVar1 != 13 ) + { + _LOBYTE(v10) = 106; + v16 = random(v10, 100); + v17 = 4 * (unsigned char)v2->_mint; + if ( v16 < 35 - v17 ) + { + _LOBYTE(v17) = 106; + v15 = 15 - 2 * (unsigned char)v2->_mint + random(v17, 10); + goto LABEL_10; + } + } + M_CallWalk(arglist, v7); + } + else + { + if ( v2->_mVar1 != 13 ) + { + _LOBYTE(v10) = 105; + v13 = random(v10, 100); + v14 = 2 * (unsigned char)v2->_mint + 20; + if ( v13 >= v14 ) + { + _LOBYTE(v14) = 105; + v15 = random(v14, 10) + 2 * (5 - (unsigned char)v2->_mint); +LABEL_10: + M_StartDelay(arglist, v15); + goto LABEL_16; + } + } + M_StartAttack(arglist); + } +LABEL_16: + if ( v2->_mmode == MM_STAND ) + v2->_mAFNum = v2->MType->Anims[0].Frames[v7 + 1]; + } +} + +//----- (00436331) -------------------------------------------------------- +void __fastcall MAI_Path(int i) +{ + int v1; // edi + MonsterStruct *v2; // esi + char v3; // al + int v4; // eax + unsigned char v5; // al + + v1 = i; + if ( (unsigned int)i >= 0xC8 ) + TermMsg("MAI_Path: Invalid monster %d", i); + v2 = &monster[v1]; + if ( v2->MType->mtype == MON_GOLEM + || _LOBYTE(v2->_msquelch) + && v2->_mmode == MM_STAND + && ((v3 = v2->_mgoal, v3 == 1) || v3 == 4 || v3 == 5) + && (v2->_mx != 1 || v2->_my) ) + { + _LOBYTE(v4) = LineClearF1( + (unsigned char (__cdecl *)())PosOkMonst2, + v1, + v2->_mx, + v2->_my, + (unsigned char)v2->_menemyx, + (unsigned char)v2->_menemyy); + if ( v4 ) + { + v5 = v2->_pathcount; + if ( v5 < 5u || v5 >= 8u ) + goto LABEL_22; + } + if ( v2->_mFlags & 0x200 ) + MonstCheckDoors(v1); + if ( ++_LOBYTE(v2->_pathcount) >= 5u && !M_PathWalk(v1) ) + { +LABEL_22: + if ( v2->MType->mtype != MON_GOLEM ) + _LOBYTE(v2->_pathcount) = 0; + } + } +} + +//----- (004363F9) -------------------------------------------------------- +void __fastcall MAI_Snake(int i) +{ + int esi1; // esi + MonsterStruct *esi3; // esi + bool v3; // zf + int v4; // ecx + int v5; // eax + int v6; // ST1C_4 + int v7; // edi + int v8; // edx + int v9; // ST18_4 + int v10; // ebx + int v11; // eax + int v12; // ST1C_4 + int v13; // ecx + int v14; // eax + int v15; // eax + int v16; // ecx + int v17; // edx + int v18; // ecx + int v19; // eax + int v20; // ST1C_4 + int v21; // ecx + int v22; // eax + int v23; // ST1C_4 + int v24; // ebx + int v25; // eax + int v26; // ecx + int v27; // eax + int v28; // ecx + int v29; // ecx + int v30; // eax + int v31; // edx + int v32; // eax + int v33; // ecx + int v34; // ecx + int v35; // eax + int v36; // eax + char v37; // [esp+4h] [ebp-1Ch] + char v38; // [esp+5h] [ebp-1Bh] + char v39; // [esp+6h] [ebp-1Ah] + char v40; // [esp+7h] [ebp-19h] + char v41; // [esp+8h] [ebp-18h] + char v42; // [esp+9h] [ebp-17h] + int micaster; // [esp+Ch] [ebp-14h] + int midir; // [esp+10h] [ebp-10h] + int v1; // [esp+14h] [ebp-Ch] + int v2; // [esp+18h] [ebp-8h] + char arglist[4]; // [esp+1Ch] [ebp-4h] + + esi1 = i; + *(_DWORD *)arglist = i; + if ( (unsigned int)i >= 0xC8 ) + TermMsg("MAI_Snake: Invalid monster %d", i); + v39 = 0; + v40 = -1; + v41 = -1; + v42 = 0; + esi3 = &monster[esi1]; + v37 = 1; + v38 = 1; + v3 = esi3->_mmode == 0; + micaster = esi3->_menemy; + if ( v3 && _LOBYTE(esi3->_msquelch) ) + { + v4 = esi3->_mx; + v5 = (unsigned char)esi3->_menemyy; + v6 = esi3->_lasty; + v1 = (unsigned char)esi3->_menemyx; + v7 = v4 - v1; + v8 = esi3->_my; + v9 = esi3->_lastx; + v2 = v5; + v10 = v8 - v5; + midir = GetDirection(v4, v8, v9, v6); + esi3->_mdir = midir; + if ( abs(v7) < 2 ) + { + v11 = abs(v10); + v13 = v12; + if ( v11 < 2 ) + { + v14 = esi3->_mVar1; + if ( v14 == 13 + || v14 == 14 + || (_LOBYTE(v13) = 105, v15 = random(v13, 100), v16 = (unsigned char)esi3->_mint + 20, v15 < v16) ) + { + M_StartAttack(*(int *)arglist); +LABEL_49: + if ( esi3->_mmode == MM_STAND ) + esi3->_mAFNum = esi3->MType->Anims[0].Frames[esi3->_mdir + 1]; + return; + } + _LOBYTE(v16) = 105; + v17 = 10 - (unsigned char)esi3->_mint + random(v16, 10); + v18 = *(_DWORD *)arglist; +LABEL_11: + M_StartDelay(v18, v17); + goto LABEL_49; + } + } + v19 = abs(v7); + v21 = v20; + if ( v19 >= 3 || (v22 = abs(v10), v21 = v23, v22 >= 3) ) + { + v24 = *(_DWORD *)arglist; + } + else + { + v24 = *(_DWORD *)arglist; + _LOBYTE(v25) = LineClearF1( + (unsigned char (__cdecl *)())PosOkMonst, + *(int *)arglist, + esi3->_mx, + esi3->_my, + v1, + v2); + if ( v25 && esi3->_mVar1 != 14 ) + { + if ( AddMissile(esi3->_mx, esi3->_my, v1, v2, midir, 20, micaster, *(int *)arglist, 0, 0) != -1 ) + { + PlayEffect(*(int *)arglist, 0); + v26 = esi3->_my + 112 * esi3->_mx; + esi3->_mmode = 14; + dMonster[0][v26] = -1 - v24; + } + goto LABEL_49; + } + } + if ( esi3->_mVar1 != 13 ) + { + _LOBYTE(v21) = 106; + v27 = random(v21, 100); + v28 = 2 * (unsigned char)esi3->_mint; + if ( v27 < 35 - v28 ) + { + _LOBYTE(v28) = 106; + v17 = 15 - (unsigned char)esi3->_mint + random(v28, 10); + v18 = v24; + goto LABEL_11; + } + } + v29 = esi3->_mgoalvar1; + v30 = midir + *(&v37 + v29); + if ( v30 >= 0 ) + { + v31 = v30 - 8; + if ( v30 < 8 ) + v31 = midir + *(&v37 + v29); + } + else + { + v31 = v30 + 8; + } + esi3->_mgoalvar1 = v29 + 1; + if ( v29 + 1 > 5 ) + esi3->_mgoalvar1 = 0; + v32 = esi3->_mgoalvar2; + v33 = v31 - v32; + if ( v31 - v32 >= 0 ) + { + if ( v33 >= 8 ) + v33 -= 8; + } + else + { + v33 += 8; + } + if ( v33 <= 0 ) + { +LABEL_47: + _LOBYTE(v36) = M_DumbWalk(v24, esi3->_mgoalvar2); + if ( !v36 ) + M_CallWalk2(v24, esi3->_mdir); + goto LABEL_49; + } + if ( v33 >= 4 ) + { + if ( v33 == 4 ) + { + esi3->_mgoalvar2 = v31; + goto LABEL_47; + } + v34 = v32 - 1; + if ( v32 - 1 < 0 ) + { + v35 = v32 + 7; + goto LABEL_46; + } + if ( v34 >= 8 ) + { + v35 = v32 - 9; + goto LABEL_46; + } + } + else + { + v34 = v32 + 1; + if ( v32 + 1 < 0 ) + { + v35 = v32 + 9; +LABEL_46: + esi3->_mgoalvar2 = v35; + goto LABEL_47; + } + if ( v34 >= 8 ) + { + v35 = v32 - 7; + goto LABEL_46; + } + } + v35 = v34; + goto LABEL_46; + } +} + +//----- (0043668F) -------------------------------------------------------- +void __fastcall MAI_Bat(int i) +{ + int esi1; // esi + MonsterStruct *esi3; // esi + int v3; // ecx + int v4; // edx + int v5; // edi + int v6; // ebx + int v7; // eax + int v8; // ecx + int v9; // ecx + int v10; // edx + int v11; // eax + int v12; // ecx + int v13; // ecx + CMonster *v14; // eax + int v15; // edi + int v16; // eax + signed int v17; // ecx + int v18; // eax + int micaster; // [esp+Ch] [ebp-18h] + int v1; // [esp+10h] [ebp-14h] + int v2; // [esp+14h] [ebp-10h] + int v22; // [esp+18h] [ebp-Ch] + int midir; // [esp+1Ch] [ebp-8h] + int arglist; // [esp+20h] [ebp-4h] + + esi1 = i; + arglist = i; + if ( (unsigned int)i >= 0xC8 ) + TermMsg("MAI_Bat: Invalid monster %d", i); + esi3 = &monster[esi1]; + micaster = esi3->_menemy; + if ( esi3->_mmode == MM_STAND && _LOBYTE(esi3->_msquelch) ) + { + v3 = esi3->_mx; + v4 = esi3->_my; + v5 = v3 - (unsigned char)esi3->_menemyx; + v6 = v4 - (unsigned char)esi3->_menemyy; + v7 = GetDirection(v3, v4, esi3->_lastx, esi3->_lasty); + _LOBYTE(v8) = 107; + midir = v7; + esi3->_mdir = v7; + v22 = random(v8, 100); + if ( _LOBYTE(esi3->_mgoal) == 2 ) + { + if ( esi3->_mgoalvar1 ) + { + _LOBYTE(v9) = 108; + if ( random(v9, 2) ) + v10 = left[midir]; + else + v10 = right[midir]; + M_CallWalk(arglist, v10); + _LOBYTE(esi3->_mgoal) = 1; + } + else + { + M_CallWalk(arglist, opposite[midir]); + ++esi3->_mgoalvar1; + } + } + else + { + v1 = (unsigned char)esi3->_menemyx; + v2 = (unsigned char)esi3->_menemyy; + if ( esi3->MType->mtype == MON_BATC + && (abs(v5) >= 5 || abs(v6) >= 5) + && v22 < 4 * (unsigned char)esi3->_mint + 33 + && (_LOBYTE(v11) = LineClearF1( + (unsigned char (__cdecl *)())PosOkMonst, + arglist, + esi3->_mx, + esi3->_my, + v1, + v2), + v11) ) + { + if ( AddMissile(esi3->_mx, esi3->_my, v1, v2, midir, 20, micaster, arglist, 0, 0) != -1 ) + { + v12 = esi3->_my + 112 * esi3->_mx; + esi3->_mmode = 14; + dMonster[0][v12] = -1 - arglist; + } + } + else if ( abs(v5) >= 2 || abs(v6) >= 2 ) + { + v17 = esi3->_mVar2; + if ( v17 > 20 && v22 < (unsigned char)esi3->_mint + 13 + || ((v18 = esi3->_mVar1, v18 == 1) || v18 == 2 || v18 == 3) + && !v17 + && v22 < (unsigned char)esi3->_mint + 63 ) + { + M_CallWalk(arglist, midir); + } + } + else if ( v22 < 4 * (unsigned char)esi3->_mint + 8 ) + { + M_StartAttack(arglist); + v14 = esi3->MType; + esi3->_mgoalvar1 = 0; + _LOBYTE(esi3->_mgoal) = 2; + if ( v14->mtype == 41 ) + { + v15 = (unsigned char)esi3->_menemyx; + _LOBYTE(v13) = 109; + v16 = random(v13, 10); + AddMissile(v15, (unsigned char)esi3->_menemyy, v15 + 1, 0, -1, 8, 1, arglist, v16 + 1, 0); + } + } + if ( esi3->_mmode == MM_STAND ) + esi3->_mAFNum = esi3->MType->Anims[0].Frames[midir + 1]; + } + } +} + +//----- (004368F7) -------------------------------------------------------- +void __fastcall MAI_SkelBow(int i) +{ + int v1; // esi + MonsterStruct *v2; // esi + int v3; // edi + int v4; // ebx + int v5; // eax + int v6; // ecx + int v7; // eax + int v8; // ST04_4 + int v9; // ecx + int v10; // eax + int v11; // ST04_4 + int v12; // eax + int v13; // eax + int v14; // edi + int v15; // ebx + int v16; // eax + int v17; // [esp+4h] [ebp-10h] + int v18; // [esp+8h] [ebp-Ch] + int v19; // [esp+Ch] [ebp-8h] + int arglist; // [esp+10h] [ebp-4h] + + v18 = 0; + v1 = i; + arglist = i; + if ( (unsigned int)i >= 0xC8 ) + TermMsg("MAI_SkelBow: Invalid monster %d", i); + v2 = &monster[v1]; + if ( v2->_mmode == MM_STAND && _LOBYTE(v2->_msquelch) ) + { + v3 = v2->_mx - (unsigned char)v2->_menemyx; + v4 = v2->_my - (unsigned char)v2->_menemyy; + v5 = M_GetDir(arglist); + _LOBYTE(v6) = 110; + v17 = v5; + v2->_mdir = v5; + v19 = random(v6, 100); + v7 = abs(v3); + v9 = v8; + if ( v7 < 4 ) + { + v10 = abs(v4); + v9 = v11; + if ( v10 < 4 ) + { + if ( (v9 = v2->_mVar2, v9 > 20) && v19 < 2 * (unsigned char)v2->_mint + 13 + || ((v12 = v2->_mVar1, v12 == 1) || v12 == 2 || v12 == 3) + && !v9 + && v19 < 2 * (unsigned char)v2->_mint + 63 ) + { + _LOBYTE(v13) = M_DumbWalk(arglist, opposite[v17]); + v18 = v13; + } + } + } + v14 = (unsigned char)v2->_menemyx; + v15 = (unsigned char)v2->_menemyy; + if ( !v18 ) + { + _LOBYTE(v9) = 110; + if ( random(v9, 100) < 2 * (unsigned char)v2->_mint + 3 ) + { + _LOBYTE(v16) = LineClear(v2->_mx, v2->_my, v14, v15); + if ( v16 ) + M_StartRAttack(arglist, 0, 4); + } + } + if ( v2->_mmode == MM_STAND ) + v2->_mAFNum = v2->MType->Anims[0].Frames[v17 + 1]; + } +} + +//----- (00436A38) -------------------------------------------------------- +void __fastcall MAI_Fat(int i) +{ + int v1; // esi + MonsterStruct *v2; // esi + int v3; // edi + int v4; // ebx + int v5; // eax + int v6; // ecx + int v7; // eax + signed int v8; // ecx + int v9; // eax + int md; // [esp+4h] [ebp-Ch] + int arglist; // [esp+8h] [ebp-8h] + int v12; // [esp+Ch] [ebp-4h] + + v1 = i; + arglist = i; + if ( (unsigned int)i >= 0xC8 ) + TermMsg("MAI_Fat: Invalid monster %d", i); + v2 = &monster[v1]; + if ( v2->_mmode == MM_STAND && _LOBYTE(v2->_msquelch) ) + { + v3 = v2->_mx - (unsigned char)v2->_menemyx; + v4 = v2->_my - (unsigned char)v2->_menemyy; + v5 = M_GetDir(arglist); + _LOBYTE(v6) = 111; + md = v5; + v2->_mdir = v5; + v12 = random(v6, 100); + if ( abs(v3) >= 2 || abs(v4) >= 2 ) + { + v8 = v2->_mVar2; + if ( v8 > 20 && v12 < 4 * (unsigned char)v2->_mint + 20 + || ((v9 = v2->_mVar1, v9 == 1) || v9 == 2 || v9 == 3) && !v8 && v12 < 4 * (unsigned char)v2->_mint + 70 ) + { + M_CallWalk(arglist, md); + } + } + else + { + v7 = (unsigned char)v2->_mint; + if ( v12 >= 4 * v7 + 15 ) + { + if ( v12 < 4 * v7 + 20 ) + M_StartSpAttack(arglist); + } + else + { + M_StartAttack(arglist); + } + } + if ( v2->_mmode == MM_STAND ) + v2->_mAFNum = v2->MType->Anims[0].Frames[md + 1]; + } +} + +//----- (00436B60) -------------------------------------------------------- +void __fastcall MAI_Sneak(int i) +{ + int v1; // edi + MonsterStruct *v2; // esi + int v3; // ebx + int v4; // ebx + int v5; // ecx + int v6; // edi + int v7; // eax + int v8; // ST04_4 + int v9; // eax + int v10; // ST04_4 + int v11; // eax + int v12; // edi + signed int v13; // ecx + int v14; // eax + int v15; // [esp+Ch] [ebp-10h] + int arglist; // [esp+10h] [ebp-Ch] + int v17; // [esp+14h] [ebp-8h] + int md; // [esp+18h] [ebp-4h] + + v1 = i; + arglist = i; + if ( (unsigned int)i >= 0xC8 ) + TermMsg("MAI_Sneak: Invalid monster %d", i); + v2 = &monster[v1]; + if ( v2->_mmode == MM_STAND ) + { + v3 = v2->_my; + if ( dTransVal[v2->_mx][v3] != lightmax ) + { + v17 = v2->_mx - (unsigned char)v2->_menemyx; + v4 = v3 - (unsigned char)v2->_menemyy; + md = M_GetDir(v1); + v6 = 5 - (unsigned char)v2->_mint; + if ( v2->_mVar1 == 5 ) + { + v2->_mgoalvar1 = 0; + _LOBYTE(v2->_mgoal) = 2; + } + else + { + v7 = abs(v17); + v5 = v8; + if ( v7 >= v6 + 3 || (v9 = abs(v4), v5 = v10, v9 >= v6 + 3) || v2->_mgoalvar1 > 8 ) + { + v2->_mgoalvar1 = 0; + _LOBYTE(v2->_mgoal) = 1; + } + } + if ( _LOBYTE(v2->_mgoal) == 2 ) + { + if ( v2->_mFlags & 0x10 ) + md = GetDirection(v2->_mx, v2->_my, plr[v2->_menemy]._pownerx, plr[v2->_menemy]._pownery); + md = opposite[md]; + if ( v2->MType->mtype == MON_SNEAKC ) + { + _LOBYTE(v5) = 112; + if ( random(v5, 2) ) + v11 = left[md]; + else + v11 = right[md]; + md = v11; + } + } + _LOBYTE(v5) = 112; + v2->_mdir = md; + v15 = random(v5, 100); + if ( abs(v17) < v6 && abs(v4) < v6 && v2->_mFlags & 1 ) + { + M_StartFadein(arglist, md, 0); + } + else + { + v12 = v6 + 1; + if ( abs(v17) < v12 && abs(v4) < v12 || v2->_mFlags & 1 ) + { + if ( _LOBYTE(v2->_mgoal) == 2 + || (abs(v17) >= 2 || abs(v4) >= 2) + && ((v13 = v2->_mVar2, v13 > 20) && v15 < 4 * (unsigned char)v2->_mint + 14 + || ((v14 = v2->_mVar1, v14 == 1) || v14 == 2 || v14 == 3) + && !v13 + && v15 < 4 * (unsigned char)v2->_mint + 64) ) + { + ++v2->_mgoalvar1; + M_CallWalk(arglist, md); + } + } + else + { + M_StartFadeout(arglist, md, 1u); + } + } + if ( v2->_mmode == MM_STAND ) + { + if ( abs(v17) >= 2 || abs(v4) >= 2 || v15 >= 4 * (unsigned char)v2->_mint + 10 ) + v2->_mAFNum = v2->MType->Anims[0].Frames[md + 1]; + else + M_StartAttack(arglist); + } + } + } +} +// 642A14: using guessed type char lightmax; + +//----- (00436DC8) -------------------------------------------------------- +void __fastcall MAI_Fireman(int i) +{ + int esi1; // esi + int esi3; // esi + int v3; // ecx + int v4; // eax + int v5; // ebx + int v6; // edi + int v7; // edx + int v8; // ecx + char v9; // al + int v10; // eax + int v11; // eax + int v12; // ecx + int v13; // eax + int v14; // eax + int v15; // edx + int v16; // eax + int v17; // eax + int micaster; // [esp+Ch] [ebp-14h] + int v1; // [esp+10h] [ebp-10h] + int v2; // [esp+14h] [ebp-Ch] + int midir; // [esp+18h] [ebp-8h] + int arglist; // [esp+1Ch] [ebp-4h] + + esi1 = i; + arglist = i; + if ( (unsigned int)i >= 0xC8 ) + TermMsg("MAI_Fireman: Invalid monster %d", i); + esi3 = esi1; + if ( monster[esi3]._mmode || !_LOBYTE(monster[esi3]._msquelch) ) + return; + v3 = (unsigned char)monster[esi3]._menemyy; + micaster = monster[esi3]._menemy; + v4 = (unsigned char)monster[esi3]._menemyx; + v2 = v3; + v5 = monster[esi3]._my - v3; + v1 = v4; + v6 = monster[esi3]._mx - v4; + v7 = M_GetDir(arglist); + v9 = monster[esi3]._mgoal; + midir = v7; + switch ( v9 ) + { + case 1: + _LOBYTE(v10) = LineClear(monster[esi3]._mx, monster[esi3]._my, v1, v2); + if ( !v10 + || AddMissile(monster[esi3]._mx, monster[esi3]._my, v1, v2, midir, 50, micaster, arglist, 0, 0) == -1 ) + { + break; + } + monster[esi3]._mgoalvar1 = 0; + monster[esi3]._mmode = MM_CHARGE; + goto LABEL_18; + case 5: + if ( monster[esi3]._mgoalvar1 == 3 ) + { + _LOBYTE(monster[esi3]._mgoal) = 1; + M_StartFadeout(arglist, v7, 1u); + } + else + { + _LOBYTE(v11) = LineClear(monster[esi3]._mx, monster[esi3]._my, v1, v2); + if ( v11 ) + { + M_StartRAttack(arglist, 51, 4); + } + else + { + _LOBYTE(v12) = 112; + v13 = random(v12, 10); + M_StartDelay(arglist, v13 + 5); + } + ++monster[esi3]._mgoalvar1; + } + break; + case 2: + M_StartFadein(arglist, v7, 0); +LABEL_18: + _LOBYTE(monster[esi3]._mgoal) = 5; + break; + } + _LOBYTE(v8) = 112; + monster[esi3]._mdir = midir; + random(v8, 100); + if ( monster[esi3]._mmode ) + return; + if ( abs(v6) < 2 && abs(v5) < 2 && _LOBYTE(monster[esi3]._mgoal) == 1 ) + { + M_TryH2HHit( + arglist, + monster[esi3]._menemy, + (unsigned char)monster[esi3].mHit, + (unsigned char)monster[esi3].mMinDamage, + (unsigned char)monster[esi3].mMaxDamage); + _LOBYTE(monster[esi3]._mgoal) = 2; + _LOBYTE(v14) = M_CallWalk(arglist, opposite[midir]); + if ( v14 ) + return; + v15 = midir; + goto LABEL_29; + } + _LOBYTE(v16) = M_CallWalk(arglist, midir); + if ( !v16 ) + { + v17 = _LOBYTE(monster[esi3]._mgoal); + if ( (_BYTE)v17 == 1 || (_BYTE)v17 == 2 ) + { + v15 = midir; +LABEL_29: + M_StartFadein(arglist, v15, 0); + _LOBYTE(monster[esi3]._mgoal) = 5; + return; + } + } +} + +//----- (00436FEC) -------------------------------------------------------- +void __fastcall MAI_Fallen(int i) +{ + int v1; // edi + int v2; // ST04_4 + int v3; // esi + int v4; // eax + int v5; // ecx + int *v6; // eax + int v7; // edx + int v8; // edx + int j; // edi + int k; // ecx + int v11; // eax + int v12; // eax + char v13; // al + int v14; // edx + int v15; // eax + int v16; // esi + + v1 = i; + if ( (unsigned int)i >= 0xC8 ) + { + TermMsg("MAI_Fallen: Invalid monster %d", i); + i = v2; + } + v3 = v1; + if ( _LOBYTE(monster[v1]._mgoal) == 5 ) + { + i = monster[v3]._mgoalvar1; + if ( i ) + monster[v3]._mgoalvar1 = --i; + else + _LOBYTE(monster[v3]._mgoal) = 1; + } + if ( monster[v3]._mmode == MM_STAND && _LOBYTE(monster[v3]._msquelch) ) + { + if ( _LOBYTE(monster[v3]._mgoal) == 2 ) + { + i = monster[v3]._mgoalvar1; + monster[v3]._mgoalvar1 = i - 1; + if ( !i ) + { + v4 = monster[v3]._mdir; + _LOBYTE(monster[v3]._mgoal) = 1; + M_StartStand(v1, opposite[v4]); + } + } + if ( monster[v3]._mAnimFrame != monster[v3]._mAnimLen ) + { + v13 = monster[v3]._mgoal; + if ( v13 == 2 ) + { + v14 = monster[v3]._mdir; + } + else + { + if ( v13 != 5 ) + { + MAI_SkelSd(v1); + return; + } + v15 = monster[v3]._mx - (unsigned char)monster[v3]._menemyx; + v16 = monster[v3]._my - (unsigned char)monster[v3]._menemyy; + if ( abs(v15) < 2 && abs(v16) < 2 ) + { + M_StartAttack(v1); + return; + } + v14 = M_GetDir(v1); + } + M_CallWalk(v1, v14); + return; + } + _LOBYTE(i) = 113; + if ( !random(i, 4) ) + { + if ( !(monster[v3]._mFlags & 8) ) + { + M_StartSpStand(v1, monster[v3]._mdir); + v5 = 2 * (unsigned char)monster[v3]._mint + 2; + v6 = &monster[v3]._mhitpoints; + v7 = monster[v3]._mhitpoints; + if ( monster[v3]._mmaxhp - v5 < v7 ) + *v6 = monster[v3]._mmaxhp; + else + *v6 = v5 + v7; + } + v8 = 2 * (unsigned char)monster[v3]._mint + 4; + for ( j = -v8; j <= v8; ++j ) + { + for ( k = -v8; k <= v8; ++k ) + { + if ( j >= 0 && j < 112 && k >= 0 && k < 112 ) + { + v11 = dMonster[0][j + monster[v3]._my + 112 * (k + monster[v3]._mx)]; + if ( v11 > 0 ) + { + v12 = v11 - 1; + if ( monster[v12]._mAi == MG_FALLEN ) + { + _LOBYTE(monster[v12]._mgoal) = 5; + monster[v12]._mgoalvar1 = 30 * (unsigned char)monster[v3]._mint + 105; + } + } + } + } + } + } + } +} + +//----- (004371D7) -------------------------------------------------------- +void __fastcall MAI_Cleaver(int i) +{ + int v1; // esi + MonsterStruct *v2; // esi + int v3; // ecx + int v4; // edx + int v5; // edi + int v6; // ebp + int v7; // ebx + int arglist; // [esp+8h] [ebp-4h] + + v1 = i; + arglist = i; + if ( (unsigned int)i >= 0xC8 ) + TermMsg("MAI_Cleaver: Invalid monster %d", i); + v2 = &monster[v1]; + if ( v2->_mmode == MM_STAND && _LOBYTE(v2->_msquelch) ) + { + v3 = v2->_mx; + v4 = v2->_my; + v5 = v3 - (unsigned char)v2->_menemyx; + v6 = v4 - (unsigned char)v2->_menemyy; + v7 = GetDirection(v3, v4, v2->_lastx, v2->_lasty); + v2->_mdir = v7; + if ( abs(v5) >= 2 || abs(v6) >= 2 ) + M_CallWalk(arglist, v7); + else + M_StartAttack(arglist); + if ( v2->_mmode == MM_STAND ) + v2->_mAFNum = v2->MType->Anims[0].Frames[v7 + 1]; + } +} + +//----- (00437285) -------------------------------------------------------- +void __fastcall MAI_Round(int i, unsigned char special) +{ + int v2; // esi + MonsterStruct *v3; // esi + int v4; // edx + int v5; // ecx + int v6; // edi + int v7; // ebx + int v8; // ecx + int v9; // eax + int v10; // ST04_4 + int v11; // ecx + int v12; // eax + int v13; // ST04_4 + int v14; // ecx + int v15; // edi + int v16; // eax + int v17; // ecx + int v18; // eax + int v19; // eax + int v20; // ecx + int v21; // eax + int v22; // eax + int v23; // ST04_4 + int v24; // ecx + signed int v25; // ecx + int v26; // eax + int v27; // [esp+4h] [ebp-18h] + int v28; // [esp+8h] [ebp-14h] + char *v29; // [esp+8h] [ebp-14h] + int v30; // [esp+Ch] [ebp-10h] + int md; // [esp+10h] [ebp-Ch] + int v32; // [esp+14h] [ebp-8h] + int arglist; // [esp+18h] [ebp-4h] + + v2 = i; + v27 = special; + arglist = i; + if ( (unsigned int)i >= 0xC8 ) + TermMsg("MAI_Round: Invalid monster %d", i); + v3 = &monster[v2]; + if ( v3->_mmode == MM_STAND && _LOBYTE(v3->_msquelch) ) + { + v4 = v3->_my; + v5 = v3->_mx; + v28 = (unsigned char)v3->_menemyy; + v6 = (unsigned char)v3->_menemyx; + v7 = v5 - v6; + v32 = v4 - v28; + md = GetDirection(v5, v4, v3->_lastx, v3->_lasty); + if ( _LOBYTE(v3->_msquelch) < 0xFFu ) + MonstCheckDoors(arglist); + _LOBYTE(v8) = 114; + v30 = random(v8, 100); + if ( (abs(v7) >= 2 || abs(v32) >= 2) && _LOBYTE(v3->_msquelch) == -1 ) + { + v29 = &dung_map[v6][v28]; + if ( dung_map[v3->_mx][v3->_my] == *v29 ) + { + if ( _LOBYTE(v3->_mgoal) != 4 ) + { + v9 = abs(v7); + v11 = v10; + if ( v9 < 4 ) + { + v12 = abs(v32); + v11 = v13; + if ( v12 < 4 ) + goto LABEL_26; + } + _LOBYTE(v11) = 115; + if ( random(v11, 4) ) + goto LABEL_26; + if ( _LOBYTE(v3->_mgoal) != 4 ) + { + v3->_mgoalvar1 = 0; + _LOBYTE(v14) = 116; + v3->_mgoalvar2 = random(v14, 2); + } + } + _LOBYTE(v3->_mgoal) = 4; + v15 = abs(v32); + if ( abs(v7) <= v15 ) + v16 = abs(v32); + else + v16 = abs(v7); + v17 = v3->_mgoalvar1; + v3->_mgoalvar1 = v17 + 1; + if ( v17 < 2 * v16 || (_LOBYTE(v18) = DirOK(arglist, md), !v18) ) + { + if ( dung_map[v3->_mx][v3->_my] == *v29 ) + { + _LOBYTE(v19) = M_RoundWalk(arglist, md, &v3->_mgoalvar2); + if ( !v19 ) + { + _LOBYTE(v20) = 125; + v21 = random(v20, 10); + M_StartDelay(arglist, v21 + 10); + } + goto LABEL_26; + } + } + } + } + _LOBYTE(v3->_mgoal) = 1; +LABEL_26: + if ( _LOBYTE(v3->_mgoal) == 1 ) + { + if ( abs(v7) >= 2 || (v22 = abs(v32), v24 = v23, v22 >= 2) ) + { + v25 = v3->_mVar2; + if ( v25 > 20 && v30 < 2 * (unsigned char)v3->_mint + 28 + || ((v26 = v3->_mVar1, v26 == 1) || v26 == 2 || v26 == 3) + && !v25 + && v30 < 2 * (unsigned char)v3->_mint + 78 ) + { + M_CallWalk(arglist, md); + } + } + else if ( v30 < 2 * (unsigned char)v3->_mint + 23 ) + { + v3->_mdir = md; + if ( v27 && v3->_mhitpoints < v3->_mmaxhp >> 1 && (_LOBYTE(v24) = 117, random(v24, 2)) ) + M_StartSpAttack(arglist); + else + M_StartAttack(arglist); + } + } + if ( v3->_mmode == MM_STAND ) + v3->_mAFNum = v3->MType->Anims[0].Frames[md + 1]; + } +} + +//----- (00437520) -------------------------------------------------------- +void __fastcall MAI_GoatMc(int i) +{ + MAI_Round(i, 1u); +} + +//----- (00437528) -------------------------------------------------------- +void __fastcall MAI_Ranged(int i, int missile_type, unsigned char special) +{ + int v3; // edi + int v4; // esi + char v5; // al + int v6; // eax + int v7; // ecx + int v8; // ebx + int v9; // edi + int v10; // ecx + bool v11; // zf + int v12; // eax + int v13; // eax + int v14; // ST00_4 + int v15; // ecx + int v16; // eax + int x2; // [esp+8h] [ebp-14h] + int y2; // [esp+Ch] [ebp-10h] + int missile_typea; // [esp+10h] [ebp-Ch] + int v20; // [esp+14h] [ebp-8h] + int arglist; // [esp+18h] [ebp-4h] + + v3 = i; + missile_typea = missile_type; + arglist = i; + if ( (unsigned int)i >= 0xC8 ) + TermMsg("MAI_Ranged: Invalid monster %d", i); + v4 = v3; + if ( monster[v3]._mmode == MM_STAND ) + { + v5 = monster[v4]._msquelch; + if ( v5 == -1 || monster[v4]._mFlags & 0x10 ) + { + v7 = (unsigned char)monster[v4]._menemyy; + y2 = v7; + v8 = monster[v4]._my - v7; + x2 = (unsigned char)monster[v4]._menemyx; + v9 = monster[v4]._mx - x2; + v20 = M_GetDir(arglist); + if ( _LOBYTE(monster[v4]._msquelch) < 0xFFu ) + MonstCheckDoors(arglist); + v11 = monster[v4]._mVar1 == 10; + monster[v4]._mdir = v20; + if ( v11 ) + { + _LOBYTE(v10) = 118; + v12 = random(v10, 20); + M_StartDelay(arglist, v12); + } + else if ( abs(v9) < 4 ) + { + v13 = abs(v8); + v15 = v14; + if ( v13 < 4 ) + { + _LOBYTE(v15) = 119; + if ( random(v15, 100) < 10 * ((unsigned char)monster[v4]._mint + 7) ) + M_CallWalk(arglist, opposite[v20]); + } + } + if ( monster[v4]._mmode == MM_STAND ) + { + _LOBYTE(v16) = LineClear(monster[v4]._mx, monster[v4]._my, x2, y2); + if ( v16 ) + { + if ( special ) + M_StartRSpAttack(arglist, missile_typea, 4); + else + M_StartRAttack(arglist, missile_typea, 4); + } + else + { + monster[v4]._mAFNum = monster[v4].MType->Anims[0].Frames[v20 + 1]; + } + } + } + else if ( v5 ) + { + v6 = GetDirection(monster[v4]._mx, monster[v4]._my, monster[v4]._lastx, monster[v4]._lasty); + M_CallWalk(v3, v6); + } + } +} + +//----- (004376B3) -------------------------------------------------------- +void __fastcall MAI_GoatBow(int i) +{ + MAI_Ranged(i, 0, 0); +} + +//----- (004376BD) -------------------------------------------------------- +void __fastcall MAI_Succ(int i) +{ + MAI_Ranged(i, 24, 0); +} + +//----- (004376C8) -------------------------------------------------------- +void __fastcall MAI_AcidUniq(int i) +{ + MAI_Ranged(i, 57, 1u); +} + +//----- (004376D3) -------------------------------------------------------- +void __fastcall MAI_Scav(int i) +{ + int v1; // edi + int v2; // esi + char *v3; // eax + int v4; // ecx + int v5; // ecx + signed int v6; // ebx + signed int v7; // edi + int v8; // edx + int v9; // eax + int v10; // eax + int v11; // ebx + int v12; // edi + signed int v13; // edi + int v14; // edx + int v15; // eax + int v16; // eax + int v17; // eax + int v18; // eax + int arglist; // [esp+Ch] [ebp-8h] + BOOL v20; // [esp+10h] [ebp-4h] + + v1 = i; + arglist = i; + if ( (unsigned int)i >= 0xC8 ) + TermMsg("MAI_Scav: Invalid monster %d", i); + v2 = v1; + v20 = 0; + if ( monster[v1]._mmode == MM_STAND ) + { + if ( monster[v2]._mhitpoints < monster[v2]._mmaxhp >> 1 ) + { + if ( _LOBYTE(monster[v2]._mgoal) == 3 ) + goto LABEL_10; + if ( monster[v2].leaderflag ) + { + v3 = &monster[(unsigned char)monster[v2].leader].unpackfilesize; + --*v3; + monster[v2].leaderflag = 0; + } + _LOBYTE(monster[v2]._mgoal) = 3; + monster[v2]._mgoalvar3 = 10; + } + if ( _LOBYTE(monster[v2]._mgoal) != 3 ) + { +LABEL_52: + if ( monster[v2]._mmode == MM_STAND ) + MAI_SkelSd(arglist); + return; + } +LABEL_10: + v4 = monster[v2]._mgoalvar3; + if ( v4 ) + { + monster[v2]._mgoalvar3 = v4 - 1; + v5 = monster[v2]._my; + if ( dDead[monster[v2]._mx][v5] ) + { + M_StartEat(v1); + if ( !(monster[v2]._mFlags & 8) ) + monster[v2]._mhitpoints += 64; + if ( monster[v2]._mhitpoints >= (monster[v2]._mmaxhp >> 1) + (monster[v2]._mmaxhp >> 2) ) + { + _LOBYTE(monster[v2]._mgoal) = 1; + monster[v2]._mgoalvar1 = 0; + monster[v2]._mgoalvar2 = 0; + } + } + else + { + if ( !monster[v2]._mgoalvar1 ) + { + _LOBYTE(v5) = 120; + v6 = arglist; + if ( random(v5, 2) ) + { + v7 = -4; + do + { + if ( v20 ) + break; + v6 = -4; + do + { + if ( v20 ) + break; + if ( v7 >= 0 && v7 < 112 && v6 >= 0 && v6 < 112 ) + { + v8 = monster[v2]._mx; + v9 = monster[v2]._my; + v20 = dDead[v8 + v6][v9 + v7] + && (_LOBYTE(v10) = LineClearF( + (unsigned char (__cdecl *)())CheckNoSolid, + v8, + v9, + v8 + v6, + v9 + v7), + v10); + } + ++v6; + } + while ( v6 <= 4 ); + ++v7; + } + while ( v7 <= 4 ); + v11 = v6 - 1; + v12 = v7 - 1; + } + else + { + v13 = 4; + do + { + if ( v20 ) + break; + v6 = 4; + do + { + if ( v20 ) + break; + if ( v13 >= 0 && v13 < 112 && v6 >= 0 && v6 < 112 ) + { + v14 = monster[v2]._mx; + v15 = monster[v2]._my; + v20 = dDead[v14 + v6][v15 + v13] + && (_LOBYTE(v16) = LineClearF( + (unsigned char (__cdecl *)())CheckNoSolid, + v14, + v15, + v14 + v6, + v15 + v13), + v16); + } + --v6; + } + while ( v6 >= -4 ); + --v13; + } + while ( v13 >= -4 ); + v11 = v6 + 1; + v12 = v13 + 1; + } + if ( v20 ) + { + monster[v2]._mgoalvar1 = monster[v2]._mx + v11 + 1; + monster[v2]._mgoalvar2 = monster[v2]._my + v12 + 1; + } + } + v17 = monster[v2]._mgoalvar1; + if ( v17 ) + { + v18 = GetDirection(monster[v2]._mx, monster[v2]._my, v17 - 1, monster[v2]._mgoalvar2 - 1); + monster[v2]._mdir = v18; + M_CallWalk(arglist, v18); + } + } + } + goto LABEL_52; + } +} + +//----- (00437957) -------------------------------------------------------- +void __fastcall MAI_Garg(int i) +{ + int v1; // ebp + MonsterStruct *v2; // esi + int v3; // edi + int v4; // ebx + char v5; // al + int v6; // edi + int v7; // eax + int v8; // [esp+10h] [ebp-4h] + + v1 = i; + if ( (unsigned int)i >= 0xC8 ) + TermMsg("MAI_Garg: Invalid monster %d", i); + v2 = &monster[v1]; + v3 = v2->_mx - v2->_lastx; + v4 = v2->_my - v2->_lasty; + v8 = M_GetDir(v1); + v5 = v2->_msquelch; + if ( v5 && v2->_mFlags & 4 ) + { + M_Enemy(v1); + v6 = v2->_my - (unsigned char)v2->_menemyy; + if ( abs(v2->_mx - (unsigned char)v2->_menemyx) < (unsigned char)v2->_mint + 2 + && abs(v6) < (unsigned char)v2->_mint + 2 ) + { + v2->_mFlags &= 0xFFFFFFFB; + } + } + else if ( v2->_mmode == MM_STAND && v5 ) + { + if ( v2->_mhitpoints < v2->_mmaxhp >> 1 && !(v2->_mFlags & 8) ) + _LOBYTE(v2->_mgoal) = 2; + if ( _LOBYTE(v2->_mgoal) == 2 ) + { + if ( abs(v3) >= (unsigned char)v2->_mint + 2 || abs(v4) >= (unsigned char)v2->_mint + 2 ) + { + _LOBYTE(v2->_mgoal) = 1; + M_StartHeal(v1); + } + else + { + _LOBYTE(v7) = M_CallWalk(v1, opposite[v8]); + if ( !v7 ) + _LOBYTE(v2->_mgoal) = 1; + } + } + MAI_Round(v1, 0); + } +} + +//----- (00437A8B) -------------------------------------------------------- +void __fastcall MAI_RoundRanged(int i, int missile_type, unsigned char checkdoors, int dam, int lessmissiles) +{ + int v5; // esi + MonsterStruct *v6; // esi + int v7; // edx + int v8; // ebx + int v9; // edi + int v10; // ecx + int v11; // eax + int v12; // ST04_4 + int v13; // ecx + int v14; // eax + int v15; // ST04_4 + int v16; // eax + int v17; // ST04_4 + int v18; // ecx + int v19; // ebx + int v20; // eax + int v21; // ecx + int v22; // eax + int v23; // eax + int v24; // eax + int v25; // eax + int v26; // ST04_4 + int v27; // eax + int v28; // ST04_4 + int v29; // eax + int v30; // edx + int v31; // eax + int missile_typea; // [esp+4h] [ebp-18h] + int v33; // [esp+8h] [ebp-14h] + int x2; // [esp+Ch] [ebp-10h] + int md; // [esp+10h] [ebp-Ch] + int y2; // [esp+14h] [ebp-8h] + int arglist; // [esp+18h] [ebp-4h] + int checkdoorsa; // [esp+24h] [ebp+8h] + + v5 = i; + missile_typea = missile_type; + arglist = i; + if ( (unsigned int)i >= 0xC8 ) + TermMsg("MAI_RoundRanged: Invalid monster %d", i); + v6 = &monster[v5]; + if ( v6->_mmode == MM_STAND && _LOBYTE(v6->_msquelch) ) + { + v7 = v6->_my; + y2 = (unsigned char)v6->_menemyy; + v8 = v7 - y2; + x2 = (unsigned char)v6->_menemyx; + v9 = v6->_mx - x2; + v33 = v7 - y2; + md = GetDirection(v6->_mx, v7, v6->_lastx, v6->_lasty); + if ( checkdoors && _LOBYTE(v6->_msquelch) < 0xFFu ) + MonstCheckDoors(arglist); + _LOBYTE(v10) = 121; + checkdoorsa = random(v10, 10000); + v11 = abs(v9); + v13 = v12; + if ( v11 < 2 ) + { + v14 = abs(v8); + v13 = v15; + if ( v14 < 2 ) + goto LABEL_50; + } + if ( _LOBYTE(v6->_msquelch) != -1 ) + goto LABEL_50; + v13 = y2; + if ( dung_map[v6->_mx][v6->_my] != dung_map[x2][y2] ) + goto LABEL_50; + if ( _LOBYTE(v6->_mgoal) != 4 ) + { + if ( abs(v9) < 3 ) + { + v16 = abs(v8); + v13 = v17; + if ( v16 < 3 ) + goto LABEL_28; + } + v18 = lessmissiles; + _LOBYTE(v18) = 122; + if ( random(v18, 4 << lessmissiles) ) + goto LABEL_28; + if ( _LOBYTE(v6->_mgoal) != 4 ) + { + v6->_mgoalvar1 = 0; + _LOBYTE(v13) = 123; + v6->_mgoalvar2 = random(v13, 2); + } + } + _LOBYTE(v6->_mgoal) = 4; + v19 = abs(v8); + if ( abs(v9) <= v19 ) + { + v8 = v33; + v20 = abs(v33); + } + else + { + v20 = abs(v9); + v8 = v33; + } + v21 = v6->_mgoalvar1; + v6->_mgoalvar1 = v21 + 1; + if ( v21 >= 2 * v20 && (_LOBYTE(v22) = DirOK(arglist, md), v22) ) + { +LABEL_50: + _LOBYTE(v6->_mgoal) = 1; + } + else if ( checkdoorsa < 500 * ((unsigned char)v6->_mint + 1) >> lessmissiles + && (_LOBYTE(v23) = LineClear(v6->_mx, v6->_my, x2, y2), v23) ) + { + M_StartRSpAttack(arglist, missile_typea, dam); + } + else + { + M_RoundWalk(arglist, md, &v6->_mgoalvar2); + } +LABEL_28: + if ( _LOBYTE(v6->_mgoal) == 1 ) + { + if ( ((abs(v9) >= 3 || abs(v8) >= 3) && checkdoorsa < 500 * ((unsigned char)v6->_mint + 2) >> lessmissiles + || checkdoorsa < 500 * ((unsigned char)v6->_mint + 1) >> lessmissiles) + && (_LOBYTE(v24) = LineClear(v6->_mx, v6->_my, x2, y2), v24) ) + { + M_StartRSpAttack(arglist, missile_typea, dam); + } + else + { + v25 = abs(v9); + v13 = v26; + if ( v25 >= 2 || (v27 = abs(v8), v13 = v28, v27 >= 2) ) + { + _LOBYTE(v13) = 124; + v29 = random(v13, 100); + v30 = (unsigned char)v6->_mint; + if ( v29 < 1000 * (v30 + 5) + || ((v13 = v6->_mVar1, v13 == 1) || v13 == 2 || v13 == 3) && !v6->_mVar2 && v29 < 1000 * (v30 + 8) ) + { + M_CallWalk(arglist, md); + } + } + else if ( checkdoorsa < 1000 * ((unsigned char)v6->_mint + 6) ) + { + v6->_mdir = md; + M_StartAttack(arglist); + } + } + } + if ( v6->_mmode == MM_STAND ) + { + _LOBYTE(v13) = 125; + v31 = random(v13, 10); + M_StartDelay(arglist, v31 + 5); + } + } +} + +//----- (00437D93) -------------------------------------------------------- +void __fastcall MAI_Magma(int i) +{ + MAI_RoundRanged(i, 21, 1u, 4, 0); +} + +//----- (00437DA2) -------------------------------------------------------- +void __fastcall MAI_Storm(int i) +{ + MAI_RoundRanged(i, 22, 1u, 4, 0); +} + +//----- (00437DB1) -------------------------------------------------------- +void __fastcall MAI_Acid(int i) +{ + MAI_RoundRanged(i, 57, 0, 4, 1); +} + +//----- (00437DC0) -------------------------------------------------------- +void __fastcall MAI_Diablo(int i) +{ + MAI_RoundRanged(i, 67, 0, 40, 0); +} + +//----- (00437DCF) -------------------------------------------------------- +void __fastcall MAI_RR2(int i, int mistype, int dam) +{ + int v3; // ebx + MonsterStruct *v4; // esi + int v5; // edi + int v6; // edx + int v7; // ebx + int v8; // edi + int v9; // ecx + int v10; // eax + int v11; // ST04_4 + int v12; // ecx + int v13; // eax + int v14; // ST04_4 + int v15; // eax + int v16; // ST04_4 + int v17; // eax + int v18; // ST04_4 + int v19; // ebx + int v20; // eax + int v21; // eax + int v22; // eax + int v23; // ecx + int v24; // eax + int v25; // ST04_4 + int v26; // ecx + int v27; // eax + int v28; // ST04_4 + int v29; // eax + int v30; // eax + int v31; // eax + int v32; // edx + int v33; // eax + int missile_type; // [esp+Ch] [ebp-1Ch] + int x2; // [esp+10h] [ebp-18h] + int v36; // [esp+14h] [ebp-14h] + int y2; // [esp+18h] [ebp-10h] + int v38; // [esp+1Ch] [ebp-Ch] + int md; // [esp+20h] [ebp-8h] + int arglist; // [esp+24h] [ebp-4h] + + v3 = i; + missile_type = mistype; + arglist = i; + if ( (unsigned int)i >= 0xC8 ) + TermMsg("MAI_RR2: Invalid monster %d", i); + v4 = &monster[v3]; + v5 = v4->_my - (unsigned char)v4->_menemyy; + if ( abs(v4->_mx - (unsigned char)v4->_menemyx) >= 5 || abs(v5) >= 5 ) + { + MAI_SkelSd(v3); + return; + } + if ( v4->_mmode == MM_STAND && _LOBYTE(v4->_msquelch) ) + { + v6 = v4->_my; + y2 = (unsigned char)v4->_menemyy; + v7 = v6 - y2; + x2 = (unsigned char)v4->_menemyx; + v8 = v4->_mx - x2; + v36 = v6 - y2; + md = GetDirection(v4->_mx, v6, v4->_lastx, v4->_lasty); + if ( _LOBYTE(v4->_msquelch) < 0xFFu ) + MonstCheckDoors(arglist); + _LOBYTE(v9) = 121; + v38 = random(v9, 100); + v10 = abs(v8); + v12 = v11; + if ( v10 >= 2 || (v13 = abs(v7), v12 = v14, v13 >= 2) ) + { + if ( _LOBYTE(v4->_msquelch) == -1 ) + { + v12 = y2; + if ( dung_map[v4->_mx][v4->_my] == dung_map[x2][y2] ) + { + if ( _LOBYTE(v4->_mgoal) != 4 ) + { + v15 = abs(v8); + v12 = v16; + if ( v15 < 3 ) + { + v17 = abs(v7); + v12 = v18; + if ( v17 < 3 ) + goto LABEL_26; + } + if ( _LOBYTE(v4->_mgoal) != 4 ) + { + v4->_mgoalvar1 = 0; + _LOBYTE(v12) = 123; + v4->_mgoalvar2 = random(v12, 2); + } + } + _LOBYTE(v4->_mgoal) = 4; + v4->_mgoalvar3 = 4; + v19 = abs(v7); + if ( abs(v8) <= v19 ) + { + v7 = v36; + v20 = abs(v36); + } + else + { + v20 = abs(v8); + v7 = v36; + } + v12 = v4->_mgoalvar1; + v4->_mgoalvar1 = v12 + 1; + if ( v12 < 2 * v20 || (_LOBYTE(v21) = DirOK(arglist, md), !v21) ) + { + if ( v38 < 5 * ((unsigned char)v4->_mint + 16) ) + M_RoundWalk(arglist, md, &v4->_mgoalvar2); +LABEL_26: + if ( _LOBYTE(v4->_mgoal) != 1 ) + goto LABEL_48; + if ( ((abs(v8) >= 3 || abs(v7) >= 3) && v38 < 5 * ((unsigned char)v4->_mint + 2) + || v38 < 5 * ((unsigned char)v4->_mint + 1) + || v4->_mgoalvar3 == 4) + && (_LOBYTE(v22) = LineClear(v4->_mx, v4->_my, x2, y2), v22) ) + { + v23 = arglist; + } + else + { + v24 = abs(v8); + v26 = v25; + if ( v24 >= 2 || (v27 = abs(v7), v26 = v28, v27 >= 2) ) + { + _LOBYTE(v26) = 124; + v31 = random(v26, 100); + v12 = (unsigned char)v4->_mint; + if ( v31 < 2 * (5 * v12 + 25) + || ((v32 = v4->_mVar1, v32 == 1) || v32 == 2 || v32 == 3) + && !v4->_mVar2 + && (v12 = 2 * (5 * v12 + 40), v31 < v12) ) + { + M_CallWalk(arglist, md); + } + goto LABEL_47; + } + _LOBYTE(v26) = 124; + v29 = random(v26, 100); + v12 = 10 * ((unsigned char)v4->_mint + 4); + if ( v29 >= v12 ) + { +LABEL_47: + v4->_mgoalvar3 = 1; +LABEL_48: + if ( v4->_mmode == MM_STAND ) + { + _LOBYTE(v12) = 125; + v33 = random(v12, 10); + M_StartDelay(arglist, v33 + 5); + } + return; + } + _LOBYTE(v12) = 124; + v4->_mdir = md; + v30 = random(v12, 2); + v23 = arglist; + if ( v30 ) + { + M_StartAttack(arglist); + goto LABEL_47; + } + } + M_StartRSpAttack(v23, missile_type, dam); + goto LABEL_47; + } + } + } + } + _LOBYTE(v4->_mgoal) = 1; + goto LABEL_26; + } +} + +//----- (004380DE) -------------------------------------------------------- +void __fastcall MAI_Mega(int i) +{ + MAI_RR2(i, 49, 0); +} + +//----- (004380E9) -------------------------------------------------------- +void __fastcall MAI_Golum(int i) +{ + int v1; // edi + int v2; // esi + int v3; // eax + int v4; // eax + int v5; // edx + int v6; // edi + int v7; // ebx + int v8; // eax + char v9; // cl + int *v10; // eax + signed int v11; // edx + signed int v12; // ecx + int v13; // eax + int v14; // eax + int *v15; // esi + int v16; // eax + int v17; // esi + int v18; // edi + int v19; // [esp+Ch] [ebp-Ch] + unsigned int v20; // [esp+10h] [ebp-8h] + int arglist; // [esp+14h] [ebp-4h] + + v1 = i; + arglist = i; + if ( (unsigned int)i >= 0xC8 ) + TermMsg("MAI_Golum: Invalid monster %d", i); + v2 = v1; + if ( monster[v1]._mx != 1 || monster[v2]._my ) + { + v3 = monster[v2]._mmode; + if ( v3 != MM_DEATH && v3 != MM_SPSTAND && (v3 < MM_WALK || v3 > MM_WALK3) ) + { + if ( !(monster[v2]._mFlags & 0x10) ) + M_Enemy(v1); + v20 = ((unsigned int)~monster[v2]._mFlags >> 10) & 1; + if ( monster[v2]._mmode != MM_ATTACK ) + { + v4 = monster[v2]._menemy; + v5 = monster[v2]._my; + v6 = monster[v2]._mx - monster[v4]._mfutx; + v7 = v5 - monster[v4]._mfuty; + v19 = GetDirection(monster[v2]._mx, v5, monster[v4]._mx, monster[v4]._my); + monster[v2]._mdir = v19; + if ( abs(v6) >= 2 || abs(v7) >= 2 ) + { + if ( v20 ) + { + MAI_Path(arglist); + if ( v14 ) + return; + } + } + else if ( v20 ) + { + v8 = monster[v2]._menemy; + monster[v2]._menemyx = monster[v8]._mx; + v9 = monster[v8]._my; + v10 = &monster[v8]._msquelch; + monster[v2]._menemyy = v9; + if ( !*(_BYTE *)v10 ) + { + *(_BYTE *)v10 = -1; + monster[monster[v2]._menemy]._lastx = monster[v2]._mx; + v11 = 0; + monster[monster[v2]._menemy]._lasty = monster[v2]._my; + do + { + v12 = 0; + do + { + v13 = *(_DWORD *)&nTransTable[4 + * (monster[v2]._my + v11 + 112 * (v12 + monster[v2]._mx)) + + 1148]; + if ( v13 > 0 ) + _LOBYTE(monster[v13]._msquelch) = -1; + ++v12; + } + while ( v12 < 5 ); + ++v11; + } + while ( v11 < 5 ); + } + M_StartAttack(arglist); + return; + } + v15 = &monster[v2]._pathcount; + if ( ++*(_BYTE *)v15 > 8u ) + *(_BYTE *)v15 = 5; + _LOBYTE(v16) = M_CallWalk(arglist, plr[arglist]._pdir); + if ( !v16 ) + { + v17 = ((_BYTE)v19 - 1) & 7; + v18 = 0; + while ( !v16 ) + { + v17 = ((_BYTE)v17 + 1) & 7; + _LOBYTE(v16) = DirOK(arglist, v17); + if ( ++v18 >= 8 ) + { + if ( !v16 ) + return; + break; + } + } + M_WalkDir(arglist, v17); + } + } + } + } +} + +//----- (00438304) -------------------------------------------------------- +void __fastcall MAI_SkelKing(int i) +{ + int v1; // esi + MonsterStruct *v2; // esi + int v3; // edx + int v4; // ebx + int v5; // edi + int v6; // ecx + int v7; // eax + int v8; // ST04_4 + int v9; // ecx + int v10; // eax + int v11; // ST04_4 + int v12; // ecx + int v13; // ebx + int v14; // eax + int v15; // ecx + int v16; // eax + int v17; // eax + int v18; // ecx + int v19; // eax + int v20; // eax + int v21; // edi + int v22; // ebx + int v23; // eax + int v24; // ST04_4 + int v25; // ecx + int v26; // eax + int v27; // ST04_4 + int v28; // eax + int v29; // ecx + int v30; // edx + int v31; // eax + char *v32; // [esp+4h] [ebp-1Ch] + int x2; // [esp+8h] [ebp-18h] + int v34; // [esp+Ch] [ebp-14h] + int v35; // [esp+10h] [ebp-10h] + int y2; // [esp+14h] [ebp-Ch] + int md; // [esp+18h] [ebp-8h] + int arglist; // [esp+1Ch] [ebp-4h] + + v1 = i; + arglist = i; + if ( (unsigned int)i >= 0xC8 ) + TermMsg("MAI_SkelKing: Invalid monster %d", i); + v2 = &monster[v1]; + if ( v2->_mmode == MM_STAND && _LOBYTE(v2->_msquelch) ) + { + v3 = v2->_my; + y2 = (unsigned char)v2->_menemyy; + v4 = v3 - y2; + x2 = (unsigned char)v2->_menemyx; + v5 = v2->_mx - x2; + v34 = v3 - y2; + md = GetDirection(v2->_mx, v3, v2->_lastx, v2->_lasty); + if ( _LOBYTE(v2->_msquelch) < 0xFFu ) + MonstCheckDoors(arglist); + _LOBYTE(v6) = 126; + v35 = random(v6, 100); + if ( (abs(v5) >= 2 || abs(v4) >= 2) && _LOBYTE(v2->_msquelch) == -1 ) + { + v32 = &dung_map[x2][y2]; + if ( dung_map[v2->_mx][v2->_my] == *v32 ) + { + if ( _LOBYTE(v2->_mgoal) != 4 ) + { + v7 = abs(v5); + v9 = v8; + if ( v7 < 3 ) + { + v10 = abs(v4); + v9 = v11; + if ( v10 < 3 ) + goto LABEL_26; + } + _LOBYTE(v9) = 127; + if ( random(v9, 4) ) + goto LABEL_26; + if ( _LOBYTE(v2->_mgoal) != 4 ) + { + v2->_mgoalvar1 = 0; + _LOBYTE(v12) = -128; + v2->_mgoalvar2 = random(v12, 2); + } + } + _LOBYTE(v2->_mgoal) = 4; + v13 = abs(v4); + if ( abs(v5) <= v13 ) + { + v4 = v34; + v14 = abs(v34); + } + else + { + v14 = abs(v5); + v4 = v34; + } + v15 = v2->_mgoalvar1; + v2->_mgoalvar1 = v15 + 1; + if ( v15 < 2 * v14 || (_LOBYTE(v16) = DirOK(arglist, md), !v16) ) + { + if ( dung_map[v2->_mx][v2->_my] == *v32 ) + { + _LOBYTE(v17) = M_RoundWalk(arglist, md, &v2->_mgoalvar2); + if ( !v17 ) + { + _LOBYTE(v18) = 125; + v19 = random(v18, 10); + M_StartDelay(arglist, v19 + 10); + } + goto LABEL_26; + } + } + } + } + _LOBYTE(v2->_mgoal) = 1; +LABEL_26: + if ( _LOBYTE(v2->_mgoal) == 1 ) + { + if ( gbMaxPlayers == 1 + && ((abs(v5) >= 3 || abs(v4) >= 3) && v35 < 4 * (unsigned char)v2->_mint + 35 || v35 < 6) + && (_LOBYTE(v20) = LineClear(v2->_mx, v2->_my, x2, y2), v20) ) + { + v21 = v2->_mx + offset_x[md]; + v22 = v2->_my + offset_y[md]; + if ( PosOkMonst(arglist, v21, v22) && nummonsters < 200 ) + { + M_SpawnSkel(v21, v22, md); + M_StartSpStand(arglist, md); + } + } + else + { + v23 = abs(v5); + v25 = v24; + if ( v23 >= 2 || (v26 = abs(v4), v25 = v27, v26 >= 2) ) + { + _LOBYTE(v25) = -127; + v28 = random(v25, 100); + v29 = (unsigned char)v2->_mint; + if ( v28 >= v29 + 25 + && ((v30 = v2->_mVar1, v30 != 1) && v30 != 2 && v30 != 3 || v2->_mVar2 || (v29 += 75, v28 >= v29)) ) + { + _LOBYTE(v29) = -126; + v31 = random(v29, 10); + M_StartDelay(arglist, v31 + 10); + } + else + { + M_CallWalk(arglist, md); + } + } + else if ( v35 < (unsigned char)v2->_mint + 20 ) + { + v2->_mdir = md; + M_StartAttack(arglist); + } + } + } + if ( v2->_mmode == MM_STAND ) + v2->_mAFNum = v2->MType->Anims[0].Frames[md + 1]; + } +} +// 679660: using guessed type char gbMaxPlayers; + +//----- (0043862D) -------------------------------------------------------- +void __fastcall MAI_Rhino(int i) +{ + int esi1; // esi + MonsterStruct *esi3; // esi + int v3; // edx + int v4; // ebx + int v5; // edi + int v6; // ecx + int v7; // eax + int v8; // ST1C_4 + int v9; // ecx + int v10; // eax + int v11; // ST1C_4 + int v12; // ecx + int v13; // ebx + int v14; // eax + int v15; // ecx + int v16; // eax + int v17; // ecx + int v18; // eax + int v19; // eax + int v20; // ecx + int v21; // eax + int v22; // ST1C_4 + int v23; // ecx + int v24; // eax + int v25; // ST1C_4 + int v26; // eax + int v27; // ecx + int v28; // edx + int v29; // eax + int v30; // [esp+4h] [ebp-18h] + int v31; // [esp+8h] [ebp-14h] + int v1; // [esp+Ch] [ebp-10h] + int midir; // [esp+10h] [ebp-Ch] + int v2; // [esp+14h] [ebp-8h] + int arglist; // [esp+18h] [ebp-4h] + + esi1 = i; + arglist = i; + if ( (unsigned int)i >= 0xC8 ) + TermMsg("MAI_Rhino: Invalid monster %d", i); + esi3 = &monster[esi1]; + if ( esi3->_mmode == MM_STAND && _LOBYTE(esi3->_msquelch) ) + { + v3 = esi3->_my; + v2 = (unsigned char)esi3->_menemyy; + v4 = v3 - v2; + v1 = (unsigned char)esi3->_menemyx; + v5 = esi3->_mx - v1; + v31 = v3 - v2; + midir = GetDirection(esi3->_mx, v3, esi3->_lastx, esi3->_lasty); + if ( _LOBYTE(esi3->_msquelch) < 0xFFu ) + MonstCheckDoors(arglist); + _LOBYTE(v6) = -125; + v30 = random(v6, 100); + if ( abs(v5) >= 2 || abs(v4) >= 2 ) + { + if ( _LOBYTE(esi3->_mgoal) != 4 ) + { + v7 = abs(v5); + v9 = v8; + if ( v7 < 5 ) + { + v10 = abs(v4); + v9 = v11; + if ( v10 < 5 ) + goto LABEL_23; + } + _LOBYTE(v9) = -124; + if ( !random(v9, 4) ) + goto LABEL_23; + if ( _LOBYTE(esi3->_mgoal) != 4 ) + { + esi3->_mgoalvar1 = 0; + _LOBYTE(v12) = -123; + esi3->_mgoalvar2 = random(v12, 2); + } + } + _LOBYTE(esi3->_mgoal) = 4; + v13 = abs(v4); + if ( abs(v5) <= v13 ) + { + v4 = v31; + v14 = abs(v31); + } + else + { + v14 = abs(v5); + v4 = v31; + } + v15 = esi3->_mgoalvar1; + esi3->_mgoalvar1 = v15 + 1; + if ( v15 < 2 * v14 && dung_map[esi3->_mx][esi3->_my] == dung_map[v1][v2] ) + { + _LOBYTE(v16) = M_RoundWalk(arglist, midir, &esi3->_mgoalvar2); + if ( !v16 ) + { + _LOBYTE(v17) = 125; + v18 = random(v17, 10); + M_StartDelay(arglist, v18 + 10); + } + goto LABEL_23; + } + } + _LOBYTE(esi3->_mgoal) = 1; +LABEL_23: + if ( _LOBYTE(esi3->_mgoal) == 1 ) + { + if ( (abs(v5) >= 5 || abs(v4) >= 5) + && v30 < 2 * (unsigned char)esi3->_mint + 43 + && (_LOBYTE(v19) = LineClearF1( + (unsigned char (__cdecl *)())PosOkMonst, + arglist, + esi3->_mx, + esi3->_my, + v1, + v2), + v19) ) + { + _LOBYTE(v19) = esi3->_menemy; + if ( AddMissile(esi3->_mx, esi3->_my, v1, v2, midir, 20, v19, arglist, 0, 0) != -1 ) + { + if ( esi3->MData->snd_special ) + PlayEffect(arglist, 3); + v20 = esi3->_my + 112 * esi3->_mx; + esi3->_mmode = 14; + dMonster[0][v20] = -1 - arglist; + } + } + else + { + v21 = abs(v5); + v23 = v22; + if ( v21 >= 2 || (v24 = abs(v4), v23 = v25, v24 >= 2) ) + { + _LOBYTE(v23) = -122; + v26 = random(v23, 100); + v27 = 2 * (unsigned char)esi3->_mint; + if ( v26 >= v27 + 33 + && ((v28 = esi3->_mVar1, v28 != 1) && v28 != 2 && v28 != 3 + || esi3->_mVar2 + || (v27 += 83, v26 >= v27)) ) + { + _LOBYTE(v27) = -121; + v29 = random(v27, 10); + M_StartDelay(arglist, v29 + 10); + } + else + { + M_CallWalk(arglist, midir); + } + } + else if ( v30 < 2 * (unsigned char)esi3->_mint + 28 ) + { + esi3->_mdir = midir; + M_StartAttack(arglist); + } + } + } + if ( esi3->_mmode == MM_STAND ) + esi3->_mAFNum = esi3->MType->Anims[0].Frames[esi3->_mdir + 1]; + } +} + +//----- (0043891F) -------------------------------------------------------- +void __fastcall MAI_Counselor(int i) +{ + int v1; // ebx + int v2; // esi + int v3; // ecx + int v4; // edi + int v5; // edx + int v6; // ebp + int v7; // ecx + int v8; // ecx + char v9; // al + int v10; // ecx + bool v11; // zf + bool v12; // sf + unsigned char v13; // of + int v14; // edx + int v15; // ecx + int v16; // ebx + int v17; // eax + int v18; // ebx + int v19; // edx + int v20; // ecx + int v21; // eax + int v22; // eax + int v23; // ST1C_4 + int v24; // ecx + int v25; // eax + int v26; // ST1C_4 + int v27; // edx + int v28; // eax + int v29; // eax + int v30; // ecx + int v31; // eax + int v32; // eax + int v33; // eax + int v34; // eax + int md; // [esp+8h] [ebp-14h] + int arglist; // [esp+Ch] [ebp-10h] + int y2; // [esp+10h] [ebp-Ch] + int x2; // [esp+14h] [ebp-8h] + int v39; // [esp+18h] [ebp-4h] + + v1 = i; + arglist = i; + if ( (unsigned int)i >= 0xC8 ) + TermMsg("MAI_Counselor: Invalid monster %d", i); + v2 = v1; + if ( monster[v1]._mmode == MM_STAND && _LOBYTE(monster[v2]._msquelch) ) + { + v3 = monster[v2]._mx; + x2 = (unsigned char)monster[v2]._menemyx; + v4 = v3 - x2; + v5 = monster[v2]._my; + y2 = (unsigned char)monster[v2]._menemyy; + v6 = v5 - y2; + md = GetDirection(v3, v5, monster[v2]._lastx, monster[v2]._lasty); + if ( _LOBYTE(monster[v2]._msquelch) < 0xFFu ) + MonstCheckDoors(v1); + _LOBYTE(v7) = 121; + v39 = random(v7, 100); + v9 = monster[v2]._mgoal; + if ( v9 == 2 ) + { + v10 = monster[v2]._mgoalvar1; + v13 = __OFSUB__(v10, 3); + v11 = v10 == 3; + v12 = v10 - 3 < 0; + v14 = v10 + 1; + v15 = v1; + monster[v2]._mgoalvar1 = v14; + if ( (unsigned char)(v12 ^ v13) | v11 ) + { + M_CallWalk(v1, opposite[md]); + goto LABEL_39; + } + goto LABEL_21; + } + if ( v9 == 4 ) + { + v16 = abs(v6); + if ( abs(v4) <= v16 ) + v17 = abs(v6); + else + v17 = abs(v4); + v18 = v17; + if ( abs(v4) < 2 && abs(v6) < 2 + || _LOBYTE(monster[v2]._msquelch) != -1 + || dung_map[monster[v2]._mx][monster[v2]._my] != dung_map[x2][y2] ) + { + v1 = arglist; +LABEL_20: + v15 = v1; +LABEL_21: + _LOBYTE(monster[v2]._mgoal) = 1; + M_StartFadein(v15, md, 1u); + goto LABEL_39; + } + v19 = 2 * v18; + v1 = arglist; + v20 = monster[v2]._mgoalvar1; + monster[v2]._mgoalvar1 = v20 + 1; + if ( v20 >= v19 ) + { + _LOBYTE(v21) = DirOK(arglist, md); + if ( v21 ) + goto LABEL_20; + } + M_RoundWalk(arglist, md, &monster[v2]._mgoalvar2); +LABEL_39: + if ( monster[v2]._mmode == MM_STAND ) + { + _LOBYTE(v8) = 125; + v34 = random(v8, 10); + M_StartDelay(v1, v34 + 5); + } + return; + } + if ( v9 != 1 ) + goto LABEL_39; + v22 = abs(v4); + v24 = v23; + if ( v22 >= 2 || (v25 = abs(v6), v24 = v26, v25 >= 2) ) + { + if ( v39 < 5 * ((unsigned char)monster[v2]._mint + 10) ) + { + _LOBYTE(v31) = LineClear(monster[v2]._mx, monster[v2]._my, x2, y2); + if ( v31 ) + { + _LOBYTE(v24) = 77; + v32 = random( + v24, + (unsigned char)monster[v2].mMaxDamage - (unsigned char)monster[v2].mMinDamage + 1); + M_StartRAttack( + v1, + (unsigned char)counsmiss[(unsigned char)monster[v2]._mint], + (unsigned char)monster[v2].mMinDamage + v32); + goto LABEL_39; + } + } + _LOBYTE(v24) = 124; + if ( random(v24, 100) < 30 ) + { + v27 = md; + _LOBYTE(monster[v2]._mgoal) = 4; + goto LABEL_29; + } + } + else + { + v27 = md; + v28 = monster[v2]._mmaxhp >> 1; + v13 = __OFSUB__(monster[v2]._mhitpoints, v28); + v12 = monster[v2]._mhitpoints - v28 < 0; + monster[v2]._mdir = md; + if ( v12 ^ v13 ) + { + _LOBYTE(monster[v2]._mgoal) = 2; +LABEL_29: + monster[v2]._mgoalvar1 = 0; + M_StartFadeout(v1, v27, 0); + goto LABEL_39; + } + if ( monster[v2]._mVar1 == 13 + || (_LOBYTE(v24) = 105, v29 = random(v24, 100), + v30 = 2 * (unsigned char)monster[v2]._mint + 20, + v29 < v30) ) + { + M_StartRAttack(v1, -1, 0); + AddMissile(monster[v2]._mx, monster[v2]._my, 0, 0, monster[v2]._mdir, 11, 1, v1, 4, 0); + AddMissile(monster[v2]._mx, monster[v2]._my, 0, 0, monster[v2]._mdir, 12, 1, v1, 4, 0); + goto LABEL_39; + } + } + _LOBYTE(v30) = 105; + v33 = random(v30, 10); + M_StartDelay(v1, v33 + 2 * (5 - (unsigned char)monster[v2]._mint)); + goto LABEL_39; + } +} + +//----- (00438C79) -------------------------------------------------------- +void __fastcall MAI_Garbud(int i) +{ + int v1; // esi + int v2; // esi + int v3; // ebx + int v4; // edi + int v5; // eax + int v6; // eax + char v7; // al + int v8; // [esp+4h] [ebp-8h] + int arglist; // [esp+8h] [ebp-4h] + + v1 = i; + arglist = i; + if ( (unsigned int)i >= 0xC8 ) + TermMsg("MAI_Garbud: Invalid monster %d", i); + v2 = v1; + if ( monster[v2]._mmode == MM_STAND ) + { + v3 = monster[v2]._my; + v4 = monster[v2]._mx; + v8 = M_GetDir(arglist); + v5 = monster[v2].mtalkmsg; + if ( v5 < (signed int)TEXT_GARBUD4 + && v5 > (signed int)TEXT_PEGBOY20 + && !(dFlags[v4][v3] & 2) + && _LOBYTE(monster[v2]._mgoal) == 7 ) + { + _LOBYTE(monster[v2]._mgoal) = 6; + monster[v2].mtalkmsg = v5 + 1; + } + if ( dFlags[v4][v3] & 2 ) + { + if ( monster[v2].mtalkmsg == TEXT_GARBUD4 ) + { + _LOBYTE(v6) = effect_is_playing(USFX_GARBUD4); + if ( !v6 && _LOBYTE(monster[v2]._mgoal) == 7 ) + { + _LOBYTE(monster[v2]._msquelch) = -1; + monster[v2].mtalkmsg = 0; + _LOBYTE(monster[v2]._mgoal) = 1; + } + } + } + v7 = monster[v2]._mgoal; + if ( v7 == 1 || v7 == 4 ) + MAI_Round(arglist, 1u); + monster[v2]._mdir = v8; + if ( monster[v2]._mmode == MM_STAND ) + monster[v2]._mAFNum = monster[v2].MType->Anims[0].Frames[v8 + 1]; + } +} + +//----- (00438D7E) -------------------------------------------------------- +void __fastcall MAI_Zhar(int i) +{ + int v1; // ebp + int v2; // esi + int v3; // ebx + int v4; // edi + int v5; // edi + int v6; // ebx + int v7; // ebp + int v8; // eax + char v9; // al + int arglist; // [esp+8h] [ebp-8h] + int v11; // [esp+Ch] [ebp-4h] + + v1 = i; + arglist = i; + if ( (unsigned int)i >= 0xC8 ) + TermMsg("MAI_Zhar: Invalid monster %d", i); + v2 = v1; + if ( monster[v1]._mmode == MM_STAND ) + { + v3 = monster[v2]._my; + v4 = monster[v2]._mx; + v11 = M_GetDir(v1); + if ( monster[v2].mtalkmsg == TEXT_ZHAR1 && !(dFlags[v4][v3] & 2) && _LOBYTE(monster[v2]._mgoal) == 7 ) + { + monster[v2].mtalkmsg = TEXT_ZHAR2; + _LOBYTE(monster[v2]._mgoal) = 6; + } + if ( dFlags[v4][v3] & 2 ) + { + v5 = monster[v2]._mx - (unsigned char)monster[v2]._menemyx; + v6 = monster[v2]._my - (unsigned char)monster[v2]._menemyy; + v7 = abs(v6); + if ( abs(v5) <= v7 ) + abs(v6); + else + abs(v5); + if ( monster[v2].mtalkmsg == TEXT_ZHAR2 ) + { + _LOBYTE(v8) = effect_is_playing(USFX_ZHAR2); + if ( !v8 && _LOBYTE(monster[v2]._mgoal) == 7 ) + { + _LOBYTE(monster[v2]._msquelch) = -1; + monster[v2].mtalkmsg = 0; + _LOBYTE(monster[v2]._mgoal) = 1; + } + } + } + v9 = monster[v2]._mgoal; + if ( v9 == 1 || v9 == 2 || v9 == 4 ) + MAI_Counselor(arglist); + monster[v2]._mdir = v11; + if ( monster[v2]._mmode == MM_STAND ) + monster[v2]._mAFNum = monster[v2].MType->Anims[0].Frames[v11 + 1]; + } +} + +//----- (00438EC2) -------------------------------------------------------- +void __fastcall MAI_SnotSpil(int i) +{ + int v1; // ebp + int v2; // esi + int v3; // ebx + int v4; // edi + int v5; // ebp + int v6; // eax + char v7; // al + int arglist; // [esp+8h] [ebp-4h] + + v1 = i; + arglist = i; + if ( (unsigned int)i >= 0xC8 ) + TermMsg("MAI_SnotSpil: Invalid monster %d", i); + v2 = v1; + if ( monster[v1]._mmode == MM_STAND ) + { + v3 = monster[v2]._my; + v4 = monster[v2]._mx; + v5 = M_GetDir(v1); + if ( monster[v2].mtalkmsg == TEXT_SNOT1 && !(dFlags[v4][v3] & 2) && _LOBYTE(monster[v2]._mgoal) == 7 ) + { + monster[v2].mtalkmsg = TEXT_SNOT2; + _LOBYTE(monster[v2]._mgoal) = 6; + } + if ( monster[v2].mtalkmsg == TEXT_SNOT2 && quests[7]._qvar1 == 3 ) + { + monster[v2].mtalkmsg = 0; + _LOBYTE(monster[v2]._mgoal) = 1; + } + if ( dFlags[v4][v3] & 2 ) + { + if ( monster[v2].mtalkmsg == TEXT_SNOT3 ) + { + _LOBYTE(v6) = effect_is_playing(USFX_SNOT3); + if ( !v6 && _LOBYTE(monster[v2]._mgoal) == 7 ) + { + DRLG_MRectTrans(setpc_x, setpc_y, setpc_w + setpc_x + 1, setpc_h + setpc_y + 1); + quests[7]._qvar1 = 3; + RedoPlayerVision(); + _LOBYTE(monster[v2]._msquelch) = -1; + monster[v2].mtalkmsg = 0; + _LOBYTE(monster[v2]._mgoal) = 1; + } + } + if ( quests[7]._qvar1 == 3 ) + { + v7 = monster[v2]._mgoal; + if ( v7 == 1 || v7 == 5 ) + MAI_Fallen(arglist); + } + } + monster[v2]._mdir = v5; + if ( monster[v2]._mmode == MM_STAND ) + monster[v2]._mAFNum = monster[v2].MType->Anims[0].Frames[v5 + 1]; + } +} +// 5CF330: using guessed type int setpc_h; +// 5CF334: using guessed type int setpc_w; + +//----- (00439016) -------------------------------------------------------- +void __fastcall MAI_Lazurus(int i) +{ + int v1; // ebx + int v2; // esi + int v3; // ebp + int v4; // edi + int v5; // ebx + int v6; // eax + char v7; // al + int v8; // eax + int arglist; // [esp+8h] [ebp-4h] + + v1 = i; + arglist = i; + if ( (unsigned int)i >= 0xC8 ) + TermMsg("MAI_Lazurus: Invalid monster %d", i); + v2 = v1; + if ( monster[v1]._mmode == MM_STAND ) + { + v3 = monster[v2]._my; + v4 = monster[v2]._mx; + v5 = M_GetDir(v1); + if ( dFlags[v4][v3] & 2 ) + { + if ( gbMaxPlayers != 1 ) + goto LABEL_29; + if ( monster[v2].mtalkmsg == TEXT_LAZ1_1 ) + { + if ( _LOBYTE(monster[v2]._mgoal) == 6 && plr[myplr].WorldX == TEXT_LAZ1_1 && plr[myplr].WorldY == 46 ) + { + PlayInGameMovie("gendata\\fprst3.smk"); + monster[v2]._mmode = MM_TALK; + quests[15]._qvar1 = 5; + } + if ( monster[v2].mtalkmsg == TEXT_LAZ1_1 ) + { + _LOBYTE(v6) = effect_is_playing(USFX_LAZ1); + if ( !v6 && _LOBYTE(monster[v2]._mgoal) == 7 ) + { + ObjChangeMapResync(1, 18, 20, 24); + RedoPlayerVision(); + _LOBYTE(monster[v2]._msquelch) = -1; + monster[v2].mtalkmsg = 0; + quests[15]._qvar1 = 6; + _LOBYTE(monster[v2]._mgoal) = 1; + } + } + } + if ( gbMaxPlayers != 1 ) + { +LABEL_29: + if ( monster[v2].mtalkmsg == TEXT_LAZ1_1 && _LOBYTE(monster[v2]._mgoal) == 6 && quests[15]._qvar1 <= 3u ) + monster[v2]._mmode = MM_TALK; + } + } + v7 = monster[v2]._mgoal; + if ( v7 == 1 || v7 == 2 || v7 == 4 ) + { + monster[v2].mtalkmsg = 0; + MAI_Counselor(arglist); + } + monster[v2]._mdir = v5; + v8 = monster[v2]._mmode; + if ( v8 == MM_STAND || v8 == MM_TALK ) + monster[v2]._mAFNum = monster[v2].MType->Anims[0].Frames[v5 + 1]; + } +} +// 679660: using guessed type char gbMaxPlayers; + +//----- (00439196) -------------------------------------------------------- +void __fastcall MAI_Lazhelp(int i) +{ + int v1; // esi + int v2; // esi + int v3; // ebx + int v4; // edi + int v5; // [esp+4h] [ebp-8h] + int ia; // [esp+8h] [ebp-4h] + + v1 = i; + ia = i; + if ( (unsigned int)i >= 0xC8 ) + TermMsg("MAI_Lazhelp: Invalid monster %d", i); + v2 = v1; + if ( monster[v2]._mmode == MM_STAND ) + { + v3 = monster[v2]._my; + v4 = monster[v2]._mx; + v5 = M_GetDir(ia); + if ( dFlags[v4][v3] & 2 ) + { + if ( gbMaxPlayers == 1 ) + { + if ( quests[15]._qvar1 <= 5u ) + { + _LOBYTE(monster[v2]._mgoal) = 6; + goto LABEL_10; + } + monster[v2].mtalkmsg = 0; + } + _LOBYTE(monster[v2]._mgoal) = 1; + } +LABEL_10: + if ( _LOBYTE(monster[v2]._mgoal) == 1 ) + MAI_Succ(ia); + monster[v2]._mdir = v5; + if ( monster[v2]._mmode == MM_STAND ) + monster[v2]._mAFNum = monster[v2].MType->Anims[0].Frames[v5 + 1]; + } +} +// 679660: using guessed type char gbMaxPlayers; + +//----- (00439253) -------------------------------------------------------- +void __fastcall MAI_Lachdanan(int i) +{ + int v1; // ebp + int v2; // esi + int v3; // ebx + int v4; // edi + int v5; // eax + int v6; // [esp+8h] [ebp-4h] + + v1 = i; + if ( (unsigned int)i >= 0xC8 ) + TermMsg("MAI_Lachdanan: Invalid monster %d", i); + v2 = v1; + if ( monster[v1]._mmode == MM_STAND ) + { + v3 = monster[v2]._my; + v4 = monster[v2]._mx; + v6 = M_GetDir(v1); + if ( monster[v2].mtalkmsg == TEXT_LACH1 && !(dFlags[v4][v3] & 2) && _LOBYTE(monster[v2]._mgoal) == 7 ) + { + monster[v2].mtalkmsg = TEXT_LACH2; + _LOBYTE(monster[v2]._mgoal) = 6; + } + if ( dFlags[v4][v3] & 2 ) + { + if ( monster[v2].mtalkmsg == TEXT_LACH3 ) + { + _LOBYTE(v5) = effect_is_playing(USFX_LACH3); + if ( !v5 && _LOBYTE(monster[v2]._mgoal) == 7 ) + { + monster[v2].mtalkmsg = 0; + quests[4]._qactive = 3; + M_StartKill(v1, -1); + } + } + } + monster[v2]._mdir = v6; + if ( monster[v2]._mmode == MM_STAND ) + monster[v2]._mAFNum = monster[v2].MType->Anims[0].Frames[v6 + 1]; + } +} + +//----- (00439338) -------------------------------------------------------- +void __fastcall MAI_Warlord(int i) +{ + int v1; // ebp + int v2; // esi + int v3; // ebx + int v4; // edi + int v5; // ebp + int v6; // eax + int v7; // eax + int arglist; // [esp+8h] [ebp-4h] + + v1 = i; + arglist = i; + if ( (unsigned int)i >= 0xC8 ) + TermMsg("MAI_Warlord: Invalid monster %d", i); + v2 = v1; + if ( monster[v1]._mmode == MM_STAND ) + { + v3 = monster[v2]._my; + v4 = monster[v2]._mx; + v5 = M_GetDir(v1); + if ( dFlags[v4][v3] & 2 && monster[v2].mtalkmsg == TEXT_WARLRD1 ) + { + if ( _LOBYTE(monster[v2]._mgoal) == 6 ) + monster[v2]._mmode = MM_TALK; + _LOBYTE(v6) = effect_is_playing(USFX_WARLRD1); + if ( !v6 && _LOBYTE(monster[v2]._mgoal) == 7 ) + { + _LOBYTE(monster[v2]._msquelch) = -1; + monster[v2].mtalkmsg = 0; + _LOBYTE(monster[v2]._mgoal) = 1; + } + } + if ( _LOBYTE(monster[v2]._mgoal) == 1 ) + MAI_SkelSd(arglist); + monster[v2]._mdir = v5; + v7 = monster[v2]._mmode; + if ( v7 == MM_STAND || v7 == MM_TALK ) + monster[v2]._mAFNum = monster[v2].MType->Anims[0].Frames[v5 + 1]; + } +} + +//----- (00439419) -------------------------------------------------------- +void __cdecl DeleteMonsterList() +{ + int *v0; // eax + signed int v1; // ecx + + v0 = &monster[0]._my; + do + { + if ( v0[18] ) + { + *(v0 - 1) = 1; + *v0 = 0; + v0[1] = 0; + v0[2] = 0; + v0[3] = 0; + v0[4] = 0; + v0[18] = 0; + } + v0 += 57; + } + while ( (signed int)v0 < (signed int)&monster[4]._my ); + v1 = 4; + while ( v1 < nummonsters ) + { + if ( monster[monstactive[v1]]._mDelFlag ) + { + DeleteMonster(v1); + v1 = 0; + } + else + { + ++v1; + } + } +} + +//----- (0043947E) -------------------------------------------------------- +void __cdecl ProcessMonsters() +{ + int v0; // edi + int v1; // esi + int v2; // ecx + int v3; // eax + char *v4; // ebx + unsigned int v5; // eax + int v6; // eax + int v7; // edx + int v8; // eax + unsigned int v9; // eax + int v10; // eax + bool v11; // zf + char *v12; // ecx + char *v13; // eax + int v14; // ecx + int v15; // eax + char v16; // al + int v17; // ecx + int v18; // eax + int v19; // eax + int v20; // ecx + int *v21; // eax + int *v22; // eax + int v23; // [esp+0h] [ebp-Ch] + int v24; // [esp+4h] [ebp-8h] + int v25; // [esp+8h] [ebp-4h] + + DeleteMonsterList(); + v24 = 0; + if ( nummonsters <= 0 ) + goto LABEL_60; + do + { + v25 = 0; + v23 = monstactive[v24]; + v0 = v23; + v1 = v23; + if ( (unsigned char)gbMaxPlayers > 1u ) + { + SetRndSeed(monster[v1]._mAISeed); + monster[v1]._mAISeed = GetRndSeed(); + } + if ( !(monster[v1]._mFlags & 8) ) + { + v2 = monster[v1]._mhitpoints; + if ( v2 < monster[v1]._mmaxhp && (signed int)(v2 & 0xFFFFFFC0) > 0 ) + { + v3 = SLOBYTE(monster[v1].mLevel); + if ( (char)v3 > 1 ) + v3 = (char)v3 >> 1; + monster[v1]._mhitpoints = v2 + v3; + } + } + v4 = &dFlags[monster[v1]._mx][monster[v1]._my]; + if ( *v4 & 2 && !_LOBYTE(monster[v1]._msquelch) && monster[v1].MType->mtype == MON_BUTCH ) + PlaySFX(USFX_CLEAVER); + if ( monster[v1]._mFlags & 0x10 ) + { + v5 = monster[v1]._menemy; + if ( v5 >= 0xC8 ) + TermMsg("Illegal enemy monster %d for monster \"%s\"", v5, monster[v1].mName); + v6 = monster[v1]._menemy; + v7 = monster[v6]._mfutx; + monster[v1]._lastx = v7; + monster[v1]._menemyx = v7; + v8 = monster[v6]._mfuty; + monster[v1]._menemyy = v8; + monster[v1]._lasty = v8; + } + else + { + v9 = monster[v1]._menemy; + if ( v9 >= 4 ) + TermMsg("Illegal enemy player %d for monster \"%s\"", v9, monster[v1].mName); + v10 = monster[v1]._menemy; + v11 = (*v4 & 2) == 0; + v12 = (char *)&plr[v10]._px; + v13 = (char *)&plr[v10]._py; + monster[v1]._menemyx = *v12; + monster[v1]._menemyy = *v13; + if ( v11 ) + { + v16 = monster[v1]._msquelch; + if ( v16 && monster[v1]._mAi != MON_DIABLO ) + _LOBYTE(monster[v1]._msquelch) = v16 - 1; + } + else + { + v14 = *(_DWORD *)v12; + v15 = *(_DWORD *)v13; + _LOBYTE(monster[v1]._msquelch) = -1; + monster[v1]._lastx = v14; + monster[v1]._lasty = v15; + } + v0 = v23; + } + while ( 1 ) + { + v17 = v0; + if ( monster[v1]._mFlags & 0x100 ) + { + MAI_Path(v0); + if ( v18 ) + goto LABEL_30; + v17 = v0; + } + AiProc[(unsigned char)monster[v1]._mAi](v17); +LABEL_30: + switch ( monster[v1]._mmode ) + { + case MM_STAND: + v19 = M_DoStand(v0); + goto LABEL_48; + case MM_WALK: + v19 = M_DoWalk(v0); + goto LABEL_48; + case MM_WALK2: + v19 = M_DoWalk2(v0); + goto LABEL_48; + case MM_WALK3: + v19 = M_DoWalk3(v0); + goto LABEL_48; + case MM_ATTACK: + v19 = M_DoAttack(v0); + goto LABEL_48; + case MM_GOTHIT: + v19 = M_DoGotHit(v0); + goto LABEL_48; + case MM_DEATH: + v19 = M_DoDeath(v0); + goto LABEL_48; + case MM_SATTACK: + v19 = M_DoSAttack(v0); + goto LABEL_48; + case MM_FADEIN: + v19 = M_DoFadein(v0); + goto LABEL_48; + case MM_FADEOUT: + v19 = M_DoFadeout(v0); + goto LABEL_48; + case MM_RATTACK: + v19 = M_DoRAttack(v0); + goto LABEL_48; + case MM_SPSTAND: + v19 = M_DoSpStand(v0); + goto LABEL_48; + case MM_RSPATTACK: + v19 = M_DoRSpAttack(v0); + goto LABEL_48; + case MM_DELAY: + v19 = M_DoDelay(v0); + goto LABEL_48; + case MM_CHARGE: + goto LABEL_51; + case MM_STONE: + v19 = M_DoStone(v0); + goto LABEL_48; + case MM_HEAL: + v19 = M_DoHeal(v0); + goto LABEL_48; + case MM_TALK: + v19 = M_DoTalk(v0); +LABEL_48: + v25 = v19; + break; + default: + break; + } + if ( !v25 ) + break; + GroupUnity(v0); + } +LABEL_51: + if ( monster[v1]._mmode != MM_STONE ) + { + v20 = monster[v1]._mFlags; + v21 = &monster[v1]._mAnimCnt; + ++*v21; + if ( !(v20 & 4) && monster[v1]._mAnimCnt >= monster[v1]._mAnimDelay ) + { + *v21 = 0; + v22 = &monster[v1]._mAnimFrame; + if ( v20 & 2 ) + { + v11 = (*v22)-- == 1; + if ( v11 ) + *v22 = monster[v1]._mAnimLen; + } + else if ( ++*v22 > monster[v1]._mAnimLen ) + { + *v22 = 1; + } + } + } + ++v24; + } + while ( v24 < nummonsters ); +LABEL_60: + DeleteMonsterList(); +} +// 679660: using guessed type char gbMaxPlayers; + +//----- (004397C5) -------------------------------------------------------- +void __cdecl FreeMonsters() +{ + void **v0; // edi + int v1; // ebx + signed int v2; // ebp + void **v3; // esi + void *v4; // ecx + int v5; // [esp+0h] [ebp-4h] + + v5 = 0; + if ( nummtypes > 0 ) + { + v0 = (void **)Monsters[0].Anims; + do + { + v1 = *((unsigned char *)v0 - 4); + v2 = 0; + v3 = v0; + do + { + if ( animletter[v2] != 's' || monsterdata[v1].has_special ) + { + v4 = *v3; + *v3 = 0; + mem_free_dbg(v4); + } + ++v2; + v3 += 11; + } + while ( v2 < 6 ); + ++v5; + v0 += 82; + } + while ( v5 < nummtypes ); + } + FreeMissiles2(); +} + +//----- (00439831) -------------------------------------------------------- +unsigned char __fastcall DirOK(int i, int mdir) +{ + int v2; // ebx + int v3; // esi + int v4; // ebx + int v5; // edi + int v6; // esi + int v7; // edi + bool v8; // zf + int v9; // edx + char *v11; // ebx + unsigned char v12; // al + int v13; // edx + int v14; // eax + int v15; // edi + int v16; // ecx + signed int j; // esi + int v18; // eax + bool v19; // zf + int v20; // eax + int v21; // [esp+Ch] [ebp-14h] + int v22; // [esp+10h] [ebp-10h] + int v23; // [esp+14h] [ebp-Ch] + int a1; // [esp+18h] [ebp-8h] + int v25; // [esp+1Ch] [ebp-4h] + int v26; // [esp+1Ch] [ebp-4h] + + v2 = i; + v3 = mdir; + v25 = mdir; + a1 = i; + if ( (unsigned int)i >= 0xC8 ) + TermMsg("DirOK: Invalid monster %d", i); + v4 = v2; + v5 = offset_y[v3]; + v6 = monster[v4]._mx + offset_x[v3]; + v7 = monster[v4]._my + v5; + if ( v7 < 0 || v7 >= 112 || v6 < 0 || v6 >= 112 || !PosOkMonst(a1, v6, v7) ) + return 0; + if ( v25 == DIR_E ) + { + if ( !SolidLoc(v6, v7 + 1) ) + { + v8 = (dFlags[v6][v7 + 1] & 0x10) == 0; + goto LABEL_18; + } + return 0; + } + if ( v25 == DIR_W ) + { + if ( SolidLoc(v6 + 1, v7) ) + return 0; + v8 = (dFlags[v6 + 1][v7] & 0x10) == 0; + } + else + { + if ( v25 == DIR_N ) + { + if ( SolidLoc(v6 + 1, v7) ) + return 0; + v9 = v7 + 1; + } + else + { + if ( v25 ) + goto LABEL_24; + if ( SolidLoc(v6 - 1, v7) ) + return 0; + v9 = v7 - 1; + } + v8 = SolidLoc(v6, v9) == 0; + } +LABEL_18: + if ( !v8 ) + return 0; +LABEL_24: + if ( monster[v4].leaderflag == 1 ) + { + v11 = &monster[v4].leader; + if ( abs(v6 - monster[(unsigned char)*v11]._mfutx) >= 4 + || abs(v7 - monster[(unsigned char)*v11]._mfuty) >= 4 ) + { + return 0; + } + return 1; + } + v12 = monster[v4]._uniqtype; + if ( !v12 || !(MonstAvailTbl[32 * v12 + 102] & 2) ) + return 1; + v26 = 0; + v13 = v6 - 3; + v21 = v6 + 3; + if ( v6 - 3 <= v6 + 3 ) + { + v14 = v7 - 3; + v15 = v7 + 3; + v23 = v14; + v22 = v15; + v16 = 112 * v13; + do + { + for ( j = v23; j <= v15; ++j ) + { + if ( j >= 0 && j < 112 && v16 >= 0 && v16 < 12544 ) + { + v18 = dMonster[0][v16 + j]; + v19 = v18 == 0; + if ( v18 < 0 ) + { + v18 = -v18; + v19 = v18 == 0; + } + if ( !v19 ) + --v18; + v20 = v18; + if ( monster[v20].leaderflag == 1 + && (unsigned char)monster[v20].leader == a1 + && monster[v20]._mfutx == v13 + && monster[v20]._mfuty == j ) + { + ++v26; + } + } + v15 = v22; + } + ++v13; + v16 += 112; + } + while ( v13 <= v21 ); + } + return v26 == (unsigned char)monster[v4].unpackfilesize; +} + +//----- (00439A32) -------------------------------------------------------- +unsigned char __fastcall PosOkMissile(int x, int y) +{ + int v2; // ecx + unsigned char result; // al + + v2 = x; + result = 0; + if ( !nMissileTable[dPiece[0][v2 * 112 + y]] && !(dFlags[v2][y] & 0x10) ) + result = 1; + return result; +} + +//----- (00439A57) -------------------------------------------------------- +unsigned char __fastcall CheckNoSolid(int x, int y) +{ + return nSolidTable[dPiece[0][y + 112 * x]] == 0; +} + +//----- (00439A71) -------------------------------------------------------- +unsigned char __fastcall LineClearF(unsigned char (__cdecl *Clear)(), int x1, int y1, int x2, int y2) +{ + int v5; // esi + int v6; // edi + int v7; // ebx + int v8; // eax + int v9; // eax + int v10; // eax + int v11; // ebx + int v12; // esi + signed int v13; // edi + int v14; // edx + int v15; // ecx + int v16; // eax + int v17; // eax + int v18; // eax + int v19; // ebx + int v20; // edi + signed int v21; // esi + int v22; // ecx + unsigned char (__cdecl *v24)(); // [esp+Ch] [ebp-14h] + int v25; // [esp+10h] [ebp-10h] + int v26; // [esp+14h] [ebp-Ch] + int v27; // [esp+18h] [ebp-8h] + int v28; // [esp+18h] [ebp-8h] + int v29; // [esp+1Ch] [ebp-4h] + + v5 = y2 - y1; + v29 = x1; + v24 = Clear; + v25 = x1; + v26 = y1; + v6 = x2 - x1; + v7 = abs(y2 - y1); + if ( abs(v6) <= v7 ) + { + if ( v5 < 0 ) + { + v16 = y1; + y1 = y2; + y2 = v16; + v17 = v29; + v5 = -v5; + v29 = x2; + x2 = v17; + v6 = -v6; + } + v18 = 2 * v6; + v28 = 2 * v6; + if ( v6 <= 0 ) + { + v19 = v18 + v5; + v20 = 2 * (v5 + v6); + v21 = -1; + } + else + { + v19 = v18 - v5; + v20 = 2 * (v6 - v5); + v21 = 1; + } + while ( 1 ) + { + v22 = v29; + if ( y1 == y2 && v29 == x2 ) + break; + if ( v19 <= 0 == v21 < 0 ) + { + v19 += v20; + v22 = v21 + v29; + v29 += v21; + } + else + { + v19 += v28; + } + if ( (++y1 != v26 || v22 != v25) && !((int (__fastcall *)(int))v24)(v22) ) + goto LABEL_29; + } + } + else + { + if ( v6 < 0 ) + { + v8 = v29; + v29 = x2; + x2 = v8; + v9 = y1; + v6 = -v6; + y1 = y2; + y2 = v9; + v5 = -v5; + } + v10 = 2 * v5; + v27 = 2 * v5; + if ( v5 <= 0 ) + { + v11 = v10 + v6; + v12 = 2 * (v6 + v5); + v13 = -1; + } + else + { + v11 = v10 - v6; + v12 = 2 * (v5 - v6); + v13 = 1; + } + do + { + v14 = y1; + if ( v29 == x2 && y1 == y2 ) + break; + if ( v11 <= 0 == v13 < 0 ) + { + v11 += v12; + v14 = v13 + y1; + y1 += v13; + } + else + { + v11 += v27; + } + v15 = v29 + 1; + } + while ( ++v29 == v25 && v14 == v26 || ((int (__fastcall *)(int, int))v24)(v15, v14) ); +LABEL_29: + if ( v29 != x2 ) + return 0; + } + if ( y1 == y2 ) + return 1; + return 0; +} + +//----- (00439BE0) -------------------------------------------------------- +unsigned char __fastcall LineClear(int x1, int y1, int x2, int y2) +{ + return LineClearF((unsigned char (__cdecl *)())PosOkMissile, x1, y1, x2, y2); +} + +//----- (00439BFA) -------------------------------------------------------- +unsigned char __fastcall LineClearF1(unsigned char (__cdecl *Clear)(), int monst, int x1, int y1, int x2, int y2) +{ + int v6; // esi + int v7; // edi + int v8; // ebx + int v9; // eax + int v10; // eax + int v11; // eax + int v12; // ebx + int v13; // esi + signed int v14; // edi + int v15; // eax + int v16; // eax + int v17; // eax + int v18; // eax + int v19; // ebx + int v20; // edi + signed int v21; // esi + int v22; // edx + unsigned char (__cdecl *v24)(); // [esp+Ch] [ebp-14h] + int v25; // [esp+10h] [ebp-10h] + int v26; // [esp+14h] [ebp-Ch] + int v27; // [esp+18h] [ebp-8h] + int v28; // [esp+1Ch] [ebp-4h] + int v29; // [esp+1Ch] [ebp-4h] + + v24 = Clear; + v6 = y2 - y1; + v25 = monst; + v26 = x1; + v27 = y1; + v7 = x2 - x1; + v8 = abs(y2 - y1); + if ( abs(x2 - x1) <= v8 ) + { + if ( v6 < 0 ) + { + v16 = y1; + y1 = y2; + y2 = v16; + v17 = x1; + v6 = -v6; + x1 = x2; + x2 = v17; + v7 = -v7; + } + v18 = 2 * v7; + v29 = 2 * v7; + if ( v7 <= 0 ) + { + v19 = v18 + v6; + v20 = 2 * (v6 + v7); + v21 = -1; + } + else + { + v19 = v18 - v6; + v20 = 2 * (v7 - v6); + v21 = 1; + } + while ( 1 ) + { + v22 = x1; + if ( y1 == y2 && x1 == x2 ) + break; + if ( v19 <= 0 == v21 < 0 ) + { + v19 += v20; + v22 = v21 + x1; + x1 += v21; + } + else + { + v19 += v29; + } + if ( (++y1 != v27 || v22 != v26) && !((int (__fastcall *)(int, int, int))v24)(v25, v22, y1) ) + goto LABEL_29; + } + } + else + { + if ( v7 < 0 ) + { + v9 = x1; + x1 = x2; + x2 = v9; + v10 = y1; + v7 = -v7; + y1 = y2; + y2 = v10; + v6 = -v6; + } + v11 = 2 * v6; + v28 = 2 * v6; + if ( v6 <= 0 ) + { + v12 = v11 + v7; + v13 = 2 * (v7 + v6); + v14 = -1; + } + else + { + v12 = v11 - v7; + v13 = 2 * (v6 - v7); + v14 = 1; + } + do + { + v15 = y1; + if ( x1 == x2 && y1 == y2 ) + break; + if ( v12 <= 0 == v14 < 0 ) + { + v12 += v13; + v15 = v14 + y1; + y1 += v14; + } + else + { + v12 += v28; + } + } + while ( ++x1 == v26 && v15 == v27 || ((int (__fastcall *)(int, int))v24)(v25, v15) ); +LABEL_29: + if ( x1 != x2 ) + return 0; + } + if ( y1 == y2 ) + return 1; + return 0; +} + +//----- (00439D75) -------------------------------------------------------- +int __fastcall SyncMonsterAnim(int monst) +{ + int v1; // esi + int result; // eax + int v3; // edx + MonsterData *v4; // esi + CMonster *v5; // ecx + unsigned char v6; // dl + char *v7; // edx + int v8; // esi + int v9; // edx + int v10; // ecx + int v11; // edx + int v12; // ecx + int v13; // edx + + v1 = monst; + if ( (unsigned int)monst >= 0xC8 ) + TermMsg("SyncMonsterAnim: Invalid monster %d", monst); + result = v1; + v3 = monster[v1]._mMTidx; + v4 = Monsters[v3].MData; + v5 = &Monsters[v3]; + v6 = monster[result]._uniqtype; + monster[result].MType = v5; + monster[result].MData = v4; + if ( v6 ) + v7 = *(char **)&MonstAvailTbl[32 * v6 + 84]; + else + v7 = v4->mName; + v8 = monster[result]._mmode; + monster[result].mName = v7; + v9 = monster[result]._mdir; + switch ( v8 ) + { + case MM_STAND: + case MM_DELAY: + case MM_TALK: + v10 = v5->Anims[0].Frames[v9 + 1]; + goto LABEL_13; + case MM_WALK: + case MM_WALK2: + case MM_WALK3: + v10 = v5->Anims[1].Frames[v9 + 1]; + goto LABEL_13; + case MM_ATTACK: + case MM_RATTACK: + v10 = v5->Anims[2].Frames[v9 + 1]; + goto LABEL_13; + case MM_GOTHIT: + v10 = v5->Anims[3].Frames[v9 + 1]; + goto LABEL_13; + case MM_DEATH: + v10 = v5->Anims[4].Frames[v9 + 1]; + goto LABEL_13; + case MM_SATTACK: + case MM_FADEIN: + case MM_FADEOUT: + case MM_SPSTAND: + case MM_RSPATTACK: + case MM_HEAL: + v10 = v5->Anims[5].Frames[v9 + 1]; +LABEL_13: + monster[result]._mAFNum = v10; + return result * 228; + case MM_CHARGE: + v11 = v5->Anims[2].Frames[v9 + 1]; + monster[result]._mAnimFrame = 1; + monster[result]._mAFNum = v11; + v12 = v5->Anims[2].Rate; + break; + default: + v13 = v5->Anims[0].Frames[v9 + 1]; + monster[result]._mAnimFrame = 1; + monster[result]._mAFNum = v13; + v12 = v5->Anims[0].Rate; + break; + } + monster[result]._mAnimLen = v12; + return result * 228; +} + +//----- (00439EA8) -------------------------------------------------------- +void __fastcall M_FallenFear(int x, int y) +{ + int v2; // eax + int *v3; // ebx + int v4; // edi + int v5; // esi + signed int v6; // eax + int v7; // eax + bool v8; // zf + int v9; // eax + int v10; // eax + signed int v11; // [esp-10h] [ebp-1Ch] + int v12; // [esp+0h] [ebp-Ch] + int x1; // [esp+4h] [ebp-8h] + int y1; // [esp+8h] [ebp-4h] + + v2 = 0; + y1 = y; + x1 = x; + v12 = 0; + if ( nummonsters > 0 ) + { + v3 = &monster[0]._mx; + do + { + v4 = 0; + v5 = monstactive[v2]; + v6 = monster[v5].MType->mtype; + if ( v6 > MON_FALSWORDA ) + { + v9 = v6 - 13; + v8 = v9 == 0; + } + else + { + if ( v6 == MON_FALSWORDA || (v7 = v6 - 4) == 0 ) + { + v11 = 7; + goto LABEL_15; + } + v9 = v7 - 1; + v8 = v9 == 0; + } + if ( v8 ) + { + v11 = 5; + } + else + { + v10 = v9 - 1; + if ( v10 ) + { + if ( v10 != 1 ) + goto LABEL_16; + v11 = 2; + } + else + { + v11 = 3; + } + } +LABEL_15: + v4 = v11; +LABEL_16: + if ( monster[v5]._mAi == MG_FALLEN + && v4 + && abs(x1 - monster[v5]._mx) < 5 + && abs(y1 - monster[v5]._my) < 5 + && (signed int)(monster[v5]._mhitpoints & 0xFFFFFFC0) > 0 ) + { + _LOBYTE(monster[v5]._mgoal) = 2; + monster[v5]._mgoalvar1 = v4; + monster[v5]._mdir = GetDirection(x1, y1, *v3, v3[1]); + } + v3 += 57; + v2 = v12++ + 1; + } + while ( v12 < nummonsters ); + } +} + +//----- (00439F92) -------------------------------------------------------- +void __fastcall PrintMonstHistory(int mt) +{ + int v1; // edi + int *v2; // ebx + int v3; // ecx + int v4; // eax + int v5; // edi + short v6; // bx + int v7; // ebx + + v1 = mt; + v2 = &monstkills[mt]; + sprintf(tempstr, "Total kills : %i", *v2); + AddPanelString(tempstr, 1); + if ( *v2 >= 30 ) + { + v3 = monsterdata[v1].mMinHP; + v4 = monsterdata[v1].mMaxHP; + if ( gbMaxPlayers == 1 ) + { + v3 = monsterdata[v1].mMinHP >> 1; + v4 = monsterdata[v1].mMaxHP >> 1; + } + if ( v3 < 1 ) + v3 = 1; + if ( v4 < 1 ) + v4 = 1; + if ( gnDifficulty == 1 ) + { + v3 = 3 * v3 + 1; + v4 = 3 * v4 + 1; + } + if ( gnDifficulty == DIFF_HELL ) + { + v3 = 4 * v3 + 3; + v4 = 4 * v4 + 3; + } + sprintf(tempstr, "Hit Points : %i-%i", v3, v4); + AddPanelString(tempstr, 1); + } + if ( *v2 >= 15 ) + { + v5 = v1 << 7; + if ( gnDifficulty == DIFF_HELL ) + v6 = *(short *)((char *)&monsterdata[0].mMagicRes2 + v5); + else + v6 = *(short *)((char *)&monsterdata[0].mMagicRes + v5); + v7 = v6 & 0x3F; + if ( v7 ) + { + if ( v7 & 7 ) + { + strcpy(tempstr, "Resists : "); + if ( v7 & 1 ) + strcat(tempstr, "Magic "); + if ( v7 & 2 ) + strcat(tempstr, "Fire "); + if ( v7 & 4 ) + strcat(tempstr, "Lightning "); + *(_BYTE *)(strlen(tempstr) + 4950091) = 0; + AddPanelString(tempstr, 1); + } + if ( v7 & 0x38 ) + { + strcpy(tempstr, "Immune : "); + if ( v7 & 8 ) + strcat(tempstr, "Magic "); + if ( v7 & 0x10 ) + strcat(tempstr, "Fire "); + if ( v7 & 0x20 ) + strcat(tempstr, "Lightning "); + *(_BYTE *)(strlen(tempstr) + 4950091) = 0; + AddPanelString(tempstr, 1); + } + } + else + { + strcpy(tempstr, "No magic resistance"); + AddPanelString(tempstr, 1); + } + } + pinfoflag = 1; +} +// 4B8824: using guessed type int pinfoflag; +// 679660: using guessed type char gbMaxPlayers; + +//----- (0043A13A) -------------------------------------------------------- +void __cdecl PrintUniqueHistory() +{ + char v0; // bl + + v0 = monster[*(_DWORD *)&pcursmonst].mMagicRes & 0x3F; + if ( v0 ) + { + if ( monster[*(_DWORD *)&pcursmonst].mMagicRes & 7 ) + strcpy(tempstr, "Some Magic Resistances"); + else + strcpy(tempstr, "No resistances"); + AddPanelString(tempstr, 1); + if ( v0 & 0x38 ) + { + strcpy(tempstr, "Some Magic Immunities"); + goto LABEL_4; + } + } + else + { + strcpy(tempstr, "No resistances"); + AddPanelString(tempstr, 1); + } + strcpy(tempstr, "No Immunities"); +LABEL_4: + AddPanelString(tempstr, 1); + pinfoflag = 1; +} +// 4B8824: using guessed type int pinfoflag; + +//----- (0043A1C1) -------------------------------------------------------- +void __fastcall MissToMonst(int i, int x, int y) +{ + int v3; // edi + MissileStruct *v4; // edi + unsigned int v5; // ebx + MonsterStruct *v6; // esi + int v7; // edx + char v8; // al + int v9; // eax + char *v10; // edi + int v11; // eax + int v12; // edx + char v13; // al + char v14; // al + int v15; // ebx + int v16; // eax + int v17; // esi + int v18; // edi + int v19; // esi + int v20; // edx + int *v21; // ebx + char v22; // cl + char v23; // al + int v24; // esi + int v25; // edi + int v26; // esi + int v27; // eax + int v28; // eax + int ia; // [esp+Ch] [ebp-10h] + int v30; // [esp+10h] [ebp-Ch] + int v31; // [esp+14h] [ebp-8h] + int v32; // [esp+18h] [ebp-4h] + int arglist; // [esp+24h] [ebp+8h] + + v3 = i; + v30 = x; + if ( (unsigned int)i >= 0x7D ) + TermMsg("MissToMonst: Invalid missile %d", i); + v4 = &missile[v3]; + v5 = v4->_misource; + ia = v4->_misource; + if ( v5 >= 0xC8 ) + TermMsg("MissToMonst: Invalid monster %d", v5); + v32 = v4->_mix; + v31 = v4->_miy; + v6 = &monster[v5]; + v6->_mx = v30; + dMonster[0][y + 112 * v30] = v5 + 1; + v7 = v4->_mimfnum; + v6->_mdir = v7; + v6->_my = y; + M_StartStand(v5, v7); + v8 = v6->MType->mtype; + if ( v8 < MON_FIREMANA || v8 > MON_FIREMAND ) + { + if ( v6->_mFlags & 0x10 ) + M2MStartHit(v5, -1, 0); + else + M_StartHit(v5, -1, 0); + } + else + { + M_StartFadein(v5, v6->_mdir, 0); + } + v9 = v32; + if ( v6->_mFlags & 0x10 ) + { + v21 = (int *)((char *)dMonster + 4 * (v31 + v9 * 112)); + if ( *v21 > 0 ) + { + v22 = v6->MType->mtype; + if ( v22 != MON_BATC && (v22 < MON_FIREMANA || v22 > MON_FIREMAND) ) + { + M_TryM2MHit(ia, *v21 - 1, 500, (unsigned char)v6->mMinDamage2, (unsigned char)v6->mMaxDamage2); + v23 = v6->MType->mtype; + if ( v23 < MON_SNAKEA || v23 > MON_SNAKED ) + { + v24 = v6->_mdir; + v25 = v32 + offset_x[v24]; + v26 = v31 + offset_y[v24]; + if ( PosOkMonst(*v21 - 1, v25, v26) ) + { + v27 = *v21; + dMonster[0][v26 + 112 * v25] = *v21; + *v21 = 0; + v28 = v27 - 1; + monster[v28]._mx = v25; + monster[v28]._mfutx = v25; + monster[v28]._my = v26; + monster[v28]._mfuty = v26; + } + } + } + } + } + else + { + v10 = &dPlayer[v9][v31]; + v11 = *v10; + v12 = v11 - 1; + arglist = v11 - 1; + if ( *v10 > 0 ) + { + v13 = v6->MType->mtype; + if ( v13 != MON_BATC && (v13 < MON_FIREMANA || v13 > MON_FIREMAND) ) + { + M_TryH2HHit(v5, v12, 500, (unsigned char)v6->mMinDamage2, (unsigned char)v6->mMaxDamage2); + if ( arglist == *v10 - 1 ) + { + v14 = v6->MType->mtype; + if ( v14 < MON_SNAKEA || v14 > MON_SNAKED ) + { + v15 = arglist; + v16 = plr[arglist]._pmode; + if ( v16 != 7 && v16 != 8 ) + StartPlrHit(arglist, 0, 1u); + v17 = v6->_mdir; + v18 = v32 + offset_x[v17]; + v19 = v31 + offset_y[v17]; + if ( PosOkPlayer(arglist, v18, v19) ) + { + v20 = plr[v15]._pdir; + plr[v15].WorldX = v18; + plr[v15].WorldY = v19; + FixPlayerLocation(arglist, v20); + FixPlrWalkTags(arglist); + dPlayer[v18][v19] = arglist + 1; + SetPlayerOld(arglist); + } + } + } + } + } + } +} + +//----- (0043A45E) -------------------------------------------------------- +int __fastcall PosOkMonst(int i, int x, int y) +{ + int v3; // edi + signed int v4; // ebx + int v5; // ecx + char v6; // dl + int result; // eax + int v8; // edx + int v9; // ecx + int v10; // [esp+Ch] [ebp-4h] + + v3 = x; + v10 = i; + v4 = 0; + if ( SolidLoc(x, y) ) + return 0; + v5 = 112 * v3; + if ( dPlayer[v3][y] || dMonster[0][v5 + y] ) + return 0; + v6 = dObject[0][v5 + y]; + result = 1; + if ( v6 ) + { + v8 = v6 <= 0 ? -1 - v6 : v6 - 1; + if ( object[v8]._oSolidFlag ) + return 0; + } + _LOBYTE(v5) = dMissile[0][v5 + y]; + if ( (_BYTE)v5 ) + { + if ( v10 >= 0 ) + { + v5 = (char)v5; + if ( (char)v5 > 0 ) + { + if ( missile[v5]._mitype == 5 ) + goto LABEL_24; + v9 = 0; + if ( nummissiles > 0 ) + { + do + { + if ( missile[missileactive[v9]]._mitype == 5 ) + v4 = 1; + ++v9; + } + while ( v9 < nummissiles ); + if ( v4 ) + { +LABEL_24: + if ( !(monster[v10].mMagicRes & 0x10) || monster[v10].MType->mtype == MON_DIABLO ) + return 0; + } + } + } + } + } + return result; +} + +//----- (0043A547) -------------------------------------------------------- +int __fastcall PosOkMonst2(int i, int x, int y) +{ + int v3; // edi + int v4; // ebx + signed int v5; // ebp + int result; // eax + char v7; // dl + int v8; // edx + int v9; // ecx + int v10; // ecx + + v3 = x; + v4 = i; + v5 = 0; + result = SolidLoc(x, y) == 0; + if ( result ) + { + v7 = dObject[v3][y]; + if ( v7 ) + { + v8 = v7 <= 0 ? -1 - v7 : v7 - 1; + if ( object[v8]._oSolidFlag ) + result = 0; + } + if ( result ) + { + _LOBYTE(v9) = dMissile[v3][y]; + if ( (_BYTE)v9 ) + { + if ( v4 >= 0 ) + { + v9 = (char)v9; + if ( (char)v9 > 0 ) + { + if ( missile[v9]._mitype == 5 ) + goto LABEL_23; + v10 = 0; + if ( nummissiles > 0 ) + { + do + { + if ( missile[missileactive[v10]]._mitype == 5 ) + v5 = 1; + ++v10; + } + while ( v10 < nummissiles ); + if ( v5 ) + { +LABEL_23: + if ( !(monster[v4].mMagicRes & 0x10) || monster[v4].MType->mtype == MON_DIABLO ) + result = 0; + } + } + } + } + } + } + } + return result; +} + +//----- (0043A613) -------------------------------------------------------- +int __fastcall PosOkMonst3(int i, int x, int y) +{ + int v3; // esi + signed int v4; // ebp + char v5; // al + int v6; // eax + int v7; // eax + int v8; // ecx + int v9; // ecx + int result; // eax + int v11; // ecx + signed int v12; // [esp+10h] [ebp-8h] + int v13; // [esp+14h] [ebp-4h] + + v12 = 0; + v3 = x; + v4 = 0; + v13 = i; + v5 = dObject[x][y]; + if ( v5 ) + { + if ( v5 <= 0 ) + v6 = -1 - v5; + else + v6 = v5 - 1; + v7 = v6; + v8 = object[v7]._otype; + v4 = 1; + if ( v8 != 1 + && v8 != OBJ_L1RDOOR + && v8 != OBJ_L2LDOOR + && v8 != OBJ_L2RDOOR + && v8 != OBJ_L3LDOOR + && v8 != OBJ_L3RDOOR ) + { + v4 = 0; + } + if ( object[v7]._oSolidFlag && !v4 ) + return 0; + } + if ( SolidLoc(x, y) && !v4 || dPlayer[v3][y] || dMonster[0][v3 * 112 + y] ) + return 0; + _LOBYTE(v9) = dMissile[v3][y]; + result = 1; + if ( (_BYTE)v9 ) + { + if ( v13 >= 0 ) + { + v9 = (char)v9; + if ( (char)v9 > 0 ) + { + if ( missile[v9]._mitype == 5 ) + goto LABEL_33; + v11 = 0; + if ( nummissiles > 0 ) + { + do + { + if ( missile[missileactive[v11]]._mitype == 5 ) + v12 = 1; + ++v11; + } + while ( v11 < nummissiles ); + if ( v12 ) + { +LABEL_33: + if ( !(monster[v13].mMagicRes & 0x10) || monster[v13].MType->mtype == MON_DIABLO ) + return 0; + } + } + } + } + } + return result; +} + +//----- (0043A73B) -------------------------------------------------------- +BOOL __fastcall IsSkel(int mt) +{ + return mt >= MON_SKELAXEA && mt <= MON_SKELAXED + || mt >= MON_SKELBOWA && mt <= MON_SKELBOWD + || mt >= MON_SKELSDA && mt <= MON_SKELSDD; +} + +//----- (0043A760) -------------------------------------------------------- +BOOL __fastcall IsGoat(int mt) +{ + return mt >= MON_GOATMACEA && mt <= MON_GOATMACED || mt >= MON_GOATBOWA && mt <= MON_GOATBOWD; +} + +//----- (0043A77B) -------------------------------------------------------- +int __fastcall M_SpawnSkel(int x, int y, int dir) +{ + CMonster *v3; // ebx + CMonster *v4; // esi + int v5; // edx + int v6; // ecx + int v7; // esi + int v8; // edx + int v9; // eax + int v10; // esi + int xa; // [esp+Ch] [ebp-10h] + int ya; // [esp+10h] [ebp-Ch] + int v14; // [esp+14h] [ebp-8h] + int v15; // [esp+18h] [ebp-4h] + int v16; // [esp+18h] [ebp-4h] + + ya = y; + xa = x; + if ( nummtypes <= 0 ) + return -1; + v3 = Monsters; + v15 = nummtypes; + v4 = Monsters; + do + { + if ( IsSkel((unsigned char)v4->mtype) ) + ++v5; + ++v4; + --v15; + } + while ( v15 ); + if ( !v5 ) + return -1; + _LOBYTE(v6) = -120; + v7 = 0; + v14 = random(v6, v5); + v16 = 0; + if ( nummtypes > 0 ) + { + do + { + if ( v16 > v14 ) + break; + if ( IsSkel((unsigned char)v3->mtype) ) + ++v16; + ++v7; + ++v3; + } + while ( v7 < v8 ); + } + v9 = AddMonster(xa, ya, dir, v7 - 1, 1); + v10 = v9; + if ( v9 != -1 ) + M_StartSpStand(v9, dir); + return v10; +} + +//----- (0043A828) -------------------------------------------------------- +void __fastcall ActivateSpawn(int i, int x, int y, int dir) +{ + int v4; // eax + + dMonster[0][y + 112 * x] = i + 1; + v4 = i; + monster[v4]._mx = x; + monster[v4]._mfutx = x; + monster[v4]._moldx = x; + monster[v4]._my = y; + monster[v4]._mfuty = y; + monster[v4]._moldy = y; + M_StartSpStand(i, dir); +} + +//----- (0043A879) -------------------------------------------------------- +int __fastcall SpawnSkeleton(int ii, int x, int y) +{ + int v3; // esi + int v4; // ebx + int v5; // ST04_4 + int v6; // ecx + int v7; // edi + int *v8; // esi + int v9; // eax + int v11; // eax + int v12; // ecx + int v13; // edx + int v14; // esi + int v15; // edi + int v16; // ST04_4 + int v17[9]; // [esp+Ch] [ebp-34h] + int i; // [esp+30h] [ebp-10h] + int x2; // [esp+34h] [ebp-Ch] + int v20; // [esp+38h] [ebp-8h] + int *v21; // [esp+3Ch] [ebp-4h] + int a3; // [esp+48h] [ebp+8h] + int a3a; // [esp+48h] [ebp+8h] + + i = ii; + v3 = x; + x2 = x; + if ( ii == -1 ) + return 0; + v4 = y; + if ( !PosOkMonst(-1, x, y) ) + { + v20 = 0; + v6 = y - 1; + a3 = y - 1; + if ( (unsigned char)(__OFSUB__(v4 - 1, v4 + 1) ^ 1) | (v4 - 1 == v4 + 1) ) + { + v21 = v17; + do + { + v7 = v3 - 1; + if ( (unsigned char)(__OFSUB__(v3 - 1, v3 + 1) ^ 1) | (v3 - 1 == v3 + 1) ) + { + v8 = v21; + do + { + v9 = PosOkMonst(-1, v7, a3); + v20 |= v9; + *v8 = v9; + v8 += 3; + ++v7; + } + while ( v7 <= x2 + 1 ); + v3 = x2; + } + ++v21; + ++a3; + } + while ( a3 <= v4 + 1 ); + if ( v20 ) + { + _LOBYTE(v6) = -119; + v11 = random(v6, 15); + v12 = 0; + v13 = 0; + a3a = v11 + 1; + if ( v11 + 1 > 0 ) + { + while ( 1 ) + { + if ( v17[v13 + 2 * v12 + v12] ) + --a3a; + if ( a3a <= 0 ) + break; + if ( ++v12 == 3 ) + { + v12 = 0; + if ( ++v13 == 3 ) + v13 = 0; + } + } + } + v14 = v12 + v3 - 1; + v15 = v13 + v4 - 1; + v16 = GetDirection(v14, v15, x2, v4); + ActivateSpawn(i, v14, v15, v16); + return 1; + } + } + return 0; + } + v5 = GetDirection(v3, y, v3, y); + ActivateSpawn(i, v3, y, v5); + return 1; +} +// 43A879: using guessed type int var_34[9]; + +//----- (0043A979) -------------------------------------------------------- +int __cdecl PreSpawnSkeleton() +{ + CMonster *v0; // edi + int v1; // ebp + CMonster *v2; // esi + int v3; // edx + int v4; // ecx + int v5; // eax + int v6; // esi + int v7; // ebp + int v8; // edx + int v9; // edx + int v10; // eax + int v11; // esi + int i; // [esp+10h] [ebp-4h] + + if ( nummtypes <= 0 ) + return -1; + v0 = Monsters; + v1 = nummtypes; + v2 = Monsters; + do + { + if ( IsSkel((unsigned char)v2->mtype) ) + ++v3; + ++v2; + --v1; + } + while ( v1 ); + if ( !v3 ) + return -1; + _LOBYTE(v4) = -120; + v5 = random(v4, v3); + v6 = nummtypes; + v7 = 0; + v8 = 0; + for ( i = v5; v8 < v6; ++v0 ) + { + if ( v7 > i ) + break; + if ( IsSkel((unsigned char)v0->mtype) ) + ++v7; + v8 = v9 + 1; + } + v10 = AddMonster(0, 0, 0, v8 - 1, 0); + v11 = v10; + if ( v10 != -1 ) + M_StartStand(v10, 0); + return v11; +} + +//----- (0043AA0C) -------------------------------------------------------- +void __fastcall TalktoMonster(int i) +{ + int v1; // esi + MonsterStruct *v2; // esi + char v3; // al + int v4; // edi + int v5; // eax + int v6; // eax + int inv_item_num; // [esp+8h] [ebp-4h] + + v1 = i; + if ( (unsigned int)i >= 0xC8 ) + TermMsg("TalktoMonster: Invalid monster %d", i); + v2 = &monster[v1]; + v3 = v2->_mAi; + v4 = v2->_menemy; + v2->_mmode = MM_TALK; + if ( v3 == MG_SNOTSPIL || v3 == MG_LACHDANAN ) + { + _LOBYTE(v5) = QuestStatus(7); + if ( v5 && quests[7]._qvar1 == 2 && PlrHasItem(v4, IDI_BANNER, &inv_item_num) ) + { + RemoveInvItem(v4, inv_item_num); + quests[7]._qactive = 3; + v2->mtalkmsg = TEXT_SNOT3; + _LOBYTE(v2->_mgoal) = 6; + } + _LOBYTE(v6) = QuestStatus(4); + if ( v6 && v2->mtalkmsg >= (signed int)TEXT_LACH1 ) + { + if ( PlrHasItem(v4, IDI_GLDNELIX, &inv_item_num) ) + { + RemoveInvItem(v4, inv_item_num); + v2->mtalkmsg = TEXT_LACH3; + _LOBYTE(v2->_mgoal) = 6; + } + } + } +} + +//----- (0043AADA) -------------------------------------------------------- +void __fastcall SpawnGolum(int i, int x, int y, int mi) +{ + int v4; // edi + int v5; // ebx + int v6; // esi + int v7; // eax + int *v8; // edx + int v9; // eax + char v10; // cl + int v11; // eax + + v4 = i; + v5 = x; + if ( (unsigned int)i >= 0xC8 ) + TermMsg("SpawnGolum: Invalid monster %d", i); + v6 = v4; + monster[v6]._mx = v5; + monster[v6]._my = y; + monster[v6]._mfuty = y; + monster[v6]._moldy = y; + monster[v6]._mfutx = v5; + monster[v6]._moldx = v5; + v7 = plr[v4]._pMaxMana; + dMonster[0][y + 112 * v5] = v4 + 1; + _LOBYTE(monster[v6]._pathcount) = 0; + monster[v6]._mFlags |= 0x20u; + v8 = &missile[mi]._mispllvl; + monster[v6].mArmorClass = 25; + v9 = 320 * *v8 + v7 / 3; + v10 = *(_BYTE *)v8; + _LOBYTE(v8) = plr[v4]._pLevel; + v9 *= 2; + monster[v6]._mmaxhp = v9; + monster[v6]._mhitpoints = v9; + monster[v6].mHit = 5 * (v10 + 8) + 2 * (_BYTE)v8; + monster[v6].mMinDamage = 2 * (v10 + 4); + monster[v6].mMaxDamage = 2 * (v10 + 8); + M_StartSpStand(v4, 0); + M_Enemy(v4); + if ( v4 == myplr ) + { + _LOBYTE(v11) = currlevel; + NetSendCmdGolem( + monster[v6]._mx, + monster[v6]._my, + monster[v6]._mdir, + monster[v6]._menemy, + monster[v6]._mhitpoints, + v11); + } +} + +//----- (0043AC0C) -------------------------------------------------------- +unsigned char __fastcall CanTalkToMonst(int m) +{ + int v1; // esi + char v2; // al + unsigned char result; // al + + v1 = m; + if ( (unsigned int)m >= 0xC8 ) + TermMsg("CanTalkToMonst: Invalid monster %d", m); + v2 = monster[v1]._mgoal; + if ( v2 == 6 ) + result = 1; + else + result = v2 == 7; + return result; +} + +//----- (0043AC43) -------------------------------------------------------- +unsigned char __fastcall CheckMonsterHit(int m, unsigned char *ret) +{ + int v2; // edi + unsigned char *v3; // esi + int v4; // ecx + int v5; // eax + unsigned char result; // al + unsigned char v7; // al + + v2 = m; + v3 = ret; + if ( (unsigned int)m >= 0xC8 ) + TermMsg("CheckMonsterHit: Invalid monster %d", m); + v4 = v2; + if ( monster[v2]._mAi == MG_GARG && (v5 = monster[v4]._mFlags, v5 & 4) ) + { + _LOBYTE(v5) = v5 & 0xFB; + monster[v4]._mmode = MM_SATTACK; + monster[v4]._mFlags = v5; + result = 1; + *(_DWORD *)v3 = 1; + } + else + { + v7 = monster[v4].MType->mtype; + if ( v7 < MON_MAGEA || v7 > MON_MAGED || (result = 1, _LOBYTE(monster[v4]._mgoal) == 1) ) + result = 0; + else + *(_DWORD *)v3 = 0; + } + return result; +} + +//----- (0043ACB5) -------------------------------------------------------- +int __cdecl encode_enemy(int m) +{ + int v1; // ecx + int v2; // ecx + int result; // eax + + v2 = v1; + result = monster[v2]._menemy; + if ( monster[v2]._mFlags & 0x10 ) + result += 4; + return result; +} + +//----- (0043ACCE) -------------------------------------------------------- +void __fastcall decode_enemy(int m, int enemy) +{ + int v2; // eax + int v3; // edx + char v4; // cl + int v5; // edx + + v2 = m; + if ( enemy >= 4 ) + { + monster[v2]._mFlags |= 0x10u; + v5 = enemy - 4; + monster[v2]._menemy = v5; + monster[v2]._menemyx = monster[v5]._mfutx; + v4 = monster[v5]._mfuty; + } + else + { + monster[v2]._mFlags &= 0xFFFFFFEF; + monster[v2]._menemy = enemy; + v3 = enemy; + monster[v2]._menemyx = plr[v3]._px; + v4 = plr[v3]._py; + } + monster[v2]._menemyy = v4; +} + +//----- (0043AD38) -------------------------------------------------------- +void __cdecl movie_cpp_init() +{ + movie_cpp_init_value = movie_inf; +} +// 47F144: using guessed type int movie_inf; +// 659AF4: using guessed type int movie_cpp_init_value; + +//----- (0043AD43) -------------------------------------------------------- +void __fastcall play_movie(char *pszMovie, bool user_can_close) +{ + char *v2; // esi + LRESULT (__stdcall *v3)(HWND, UINT, WPARAM, LPARAM); // edi + int v4; // eax + MSG Msg; // [esp+8h] [ebp-24h] + BOOL v6; // [esp+24h] [ebp-8h] + void *video_stream; // [esp+28h] [ebp-4h] + + v6 = user_can_close; + v2 = pszMovie; + if ( window_activated ) + { + v3 = SetWindowProc(MovieWndProc); + InvalidateRect(ghMainWnd, 0, 0); + UpdateWindow(ghMainWnd); + _LOBYTE(movie_playing) = 1; + sound_disable_music(1); + sfx_stop(); + effects_play_sound("Sfx\\Misc\\blank.wav"); + SVidPlayBegin(v2, 0, 0, 0, 0, loop_movie != 0 ? 0x100C0808 : 0x10280808, &video_stream); + if ( video_stream ) + { + do + { + if ( !window_activated || v6 && !(_BYTE)movie_playing ) + break; + while ( PeekMessageA(&Msg, 0, 0, 0, 1u) ) + { + if ( Msg.message != WM_QUIT ) + { + TranslateMessage(&Msg); + DispatchMessageA(&Msg); + } + } + _LOBYTE(v4) = SVidPlayContinue(); + if ( !v4 ) + break; + } + while ( video_stream ); + if ( video_stream ) + SVidPlayEnd(video_stream); + } + SetWindowProc(v3); + sound_disable_music(0); + } +} +// 634980: using guessed type int window_activated; +// 659AF8: using guessed type int movie_playing; +// 659AFC: using guessed type int loop_movie; + +//----- (0043AE3E) -------------------------------------------------------- +LRESULT __stdcall MovieWndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) +{ + if ( Msg == WM_KEYFIRST || Msg == WM_CHAR ) + { +LABEL_6: + _LOBYTE(movie_playing) = 0; + return init_palette(hWnd, Msg, wParam, lParam); + } + if ( Msg != WM_SYSCOMMAND ) + { + if ( Msg != WM_LBUTTONDOWN && Msg != WM_RBUTTONDOWN ) + return init_palette(hWnd, Msg, wParam, lParam); + goto LABEL_6; + } + if ( wParam != SC_CLOSE ) + return init_palette(hWnd, Msg, wParam, lParam); + _LOBYTE(movie_playing) = 0; + return 0; +} +// 659AF8: using guessed type int movie_playing; + +//----- (0043AE95) -------------------------------------------------------- +void __cdecl mpqapi_cpp_init() +{ + mpqapi_cpp_init_value = mpqapi_inf; +} +// 47F148: using guessed type int mpqapi_inf; +// 659B00: using guessed type int mpqapi_cpp_init_value; + +//----- (0043AEA0) -------------------------------------------------------- +bool __fastcall mpqapi_set_hidden(char *save_path, bool hidden) +{ + char *v2; // edi + BOOL v3; // esi + DWORD v4; // eax + bool result; // al + DWORD v6; // esi + + v2 = save_path; + v3 = hidden; + v4 = GetFileAttributesA(save_path); + if ( v4 == -1 ) + return GetLastError() == ERROR_FILE_NOT_FOUND; + v6 = v3 != 0 ? 6 : 0; + if ( v4 == v6 ) + result = 1; + else + result = SetFileAttributesA(v2, v6); + return result; +} + +//----- (0043AEDC) -------------------------------------------------------- +void __fastcall mpqapi_store_creation_time(char *save_path, int save_num) +{ + int v2; // esi + char *v3; // ebx + HANDLE v4; // eax + int v5; // esi + struct _WIN32_FIND_DATAA FindFileData; // [esp+8h] [ebp-1E0h] + char dst[160]; // [esp+148h] [ebp-A0h] + + v2 = save_num; + v3 = save_path; + if ( gbMaxPlayers != 1 ) + { + mpqapi_reg_load_modification_time(dst, 160); + v4 = FindFirstFileA(v3, &FindFileData); + if ( v4 != (HANDLE)-1 ) + { + FindClose(v4); + v5 = 16 * v2; + *(_DWORD *)&dst[v5] = FindFileData.ftCreationTime.dwLowDateTime; + *(_DWORD *)&dst[v5 + 4] = FindFileData.ftCreationTime.dwHighDateTime; + mpqapi_reg_store_modification_time(dst, 160); + } + } +} +// 679660: using guessed type char gbMaxPlayers; + +//----- (0043AF4F) -------------------------------------------------------- +bool __fastcall mpqapi_reg_load_modification_time(char *dst, int size) +{ + unsigned int v2; // esi + char *v3; // edi + int v4; // eax + unsigned int v6; // esi + char *v7; // ecx + int nbytes_read; // [esp+8h] [ebp-4h] + + v2 = size; + v3 = dst; + memset(dst, 0, size); + _LOBYTE(v4) = SRegLoadData("Diablo", "Video Player ", 0, (unsigned char *)v3, v2, (unsigned long *)&nbytes_read); + if ( !v4 || nbytes_read != v2 ) + return 0; + if ( v2 >= 8 ) + { + v6 = v2 >> 3; + do + { + v7 = v3; + v3 += 8; + mpqapi_xor_buf(v7); + --v6; + } + while ( v6 ); + } + return 1; +} + +//----- (0043AFA5) -------------------------------------------------------- +void __fastcall mpqapi_xor_buf(char *buf) +{ + signed int v1; // eax + char *v2; // esi + signed int v3; // edi + + v1 = 0xF0761AB; + v2 = buf; + v3 = 8; + do + { + *v2 ^= v1; + ++v2; + v1 = _rotl(v1, 1); + --v3; + } + while ( v3 ); +} + +//----- (0043AFC4) -------------------------------------------------------- +bool __fastcall mpqapi_reg_store_modification_time(char *src, int len) +{ + int v2; // ebx + char *v3; // ebp + char *v4; // edi + unsigned int v5; // esi + char *v6; // ecx + + v2 = len; + v3 = src; + v4 = src; + if ( (unsigned int)len >= 8 ) + { + v5 = (unsigned int)len >> 3; + do + { + v6 = v4; + v4 += 8; + mpqapi_xor_buf(v6); + --v5; + } + while ( v5 ); + } + return SRegSaveData("Diablo", "Video Player ", 0, (unsigned char *)v3, v2); +} + +//----- (0043B002) -------------------------------------------------------- +void __fastcall mpqapi_remove_hash_entry(char *path) +{ + int v1; // eax + _BLOCKENTRY *v2; // ecx + _BLOCKENTRY *v3; // eax + int v4; // esi + int v5; // edi + + v1 = mpqapi_get_hash_index_of_path(path); + if ( v1 != -1 ) + { + v2 = &sgpHashTbl[v1]; + v3 = &sgpBlockTbl[v2->flags]; + v2->flags = -2; + v4 = v3->offset; + v5 = v3->sizealloc; + memset(v3, 0, 0x10u); + mpqapi_alloc_block(v4, v5); + dword_65AB0C = 1; + } +} +// 65AB0C: using guessed type int dword_65AB0C; + +//----- (0043B054) -------------------------------------------------------- +void __fastcall mpqapi_alloc_block(int block_offset, int block_size) +{ + int v2; // esi + int v3; // edi + _BLOCKENTRY *v4; // eax + signed int v5; // edx + signed int v6; // ecx + int v7; // ecx + bool v8; // zf + _BLOCKENTRY *v9; // eax + + v2 = block_size; + v3 = block_offset; +LABEL_2: + v4 = sgpBlockTbl; + v5 = 2048; + while ( 1 ) + { + v6 = v5--; + if ( !v6 ) + break; + v7 = v4->offset; + if ( v4->offset && !v4->flags && !v4->sizefile ) + { + if ( v7 + v4->sizealloc == v3 ) + { + v3 = v4->offset; +LABEL_11: + v2 += v4->sizealloc; + memset(v4, 0, 0x10u); + goto LABEL_2; + } + if ( v3 + v2 == v7 ) + goto LABEL_11; + } + ++v4; + } + v8 = v3 + v2 == lDistanceToMove; + if ( v3 + v2 > (unsigned int)lDistanceToMove ) + { + TermMsg("MPQ free list error"); + v8 = v3 + v2 == lDistanceToMove; + } + if ( v8 ) + { + lDistanceToMove = v3; + } + else + { + v9 = mpqapi_new_block(0); + v9->offset = v3; + v9->sizealloc = v2; + v9->sizefile = 0; + v9->flags = 0; + } +} + +//----- (0043B0E4) -------------------------------------------------------- +_BLOCKENTRY *__fastcall mpqapi_new_block(int *block_index) +{ + _BLOCKENTRY *result; // eax + unsigned int v2; // edx + + result = sgpBlockTbl; + v2 = 0; + while ( result->offset || result->sizealloc || result->flags || result->sizefile ) + { + ++v2; + ++result; + if ( v2 >= 0x800 ) + { + TermMsg("Out of free block entries"); + return 0; + } + } + if ( block_index ) + *block_index = v2; + return result; +} + +//----- (0043B123) -------------------------------------------------------- +int __fastcall mpqapi_get_hash_index_of_path(char *path) +{ + char *v1; // esi + int v2; // ST00_4 + int v3; // edi + short v4; // ax + + v1 = path; + v2 = encrypt_hash(path, 2); + v3 = encrypt_hash(v1, 1); + v4 = encrypt_hash(v1, 0); + return mpqapi_get_hash_index(v4, v3, v2, 0); +} + +//----- (0043B153) -------------------------------------------------------- +int __fastcall mpqapi_get_hash_index(short index, int hash_a, int hash_b, int locale) +{ + int v4; // ecx + signed int v5; // eax + signed int v6; // edx + _BLOCKENTRY *v7; // ecx + int v8; // edi + int v10; // [esp+Ch] [ebp-8h] + int i; // [esp+10h] [ebp-4h] + + v4 = index & 0x7FF; + v10 = hash_a; + v5 = 2048; + for ( i = v4; ; i = (i + 1) & 0x7FF ) + { + v7 = &sgpHashTbl[v4]; + v8 = v7->flags; + if ( v8 == -1 ) + return -1; + v6 = v5--; + if ( !v6 ) + return -1; + if ( v7->offset == v10 && v7->sizealloc == hash_b && v7->sizefile == locale && v8 != -2 ) + break; + v4 = (i + 1) & 0x7FF; + } + return i; +} + +//----- (0043B1BD) -------------------------------------------------------- +void __fastcall mpqapi_remove_hash_entries(bool (__stdcall *get_file_name)(int lvl, char *file_name)) +{ + bool (__stdcall *v1)(int, char *); // edi + signed int v2; // esi + int i; // eax + int v4; // eax + char v5[260]; // [esp+8h] [ebp-104h] + + v1 = get_file_name; + v2 = 1; + for ( i = get_file_name(0, v5); i; i = v1(v4, v5) ) + { + mpqapi_remove_hash_entry(v5); + v4 = v2++; + } +} + +//----- (0043B1F8) -------------------------------------------------------- +bool __fastcall mpqapi_write_file(char *file_name, char *buf, int len) +{ + char *v3; // edi + char *v4; // esi + _BLOCKENTRY *v5; // eax + int v6; // eax + + v3 = buf; + v4 = file_name; + dword_65AB0C = 1; + mpqapi_remove_hash_entry(file_name); + v5 = mpqapi_add_file(v4, 0, 0); + _LOBYTE(v6) = mpqapi_write_file_contents(v4, v3, len, v5); + if ( v6 ) + return 1; + mpqapi_remove_hash_entry(v4); + return 0; +} +// 65AB0C: using guessed type int dword_65AB0C; + +//----- (0043B23D) -------------------------------------------------------- +_BLOCKENTRY *__fastcall mpqapi_add_file(char *path, _BLOCKENTRY *block, int block_index) +{ + char *v3; // edi + short v4; // si + int v5; // ebx + signed int v6; // edx + int v7; // esi + int v8; // ecx + int v9; // esi + int v11; // [esp+Ch] [ebp-8h] + _BLOCKENTRY *v12; // [esp+10h] [ebp-4h] + + v12 = block; + v3 = path; + v4 = encrypt_hash(path, 0); + v5 = encrypt_hash(v3, 1); + v11 = encrypt_hash(v3, 2); + if ( mpqapi_get_hash_index(v4, v5, v11, 0) != -1 ) + TermMsg("Hash collision between \"%s\" and existing file\n", v3); + v6 = 2048; + v7 = v4 & 0x7FF; + while ( 1 ) + { + --v6; + v8 = sgpHashTbl[v7].flags; + if ( v8 == -1 || v8 == -2 ) + break; + v7 = (v7 + 1) & 0x7FF; + if ( !v6 ) + { + v6 = -1; + break; + } + } + if ( v6 < 0 ) + TermMsg("Out of hash space"); + if ( !v12 ) + v12 = mpqapi_new_block(&block_index); + v9 = v7; + sgpHashTbl[v9].offset = v5; + sgpHashTbl[v9].sizealloc = v11; + sgpHashTbl[v9].sizefile = 0; + sgpHashTbl[v9].flags = block_index; + return v12; +} + +//----- (0043B317) -------------------------------------------------------- +bool __fastcall mpqapi_write_file_contents(char *path, char *buf, int len, _BLOCKENTRY *block) +{ + char *v4; // esi + char *v5; // eax + unsigned int v6; // ebx + char *v7; // eax + unsigned int v8; // esi + _BLOCKENTRY *v9; // edi + int v10; // eax + signed int v11; // eax + unsigned int v13; // eax + unsigned int v14; // eax + int v15; // ecx + int size; // [esp+Ch] [ebp-10h] + char *v17; // [esp+10h] [ebp-Ch] + int v18; // [esp+14h] [ebp-8h] + DWORD nNumberOfBytesToWrite; // [esp+18h] [ebp-4h] + + v4 = path; + v17 = buf; + v5 = strchr(path, 58); + v6 = 0; + while ( v5 ) + { + v4 = v5 + 1; + v5 = strchr(v5 + 1, 58); + } + while ( 1 ) + { + v7 = strchr(v4, 92); + if ( !v7 ) + break; + v4 = v7 + 1; + } + encrypt_hash(v4, 3); + v8 = len; + v9 = block; + size = 4 * ((unsigned int)(len + 4095) >> 12) + 4; + nNumberOfBytesToWrite = 4 * ((unsigned int)(len + 4095) >> 12) + 4; + v10 = mpqapi_find_free_block(size + len, &block->sizealloc); + v9->offset = v10; + v9->sizefile = v8; + v9->flags = 0x80000100; + if ( SetFilePointer(sghArchive, v10, 0, 0) == -1 ) + return 0; + block = 0; + v18 = 0; + while ( v8 ) + { + v11 = 0; + do + *((_BYTE *)mpq_buf + v11++) -= 86; + while ( v11 < 4096 ); + len = v8; + if ( v8 >= 0x1000 ) + len = 4096; + memcpy(mpq_buf, v17, len); + v17 += len; + len = encrypt_compress(mpq_buf, len); + if ( !v18 ) + { + nNumberOfBytesToWrite = size; + block = (_BLOCKENTRY *)DiabloAllocPtr(size); + memset(block, 0, nNumberOfBytesToWrite); + if ( !WriteFile(sghArchive, block, nNumberOfBytesToWrite, &nNumberOfBytesToWrite, 0) ) + goto LABEL_25; + v6 += nNumberOfBytesToWrite; + } + *(&block->offset + v18) = v6; + if ( !WriteFile(sghArchive, mpq_buf, len, (LPDWORD)&len, 0) ) + goto LABEL_25; + ++v18; + if ( v8 <= 0x1000 ) + v8 = 0; + else + v8 -= 4096; + v6 += len; + } + *(&block->offset + v18) = v6; + if ( SetFilePointer(sghArchive, -v6, 0, 1u) == -1 + || !WriteFile(sghArchive, block, nNumberOfBytesToWrite, &nNumberOfBytesToWrite, 0) + || SetFilePointer(sghArchive, v6 - nNumberOfBytesToWrite, 0, 1u) == -1 ) + { +LABEL_25: + if ( block ) + mem_free_dbg(block); + return 0; + } + mem_free_dbg(block); + v13 = v9->sizealloc; + if ( v6 < v13 ) + { + v14 = v13 - v6; + if ( v14 >= 0x400 ) + { + v15 = v6 + v9->offset; + v9->sizealloc = v6; + mpqapi_alloc_block(v15, v14); + } + } + return 1; +} + +//----- (0043B51C) -------------------------------------------------------- +int __fastcall mpqapi_find_free_block(int size, int *block_size) +{ + _BLOCKENTRY *v2; // eax + signed int v3; // esi + int result; // eax + int v5; // esi + bool v6; // zf + + v2 = sgpBlockTbl; + v3 = 2048; + while ( 1 ) + { + --v3; + if ( v2->offset ) + { + if ( !v2->flags && !v2->sizefile && v2->sizealloc >= (unsigned int)size ) + break; + } + ++v2; + if ( !v3 ) + { + *block_size = size; + result = lDistanceToMove; + lDistanceToMove += size; + return result; + } + } + v5 = v2->offset; + *block_size = size; + v2->offset += size; + v6 = v2->sizealloc == size; + v2->sizealloc -= size; + if ( v6 ) + memset(v2, 0, 0x10u); + return v5; +} + +//----- (0043B570) -------------------------------------------------------- +void __fastcall mpqapi_rename(char *old_name, char *new_name) +{ + char *v2; // esi + int v3; // eax + _BLOCKENTRY *v4; // eax + int v5; // ST00_4 + _BLOCKENTRY *v6; // edx + + v2 = new_name; + v3 = mpqapi_get_hash_index_of_path(old_name); + if ( v3 != -1 ) + { + v4 = &sgpHashTbl[v3]; + v5 = v4->flags; + v6 = &sgpBlockTbl[v5]; + v4->flags = -2; + mpqapi_add_file(v2, v6, v5); + dword_65AB0C = 1; + } +} +// 65AB0C: using guessed type int dword_65AB0C; + +//----- (0043B5AF) -------------------------------------------------------- +bool __fastcall mpqapi_has_file(char *path) +{ + return mpqapi_get_hash_index_of_path(path) != -1; +} + +//----- (0043B5BF) -------------------------------------------------------- +bool __fastcall mpqapi_open_archive(char *save_path, bool hidden, int save_num) +{ + char *v3; // ebp + BOOL v4; // esi + int v5; // eax + DWORD v6; // edi + int v7; // eax + int v8; // eax + int v10; // eax + char *lpFileName; // [esp+10h] [ebp-70h] + DWORD NumberOfBytesRead; // [esp+14h] [ebp-6Ch] + _DWORD v13[26]; // [esp+18h] [ebp-68h] + + v3 = save_path; + v4 = hidden; + lpFileName = save_path; + encrypt_init_lookup_table(); + _LOBYTE(v5) = mpqapi_set_hidden(v3, v4); + if ( !v5 ) + return 0; + v6 = (unsigned char)gbMaxPlayers > 1u ? 0x80000000 : 0; + byte_65AB14 = 0; + sghArchive = CreateFileA(v3, 0xC0000000, 0, 0, 3u, v6, 0); + if ( sghArchive == (HANDLE)-1 ) + { + sghArchive = CreateFileA(lpFileName, 0xC0000000, 0, 0, 2u, v6 | (v4 != 0 ? 6 : 0), 0); + if ( sghArchive == (HANDLE)-1 ) + return 0; + byte_65AB14 = 1; + dword_65AB0C = 1; + } + if ( !sgpBlockTbl || !sgpHashTbl ) + { + memset(v13, 0, 0x68u); + _LOBYTE(v7) = mpqapi_parse_archive_header((TMPQHeader *)v13, (int *)&lDistanceToMove); + if ( !v7 ) + { +LABEL_15: + mpqapi_close_archive(lpFileName, 1, save_num); + return 0; + } + sgpBlockTbl = (_BLOCKENTRY *)DiabloAllocPtr(0x8000); + memset(sgpBlockTbl, 0, 0x8000u); + if ( v13[7] ) + { + if ( SetFilePointer(sghArchive, 104, 0, 0) == -1 + || !ReadFile(sghArchive, sgpBlockTbl, 0x8000u, &NumberOfBytesRead, 0) ) + { + goto LABEL_15; + } + v8 = encrypt_hash("(block table)", 3); + encrypt_decrypt_block(sgpBlockTbl, 0x8000, v8); + } + sgpHashTbl = (_BLOCKENTRY *)DiabloAllocPtr(0x8000); + memset(sgpHashTbl, 255, 0x8000u); + if ( v13[6] ) + { + if ( SetFilePointer(sghArchive, 32872, 0, 0) == -1 + || !ReadFile(sghArchive, sgpHashTbl, 0x8000u, &NumberOfBytesRead, 0) ) + { + goto LABEL_15; + } + v10 = encrypt_hash("(hash table)", 3); + encrypt_decrypt_block(sgpHashTbl, 0x8000, v10); + } + } + return 1; +} +// 65AB0C: using guessed type int dword_65AB0C; +// 65AB14: using guessed type char byte_65AB14; +// 679660: using guessed type char gbMaxPlayers; + +//----- (0043B791) -------------------------------------------------------- +bool __fastcall mpqapi_parse_archive_header(TMPQHeader *header, int *mpq_offset) +{ + int *v2; // ebp + TMPQHeader *v3; // esi + DWORD v4; // eax + DWORD v5; // edi + DWORD NumberOfBytesRead; // [esp+10h] [ebp-4h] + + v2 = mpq_offset; + v3 = header; + v4 = GetFileSize(sghArchive, 0); + v5 = v4; + *v2 = v4; + if ( v4 == -1 + || v4 < 0x68 + || !ReadFile(sghArchive, v3, 0x68u, &NumberOfBytesRead, 0) + || NumberOfBytesRead != 104 + || v3->dwID != '\x1AQPM' + || v3->dwHeaderSize != 32 + || v3->wFormatVersion > 0u + || v3->wSectorSize != 3 + || v3->dwArchiveSize != v5 + || v3->dwHashTablePos != 32872 + || v3->dwBlockTablePos != 104 + || v3->dwHashTableSize != 2048 + || v3->dwBlockTableSize != 2048 ) + { + if ( SetFilePointer(sghArchive, 0, 0, 0) == -1 || !SetEndOfFile(sghArchive) ) + return 0; + memset(v3, 0, 0x68u); + v3->dwID = '\x1AQPM'; + v3->dwHeaderSize = 32; + v3->wSectorSize = 3; + v3->wFormatVersion = 0; + *v2 = 0x10068; + dword_65AB0C = 1; + byte_65AB14 = 1; + } + return 1; +} +// 65AB0C: using guessed type int dword_65AB0C; +// 65AB14: using guessed type char byte_65AB14; + +//----- (0043B882) -------------------------------------------------------- +void __fastcall mpqapi_close_archive(char *save_path, bool free_tables, int save_num) +{ + char *v3; // esi + _BLOCKENTRY *v4; // ecx + _BLOCKENTRY *v5; // ecx + + v3 = save_path; + if ( free_tables ) + { + v4 = sgpBlockTbl; + sgpBlockTbl = 0; + mem_free_dbg(v4); + v5 = sgpHashTbl; + sgpHashTbl = 0; + mem_free_dbg(v5); + } + if ( sghArchive != (HANDLE)-1 ) + { + CloseHandle(sghArchive); + sghArchive = (HANDLE)-1; + } + if ( dword_65AB0C ) + { + dword_65AB0C = 0; + mpqapi_store_modified_time(v3, save_num); + } + if ( byte_65AB14 ) + { + byte_65AB14 = 0; + mpqapi_store_creation_time(v3, save_num); + } +} +// 65AB0C: using guessed type int dword_65AB0C; +// 65AB14: using guessed type char byte_65AB14; + +//----- (0043B8FD) -------------------------------------------------------- +void __fastcall mpqapi_store_modified_time(char *save_path, int save_num) +{ + int v2; // esi + char *v3; // ebx + HANDLE v4; // eax + int v5; // esi + struct _WIN32_FIND_DATAA FindFileData; // [esp+8h] [ebp-1E0h] + char dst[160]; // [esp+148h] [ebp-A0h] + + v2 = save_num; + v3 = save_path; + if ( gbMaxPlayers != 1 ) + { + mpqapi_reg_load_modification_time(dst, 160); + v4 = FindFirstFileA(v3, &FindFileData); + if ( v4 != (HANDLE)-1 ) + { + FindClose(v4); + v5 = 16 * v2; + *(_DWORD *)&dst[v5 + 8] = FindFileData.ftLastWriteTime.dwLowDateTime; + *(_DWORD *)&dst[v5 + 12] = FindFileData.ftLastWriteTime.dwHighDateTime; + mpqapi_reg_store_modification_time(dst, 160); + } + } +} +// 679660: using guessed type char gbMaxPlayers; + +//----- (0043B970) -------------------------------------------------------- +void __fastcall mpqapi_flush_and_close(char *save_path, bool is_single_player, int save_num) +{ + bool v3; // di + char *v4; // ebx + int v5; // eax + int v6; // eax + int v7; // eax + + v3 = is_single_player; + v4 = save_path; + if ( sghArchive != (HANDLE)-1 ) + { + if ( dword_65AB0C ) + { + _LOBYTE(v5) = mpqapi_can_seek(); + if ( v5 ) + { + _LOBYTE(v6) = mpqapi_write_header(); + if ( v6 ) + { + _LOBYTE(v7) = mpqapi_write_block_table(); + if ( v7 ) + mpqapi_write_hash_table(); + } + } + } + } + mpqapi_close_archive(v4, v3, save_num); +} +// 65AB0C: using guessed type int dword_65AB0C; + +//----- (0043B9CA) -------------------------------------------------------- +bool __cdecl mpqapi_write_header() +{ + bool result; // al + TMPQHeader Buffer; // [esp+8h] [ebp-6Ch] + DWORD NumberOfBytesWritten; // [esp+70h] [ebp-4h] + + memset(&Buffer, 0, 0x68u); + Buffer.dwID = '\x1AQPM'; + Buffer.dwHeaderSize = 32; + Buffer.dwArchiveSize = GetFileSize(sghArchive, 0); + Buffer.wFormatVersion = 0; + Buffer.wSectorSize = 3; + Buffer.dwHashTablePos = 32872; + Buffer.dwBlockTablePos = 104; + Buffer.dwHashTableSize = 2048; + Buffer.dwBlockTableSize = 2048; + if ( SetFilePointer(sghArchive, 0, 0, 0) != -1 && WriteFile(sghArchive, &Buffer, 0x68u, &NumberOfBytesWritten, 0) ) + result = NumberOfBytesWritten == 104; + else + result = 0; + return result; +} + +//----- (0043BA60) -------------------------------------------------------- +bool __cdecl mpqapi_write_block_table() +{ + int v1; // eax + BOOL v2; // ebx + int v3; // eax + DWORD NumberOfBytesWritten; // [esp+4h] [ebp-4h] + + if ( SetFilePointer(sghArchive, 104, 0, 0) == -1 ) + return 0; + v1 = encrypt_hash("(block table)", 3); + encrypt_encrypt_block(sgpBlockTbl, 0x8000, v1); + v2 = WriteFile(sghArchive, sgpBlockTbl, 0x8000u, &NumberOfBytesWritten, 0); + v3 = encrypt_hash("(block table)", 3); + encrypt_decrypt_block(sgpBlockTbl, 0x8000, v3); + return v2 && NumberOfBytesWritten == 0x8000; +} + +//----- (0043BAEB) -------------------------------------------------------- +bool __cdecl mpqapi_write_hash_table() +{ + int v1; // eax + BOOL v2; // ebx + int v3; // eax + DWORD NumberOfBytesWritten; // [esp+4h] [ebp-4h] + + if ( SetFilePointer(sghArchive, 32872, 0, 0) == -1 ) + return 0; + v1 = encrypt_hash("(hash table)", 3); + encrypt_encrypt_block(sgpHashTbl, 0x8000, v1); + v2 = WriteFile(sghArchive, sgpHashTbl, 0x8000u, &NumberOfBytesWritten, 0); + v3 = encrypt_hash("(hash table)", 3); + encrypt_decrypt_block(sgpHashTbl, 0x8000, v3); + return v2 && NumberOfBytesWritten == 0x8000; +} + +//----- (0043BB79) -------------------------------------------------------- +bool __cdecl mpqapi_can_seek() +{ + bool result; // al + + if ( SetFilePointer(sghArchive, lDistanceToMove, 0, 0) == -1 ) + result = 0; + else + result = SetEndOfFile(sghArchive); + return result; +} + +//----- (0043BBA9) -------------------------------------------------------- +void __cdecl msg_cpp_init() +{ + msg_cpp_init_value = msg_inf; +} +// 47F14C: using guessed type int msg_inf; +// 65AB1C: using guessed type int msg_cpp_init_value; + +//----- (0043BBB4) -------------------------------------------------------- +void __fastcall msg_send_drop_pkt(int pnum, int reason) +{ + _cmd_id packet; // [esp+0h] [ebp-8h] + char v3; // [esp+1h] [ebp-7h] + int v4; // [esp+2h] [ebp-6h] + + v4 = reason; + packet = FAKE_CMD_DROPID; + v3 = pnum; + msg_send_packet(pnum, &packet, 6); +} + +//----- (0043BBCF) -------------------------------------------------------- +void __fastcall msg_send_packet(int pnum, void *packet, int dwSize) +{ + void *v3; // edi + TMegaPkt *v4; // eax + _cmd_id packeta; // [esp+Ah] [ebp-2h] + char v6; // [esp+Bh] [ebp-1h] + + v3 = packet; + if ( pnum != sgnCurrMegaPlayer ) + { + sgnCurrMegaPlayer = pnum; + packeta = FAKE_CMD_SETID; + v6 = pnum; + msg_send_packet(pnum, &packeta, 2); + } + v4 = sgpCurrPkt; + if ( sgpCurrPkt->dwSpaceLeft < (unsigned int)dwSize ) + { + msg_get_next_packet(); + v4 = sgpCurrPkt; + } + memcpy((char *)&v4[1] - v4->dwSpaceLeft, v3, dwSize); + sgpCurrPkt->dwSpaceLeft -= dwSize; +} +// 65AB24: using guessed type int sgnCurrMegaPlayer; + +//----- (0043BC31) -------------------------------------------------------- +TMegaPkt *__cdecl msg_get_next_packet() +{ + TMegaPkt *v0; // eax + TMegaPkt *v1; // ecx + TMegaPkt *result; // eax + + v0 = (TMegaPkt *)DiabloAllocPtr(32008); + sgpCurrPkt = v0; + v0->pNext = 0; + sgpCurrPkt->dwSpaceLeft = 32000; + v1 = sgpMegaPkt; + result = (TMegaPkt *)&sgpMegaPkt; + while ( v1 ) + { + result = v1; + v1 = v1->pNext; + } + result->pNext = sgpCurrPkt; + return result; +} + +//----- (0043BC6D) -------------------------------------------------------- +int __cdecl msg_wait_resync() +{ + int v0; // eax + + msg_get_next_packet(); + sgbDeltaChunks = 0; + sgnCurrMegaPlayer = -1; + sgbRecvCmd = CMD_DLEVEL_END; + gbBufferMsgs = 1; + sgdwOwnerWait = GetTickCount(); + v0 = UiProgressDialog(ghMainWnd, "Waiting for game data...", 1, msg_wait_for_turns, 20); + gbBufferMsgs = 0; + if ( !v0 ) + goto LABEL_6; + if ( gbGameDestroyed ) + { + DrawDlg("The game ended"); +LABEL_6: + msg_free_packets(); + return 0; + } + if ( sgbDeltaChunks != 21 ) + { + DrawDlg("Unable to get level data"); + goto LABEL_6; + } + return 1; +} +// 65AB18: using guessed type int sgdwOwnerWait; +// 65AB24: using guessed type int sgnCurrMegaPlayer; +// 67618D: using guessed type char sgbDeltaChunks; +// 676194: using guessed type char gbBufferMsgs; +// 67862D: using guessed type char gbGameDestroyed; + +//----- (0043BCED) -------------------------------------------------------- +void __cdecl msg_free_packets() +{ + TMegaPkt *v0; // eax + TMegaPkt *v1; // ecx + + v0 = sgpMegaPkt; + while ( v0 ) + { + v1 = v0->pNext; + sgpMegaPkt = 0; + sgpCurrPkt = v1; + mem_free_dbg(v0); + v0 = sgpCurrPkt; + sgpMegaPkt = sgpCurrPkt; + } +} + +//----- (0043BD19) -------------------------------------------------------- +int __cdecl msg_wait_for_turns() +{ + int v0; // eax + int v2; // eax + bool recieved; // [esp+0h] [ebp-8h] + int turns; // [esp+4h] [ebp-4h] + + if ( !sgbDeltaChunks ) + { + nthread_send_and_recv_turn(0, 0); + _LOBYTE(v0) = SNetGetOwnerTurnsWaiting(&turns); + if ( !v0 && SErrGetLastError() == 0x85100070 ) + return 100; + if ( GetTickCount() - sgdwOwnerWait <= 0x7D0 && turns < (unsigned int)gdwTurnsInTransit ) + return 0; + ++sgbDeltaChunks; + } + multi_process_network_packets(); + nthread_send_and_recv_turn(0, 0); + _LOBYTE(v2) = nthread_has_500ms_passed(); + if ( v2 ) + nthread_recv_turns(&recieved); + if ( gbGameDestroyed ) + return 100; + if ( (unsigned char)gbDeltaSender >= 4u ) + { + sgbDeltaChunks = 0; + sgbRecvCmd = CMD_DLEVEL_END; + gbDeltaSender = myplr; + nthread_set_turn_upper_bit(); + } + if ( sgbDeltaChunks == 20 ) + { + sgbDeltaChunks = 21; + return 99; + } + return 100 * (unsigned char)sgbDeltaChunks / 21; +} +// 65AB18: using guessed type int sgdwOwnerWait; +// 67618D: using guessed type char sgbDeltaChunks; +// 67862D: using guessed type char gbGameDestroyed; +// 6796E4: using guessed type char gbDeltaSender; +// 679738: using guessed type int gdwTurnsInTransit; + +//----- (0043BDEB) -------------------------------------------------------- +void __cdecl msg_process_net_packets() +{ + if ( gbMaxPlayers != 1 ) + { + gbBufferMsgs = 2; + msg_pre_packet(); + gbBufferMsgs = 0; + msg_free_packets(); + } +} +// 676194: using guessed type char gbBufferMsgs; +// 679660: using guessed type char gbMaxPlayers; + +//----- (0043BE0D) -------------------------------------------------------- +void __cdecl msg_pre_packet() +{ + TMegaPkt *v0; // edi + int i; // ebp + signed int v2; // ebx + TFakeCmdPlr *v3; // esi + TFakeCmdPlr *v4; // eax + TFakeDropPlr *v5; // eax + int v6; // eax + + v0 = sgpMegaPkt; + for ( i = -1; v0; v0 = v0->pNext ) + { + v2 = 32000; + v3 = (TFakeCmdPlr *)v0->data; + while ( v2 != v0->dwSpaceLeft ) + { + if ( v3->bCmd == FAKE_CMD_SETID ) + { + v4 = v3; + ++v3; + i = (unsigned char)v4->bPlr; + v2 -= 2; + } + else if ( v3->bCmd == FAKE_CMD_DROPID ) + { + v5 = (TFakeDropPlr *)v3; + v3 += 3; + v2 -= 6; + multi_player_left((unsigned char)v5->bPlr, v5->dwReason); + } + else + { + v6 = ParseCmd(i, (TCmd *)v3); + v3 = (TFakeCmdPlr *)((char *)v3 + v6); + v2 -= v6; + } + } + } +} + +//----- (0043BE74) -------------------------------------------------------- +void __fastcall msg_do_sync(int pnum) +{ + char *v1; // edi + DObjectStr *v2; // esi + void *v3; // ebx + void *v4; // eax + void *v5; // eax + void *v6; // eax + int v7; // eax + char *v8; // eax + int v9; // eax + int player_num; // [esp+0h] [ebp-Ch] + int v11; // [esp+4h] [ebp-8h] + char src; // [esp+Bh] [ebp-1h] + + player_num = pnum; + if ( sgbDeltaChanged ) + { + v11 = 0; + v1 = (char *)DiabloAllocPtr(4722); + v2 = sgLevels[0].object; + v3 = v1 + 1; + do + { + v4 = msg_sync_items(v3, &v2[-2794]); + v5 = msg_sync_objects(v4, v2); + v6 = msg_sync_monsters(v5, &v2[127]); + v7 = msg_comp_level(v1, (int)v6); + dthread_send_delta(player_num, (_BYTE)v11++ + CMD_DLEVEL_0, v1, v7); + v2 += 4721; + } + while ( (signed int)v2 < (signed int)&sgTempLevel.item[126].bMCh ); + v8 = msg_sync_portals((char *)v3); + v9 = msg_comp_level(v1, (int)v8); + dthread_send_delta(player_num, CMD_DLEVEL_JUNK, v1, v9); + mem_free_dbg(v1); + } + src = 0; + dthread_send_delta(player_num, CMD_DLEVEL_END, &src, 1); +} +// 67618C: using guessed type char sgbDeltaChanged; + +//----- (0043BF2B) -------------------------------------------------------- +void *__fastcall msg_sync_items(void *dst, void *src) +{ + _BYTE *v2; // edi + _BYTE *v3; // esi + signed int v4; // ebx + + v2 = (unsigned char *)src; + v3 = (unsigned char *)dst; + v4 = 127; + do + { + if ( *v2 == -1 ) + { + *v3++ = -1; + } + else + { + memcpy(v3, v2, 0x16u); + v3 += 22; + } + v2 += 22; + --v4; + } + while ( v4 ); + return v3; +} + +//----- (0043BF5B) -------------------------------------------------------- +void *__fastcall msg_sync_objects(void *dst, void *src) +{ + char *v2; // esi + + v2 = (char *)dst; + memcpy(dst, src, 0x7Fu); + return v2 + 127; +} + +//----- (0043BF6F) -------------------------------------------------------- +void *__fastcall msg_sync_monsters(void *dst, void *src) +{ + _BYTE *v2; // edi + _BYTE *v3; // esi + signed int v4; // ebx + + v2 = (unsigned char *)src; + v3 = (unsigned char *)dst; + v4 = 200; + do + { + if ( *v2 == -1 ) + { + *v3++ = -1; + } + else + { + memcpy(v3, v2, 9u); + v3 += 9; + } + v2 += 9; + --v4; + } + while ( v4 ); + return v3; +} + +//----- (0043BFA1) -------------------------------------------------------- +char *__fastcall msg_sync_portals(char *a1) +{ + char *v1; // ebx + DJunk *v2; // edi + MultiQuests *v3; // esi + char *v4; // edi + unsigned char *v5; // ebp + + v1 = a1; + v2 = sgJunk; + v3 = sgJunk[0].quests; + do + { + if ( v2->portal[0].x == -1 ) + { + *v1++ = -1; + } + else + { + memcpy(v1, v2, 5u); + v1 += 5; + } + v2 = (DJunk *)((char *)v2 + 5); + } + while ( (signed int)v2 < (signed int)sgJunk[0].quests ); + v4 = &quests[0]._qactive; + v5 = &questlist[0]._qflags; + do + { + if ( *v5 & 1 ) + { + v3->qlog = v4[18]; + v3->qstate = *v4; + v3->qvar1 = v4[13]; + memcpy(v1, v3, 3u); + v1 += 3; + ++v3; + } + v5 += 20; + v4 += 24; + } + while ( (signed int)v5 < (signed int)questyoff ); + return v1; +} + +//----- (0043C019) -------------------------------------------------------- +int __fastcall msg_comp_level(char *buffer, int size) +{ + char *v2; // esi + int v3; // edi + int v4; // eax + + v2 = buffer; + v3 = size - (_DWORD)buffer - 1; + v4 = encrypt_compress(buffer + 1, v3); + *v2 = v3 != v4; + return v4 + 1; +} + +//----- (0043C035) -------------------------------------------------------- +void __cdecl delta_init() +{ + sgbDeltaChanged = 0; + memset(sgJunk, 255, 0x20u); + memset(sgLevels, 255, 0x13981u); + memset(sgLocals, 0, 0x6A40u); + deltaload = 0; +} +// 67618C: using guessed type char sgbDeltaChanged; +// 676190: using guessed type int deltaload; + +//----- (0043C07C) -------------------------------------------------------- +void __fastcall delta_kill_monster(int mi, unsigned char x, unsigned char y, unsigned char bLevel) +{ + DMonsterStr *v4; // eax + char v5; // cl + + if ( gbMaxPlayers != 1 ) + { + v4 = &sgLevels[bLevel].monster[mi]; + sgbDeltaChanged = 1; + v5 = monster[mi]._mdir; + v4->_mhitpoints = 0; + v4->_mx = x; + v4->_mdir = v5; + v4->_my = y; + } +} +// 67618C: using guessed type char sgbDeltaChanged; +// 679660: using guessed type char gbMaxPlayers; + +//----- (0043C0C2) -------------------------------------------------------- +void __fastcall delta_monster_hp(int mi, __int32 hp, unsigned char bLevel) +{ + DMonsterStr *v3; // eax + + if ( gbMaxPlayers != 1 ) + { + sgbDeltaChanged = 1; + v3 = &sgLevels[bLevel].monster[mi]; + if ( v3->_mhitpoints > hp ) + v3->_mhitpoints = hp; + } +} +// 67618C: using guessed type char sgbDeltaChanged; +// 679660: using guessed type char gbMaxPlayers; + +//----- (0043C0F2) -------------------------------------------------------- +void __fastcall delta_sync_monster(TCmdLocParam1 *packet, char level) +{ + DMonsterStr *v2; // eax + char v3; // dl + + if ( gbMaxPlayers != 1 ) + { + sgbDeltaChanged = 1; + v2 = &sgLevels[(unsigned char)level].monster[(unsigned char)packet->bCmd]; + if ( v2->_mhitpoints ) + { + v2->_mx = packet->x; + v3 = packet->y; + v2->_mactive = -1; + v2->_my = v3; + v2->_menemy = packet->wParam1; + } + } +} +// 67618C: using guessed type char sgbDeltaChanged; +// 679660: using guessed type char gbMaxPlayers; + +//----- (0043C134) -------------------------------------------------------- +void __fastcall delta_sync_golem(TCmdGolem *pG, int pnum, int bLevel) +{ + DMonsterStr *v3; // eax + char v4; // dl + + if ( gbMaxPlayers != 1 ) + { + sgbDeltaChanged = 1; + v3 = &sgLevels[(unsigned char)bLevel].monster[pnum]; + v3->_mx = pG->_mx; + v4 = pG->_my; + v3->_mactive = -1; + v3->_my = v4; + v3->_menemy = pG->_menemy; + v3->_mdir = pG->_mdir; + v3->_mhitpoints = pG->_mhitpoints; + } +} +// 67618C: using guessed type char sgbDeltaChanged; +// 679660: using guessed type char gbMaxPlayers; + +//----- (0043C17D) -------------------------------------------------------- +void __fastcall delta_leave_sync(unsigned char bLevel) +{ + int v1; // edi + unsigned char v2; // bl + bool v3; // zf + int v4; // eax + int v5; // ebp + int v6; // ecx + int v7; // esi + DMonsterStr *v8; // edi + int v9; // [esp-Ch] [ebp-10h] + + v2 = bLevel; + if ( gbMaxPlayers != 1 ) + { + v3 = currlevel == 0; + if ( !currlevel ) + { + v4 = GetRndSeed(); + v3 = currlevel == 0; + glSeedTbl[0] = v4; + } + if ( !v3 ) + { + v5 = 0; + if ( nummonsters > 0 ) + { + v9 = v1; + do + { + v6 = monstactive[v5]; + v7 = monstactive[v5]; + if ( monster[v7]._mhitpoints ) + { + sgbDeltaChanged = 1; + v8 = &sgLevels[v2].monster[v6]; + v8->_mx = monster[v7]._mx; + v8->_my = monster[v7]._my; + v8->_mdir = monster[v7]._mdir; + v8->_menemy = encode_enemy(v9); + v8->_mhitpoints = monster[v7]._mhitpoints; + v8->_mactive = monster[v7]._msquelch; + } + ++v5; + } + while ( v5 < nummonsters ); + } + memcpy(&sgLocals[v2], automapview, 0x640u); + } + } +} +// 43C17D: could not find valid save-restore pair for edi +// 67618C: using guessed type char sgbDeltaChanged; +// 679660: using guessed type char gbMaxPlayers; + +//----- (0043C24F) -------------------------------------------------------- +bool __fastcall delta_portal_inited(int portal_num) +{ + return sgJunk[0].portal[portal_num].x == -1; +} + +//----- (0043C25D) -------------------------------------------------------- +bool __fastcall delta_quest_inited(int quest_num) +{ + return sgJunk[0].quests[quest_num].qstate != -1; +} + +//----- (0043C26B) -------------------------------------------------------- +void __fastcall DeltaAddItem(int ii) +{ + int v1; // eax + int v2; // ecx + signed int v3; // ebp + DLevel *v4; // edx + DLevel *v5; // edi + char v6; // bl + int v7; // esi + signed int v8; // esi + int v9; // eax + char v10; // cl + char v11; // cl + + v1 = ii; + if ( gbMaxPlayers != 1 ) + { + v2 = currlevel; + v3 = 0; + v4 = &sgLevels[v2]; + v5 = &sgLevels[v2]; + while ( 1 ) + { + v6 = v5->item[0].bCmd; + if ( v5->item[0].bCmd != -1 ) + { + v7 = v1; + if ( (unsigned short)v5->item[0].wIndx == items[v1].IDidx + && v5->item[0].wCI == items[v7]._iCreateInfo + && v5->item[0].dwSeed == items[v7]._iSeed + && (v6 == 1 || !v6) ) + { + break; + } + } + ++v3; + v5 = (DLevel *)((char *)v5 + 22); + if ( v3 >= 127 ) + { + v8 = 0; + while ( v4->item[0].bCmd != -1 ) + { + ++v8; + v4 = (DLevel *)((char *)v4 + 22); + if ( v8 >= 127 ) + return; + } + v4->item[0].bCmd = 0; + v9 = 368 * v1; + v10 = *((_BYTE *)&items[0]._ix + v9); + sgbDeltaChanged = 1; + v4->item[0].x = v10; + v4->item[0].y = *((_BYTE *)&items[0]._iy + v9); + v4->item[0].wIndx = *(_WORD *)((char *)&items[0].IDidx + v9); + v4->item[0].wCI = *(short *)((char *)&items[0]._iCreateInfo + v9); + v4->item[0].dwSeed = *(int *)((char *)&items[0]._iSeed + v9); + v4->item[0].bId = *((_BYTE *)&items[0]._iIdentified + v9); + v4->item[0].bDur = *((_BYTE *)&items[0]._iDurability + v9); + v4->item[0].bMDur = *((_BYTE *)&items[0]._iMaxDur + v9); + v4->item[0].bCh = *((_BYTE *)&items[0]._iCharges + v9); + v11 = *((_BYTE *)&items[0]._iMaxCharges + v9); + _LOWORD(v9) = *(_WORD *)((char *)&items[0]._ivalue + v9); + v4->item[0].bMCh = v11; + v4->item[0].wValue = v9; + return; + } + } + } +} +// 67618C: using guessed type char sgbDeltaChanged; +// 679660: using guessed type char gbMaxPlayers; + +//----- (0043C372) -------------------------------------------------------- +void __cdecl DeltaSaveLevel() +{ + int v0; // eax + int v1; // edx + int *v2; // ecx + unsigned char v3; // cl + + if ( gbMaxPlayers != 1 ) + { + v0 = myplr; + v1 = 0; + v2 = &plr[0]._pGFXLoad; + do + { + if ( v1 != v0 ) + *v2 = 0; + v2 += 5430; + ++v1; + } + while ( (signed int)v2 < (signed int)&plr_msgs[3].msg[27] ); + v3 = currlevel; + plr[v0]._pLvlVisited[currlevel] = 1; + delta_leave_sync(v3); + } +} +// 679660: using guessed type char gbMaxPlayers; + +//----- (0043C3BA) -------------------------------------------------------- +void __cdecl DeltaLoadLevel() +{ + int v0; // ebx + int *v1; // esi + int v2; // eax + int v3; // ecx + int v4; // edx + int v5; // edi + char v6; // al + int v7; // eax + signed int v8; // esi + int v9; // eax + char v10; // cl + int v11; // eax + char *v12; // edx + int v13; // eax + int v14; // ebx + int *v15; // edx + unsigned short v16; // cx + int v17; // ST1C_4 + int v18; // ST18_4 + int v19; // eax + int v20; // ecx + int v21; // edx + int v22; // eax + int v23; // eax + int v24; // esi + int v25; // edi + int v26; // eax + int v27; // eax + int v28; // esi + unsigned char v29; // al + int j; // esi + int v31; // eax + signed int v32; // [esp+0h] [ebp-24h] + int v33; // [esp+4h] [ebp-20h] + int o2; // [esp+8h] [ebp-1Ch] + int i; // [esp+Ch] [ebp-18h] + signed int v36; // [esp+10h] [ebp-14h] + int v37; // [esp+14h] [ebp-10h] + signed int v38; // [esp+18h] [ebp-Ch] + signed int v39; // [esp+1Ch] [ebp-8h] + int v40; // [esp+20h] [ebp-4h] + signed int v41; // [esp+20h] [ebp-4h] + + if ( gbMaxPlayers != 1 ) + { + deltaload = 1; + if ( currlevel ) + { + v0 = 0; + if ( nummonsters > 0 ) + { + v40 = 0; + v1 = &monster[0]._mfuty; + do + { + if ( sgLevels[currlevel].monster[v40]._mx != -1 ) + { + M_ClearSquares(v0); + v2 = v40 * 9 + 4721 * currlevel; + v3 = *((unsigned char *)&sgLevels[0].monster[0]._mx + v2); + v4 = *((unsigned char *)&sgLevels[0].monster[0]._my + v2); + v5 = *(int *)((char *)&sgLevels[0].monster[0]._mhitpoints + v2); + *(v1 - 3) = v3; + *(v1 - 2) = v4; + v1[1] = v3; + v1[2] = v4; + *(v1 - 1) = v3; + *v1 = v4; + if ( v5 != -1 ) + v1[26] = v5; + if ( v5 ) + { + decode_enemy(v0, *((unsigned char *)&sgLevels[0].monster[0]._menemy + v2)); + v7 = *(v1 - 3); + if ( v7 && v7 != 1 || *(v1 - 2) ) + dMonster[0][*(v1 - 2) + 112 * v7] = v0 + 1; + if ( (signed int)v1 >= (signed int)&monster[4]._mfuty ) + { + M_StartStand(v0, v1[7]); + } + else + { + MAI_Golum(v0); + v1[28] |= 0x30u; + } + *((_BYTE *)v1 + 116) = sgLevels[currlevel].monster[v40]._mactive; + } + else + { + v1[1] = v3; + v1[2] = v4; + M_ClearSquares(v0); + if ( *((_BYTE *)v1 + 108) != 27 ) + { + if ( *((_BYTE *)v1 + 144) ) + v6 = *((_BYTE *)v1 + 146); + else + v6 = *(_BYTE *)(v1[44] + 317); + AddDead(*(v1 - 3), *(v1 - 2), v6, (direction)v1[7]); + } + v1[16] = 1; + M_UpdateLeader(v0); + } + } + ++v40; + ++v0; + v1 += 57; + } + while ( v0 < nummonsters ); + } + memcpy(automapview, &sgLocals[currlevel], 0x640u); + } + v8 = 0; + i = 0; + v32 = 0; + do + { + v9 = v8 + 4721 * currlevel; + v10 = *(&sgLevels[0].item[0].bCmd + v9); + if ( v10 != -1 ) + { + if ( v10 == 1 ) + { + FindGetItem( + *(unsigned short *)((char *)&sgLevels[0].item[0].wIndx + v9), + *(short *)((char *)&sgLevels[0].item[0].wCI + v9), + *(int *)((char *)&sgLevels[0].item[0].dwSeed + v9)); + if ( v11 != -1 ) + { + v12 = &dItem[items[v11]._ix][items[v11]._iy]; + if ( *v12 == v11 + 1 ) + *v12 = 0; + DeleteItem(v11, i); + } + } + v13 = v8 + 4721 * currlevel; + if ( *(&sgLevels[0].item[0].bCmd + v13) == 2 ) + { + v14 = itemavail[0]; + v33 = itemavail[0]; + v15 = &itemavail[-numitems + 126]; + itemactive[numitems] = itemavail[0]; + v16 = *(short *)((char *)&sgLevels[0].item[0].wIndx + v13); + itemavail[0] = *v15; + if ( v16 == 23 ) + { + RecreateEar( + v14, + *(short *)((char *)&sgLevels[0].item[0].wCI + v13), + *(int *)((char *)&sgLevels[0].item[0].dwSeed + v13), + *(&sgLevels[0].item[0].bId + v13), + *((unsigned char *)&sgLevels[0].item[0].bDur + v13), + *((unsigned char *)&sgLevels[0].item[0].bMDur + v13), + *((unsigned char *)&sgLevels[0].item[0].bCh + v13), + *((unsigned char *)&sgLevels[0].item[0].bMCh + v13), + *(unsigned short *)((char *)&sgLevels[0].item[0].wValue + v13), + *(int *)((char *)&sgLevels[0].item[0].dwBuff + v13)); + } + else + { + v17 = *(unsigned short *)((char *)&sgLevels[0].item[0].wValue + v13); + v18 = *(int *)((char *)&sgLevels[0].item[0].dwSeed + v13); + _LOWORD(v13) = *(short *)((char *)&sgLevels[0].item[0].wCI + v13); + TempItemGeneration(v14, v16, v13, v18, v17); + v19 = v8 + 4721 * currlevel; + if ( *(&sgLevels[0].item[0].bId + v19) ) + items[v14]._iIdentified = 1; + v20 = v14; + items[v20]._iDurability = *((unsigned char *)&sgLevels[0].item[0].bDur + v19); + items[v20]._iMaxDur = *((unsigned char *)&sgLevels[0].item[0].bMDur + v19); + v21 = *((unsigned char *)&sgLevels[0].item[0].bCh + v19); + v22 = *((unsigned char *)&sgLevels[0].item[0].bMCh + v19); + items[v20]._iCharges = v21; + items[v20]._iMaxCharges = v22; + } + v23 = v8 + 4721 * currlevel; + v24 = *((unsigned char *)&sgLevels[0].item[0].x + v23); + v25 = *((unsigned char *)&sgLevels[0].item[0].y + v23); + if ( !CanPut(v24, v25) ) + { + v39 = 0; + v26 = -1; + v41 = 1; + v36 = -1; + do + { + if ( v39 ) + break; + v37 = v26; + while ( v26 <= v41 && !v39 ) + { + o2 = v25 + v37; + v38 = v36; + do + { + if ( v39 ) + break; + if ( CanPut(v38 + v24, o2) ) + { + v25 = o2; + v39 = 1; + v24 += v38; + } + ++v38; + v14 = v33; + } + while ( v38 <= v41 ); + v26 = ++v37; + } + ++v41; + v26 = v36-- - 1; + } + while ( v36 > -50 ); + } + v27 = v14; + items[v27]._ix = v24; + items[v27]._iy = v25; + dItem[v24][v25] = v14 + 1; + RespawnItem(v14, 0); + ++numitems; + v8 = v32; + } + } + ++i; + v8 += 22; + v32 = v8; + } + while ( v8 < 2794 ); + if ( currlevel ) + { + v28 = 0; + do + { + v29 = sgLevels[currlevel].object[v28].bCmd; + if ( v29 >= 0x2Bu ) + { + if ( v29 <= 0x2Eu ) + { + SyncOpObject(-1, v29, v28); + } + else if ( v29 == 47 ) + { + SyncBreakObj(-1, v28); + } + } + ++v28; + } + while ( v28 < 127 ); + for ( j = 0; j < nobjects; ++j ) + { + v31 = object[objectactive[j]]._otype; + if ( v31 == OBJ_TRAPL || v31 == OBJ_TRAPR ) + Obj_Trap(objectactive[j]); + } + } + deltaload = 0; + } +} +// 676190: using guessed type int deltaload; +// 679660: using guessed type char gbMaxPlayers; + +//----- (0043C873) -------------------------------------------------------- +void __fastcall NetSendCmd(unsigned char bHiPri, unsigned char bCmd) +{ + TCmd cmd; // [esp+3h] [ebp-1h] + + cmd.bCmd = bCmd; + if ( bHiPri ) + NetSendHiPri((unsigned char *)&cmd, 1u); + else + NetSendLoPri((unsigned char *)&cmd, 1u); +} + +//----- (0043C891) -------------------------------------------------------- +void __fastcall NetSendCmdGolem(unsigned char mx, unsigned char my, unsigned char dir, unsigned char menemy, __int32 hp, int cl) +{ + TCmdGolem cmd; // [esp+0h] [ebp-Ch] + + cmd._mx = mx; + cmd._mdir = dir; + cmd._menemy = menemy; + cmd._mhitpoints = hp; + cmd._my = my; + cmd.bCmd = CMD_AWAKEGOLEM; + cmd._currlevel = cl; + NetSendLoPri((unsigned char *)&cmd, 0xAu); +} + +//----- (0043C8C7) -------------------------------------------------------- +void __fastcall NetSendCmdLoc(unsigned char bHiPri, unsigned char bCmd, unsigned char x, unsigned char y) +{ + TCmdLoc cmd; // [esp+1h] [ebp-3h] + + cmd.bCmd = bCmd; + cmd.x = x; + cmd.y = y; + if ( bHiPri ) + NetSendHiPri((unsigned char *)&cmd, 3u); + else + NetSendLoPri((unsigned char *)&cmd, 3u); +} + +//----- (0043C8F3) -------------------------------------------------------- +void __fastcall NetSendCmdLocParam1(unsigned char bHiPri, unsigned char bCmd, unsigned char x, unsigned char y, int wParam1) +{ + TCmdLocParam1 cmd; // [esp+0h] [ebp-8h] + + cmd.bCmd = bCmd; + cmd.x = x; + cmd.y = y; + cmd.wParam1 = wParam1; + if ( bHiPri ) + NetSendHiPri((unsigned char *)&cmd, 5u); + else + NetSendLoPri((unsigned char *)&cmd, 5u); +} + +//----- (0043C928) -------------------------------------------------------- +void __fastcall NetSendCmdLocParam2(unsigned char bHiPri, unsigned char bCmd, unsigned char x, unsigned char y, int wParam1, int wParam2) +{ + TCmdLocParam2 cmd; // [esp+0h] [ebp-8h] + + cmd.bCmd = bCmd; + cmd.x = x; + cmd.y = y; + cmd.wParam1 = wParam1; + cmd.wParam2 = wParam2; + if ( bHiPri ) + NetSendHiPri((unsigned char *)&cmd, 7u); + else + NetSendLoPri((unsigned char *)&cmd, 7u); +} + +//----- (0043C965) -------------------------------------------------------- +void __fastcall NetSendCmdLocParam3(unsigned char bHiPri, unsigned char bCmd, unsigned char x, unsigned char y, int wParam1, int wParam2, int wParam3) +{ + TCmdLocParam3 cmd; // [esp+0h] [ebp-Ch] + + cmd.bCmd = bCmd; + cmd.x = x; + cmd.y = y; + cmd.wParam1 = wParam1; + cmd.wParam2 = wParam2; + cmd.wParam3 = wParam3; + if ( bHiPri ) + NetSendHiPri((unsigned char *)&cmd, 9u); + else + NetSendLoPri((unsigned char *)&cmd, 9u); +} + +//----- (0043C9AB) -------------------------------------------------------- +void __fastcall NetSendCmdParam1(unsigned char bHiPri, unsigned char bCmd, unsigned short wParam1) +{ + TCmdParam1 cmd; // [esp+1h] [ebp-3h] + + cmd.bCmd = bCmd; + cmd.wParam1 = wParam1; + if ( bHiPri ) + NetSendHiPri((unsigned char *)&cmd, 3u); + else + NetSendLoPri((unsigned char *)&cmd, 3u); +} + +//----- (0043C9D3) -------------------------------------------------------- +void __fastcall NetSendCmdParam2(unsigned char bHiPri, unsigned char bCmd, unsigned short wParam1, unsigned short wParam2) +{ + TCmdParam2 cmd; // [esp+0h] [ebp-8h] + + cmd.bCmd = bCmd; + cmd.wParam1 = wParam1; + cmd.wParam2 = wParam2; + if ( bHiPri ) + NetSendHiPri((unsigned char *)&cmd, 5u); + else + NetSendLoPri((unsigned char *)&cmd, 5u); +} + +//----- (0043CA04) -------------------------------------------------------- +void __fastcall NetSendCmdParam3(unsigned char bHiPri, unsigned char bCmd, unsigned short wParam1, unsigned short wParam2, int wParam3) +{ + TCmdParam3 cmd; // [esp+0h] [ebp-8h] + + cmd.bCmd = bCmd; + cmd.wParam1 = wParam1; + cmd.wParam2 = wParam2; + cmd.wParam3 = wParam3; + if ( bHiPri ) + NetSendHiPri((unsigned char *)&cmd, 7u); + else + NetSendLoPri((unsigned char *)&cmd, 7u); +} + +//----- (0043CA3D) -------------------------------------------------------- +void __fastcall NetSendCmdQuest(unsigned char bHiPri, unsigned char q) +{ + int v2; // eax + char v3; // dl + TCmdQuest cmd; // [esp+0h] [ebp-8h] + + cmd.q = q; + cmd.bCmd = CMD_SYNCQUEST; + v2 = 24 * q; + cmd.qstate = *(&quests[0]._qactive + v2); + v3 = *((_BYTE *)&quests[0]._qlog + v2); + _LOBYTE(v2) = *(&quests[0]._qvar1 + v2); + cmd.qlog = v3; + cmd.qvar1 = v2; + if ( bHiPri ) + NetSendHiPri((unsigned char *)&cmd, 5u); + else + NetSendLoPri((unsigned char *)&cmd, 5u); +} + +//----- (0043CA84) -------------------------------------------------------- +void __fastcall NetSendCmdGItem(unsigned char bHiPri, unsigned char bCmd, unsigned char mast, unsigned char pnum, int ii) +{ + int v5; // eax + bool v6; // zf + short v7; // dx + short v8; // bx + int v9; // esi + int v10; // esi + char v11; // dl + short v12; // ax + TCmdGItem cmd; // [esp+4h] [ebp-20h] + + cmd.bCmd = bCmd; + cmd.bPnum = pnum; + cmd.bMaster = mast; + cmd.bLevel = currlevel; + cmd.bCursitem = ii; + cmd.dwTime = 0; + v5 = (unsigned char)ii; + cmd.x = items[v5]._ix; + cmd.y = items[v5]._iy; + v6 = items[v5].IDidx == IDI_EAR; + cmd.wIndx = items[v5].IDidx; + if ( v6 ) + { + _LOBYTE(v7) = 0; + _HIBYTE(v7) = items[v5]._iName[7]; + _LOBYTE(v8) = 0; + _HIBYTE(v8) = items[v5]._iName[18]; + v9 = items[v5]._iName[10]; + cmd.wCI = items[v5]._iName[8] | v7; + cmd.dwSeed = items[v5]._iName[12] | ((items[v5]._iName[11] | ((v9 | (items[v5]._iName[9] << 8)) << 8)) << 8); + cmd.bId = items[v5]._iName[13]; + cmd.bDur = items[v5]._iName[14]; + cmd.bMDur = items[v5]._iName[15]; + cmd.bCh = items[v5]._iName[16]; + cmd.bMCh = items[v5]._iName[17]; + v10 = items[v5]._iName[20]; + cmd.wValue = _LOWORD(items[v5]._ivalue) | v8 | ((_LOWORD(items[v5]._iCurs) - 19) << 6); + cmd.dwBuff = items[v5]._iName[22] | ((items[v5]._iName[21] | ((v10 | (items[v5]._iName[19] << 8)) << 8)) << 8); + } + else + { + cmd.wCI = items[v5]._iCreateInfo; + cmd.dwSeed = items[v5]._iSeed; + cmd.bId = items[v5]._iIdentified; + cmd.bDur = items[v5]._iDurability; + cmd.bMDur = items[v5]._iMaxDur; + cmd.bCh = items[v5]._iCharges; + v11 = items[v5]._iMaxCharges; + v12 = items[v5]._ivalue; + cmd.bMCh = v11; + cmd.wValue = v12; + } + if ( bHiPri ) + NetSendHiPri((unsigned char *)&cmd, 0x1Eu); + else + NetSendLoPri((unsigned char *)&cmd, 0x1Eu); +} + +//----- (0043CC09) -------------------------------------------------------- +void __fastcall NetSendCmdGItem2(unsigned char usonly, unsigned char bCmd, unsigned char mast, unsigned char pnum, struct TCmdGItem *p) +{ + unsigned char v5; // bl + int v6; // esi + int v7; // eax + TCmdGItem cmd; // [esp+8h] [ebp-20h] + + v5 = bCmd; + v6 = usonly; + memcpy(&cmd, p, 0x1Eu); + cmd.bPnum = pnum; + cmd.bCmd = v5; + cmd.bMaster = mast; + if ( !v6 ) + { + cmd.dwTime = 0; + NetSendHiPri((unsigned char *)&cmd, 0x1Eu); + return; + } + v7 = GetTickCount(); + if ( cmd.dwTime ) + { + if ( v7 - cmd.dwTime > 5000 ) + return; + } + else + { + cmd.dwTime = v7; + } + multi_msg_add(&cmd.bCmd, 0x1Eu); +} + +//----- (0043CC74) -------------------------------------------------------- +unsigned char __fastcall NetSendCmdReq2(unsigned char bCmd, unsigned char mast, unsigned char pnum, struct TCmdGItem *p) +{ + unsigned char v4; // bl + int v5; // eax + TCmdGItem cmd; // [esp+4h] [ebp-24h] + unsigned char v8; // [esp+24h] [ebp-4h] + + v4 = mast; + v8 = bCmd; + memcpy(&cmd, p, 0x1Eu); + cmd.bCmd = v8; + cmd.bPnum = pnum; + cmd.bMaster = v4; + v5 = GetTickCount(); + if ( !cmd.dwTime ) + { + cmd.dwTime = v5; +LABEL_3: + multi_msg_add(&cmd.bCmd, 0x1Eu); + return 1; + } + if ( v5 - cmd.dwTime <= 5000 ) + goto LABEL_3; + return 0; +} + +//----- (0043CCCF) -------------------------------------------------------- +void __fastcall NetSendCmdExtra(struct TCmdGItem *p) +{ + TCmdGItem cmd; // [esp+0h] [ebp-20h] + + memcpy(&cmd, p, 0x1Eu); + cmd.dwTime = 0; + cmd.bCmd = CMD_ITEMEXTRA; + NetSendHiPri((unsigned char *)&cmd, 0x1Eu); +} + +//----- (0043CCF8) -------------------------------------------------------- +void __fastcall NetSendCmdPItem(unsigned char bHiPri, unsigned char bCmd, unsigned char x, unsigned char y) +{ + int v4; // eax + short *v5; // edx + bool v6; // zf + short v7; // dx + short v8; // bx + int v9; // esi + int v10; // esi + char v11; // dl + short v12; // ax + TCmdPItem cmd; // [esp+4h] [ebp-18h] + + cmd.bCmd = bCmd; + cmd.x = x; + cmd.y = y; + v4 = myplr; + v5 = (short *)&plr[myplr].HoldItem.IDidx; + v6 = *(_DWORD *)v5 == IDI_EAR; + cmd.wIndx = *v5; + if ( v6 ) + { + _LOBYTE(v7) = 0; + _HIBYTE(v7) = plr[v4].HoldItem._iName[7]; + _LOBYTE(v8) = 0; + _HIBYTE(v8) = plr[v4].HoldItem._iName[18]; + v9 = plr[v4].HoldItem._iName[10]; + cmd.wCI = plr[v4].HoldItem._iName[8] | v7; + cmd.dwSeed = plr[v4].HoldItem._iName[12] | ((plr[v4].HoldItem._iName[11] | ((v9 | (plr[v4].HoldItem._iName[9] << 8)) << 8)) << 8); + cmd.bId = plr[v4].HoldItem._iName[13]; + cmd.bDur = plr[v4].HoldItem._iName[14]; + cmd.bMDur = plr[v4].HoldItem._iName[15]; + cmd.bCh = plr[v4].HoldItem._iName[16]; + cmd.bMCh = plr[v4].HoldItem._iName[17]; + v10 = plr[v4].HoldItem._iName[20]; + cmd.wValue = _LOWORD(plr[v4].HoldItem._ivalue) | v8 | ((_LOWORD(plr[v4].HoldItem._iCurs) - 19) << 6); + cmd.dwBuff = plr[v4].HoldItem._iName[22] | ((plr[v4].HoldItem._iName[21] | ((v10 | (plr[v4].HoldItem._iName[19] << 8)) << 8)) << 8); + } + else + { + cmd.wCI = plr[v4].HoldItem._iCreateInfo; + cmd.dwSeed = plr[v4].HoldItem._iSeed; + cmd.bId = plr[v4].HoldItem._iIdentified; + cmd.bDur = plr[v4].HoldItem._iDurability; + cmd.bMDur = plr[v4].HoldItem._iMaxDur; + cmd.bCh = plr[v4].HoldItem._iCharges; + v11 = plr[v4].HoldItem._iMaxCharges; + v12 = plr[v4].HoldItem._ivalue; + cmd.bMCh = v11; + cmd.wValue = v12; + } + if ( bHiPri ) + NetSendHiPri((unsigned char *)&cmd, 0x16u); + else + NetSendLoPri((unsigned char *)&cmd, 0x16u); +} + +//----- (0043CE5B) -------------------------------------------------------- +void __fastcall NetSendCmdChItem(unsigned char bHiPri, unsigned char bLoc) +{ + short v2; // dx + char v3; // al + TCmdChItem cmd; // [esp+0h] [ebp-Ch] + + cmd.bLoc = bLoc; + v2 = plr[myplr].HoldItem.IDidx; + cmd.bCmd = CMD_CHANGEPLRITEMS; + cmd.wIndx = v2; + cmd.wCI = plr[myplr].HoldItem._iCreateInfo; + v3 = plr[myplr].HoldItem._iIdentified; + cmd.dwSeed = plr[myplr].HoldItem._iSeed; + cmd.bId = v3; + if ( bHiPri ) + NetSendHiPri((unsigned char *)&cmd, 0xBu); + else + NetSendLoPri((unsigned char *)&cmd, 0xBu); +} + +//----- (0043CEB2) -------------------------------------------------------- +void __fastcall NetSendCmdDelItem(unsigned char bHiPri, unsigned char bLoc) +{ + TCmdDelItem cmd; // [esp+2h] [ebp-2h] + + cmd.bLoc = bLoc; + cmd.bCmd = CMD_DELPLRITEMS; + if ( bHiPri ) + NetSendHiPri((unsigned char *)&cmd, 2u); + else + NetSendLoPri((unsigned char *)&cmd, 2u); +} + +//----- (0043CED4) -------------------------------------------------------- +void __fastcall NetSendCmdDItem(unsigned char bHiPri, int ii) +{ + int v2; // eax + short *v3; // edx + bool v4; // zf + short v5; // dx + short v6; // bx + int v7; // esi + int v8; // esi + char v9; // dl + short v10; // ax + TCmdPItem cmd; // [esp+4h] [ebp-18h] + + v2 = ii; + cmd.bCmd = CMD_DROPITEM; + cmd.x = items[ii]._ix; + cmd.y = items[ii]._iy; + v3 = (short *)&items[ii].IDidx; + v4 = *(_DWORD *)v3 == IDI_EAR; + cmd.wIndx = *v3; + if ( v4 ) + { + _LOBYTE(v5) = 0; + _HIBYTE(v5) = items[v2]._iName[7]; + _LOBYTE(v6) = 0; + _HIBYTE(v6) = items[v2]._iName[18]; + v7 = items[v2]._iName[10]; + cmd.wCI = items[v2]._iName[8] | v5; + cmd.dwSeed = items[v2]._iName[12] | ((items[v2]._iName[11] | ((v7 | (items[v2]._iName[9] << 8)) << 8)) << 8); + cmd.bId = items[v2]._iName[13]; + cmd.bDur = items[v2]._iName[14]; + cmd.bMDur = items[v2]._iName[15]; + cmd.bCh = items[v2]._iName[16]; + cmd.bMCh = items[v2]._iName[17]; + v8 = items[v2]._iName[20]; + cmd.wValue = _LOWORD(items[v2]._ivalue) | v6 | ((_LOWORD(items[v2]._iCurs) - 19) << 6); + cmd.dwBuff = items[v2]._iName[22] | ((items[v2]._iName[21] | ((v8 | (items[v2]._iName[19] << 8)) << 8)) << 8); + } + else + { + cmd.wCI = items[v2]._iCreateInfo; + cmd.dwSeed = items[v2]._iSeed; + cmd.bId = items[v2]._iIdentified; + cmd.bDur = items[v2]._iDurability; + cmd.bMDur = items[v2]._iMaxDur; + cmd.bCh = items[v2]._iCharges; + v9 = items[v2]._iMaxCharges; + v10 = items[v2]._ivalue; + cmd.bMCh = v9; + cmd.wValue = v10; + } + if ( bHiPri ) + NetSendHiPri((unsigned char *)&cmd, 0x16u); + else + NetSendLoPri((unsigned char *)&cmd, 0x16u); +} + +//----- (0043D039) -------------------------------------------------------- +void __fastcall NetSendCmdDamage(unsigned char bHiPri, unsigned char bPlr, unsigned __int32 dwDam) +{ + TCmdDamage cmd; // [esp+0h] [ebp-8h] + + cmd.bPlr = bPlr; + cmd.bCmd = CMD_PLRDAMAGE; + cmd.dwDam = dwDam; + if ( bHiPri ) + NetSendHiPri((unsigned char *)&cmd, 6u); + else + NetSendLoPri((unsigned char *)&cmd, 6u); +} + +//----- (0043D064) -------------------------------------------------------- +void __fastcall msg_init_msg(int a1, const char *pszStr) +{ + const char *v2; // esi + int v3; // edi + char v4; // bl + char v5[84]; // [esp+Ch] [ebp-54h] + + v2 = pszStr; + v3 = a1; + v4 = strlen(pszStr); + v5[0] = 78; + strcpy(&v5[1], v2); + multi_send_msg_packet(v3, v5, v4 + 2); +} + +//----- (0043D09D) -------------------------------------------------------- +void __fastcall RemovePlrPortal(int pnum) +{ + memset((char *)sgJunk + 5 * pnum, 255, 5u); + sgbDeltaChanged = 1; +} +// 67618C: using guessed type char sgbDeltaChanged; + +//----- (0043D0BC) -------------------------------------------------------- +int __fastcall ParseCmd(int pnum, TCmd *pCmd) +{ + bool v2; // zf + TCmd *v3; // eax + char v4; // dl + unsigned char v5; // bl + int result; // eax + TCmd *v7; // esi + + v2 = sgwPackPlrOffsetTbl[pnum] == 0; + v3 = pCmd; + v4 = pCmd->bCmd; + sbLastCmd = v4; + if ( !v2 && v4 != CMD_ACK_PLRINFO && v4 != CMD_SEND_PLRINFO ) + return 0; + v5 = v3->bCmd; + switch ( v3->bCmd ) + { + case CMD_WALKXY: + return On_WALKXY((struct TCmdLoc *)v3, pnum); + case CMD_ACK_PLRINFO: + return On_ACK_PLRINFO((struct TCmdPlrInfoHdr *)v3, pnum); + case CMD_ADDSTR: + return On_ADDSTR((struct TCmdParam1 *)v3, pnum); + case CMD_ADDMAG: + return On_ADDMAG((struct TCmdParam1 *)v3, pnum); + case CMD_ADDDEX: + return On_ADDDEX((struct TCmdParam1 *)v3, pnum); + case CMD_ADDVIT: + return On_ADDVIT((struct TCmdParam1 *)v3, pnum); + case CMD_SBSPELL: + return On_SBSPELL((struct TCmdParam1 *)v3, pnum); + case CMD_GETITEM: + return On_GETITEM((struct TCmdGItem *)v3, pnum); + case CMD_AGETITEM: + return On_AGETITEM((struct TCmdGItem *)v3, pnum); + case CMD_PUTITEM: + return On_PUTITEM((struct TCmdPItem *)v3, pnum); + case CMD_RESPAWNITEM: + return On_RESPAWNITEM((struct TCmdPItem *)v3, pnum); + case CMD_ATTACKXY: + return On_ATTACKXY((struct TCmdLoc *)v3, pnum); + case CMD_RATTACKXY: + return On_RATTACKXY((struct TCmdLoc *)v3, pnum); + case CMD_SPELLXY: + return On_SPELLXY((struct TCmdLocParam2 *)v3, pnum); + case CMD_TSPELLXY: + return On_TSPELLXY((struct TCmdLocParam2 *)v3, pnum); + case CMD_OPOBJXY: + return On_OPOBJXY((struct TCmdLocParam1 *)v3, pnum); + case CMD_DISARMXY: + return On_DISARMXY((struct TCmdLocParam1 *)v3, pnum); + case CMD_ATTACKID: + return On_ATTACKID((struct TCmdParam1 *)v3, pnum); + case CMD_ATTACKPID: + return On_ATTACKPID((struct TCmdParam1 *)v3, pnum); + case CMD_RATTACKID: + return On_RATTACKID((struct TCmdParam1 *)v3, pnum); + case CMD_RATTACKPID: + return On_RATTACKPID((struct TCmdParam1 *)v3, pnum); + case CMD_SPELLID: + return On_SPELLID((struct TCmdLocParam2 *)v3, pnum); + case CMD_SPELLPID: + return On_SPELLPID((struct TCmdLocParam2 *)v3, pnum); + case CMD_TSPELLID: + return On_TSPELLID((struct TCmdLocParam2 *)v3, pnum); + case CMD_TSPELLPID: + return On_TSPELLPID((struct TCmdLocParam2 *)v3, pnum); + case CMD_RESURRECT: + return On_RESURRECT((struct TCmdParam1 *)v3, pnum); + case CMD_OPOBJT: + return On_OPOBJT((struct TCmdParam1 *)v3, pnum); + case CMD_KNOCKBACK: + return On_KNOCKBACK((struct TCmdParam1 *)v3, pnum); + case CMD_TALKXY: + return On_TALKXY((struct TCmdLocParam1 *)v3, pnum); + case CMD_NEWLVL: + return On_NEWLVL((struct TCmdParam2 *)v3, pnum); + case CMD_WARP: + return On_WARP((struct TCmdParam1 *)v3, pnum); + case CMD_CHEAT_EXPERIENCE: + return On_DEBUG(); + case CMD_CHEAT_SPELL_LEVEL: + return On_DEBUG(); + case CMD_DEBUG: + return On_DEBUG(); + case CMD_SYNCDATA: + return On_SYNCDATA(v3, pnum); + case CMD_MONSTDEATH: + return On_MONSTDEATH((struct TCmdLocParam1 *)v3, pnum); + case CMD_MONSTDAMAGE: + return On_MONSTDAMAGE((struct TCmdLocParam1 *)v3, pnum); + case CMD_PLRDEAD: + return On_PLRDEAD((struct TCmdParam1 *)v3, pnum); + case CMD_REQUESTGITEM: + return On_REQUESTGITEM((struct TCmdGItem *)v3, pnum); + case CMD_REQUESTAGITEM: + return On_REQUESTAGITEM((struct TCmdGItem *)v3, pnum); + case CMD_GOTOGETITEM: + return On_GOTOGETITEM((struct TCmdLocParam1 *)v3, pnum); + case CMD_GOTOAGETITEM: + return On_GOTOAGETITEM((struct TCmdLocParam1 *)v3, pnum); + case CMD_OPENDOOR: + return On_OPENDOOR((struct TCmdParam1 *)v3, pnum); + case CMD_CLOSEDOOR: + return On_CLOSEDOOR((struct TCmdParam1 *)v3, pnum); + case CMD_OPERATEOBJ: + return On_OPERATEOBJ((struct TCmdParam1 *)v3, pnum); + case CMD_PLROPOBJ: + return On_PLROPOBJ((struct TCmdParam2 *)v3, pnum); + case CMD_BREAKOBJ: + return On_BREAKOBJ((struct TCmdParam2 *)v3, pnum); + case CMD_CHANGEPLRITEMS: + return On_CHANGEPLRITEMS((struct TCmdChItem *)v3, pnum); + case CMD_DELPLRITEMS: + return On_DELPLRITEMS((struct TCmdDelItem *)v3, pnum); + case CMD_PLRDAMAGE: + return On_PLRDAMAGE((struct TCmdDamage *)v3, pnum); + case CMD_PLRLEVEL: + return On_PLRLEVEL((struct TCmdParam1 *)v3, pnum); + case CMD_DROPITEM: + return On_DROPITEM((struct TCmdPItem *)v3, pnum); + case CMD_PLAYER_JOINLEVEL: + return On_PLAYER_JOINLEVEL((struct TCmdLocParam1 *)v3, pnum); + case CMD_SEND_PLRINFO: + return On_SEND_PLRINFO((struct TCmdPlrInfoHdr *)v3, pnum); + case CMD_SATTACKXY: + return On_SATTACKXY((struct TCmdLoc *)v3, pnum); + case CMD_ACTIVATEPORTAL: + return On_ACTIVATEPORTAL((DJunk *)v3, pnum); + case CMD_DEACTIVATEPORTAL: + return On_DEACTIVATEPORTAL(v3, pnum); + case CMD_HEALOTHER: + return On_HEALOTHER((struct TCmdParam1 *)v3, pnum); + case CMD_STRING: + return On_STRING((struct TCmdString *)v3, pnum); + case CMD_SETSTR: + return On_SETSTR((struct TCmdParam1 *)v3, pnum); + case CMD_SETMAG: + return On_SETMAG((struct TCmdParam1 *)v3, pnum); + case CMD_SETDEX: + return On_SETDEX((struct TCmdParam1 *)v3, pnum); + case CMD_SETVIT: + return On_SETVIT((struct TCmdParam1 *)v3, pnum); + case CMD_RETOWN: + return On_RETOWN(v3, pnum); + case CMD_SPELLXYD: + return On_SPELLXYD((struct TCmdLocParam3 *)v3, pnum); + case CMD_ITEMEXTRA: + return On_ITEMEXTRA((struct TCmdGItem *)v3, pnum); + case CMD_SYNCPUTITEM: + return On_SYNCPUTITEM((struct TCmdPItem *)v3, pnum); + case CMD_KILLGOLEM: + return On_KILLGOLEM((struct TCmdLocParam1 *)v3, pnum); + case CMD_SYNCQUEST: + return On_SYNCQUEST((struct TCmdQuest *)v3, pnum); + case CMD_ENDSHIELD: + return On_ENDSHIELD((int)v3, pnum); + case CMD_AWAKEGOLEM: + return On_AWAKEGOLEM((struct TCmdGolem *)v3, pnum); + case CMD_NOVA: + return On_NOVA((struct TCmdLoc *)v3, pnum); + case CMD_SETSHIELD: + return On_SETSHIELD((int)v3, pnum); + case CMD_REMSHIELD: + return On_REMSHIELD((int)v3, pnum); + default: + if ( v5 < CMD_DLEVEL_0 || v5 > CMD_DLEVEL_END ) + { + SNetDropPlayer(pnum, 0x40000006); + return 0; + } + v7 = v3; + if ( (unsigned char)gbDeltaSender == pnum ) + { + if ( sgbRecvCmd != CMD_DLEVEL_END ) + { + if ( sgbRecvCmd == v3->bCmd ) + { +LABEL_99: + memcpy( + (char *)&sgTempLevel + *(unsigned short *)&v7[1].bCmd, + &v7[5], + *(unsigned short *)&v7[3].bCmd); + sgdwRecvOffset += *(unsigned short *)&v7[3].bCmd; + goto LABEL_100; + } + DoCopySync(sgbRecvCmd, sgdwRecvOffset); + if ( v7->bCmd == CMD_DLEVEL_END ) + { + sgbDeltaChunks = 20; + sgbRecvCmd = CMD_DLEVEL_END; + goto LABEL_100; + } + sgdwRecvOffset = 0; +LABEL_98: + sgbRecvCmd = v7->bCmd; + goto LABEL_99; + } + } + else + { + if ( v3->bCmd != CMD_DLEVEL_END && (v3->bCmd != CMD_DLEVEL_0 || *(_WORD *)&v3[1].bCmd) ) + goto LABEL_100; + gbDeltaSender = pnum; + sgbRecvCmd = CMD_DLEVEL_END; + } + if ( v3->bCmd == CMD_DLEVEL_END ) + { + sgbDeltaChunks = 20; + goto LABEL_100; + } + if ( v3->bCmd == CMD_DLEVEL_0 && !*(_WORD *)&v3[1].bCmd ) + { + sgdwRecvOffset = 0; + goto LABEL_98; + } +LABEL_100: + result = *(unsigned short *)&v7[3].bCmd + 5; + break; + } + return result; +} +// 66E4A9: using guessed type char sbLastCmd; +// 67618D: using guessed type char sgbDeltaChunks; +// 6796E4: using guessed type char gbDeltaSender; + +//----- (0043D632) -------------------------------------------------------- +void __fastcall DoCopySync(unsigned char cmd, int recv_offset) +{ + unsigned char v2; // bl + int v3; // esi + void *v4; // eax + void *v5; // eax + + v2 = cmd; + if ( sgTempLevel.item[0].bCmd ) + encrypt_decompress(&sgTempLevel.item[0].x, recv_offset, 4721); + if ( v2 == CMD_DLEVEL_JUNK ) + { + msg_copy_portals((int)&sgTempLevel.item[0].x); + } + else if ( v2 < CMD_DLEVEL_0 || v2 > CMD_DLEVEL_16 ) + { + TermMsg("msg:1"); + } + else + { + v3 = (unsigned char)(v2 - CMD_DLEVEL_0); + v4 = msg_copy_items(&sgTempLevel.item[0].x, &sgLevels[v3]); + v5 = msg_copy_objects(v4, sgLevels[v3].object); + msg_copy_monsters(v5, sgLevels[v3].monster); + } + ++sgbDeltaChunks; + sgbDeltaChanged = 1; +} +// 67618C: using guessed type char sgbDeltaChanged; +// 67618D: using guessed type char sgbDeltaChunks; + +//----- (0043D6BA) -------------------------------------------------------- +void *__fastcall msg_copy_items(void *src, void *dst) +{ + char *v2; // edi + _BYTE *v3; // esi + signed int v4; // ebx + + v2 = (char *)dst; + v3 = (unsigned char *)src; + v4 = 127; + do + { + if ( *v3 == -1 ) + { + memset(v2, 255, 0x16u); + ++v3; + } + else + { + memcpy(v2, v3, 0x16u); + v3 += 22; + } + v2 += 22; + --v4; + } + while ( v4 ); + return v3; +} + +//----- (0043D6F5) -------------------------------------------------------- +void *__fastcall msg_copy_objects(void *src, void *dst) +{ + char *v2; // esi + + v2 = (char *)src; + memcpy(dst, src, 0x7Fu); + return v2 + 127; +} + +//----- (0043D709) -------------------------------------------------------- +void *__fastcall msg_copy_monsters(void *src, void *dst) +{ + char *v2; // edi + _BYTE *v3; // esi + signed int v4; // ebx + + v2 = (char *)dst; + v3 = (unsigned char *)src; + v4 = 200; + do + { + if ( *v3 == -1 ) + { + memset(v2, 255, 9u); + ++v3; + } + else + { + memcpy(v2, v3, 9u); + v3 += 9; + } + v2 += 9; + --v4; + } + while ( v4 ); + return v3; +} + +//----- (0043D746) -------------------------------------------------------- +char __fastcall msg_copy_portals(int a1) +{ + _BYTE *v1; // ebx + int v2; // edi + DJunk *v3; // esi + char result; // al + MultiQuests *v5; // esi + char *v6; // edi + unsigned char *v7; // ebp + + v1 = (_BYTE *)a1; + v2 = 0; + v3 = sgJunk; + do + { + if ( *v1 == -1 ) + { + memset(v3, 255, 5u); + ++v1; + SetPortalStats(v2, 0, 0, 0, 0, 0); + } + else + { + memcpy(v3, v1, 5u); + v1 += 5; + SetPortalStats( + v2, + 1, + (unsigned char)v3->portal[0].x, + (unsigned char)v3->portal[0].y, + (unsigned char)v3->portal[0].level, + (unsigned char)v3->portal[0].ltype); + } + v3 = (DJunk *)((char *)v3 + 5); + ++v2; + } + while ( (signed int)v3 < (signed int)sgJunk[0].quests ); + v5 = sgJunk[0].quests; + v6 = &quests[0]._qactive; + v7 = &questlist[0]._qflags; + do + { + if ( *v7 & 1 ) + { + memcpy(v5, v1, 3u); + *(_DWORD *)(v6 + 18) = (unsigned char)v5->qlog; + *v6 = v5->qstate; + result = v5->qvar1; + v1 += 3; + v6[13] = result; + ++v5; + } + v7 += 20; + v6 += 24; + } + while ( (signed int)v7 < (signed int)questyoff ); + return result; +} + +//----- (0043D7F1) -------------------------------------------------------- +int __fastcall On_SYNCDATA(void *packet, int pnum) +{ + return SyncData(pnum, (TSyncHeader *)packet); +} + +//----- (0043D7FC) -------------------------------------------------------- +int __fastcall On_WALKXY(struct TCmdLoc *pCmd, int pnum) +{ + int v2; // ebx + struct TCmdLoc *v3; // edi + int v4; // esi + + v2 = pnum; + v3 = pCmd; + if ( gbBufferMsgs != 1 ) + { + v4 = pnum; + if ( currlevel == plr[pnum].plrlevel ) + { + ClrPlrPath(pnum); + MakePlrPath(v2, (unsigned char)v3->x, (unsigned char)v3->y, 1u); + plr[v4].destAction = -1; + } + } + return 3; +} +// 676194: using guessed type char gbBufferMsgs; + +//----- (0043D84A) -------------------------------------------------------- +int __fastcall On_ADDSTR(struct TCmdParam1 *pCmd, int pnum) +{ + unsigned short v2; // cx + + if ( gbBufferMsgs == 1 ) + { + msg_send_packet(pnum, pCmd, 3); + } + else + { + v2 = pCmd->wParam1; + if ( v2 <= 0x100u ) + ModifyPlrStr(pnum, v2); + } + return 3; +} +// 676194: using guessed type char gbBufferMsgs; + +//----- (0043D87B) -------------------------------------------------------- +int __fastcall On_ADDMAG(struct TCmdParam1 *pCmd, int pnum) +{ + unsigned short v2; // cx + + if ( gbBufferMsgs == 1 ) + { + msg_send_packet(pnum, pCmd, 3); + } + else + { + v2 = pCmd->wParam1; + if ( v2 <= 0x100u ) + ModifyPlrMag(pnum, v2); + } + return 3; +} +// 676194: using guessed type char gbBufferMsgs; + +//----- (0043D8AC) -------------------------------------------------------- +int __fastcall On_ADDDEX(struct TCmdParam1 *pCmd, int pnum) +{ + unsigned short v2; // cx + + if ( gbBufferMsgs == 1 ) + { + msg_send_packet(pnum, pCmd, 3); + } + else + { + v2 = pCmd->wParam1; + if ( v2 <= 0x100u ) + ModifyPlrDex(pnum, v2); + } + return 3; +} +// 676194: using guessed type char gbBufferMsgs; + +//----- (0043D8DD) -------------------------------------------------------- +int __fastcall On_ADDVIT(struct TCmdParam1 *pCmd, int pnum) +{ + unsigned short v2; // cx + + if ( gbBufferMsgs == 1 ) + { + msg_send_packet(pnum, pCmd, 3); + } + else + { + v2 = pCmd->wParam1; + if ( v2 <= 0x100u ) + ModifyPlrVit(pnum, v2); + } + return 3; +} +// 676194: using guessed type char gbBufferMsgs; + +//----- (0043D90E) -------------------------------------------------------- +int __fastcall On_SBSPELL(struct TCmdParam1 *pCmd, int pnum) +{ + int v2; // eax + + if ( gbBufferMsgs != 1 ) + { + if ( currlevel || *(_DWORD *)&spelldata[(unsigned short)pCmd->wParam1].sTownSpell ) + { + v2 = pnum; + plr[v2]._pSpell = (unsigned short)pCmd->wParam1; + plr[v2]._pSplType = plr[v2]._pSBkSplType; + plr[v2]._pSplFrom = 1; + plr[v2].destAction = 12; + } + else + { + msg_errorf("%s has cast an illegal spell.", plr[pnum]._pName); + } + } + return 3; +} +// 676194: using guessed type char gbBufferMsgs; + +//----- (0043D97D) -------------------------------------------------------- +void msg_errorf(char *format, ...) +{ + DWORD v1; // eax + char v2[256]; // [esp+0h] [ebp-100h] + va_list va; // [esp+10Ch] [ebp+Ch] + + va_start(va, format); + v1 = GetTickCount(); + if ( v1 - msg_err_timer >= 5000 ) + { + msg_err_timer = v1; + vsprintf(v2, format, va); + ErrorPlrMsg(v2); + } +} +// 67619C: using guessed type int msg_err_timer; + +//----- (0043D9C4) -------------------------------------------------------- +int __fastcall On_GOTOGETITEM(struct TCmdLocParam1 *pCmd, int pnum) +{ + struct TCmdLocParam1 *v2; // edi + int v3; // esi + + v2 = pCmd; + if ( gbBufferMsgs != 1 ) + { + v3 = pnum; + if ( currlevel == plr[pnum].plrlevel ) + { + MakePlrPath(pnum, (unsigned char)pCmd->x, (unsigned char)pCmd->y, 0); + plr[v3].destAction = 15; + plr[v3].destParam1 = (unsigned short)v2->wParam1; + } + } + return 5; +} +// 676194: using guessed type char gbBufferMsgs; + +//----- (0043DA16) -------------------------------------------------------- +int __fastcall On_REQUESTGITEM(struct TCmdGItem *pCmd, int pnum) +{ + struct TCmdGItem *v2; // esi + int v3; // eax + int v4; // edx + int v5; // edx + int v6; // eax + int v7; // edi + unsigned char v8; // al + int v9; // edx + int v10; // eax + + v2 = pCmd; + if ( gbBufferMsgs != 1 ) + { + _LOBYTE(v3) = i_own_level(plr[pnum].plrlevel); + if ( v3 ) + { + _LOWORD(v4) = v2->wCI; + if ( GetItemRecord(v2->dwSeed, v4, (unsigned short)v2->wIndx) ) + { + _LOWORD(v5) = v2->wCI; + FindGetItem((unsigned short)v2->wIndx, v5, v2->dwSeed); + v7 = v6; + v8 = v2->bPnum; + if ( v7 == -1 ) + { + _LOBYTE(v10) = NetSendCmdReq2(CMD_REQUESTGITEM, myplr, v8, v2); + if ( !v10 ) + NetSendCmdExtra(v2); + } + else + { + NetSendCmdGItem2(0, CMD_GETITEM, myplr, v8, v2); + if ( (unsigned char)v2->bPnum == myplr ) + InvGetItem(myplr, v7); + else + SyncGetItem( + (unsigned char)v2->x, + (unsigned char)v2->y, + (unsigned short)v2->wIndx, + v2->wCI, + v2->dwSeed); + _LOWORD(v9) = v2->wCI; + SetItemRecord(v2->dwSeed, v9, (unsigned short)v2->wIndx); + } + } + } + } + return 30; +} +// 676194: using guessed type char gbBufferMsgs; + +//----- (0043DAE6) -------------------------------------------------------- +bool __fastcall i_own_level(int nReqLevel) +{ + int v1; // edx + char *v2; // eax + + v1 = 0; + v2 = &plr[0]._pLvlChanging; + do + { + if ( *(v2 - 290) && !*v2 && *(_DWORD *)(v2 - 267) == nReqLevel && (v1 != myplr || !gbBufferMsgs) ) + break; + v2 += 21720; + ++v1; + } + while ( (signed int)v2 < (signed int)&plr_msgs[1].msg[114] ); + return v1 == myplr; +} +// 676194: using guessed type char gbBufferMsgs; + +//----- (0043DB2D) -------------------------------------------------------- +int __fastcall On_GETITEM(struct TCmdGItem *pCmd, int pnum) +{ + struct TCmdGItem *v2; // esi + int v3; // eax + int v4; // edi + int v5; // eax + char v6; // al + int v7; // ecx + int v8; // edx + int v9; // eax + int v10; // edx + + v2 = pCmd; + if ( gbBufferMsgs == 1 ) + { + msg_send_packet((unsigned short)pnum, pCmd, 30); + } + else + { + FindGetItem((unsigned short)pCmd->wIndx, pCmd->wCI, pCmd->dwSeed); + v4 = v3; + _LOBYTE(v5) = delta_get_item(v2, v2->bLevel); + if ( !v5 ) + { + NetSendCmdGItem2(1u, CMD_GETITEM, v2->bMaster, v2->bPnum, v2); + return 30; + } + v6 = v2->bLevel; + v7 = myplr; + if ( (currlevel == v6 || (unsigned char)v2->bPnum == myplr) && (unsigned char)v2->bMaster != myplr ) + { + if ( (unsigned char)v2->bPnum != myplr ) + { + SyncGetItem( + (unsigned char)v2->x, + (unsigned char)v2->y, + (unsigned short)v2->wIndx, + v2->wCI, + v2->dwSeed); + return 30; + } + if ( currlevel == v6 ) + { + v10 = v4; + } + else + { + v8 = (unsigned char)v2->bId; + _LOWORD(v8) = v2->wCI; + v9 = SyncPutItem( + myplr, + plr[myplr].WorldX, + plr[myplr].WorldY, + (unsigned short)v2->wIndx, + v8, + v2->dwSeed, + (unsigned char)v2->bId, + (unsigned char)v2->bDur, + (unsigned char)v2->bMDur, + (unsigned char)v2->bCh, + (unsigned char)v2->bMCh, + (unsigned short)v2->wValue, + v2->dwBuff); + if ( v9 == -1 ) + return 30; + v7 = myplr; + v10 = v9; + } + InvGetItem(v7, v10); + return 30; + } + } + return 30; +} +// 676194: using guessed type char gbBufferMsgs; + +//----- (0043DC3D) -------------------------------------------------------- +unsigned char __fastcall delta_get_item(struct TCmdGItem *pI, unsigned char bLevel) +{ + struct TCmdGItem *v2; // esi + signed int v3; // ecx + DLevel *v4; // edi + DLevel *v5; // eax + char v6; // cl + DLevel *v8; // eax + signed int v9; // ecx + + v2 = pI; + if ( gbMaxPlayers != 1 ) + { + v3 = 0; + v4 = &sgLevels[bLevel]; + v5 = &sgLevels[bLevel]; + while ( v5->item[0].bCmd == -1 + || v5->item[0].wIndx != v2->wIndx + || v5->item[0].wCI != v2->wCI + || v5->item[0].dwSeed != v2->dwSeed ) + { + ++v3; + v5 = (DLevel *)((char *)v5 + 22); + if ( v3 >= 127 ) + goto LABEL_15; + } + v6 = v5->item[0].bCmd; + if ( v5->item[0].bCmd == 1 ) + return 1; + if ( !v6 ) + { + sgbDeltaChanged = 1; + v5->item[0].bCmd = 1; + return 1; + } + if ( v6 == 2 ) + { + v5->item[0].bCmd = -1; + sgbDeltaChanged = 1; + return 1; + } + TermMsg("delta:1"); +LABEL_15: + if ( v2->wCI >= 0 ) + return 0; + v8 = v4; + v9 = 0; + while ( v8->item[0].bCmd != -1 ) + { + ++v9; + v8 = (DLevel *)((char *)v8 + 22); + if ( v9 >= 127 ) + return 1; + } + sgbDeltaChanged = 1; + v8->item[0].bCmd = 1; + v8->item[0].x = v2->x; + v8->item[0].y = v2->y; + v8->item[0].wIndx = v2->wIndx; + v8->item[0].wCI = v2->wCI; + v8->item[0].dwSeed = v2->dwSeed; + v8->item[0].bId = v2->bId; + v8->item[0].bDur = v2->bDur; + v8->item[0].bMDur = v2->bMDur; + v8->item[0].bCh = v2->bCh; + v8->item[0].bMCh = v2->bMCh; + v8->item[0].wValue = v2->wValue; + v8->item[0].dwBuff = v2->dwBuff; + } + return 1; +} +// 67618C: using guessed type char sgbDeltaChanged; +// 679660: using guessed type char gbMaxPlayers; + +//----- (0043DD40) -------------------------------------------------------- +int __fastcall On_GOTOAGETITEM(struct TCmdLocParam1 *pCmd, int pnum) +{ + struct TCmdLocParam1 *v2; // edi + int v3; // esi + + v2 = pCmd; + if ( gbBufferMsgs != 1 ) + { + v3 = pnum; + if ( currlevel == plr[pnum].plrlevel ) + { + MakePlrPath(pnum, (unsigned char)pCmd->x, (unsigned char)pCmd->y, 0); + plr[v3].destAction = 16; + plr[v3].destParam1 = (unsigned short)v2->wParam1; + } + } + return 5; +} +// 676194: using guessed type char gbBufferMsgs; + +//----- (0043DD92) -------------------------------------------------------- +int __fastcall On_REQUESTAGITEM(struct TCmdGItem *pCmd, int pnum) +{ + struct TCmdGItem *v2; // esi + int v3; // eax + int v4; // edx + int v5; // edx + int v6; // eax + bool v7; // zf + unsigned char v8; // al + int v9; // edx + int v10; // eax + + v2 = pCmd; + if ( gbBufferMsgs != 1 ) + { + _LOBYTE(v3) = i_own_level(plr[pnum].plrlevel); + if ( v3 ) + { + _LOWORD(v4) = v2->wCI; + if ( GetItemRecord(v2->dwSeed, v4, (unsigned short)v2->wIndx) ) + { + _LOWORD(v5) = v2->wCI; + FindGetItem((unsigned short)v2->wIndx, v5, v2->dwSeed); + v7 = v6 == -1; + v8 = v2->bPnum; + if ( v7 ) + { + _LOBYTE(v10) = NetSendCmdReq2(CMD_REQUESTAGITEM, myplr, v8, v2); + if ( !v10 ) + NetSendCmdExtra(v2); + } + else + { + NetSendCmdGItem2(0, CMD_AGETITEM, myplr, v8, v2); + if ( (unsigned char)v2->bPnum == myplr ) + AutoGetItem(myplr, (unsigned char)v2->bCursitem); + else + SyncGetItem( + (unsigned char)v2->x, + (unsigned char)v2->y, + (unsigned short)v2->wIndx, + v2->wCI, + v2->dwSeed); + _LOWORD(v9) = v2->wCI; + SetItemRecord(v2->dwSeed, v9, (unsigned short)v2->wIndx); + } + } + } + } + return 30; +} +// 676194: using guessed type char gbBufferMsgs; + +//----- (0043DE60) -------------------------------------------------------- +int __fastcall On_AGETITEM(struct TCmdGItem *pCmd, int pnum) +{ + struct TCmdGItem *v2; // esi + int v3; // eax + char v4; // al + int v5; // ecx + int v6; // edx + int v7; // eax + int v8; // edx + + v2 = pCmd; + if ( gbBufferMsgs == 1 ) + { + msg_send_packet((unsigned short)pnum, pCmd, 30); + } + else + { + FindGetItem((unsigned short)pCmd->wIndx, pCmd->wCI, pCmd->dwSeed); + _LOBYTE(v3) = delta_get_item(v2, v2->bLevel); + if ( !v3 ) + { + NetSendCmdGItem2(1u, CMD_AGETITEM, v2->bMaster, v2->bPnum, v2); + return 30; + } + v4 = v2->bLevel; + v5 = myplr; + if ( (currlevel == v4 || (unsigned char)v2->bPnum == myplr) && (unsigned char)v2->bMaster != myplr ) + { + if ( (unsigned char)v2->bPnum != myplr ) + { + SyncGetItem( + (unsigned char)v2->x, + (unsigned char)v2->y, + (unsigned short)v2->wIndx, + v2->wCI, + v2->dwSeed); + return 30; + } + if ( currlevel == v4 ) + { + v8 = (unsigned char)v2->bCursitem; + } + else + { + v6 = (unsigned char)v2->bId; + _LOWORD(v6) = v2->wCI; + v7 = SyncPutItem( + myplr, + plr[myplr].WorldX, + plr[myplr].WorldY, + (unsigned short)v2->wIndx, + v6, + v2->dwSeed, + (unsigned char)v2->bId, + (unsigned char)v2->bDur, + (unsigned char)v2->bMDur, + (unsigned char)v2->bCh, + (unsigned char)v2->bMCh, + (unsigned short)v2->wValue, + v2->dwBuff); + if ( v7 == -1 ) + return 30; + v5 = myplr; + v8 = v7; + } + AutoGetItem(v5, v8); + return 30; + } + } + return 30; +} +// 676194: using guessed type char gbBufferMsgs; + +//----- (0043DF6E) -------------------------------------------------------- +int __fastcall On_ITEMEXTRA(struct TCmdGItem *pCmd, int pnum) +{ + int v2; // edi + struct TCmdGItem *v3; // esi + + v2 = pnum; + v3 = pCmd; + if ( gbBufferMsgs == 1 ) + { + msg_send_packet(pnum, pCmd, 30); + } + else + { + delta_get_item(pCmd, pCmd->bLevel); + if ( currlevel == plr[v2].plrlevel ) + SyncGetItem( + (unsigned char)v3->x, + (unsigned char)v3->y, + (unsigned short)v3->wIndx, + v3->wCI, + v3->dwSeed); + } + return 30; +} +// 676194: using guessed type char gbBufferMsgs; + +//----- (0043DFC9) -------------------------------------------------------- +int __fastcall On_PUTITEM(struct TCmdPItem *pCmd, int pnum) +{ + int v2; // edi + struct TCmdPItem *v3; // esi + unsigned char *v4; // ebx + int v5; // edx + int v6; // eax + int v7; // edx + int v8; // ebp + + v2 = pnum; + v3 = pCmd; + if ( gbBufferMsgs == 1 ) + { + msg_send_packet(pnum, pCmd, 22); + return 22; + } + v4 = (unsigned char *)&plr[pnum].plrlevel; + if ( currlevel != *(_DWORD *)v4 ) + { + _LOWORD(pnum) = pCmd->wCI; + PutItemRecord(pCmd->dwSeed, pnum, (unsigned short)pCmd->wIndx); + delta_put_item(v3, (unsigned char)v3->x, (unsigned char)v3->y, *v4); + check_update_plr(v2); + return 22; + } + v5 = (unsigned char)pCmd->x; + if ( v2 == myplr ) + v6 = InvPutItem(v2, v5, (unsigned char)pCmd->y); + else + v6 = SyncPutItem( + v2, + v5, + (unsigned char)pCmd->y, + (unsigned short)pCmd->wIndx, + (unsigned short)pCmd->wCI, + pCmd->dwSeed, + (unsigned char)pCmd->bId, + (unsigned char)pCmd->bDur, + (unsigned char)pCmd->bMDur, + (unsigned char)pCmd->bCh, + (unsigned char)pCmd->bMCh, + (unsigned short)pCmd->wValue, + pCmd->dwBuff); + v8 = v6; + if ( v6 != -1 ) + { + _LOWORD(v7) = v3->wCI; + PutItemRecord(v3->dwSeed, v7, (unsigned short)v3->wIndx); + delta_put_item(v3, items[v8]._ix, items[v8]._iy, *v4); + check_update_plr(v2); + } + return 22; +} +// 676194: using guessed type char gbBufferMsgs; + +//----- (0043E0CE) -------------------------------------------------------- +void __fastcall delta_put_item(struct TCmdPItem *pI, int x, int y, unsigned char bLevel) +{ + struct TCmdPItem *v4; // ebx + int v5; // eax + DLevel *v6; // esi + DLevel *v7; // edi + char v8; // al + signed int v9; // eax + char v10; // [esp+Ch] [ebp-4h] + signed int bLevela; // [esp+1Ch] [ebp+Ch] + + v10 = x; + v4 = pI; + if ( gbMaxPlayers != 1 ) + { + v5 = bLevel; + bLevela = 0; + v6 = &sgLevels[v5]; + v7 = &sgLevels[v5]; + do + { + v8 = v7->item[0].bCmd; + if ( v7->item[0].bCmd != 1 + && v8 != -1 + && v7->item[0].wIndx == v4->wIndx + && v7->item[0].wCI == v4->wCI + && v7->item[0].dwSeed == v4->dwSeed ) + { + if ( v8 == 2 ) + return; + TermMsg("Trying to drop a floor item?"); + } + ++bLevela; + v7 = (DLevel *)((char *)v7 + 22); + } + while ( bLevela < 127 ); + v9 = 0; + while ( v6->item[0].bCmd != -1 ) + { + ++v9; + v6 = (DLevel *)((char *)v6 + 22); + if ( v9 >= 127 ) + return; + } + sgbDeltaChanged = 1; + memcpy(v6, v4, 0x16u); + v6->item[0].x = v10; + v6->item[0].bCmd = 2; + v6->item[0].y = y; + } +} +// 67618C: using guessed type char sgbDeltaChanged; +// 679660: using guessed type char gbMaxPlayers; + +//----- (0043E179) -------------------------------------------------------- +void __fastcall check_update_plr(int pnum) +{ + if ( gbMaxPlayers != 1 && pnum == myplr ) + pfile_update(1); +} +// 679660: using guessed type char gbMaxPlayers; + +//----- (0043E193) -------------------------------------------------------- +int __fastcall On_SYNCPUTITEM(struct TCmdPItem *pCmd, int pnum) +{ + int v2; // ebx + struct TCmdPItem *v3; // esi + unsigned char *v4; // edi + int v5; // edx + int v6; // ebp + + v2 = pnum; + v3 = pCmd; + if ( gbBufferMsgs == 1 ) + { + msg_send_packet(pnum, pCmd, 22); + return 22; + } + v4 = (unsigned char *)&plr[pnum].plrlevel; + if ( currlevel != *(_DWORD *)v4 ) + { + _LOWORD(pnum) = pCmd->wCI; + PutItemRecord(pCmd->dwSeed, pnum, (unsigned short)pCmd->wIndx); + delta_put_item(v3, (unsigned char)v3->x, (unsigned char)v3->y, *v4); + check_update_plr(v2); + return 22; + } + v6 = SyncPutItem( + pnum, + (unsigned char)pCmd->x, + (unsigned char)pCmd->y, + (unsigned short)pCmd->wIndx, + (unsigned short)pCmd->wCI, + pCmd->dwSeed, + (unsigned char)pCmd->bId, + (unsigned char)pCmd->bDur, + (unsigned char)pCmd->bMDur, + (unsigned char)pCmd->bCh, + (unsigned char)pCmd->bMCh, + (unsigned short)pCmd->wValue, + pCmd->dwBuff); + if ( v6 != -1 ) + { + _LOWORD(v5) = v3->wCI; + PutItemRecord(v3->dwSeed, v5, (unsigned short)v3->wIndx); + delta_put_item(v3, items[v6]._ix, items[v6]._iy, *v4); + check_update_plr(v2); + } + return 22; +} +// 676194: using guessed type char gbBufferMsgs; + +//----- (0043E284) -------------------------------------------------------- +int __fastcall On_RESPAWNITEM(struct TCmdPItem *pCmd, int pnum) +{ + struct TCmdPItem *v2; // esi + unsigned char *v3; // edi + + v2 = pCmd; + if ( gbBufferMsgs == 1 ) + { + msg_send_packet(pnum, pCmd, 22); + } + else + { + v3 = (unsigned char *)&plr[pnum].plrlevel; + if ( currlevel == *(_DWORD *)v3 && pnum != myplr ) + SyncPutItem( + pnum, + (unsigned char)pCmd->x, + (unsigned char)pCmd->y, + (unsigned short)pCmd->wIndx, + (unsigned short)pCmd->wCI, + pCmd->dwSeed, + (unsigned char)pCmd->bId, + (unsigned char)pCmd->bDur, + (unsigned char)pCmd->bMDur, + (unsigned char)pCmd->bCh, + (unsigned char)pCmd->bMCh, + (unsigned short)pCmd->wValue, + pCmd->dwBuff); + _LOWORD(pnum) = v2->wCI; + PutItemRecord(v2->dwSeed, pnum, (unsigned short)v2->wIndx); + delta_put_item(v2, (unsigned char)v2->x, (unsigned char)v2->y, *v3); + } + return 22; +} +// 676194: using guessed type char gbBufferMsgs; + +//----- (0043E32A) -------------------------------------------------------- +int __fastcall On_ATTACKXY(struct TCmdLoc *pCmd, int pnum) +{ + struct TCmdLoc *v2; // edi + int v3; // esi + + v2 = pCmd; + if ( gbBufferMsgs != 1 ) + { + v3 = pnum; + if ( currlevel == plr[pnum].plrlevel ) + { + MakePlrPath(pnum, (unsigned char)pCmd->x, (unsigned char)pCmd->y, 0); + plr[v3].destAction = 9; + plr[v3].destParam1 = (unsigned char)v2->x; + plr[v3].destParam2 = (unsigned char)v2->y; + } + } + return 3; +} +// 676194: using guessed type char gbBufferMsgs; + +//----- (0043E386) -------------------------------------------------------- +int __fastcall On_SATTACKXY(struct TCmdLoc *pCmd, int pnum) +{ + struct TCmdLoc *v2; // edi + int v3; // esi + + v2 = pCmd; + if ( gbBufferMsgs != 1 ) + { + v3 = pnum; + if ( currlevel == plr[pnum].plrlevel ) + { + ClrPlrPath(pnum); + plr[v3].destAction = 9; + plr[v3].destParam1 = (unsigned char)v2->x; + plr[v3].destParam2 = (unsigned char)v2->y; + } + } + return 3; +} +// 676194: using guessed type char gbBufferMsgs; + +//----- (0043E3D5) -------------------------------------------------------- +int __fastcall On_RATTACKXY(struct TCmdLoc *pCmd, int pnum) +{ + struct TCmdLoc *v2; // edi + int v3; // esi + + v2 = pCmd; + if ( gbBufferMsgs != 1 ) + { + v3 = pnum; + if ( currlevel == plr[pnum].plrlevel ) + { + ClrPlrPath(pnum); + plr[v3].destAction = 10; + plr[v3].destParam1 = (unsigned char)v2->x; + plr[v3].destParam2 = (unsigned char)v2->y; + } + } + return 3; +} +// 676194: using guessed type char gbBufferMsgs; + +//----- (0043E424) -------------------------------------------------------- +int __fastcall On_SPELLXYD(struct TCmdLocParam3 *pCmd, int pnum) +{ + struct TCmdLocParam3 *v2; // edi + int v3; // esi + int v4; // eax + + v2 = pCmd; + if ( gbBufferMsgs != 1 ) + { + v3 = pnum; + if ( currlevel == plr[pnum].plrlevel ) + { + if ( currlevel || *(_DWORD *)&spelldata[(unsigned short)pCmd->wParam1].sTownSpell ) + { + ClrPlrPath(pnum); + plr[v3].destAction = 26; + plr[v3].destParam1 = (unsigned char)v2->x; + plr[v3].destParam2 = (unsigned char)v2->y; + plr[v3].destParam3 = (unsigned short)v2->wParam2; + plr[v3].destParam4 = (unsigned short)v2->wParam3; + v4 = (unsigned short)v2->wParam1; + plr[v3]._pSplFrom = 0; + plr[v3]._pSpell = v4; + plr[v3]._pSplType = plr[v3]._pRSplType; + } + else + { + msg_errorf("%s has cast an illegal spell.", plr[v3]._pName); + } + } + } + return 9; +} +// 676194: using guessed type char gbBufferMsgs; + +//----- (0043E4D2) -------------------------------------------------------- +int __fastcall On_SPELLXY(struct TCmdLocParam2 *pCmd, int pnum) +{ + struct TCmdLocParam2 *v2; // edi + int v3; // esi + int v4; // eax + + v2 = pCmd; + if ( gbBufferMsgs != 1 ) + { + v3 = pnum; + if ( currlevel == plr[pnum].plrlevel ) + { + if ( currlevel || *(_DWORD *)&spelldata[(unsigned short)pCmd->wParam1].sTownSpell ) + { + ClrPlrPath(pnum); + plr[v3].destAction = 12; + plr[v3].destParam1 = (unsigned char)v2->x; + plr[v3].destParam2 = (unsigned char)v2->y; + plr[v3].destParam3 = (unsigned short)v2->wParam2; + v4 = (unsigned short)v2->wParam1; + plr[v3]._pSplFrom = 0; + plr[v3]._pSpell = v4; + plr[v3]._pSplType = plr[v3]._pRSplType; + } + else + { + msg_errorf("%s has cast an illegal spell.", plr[v3]._pName); + } + } + } + return 7; +} +// 676194: using guessed type char gbBufferMsgs; + +//----- (0043E576) -------------------------------------------------------- +int __fastcall On_TSPELLXY(struct TCmdLocParam2 *pCmd, int pnum) +{ + struct TCmdLocParam2 *v2; // edi + int v3; // esi + + v2 = pCmd; + if ( gbBufferMsgs != 1 ) + { + v3 = pnum; + if ( currlevel == plr[pnum].plrlevel ) + { + if ( currlevel || *(_DWORD *)&spelldata[(unsigned short)pCmd->wParam1].sTownSpell ) + { + ClrPlrPath(pnum); + plr[v3].destAction = 12; + plr[v3].destParam1 = (unsigned char)v2->x; + plr[v3].destParam2 = (unsigned char)v2->y; + plr[v3].destParam3 = (unsigned short)v2->wParam2; + plr[v3]._pSpell = (unsigned short)v2->wParam1; + plr[v3]._pSplType = plr[v3]._pTSplType; + plr[v3]._pSplFrom = 2; + } + else + { + msg_errorf("%s has cast an illegal spell.", plr[v3]._pName); + } + } + } + return 7; +} +// 676194: using guessed type char gbBufferMsgs; + +//----- (0043E61A) -------------------------------------------------------- +int __fastcall On_OPOBJXY(struct TCmdLocParam1 *pCmd, int pnum) +{ + struct TCmdLocParam1 *v2; // esi + int v3; // edi + int v4; // eax + + v2 = pCmd; + if ( gbBufferMsgs != 1 ) + { + v3 = pnum; + if ( currlevel == plr[pnum].plrlevel ) + { + v4 = (unsigned short)pCmd->wParam1; + if ( object[v4]._oSolidFlag || object[v4]._oDoorFlag ) + MakePlrPath(pnum, (unsigned char)pCmd->x, (unsigned char)pCmd->y, 0); + else + MakePlrPath(pnum, (unsigned char)pCmd->x, (unsigned char)pCmd->y, 1u); + plr[v3].destAction = 13; + plr[v3].destParam1 = (unsigned short)v2->wParam1; + } + } + return 5; +} +// 676194: using guessed type char gbBufferMsgs; + +//----- (0043E68A) -------------------------------------------------------- +int __fastcall On_DISARMXY(struct TCmdLocParam1 *pCmd, int pnum) +{ + struct TCmdLocParam1 *v2; // esi + int v3; // edi + int v4; // eax + + v2 = pCmd; + if ( gbBufferMsgs != 1 ) + { + v3 = pnum; + if ( currlevel == plr[pnum].plrlevel ) + { + v4 = (unsigned short)pCmd->wParam1; + if ( object[v4]._oSolidFlag || object[v4]._oDoorFlag ) + MakePlrPath(pnum, (unsigned char)pCmd->x, (unsigned char)pCmd->y, 0); + else + MakePlrPath(pnum, (unsigned char)pCmd->x, (unsigned char)pCmd->y, 1u); + plr[v3].destAction = 14; + plr[v3].destParam1 = (unsigned short)v2->wParam1; + } + } + return 5; +} +// 676194: using guessed type char gbBufferMsgs; + +//----- (0043E6FA) -------------------------------------------------------- +int __fastcall On_OPOBJT(struct TCmdParam1 *pCmd, int pnum) +{ + int v2; // eax + + if ( gbBufferMsgs != 1 ) + { + v2 = pnum; + if ( currlevel == plr[pnum].plrlevel ) + { + plr[v2].destAction = 18; + plr[v2].destParam1 = (unsigned short)pCmd->wParam1; + } + } + return 3; +} +// 676194: using guessed type char gbBufferMsgs; + +//----- (0043E732) -------------------------------------------------------- +int __fastcall On_ATTACKID(struct TCmdParam1 *pCmd, int pnum) +{ + int v2; // ebp + struct TCmdParam1 *v3; // edi + int v4; // esi + int v5; // ebx + int v6; // eax + + v2 = pnum; + v3 = pCmd; + if ( gbBufferMsgs != 1 ) + { + v4 = pnum; + if ( currlevel == plr[pnum].plrlevel ) + { + v5 = abs(plr[v4].WorldX - monster[(unsigned short)pCmd->wParam1]._mfutx); + v6 = abs(plr[v4].WorldY - monster[(unsigned short)v3->wParam1]._mfuty); + if ( v5 > 1 || v6 > 1 ) + MakePlrPath( + v2, + monster[(unsigned short)v3->wParam1]._mfutx, + monster[(unsigned short)v3->wParam1]._mfuty, + 0); + plr[v4].destAction = 20; + plr[v4].destParam1 = (unsigned short)v3->wParam1; + } + } + return 3; +} +// 676194: using guessed type char gbBufferMsgs; + +//----- (0043E7DF) -------------------------------------------------------- +int __fastcall On_ATTACKPID(struct TCmdParam1 *pCmd, int pnum) +{ + struct TCmdParam1 *v2; // edi + int v3; // esi + + v2 = pCmd; + if ( gbBufferMsgs != 1 ) + { + v3 = pnum; + if ( currlevel == plr[pnum].plrlevel ) + { + MakePlrPath(pnum, plr[(unsigned short)pCmd->wParam1]._px, plr[(unsigned short)pCmd->wParam1]._py, 0); + plr[v3].destAction = 21; + plr[v3].destParam1 = (unsigned short)v2->wParam1; + } + } + return 3; +} +// 676194: using guessed type char gbBufferMsgs; + +//----- (0043E840) -------------------------------------------------------- +int __fastcall On_RATTACKID(struct TCmdParam1 *pCmd, int pnum) +{ + struct TCmdParam1 *v2; // edi + int v3; // esi + + v2 = pCmd; + if ( gbBufferMsgs != 1 ) + { + v3 = pnum; + if ( currlevel == plr[pnum].plrlevel ) + { + ClrPlrPath(pnum); + plr[v3].destAction = 22; + plr[v3].destParam1 = (unsigned short)v2->wParam1; + } + } + return 3; +} +// 676194: using guessed type char gbBufferMsgs; + +//----- (0043E885) -------------------------------------------------------- +int __fastcall On_RATTACKPID(struct TCmdParam1 *pCmd, int pnum) +{ + struct TCmdParam1 *v2; // edi + int v3; // esi + + v2 = pCmd; + if ( gbBufferMsgs != 1 ) + { + v3 = pnum; + if ( currlevel == plr[pnum].plrlevel ) + { + ClrPlrPath(pnum); + plr[v3].destAction = 23; + plr[v3].destParam1 = (unsigned short)v2->wParam1; + } + } + return 3; +} +// 676194: using guessed type char gbBufferMsgs; + +//----- (0043E8CA) -------------------------------------------------------- +int __fastcall On_SPELLID(struct TCmdLocParam2 *pCmd, int pnum) +{ + struct TCmdLocParam2 *v2; // edi + int v3; // esi + int v4; // eax + + v2 = pCmd; + if ( gbBufferMsgs != 1 ) + { + v3 = pnum; + if ( currlevel == plr[pnum].plrlevel ) + { + if ( currlevel || *(_DWORD *)&spelldata[(unsigned short)pCmd->wParam1].sTownSpell ) + { + ClrPlrPath(pnum); + plr[v3].destAction = 24; + plr[v3].destParam1 = *(unsigned short *)&v2->x; + plr[v3].destParam2 = (unsigned short)v2->wParam2; + v4 = (unsigned short)v2->wParam1; + plr[v3]._pSplFrom = 0; + plr[v3]._pSpell = v4; + plr[v3]._pSplType = plr[v3]._pRSplType; + } + else + { + msg_errorf("%s has cast an illegal spell.", plr[v3]._pName); + } + } + } + return 7; +} +// 676194: using guessed type char gbBufferMsgs; + +//----- (0043E964) -------------------------------------------------------- +int __fastcall On_SPELLPID(struct TCmdLocParam2 *pCmd, int pnum) +{ + struct TCmdLocParam2 *v2; // edi + int v3; // esi + int v4; // eax + + v2 = pCmd; + if ( gbBufferMsgs != 1 ) + { + v3 = pnum; + if ( currlevel == plr[pnum].plrlevel ) + { + if ( currlevel || *(_DWORD *)&spelldata[(unsigned short)pCmd->wParam1].sTownSpell ) + { + ClrPlrPath(pnum); + plr[v3].destAction = 25; + plr[v3].destParam1 = *(unsigned short *)&v2->x; + plr[v3].destParam2 = (unsigned short)v2->wParam2; + v4 = (unsigned short)v2->wParam1; + plr[v3]._pSplFrom = 0; + plr[v3]._pSpell = v4; + plr[v3]._pSplType = plr[v3]._pRSplType; + } + else + { + msg_errorf("%s has cast an illegal spell.", plr[v3]._pName); + } + } + } + return 7; +} +// 676194: using guessed type char gbBufferMsgs; + +//----- (0043E9FE) -------------------------------------------------------- +int __fastcall On_TSPELLID(struct TCmdLocParam2 *pCmd, int pnum) +{ + struct TCmdLocParam2 *v2; // edi + int v3; // esi + + v2 = pCmd; + if ( gbBufferMsgs != 1 ) + { + v3 = pnum; + if ( currlevel == plr[pnum].plrlevel ) + { + if ( currlevel || *(_DWORD *)&spelldata[(unsigned short)pCmd->wParam1].sTownSpell ) + { + ClrPlrPath(pnum); + plr[v3].destAction = 24; + plr[v3].destParam1 = *(unsigned short *)&v2->x; + plr[v3].destParam2 = (unsigned short)v2->wParam2; + plr[v3]._pSpell = (unsigned short)v2->wParam1; + plr[v3]._pSplType = plr[v3]._pTSplType; + plr[v3]._pSplFrom = 2; + } + else + { + msg_errorf("%s has cast an illegal spell.", plr[v3]._pName); + } + } + } + return 7; +} +// 676194: using guessed type char gbBufferMsgs; + +//----- (0043EA98) -------------------------------------------------------- +int __fastcall On_TSPELLPID(struct TCmdLocParam2 *pCmd, int pnum) +{ + struct TCmdLocParam2 *v2; // edi + int v3; // esi + + v2 = pCmd; + if ( gbBufferMsgs != 1 ) + { + v3 = pnum; + if ( currlevel == plr[pnum].plrlevel ) + { + if ( currlevel || *(_DWORD *)&spelldata[(unsigned short)pCmd->wParam1].sTownSpell ) + { + ClrPlrPath(pnum); + plr[v3].destAction = 25; + plr[v3].destParam1 = *(unsigned short *)&v2->x; + plr[v3].destParam2 = (unsigned short)v2->wParam2; + plr[v3]._pSpell = (unsigned short)v2->wParam1; + plr[v3]._pSplType = plr[v3]._pTSplType; + plr[v3]._pSplFrom = 2; + } + else + { + msg_errorf("%s has cast an illegal spell.", plr[v3]._pName); + } + } + } + return 7; +} +// 676194: using guessed type char gbBufferMsgs; + +//----- (0043EB32) -------------------------------------------------------- +int __fastcall On_KNOCKBACK(struct TCmdParam1 *pCmd, int pnum) +{ + int v2; // edi + struct TCmdParam1 *v3; // esi + + v2 = pnum; + v3 = pCmd; + if ( gbBufferMsgs != 1 && currlevel == plr[pnum].plrlevel ) + { + M_GetKnockback((unsigned short)pCmd->wParam1); + M_StartHit((unsigned short)v3->wParam1, v2, 0); + } + return 3; +} +// 676194: using guessed type char gbBufferMsgs; + +//----- (0043EB74) -------------------------------------------------------- +int __fastcall On_RESURRECT(struct TCmdParam1 *pCmd, int pnum) +{ + int v2; // esi + + v2 = pnum; + if ( gbBufferMsgs == 1 ) + { + msg_send_packet(pnum, pCmd, 3); + } + else + { + DoResurrect(pnum, (unsigned short)pCmd->wParam1); + check_update_plr(v2); + } + return 3; +} +// 676194: using guessed type char gbBufferMsgs; + +//----- (0043EBA4) -------------------------------------------------------- +int __fastcall On_HEALOTHER(struct TCmdParam1 *pCmd, int pnum) +{ + if ( gbBufferMsgs != 1 && currlevel == plr[pnum].plrlevel ) + DoHealOther(pnum, (unsigned short)pCmd->wParam1); + return 3; +} +// 676194: using guessed type char gbBufferMsgs; + +//----- (0043EBD5) -------------------------------------------------------- +int __fastcall On_TALKXY(struct TCmdLocParam1 *pCmd, int pnum) +{ + struct TCmdLocParam1 *v2; // edi + int v3; // esi + + v2 = pCmd; + if ( gbBufferMsgs != 1 ) + { + v3 = pnum; + if ( currlevel == plr[pnum].plrlevel ) + { + MakePlrPath(pnum, (unsigned char)pCmd->x, (unsigned char)pCmd->y, 0); + plr[v3].destAction = 17; + plr[v3].destParam1 = (unsigned short)v2->wParam1; + } + } + return 5; +} +// 676194: using guessed type char gbBufferMsgs; + +//----- (0043EC27) -------------------------------------------------------- +int __fastcall On_NEWLVL(struct TCmdParam2 *pCmd, int pnum) +{ + if ( gbBufferMsgs == 1 ) + { + msg_send_packet(pnum, pCmd, 5); + } + else if ( pnum != myplr ) + { + StartNewLvl(pnum, (unsigned short)pCmd->wParam1, (unsigned short)pCmd->wParam2); + } + return 5; +} +// 676194: using guessed type char gbBufferMsgs; + +//----- (0043EC5B) -------------------------------------------------------- +int __fastcall On_WARP(struct TCmdParam1 *pCmd, int pnum) +{ + int v2; // esi + + v2 = pnum; + if ( gbBufferMsgs == 1 ) + { + msg_send_packet(pnum, pCmd, 3); + } + else + { + StartWarpLvl(pnum, (unsigned short)pCmd->wParam1); + if ( v2 == myplr && pcurs >= CURSOR_FIRSTITEM ) + { + qmemcpy(&items[127], &plr[myplr].HoldItem, sizeof(ItemStruct)); + AutoGetItem(myplr, 127); + } + } + return 3; +} +// 676194: using guessed type char gbBufferMsgs; + +//----- (0043ECBA) -------------------------------------------------------- +int __fastcall On_MONSTDEATH(struct TCmdLocParam1 *pCmd, int pnum) +{ + struct TCmdLocParam1 *v2; // esi + unsigned char *v3; // edi + + v2 = pCmd; + if ( gbBufferMsgs == 1 ) + { + msg_send_packet(pnum, pCmd, 5); + } + else if ( pnum != myplr ) + { + v3 = (unsigned char *)&plr[pnum].plrlevel; + if ( currlevel == *(_DWORD *)v3 ) + M_SyncStartKill((unsigned short)pCmd->wParam1, (unsigned char)pCmd->x, (unsigned char)pCmd->y, pnum); + delta_kill_monster((unsigned short)v2->wParam1, v2->x, v2->y, *v3); + } + return 5; +} +// 676194: using guessed type char gbBufferMsgs; + +//----- (0043ED23) -------------------------------------------------------- +int __fastcall On_KILLGOLEM(struct TCmdLocParam1 *pCmd, int pnum) +{ + int v2; // edi + struct TCmdLocParam1 *v3; // esi + + v2 = pnum; + v3 = pCmd; + if ( gbBufferMsgs == 1 ) + { + msg_send_packet(pnum, pCmd, 5); + } + else if ( pnum != myplr ) + { + if ( currlevel == pCmd->wParam1 ) + M_SyncStartKill(pnum, (unsigned char)pCmd->x, (unsigned char)pCmd->y, pnum); + delta_kill_monster(v2, v3->x, v3->y, plr[v2].plrlevel); + } + return 5; +} +// 676194: using guessed type char gbBufferMsgs; + +//----- (0043ED89) -------------------------------------------------------- +int __fastcall On_AWAKEGOLEM(struct TCmdGolem *pCmd, int pnum) +{ + int v2; // esi + int v3; // eax + signed int v4; // ebp + int v5; // edi + int v6; // edx + + v2 = pnum; + if ( gbBufferMsgs == 1 ) + { + msg_send_packet(pnum, pCmd, 10); + } + else + { + v3 = 21720 * pnum; + if ( currlevel == plr[pnum].plrlevel ) + { + if ( pnum != myplr ) + { + v4 = 1; + v5 = 0; + if ( nummissiles <= 0 ) + goto LABEL_16; + do + { + v6 = missileactive[v5]; + if ( missile[v6]._mitype == 33 && missile[v6]._misource == v2 ) + v4 = 0; + ++v5; + } + while ( v5 < nummissiles ); + if ( v4 ) +LABEL_16: + AddMissile( + *(int *)((char *)&plr[0].WorldX + v3), + *(int *)((char *)&plr[0].WorldY + v3), + (unsigned char)pCmd->_mx, + (unsigned char)pCmd->_my, + (unsigned char)pCmd->_mdir, + 33, + 0, + v2, + 0, + 1); + } + } + else + { + _LOBYTE(v3) = pCmd->_currlevel; + delta_sync_golem(pCmd, pnum, v3); + } + } + return 10; +} +// 676194: using guessed type char gbBufferMsgs; + +//----- (0043EE3D) -------------------------------------------------------- +int __fastcall On_MONSTDAMAGE(struct TCmdLocParam1 *pCmd, int pnum) +{ + int v2; // edi + struct TCmdLocParam1 *v3; // edx + unsigned char *v4; // ebx + char *v5; // esi + int *v6; // ecx + int *v7; // eax + + v2 = pnum; + v3 = pCmd; + if ( gbBufferMsgs == 1 ) + { + msg_send_packet(v2, pCmd, 5); + } + else if ( v2 != myplr ) + { + v4 = (unsigned char *)&plr[v2].plrlevel; + if ( currlevel == *(_DWORD *)v4 ) + { + v5 = &monster[*(unsigned short *)&pCmd->x].mWhoHit; + *v5 |= 1 << v2; + v6 = &monster[*(unsigned short *)&pCmd->x]._mhitpoints; + if ( *v6 ) + { + *v6 -= (unsigned short)v3->wParam1; + v7 = &monster[*(unsigned short *)&v3->x]._mhitpoints; + if ( (signed int)(*v7 & 0xFFFFFFC0) < 64 ) + *v7 = 64; + delta_monster_hp(*(unsigned short *)&v3->x, monster[*(unsigned short *)&v3->x]._mhitpoints, *v4); + } + } + } + return 5; +} +// 676194: using guessed type char gbBufferMsgs; + +//----- (0043EEF5) -------------------------------------------------------- +int __fastcall On_PLRDEAD(struct TCmdParam1 *pCmd, int pnum) +{ + if ( gbBufferMsgs == 1 ) + { + msg_send_packet(pnum, pCmd, 3); + } + else if ( pnum == myplr ) + { + check_update_plr(pnum); + } + else + { + StartPlayerKill(pnum, (unsigned short)pCmd->wParam1); + } + return 3; +} +// 676194: using guessed type char gbBufferMsgs; + +//----- (0043EF2D) -------------------------------------------------------- +int __fastcall On_PLRDAMAGE(struct TCmdDamage *pCmd, int pnum) +{ + int v2; // edi + int v3; // eax + int v4; // esi + int *v5; // esi + int v6; // ecx + + v2 = myplr; + if ( (unsigned char)pCmd->bPlr == myplr ) + { + if ( currlevel ) + { + if ( gbBufferMsgs != 1 && currlevel == plr[pnum].plrlevel && pCmd->dwDam <= 0x2EE00u ) + { + v3 = myplr; + v4 = plr[myplr]._pHitPoints; + if ( (signed int)(v4 & 0xFFFFFFC0) > 0 ) + { + drawhpflag = 1; + plr[v3]._pHitPoints = v4 - pCmd->dwDam; + v5 = &plr[v3]._pHPBase; + *v5 -= pCmd->dwDam; + v6 = plr[v3]._pMaxHP; + if ( plr[v3]._pHitPoints > v6 ) + { + plr[v3]._pHitPoints = v6; + *v5 = plr[v3]._pMaxHPBase; + } + if ( (signed int)(plr[v3]._pHitPoints & 0xFFFFFFC0) <= 0 ) + SyncPlrKill(v2, 1); + } + } + } + } + return 6; +} +// 676194: using guessed type char gbBufferMsgs; + +//----- (0043EFDD) -------------------------------------------------------- +int __fastcall On_OPENDOOR(struct TCmdParam1 *pCmd, int pnum) +{ + struct TCmdParam1 *v2; // edi + unsigned char *v3; // esi + + v2 = pCmd; + if ( gbBufferMsgs == 1 ) + { + msg_send_packet(pnum, pCmd, 3); + } + else + { + v3 = (unsigned char *)&plr[pnum].plrlevel; + if ( currlevel == *(_DWORD *)v3 ) + SyncOpObject(pnum, 43, (unsigned short)pCmd->wParam1); + delta_sync_object((unsigned short)v2->wParam1, 0x2Bu, *v3); + } + return 3; +} +// 676194: using guessed type char gbBufferMsgs; + +//----- (0043F033) -------------------------------------------------------- +void __fastcall delta_sync_object(int oi, unsigned char bCmd, unsigned char bLevel) +{ + if ( gbMaxPlayers != 1 ) + { + sgbDeltaChanged = 1; + sgLevels[bLevel].object[oi].bCmd = bCmd; + } +} +// 67618C: using guessed type char sgbDeltaChanged; +// 679660: using guessed type char gbMaxPlayers; + +//----- (0043F058) -------------------------------------------------------- +int __fastcall On_CLOSEDOOR(struct TCmdParam1 *pCmd, int pnum) +{ + struct TCmdParam1 *v2; // edi + unsigned char *v3; // esi + + v2 = pCmd; + if ( gbBufferMsgs == 1 ) + { + msg_send_packet(pnum, pCmd, 3); + } + else + { + v3 = (unsigned char *)&plr[pnum].plrlevel; + if ( currlevel == *(_DWORD *)v3 ) + SyncOpObject(pnum, 44, (unsigned short)pCmd->wParam1); + delta_sync_object((unsigned short)v2->wParam1, 0x2Cu, *v3); + } + return 3; +} +// 676194: using guessed type char gbBufferMsgs; + +//----- (0043F0AE) -------------------------------------------------------- +int __fastcall On_OPERATEOBJ(struct TCmdParam1 *pCmd, int pnum) +{ + struct TCmdParam1 *v2; // edi + unsigned char *v3; // esi + + v2 = pCmd; + if ( gbBufferMsgs == 1 ) + { + msg_send_packet(pnum, pCmd, 3); + } + else + { + v3 = (unsigned char *)&plr[pnum].plrlevel; + if ( currlevel == *(_DWORD *)v3 ) + SyncOpObject(pnum, 45, (unsigned short)pCmd->wParam1); + delta_sync_object((unsigned short)v2->wParam1, 0x2Du, *v3); + } + return 3; +} +// 676194: using guessed type char gbBufferMsgs; + +//----- (0043F104) -------------------------------------------------------- +int __fastcall On_PLROPOBJ(struct TCmdParam2 *pCmd, int pnum) +{ + struct TCmdParam2 *v2; // esi + unsigned char *v3; // edi + + v2 = pCmd; + if ( gbBufferMsgs == 1 ) + { + msg_send_packet(pnum, pCmd, 5); + } + else + { + v3 = (unsigned char *)&plr[pnum].plrlevel; + if ( currlevel == *(_DWORD *)v3 ) + SyncOpObject((unsigned short)pCmd->wParam1, 46, (unsigned short)pCmd->wParam2); + delta_sync_object((unsigned short)v2->wParam2, 0x2Eu, *v3); + } + return 5; +} +// 676194: using guessed type char gbBufferMsgs; + +//----- (0043F15C) -------------------------------------------------------- +int __fastcall On_BREAKOBJ(struct TCmdParam2 *pCmd, int pnum) +{ + struct TCmdParam2 *v2; // esi + unsigned char *v3; // edi + + v2 = pCmd; + if ( gbBufferMsgs == 1 ) + { + msg_send_packet(pnum, pCmd, 5); + } + else + { + v3 = (unsigned char *)&plr[pnum].plrlevel; + if ( currlevel == *(_DWORD *)v3 ) + SyncBreakObj((unsigned short)pCmd->wParam1, (unsigned short)pCmd->wParam2); + delta_sync_object((unsigned short)v2->wParam2, 0x2Fu, *v3); + } + return 5; +} +// 676194: using guessed type char gbBufferMsgs; + +//----- (0043F1B0) -------------------------------------------------------- +int __fastcall On_CHANGEPLRITEMS(struct TCmdChItem *pCmd, int pnum) +{ + int v2; // eax + int v3; // edx + int v4; // ST04_4 + int v5; // edx + + v2 = pnum; + if ( gbBufferMsgs == 1 ) + { + msg_send_packet(pnum, pCmd, 11); + } + else if ( pnum != myplr ) + { + v3 = (unsigned char)pCmd->bId; + _LOWORD(v3) = pCmd->wCI; + v4 = v3; + v5 = (unsigned short)pCmd->wIndx; + _LOBYTE(v5) = pCmd->bLoc; + CheckInvSwap(v2, v5, (unsigned short)pCmd->wIndx, v4, pCmd->dwSeed, (unsigned char)pCmd->bId); + } + return 11; +} +// 676194: using guessed type char gbBufferMsgs; + +//----- (0043F1F0) -------------------------------------------------------- +int __fastcall On_DELPLRITEMS(struct TCmdDelItem *pCmd, int pnum) +{ + int v2; // eax + + v2 = pnum; + if ( gbBufferMsgs == 1 ) + { + msg_send_packet(pnum, pCmd, 2); + } + else if ( pnum != myplr ) + { + _LOBYTE(pnum) = pCmd->bLoc; + inv_update_rem_item(v2, pnum); + } + return 2; +} +// 676194: using guessed type char gbBufferMsgs; + +//----- (0043F21E) -------------------------------------------------------- +int __fastcall On_PLRLEVEL(struct TCmdParam1 *pCmd, int pnum) +{ + if ( gbBufferMsgs == 1 ) + { + msg_send_packet(pnum, pCmd, 3); + } + else if ( pCmd->wParam1 <= 0x33u && pnum != myplr ) + { + plr[pnum]._pLevel = pCmd->wParam1; + } + return 3; +} +// 676194: using guessed type char gbBufferMsgs; + +//----- (0043F258) -------------------------------------------------------- +int __fastcall On_DROPITEM(struct TCmdPItem *pCmd, int pnum) +{ + if ( gbBufferMsgs == 1 ) + msg_send_packet(pnum, pCmd, 22); + else + delta_put_item(pCmd, (unsigned char)pCmd->x, (unsigned char)pCmd->y, plr[pnum].plrlevel); + return 22; +} +// 676194: using guessed type char gbBufferMsgs; + +//----- (0043F28F) -------------------------------------------------------- +int __fastcall On_SEND_PLRINFO(struct TCmdPlrInfoHdr *pCmd, int pnum) +{ + struct TCmdPlrInfoHdr *v2; // esi + + v2 = pCmd; + if ( gbBufferMsgs == 1 ) + msg_send_packet(pnum, pCmd, (unsigned short)pCmd->wBytes + 5); + else + multi_player_joins(pnum, pCmd, pCmd->bCmd == 2); + return (unsigned short)v2->wBytes + 5; +} +// 676194: using guessed type char gbBufferMsgs; + +int __fastcall On_ACK_PLRINFO(struct TCmdPlrInfoHdr *pCmd, int pnum) +{ + return On_SEND_PLRINFO(pCmd, pnum); +} + +//----- (0043F2CE) -------------------------------------------------------- +int __fastcall On_PLAYER_JOINLEVEL(struct TCmdLocParam1 *pCmd, int pnum) +{ + int v2; // ebx + struct TCmdLocParam1 *v3; // edi + int v4; // esi + int v5; // ecx + int v6; // ST08_4 + int v7; // edx + int v8; // eax + int v9; // ecx + int v10; // eax + int v11; // eax + + v2 = pnum; + v3 = pCmd; + if ( gbBufferMsgs == 1 ) + { + msg_send_packet(pnum, pCmd, 5); + } + else + { + v4 = pnum; + plr[pnum]._pLvlChanging = 0; + if ( plr[pnum]._pName[0] && !plr[v4].plractive[0] ) + { + plr[v4].plractive[0] = 1; + ++gbActivePlayers; + EventPlrMsg("Player '%s' (level %d) just joined the game", plr[pnum]._pName, plr[v4]._pLevel); + } + if ( plr[v4].plractive[0] ) + { + if ( myplr != v2 ) + { + plr[v4].WorldX = (unsigned char)v3->x; + plr[v4].WorldY = (unsigned char)v3->y; + v5 = (unsigned short)v3->wParam1; + plr[v4]._pGFXLoad = 0; + plr[v4].plrlevel = v5; + if ( currlevel == plr[v4].plrlevel ) + { + LoadPlrGFX(v2, 1); + SyncInitPlr(v2); + if ( (signed int)(plr[v4]._pHitPoints & 0xFFFFFFC0) <= 0 ) + { + plr[v4]._pgfxnum = 0; + LoadPlrGFX(v2, 128); + v6 = plr[v4]._pDFNum; + v7 = plr[v4]._peqD[0]; + plr[v4]._pmode = PM_DEATH; + NewPlrAnim(v2, v7, plr[v4]._pDFrames, 1); + v8 = plr[v4]._pAnimLen; + v9 = v8 - 1; + plr[v4]._pVar8 = 2 * v8; + v10 = plr[v4].WorldX; + plr[v4]._pAnimFrame = v9; + dFlags[v10][plr[v4].WorldY] |= 4u; + } + else + { + StartStand(v2, 0); + } + v11 = AddVision(plr[v4].WorldX, plr[v4].WorldY, plr[v4]._pLightRad, v2 == myplr); + plr[v4]._plid = -1; + plr[v4]._pvid = v11; + } + } + } + } + return 5; +} +// 676194: using guessed type char gbBufferMsgs; +// 67862C: using guessed type char gbActivePlayers; + +//----- (0043F448) -------------------------------------------------------- +int __fastcall On_ACTIVATEPORTAL(DJunk *pCmd, int pnum) +{ + signed int v2; // ebx + int v3; // edi + DJunk *v4; // esi + int v5; // eax + int v6; // edx + int v7; // ecx + int v8; // ST0C_4 + int v9; // ST08_4 + int v10; // ST04_4 + + v2 = 1; + v3 = pnum; + v4 = pCmd; + if ( gbBufferMsgs == 1 ) + { + msg_send_packet(pnum, pCmd, 9); + } + else + { + ActivatePortal( + pnum, + (unsigned char)pCmd->portal[0].y, + (unsigned char)pCmd->portal[0].level, + *(unsigned short *)&pCmd->portal[0].ltype, + *(unsigned short *)&pCmd->portal[1].x, + *(unsigned short *)&pCmd->portal[1].level); + if ( v3 != myplr ) + { + if ( currlevel ) + { + if ( currlevel == plr[v3].plrlevel ) + { + v6 = nummissiles; + v7 = 0; + if ( nummissiles <= 0 ) + goto LABEL_19; + do + { + v5 = 176 * missileactive[v7]; + if ( *(int *)((char *)&missile[0]._mitype + v5) == 10 + && *(int *)((char *)&missile[0]._misource + v5) == v3 ) + { + v2 = 0; + } + ++v7; + } + while ( v7 < nummissiles ); + if ( v2 ) +LABEL_19: + AddWarpMissile(v3, (unsigned char)v4->portal[0].y, (unsigned char)v4->portal[0].level); + } + else + { + RemovePortalMissile(v3); + } + } + else + { + AddInTownPortal(v3); + } + } + _LOBYTE(v5) = v4->portal[1].level; + _LOBYTE(v6) = v4->portal[0].y; + v8 = v5; + _LOBYTE(v5) = v4->portal[1].x; + v9 = v5; + _LOBYTE(v5) = v4->portal[0].ltype; + v10 = v5; + _LOBYTE(v5) = v4->portal[0].level; + delta_open_portal(v3, v6, v5, v10, v9, v8); + } + return 9; +} +// 676194: using guessed type char gbBufferMsgs; + +//----- (0043F521) -------------------------------------------------------- +void __fastcall delta_open_portal(int pnum, int x, int y, int bLevel, int bLType, int bSetLvl) +{ + int v6; // eax + + v6 = pnum; + sgbDeltaChanged = 1; + sgJunk[0].portal[v6].y = y; + sgJunk[0].portal[v6].level = bLevel; + sgJunk[0].portal[v6].ltype = bLType; + sgJunk[0].portal[v6].x = x; + sgJunk[0].portal[v6].setlvl = bSetLvl; +} +// 67618C: using guessed type char sgbDeltaChanged; + +//----- (0043F55C) -------------------------------------------------------- +int __fastcall On_DEACTIVATEPORTAL(struct TCmd *pCmd, int pnum) +{ + int v2; // esi + + v2 = pnum; + if ( gbBufferMsgs == 1 ) + { + msg_send_packet(pnum, pCmd, 1); + } + else + { + if ( PortalOnLevel(pnum) ) + RemovePortalMissile(v2); + DeactivatePortal(v2); + RemovePlrPortal(v2); + } + return 1; +} +// 676194: using guessed type char gbBufferMsgs; + +//----- (0043F59A) -------------------------------------------------------- +int __fastcall On_RETOWN(struct TCmd *pCmd, int pnum) +{ + int v2; // esi + + v2 = pnum; + if ( gbBufferMsgs == 1 ) + { + msg_send_packet(pnum, pCmd, 1); + } + else + { + if ( pnum == myplr ) + { + *(_DWORD *)&deathflag = 0; + gamemenu_off(); + } + RestartTownLvl(v2); + } + return 1; +} +// 676194: using guessed type char gbBufferMsgs; + +//----- (0043F5D3) -------------------------------------------------------- +int __fastcall On_SETSTR(struct TCmdParam1 *pCmd, int pnum) +{ + unsigned short v2; // cx + + if ( gbBufferMsgs == 1 ) + { + msg_send_packet(pnum, pCmd, 3); + } + else + { + v2 = pCmd->wParam1; + if ( v2 <= 0x2EEu && pnum != myplr ) + SetPlrStr(pnum, v2); + } + return 3; +} +// 676194: using guessed type char gbBufferMsgs; + +//----- (0043F60C) -------------------------------------------------------- +int __fastcall On_SETDEX(struct TCmdParam1 *pCmd, int pnum) +{ + unsigned short v2; // cx + + if ( gbBufferMsgs == 1 ) + { + msg_send_packet(pnum, pCmd, 3); + } + else + { + v2 = pCmd->wParam1; + if ( v2 <= 0x2EEu && pnum != myplr ) + SetPlrDex(pnum, v2); + } + return 3; +} +// 676194: using guessed type char gbBufferMsgs; + +//----- (0043F645) -------------------------------------------------------- +int __fastcall On_SETMAG(struct TCmdParam1 *pCmd, int pnum) +{ + unsigned short v2; // cx + + if ( gbBufferMsgs == 1 ) + { + msg_send_packet(pnum, pCmd, 3); + } + else + { + v2 = pCmd->wParam1; + if ( v2 <= 0x2EEu && pnum != myplr ) + SetPlrMag(pnum, v2); + } + return 3; +} +// 676194: using guessed type char gbBufferMsgs; + +//----- (0043F67E) -------------------------------------------------------- +int __fastcall On_SETVIT(struct TCmdParam1 *pCmd, int pnum) +{ + unsigned short v2; // cx + + if ( gbBufferMsgs == 1 ) + { + msg_send_packet(pnum, pCmd, 3); + } + else + { + v2 = pCmd->wParam1; + if ( v2 <= 0x2EEu && pnum != myplr ) + SetPlrVit(pnum, v2); + } + return 3; +} +// 676194: using guessed type char gbBufferMsgs; + +//----- (0043F6B7) -------------------------------------------------------- +int __fastcall On_STRING(struct TCmdString *pCmd, int pnum) +{ + const char *v2; // esi + int v3; // edi + size_t v4; // ebx + + v2 = pCmd->str; + v3 = pnum; + v4 = strlen(pCmd->str); + if ( !gbBufferMsgs ) + SendPlrMsg(v3, v2); + return v4 + 2; +} +// 676194: using guessed type char gbBufferMsgs; + +//----- (0043F6EC) -------------------------------------------------------- +int __fastcall On_SYNCQUEST(struct TCmdQuest *pCmd, int pnum) +{ + if ( gbBufferMsgs == 1 ) + { + msg_send_packet(pnum, pCmd, 5); + } + else + { + if ( pnum != myplr ) + SetMultiQuest( + (unsigned char)pCmd->q, + (unsigned char)pCmd->qstate, + pCmd->qlog, + (unsigned char)pCmd->qvar1); + sgbDeltaChanged = 1; + } + return 5; +} +// 67618C: using guessed type char sgbDeltaChanged; +// 676194: using guessed type char gbBufferMsgs; + +//----- (0043F72E) -------------------------------------------------------- +int __fastcall On_ENDSHIELD(int a1, int pnum) +{ + int v2; // ebx + int i; // esi + int v4; // edi + int v5; // eax + + v2 = pnum; + if ( gbBufferMsgs != 1 && pnum != myplr && currlevel == plr[pnum].plrlevel ) + { + for ( i = 0; i < nummissiles; ++i ) + { + v4 = missileactive[i]; + v5 = missileactive[i]; + if ( missile[v5]._mitype == 13 && missile[v5]._misource == v2 ) + { + ClearMissileSpot(missileactive[i]); + DeleteMissile(v4, i); + } + } + } + return 1; +} +// 676194: using guessed type char gbBufferMsgs; + +//----- (0043F7A5) -------------------------------------------------------- +int __cdecl On_DEBUG() +{ + return 1; +} + +//----- (0043F7A9) -------------------------------------------------------- +int __fastcall On_NOVA(struct TCmdLoc *pCmd, int pnum) +{ + struct TCmdLoc *v2; // edi + int v3; // esi + + v2 = pCmd; + if ( gbBufferMsgs != 1 ) + { + v3 = pnum; + if ( currlevel == plr[pnum].plrlevel && pnum != myplr ) + { + ClrPlrPath(pnum); + plr[v3]._pSpell = SPL_NOVA; + plr[v3]._pSplType = 4; + plr[v3]._pSplFrom = 3; + plr[v3].destAction = 12; + plr[v3].destParam1 = (unsigned char)v2->x; + plr[v3].destParam2 = (unsigned char)v2->y; + } + } + return 3; +} +// 676194: using guessed type char gbBufferMsgs; + +//----- (0043F818) -------------------------------------------------------- +int __fastcall On_SETSHIELD(int unused, int pnum) +{ + int result; // eax + + result = 1; + if ( gbBufferMsgs != 1 ) + plr[pnum].pManaShield = 1; + return result; +} +// 676194: using guessed type char gbBufferMsgs; + +//----- (0043F830) -------------------------------------------------------- +int __fastcall On_REMSHIELD(int unused, int pnum) +{ + int result; // eax + + result = 1; + if ( gbBufferMsgs != 1 ) + plr[pnum].pManaShield = 0; + return result; +} +// 676194: using guessed type char gbBufferMsgs; + +//----- (0043F84E) -------------------------------------------------------- +void __cdecl msgcmd_cpp_init_1() +{ + msgcmd_cpp_init_value = msgcmd_inf; +} +// 47F150: using guessed type int msgcmd_inf; +// 6761A0: using guessed type int msgcmd_cpp_init_value; + +//----- (0043F859) -------------------------------------------------------- +void __cdecl msgcmd_cpp_init_2() +{ + msgcmd_init_event(); + msgcmd_init_exit_event(); +} + +//----- (0043F863) -------------------------------------------------------- +_SNETEVENT *__cdecl msgcmd_init_event() +{ + return msgcmd_clear_event(&pEvent); +} + +//----- (0043F86D) -------------------------------------------------------- +int __cdecl msgcmd_init_exit_event() +{ + return atexit(msgcmd_clear_all_events); +} + +//----- (0043F879) -------------------------------------------------------- +void __cdecl msgcmd_clear_all_events() +{ + msgcmd_wait_zero_event(&pEvent); + msgcmd_zero_event((_SNETEVENT *)((char *)&pEvent + 4)); +} + +//----- (0043F88D) -------------------------------------------------------- +void __cdecl msgcmd_free_pevent() +{ + msgcmd_free_event(&pEvent); +} + +//----- (0043F897) -------------------------------------------------------- +void __cdecl msgcmd_send_chat() +{ + char *v0; // esi + int v1; // eax + + if ( (_DWORD)pEvent.data > 0 ) + { + v0 = (char *)pEvent.data; + v1 = GetTickCount(); + if ( (unsigned int)(v1 - pEvent.databytes) >= 2000 ) + { + pEvent.databytes = v1; + SNetSendServerChatCommand(v0 + 8); + msgcmd_free_str_event(&pEvent); + } + } +} + +//----- (0043F8D4) -------------------------------------------------------- +int __fastcall msgcmd_check_set_event(int a1) +{ + if ( *(_BYTE *)a1 != 47 ) + return 0; + msgcmd_set_event((const char *)a1); + return 1; +} + +//----- (0043F8E5) -------------------------------------------------------- +int __fastcall msgcmd_set_event(const char *a1) +{ + const char *v1; // edi + int result; // eax + int v3; // edx + size_t v4; // esi + int v5; // eax + + v1 = a1; + result = strlen(a1); + if ( result ) + { + v4 = result + 1; + if ( (unsigned int)(result + 1) <= 0x80 ) + { + v5 = msgcmd_alloc_event((int *)&pEvent, v3, 2, 0); + result = (int)memcpy((void *)(v5 + 8), v1, v4); + } + } + return result; +} + +//----- (0043F920) -------------------------------------------------------- +_SNETEVENT *__fastcall msgcmd_clear_event(_SNETEVENT *a1) +{ + _SNETEVENT *result; // eax + int *v2; // edx + + result = a1; + v2 = &a1->playerid; + *v2 = 0; + v2[1] = 0; + *v2 = (int)v2; + a1->eventid = 0; + result->data = (void *)~(unsigned int)&result->playerid; + return result; +} + +//----- (0043F936) -------------------------------------------------------- +bool __fastcall msgcmd_free_event(_SNETEVENT *a1) +{ + _SNETEVENT *v1; // edi + _SNETEVENT *v2; // esi + bool result; // al + + v1 = a1; + while ( 1 ) + { + v2 = (_SNETEVENT *)v1->data; + if ( (signed int)v2 <= 0 ) + break; + msgcmd_remove_event(v2); + result = SMemFree(v2, ".?AUEXTERNMESSAGE@@", -2, 0); + } + return result; +} + +//----- (0043F95E) -------------------------------------------------------- +int __fastcall msgcmd_free_str_event(_SNETEVENT *a1) +{ + char *v1; // eax + int v2; // eax + int v3; // esi + _SNETEVENT *ptr; // [esp+Ch] [ebp+4h] + + v1 = (char *)ptr; + if ( !ptr ) + v1 = (char *)&a1->playerid; + v2 = *((_DWORD *)v1 + 1); + if ( v2 > 0 ) + v3 = v2; + else + v3 = 0; + msgcmd_remove_event(ptr); + SMemFree(ptr, ".?AUEXTERNMESSAGE@@", -2, 0); + return v3; +} + +//----- (0043F999) -------------------------------------------------------- +int __fastcall msgcmd_alloc_event(int *a1, int a2, int a3, int a4) +{ + int v4; // eax + int *v5; // edi + int *v6; // eax + int v7; // edx + int *v8; // esi + int v10; // [esp+18h] [ebp+Ch] + + v4 = v10; + _LOBYTE(v4) = v10 | 8; + v5 = a1; + v6 = (int *)SMemAlloc(a4 + 136, ".?AUEXTERNMESSAGE@@", -2, v4); + if ( v6 ) + { + *v6 = 0; + v6[1] = 0; + v8 = v6; + } + else + { + v8 = 0; + } + if ( a3 ) + msgcmd_event_type((_SNETEVENT *)v5, v7, v8, a3); + return (int)v8; +} + +//----- (0043F9E5) -------------------------------------------------------- +char *__fastcall msgcmd_remove_event(_SNETEVENT *a1) +{ + _SNETEVENT *v1; // esi + char v3; // [esp+8h] [ebp+4h] + + v1 = a1; + msgcmd_zero_event(a1); + msgcmd_zero_event(v1); + if ( v3 & 1 && v1 ) + SMemFree(v1, "delete", -1, 0); + return (char *)v1; +} + +//----- (0043FA14) -------------------------------------------------------- +char *__fastcall msgcmd_event_type(_SNETEVENT *a1, int a2, int *a3, int a4) +{ + _SNETEVENT *v4; // edi + _SNETEVENT *v5; // esi + char *result; // eax + int v7; // ecx + int v8; // edx + char *v9; // ecx + int v10; // edx + char *v11; // [esp+18h] [ebp+Ch] + + v4 = a1; + v5 = (_SNETEVENT *)a3; + if ( !a3 ) + v5 = (_SNETEVENT *)((char *)a1 + 4); + if ( v5->eventid ) + msgcmd_zero_event(v5); + result = v11; + if ( !v11 ) + result = (char *)&v4->playerid; + if ( a4 == 1 ) + { + v5->eventid = (int)result; + v5->playerid = *((_DWORD *)result + 1); + v8 = *((_DWORD *)result + 1); + v9 = (char *)v4->eventid; + if ( v8 > 0 ) + { + if ( (signed int)v9 < 0 ) + v9 = &result[-*(_DWORD *)(*(_DWORD *)result + 4)]; + v10 = (int)&v9[v8]; + } + else + { + v10 = ~v8; + } + *(_DWORD *)v10 = (unsigned int)v5; + *((_DWORD *)result + 1) = (unsigned int)a3; + } + else if ( a4 == 2 ) + { + v7 = *(_DWORD *)result; + v5->eventid = *(_DWORD *)result; + v5->playerid = *(_DWORD *)(v7 + 4); + *(_DWORD *)(v7 + 4) = (unsigned int)a3; + *(_DWORD *)result = (unsigned int)v5; + } + return result; +} + +//----- (0043FA85) -------------------------------------------------------- +void __fastcall msgcmd_wait_zero_event(_SNETEVENT *a1) +{ + _SNETEVENT *v1; // esi + _SNETEVENT *v2; // ecx + + v1 = a1; + while ( 1 ) + { + v2 = (_SNETEVENT *)v1->data; + if ( (signed int)v2 <= 0 ) + break; + msgcmd_zero_event(v2); + } +} + +//----- (0043FA98) -------------------------------------------------------- +void __fastcall msgcmd_zero_event(_SNETEVENT *a1) +{ + int v1; // esi + int v2; // edx + int v3; // edx + + v1 = a1->eventid; + if ( a1->eventid ) + { + v2 = a1->playerid; + if ( v2 > 0 ) + v3 = (int)a1 + v2 - *(_DWORD *)(v1 + 4); + else + v3 = ~v2; + *(_DWORD *)v3 = v1; + *(_DWORD *)(a1->eventid + 4) = a1->playerid; + a1->eventid = 0; + a1->playerid = 0; + } +} + +//----- (0043FAC9) -------------------------------------------------------- +void __cdecl multi_cpp_init() +{ + multi_cpp_init_value = multi_inf; +} +// 47F154: using guessed type int multi_inf; +// 678620: using guessed type int multi_cpp_init_value; + +//----- (0043FAD4) -------------------------------------------------------- +void __fastcall multi_msg_add(char *a1, unsigned char a2) +{ + if ( a1 ) + { + if ( a2 ) + tmsg_add(a1, a2); + } +} + +//----- (0043FAE2) -------------------------------------------------------- +void __fastcall NetSendLoPri(unsigned char *pbMsg, unsigned char bLen) +{ + unsigned char *v2; // esi + unsigned char v3; // bl + int v4; // edx + + v2 = pbMsg; + v3 = bLen; + if ( pbMsg ) + { + if ( bLen ) + { + multi_copy_packet(pkdata_678658, pbMsg, bLen); + _LOBYTE(v4) = v3; + multi_send_packet(v2, v4); + } + } +} + +//----- (0043FB0B) -------------------------------------------------------- +void __fastcall multi_copy_packet(void *a1, void *packet, int size) +{ + int v3; // eax + int v4; // ebx + char *v5; // esi + + v3 = *(_DWORD *)a1; + v4 = *(_DWORD *)a1 + (unsigned char)size; + if ( (unsigned int)(v4 + 2) <= 0x1000 ) + { + *(_DWORD *)a1 = v4 + 1; + *((_BYTE *)a1 + v3 + 4) = size; + v5 = (char *)a1 + v3 + 5; + memcpy(v5, packet, (unsigned char)size); + v5[(unsigned char)size] = 0; + } +} + +//----- (0043FB4D) -------------------------------------------------------- +void __fastcall multi_send_packet(void *packet, int dwSize) +{ + void *v2; // esi + unsigned char v3; // bl + int v4; // eax + TPkt pkt; // [esp+8h] [ebp-200h] + + v2 = packet; + v3 = dwSize; + NetRecvPlrData(&pkt); + pkt.hdr.wLen = v3 + 19; + memcpy(pkt.body, v2, v3); + _LOBYTE(v4) = SNetSendMessage(myplr, &pkt.hdr, (unsigned short)pkt.hdr.wLen); + if ( !v4 ) + nthread_terminate_game("SNetSendMessage0"); +} + +//----- (0043FBB5) -------------------------------------------------------- +void __fastcall NetRecvPlrData(TPkt *pkt) +{ + pkt->hdr.wCheck = 'ip'; + pkt->hdr.px = plr[myplr].WorldX; + pkt->hdr.py = plr[myplr].WorldY; + pkt->hdr.targx = plr[myplr]._ptargx; + pkt->hdr.targy = plr[myplr]._ptargy; + pkt->hdr.php = plr[myplr]._pHitPoints; + pkt->hdr.pmhp = plr[myplr]._pMaxHP; + pkt->hdr.bstr = plr[myplr]._pBaseStr; + pkt->hdr.bmag = plr[myplr]._pBaseMag; + pkt->hdr.bdex = plr[myplr]._pBaseDex; +} + +//----- (0043FC6F) -------------------------------------------------------- +void __fastcall NetSendHiPri(unsigned char *pbMsg, unsigned char bLen) +{ + unsigned char *v2; // edi + unsigned char v3; // bl + int v4; // edx + char *v5; // eax + TSyncHeader *v6; // eax + int v7; // eax + int v8; // eax + int v9; // eax + TPkt pkt; // [esp+Ch] [ebp-204h] + int size; // [esp+20Ch] [ebp-4h] + + v2 = pbMsg; + v3 = bLen; + if ( pbMsg && bLen ) + { + multi_copy_packet(pkdata_6761C0, pbMsg, bLen); + _LOBYTE(v4) = v3; + multi_send_packet(v2, v4); + } + if ( !dword_678628 ) + { + dword_678628 = 1; + NetRecvPlrData(&pkt); + size = gdwNormalMsgSize - 19; + v5 = multi_recv_packet(pkdata_6761C0, pkt.body, &size); + v6 = (TSyncHeader *)multi_recv_packet(pkdata_678658, v5, &size); + v7 = sync_all_monsters(v6, size); + size = v7; + v8 = gdwNormalMsgSize - v7; + pkt.hdr.wLen = v8; + _LOBYTE(v9) = SNetSendMessage(-2, &pkt.hdr, v8); + if ( !v9 ) + nthread_terminate_game("SNetSendMessage"); + } +} +// 678628: using guessed type int dword_678628; +// 679760: using guessed type int gdwNormalMsgSize; + +//----- (0043FD27) -------------------------------------------------------- +char *__fastcall multi_recv_packet(void *packet, char *a2, int *a3) +{ + char *v3; // esi + char *result; // eax + char *v5; // ebx + size_t v6; // edi + char *v7; // ebx + char *v8; // [esp+4h] [ebp-4h] + + v3 = (char *)packet; + result = a2; + v8 = a2; + if ( *(_DWORD *)packet ) + { + v5 = (char *)packet + 4; + while ( *v5 ) + { + v6 = (unsigned char)*v5; + if ( v6 > *a3 ) + break; + v7 = v5 + 1; + memcpy(v8, v7, v6); + v8 += v6; + v5 = &v7[v6]; + *a3 -= v6; + } + memcpy(v3 + 4, v5, (size_t)&v3[*(_DWORD *)v3 - (_DWORD)v5 + 5]); + *(_DWORD *)v3 += v3 - v5 + 4; + result = v8; + } + return result; +} + +//----- (0043FD90) -------------------------------------------------------- +void __fastcall multi_send_msg_packet(int a1, char *a2, unsigned char len) +{ + const void *v3; // edx + signed int v4; // ebx + unsigned int v5; // edi + int v6; // eax + TPkt pkt; // [esp+Ch] [ebp-204h] + int v8; // [esp+20Ch] [ebp-4h] + + v8 = a1; + NetRecvPlrData(&pkt); + pkt.hdr.wLen = len + 19; + memcpy(pkt.body, v3, len); + v4 = 1; + v5 = 0; + while ( 1 ) + { + if ( v4 & v8 ) + { + _LOBYTE(v6) = SNetSendMessage(v5, &pkt.hdr, len + 19); + if ( !v6 && SErrGetLastError() != 0x8510006A ) + break; + } + ++v5; + v4 *= 2; + if ( v5 >= 4 ) + return; + } + nthread_terminate_game("SNetSendMessage"); +} + +//----- (0043FE0E) -------------------------------------------------------- +void __cdecl multi_msg_countdown() +{ + int v0; // esi + + v0 = 0; + do + { + if ( player_state[v0] & 0x20000 ) + { + if ( gdwMsgLenTbl[v0] == 4 ) + multi_start_countdown(v0, *(_DWORD *)glpMsgTbl[v0]); + } + ++v0; + } + while ( v0 < 4 ); +} + +//----- (0043FE3D) -------------------------------------------------------- +int __fastcall multi_start_countdown(int pnum, int a2) +{ + int v2; // esi + int result; // eax + unsigned int v4; // esi + + v2 = a2; + if ( a2 < 0 ) + multi_wait_delta_send(pnum); + result = gdwTurnsInTransit; + v4 = v2 & 0x7FFFFFFF; + if ( sgbSentThisCycle < gdwTurnsInTransit + v4 ) + { + if ( v4 >= 0x7FFFFFFF ) + v4 = (unsigned short)v4; + sgbSentThisCycle = v4 + gdwTurnsInTransit; + result = 4 * v4 * (unsigned char)byte_679704; + sgdwGameLoops = 4 * v4 * (unsigned char)byte_679704; + } + return result; +} +// 679704: using guessed type char byte_679704; +// 679738: using guessed type int gdwTurnsInTransit; + +//----- (0043FE85) -------------------------------------------------------- +void __fastcall multi_wait_delta_send(int pnum) +{ + signed int v1; // eax + + v1 = 0; + do + { + if ( player_state[v1] & 0x10000 && v1 != pnum ) + break; + ++v1; + } + while ( v1 < 4 ); + if ( myplr == v1 ) + { + sgbSendDeltaTbl[pnum] = 1; + } + else if ( myplr == pnum ) + { + gbDeltaSender = v1; + } +} +// 6796E4: using guessed type char gbDeltaSender; + +//----- (0043FEB7) -------------------------------------------------------- +void __fastcall multi_player_left(int pnum, int reason) +{ + sgbPlayerLeftGameTbl[pnum] = 1; + sgdwPlayerLeftReasonTbl[pnum] = reason; + multi_clear_left_tbl(); +} + +//----- (0043FECA) -------------------------------------------------------- +void __cdecl multi_clear_left_tbl() +{ + int v0; // esi + + v0 = 0; + do + { + if ( sgbPlayerLeftGameTbl[v0] ) + { + if ( gbBufferMsgs == 1 ) + msg_send_drop_pkt(v0, sgdwPlayerLeftReasonTbl[v0]); + else + multi_player_left_msg(v0, 1); + sgbPlayerLeftGameTbl[v0] = 0; + sgdwPlayerLeftReasonTbl[v0] = 0; + } + ++v0; + } + while ( v0 < 4 ); +} +// 676194: using guessed type char gbBufferMsgs; + +//----- (0043FF0E) -------------------------------------------------------- +void __fastcall multi_player_left_msg(int pnum, int left) +{ + int v2; // edi + int v3; // ebx + int v4; // esi + char *v5; // eax + int v6; // edi + + v2 = pnum; + v3 = left; + v4 = pnum; + if ( plr[pnum].plractive[0] ) + { + RemovePlrFromMap(pnum); + RemovePortalMissile(v2); + DeactivatePortal(v2); + RemovePlrPortal(v2); + RemovePlrMissiles(v2); + if ( v3 ) + { + v5 = "Player '%s' just left the game"; + v6 = sgdwPlayerLeftReasonTbl[v2] - 0x40000004; + if ( v6 ) + { + if ( v6 == 2 ) + v5 = "Player '%s' dropped due to timeout"; + } + else + { + v5 = "Player '%s' killed Diablo and left the game!"; + gbSomebodyWonGameKludge = 1; + } + EventPlrMsg(v5, plr[v4]._pName); + } + plr[v4].plractive[0] = 0; + plr[v4]._pName[0] = 0; + --gbActivePlayers; + } +} +// 6761B8: using guessed type char gbSomebodyWonGameKludge; +// 67862C: using guessed type char gbActivePlayers; + +//----- (0043FF9D) -------------------------------------------------------- +void __cdecl multi_net_ping() +{ + sgbTimeout = 1; + sglTimeoutStart = GetTickCount(); +} +// 678644: using guessed type int sglTimeoutStart; +// 679661: using guessed type char sgbTimeout; + +//----- (0043FFB0) -------------------------------------------------------- +int __cdecl multi_handle_delta() +{ + int v0; // esi + int v1; // eax + bool recieved[4]; // [esp+4h] [ebp-4h] + + if ( gbGameDestroyed ) + { + gbRunGame = 0; + return 0; + } + v0 = 0; + do + { + if ( sgbSendDeltaTbl[v0] ) + { + sgbSendDeltaTbl[v0] = 0; + msg_do_sync(v0); + } + ++v0; + } + while ( v0 < 4 ); + sgbSentThisCycle = nthread_send_and_recv_turn(sgbSentThisCycle, 1); + nthread_recv_turns(recieved); + if ( !v1 ) + { + multi_begin_timeout(); + return 0; + } + sgbTimeout = 0; + if ( *(_DWORD *)recieved ) + { + if ( dword_678628 ) + { + dword_678628 = 0; + if ( !multi_check_pkt_valid(pkdata_6761C0) ) + NetSendHiPri(0, 0); + } + else + { + NetSendHiPri(0, 0); + dword_678628 = 0; + } + } + multi_mon_seeds(); + return 1; +} +// 525650: using guessed type int gbRunGame; +// 678628: using guessed type int dword_678628; +// 67862D: using guessed type char gbGameDestroyed; +// 679661: using guessed type char sgbTimeout; + +//----- (00440058) -------------------------------------------------------- +// Microsoft VisualC 2-11/net runtime +int __fastcall multi_check_pkt_valid(char *a1) +{ + return *(_DWORD *)a1 == 0; +} + +//----- (00440060) -------------------------------------------------------- +void __cdecl multi_mon_seeds() +{ + unsigned int v0; // eax + int v1; // edx + int *v2; // ecx + int v3; // esi + + v0 = _rotr(++sgdwGameLoops, 8); + v1 = 0; + v2 = &monster[0]._mAISeed; + do + { + v3 = v1++ + v0; + *v2 = v3; + v2 += 57; + } + while ( (signed int)v2 < (signed int)&Monsters[0].Anims[3].Rate ); +} + +//----- (00440093) -------------------------------------------------------- +void __cdecl multi_begin_timeout() +{ + unsigned char v0; // bl + signed __int32 v1; // eax + signed int v2; // esi + signed int v3; // edi + signed int v4; // eax + int v5; // edx + unsigned char v6; // [esp+Fh] [ebp-1h] + + v0 = 0; + if ( sgbTimeout ) + { + v1 = GetTickCount() - sglTimeoutStart; + if ( v1 <= 20000 ) + { + if ( v1 >= 10000 ) + { + v6 = 0; + v2 = -1; + v3 = -1; + v4 = 0; + do + { + v5 = player_state[v4]; + if ( v5 & 0x10000 ) + { + if ( v3 == -1 ) + v3 = v4; + if ( v5 & 0x40000 ) + { + ++v0; + if ( v2 == -1 ) + v2 = v4; + } + else + { + ++v6; + } + } + ++v4; + } + while ( v4 < 4 ); + if ( v0 >= v6 && (v0 != v6 || v3 == v2) ) + { + if ( v2 == myplr ) + multi_check_drop_player(); + } + else + { + gbGameDestroyed = 1; + } + } + } + else + { + gbRunGame = 0; + } + } +} +// 525650: using guessed type int gbRunGame; +// 67862D: using guessed type char gbGameDestroyed; +// 678644: using guessed type int sglTimeoutStart; +// 679661: using guessed type char sgbTimeout; + +//----- (00440128) -------------------------------------------------------- +void __cdecl multi_check_drop_player() +{ + int v0; // esi + int v1; // eax + + v0 = 0; + do + { + v1 = player_state[v0]; + if ( !(v1 & 0x40000) ) + { + if ( v1 & 0x10000 ) + SNetDropPlayer(v0, 0x40000006); + } + ++v0; + } + while ( v0 < 4 ); +} + +//----- (00440153) -------------------------------------------------------- +void __cdecl multi_process_network_packets() +{ + int v0; // eax + TPktHdr *v1; // ecx + TPktHdr *v2; // edi + int v3; // eax + bool v4; // zf + char *v5; // esi + int v6; // ebx + int v7; // eax + int v8; // ecx + int v9; // eax + int v10; // eax + int v11; // esi + int v12; // eax + int v13; // ecx + int v14; // eax + int v15; // eax + TPktHdr *pkt; // [esp+0h] [ebp-Ch] + int len; // [esp+4h] [ebp-8h] + char arglist[4]; // [esp+8h] [ebp-4h] + + multi_clear_left_tbl(); + multi_start_packets(); + _LOBYTE(v0) = SNetReceiveMessage((int *)arglist, (char **)&pkt, &len); + if ( v0 ) + { + do + { + ++dword_676198; + multi_clear_left_tbl(); + v1 = pkt; + v2 = pkt; + if ( (unsigned int)len >= 0x13 + && *(_DWORD *)arglist < 4u + && pkt->wCheck == 'ip' + && (unsigned short)pkt->wLen == len ) + { + v3 = *(_DWORD *)arglist; + v4 = *(_DWORD *)arglist == myplr; + plr[v3]._pownerx = (unsigned char)pkt->px; + v5 = &v1->py; + plr[v3]._pownery = (unsigned char)v1->py; + if ( !v4 ) + { + v4 = gbBufferMsgs == 1; + plr[v3]._pHitPoints = v1->php; + plr[v3]._pMaxHP = v1->pmhp; + plr[v3]._pBaseStr = (unsigned char)v1->bstr; + plr[v3]._pBaseMag = (unsigned char)v1->bmag; + plr[v3]._pBaseDex = (unsigned char)v1->bdex; + if ( !v4 && plr[v3].plractive[0] && plr[v3]._pHitPoints ) + { + if ( currlevel != plr[v3].plrlevel || plr[v3]._pLvlChanging ) + { + plr[v3].WorldX = (unsigned char)v1->px; + plr[v3].WorldY = (unsigned char)*v5; + plr[v3]._px = (unsigned char)v1->px; + plr[v3]._py = (unsigned char)*v5; + plr[v3]._ptargx = (unsigned char)v1->targx; + plr[v3]._ptargy = (unsigned char)v1->targy; + } + else + { + v6 = abs(plr[v3].WorldX - (unsigned char)v1->px); + v7 = abs(plr[*(_DWORD *)arglist].WorldY - (unsigned char)*v5); + if ( (v6 > 3 || v7 > 3) && !dPlayer[(unsigned char)v2->px][(unsigned char)*v5] ) + { + FixPlrWalkTags(*(int *)arglist); + v8 = *(_DWORD *)arglist; + v9 = *(_DWORD *)arglist; + plr[v9]._poldx = plr[*(_DWORD *)arglist].WorldX; + plr[v9]._poldy = plr[v9].WorldY; + FixPlrWalkTags(v8); + v10 = *(_DWORD *)arglist; + plr[v10].WorldX = (unsigned char)v2->px; + plr[v10].WorldY = (unsigned char)*v5; + plr[v10]._px = (unsigned char)v2->px; + plr[v10]._py = (unsigned char)*v5; + dPlayer[plr[v10].WorldX][plr[v10].WorldY] = arglist[0] + 1; + } + v11 = abs(plr[*(_DWORD *)arglist]._px - plr[*(_DWORD *)arglist].WorldX); + v12 = abs(plr[*(_DWORD *)arglist]._py - plr[*(_DWORD *)arglist].WorldY); + v13 = *(_DWORD *)arglist; + if ( v11 > 1 || v12 > 1 ) + { + v14 = *(_DWORD *)arglist; + plr[v14]._px = plr[*(_DWORD *)arglist].WorldX; + plr[v14]._py = plr[v13].WorldY; + } + MakePlrPath(v13, (unsigned char)v2->targx, (unsigned char)v2->targy, 1u); + } + } + } + multi_handle_all_packets(*(int *)arglist, (TPkt *)&v2[1], len - 19); + } + _LOBYTE(v15) = SNetReceiveMessage((int *)arglist, (char **)&pkt, &len); + } + while ( v15 ); + } + if ( SErrGetLastError() != 0x8510006B ) + nthread_terminate_game("SNetReceiveMsg"); +} +// 676194: using guessed type char gbBufferMsgs; +// 676198: using guessed type int dword_676198; + +//----- (0044041D) -------------------------------------------------------- +void __fastcall multi_handle_all_packets(int players, TPkt *packet, int a3) +{ + TCmd *v3; // esi + int i; // edi + int v5; // eax + + v3 = (TCmd *)packet; + for ( i = players; a3; a3 -= v5 ) + { + v5 = ParseCmd(i, v3); + if ( !v5 ) + break; + v3 += v5; + } +} + +//----- (00440444) -------------------------------------------------------- +void __cdecl multi_start_packets() +{ + int v0; // eax + TPkt pkt; // [esp+0h] [ebp-200h] + + while ( 1 ) + { + v0 = tmsg_get(&pkt.hdr.px, 512); + if ( !v0 ) + break; + multi_handle_all_packets(myplr, &pkt, v0); + } +} + +//----- (00440477) -------------------------------------------------------- +void __fastcall multi_send_zero_packet(int pnum, char a2, void *ptr, int len) +{ + unsigned int v4; // edi + short v5; // si + unsigned short v6; // ax + int v7; // eax + TPkt pkt; // [esp+Ch] [ebp-208h] + int pnuma; // [esp+20Ch] [ebp-8h] + int v10; // [esp+210h] [ebp-4h] + + v4 = len; + _LOBYTE(v10) = a2; + pnuma = pnum; + v5 = 0; + while ( v4 ) + { + pkt.hdr.wCheck = 'ip'; + pkt.body[0] = v10; + v6 = gdwLargestMsgSize - 24; + pkt.hdr.px = 0; + pkt.hdr.py = 0; + pkt.hdr.targx = 0; + pkt.hdr.targy = 0; + pkt.hdr.php = 0; + pkt.hdr.pmhp = 0; + pkt.hdr.bstr = 0; + pkt.hdr.bmag = 0; + pkt.hdr.bdex = 0; + *(_WORD *)&pkt.body[1] = v5; + if ( v4 < gdwLargestMsgSize - 24 ) + v6 = v4; + *(_WORD *)&pkt.body[3] = v6; + memcpy(&pkt.body[5], ptr, v6); + pkt.hdr.wLen = *(_WORD *)&pkt.body[3] + 24; + _LOBYTE(v7) = SNetSendMessage(pnuma, &pkt.hdr, *(unsigned short *)&pkt.body[3] + 24); + if ( !v7 ) + { + nthread_terminate_game("SNetSendMessage2"); + return; + } + ptr = (char *)ptr + *(unsigned short *)&pkt.body[3]; + v4 -= *(unsigned short *)&pkt.body[3]; + v5 += *(_WORD *)&pkt.body[3]; + } +} +// 67975C: using guessed type int gdwLargestMsgSize; + +//----- (0044055D) -------------------------------------------------------- +void __cdecl NetClose() +{ + if ( sgbNetInited ) + { + sgbNetInited = 0; + nthread_cleanup(); + dthread_cleanup(); + tmsg_cleanup(); + multi_event_handler(0); + SNetLeaveGame(3); + msgcmd_free_pevent(); + if ( (unsigned char)gbMaxPlayers > 1u ) + Sleep(0x7D0u); + } +} +// 679660: using guessed type char gbMaxPlayers; +// 6796E8: using guessed type int sgbNetInited; + +//----- (004405A4) -------------------------------------------------------- +char __fastcall multi_event_handler(int a1) +{ + int v1; // edi + void *(__stdcall *v2)(int, void (__stdcall *)(_SNETEVENT *)); // ebx + unsigned int v3; // esi + int v4; // eax + char *v5; // eax + + v1 = a1; + v2 = SNetRegisterEventHandler; + if ( !a1 ) + v2 = SNetUnregisterEventHandler; + v3 = 0; + do + { + _LOBYTE(v4) = (unsigned char)v2(event_types[v3], multi_handle_events); + if ( !v4 && v1 ) + { + v5 = GetLastErr(); + TermMsg("SNetRegisterEventHandler:\n%s", v5); + } + ++v3; + } + while ( v3 < 3 ); + return v4; +} + +//----- (004405EC) -------------------------------------------------------- +void __stdcall multi_handle_events(_SNETEVENT *event) +{ + int v1; // ecx + int *v2; // eax + int *v3; // eax + + switch ( event->eventid ) + { + case EVENT_TYPE_PLAYER_CREATE_GAME: + v3 = (int *)event->data; + sgGameInitInfo.dwSeed = *v3; + _LOBYTE(sgGameInitInfo.bDiff) = *((_BYTE *)v3 + 4); + sgbPlayerTurnBitTbl[event->playerid] = 1; + break; + case EVENT_TYPE_PLAYER_LEAVE_GAME: + v1 = 0; + sgbPlayerLeftGameTbl[event->playerid] = 1; + sgbPlayerTurnBitTbl[event->playerid] = 0; + v2 = (int *)event->data; + if ( v2 && event->databytes >= 4u ) + v1 = *v2; + sgdwPlayerLeftReasonTbl[event->playerid] = v1; + if ( v1 == 0x40000004 ) + gbSomebodyWonGameKludge = 1; + sgbSendDeltaTbl[event->playerid] = 0; + dthread_remove_player(event->playerid); + if ( (unsigned char)gbDeltaSender == event->playerid ) + gbDeltaSender = 4; + break; + case EVENT_TYPE_PLAYER_MESSAGE: + ErrorPlrMsg((char *)event->data); + break; + } +} +// 6761B8: using guessed type char gbSomebodyWonGameKludge; +// 6796E4: using guessed type char gbDeltaSender; + +//----- (00440694) -------------------------------------------------------- +int __fastcall NetInit(int bSinglePlayer, int *pfExitProgram) +{ + int v2; // ebx + void (__cdecl *v3)(); // eax + int v4; // eax + int v5; // ecx + TCmdPlrInfoHdr *v6; // edx + bool v7; // zf + int v9; // eax + int v10; // eax + _SNETPROGRAMDATA ProgramData; // [esp+8h] [ebp-A8h] + _SNETUIDATA UiData; // [esp+44h] [ebp-6Ch] + _SNETPLAYERDATA a2; // [esp+94h] [ebp-1Ch] + int v14; // [esp+A4h] [ebp-Ch] + int len; // [esp+A8h] [ebp-8h] + int *a4; // [esp+ACh] [ebp-4h] + + a4 = pfExitProgram; + v14 = bSinglePlayer; + v2 = 0; + while ( 1 ) + { + *a4 = 0; + SetRndSeed(0); + sgGameInitInfo.dwSeed = time(0); + _LOBYTE(sgGameInitInfo.bDiff) = gnDifficulty; + memset(&ProgramData, 0, 0x3Cu); + ProgramData.size = 60; + ProgramData.programname = "Diablo Retail"; + ProgramData.programdescription = "internal version unknown"; + ProgramData.programid = 'DRTL'; + ProgramData.versionid = 42; + ProgramData.maxplayers = 4; + ProgramData.multi_seed = (int)&sgGameInitInfo; + ProgramData.initdata = (void *)8; + ProgramData.reserved2 = (void *)15; + ProgramData.languageid = 1033; + memset(&a2, 0, 0x10u); + a2.size = 16; + memset(&UiData, 0, 0x50u); + UiData.size = 80; + UiData.parentwindow = SDrawGetFrameWindow(0); + UiData.artcallback = UiArtCallback; + UiData.createcallback = UiCreateGameCallback; + UiData.drawdesccallback = UiDrawDescCallback; + UiData.messageboxcallback = UiMessageBoxCallback; + UiData.soundcallback = UiSoundCallback; + UiData.authcallback = UiAuthCallback; + UiData.getdatacallback = UiGetDataCallback; + UiData.categorycallback = UiCategoryCallback; + UiData.selecthero = (void (__cdecl *)())mainmenu_select_hero_dialog; + UiData.createhero = (void (__cdecl *)())mainmenu_create_hero; + UiData.profiledraw = UiProfileDraw; + UiData.profilecallback = UiProfileCallback; + UiProfileGetString(); + UiData.profilegetstring = v3; + memset(sgbPlayerTurnBitTbl, 0, 4u); + gbGameDestroyed = 0; + memset(sgbPlayerLeftGameTbl, 0, 4u); + memset(sgdwPlayerLeftReasonTbl, 0, 0x10u); + memset(sgbSendDeltaTbl, 0, 4u); + memset(plr, 0, 0x15360u); + memset(sgwPackPlrOffsetTbl, 0, 8u); + SNetSetBasePlayer(0); + if ( v14 ) + v4 = multi_init_single(&ProgramData, &a2, &UiData); + else + v4 = multi_init_multi(&ProgramData, &a2, &UiData, a4); + if ( !v4 ) + return 0; + sgbNetInited = 1; + sgbTimeout = 0; + delta_init(); + InitPlrMsg(); + multi_clear_pkt(pkdata_6761C0); + multi_clear_pkt(pkdata_678658); + dword_678628 = 0; + sync_clear_pkt(); + nthread_start(sgbPlayerTurnBitTbl[myplr]); + dthread_start(); + MI_Dummy(v5); + sgdwGameLoops = 0; + sgbSentThisCycle = 0; + gbDeltaSender = myplr; + gbSomebodyWonGameKludge = 0; + nthread_send_and_recv_turn(0, 0); + SetupLocalCoords(); + _LOBYTE(v6) = CMD_SEND_PLRINFO; + multi_send_pinfo(-2, v6); + gbActivePlayers = 1; + v7 = sgbPlayerTurnBitTbl[myplr] == 0; + plr[myplr].plractive[0] = 1; + if ( v7 || msg_wait_resync() ) + break; + NetClose(); + byte_678640 = 0; + } + gnDifficulty = _LOBYTE(sgGameInitInfo.bDiff); + SetRndSeed(sgGameInitInfo.dwSeed); + do + { + glSeedTbl[v2] = GetRndSeed(); + gnLevelTypeTbl[v2] = InitNewSeed(v2); + ++v2; + } + while ( v2 < 17 ); + _LOBYTE(v9) = SNetGetGameInfo(GAME_INFO_NAME, szPlayerName, 128, (unsigned int *)len); + if ( !v9 ) + nthread_terminate_game("SNetGetGameInfo1"); + _LOBYTE(v10) = SNetGetGameInfo(GAME_INFO_PASS, szPlayerDescript, 128, (unsigned int *)len); + if ( !v10 ) + nthread_terminate_game("SNetGetGameInfo2"); + return 1; +} +// 6761B8: using guessed type char gbSomebodyWonGameKludge; +// 678628: using guessed type int dword_678628; +// 67862C: using guessed type char gbActivePlayers; +// 67862D: using guessed type char gbGameDestroyed; +// 678640: using guessed type char byte_678640; +// 679661: using guessed type char sgbTimeout; +// 6796E4: using guessed type char gbDeltaSender; +// 6796E8: using guessed type int sgbNetInited; + +//----- (00440992) -------------------------------------------------------- +void __fastcall multi_clear_pkt(char *a1) +{ + *(_DWORD *)a1 = 0; + a1[4] = 0; +} + +//----- (0044099A) -------------------------------------------------------- +void __fastcall multi_send_pinfo(int pnum, TCmdPlrInfoHdr *cmd) +{ + char v2; // bl + int v3; // esi + int v4; // edx + PkPlayerStruct pkplr; // [esp+8h] [ebp-4F4h] + + v2 = (char)cmd; + v3 = pnum; + PackPlayer(&pkplr, myplr, 1); + _LOBYTE(v4) = v2; + dthread_send_delta(v3, v4, &pkplr, 1266); +} + +//----- (004409D5) -------------------------------------------------------- +int __fastcall InitNewSeed(int newseed) +{ + int result; // eax + + result = 0; + if ( newseed ) + { + result = 1; + if ( newseed < 1 || newseed > 4 ) + { + if ( newseed < 5 || newseed > 8 ) + { + if ( newseed < 9 || newseed > 12 ) + result = 4; + else + result = 3; + } + else + { + result = 2; + } + } + } + return result; +} + +//----- (00440A05) -------------------------------------------------------- +void __cdecl SetupLocalCoords() +{ + int v0; // eax + int v1; // ecx + int v2; // edx + + if ( !leveldebug || (unsigned char)gbMaxPlayers > 1u ) + { + currlevel = 0; + leveltype = 0; + setlevel = 0; + } + v0 = myplr; + v1 = plrxoff[myplr] + 75; + v2 = plryoff[myplr] + 68; + plr[v0].WorldX = v1; + plr[v0].WorldY = v2; + plr[v0]._px = v1; + plr[v0]._py = v2; + plr[v0]._ptargx = v1; + plr[v0]._ptargy = v2; + plr[v0].plrlevel = currlevel; + plr[v0]._pLvlChanging = 1; + plr[v0].pLvlLoad = 0; + plr[v0]._pmode = PM_NEWLVL; + plr[v0].destAction = -1; +} +// 52572C: using guessed type int leveldebug; +// 5BB1ED: using guessed type char leveltype; +// 5CF31D: using guessed type char setlevel; +// 679660: using guessed type char gbMaxPlayers; + +//----- (00440A9B) -------------------------------------------------------- +int __fastcall multi_init_single(_SNETPROGRAMDATA *client_info, _SNETPLAYERDATA *user_info, _SNETUIDATA *ui_info) +{ + int v3; // eax + int result; // eax + int v5; // eax + char *v6; // eax + + _LOBYTE(v3) = SNetInitializeProvider(0, client_info, user_info, ui_info, &fileinfo); + if ( v3 ) + { + ui_info = 0; + _LOBYTE(v5) = SNetCreateGame( + "local", + "local", + "local", + 0, + (char *)&sgGameInitInfo.dwSeed, + 8, + 1, + "local", + "local", + (int *)&ui_info); + if ( !v5 ) + { + v6 = GetLastErr(); + TermMsg("SNetCreateGame1:\n%s", v6); + } + myplr = 0; + gbMaxPlayers = 1; + result = 1; + } + else + { + SErrGetLastError(); + result = 0; + } + return result; +} +// 679660: using guessed type char gbMaxPlayers; + +//----- (00440B09) -------------------------------------------------------- +int __fastcall multi_init_multi(_SNETPROGRAMDATA *client_info, _SNETPLAYERDATA *user_info, _SNETUIDATA *ui_info, int *a4) +{ + _SNETPLAYERDATA *v4; // ebx + signed int i; // edi + int a6; // [esp+Ch] [ebp-Ch] + int a2; // [esp+10h] [ebp-8h] + int type; // [esp+14h] [ebp-4h] + + v4 = user_info; + a2 = (int)client_info; + for ( i = 1; ; i = 0 ) + { + type = 0; + if ( byte_678640 ) + { + if ( !UiSelectProvider(0, (_SNETPROGRAMDATA *)a2, v4, ui_info, &fileinfo, &type) + && (!i || SErrGetLastError() != 0x85100077 || !multi_upgrade(a4)) ) + { + return 0; + } + if ( type == 'BNET' ) + plr[0].pBattleNet = 1; + } + multi_event_handler(1); + if ( UiSelectGame(1, (_SNETPROGRAMDATA *)a2, v4, ui_info, &fileinfo, &a6) ) + break; + byte_678640 = 1; + } + if ( (unsigned int)a6 >= 4 ) + return 0; + myplr = a6; + gbMaxPlayers = 4; + pfile_read_player_from_save(); + if ( type == 'BNET' ) + plr[myplr].pBattleNet = 1; + return 1; +} +// 678640: using guessed type char byte_678640; +// 679660: using guessed type char gbMaxPlayers; + +//----- (00440BDB) -------------------------------------------------------- +int __fastcall multi_upgrade(int *a1) +{ + int *v1; // esi + int result; // eax + int status; // [esp+4h] [ebp-4h] + + v1 = a1; + SNetPerformUpgrade((unsigned long *)&status); + result = 1; + if ( status && status != 1 ) + { + if ( status == 2 ) + { + *v1 = 1; + } + else if ( status == -1 ) + { + DrawDlg("Network upgrade failed"); + } + result = 0; + } + return result; +} + +//----- (00440C17) -------------------------------------------------------- +void __fastcall multi_player_joins(int pnum, TCmdPlrInfoHdr *cmd, int a3) +{ + int v3; // ebx + TCmdPlrInfoHdr *v4; // edi + short *v5; // esi + int v6; // esi + bool v7; // zf + char *v8; // eax + int v9; // ST08_4 + int v10; // edx + int v11; // eax + int v12; // ecx + int v13; // eax + + v3 = pnum; + v4 = cmd; + if ( myplr != pnum ) + { + v5 = &sgwPackPlrOffsetTbl[pnum]; + if ( *v5 == cmd->wOffset || (*v5 = 0, !cmd->wOffset) ) + { + if ( !a3 && !*v5 ) + { + _LOBYTE(cmd) = CMD_ACK_PLRINFO; + multi_send_pinfo(pnum, cmd); + } + memcpy((char *)&pkplr[v3] + (unsigned short)v4->wOffset, &v4[1], (unsigned short)v4->wBytes); + *v5 += v4->wBytes; + if ( *v5 == 1266 ) + { + *v5 = 0; + multi_player_left_msg(v3, 0); + v6 = v3; + plr[v3]._pGFXLoad = 0; + UnPackPlayer(&pkplr[v3], v3, 1); + if ( a3 ) + { + ++gbActivePlayers; + v7 = sgbPlayerTurnBitTbl[v3] == 0; + plr[v6].plractive[0] = 1; + v8 = "Player '%s' (level %d) just joined the game"; + if ( v7 ) + v8 = "Player '%s' (level %d) is already in the game"; + EventPlrMsg(v8, plr[v6]._pName, plr[v6]._pLevel); + LoadPlrGFX(v3, 1); + SyncInitPlr(v3); + if ( plr[v6].plrlevel == currlevel ) + { + if ( (signed int)(plr[v6]._pHitPoints & 0xFFFFFFC0) <= 0 ) + { + plr[v6]._pgfxnum = 0; + LoadPlrGFX(v3, 128); + v9 = plr[v6]._pDFNum; + v10 = plr[v6]._peqD[0]; + plr[v6]._pmode = 8; + NewPlrAnim(v3, v10, plr[v6]._pDFrames, 1); + v11 = plr[v6]._pAnimLen; + v12 = v11 - 1; + plr[v6]._pVar8 = 2 * v11; + v13 = plr[v6].WorldX; + plr[v6]._pAnimFrame = v12; + dFlags[v13][plr[v6].WorldY] |= 4u; + } + else + { + StartStand(v3, 0); + } + } + } + } + } + } +} +// 67862C: using guessed type char gbActivePlayers; + +//----- (00440DB3) -------------------------------------------------------- +void __cdecl nthread_cpp_init_1() +{ + nthread_cpp_init_value = nthread_inf; +} +// 47F164: using guessed type int nthread_inf; +// 679700: using guessed type int nthread_cpp_init_value; + +//----- (00440DBE) -------------------------------------------------------- +void __cdecl nthread_cpp_init_2() +{ + nthread_init_mutex(); + nthread_cleanup_mutex_atexit(); +} + +//----- (00440DC8) -------------------------------------------------------- +void __cdecl nthread_init_mutex() +{ + InitializeCriticalSection(&stru_679718); +} + +//----- (00440DD4) -------------------------------------------------------- +void __cdecl nthread_cleanup_mutex_atexit() +{ + atexit(nthread_cleanup_mutex); +} + +//----- (00440DE0) -------------------------------------------------------- +void __cdecl nthread_cleanup_mutex() +{ + DeleteCriticalSection(&stru_679718); +} + +//----- (00440DEC) -------------------------------------------------------- +void __fastcall nthread_terminate_game(char *func_name) +{ + char *v1; // esi + int v2; // eax + char *v3; // eax + + v1 = func_name; + v2 = SErrGetLastError(); + if ( v2 != 0x8510006A ) + { + if ( v2 == 0x85100069 || v2 == 0x85100070 ) + { + gbGameDestroyed = 1; + } + else + { + v3 = GetLastErr(); + TermMsg("%s:\n%s", v1, v3); + } + } +} +// 67862D: using guessed type char gbGameDestroyed; + +//----- (00440E28) -------------------------------------------------------- +int __fastcall nthread_send_and_recv_turn(int cur_turn, int turn_delta) +{ + int v2; // ebx + unsigned int v3; // edi + int v4; // eax + char *v5; // ecx + int v6; // eax + int v7; // eax + int turn; // [esp+Ch] [ebp-8h] + int turns; // [esp+10h] [ebp-4h] + + v2 = turn_delta; + v3 = cur_turn; + _LOBYTE(v4) = SNetGetTurnsInTransit(&turns); + if ( v4 ) + { + if ( turns >= (unsigned int)gdwTurnsInTransit ) + return v3; + while ( 1 ) + { + ++turns; + v6 = dword_679754 | v3 & 0x7FFFFFFF; + dword_679754 = 0; + turn = v6; + _LOBYTE(v7) = SNetSendTurn((char *)&turn, 4); + if ( !v7 ) + break; + v3 += v2; + if ( v3 >= 0x7FFFFFFF ) + v3 = (unsigned short)v3; + if ( turns >= (unsigned int)gdwTurnsInTransit ) + return v3; + } + v5 = "SNetSendTurn"; + } + else + { + v5 = "SNetGetTurnsInTransit"; + } + nthread_terminate_game(v5); + return 0; +} +// 679738: using guessed type int gdwTurnsInTransit; +// 679754: using guessed type int dword_679754; + +//----- (00440EAA) -------------------------------------------------------- +void __fastcall nthread_recv_turns(bool *recieved) +{ + bool *v1; // esi + bool v2; // zf + int v3; // eax + + v1 = recieved; + *(_DWORD *)recieved = 0; + if ( --sgbPacketCountdown ) + { + dword_679764 += 50; + return; + } + v2 = sgbSyncCountdown-- == 1; + sgbPacketCountdown = byte_679704; + if ( !v2 ) + goto LABEL_11; + _LOBYTE(v3) = SNetReceiveTurns(0, 4, (char **)glpMsgTbl, (unsigned int *)gdwMsgLenTbl, (unsigned long *)player_state); + if ( v3 ) + { + if ( !byte_679758 ) + { + byte_679758 = 1; + dword_679764 = GetTickCount(); + } + sgbSyncCountdown = 4; + multi_msg_countdown(); +LABEL_11: + *(_DWORD *)v1 = 1; + dword_679764 += 50; + return; + } + if ( SErrGetLastError() != 0x8510006B ) + nthread_terminate_game("SNetReceiveTurns"); + byte_679758 = 0; + sgbSyncCountdown = 1; + sgbPacketCountdown = 1; +} +// 679704: using guessed type char byte_679704; +// 679750: using guessed type char sgbSyncCountdown; +// 679758: using guessed type char byte_679758; +// 679759: using guessed type char sgbPacketCountdown; +// 679764: using guessed type int dword_679764; + +//----- (00440F56) -------------------------------------------------------- +void __cdecl nthread_set_turn_upper_bit() +{ + dword_679754 = 0x80000000; +} +// 679754: using guessed type int dword_679754; + +//----- (00440F61) -------------------------------------------------------- +void __fastcall nthread_start(bool set_turn_upper_bit) +{ + BOOL v1; // esi + int v2; // eax + char *v3; // eax + unsigned int v4; // esi + unsigned int v5; // eax + char *v6; // eax + _SNETCAPS caps; // [esp+8h] [ebp-24h] + + v1 = set_turn_upper_bit; + dword_679764 = GetTickCount(); + sgbPacketCountdown = 1; + sgbSyncCountdown = 1; + byte_679758 = 1; + if ( v1 ) + nthread_set_turn_upper_bit(); + else + dword_679754 = 0; + caps.size = 36; + _LOBYTE(v2) = SNetGetProviderCaps(&caps); + if ( !v2 ) + { + v3 = GetLastErr(); + TermMsg("SNetGetProviderCaps:\n%s", v3); + } + gdwTurnsInTransit = caps.defaultturnsintransit; + if ( !caps.defaultturnsintransit ) + gdwTurnsInTransit = 1; + if ( caps.defaultturnssec <= 0x14u && caps.defaultturnssec ) + byte_679704 = 0x14u / caps.defaultturnssec; + else + byte_679704 = 1; + v4 = 512; + if ( caps.maxmessagesize < 0x200u ) + v4 = caps.maxmessagesize; + gdwDeltaBytesSec = (unsigned int)caps.bytessec >> 2; + gdwLargestMsgSize = v4; + if ( caps.maxplayers > 4u ) + caps.maxplayers = 4; + v5 = (3 * (caps.bytessec * (unsigned int)(unsigned char)byte_679704 / 0x14) >> 2) / caps.maxplayers; + gdwNormalMsgSize = v5; + if ( v5 < 0x80 ) + { + do + { + byte_679704 *= 2; + v5 *= 2; + } + while ( v5 < 0x80 ); + gdwNormalMsgSize = v5; + } + if ( v5 > v4 ) + gdwNormalMsgSize = v4; + if ( (unsigned char)gbMaxPlayers > 1u ) + { + sgbThreadIsRunning = 0; + EnterCriticalSection(&stru_679718); + byte_679734 = 1; + hObject = (HANDLE)_beginthreadex(0, 0, nthread_handler, 0, 0, (unsigned int *)&dword_67974C); + if ( hObject == (HANDLE)-1 ) + { + v6 = GetLastErr(); + TermMsg("nthread2:\n%s", v6); + } + SetThreadPriority(hObject, 2); + } +} +// 679660: using guessed type char gbMaxPlayers; +// 679704: using guessed type char byte_679704; +// 679730: using guessed type int gdwDeltaBytesSec; +// 679734: using guessed type char byte_679734; +// 679738: using guessed type int gdwTurnsInTransit; +// 679750: using guessed type char sgbSyncCountdown; +// 679754: using guessed type int dword_679754; +// 679758: using guessed type char byte_679758; +// 679759: using guessed type char sgbPacketCountdown; +// 67975A: using guessed type char sgbThreadIsRunning; +// 67975C: using guessed type int gdwLargestMsgSize; +// 679760: using guessed type int gdwNormalMsgSize; +// 679764: using guessed type int dword_679764; + +//----- (004410CF) -------------------------------------------------------- +unsigned int __stdcall nthread_handler(void *a1) +{ + int v1; // eax + signed __int32 v2; // esi + bool recieved; // [esp+Ch] [ebp-4h] + + if ( byte_679734 ) + { + while ( 1 ) + { + EnterCriticalSection(&stru_679718); + if ( !byte_679734 ) + break; + nthread_send_and_recv_turn(0, 0); + nthread_recv_turns(&recieved); + if ( v1 ) + v2 = dword_679764 - GetTickCount(); + else + v2 = 50; + LeaveCriticalSection(&stru_679718); + if ( v2 > 0 ) + Sleep(v2); + if ( !byte_679734 ) + return 0; + } + LeaveCriticalSection(&stru_679718); + } + return 0; +} +// 679734: using guessed type char byte_679734; +// 679764: using guessed type int dword_679764; + +//----- (00441145) -------------------------------------------------------- +void __cdecl nthread_cleanup() +{ + char *v0; // eax + + byte_679734 = 0; + gdwTurnsInTransit = 0; + gdwNormalMsgSize = 0; + gdwLargestMsgSize = 0; + if ( hObject != (HANDLE)-1 && dword_67974C != GetCurrentThreadId() ) + { + if ( !sgbThreadIsRunning ) + LeaveCriticalSection(&stru_679718); + if ( WaitForSingleObject(hObject, 0xFFFFFFFF) == -1 ) + { + v0 = GetLastErr(); + TermMsg("nthread3:\n(%s)", v0); + } + CloseHandle(hObject); + hObject = (HANDLE)-1; + } +} +// 679734: using guessed type char byte_679734; +// 679738: using guessed type int gdwTurnsInTransit; +// 67975A: using guessed type char sgbThreadIsRunning; +// 67975C: using guessed type int gdwLargestMsgSize; +// 679760: using guessed type int gdwNormalMsgSize; + +//----- (004411C4) -------------------------------------------------------- +void __fastcall nthread_ignore_mutex(bool ignore_mutex) +{ + bool v1; // bl + + v1 = ignore_mutex; + if ( hObject != (HANDLE)-1 ) + { + if ( ignore_mutex ) + LeaveCriticalSection(&stru_679718); + else + EnterCriticalSection(&stru_679718); + sgbThreadIsRunning = v1; + } +} +// 67975A: using guessed type char sgbThreadIsRunning; + +//----- (004411EF) -------------------------------------------------------- +bool __cdecl nthread_has_500ms_passed() +{ + DWORD v0; // eax + int v1; // ecx + + v0 = GetTickCount(); + v1 = v0 - dword_679764; + if ( gbMaxPlayers == 1 && v1 > 500 ) + { + dword_679764 = v0; + v1 = 0; + } + return v1 >= 0; +} +// 679660: using guessed type char gbMaxPlayers; +// 679764: using guessed type int dword_679764; + +//----- (0044121D) -------------------------------------------------------- +void __cdecl InitObjectGFX() +{ + ObjDataStruct *v0; // eax + unsigned char *v1; // esi + unsigned char v2; // cl + int v3; // edx + int i; // eax + char v5; // al + int v6; // eax + signed int v7; // ebx + char *v8; // ST08_4 + unsigned char *v9; // eax + int v10; // ecx + char fileload[56]; // [esp+4h] [ebp-58h] + char arglist; // [esp+3Ch] [ebp-20h] + + memset(fileload, 0, 0x38u); + if ( AllObjects[0].oload != -1 ) + { + v0 = AllObjects; + v1 = &AllObjects[0].otheme; + do + { + if ( v0->oload == 1 && currlevel >= (signed int)(char)*(v1 - 3) && currlevel <= (signed int)(char)*(v1 - 2) ) + fileload[(char)*(v1 - 4)] = 1; + v2 = *v1; + if ( *v1 != -1 ) + { + v3 = numthemes; + for ( i = 0; i < v3; ++i ) + { + if ( _LOBYTE(themes[i].ttype) == v2 ) + fileload[(char)*(v1 - 4)] = 1; + } + } + v5 = v1[1]; + if ( v5 != -1 ) + { + _LOBYTE(v6) = QuestStatus(v5); + if ( v6 ) + fileload[(char)*(v1 - 4)] = 1; + } + v1 += 44; + v0 = (ObjDataStruct *)(v1 - 5); + } + while ( *(v1 - 5) != -1 ); + } + v7 = 0; + do + { + if ( fileload[v7] ) + { + v8 = ObjMasterLoadList[v7]; + ObjFileList[numobjfiles] = v7; + sprintf(&arglist, "Objects\\%s.CEL", v8); + v9 = LoadFileInMem(&arglist, 0); + v10 = numobjfiles++; + pObjCels[v10] = (int)v9; + } + ++v7; + } + while ( v7 < 56 ); +} +// 67D7C4: using guessed type int numobjfiles; +// 44121D: using guessed type char fileload[56]; + +//----- (00441317) -------------------------------------------------------- +void __cdecl FreeObjectGFX() +{ + int i; // esi + void *v1; // ecx + + for ( i = 0; i < numobjfiles; ++i ) + { + v1 = (void *)pObjCels[i]; + pObjCels[i] = 0; + mem_free_dbg(v1); + } + numobjfiles = 0; +} +// 67D7C4: using guessed type int numobjfiles; + +//----- (00441345) -------------------------------------------------------- +int __fastcall RndLocOk(int xp, int yp) +{ + int v2; // ecx + int v3; // eax + int v4; // eax + int result; // eax + + v2 = xp; + v3 = v2 * 112 + yp; + result = 0; + if ( !dMonster[0][v3] && !dPlayer[v2][yp] && !dObject[v2][yp] && !(dFlags[v2][yp] & 8) ) + { + v4 = dPiece[0][v3]; + if ( !nSolidTable[v4] && (leveltype != 1 || v4 <= 126 || v4 >= 144) ) + result = 1; + } + return result; +} +// 5BB1ED: using guessed type char leveltype; + +//----- (004413A0) -------------------------------------------------------- +void __fastcall InitRndLocObj(int min, int max, int objtype) +{ + int v3; // esi + int v4; // ecx + int v5; // ebx + int v6; // eax + int v7; // ecx + int v8; // esi + int v9; // eax + int v10; // edi + int v11; // edx + int v12; // edx + int v13; // edx + int v14; // edx + int v15; // edx + int v16; // edx + int v17; // [esp+8h] [ebp-4h] + + v3 = min; + _LOBYTE(min) = -117; + v17 = 0; + v5 = v3 + random(min, max - v3); + if ( v5 > 0 ) + { + while ( 1 ) + { + do + { + _LOBYTE(v4) = -117; + v6 = random(v4, 80); + _LOBYTE(v7) = -117; + v8 = v6 + 16; + v9 = random(v7, 80); + v10 = v9 + 16; + } + while ( !RndLocOk(v8 - 1, v9 + 15) ); + if ( RndLocOk(v8, v11) ) + { + if ( RndLocOk(v8 + 1, v12) ) + { + if ( RndLocOk(v8 - 1, v10) ) + { + if ( RndLocOk(v8, v13) ) + { + if ( RndLocOk(v8 + 1, v14) ) + { + if ( RndLocOk(v8 - 1, v10 + 1) ) + { + if ( RndLocOk(v8, v15) ) + { + if ( RndLocOk(v8 + 1, v16) ) + { + AddObject(objtype, v8, v10); + if ( ++v17 >= v5 ) + break; + } + } + } + } + } + } + } + } + } + } +} + +//----- (00441477) -------------------------------------------------------- +void __fastcall InitRndLocBigObj(int min, int max, int objtype) +{ + int v3; // esi + int v4; // edx + int v5; // ecx + int v6; // eax + int v7; // ecx + int v8; // edi + int v9; // eax + int v10; // esi + int v11; // edx + int v12; // edx + int v13; // edx + int v14; // edx + int v15; // edx + int v16; // edx + int v17; // edx + int v18; // edx + int v19; // [esp+4h] [ebp-8h] + int v20; // [esp+8h] [ebp-4h] + + v3 = min; + v4 = max - min; + _LOBYTE(min) = -116; + v20 = 0; + v19 = v3 + random(min, v4); + if ( v19 > 0 ) + { + while ( 1 ) + { + do + { + _LOBYTE(v5) = -116; + v6 = random(v5, 80); + _LOBYTE(v7) = -116; + v8 = v6 + 16; + v9 = random(v7, 80); + v10 = v9 + 16; + } + while ( !RndLocOk(v8 - 1, v9 + 14) ); + if ( RndLocOk(v8, v11) ) + { + if ( RndLocOk(v8 + 1, v12) ) + { + if ( RndLocOk(v8 - 1, v10 - 1) ) + { + if ( RndLocOk(v8, v13) ) + { + if ( RndLocOk(v8 + 1, v14) ) + { + if ( RndLocOk(v8 - 1, v10) ) + { + if ( RndLocOk(v8, v15) ) + { + if ( RndLocOk(v8 + 1, v16) ) + { + if ( RndLocOk(v8 - 1, v10 + 1) ) + { + if ( RndLocOk(v8, v17) ) + { + if ( RndLocOk(v8 + 1, v18) ) + { + AddObject(objtype, v8, v10); + if ( ++v20 >= v19 ) + break; + } + } + } + } + } + } + } + } + } + } + } + } + } +} + +//----- (00441584) -------------------------------------------------------- +void __fastcall InitRndLocObj5x5(int min, int max, int objtype) +{ + int v3; // esi + int v4; // edx + int v5; // ecx + int v6; // ebx + int v7; // eax + int v8; // ecx + int v9; // edi + int v10; // esi + int v11; // edx + signed int v12; // [esp+Ch] [ebp-14h] + int v13; // [esp+10h] [ebp-10h] + int v14; // [esp+14h] [ebp-Ch] + signed int v15; // [esp+18h] [ebp-8h] + signed int v16; // [esp+1Ch] [ebp-4h] + + v3 = min; + v4 = max - min; + _LOBYTE(min) = -117; + v13 = 0; + v6 = v3 + random(min, v4); + if ( v6 > 0 ) + { + do + { + v14 = 0; + while ( 1 ) + { + _LOBYTE(v5) = -117; + v12 = 1; + v7 = random(v5, 80); + _LOBYTE(v8) = -117; + v9 = v7 + 16; + v15 = -2; + v10 = random(v8, 80) + 16; + do + { + v16 = -2; + v11 = v15 + v10; + do + { + if ( !RndLocOk(v16 + v9, v11) ) + v12 = 0; + ++v16; + } + while ( v16 <= 2 ); + ++v15; + } + while ( v15 <= 2 ); + if ( v12 ) + break; + if ( ++v14 > 20000 ) + return; + } + AddObject(objtype, v9, v10); + ++v13; + } + while ( v13 < v6 ); + } +} + +//----- (0044163B) -------------------------------------------------------- +void __cdecl ClrAllObjects() +{ + int *v0; // eax + int v1; // edx + + v0 = &object[0]._oy; + do + { + *(v0 - 1) = 0; + *v0 = 0; + v0[3] = 0; + v0[4] = 0; + v0[5] = 0; + v0[6] = 0; + v0[7] = 0; + v0[10] = 0; + v0[20] = 0; + v0[21] = 0; + v0[22] = 0; + v0[23] = 0; + v0 += 30; + } + while ( (signed int)v0 < (signed int)&hero_cpp_init_value ); + v1 = 0; + memset(objectactive, 0, sizeof(objectactive)); + nobjects = 0; + do + { + objectavail[v1] = v1; + ++v1; + } + while ( v1 < 127 ); + trapdir = 0; + trapid = 1; + leverid = 1; +} +// 679768: using guessed type int trapid; +// 67976C: using guessed type int trapdir; +// 67D7C8: using guessed type int hero_cpp_init_value; + +//----- (004416A8) -------------------------------------------------------- +void __cdecl AddTortures() +{ + int v0; // esi + int v1; // edi + _DWORD *v2; // [esp+Ch] [ebp-4h] + + v0 = 0; + do + { + v1 = 2; + v2 = (_DWORD *)((char *)dPiece + 4 * v0); + do + { + if ( *v2 == 367 ) + { + AddObject(36, v1 - 2, v0 + 1); + AddObject(38, v1, v0 - 1); + AddObject(37, v1 - 2, v0 + 3); + AddObject(39, v1 + 2, v0 - 1); + AddObject(40, v1 - 2, v0 + 5); + AddObject(29, v1 - 1, v0 + 3); + AddObject(30, v1 + 2, v0 + 5); + AddObject(31, v1, v0); + AddObject(32, v1 + 1, v0 + 2); + AddObject(33, v1, v0 + 4); + AddObject(34, v1, v0 + 1); + AddObject(35, v1 + 2, v0 + 2); + } + v2 += 112; + ++v1; + } + while ( v1 - 2 < 112 ); + ++v0; + } + while ( v0 < 112 ); +} + +//----- (0044179F) -------------------------------------------------------- +void __cdecl AddCandles() +{ + int v0; // esi + int v1; // edi + int v2; // ebx + + v0 = quests[13]._qtx; + v1 = quests[13]._qty; + v2 = quests[13]._qty + 1; + AddObject(87, quests[13]._qtx - 2, quests[13]._qty + 1); + AddObject(87, v0 + 3, v2); + v1 += 2; + AddObject(87, v0 - 1, v1); + AddObject(87, v0 + 2, v1); +} + +//----- (004417E8) -------------------------------------------------------- +void __fastcall AddBookLever(int lx1, int ly1, int lx2, int ly2, int x1, int y1, int x2, int y2, int msg) +{ + int v9; // esi + int v10; // edi + signed int v11; // ebx + int v12; // edx + int v13; // eax + int v14; // eax + int v15; // eax + int v16; // esi + signed int v17; // [esp+Ch] [ebp-Ch] + int v18; // [esp+10h] [ebp-8h] + signed int v19; // [esp+14h] [ebp-4h] + + v18 = 0; + while ( 1 ) + { + v17 = 1; + v9 = random(-117, 80) + 16; + v10 = random(-117, 80) + 16; + v11 = -2; + do + { + v19 = -2; + v12 = v11 + v10; + do + { + if ( !RndLocOk(v19 + v9, v12) ) + v17 = 0; + ++v19; + } + while ( v19 <= 2 ); + ++v11; + } + while ( v11 <= 2 ); + if ( v17 ) + break; + if ( ++v18 > 20000 ) + return; + } + _LOBYTE(v13) = QuestStatus(8); + if ( v13 ) + AddObject(71, v9, v10); + _LOBYTE(v14) = QuestStatus(11); + if ( v14 ) + AddObject(88, v9, v10); + _LOBYTE(v15) = QuestStatus(9); + if ( v15 ) + { + v9 = 2 * setpc_x + 25; + v10 = 2 * setpc_y + 40; + AddObject(72, v9, v10); + } + v16 = dObject[v9][v10] - 1; + SetObjMapRange(v16, x1, y1, x2, y2, leverid); + SetBookMsg(v16, msg); + ++leverid; + object[v16]._oVar6 = object[v16]._oAnimFrame + 1; +} + +//----- (00441904) -------------------------------------------------------- +void __cdecl InitRndBarrels() +{ + int v0; // ebp + int v1; // esi + int v2; // edi + int v3; // eax + int v4; // ebx + int v5; // edx + int v6; // eax + int v7; // eax + signed int v8; // [esp+4h] [ebp-Ch] + signed int v9; // [esp+8h] [ebp-8h] + int v10; // [esp+Ch] [ebp-4h] + + v10 = 0; + v0 = random(-113, 5) + 3; + if ( v0 > 0 ) + { + do + { + do + { + v1 = random(-113, 80) + 16; + v2 = random(-113, 80) + 16; + } + while ( !RndLocOk(v1, v2) ); + v3 = random(-113, 4); + AddObject(58 - (v3 != 0), v1, v2); + v4 = 1; + v5 = 0; + v9 = 1; + while ( !random(-113, v5) && v4 ) + { + v8 = 0; + v4 = 0; + do + { + if ( v8 >= 3 ) + break; + v6 = random(-113, 8); + v1 += bxadd[v6]; + v2 += byadd[v6]; + ++v8; + v4 = RndLocOk(v1, v2); + } + while ( !v4 ); + if ( v4 ) + { + v7 = random(-113, 5); + AddObject(58 - (v7 != 0), v1, v2); + ++v9; + } + v5 = v9 >> 1; + } + ++v10; + } + while ( v10 < v0 ); + } +} + +//----- (00441A00) -------------------------------------------------------- +void __fastcall AddL1Objs(int x1, int y1, int x2, int y2) +{ + int v4; // ebx + int *v5; // edi + int v6; // esi + int x; // [esp+0h] [ebp-8h] + int y; // [esp+4h] [ebp-4h] + + x = x1; + for ( y = y1; y < y2; ++y ) + { + v4 = x; + if ( x < x2 ) + { + v5 = (int *)((char *)dPiece + 4 * (y + 112 * x)); + do + { + v6 = *v5; + if ( *v5 == 270 ) + AddObject(0, v4, y); + if ( v6 == 44 || v6 == 51 || v6 == 214 ) + AddObject(1, v4, y); + if ( v6 == 46 || v6 == 56 ) + AddObject(2, v4, y); + ++v4; + v5 += 112; + } + while ( v4 < x2 ); + } + } +} + +//----- (00441A98) -------------------------------------------------------- +void __fastcall AddL2Objs(int x1, int y1, int x2, int y2) +{ + int v4; // ebx + int *v5; // esi + int v6; // edi + int x; // [esp+0h] [ebp-8h] + int y; // [esp+4h] [ebp-4h] + + x = x1; + for ( y = y1; y < y2; ++y ) + { + v4 = x; + if ( x < x2 ) + { + v5 = (int *)((char *)dPiece + 4 * (y + 112 * x)); + do + { + v6 = *v5; + if ( *v5 == 13 || v6 == 541 ) + AddObject(42, v4, y); + if ( v6 == 17 || v6 == 542 ) + AddObject(43, v4, y); + ++v4; + v5 += 112; + } + while ( v4 < x2 ); + } + } +} + +//----- (00441B16) -------------------------------------------------------- +void __fastcall AddL3Objs(int x1, int y1, int x2, int y2) +{ + int v4; // edi + int *v5; // esi + int v6; // ebx + int x; // [esp+0h] [ebp-8h] + int y; // [esp+4h] [ebp-4h] + + x = x1; + for ( y = y1; y < y2; ++y ) + { + v4 = x; + if ( x < x2 ) + { + v5 = (int *)((char *)dPiece + 4 * (y + 112 * x)); + do + { + v6 = *v5; + if ( *v5 == 531 ) + AddObject(74, v4, y); + if ( v6 == 534 ) + AddObject(75, v4, y); + ++v4; + v5 += 112; + } + while ( v4 < x2 ); + } + } +} + +//----- (00441B8A) -------------------------------------------------------- +unsigned char __fastcall WallTrapLocOk(int xp, int yp) +{ + return (~dFlags[xp][yp] & 8u) >> 3; +} + +//----- (00441BA0) -------------------------------------------------------- +void __cdecl AddL2Torches() +{ + int v0; // esi + int v1; // edi + char *v2; // ebx + int v3; // eax + int v4; // ecx + int (*v5)[112]; // [esp+Ch] [ebp-Ch] + int v6; // [esp+10h] [ebp-8h] + int (*v7)[112]; // [esp+14h] [ebp-4h] + + v0 = 0; + v7 = dPiece; + do + { + v1 = 0; + v2 = &dungeon[39][v0 + 39]; + v5 = v7; + do + { + _LOBYTE(v3) = WallTrapLocOk(v1, v0); + if ( !v3 ) + goto LABEL_18; + v6 = (*v5)[0]; + if ( (*v5)[0] == 1 ) + { + _LOBYTE(v4) = -111; + if ( random(v4, 3) ) + goto LABEL_18; + AddObject(46, v1, v0); + } + if ( v6 == 5 ) + { + _LOBYTE(v4) = -111; + if ( random(v4, 3) ) + goto LABEL_18; + AddObject(47, v1, v0); + } + if ( v6 == 37 ) + { + _LOBYTE(v4) = -111; + if ( random(v4, 10) || *(v2 - 111) ) + goto LABEL_18; + AddObject(44, v1 - 1, v0); + } + if ( v6 == 41 ) + { + _LOBYTE(v4) = -111; + if ( !random(v4, 10) && !*v2 ) + AddObject(45, v1, v0 - 1); + } +LABEL_18: + ++v5; + ++v1; + v2 += 112; + } + while ( v1 < 112 ); + v7 = (int (*)[112])((char *)v7 + 4); + ++v0; + } + while ( (signed int)v7 < (signed int)dPiece[1] ); +} + +//----- (00441C8C) -------------------------------------------------------- +unsigned char __fastcall TorchLocOK(int xp, int yp) +{ + int v2; // ecx + unsigned char result; // al + + v2 = xp; + if ( dFlags[v2][yp] & 8 ) + result = 0; + else + result = nTrapTable[dPiece[0][yp + v2 * 112]] != 0; + return result; +} + +//----- (00441CB3) -------------------------------------------------------- +void __cdecl AddObjTraps() +{ + int v0; // esi + int *v1; // eax + _BYTE *v2; // edi + int v3; // ebx + int v4; // edi + int *j; // eax + int v6; // eax + char v7; // al + int v8; // edi + char *i; // eax + int v10; // eax + int v11; // eax + int *v12; // [esp+0h] [ebp-18h] + char *v13; // [esp+4h] [ebp-14h] + int *v14; // [esp+8h] [ebp-10h] + int v15; // [esp+Ch] [ebp-Ch] + signed int v16; // [esp+10h] [ebp-8h] + int x; // [esp+14h] [ebp-4h] + + if ( currlevel == 1 ) + v15 = 10; + if ( currlevel >= 2u ) + v15 = 15; + if ( currlevel >= 5u ) + v15 = 20; + if ( currlevel >= 7u ) + v15 = 25; + v0 = 0; + v1 = dPiece[-1]; + v12 = dPiece[-1]; + do + { + x = 0; + v16 = 0; + v2 = (unsigned char *)dObject + v0; + v14 = v1; + v13 = (char *)dObject + v0; + do + { + if ( *v2 > 0 && random(-112, 100) < v15 ) + { + v3 = (char)(*v2 - 1); + if ( AllObjects[object[v3]._otype].oTrapFlag ) + { + if ( random(-112, 2) ) + { + v8 = v0 - 1; + for ( i = &dflags[39][4 * (v0 + v16 * 112) + 36]; !nSolidTable[*(_DWORD *)i]; i -= 4 ) + --v8; + _LOBYTE(v10) = TorchLocOK(x, v8); + if ( v10 && v0 - v8 > 1 ) + { + AddObject(54, x, v8); + v7 = dObject[v16][v8]; + goto LABEL_27; + } + } + else + { + v4 = x - 1; + for ( j = v14; !nSolidTable[*j]; j -= 112 ) + --v4; + _LOBYTE(v6) = TorchLocOK(v4, v0); + if ( v6 && x - v4 > 1 ) + { + AddObject(53, v4, v0); + v7 = dObject[v4][v0]; +LABEL_27: + v11 = (char)(v7 - 1); + object[v11]._oVar2 = v0; + object[v11]._oVar1 = x; + object[v3]._oTrapFlag = 1; + goto LABEL_28; + } + } + } + } +LABEL_28: + ++v16; + ++x; + v14 += 112; + v2 = (unsigned char *)v13 + 112; + v13 += 112; + } + while ( v16 < 112 ); + ++v0; + v1 = v12 + 1; + ++v12; + } + while ( (signed int)v12 < (signed int)dPiece ); +} + +//----- (00441E58) -------------------------------------------------------- +void __cdecl AddChestTraps() +{ + signed int v0; // ebp + _BYTE *v1; // ebx + int v2; // esi + int v3; // eax + bool v4; // zf + int v5; // eax + signed int v6; // [esp+10h] [ebp-4h] + + v0 = 0; + do + { + v1 = (unsigned char *)dObject + v0; + v6 = 112; + do + { + if ( *v1 > 0 ) + { + v2 = (char)(*v1 - 1); + v3 = object[v2]._otype; + if ( v3 >= OBJ_CHEST1 && v3 <= OBJ_CHEST3 && !object[v2]._oTrapFlag && random(0, 100) < 10 ) + { + object[v2]._otype += OBJ_BOOKCASER; + v4 = leveltype == 2; + object[v2]._oTrapFlag = 1; + if ( v4 ) + v5 = random(0, 2); + else + v5 = random(0, 3); + object[v2]._oVar4 = v5; + } + } + v1 += 112; + --v6; + } + while ( v6 ); + ++v0; + } + while ( v0 < 112 ); +} +// 5BB1ED: using guessed type char leveltype; + +//----- (00441EE4) -------------------------------------------------------- +void __fastcall LoadMapObjects(unsigned char *pMap, int startx, int starty, int x1, int y1, int w, int h, int leveridx) +{ + unsigned char *v8; // ebx + int v9; // esi + int v10; // ecx + int v11; // eax + int v12; // ecx + int v13; // eax + int v14; // esi + unsigned char *v15; // ebx + int i; // edi + int v17; // eax + int v18; // [esp+8h] [ebp-10h] + int v19; // [esp+Ch] [ebp-Ch] + int v20; // [esp+10h] [ebp-8h] + int v21; // [esp+14h] [ebp-4h] + int y; // [esp+20h] [ebp+8h] + + v8 = pMap + 2; + InitObjFlag = 1; + v9 = *pMap; + v10 = pMap[2]; + v11 = v10; + v12 = 2 * v10; + v20 = startx; + v13 = v9 * v11; + v14 = 2 * v9; + v19 = v14; + v18 = v12; + v15 = &v8[4 * v14 * v12 + 2 + 2 * v13]; + if ( v12 > 0 ) + { + v21 = -16 - starty; + y = starty + 16; + do + { + for ( i = 0; i < v14; ++i ) + { + if ( *v15 ) + { + AddObject(ObjTypeConv[*v15], i + v20 + 16, y); + v17 = ObjIndex(i + v20 + 16, y); + SetObjMapRange(v17, x1, y1, x1 + w, y1 + h, leveridx); + v14 = v19; + v12 = v18; + } + v15 += 2; + } + ++y; + } + while ( y + v21 < v12 ); + } + InitObjFlag = 0; +} +// 67D7C0: using guessed type int InitObjFlag; + +//----- (00441FAF) -------------------------------------------------------- +void __fastcall LoadMapObjs(unsigned char *pMap, int startx, int starty) +{ + unsigned char *v3; // esi + int v4; // eax + int v5; // edi + int v6; // ecx + int v7; // eax + int v8; // ecx + int v9; // edi + unsigned char *v10; // esi + int i; // ebx + int v12; // [esp+8h] [ebp-8h] + int v13; // [esp+Ch] [ebp-4h] + int y; // [esp+18h] [ebp+8h] + + v3 = pMap + 2; + InitObjFlag = 1; + v4 = pMap[2]; + v5 = *pMap; + v6 = v4; + v7 = 2 * v4; + v12 = startx; + v8 = v5 * v6; + v9 = 2 * v5; + v10 = &v3[4 * v9 * v7 + 2 + 2 * v8]; + if ( v7 > 0 ) + { + v13 = v7; + y = starty + 16; + do + { + for ( i = 0; i < v9; ++i ) + { + if ( *v10 ) + AddObject(ObjTypeConv[*v10], i + v12 + 16, y); + v10 += 2; + } + ++y; + --v13; + } + while ( v13 ); + } + InitObjFlag = 0; +} +// 67D7C0: using guessed type int InitObjFlag; + +//----- (00442036) -------------------------------------------------------- +void __cdecl AddDiabObjs() +{ + unsigned char *v0; // esi + unsigned char *v1; // esi + unsigned char *v2; // esi + + v0 = LoadFileInMem("Levels\\L4Data\\diab1.DUN", 0); + LoadMapObjects(v0, 2 * diabquad1x, 2 * diabquad1y, diabquad2x, diabquad2y, 11, 12, 1); + mem_free_dbg(v0); + v1 = LoadFileInMem("Levels\\L4Data\\diab2a.DUN", 0); + LoadMapObjects(v1, 2 * diabquad2x, 2 * diabquad2y, diabquad3x, diabquad3y, 11, 11, 2); + mem_free_dbg(v1); + v2 = LoadFileInMem("Levels\\L4Data\\diab3a.DUN", 0); + LoadMapObjects(v2, 2 * diabquad3x, 2 * diabquad3y, diabquad4x, diabquad4y, 9, 9, 3); + mem_free_dbg(v2); +} +// 5289C4: using guessed type int diabquad1x; +// 5289C8: using guessed type int diabquad1y; + +//----- (004420F2) -------------------------------------------------------- +void __cdecl AddStoryBooks() +{ + int v0; // esi + int v1; // edi + signed int v2; // ebx + int v3; // edx + int v4; // esi + int y; // [esp+Ch] [ebp-Ch] + int v6; // [esp+10h] [ebp-8h] + signed int v7; // [esp+14h] [ebp-4h] + + v6 = 0; + while ( 1 ) + { + y = 1; + v0 = random(-117, 80) + 16; + v1 = random(-117, 80) + 16; + v2 = -2; + do + { + v7 = -3; + v3 = v2 + v1; + do + { + if ( !RndLocOk(v7 + v0, v3) ) + y = 0; + ++v7; + } + while ( v7 <= 3 ); + ++v2; + } + while ( v2 <= 2 ); + if ( y ) + break; + if ( ++v6 > 20000 ) + return; + } + AddObject(86, v0, v1); + AddObject(87, v0 - 2, v1 + 1); + AddObject(87, v0 - 2, v1); + AddObject(87, v0 - 1, v1 - 1); + AddObject(87, v0 + 1, v1 - 1); + v4 = v0 + 2; + AddObject(87, v4, v1); + AddObject(87, v4, v1 + 1); +} + +//----- (004421CA) -------------------------------------------------------- +void __fastcall AddHookedBodies(int freq) +{ + int v1; // ebx + char *v2; // esi + int v3; // edi + int v4; // eax + int v5; // eax + int v6; // eax + int v7; // eax + int v8; // [esp-8h] [ebp-20h] + int v9; // [esp-4h] [ebp-1Ch] + int max; // [esp+Ch] [ebp-Ch] + int x; // [esp+10h] [ebp-8h] + int y; // [esp+14h] [ebp-4h] + + y = 0; + max = freq; + v1 = 16; + do + { + x = 0; + v2 = (char *)dungeon + y; + v3 = 17; + do + { + if ( *v2 == 1 || *v2 == 2 ) + { + _LOBYTE(freq) = 0; + if ( !random(freq, max) ) + { + _LOBYTE(v4) = SkipThemeRoom(x, y); + if ( v4 ) + { + if ( *v2 != 1 || v2[40] != 6 ) + { + if ( *v2 == 2 && v2[1] == 6 ) + { + _LOBYTE(freq) = 0; + v7 = random(freq, 2); + if ( v7 ) + { + if ( v7 != 1 ) + goto LABEL_22; + v9 = v1; + v8 = 39; + } + else + { + v9 = v1; + v8 = 38; + } + AddObject(v8, v3 - 1, v9); + } + } + else + { + _LOBYTE(freq) = 0; + v5 = random(freq, 3); + if ( v5 ) + { + v6 = v5 - 1; + if ( v6 ) + { + if ( v6 == 1 ) + AddObject(40, v3, v1); + } + else + { + AddObject(37, v3, v1); + } + } + else + { + AddObject(36, v3, v1); + } + } + } + } + } +LABEL_22: + ++x; + v3 += 2; + v2 += 40; + } + while ( v3 < 97 ); + ++y; + v1 += 2; + } + while ( v1 < 96 ); +} + +//----- (0044229F) -------------------------------------------------------- +void __cdecl AddL4Goodies() +{ + AddHookedBodies(6); + InitRndLocObj(2, 6, 29); + InitRndLocObj(2, 6, 30); + InitRndLocObj(2, 6, 31); + InitRndLocObj(2, 6, 32); + InitRndLocObj(2, 6, 33); + InitRndLocObj(2, 6, 34); + InitRndLocObj(2, 6, 35); + InitRndLocObj(2, 6, 67); + InitRndLocObj(1, 3, 80); +} + +//----- (00442316) -------------------------------------------------------- +void __cdecl AddLazStand() +{ + int v0; // edi + int v1; // esi + signed int v2; // ebx + int v3; // edx + int v4; // edi + signed int v5; // [esp+Ch] [ebp-Ch] + int v6; // [esp+10h] [ebp-8h] + signed int v7; // [esp+14h] [ebp-4h] + + v6 = 0; + while ( 1 ) + { + v5 = 1; + v0 = random(-117, 80) + 16; + v1 = random(-117, 80) + 16; + v2 = -3; + do + { + v7 = -2; + v3 = v2 + v1; + do + { + if ( !RndLocOk(v7 + v0, v3) ) + v5 = 0; + ++v7; + } + while ( v7 <= 3 ); + ++v2; + } + while ( v2 <= 3 ); + if ( v5 ) + break; + if ( ++v6 > 10000 ) + { + InitRndLocObj(1, 1, 95); + return; + } + } + AddObject(95, v0, v1); + AddObject(30, v0, v1 + 2); + AddObject(87, v0 + 1, v1 + 2); + AddObject(31, v0 + 2, v1 + 2); + AddObject(33, v0, v1 - 2); + AddObject(87, v0 + 1, v1 - 2); + AddObject(34, v0 + 2, v1 - 2); + v4 = v0 - 1; + AddObject(87, v4, v1 - 1); + AddObject(35, v4, v1); + AddObject(87, v4, v1 + 1); +} + +//----- (00442418) -------------------------------------------------------- +void __fastcall InitObjects(int a1) +{ + int v1; // eax + int v2; // eax + int v3; // eax + int v4; // eax + int v5; // eax + int v6; // eax + char v7; // al + signed int v8; // ebx + unsigned char *v9; // esi + int v10; // eax + char v11; // al + int v12; // eax + char v13; // al + unsigned char *v14; // esi + int v15; // eax + int v16; // [esp+0h] [ebp-4h] + + v16 = a1; + ClrAllObjects(); + if ( currlevel == 16 ) + { + AddDiabObjs(); + } + else + { + InitObjFlag = 1; + GetRndSeed(); + if ( currlevel == 9 && gbMaxPlayers == 1 ) + AddSlainHero(); + if ( currlevel == quests[1]._qlevel && quests[1]._qactive == 1 ) + AddMushPatch(); + if ( currlevel == 4 ) + AddStoryBooks(); + if ( currlevel == 8 ) + AddStoryBooks(); + if ( currlevel == 12 ) + AddStoryBooks(); + if ( leveltype == 1 ) + { + _LOBYTE(v1) = QuestStatus(6); + if ( v1 ) + AddTortures(); + _LOBYTE(v2) = QuestStatus(13); + if ( v2 ) + AddCandles(); + _LOBYTE(v3) = QuestStatus(7); + if ( v3 ) + AddObject(97, 2 * setpc_x + 26, 2 * setpc_y + 19); + InitRndLocBigObj(10, 15, 48); + AddL1Objs(0, 0, 112, 112); + InitRndBarrels(); + } + if ( leveltype == 2 ) + { + _LOBYTE(v4) = QuestStatus(0); + if ( v4 ) + InitRndLocObj5x5(1, 1, 23); + _LOBYTE(v5) = QuestStatus(14); + if ( v5 ) + InitRndLocObj5x5(1, 1, 41); + AddL2Objs(0, 0, 112, 112); + AddL2Torches(); + _LOBYTE(v6) = QuestStatus(8); + if ( v6 ) + { + v7 = plr[myplr]._pClass; + if ( v7 ) + { + if ( v7 == 1 ) + { + v8 = 245; + } + else + { + v8 = 241; + if ( v7 != 2 ) + v8 = v16; + } + } + else + { + v8 = 237; + } + quests[8]._qmsg = v8; + AddBookLever(0, 0, 112, 112, setpc_x, setpc_y, setpc_w + setpc_x + 1, setpc_h + setpc_y + 1, v8); + v9 = LoadFileInMem("Levels\\L2Data\\Blind2.DUN", 0); + LoadMapObjs(v9, 2 * setpc_x, 2 * setpc_y); + mem_free_dbg(v9); + } + else + { + v8 = v16; + } + _LOBYTE(v10) = QuestStatus(9); + if ( v10 ) + { + v11 = plr[myplr]._pClass; + if ( v11 ) + { + if ( v11 == 1 ) + { + v8 = 244; + } + else if ( v11 == 2 ) + { + v8 = 240; + } + } + else + { + v8 = 236; + } + quests[9]._qmsg = v8; + AddBookLever(0, 0, 112, 112, setpc_x, setpc_y + 3, setpc_x + 2, setpc_y + 7, v8); + AddObject(73, 2 * setpc_x + 25, 2 * setpc_y + 32); + } + InitRndBarrels(); + } + else + { + v8 = v16; + } + if ( leveltype == 3 ) + { + AddL3Objs(0, 0, 112, 112); + InitRndBarrels(); + } + if ( leveltype == 4 ) + { + _LOBYTE(v12) = QuestStatus(11); + if ( v12 ) + { + v13 = plr[myplr]._pClass; + if ( v13 ) + { + if ( v13 == 1 ) + { + v8 = 246; + } + else if ( v13 == 2 ) + { + v8 = 242; + } + } + else + { + v8 = 238; + } + quests[11]._qmsg = v8; + AddBookLever(0, 0, 112, 112, setpc_x, setpc_y, setpc_x + setpc_w, setpc_y + setpc_h, v8); + v14 = LoadFileInMem("Levels\\L4Data\\Warlord.DUN", 0); + LoadMapObjs(v14, 2 * setpc_x, 2 * setpc_y); + mem_free_dbg(v14); + } + _LOBYTE(v15) = QuestStatus(15); + if ( v15 && gbMaxPlayers == 1 ) + AddLazStand(); + InitRndBarrels(); + AddL4Goodies(); + } + InitRndLocObj(5, 10, 5); + InitRndLocObj(3, 6, 6); + InitRndLocObj(1, 5, 7); + if ( leveltype != 4 ) + AddObjTraps(); + if ( (unsigned char)leveltype > 1u ) + AddChestTraps(); + InitObjFlag = 0; + } +} +// 5BB1ED: using guessed type char leveltype; +// 5CF330: using guessed type int setpc_h; +// 5CF334: using guessed type int setpc_w; +// 679660: using guessed type char gbMaxPlayers; +// 67D7C0: using guessed type int InitObjFlag; + +//----- (004427C5) -------------------------------------------------------- +void __fastcall SetMapObjects(char *pMap, int startx, int starty) +{ + char *v3; // esi + unsigned char v4; // al + char *v5; // ecx + int v6; // edi + int v7; // eax + int v8; // esi + int v9; // ecx + int v10; // esi + int v11; // ecx + int v12; // edi + _BYTE *v13; // eax + int v14; // ebx + signed int v15; // ebx + char *v16; // ST08_4 + unsigned char *v17; // eax + int v18; // ecx + int i; // ebx + int v20[56]; // [esp+Ch] [ebp-10Ch] + char arglist[32]; // [esp+ECh] [ebp-2Ch] + _BYTE *v22; // [esp+10Ch] [ebp-Ch] + int v23; // [esp+110h] [ebp-8h] + _BYTE *v24; // [esp+114h] [ebp-4h] + int y; // [esp+120h] [ebp+8h] + + v23 = startx; + v3 = pMap; + ClrAllObjects(); + memset(v20, 0, sizeof(v20)); + v4 = AllObjects[0].oload; + InitObjFlag = 1; + if ( AllObjects[0].oload != -1 ) + { + v5 = &AllObjects[0].ofindex; + do + { + if ( v4 == 1 && (unsigned char)leveltype == *((char *)v5 + 3) ) + v20[*(char *)v5] = 1; + v4 = *((_BYTE *)v5 + 43); + v5 += 44; + } + while ( v4 != -1 ); + } + v6 = (unsigned char)*v3; + v7 = (int)(v3 + 2); + v8 = (unsigned char)v3[2]; + v9 = v8; + v10 = 2 * v8; + v11 = v6 * v9; + v12 = 2 * v6; + v13 = (_BYTE *)(2 * v11 + 2 + 4 * v12 * v10 + v7); + v22 = v13; + if ( v10 > 0 ) + { + v24 = (_BYTE *)v10; + do + { + if ( v12 > 0 ) + { + v14 = v12; + do + { + if ( *v13 ) + v20[(char)AllObjects[ObjTypeConv[(unsigned char)*v13]].ofindex] = 1; + v13 += 2; + --v14; + } + while ( v14 ); + } + --v24; + } + while ( v24 ); + } + v15 = 0; + do + { + if ( v20[v15] ) + { + v16 = ObjMasterLoadList[v15]; + ObjFileList[numobjfiles] = v15; + sprintf(arglist, "Objects\\%s.CEL", v16); + v17 = LoadFileInMem(arglist, 0); + v18 = numobjfiles++; + pObjCels[v18] = (int)v17; + } + ++v15; + } + while ( v15 < 56 ); + v24 = v22; + if ( v10 > 0 ) + { + y = starty + 16; + do + { + for ( i = 0; i < v12; ++i ) + { + if ( *v24 ) + AddObject(ObjTypeConv[(unsigned char)*v24], i + v23 + 16, y); + v24 += 2; + } + ++y; + --v10; + } + while ( v10 ); + } + InitObjFlag = 0; +} +// 5BB1ED: using guessed type char leveltype; +// 67D7C0: using guessed type int InitObjFlag; +// 67D7C4: using guessed type int numobjfiles; +// 4427C5: using guessed type int var_10C[56]; + +//----- (0044292B) -------------------------------------------------------- +void __fastcall DeleteObject(int oi, int i) +{ + int v2; // eax + bool v3; // zf + bool v4; // sf + + dObject[object[oi]._ox][object[oi]._oy] = 0; + v2 = nobjects - 1; + v3 = nobjects == 1; + v4 = nobjects - 1 < 0; + *(&object[0]._otype - nobjects) = oi; + nobjects = v2; + if ( !v4 && !v3 && i != v2 ) + objectactive[i] = objectactive[v2]; +} + +//----- (0044297B) -------------------------------------------------------- +void __fastcall SetupObject(int i, int x, int y, int ot) +{ + int v4; // esi + int v5; // edi + int v6; // ecx + int v7; // edx + int v8; // eax + int v9; // eax + int v10; // edx + int v11; // eax + int v12; // ecx + int v13; // eax + int v14; // eax + unsigned char v15; // al + + v4 = i; + object[v4]._otype = ot; + v5 = ot; + v6 = AllObjects[ot].ofindex; + object[v4]._ox = x; + object[v4]._oy = y; + v7 = ObjFileList[0]; + v8 = 0; + while ( v7 != v6 ) + v7 = ObjFileList[v8++ + 1]; + object[v4]._oAnimCel = pObjCels[v8]; + v9 = AllObjects[v5].oAnimFlag; + object[v4]._oAnimFlag = v9; + if ( v9 ) + { + v10 = AllObjects[v5].oAnimDelay; + _LOBYTE(v6) = -110; + object[v4]._oAnimDelay = v10; + object[v4]._oAnimCnt = random(v6, v10); + v11 = AllObjects[v5].oAnimLen; + _LOBYTE(v12) = -110; + object[v4]._oAnimLen = v11; + v13 = random(v12, v11 - 1) + 1; + } + else + { + v14 = AllObjects[v5].oAnimLen; + object[v4]._oAnimDelay = 1000; + object[v4]._oAnimLen = v14; + v13 = AllObjects[v5].oAnimDelay; + object[v4]._oAnimCnt = 0; + } + object[v4]._oAnimFrame = v13; + object[v4]._oAnimWidth = AllObjects[v5].oAnimWidth; + object[v4]._oSolidFlag = AllObjects[v5].oSolidFlag; + object[v4]._oMissFlag = AllObjects[v5].oMissFlag; + object[v4]._oLight = AllObjects[v5].oLightFlag; + _LOBYTE(object[v4]._oBreak) = AllObjects[v5].oBreak; + v15 = AllObjects[v5].oSelFlag; + object[v4]._oDelFlag = 0; + _LOBYTE(object[v4]._oSelFlag) = v15; + object[v4]._oPreFlag = 0; + object[v4]._oTrapFlag = 0; + object[v4]._oDoorFlag = 0; +} + +//----- (00442A9D) -------------------------------------------------------- +void __fastcall SetObjMapRange(int i, int x1, int y1, int x2, int y2, int v) +{ + int v6; // ecx + + v6 = i; + object[v6]._oVar2 = y1; + object[v6]._oVar3 = x2; + object[v6]._oVar4 = y2; + object[v6]._oVar1 = x1; + object[v6]._oVar8 = v; +} + +//----- (00442AD1) -------------------------------------------------------- +void __fastcall SetBookMsg(int i, int msg) +{ + object[i]._oVar7 = msg; +} + +//----- (00442ADB) -------------------------------------------------------- +void __fastcall AddL1Door(int i, int x, int y, int ot) +{ + int v4; // ecx + int v5; // edx + int *v6; // eax + int v7; // edx + int v8; // eax + int v9; // eax + + v4 = i; + v5 = 112 * x; + object[v4]._oDoorFlag = 1; + if ( ot == 1 ) + { + v6 = (int *)((char *)dPiece + 4 * (y + v5)); + v7 = *v6; + v8 = *(v6 - 1); + } + else + { + v9 = v5 + y; + v7 = dPiece[0][v5 + y]; + v8 = *(_DWORD *)&dflags[28][4 * v9 + 32]; + } + object[v4]._oVar4 = 0; + object[v4]._oVar1 = v7; + object[v4]._oVar2 = v8; +} + +//----- (00442B2C) -------------------------------------------------------- +void __fastcall AddSCambBook(int i) +{ + int v1; // ecx + int v2; // eax + int v3; // edx + int v4; // esi + + v1 = i; + v2 = setpc_x; + v3 = setpc_y; + v4 = setpc_w; + object[v1]._oVar1 = setpc_x; + object[v1]._oVar2 = v3; + object[v1]._oVar3 = v4 + v2 + 1; + object[v1]._oVar4 = setpc_h + v3 + 1; + object[v1]._oVar6 = object[v1]._oAnimFrame + 1; +} +// 5CF330: using guessed type int setpc_h; +// 5CF334: using guessed type int setpc_w; + +//----- (00442B75) -------------------------------------------------------- +void __fastcall AddChest(int i, int t) +{ + int v2; // edi + int v3; // esi + int v4; // esi + int v5; // ecx + int v6; // [esp-4h] [ebp-Ch] + + v2 = t; + v3 = i; + _LOBYTE(i) = -109; + if ( !random(i, 2) ) + object[v3]._oAnimFrame += 3; + v4 = v3; + object[v4]._oRndSeed = GetRndSeed(); + switch ( v2 ) + { + case OBJ_CHEST1: + goto LABEL_22; + case OBJ_CHEST2: +LABEL_12: + if ( setlevel ) + { + object[v4]._oVar1 = 2; + break; + } + v6 = 3; + goto LABEL_18; + case OBJ_CHEST3: +LABEL_9: + if ( setlevel ) + { + object[v4]._oVar1 = 3; + break; + } + v6 = 4; +LABEL_18: + _LOBYTE(v5) = -109; + object[v4]._oVar1 = random(v5, v6); + break; + case OBJ_TCHEST1: +LABEL_22: + if ( setlevel ) + { + object[v4]._oVar1 = 1; + break; + } + v6 = 2; + goto LABEL_18; + case OBJ_TCHEST2: + goto LABEL_12; + case OBJ_TCHEST3: + goto LABEL_9; + } + _LOBYTE(v5) = -109; + object[v4]._oVar2 = random(v5, 8); +} +// 5CF31D: using guessed type char setlevel; + +//----- (00442C27) -------------------------------------------------------- +void __fastcall AddL2Door(int i, int x, int y, int ot) +{ + int v4; // esi + + v4 = i; + object[i]._oDoorFlag = 1; + if ( ot == 42 ) + ObjSetMicro(x, y, 538); + else + ObjSetMicro(x, y, 540); + object[v4]._oVar4 = 0; +} + +//----- (00442C62) -------------------------------------------------------- +void __fastcall AddL3Door(int i, int x, int y, int ot) +{ + int v4; // esi + + v4 = i; + object[i]._oDoorFlag = 1; + if ( ot == 74 ) + ObjSetMicro(x, y, 531); + else + ObjSetMicro(x, y, 534); + object[v4]._oVar4 = 0; +} + +//----- (00442C9D) -------------------------------------------------------- +void __fastcall AddSarc(int i) +{ + int v1; // esi + char v2; // al + int v3; // ecx + int v4; // eax + bool v5; // sf + unsigned char v6; // of + + v1 = i; + v2 = -1 - i; + v3 = 112 * object[i]._ox; + dungeon[39][v3 + 39 + object[v1]._oy] = v2; + _LOBYTE(v3) = -103; + object[v1]._oVar1 = random(v3, 10); + v4 = GetRndSeed(); + v6 = __OFSUB__(object[v1]._oVar1, 8); + v5 = object[v1]._oVar1 - 8 < 0; + object[v1]._oRndSeed = v4; + if ( !(v5 ^ v6) ) + object[v1]._oVar2 = PreSpawnSkeleton(); +} + +//----- (00442CEE) -------------------------------------------------------- +void __fastcall AddFlameTrap(int i) +{ + int v1; // ecx + int v2; // eax + + v1 = i; + v2 = trapid; + object[v1]._oVar2 = 0; + object[v1]._oVar4 = 0; + object[v1]._oVar1 = v2; + object[v1]._oVar3 = trapdir; +} +// 679768: using guessed type int trapid; +// 67976C: using guessed type int trapdir; + +//----- (00442D16) -------------------------------------------------------- +void __fastcall AddFlameLvr(int i) +{ + int v1; // ecx + + v1 = i; + object[v1]._oVar1 = trapid; + object[v1]._oVar2 = 49; +} +// 679768: using guessed type int trapid; + +//----- (00442D2F) -------------------------------------------------------- +void __fastcall AddTrap(int i) +{ + int v1; // esi + int v2; // eax + + v1 = i; + v2 = random(148, currlevel / 3 + 1); + if ( !v2 ) + object[v1]._oVar3 = 0; + if ( v2 == 1 ) + object[v1]._oVar3 = 1; + if ( v2 == 2 ) + object[v1]._oVar3 = 7; + object[v1]._oVar4 = 0; +} + +//----- (00442D8A) -------------------------------------------------------- +void __fastcall AddObjLight(int i, int r) +{ + int v2; // esi + + if ( InitObjFlag ) + { + v2 = i; + DoLighting(object[i]._ox, object[i]._oy, r, -1); + object[v2]._oVar1 = -1; + } + else + { + object[i]._oVar1 = 0; + } +} +// 67D7C0: using guessed type int InitObjFlag; + +//----- (00442DC1) -------------------------------------------------------- +void __fastcall AddBarrel(int i) +{ + int v1; // esi + int v2; // eax + int v3; // ecx + int v4; // eax + int v5; // ecx + int v6; // eax + bool v7; // sf + unsigned char v8; // of + + v1 = i; + object[i]._oVar1 = 0; + v2 = GetRndSeed(); + _LOBYTE(v3) = -107; + object[v1]._oRndSeed = v2; + v4 = random(v3, 10); + _LOBYTE(v5) = -107; + object[v1]._oVar2 = v4; + v6 = random(v5, 3); + v8 = __OFSUB__(object[v1]._oVar2, 8); + v7 = object[v1]._oVar2 - 8 < 0; + object[v1]._oVar3 = v6; + if ( !(v7 ^ v8) ) + object[v1]._oVar4 = PreSpawnSkeleton(); +} + +//----- (00442E0F) -------------------------------------------------------- +void __fastcall AddShrine(int i) +{ + int v1; // esi + signed int v2; // edi + signed int v3; // eax + int *v4; // ecx + bool v5; // zf + int v6; // eax + int v7[26]; // [esp+8h] [ebp-68h] + + v1 = i; + v2 = currlevel; + v3 = 0; + object[i]._oPreFlag = 1; + do + { + if ( v2 < (char)shrinemin[v3] || v2 > (char)shrinemax[v3] ) + { + v4 = &v7[v3]; + *v4 = 0; + } + else + { + v4 = &v7[v3]; + *v4 = 1; + } + if ( gbMaxPlayers == 1 ) + v5 = shrineavail[v3] == 2; + else + v5 = shrineavail[v3] == 1; + if ( v5 ) + *v4 = 0; + ++v3; + } + while ( v3 < 26 ); + do + { + _LOBYTE(v4) = -106; + v6 = random((int)v4, 26); + } + while ( !v7[v6] ); + _LOBYTE(v4) = -106; + object[v1]._oVar1 = v6; + if ( random((int)v4, 2) ) + { + object[v1]._oAnimFrame = 12; + object[v1]._oAnimLen = 22; + } +} +// 679660: using guessed type char gbMaxPlayers; +// 442E0F: using guessed type int var_68[26]; + +//----- (00442EB2) -------------------------------------------------------- +void __fastcall AddBookcase(int i) +{ + int v1; // esi + + v1 = i; + object[v1]._oRndSeed = GetRndSeed(); + object[v1]._oPreFlag = 1; +} + +//----- (00442ECF) -------------------------------------------------------- +void __fastcall AddPurifyingFountain(int i) +{ + char *v1; // eax + + v1 = &dObject[object[i]._ox][object[i]._oy]; + *(v1 - 1) = -1 - i; + *(v1 - 112) = -1 - i; + *(v1 - 113) = -1 - i; + object[i]._oRndSeed = GetRndSeed(); +} + +//----- (00442F08) -------------------------------------------------------- +void __fastcall AddArmorStand(int i) +{ + int v1; // eax + + if ( !armorFlag ) + { + v1 = i; + _LOBYTE(object[v1]._oSelFlag) = 0; + object[v1]._oAnimFlag = 2; + } + object[i]._oRndSeed = GetRndSeed(); +} +// 6AAA3C: using guessed type int armorFlag; + +//----- (00442F3A) -------------------------------------------------------- +void __fastcall AddDecap(int i) +{ + int v1; // esi + int v2; // eax + int v3; // ecx + int v4; // eax + + v1 = i; + v2 = GetRndSeed(); + _LOBYTE(v3) = -105; + object[v1]._oRndSeed = v2; + v4 = random(v3, 8); + object[v1]._oPreFlag = 1; + object[v1]._oAnimFrame = v4 + 1; +} + +//----- (00442F68) -------------------------------------------------------- +void __fastcall AddVilebook(int i) +{ + if ( setlevel ) + { + if ( setlvlnum == SL_VILEBETRAYER ) + object[i]._oAnimFrame = 4; + } +} +// 5CCB10: using guessed type char setlvlnum; +// 5CF31D: using guessed type char setlevel; + +//----- (00442F88) -------------------------------------------------------- +void __fastcall AddMagicCircle(int i) +{ + int v1; // esi + int v2; // eax + + v1 = i; + v2 = GetRndSeed(); + object[v1]._oVar6 = 0; + object[v1]._oRndSeed = v2; + object[v1]._oPreFlag = 1; + object[v1]._oVar5 = 1; +} + +//----- (00442FB1) -------------------------------------------------------- +void __fastcall AddBookstand(int i) +{ + object[i]._oRndSeed = GetRndSeed(); +} + +//----- (00442FC4) -------------------------------------------------------- +void __fastcall AddPedistal(int i) +{ + int v1; // ecx + int v2; // eax + int v3; // edx + int v4; // esi + int v5; // esi + int v6; // eax + + v1 = i; + v2 = setpc_x; + v3 = setpc_y; + v4 = setpc_w; + object[v1]._oVar1 = setpc_x; + v5 = v2 + v4; + v6 = setpc_h; + object[v1]._oVar3 = v5; + object[v1]._oVar2 = v3; + object[v1]._oVar4 = v3 + v6; +} +// 5CF330: using guessed type int setpc_h; +// 5CF334: using guessed type int setpc_w; + +//----- (00442FFC) -------------------------------------------------------- +void __fastcall AddStoryBook(int i) +{ + int v1; // esi + int v2; // ecx + int v3; // eax + unsigned char v4; // dl + int v5; // ecx + bool v6; // zf + int v7; // eax + + v1 = i; + SetRndSeed(glSeedTbl[16]); + _LOBYTE(v2) = 0; + v3 = random(v2, 3); + v4 = currlevel; + v5 = v1; + v6 = currlevel == 4; + object[v1]._oVar1 = v3; + if ( v6 ) + object[v5]._oVar2 = StoryText[v3][0]; + if ( v4 == 8 ) + object[v5]._oVar2 = StoryText[v3][1]; + if ( v4 == 12 ) + object[v5]._oVar2 = StoryText[v3][2]; + object[v5]._oVar3 = ((unsigned int)v4 >> 2) + 3 * v3 - 1; + v7 = 5 - 2 * v3; + object[v5]._oAnimFrame = v7; + object[v5]._oVar4 = v7 + 1; +} + +//----- (0044308E) -------------------------------------------------------- +void __fastcall AddWeaponRack(int i) +{ + int v1; // eax + + if ( !weaponFlag ) + { + v1 = i; + _LOBYTE(object[v1]._oSelFlag) = 0; + object[v1]._oAnimFlag = 2; + } + object[i]._oRndSeed = GetRndSeed(); +} +// 6AAA50: using guessed type int weaponFlag; + +//----- (004430C0) -------------------------------------------------------- +void __fastcall AddTorturedBody(int i) +{ + int v1; // esi + int v2; // eax + int v3; // ecx + int v4; // eax + + v1 = i; + v2 = GetRndSeed(); + _LOBYTE(v3) = 0; + object[v1]._oRndSeed = v2; + v4 = random(v3, 4); + object[v1]._oPreFlag = 1; + object[v1]._oAnimFrame = v4 + 1; +} + +//----- (004430EE) -------------------------------------------------------- +void __fastcall GetRndObjLoc(int randarea, int *xx, int *yy) +{ + int *v3; // ebx + int v4; // eax + int v5; // ecx + int v6; // eax + int v7; // esi + BOOL v8; // eax + int v9; // edi + int v10; // [esp+Ch] [ebp-Ch] + int v11; // [esp+10h] [ebp-8h] + int v12; // [esp+14h] [ebp-4h] + + v3 = xx; + v12 = randarea; + if ( randarea ) + { + v10 = 0; + while ( 1 ) + { +LABEL_3: + if ( ++v10 > 1000 && v12 > 1 ) + --v12; + _LOBYTE(randarea) = 0; + v4 = random(randarea, 112); + _LOBYTE(v5) = 0; + *v3 = v4; + v6 = random(v5, 112); + v7 = v6; + *yy = v6; + v8 = 0; + v11 = 0; + if ( v12 <= 0 ) + break; + while ( !v8 ) + { + v9 = 0; + do + { + if ( v8 ) + break; + v8 = RndLocOk(v11 + *v3, v7 + v9++) == 0; + } + while ( v9 < v12 ); + randarea = ++v11; + if ( v11 >= v12 ) + { + if ( v8 ) + goto LABEL_3; + return; + } + } + } + } +} + +//----- (00443178) -------------------------------------------------------- +void __cdecl AddMushPatch() +{ + char v0; // bl + int v1; // esi + int v2; // eax + int v3; // edx + int yy; // [esp+0h] [ebp-8h] + int xx; // [esp+4h] [ebp-4h] + + if ( nobjects < 127 ) + { + v0 = objectavail[0]; + GetRndObjLoc(5, &xx, &yy); + v1 = xx; + v2 = yy + 112 * xx; + v3 = yy + 2; + dObject[1][v2 + 1] = -1 - v0; + dObject[2][v2 + 1] = -1 - v0; + dObject[1][v2 + 2] = -1 - v0; + AddObject(94, v1 + 2, v3); + } +} + +//----- (004431D4) -------------------------------------------------------- +void __cdecl AddSlainHero() +{ + int xx; // [esp+0h] [ebp-8h] + int yy; // [esp+4h] [ebp-4h] + + GetRndObjLoc(5, &xx, &yy); + AddObject(96, xx + 2, yy + 2); +} + +//----- (004431FF) -------------------------------------------------------- +void __fastcall AddObject(int ot, int ox, int oy) +{ + int v3; // ebp + int v4; // esi + unsigned int v5; // eax + int v6; // ebx + int v7; // ebx + int v8; // eax + + v3 = ox; + v4 = ot; + if ( nobjects < 127 ) + { + v5 = 4 * nobjects; + v6 = objectavail[0]; + objectactive[v5 / 4] = objectavail[0]; + objectavail[0] = objectavail[v5 / 0xFFFFFFFC + 126]; + dObject[ox][oy] = v6 + 1; + SetupObject(v6, ox, oy, ot); + switch ( v4 ) + { + case OBJ_L1LIGHT: + case OBJ_SKFIRE: + case OBJ_CANDLE1: + case OBJ_CANDLE2: + case OBJ_BOOKCANDLE: + goto LABEL_31; + case OBJ_L1LDOOR: + case OBJ_L1RDOOR: + AddL1Door(v6, v3, oy, v4); + break; + case OBJ_CHEST1: + case OBJ_CHEST2: + case OBJ_CHEST3: + case OBJ_TCHEST1: + case OBJ_TCHEST2: + case OBJ_TCHEST3: + AddChest(v6, v4); + break; + case OBJ_BOOK2L: + AddVilebook(v6); + break; + case OBJ_BCROSS: + case OBJ_TBCROSS: + AddBookstand(v6); +LABEL_31: + AddObjLight(v6, 5); + break; + case OBJ_TNUDEM2: + AddTorturedBody(v6); + break; + case OBJ_BOOK2R: + AddSCambBook(v6); + break; + case OBJ_L2LDOOR: + case OBJ_L2RDOOR: + AddL2Door(v6, v3, oy, v4); + break; + case OBJ_TORCHL: + case OBJ_TORCHR: + case OBJ_TORCHL2: + case OBJ_TORCHR2: + AddObjLight(v6, 8); + break; + case OBJ_SARC: + AddSarc(v6); + break; + case OBJ_FLAMEHOLE: + AddFlameTrap(v6); + break; + case OBJ_FLAMELVR: + AddFlameLvr(v6); + break; + case OBJ_WATER: + object[v6]._oAnimFrame = 1; + break; + case OBJ_TRAPL: + case OBJ_TRAPR: + AddTrap(v6); + break; + case OBJ_BARREL: + case OBJ_BARRELEX: + AddBarrel(v6); + break; + case OBJ_SHRINEL: + case OBJ_SHRINER: + AddShrine(v6); + break; + case OBJ_SKELBOOK: + case OBJ_BOOKSTAND: + AddBookstand(v6); + break; + case OBJ_BOOKCASEL: + case OBJ_BOOKCASER: + AddBookcase(v6); + break; + case OBJ_BLOODFTN: + AddBookstand(v6); + break; + case OBJ_DECAP: + AddDecap(v6); + break; + case OBJ_PEDISTAL: + AddPedistal(v6); + break; + case OBJ_L3LDOOR: + case OBJ_L3RDOOR: + AddL3Door(v6, v3, oy, v4); + break; + case OBJ_PURIFYINGFTN: + AddPurifyingFountain(v6); + break; + case OBJ_ARMORSTAND: + case OBJ_WARARMOR: + AddArmorStand(v6); + break; + case OBJ_GOATSHRINE: + AddBookstand(v6); + break; + case OBJ_CAULDRON: + AddBookstand(v6); + break; + case OBJ_MURKYFTN: + AddPurifyingFountain(v6); + break; + case OBJ_TEARFTN: + AddBookstand(v6); + break; + case OBJ_MCIRCLE1: + case OBJ_MCIRCLE2: + AddMagicCircle(v6); + break; + case OBJ_STORYBOOK: + AddStoryBook(v6); + break; + case OBJ_STORYCANDLE: + AddObjLight(v6, 3); + break; + case OBJ_WARWEAP: + case OBJ_WEAPONRACK: + AddWeaponRack(v6); + break; + default: + break; + } + v7 = v6; + v8 = object[v7]._oAnimWidth - 64; + ++nobjects; + object[v7]._oAnimWidth2 = v8 >> 1; + } +} + +//----- (004434CB) -------------------------------------------------------- +void __fastcall Obj_Light(int i, int lr) +{ + int v2; // esi + int v3; // ebx + int *v4; // edi + int v5; // ST18_4 + int v6; // eax + int r; // [esp+Ch] [ebp-14h] + int x; // [esp+14h] [ebp-Ch] + int y; // [esp+18h] [ebp-8h] + signed int v10; // [esp+1Ch] [ebp-4h] + + v2 = i; + r = lr; + if ( object[i]._oVar1 != -1 ) + { + v10 = 0; + x = object[v2]._ox; + v3 = lr + 10; + y = object[v2]._oy; + if ( lightflag ) + { +LABEL_15: + if ( object[v2]._oVar1 == 1 ) + AddUnLight(object[v2]._olid); + object[v2]._oVar1 = 0; + } + else + { + v4 = &plr[0].plrlevel; + while ( !v10 ) + { + if ( *((_BYTE *)v4 - 23) ) + { + if ( currlevel == *v4 ) + { + v5 = abs(v4[1] - x); + v6 = abs(v4[2] - y); + if ( v5 < v3 && v6 < v3 ) + v10 = 1; + } + } + v4 += 5430; + if ( (signed int)v4 >= (signed int)&plr_msgs[0].player ) + { + if ( !v10 ) + goto LABEL_15; + break; + } + } + if ( !object[v2]._oVar1 ) + object[v2]._olid = AddLight(x, y, r); + object[v2]._oVar1 = 1; + } + } +} +// 646A28: using guessed type int lightflag; + +//----- (004435B5) -------------------------------------------------------- +void __fastcall Obj_Circle(int i) +{ + int v1; // ecx + int v2; // edx + int v3; // esi + int v4; // eax + int v5; // ST1C_4 + int v6; // edx + int v7; // eax + + v1 = i; + v2 = object[v1]._ox; + v3 = object[v1]._oy; + if ( plr[myplr].WorldX != v2 || plr[myplr].WorldY != v3 ) + { + v7 = object[v1]._otype; + if ( v7 == OBJ_MCIRCLE1 ) + object[v1]._oAnimFrame = 1; + if ( v7 == OBJ_MCIRCLE2 ) + object[v1]._oAnimFrame = 3; + object[v1]._oVar6 = 0; + } + else + { + v4 = object[v1]._otype; + if ( v4 == OBJ_MCIRCLE1 ) + object[v1]._oAnimFrame = 2; + if ( v4 == OBJ_MCIRCLE2 ) + object[v1]._oAnimFrame = 4; + if ( v2 == 45 ) + { + if ( v3 == 47 ) + { + object[v1]._oVar6 = 2; + return; + } + } + else if ( v2 == 26 && v3 == 46 ) + { + object[v1]._oVar6 = 1; + return; + } + object[v1]._oVar6 = 0; + if ( v2 == 35 && v3 == 36 && object[v1]._oVar5 == 3 ) + { + v5 = object[v1]._oVar4; + v6 = object[v1]._oVar2; + object[v1]._oVar6 = 4; + ObjChangeMapResync(object[v1]._oVar1, v6, object[v1]._oVar3, v5); + if ( quests[15]._qactive == 2 ) + quests[15]._qvar1 = 4; + AddMissile(plr[myplr].WorldX, plr[myplr].WorldY, 35, 46, plr[myplr]._pdir, 3, 0, myplr, 0, 0); + track_mouse_stance(0); + sgbMouseDown = 0; + ReleaseCapture(); + ClrPlrPath(myplr); + StartStand(myplr, 0); + } + } +} +// 525748: using guessed type char sgbMouseDown; + +//----- (00443727) -------------------------------------------------------- +void __fastcall Obj_StopAnim(int i) +{ + int v1; // ecx + + v1 = i; + if ( object[v1]._oAnimFrame == object[v1]._oAnimLen ) + { + object[v1]._oAnimCnt = 0; + object[v1]._oAnimDelay = 1000; + } +} + +//----- (0044374A) -------------------------------------------------------- +void __fastcall Obj_Door(int i) +{ + int v1; // ecx + int v2; // edx + int v3; // eax + + v1 = i; + if ( object[v1]._oVar4 ) + { + v2 = object[v1]._oy; + v3 = object[v1]._ox; + _LOBYTE(object[v1]._oSelFlag) = 2; + object[v1]._oMissFlag = 1; + object[v1]._oVar4 = ((dItem[v3][v2] == 0 + && dDead[v3][v2] == 0 + && dPlayer[v3][v2] == 0 + && dMonster[0][v3 * 112 + v2] == 0) == 0) + + 1; + } + else + { + object[v1]._oMissFlag = 0; + _LOBYTE(object[v1]._oSelFlag) = 3; + } +} + +//----- (004437CD) -------------------------------------------------------- +void __fastcall Obj_Sarc(int i) +{ + int v1; // ecx + + v1 = i; + if ( object[v1]._oAnimFrame == object[v1]._oAnimLen ) + object[v1]._oAnimFlag = 0; +} + +//----- (004437E6) -------------------------------------------------------- +void __fastcall ActivateTrapLine(int ttype, int tid) +{ + int v2; // edi + int i; // ebp + int v4; // esi + int v5; // edx + int v6; // ecx + int v7; // [esp+8h] [ebp-4h] + + v2 = 0; + v7 = tid; + for ( i = ttype; v2 < nobjects; ++v2 ) + { + v4 = objectactive[v2]; + if ( object[v4]._otype == i && object[v4]._oVar1 == v7 ) + { + v5 = object[v4]._oy; + v6 = object[v4]._ox; + object[v4]._oVar4 = 1; + object[v4]._oAnimFlag = 1; + object[v4]._oAnimDelay = 1; + object[v4]._olid = AddLight(v6, v5, 1); + } + } +} + +//----- (00443855) -------------------------------------------------------- +void __fastcall Obj_FlameTrap(int i) +{ + int v1; // ecx + int *v2; // esi + int v3; // eax + int v4; // ecx + bool v5; // zf + bool v6; // sf + unsigned char v7; // of + int v8; // edx + int v9; // eax + signed int v10; // esi + int v11; // eax + _BYTE *v12; // edx + _DWORD *v13; // eax + int v14; // eax + _BYTE *v15; // edx + _DWORD *v16; // eax + int *v17; // eax + + v1 = i; + if ( object[v1]._oVar2 ) + { + v2 = &object[v1]._oVar4; + if ( !object[v1]._oVar4 ) + return; + v3 = --object[v1]._oAnimFrame; + if ( v3 == 1 ) + { + v4 = object[v1]._olid; + *v2 = 0; + AddUnLight(v4); + return; + } + v7 = __OFSUB__(v3, 4); + v5 = v3 == 4; + v6 = v3 - 4 < 0; + goto LABEL_24; + } + if ( object[v1]._oVar4 ) + { + v17 = &object[v1]._oAnimFrame; + if ( object[v1]._oAnimFrame == object[v1]._oAnimLen ) + *v17 = 11; + v3 = *v17; + v7 = __OFSUB__(v3, 5); + v5 = v3 == 5; + v6 = v3 - 5 < 0; +LABEL_24: + if ( (unsigned char)(v6 ^ v7) | v5 ) + ChangeLightRadius(object[v1]._olid, v3); + return; + } + v8 = object[v1]._oy; + v9 = object[v1]._ox; + v10 = 5; + if ( object[v1]._oVar3 == 2 ) + { + v11 = v8 + 112 * (v9 - 2); + v12 = (unsigned char *)dPlayer + v11; + v13 = (_DWORD *)((char *)dMonster + 4 * v11); + do + { + if ( *v12 || *v13 ) + object[v1]._oVar4 = 1; + v13 += 112; + v12 += 112; + --v10; + } + while ( v10 ); + } + else + { + v14 = v8 - 2 + 112 * v9; + v15 = (unsigned char *)dPlayer + v14; + v16 = (_DWORD *)((char *)dMonster + 4 * v14); + do + { + if ( *v15 || *v16 ) + object[v1]._oVar4 = 1; + ++v16; + ++v15; + --v10; + } + while ( v10 ); + } + if ( object[v1]._oVar4 ) + ActivateTrapLine(object[v1]._otype, object[v1]._oVar1); +} + +//----- (00443966) -------------------------------------------------------- +void __fastcall Obj_Trap(int i) +{ + int edi1; // edi + int v2; // esi + int v3; // eax + int v4; // eax + int v5; // ebx + int v6; // ecx + int v7; // eax + int v8; // ecx + char *j; // edx + int v10; // eax + int v11; // [esp+8h] [ebp-1Ch] + int v12; // [esp+10h] [ebp-14h] + int sx; // [esp+14h] [ebp-10h] + int sy; // [esp+18h] [ebp-Ch] + int v15; // [esp+1Ch] [ebp-8h] + int v1; // [esp+20h] [ebp-4h] + + edi1 = i; + if ( object[i]._oVar4 ) + return; + v2 = dObject[object[edi1]._oVar1][object[edi1]._oVar2] - 1; + v3 = object[v2]._otype; + if ( v3 <= OBJ_L2RDOOR ) + { + if ( v3 < OBJ_L2LDOOR ) + { + if ( v3 <= 0 ) + return; + if ( v3 > OBJ_L1RDOOR ) + { + if ( v3 <= OBJ_SKFIRE || v3 > OBJ_CHEST3 && v3 != OBJ_SWITCHSKL ) + return; + goto LABEL_9; + } + } +LABEL_17: + if ( !object[v2]._oVar4 ) + return; + goto LABEL_10; + } + if ( v3 != OBJ_SARC ) + { + if ( v3 <= OBJ_PEDISTAL || v3 > OBJ_L3RDOOR ) + return; + goto LABEL_17; + } +LABEL_9: + if ( _LOBYTE(object[v2]._oSelFlag) ) + return; +LABEL_10: + v4 = object[edi1]._ox; + object[edi1]._oVar4 = 1; + v5 = object[v2]._oy; + v6 = object[v2]._ox; + sx = v4; + sy = object[edi1]._oy; + v7 = v5 - 1; + v1 = object[v2]._ox; + v11 = v5 + 1; + if ( (unsigned char)(__OFSUB__(v5 - 1, v5 + 1) ^ 1) | (v5 - 1 == v5 + 1) ) + { + v12 = v6 - 1; + v15 = v6 + 1; + do + { + v8 = v12; + if ( v12 <= v15 ) + { + for ( j = &dPlayer[v12][v7]; ; j += 112 ) + { + if ( *j ) + { + v1 = v8; + v5 = v7; + } + if ( ++v8 > v15 ) + break; + } + } + ++v7; + } + while ( v7 <= v11 ); + v6 = v1; + } + if ( !deltaload ) + { + v10 = GetDirection(sx, sy, v6, v5); + AddMissile(sx, sy, v1, v5, v10, object[edi1]._oVar3, 1, -1, 0, 0); + PlaySfxLoc(IS_TRAP, object[v2]._ox, object[v2]._oy); + } + object[v2]._oTrapFlag = 0; +} +// 676190: using guessed type int deltaload; + +//----- (00443AD5) -------------------------------------------------------- +void __fastcall Obj_BCrossDamage(int i) +{ + int v1; // esi + bool v2; // zf + int v3; // ecx + int v4; // edx + char v5; // al + int v6; // ecx + int v7; // [esp+4h] [ebp-18h] + int v8; // [esp+8h] [ebp-14h] + int v9; // [esp+Ch] [ebp-10h] + int v10; // [esp+10h] [ebp-Ch] + int v11; // [esp+14h] [ebp-8h] + int v12; // [esp+18h] [ebp-4h] + + v1 = myplr; + v12 = i; + v2 = plr[myplr]._pmode == PM_DEATH; + v8 = 6; + v9 = PM_DEATH; + v10 = 10; + v11 = 12; + if ( !v2 ) + { + v3 = plr[v1]._pFireResist; + if ( v3 > 0 ) + *(&v7 + (unsigned char)leveltype) -= v3 * *(&v7 + (unsigned char)leveltype) / 100; + if ( plr[v1].WorldX == object[v12]._ox && plr[v1].WorldY == object[v12]._oy - 1 ) + { + v4 = *(&v7 + (unsigned char)leveltype); + plr[v1]._pHitPoints -= v4; + plr[v1]._pHPBase -= v4; + if ( (signed int)(plr[v1]._pHitPoints & 0xFFFFFFC0) <= 0 ) + { + SyncPlrKill(myplr, 0); +LABEL_15: + drawhpflag = 1; + return; + } + v5 = plr[v1]._pClass; + if ( v5 ) + { + if ( v5 == 1 ) + { + v6 = PS_ROGUE68; + } + else + { + if ( v5 != 2 ) + goto LABEL_15; + v6 = PS_MAGE68; + } + } + else + { + v6 = PS_WARR68; + } + PlaySfxLoc(v6, plr[v1].WorldX, plr[v1].WorldY); + goto LABEL_15; + } + } +} +// 5BB1ED: using guessed type char leveltype; + +//----- (00443BD2) -------------------------------------------------------- +void __cdecl ProcessObjects() +{ + int v0; // ebx + int v1; // edi + int v2; // esi + int v3; // eax + int *v4; // eax + int *v5; // eax + int v6; // edx + + v0 = 0; + if ( nobjects > 0 ) + { + while ( 1 ) + { + v1 = objectactive[v0]; + v2 = objectactive[v0]; + v3 = object[v2]._otype; + if ( v3 <= OBJ_SARC ) + break; + if ( v3 <= OBJ_L3RDOOR ) + { + if ( v3 >= OBJ_L3LDOOR ) + goto LABEL_32; + if ( v3 == OBJ_FLAMEHOLE ) + { + Obj_FlameTrap(v1); + goto LABEL_40; + } + if ( v3 <= OBJ_BOOKLVR ) + goto LABEL_40; + if ( v3 <= OBJ_TRAPR ) + { + Obj_Trap(v1); + goto LABEL_40; + } + if ( v3 <= OBJ_WEAPRACK ) + goto LABEL_40; + if ( v3 <= OBJ_SHRINER ) + { +LABEL_29: + Obj_StopAnim(v1); + goto LABEL_40; + } + if ( v3 != OBJ_BOOKCANDLE ) + goto LABEL_40; +LABEL_28: + Obj_Light(v1, 5); + goto LABEL_40; + } + if ( v3 < OBJ_MCIRCLE1 ) + goto LABEL_40; + if ( v3 <= OBJ_MCIRCLE2 ) + { + Obj_Circle(v1); + } + else + { + if ( v3 != OBJ_STORYCANDLE ) + { + if ( v3 != OBJ_TBCROSS ) + goto LABEL_40; + goto LABEL_37; + } + Obj_Light(v1, 3); + } +LABEL_40: + if ( object[v2]._oAnimFlag ) + { + v4 = &object[v2]._oAnimCnt; + ++*v4; + if ( object[v2]._oAnimCnt >= object[v2]._oAnimDelay ) + { + *v4 = 0; + v5 = &object[v2]._oAnimFrame; + ++*v5; + if ( object[v2]._oAnimFrame > object[v2]._oAnimLen ) + *v5 = 1; + } + } + if ( ++v0 >= nobjects ) + goto LABEL_45; + } + if ( v3 == OBJ_SARC ) + { + Obj_Sarc(v1); + goto LABEL_40; + } + if ( v3 > OBJ_CRUX3 ) + { + if ( v3 != OBJ_BCROSS ) + { + if ( v3 <= OBJ_BOOK2R ) + goto LABEL_40; + if ( v3 > OBJ_L2RDOOR ) + { + if ( v3 <= OBJ_TORCHR2 ) + Obj_Light(v1, 8); + goto LABEL_40; + } +LABEL_32: + Obj_Door(v1); + goto LABEL_40; + } +LABEL_37: + Obj_Light(v1, 10); + Obj_BCrossDamage(v1); + goto LABEL_40; + } + if ( v3 >= OBJ_CRUX1 ) + goto LABEL_29; + if ( !v3 ) + { + Obj_Light(v1, 10); + goto LABEL_40; + } + if ( v3 <= 0 ) + goto LABEL_40; + if ( v3 <= OBJ_L1RDOOR ) + goto LABEL_32; + if ( v3 != OBJ_SKFIRE && v3 != OBJ_CANDLE2 ) + goto LABEL_40; + goto LABEL_28; + } +LABEL_45: + v6 = 0; + while ( v6 < nobjects ) + { + if ( object[objectactive[v6]]._oDelFlag ) + { + DeleteObject(objectactive[v6], v6); + v6 = 0; + } + else + { + ++v6; + } + } +} + +//----- (00443D69) -------------------------------------------------------- +void __fastcall ObjSetMicro(int dx, int dy, int pn) +{ + int v3; // esi + char *v4; // eax + int v5; // edx + signed int v6; // ecx + int v7; // esi + signed int v8; // ecx + + dPiece[0][dy + 112 * dx] = pn; + v3 = pn - 1; + v4 = (char *)dpiece_defs_map_1 + 32 * gendung_41927A(dx, dy); + if ( leveltype == 4 ) + { + v7 = *(_DWORD *)&dpiece_defs[0].blocks + 32 * v3; + v8 = 0; + do + { + *(_WORD *)&v4[2 * v8] = *(_WORD *)(v7 + 2 * ((v8 & 1) - (v8 & 0xE)) + 28); + ++v8; + } + while ( v8 < 16 ); + } + else + { + v5 = *(_DWORD *)&dpiece_defs[0].blocks + 20 * v3; + v6 = 0; + do + { + *(_WORD *)&v4[2 * v6] = *(_WORD *)(v5 + 2 * ((v6 & 1) - (v6 & 0xE)) + 16); + ++v6; + } + while ( v6 < 10 ); + } +} +// 5BB1ED: using guessed type char leveltype; + +//----- (00443DEA) -------------------------------------------------------- +void __fastcall objects_set_door_piece(int x, int y) +{ + int v2; // edi + int v3; // ST10_4 + int v4; // ST18_4 + short v5; // ST14_2 + short v6; // ST0C_2 + + v2 = y; + v3 = x; + v4 = dPiece[0][y + 112 * x] - 1; + v5 = *(_WORD *)(20 * (unsigned short)v4 + *(_DWORD *)&dpiece_defs[0].blocks + 16); + v6 = *(_WORD *)(20 * (unsigned short)v4 + *(_DWORD *)&dpiece_defs[0].blocks + 18); + dpiece_defs_map_1[0][0][16 * gendung_41927A(x, y)] = v5; + dpiece_defs_map_1[0][0][16 * gendung_41927A(v3, v2) + 1] = v6; +} + +//----- (00443E62) -------------------------------------------------------- +void __fastcall ObjSetMini(int x, int y, int v) +{ + unsigned short *v3; // esi + unsigned short v4; // ax + int v5; // eax + int pn; // ST1C_4 + int v7; // ST18_4 + int v8; // ST14_4 + int v9; // ST10_4 + int v10; // esi + int v11; // edi + + v3 = (unsigned short *)((char *)pMegaTiles + 8 * ((unsigned short)v - 1)); + v4 = *v3; + ++v3; + v5 = v4 + 1; + pn = v5; + _LOWORD(v5) = *v3; + ++v3; + v7 = ++v5; + _LOWORD(v5) = *v3; + v8 = ++v5; + _LOWORD(v5) = v3[1]; + v9 = v5 + 1; + v10 = 2 * x + 16; + v11 = 2 * y + 16; + ObjSetMicro(v10, v11, pn); + ObjSetMicro(v10 + 1, v11++, v7); + ObjSetMicro(v10, v11, v8); + ObjSetMicro(v10 + 1, v11, v9); +} + +//----- (00443EDA) -------------------------------------------------------- +void __fastcall ObjL1Special(int x1, int y1, int x2, int y2) +{ + int i; // ebx + int v5; // edx + _BYTE *v6; // eax + int *v7; // edi + int v8; // edx + int v9; // esi + + for ( i = y1; i <= y2; ++i ) + { + if ( x1 <= x2 ) + { + v5 = 112 * x1 + i; + v6 = (unsigned char *)dArch + v5; + v7 = (int *)((char *)dPiece + 4 * v5); + v8 = x2 - x1 + 1; + do + { + v9 = *v7; + *v6 = 0; + if ( v9 == 12 ) + *v6 = 1; + if ( v9 == 11 ) + *v6 = 2; + if ( v9 == 71 ) + *v6 = 1; + if ( v9 == 259 ) + *v6 = 5; + if ( v9 == 249 ) + *v6 = 2; + if ( v9 == 325 ) + *v6 = 2; + if ( v9 == 321 ) + *v6 = 1; + if ( v9 == 255 ) + *v6 = 4; + if ( v9 == 211 ) + *v6 = 1; + if ( v9 == 344 ) + *v6 = 2; + if ( v9 == 341 ) + *v6 = 1; + if ( v9 == 331 ) + *v6 = 2; + if ( v9 == 418 ) + *v6 = 1; + if ( v9 == 421 ) + *v6 = 2; + v7 += 112; + v6 += 112; + --v8; + } + while ( v8 ); + } + } +} + +//----- (00443FC6) -------------------------------------------------------- +void __fastcall ObjL2Special(int x1, int y1, int x2, int y2) +{ + int v4; // edi + int v5; // esi + _BYTE *v6; // eax + int *v7; // ebx + int v8; // esi + int v9; // edx + int i; // edi + int v11; // eax + char *v12; // edx + int *v13; // esi + int v14; // eax + int v15; // ebx + int v16; // [esp+Ch] [ebp-4h] + + v4 = y1; + v16 = y1; + if ( y1 <= y2 ) + { + do + { + if ( x1 <= x2 ) + { + v5 = 112 * x1 + v4; + v6 = (unsigned char *)dArch + v5; + v7 = (int *)((char *)dPiece + 4 * v5); + v8 = x2 - x1 + 1; + do + { + v9 = *v7; + *v6 = 0; + if ( v9 == 541 ) + *v6 = 5; + if ( v9 == 178 ) + *v6 = 5; + if ( v9 == 551 ) + *v6 = 5; + if ( v9 == 542 ) + *v6 = 6; + if ( v9 == 553 ) + *v6 = 6; + if ( v9 == 13 ) + *v6 = 5; + if ( v9 == 17 ) + *v6 = 6; + v7 += 112; + v6 += 112; + --v8; + } + while ( v8 ); + } + ++v4; + } + while ( v4 <= y2 ); + for ( i = v16; i <= y2; ++i ) + { + if ( x1 <= x2 ) + { + v11 = i + 112 * x1; + v12 = &dArch[0][v11 + 2]; + v13 = (int *)((char *)dPiece + 4 * v11); + v14 = x2 - x1 + 1; + do + { + v15 = *v13; + if ( *v13 == 132 ) + { + *(v12 - 1) = 2; + *v12 = 1; + } + if ( v15 == 135 || v15 == 139 ) + { + v12[110] = 3; + v12[222] = 4; + } + v13 += 112; + v12 += 112; + --v14; + } + while ( v14 ); + } + } + } +} + +//----- (004440C2) -------------------------------------------------------- +void __fastcall DoorSet(int oi, int dx, int dy) +{ + int v3; // esi + int v4; // ebp + int v5; // ebx + ObjectStruct *v6; // ebp + + v3 = dx; + v4 = oi; + v5 = dPiece[0][dy + 112 * dx]; + if ( v5 == 43 ) + ObjSetMicro(dx, dy, 392); + if ( v5 == 45 ) + ObjSetMicro(v3, dy, 394); + if ( v5 != 50 ) + goto LABEL_10; + v6 = &object[v4]; + if ( v6->_otype == OBJ_L1LDOOR ) + ObjSetMicro(v3, dy, 411); + if ( v6->_otype == OBJ_L1RDOOR ) + { + ObjSetMicro(v3, dy, 412); +LABEL_10: + if ( v5 == 54 ) + ObjSetMicro(v3, dy, 397); + if ( v5 == 55 ) + ObjSetMicro(v3, dy, 398); + if ( v5 == 61 ) + ObjSetMicro(v3, dy, 399); + if ( v5 == 67 ) + ObjSetMicro(v3, dy, 400); + if ( v5 == 68 ) + ObjSetMicro(v3, dy, 401); + if ( v5 == 69 ) + ObjSetMicro(v3, dy, 403); + if ( v5 == 70 ) + ObjSetMicro(v3, dy, 404); + if ( v5 == 72 ) + ObjSetMicro(v3, dy, 406); + if ( v5 == 212 ) + ObjSetMicro(v3, dy, 407); + if ( v5 == 354 ) + ObjSetMicro(v3, dy, 409); + if ( v5 == 355 ) + ObjSetMicro(v3, dy, 410); + if ( v5 == 411 ) + ObjSetMicro(v3, dy, 396); + if ( v5 == 412 ) + ObjSetMicro(v3, dy, 396); + } +} + +//----- (00444246) -------------------------------------------------------- +void __cdecl RedoPlayerVision() +{ + int *v0; // esi + + v0 = &plr[0].plrlevel; + do + { + if ( *((_BYTE *)v0 - 23) ) + { + if ( currlevel == *v0 ) + ChangeVisionXY(v0[27], v0[1], v0[2]); + } + v0 += 5430; + } + while ( (signed int)v0 < (signed int)&plr_msgs[0].player ); +} + +//----- (0044427B) -------------------------------------------------------- +void __fastcall OperateL1RDoor(int pnum, int oi, unsigned char sendflag) +{ + int v3; // esi + int v4; // eax + int v5; // ebx + int v6; // edi + int v7; // ST04_4 + int v8; // [esp+Ch] [ebp-Ch] + int v9; // [esp+10h] [ebp-8h] + int param1; // [esp+14h] [ebp-4h] + + v3 = oi; + param1 = oi; + v9 = pnum; + v4 = object[oi]._oVar4; + if ( v4 != 2 ) + { + v5 = object[v3]._ox; + v6 = object[v3]._oy; + if ( v4 ) + { + if ( !deltaload ) + PlaySfxLoc(IS_DOORCLOS, v5, object[v3]._oy); + v8 = v6 + 112 * v5; + if ( dDead[0][v8] != 0 || dMonster[0][v8] != 0 || dItem[0][v8] != 0 ) + { + object[v3]._oVar4 = 2; + return; + } + if ( v9 == myplr && sendflag ) + NetSendCmdParam1(1u, CMD_CLOSEDOOR, param1); + v7 = object[v3]._oVar1; + object[v3]._oVar4 = 0; + _LOBYTE(object[v3]._oSelFlag) = 3; + ObjSetMicro(v5, v6, v7); + if ( object[v3]._oVar2 == 50 ) + { + if ( *(_DWORD *)&dflags[28][4 * v8 + 32] == 396 ) + ObjSetMicro(v5 - 1, v6, 411); + else + ObjSetMicro(v5 - 1, v6, 50); + } + else + { + ObjSetMicro(v5 - 1, v6, object[v3]._oVar2); + } + object[v3]._oAnimFrame -= 2; + object[v3]._oPreFlag = 0; + } + else + { + if ( pnum == myplr && sendflag ) + NetSendCmdParam1(1u, CMD_OPENDOOR, oi); + if ( !deltaload ) + PlaySfxLoc(IS_DOOROPEN, object[v3]._ox, object[v3]._oy); + ObjSetMicro(v5, v6, 395); + dArch[v5][v6] = 8; + objects_set_door_piece(v5, v6 - 1); + object[v3]._oAnimFrame += 2; + object[v3]._oPreFlag = 1; + DoorSet(param1, v5 - 1, v6); + object[v3]._oVar4 = 1; + _LOBYTE(object[v3]._oSelFlag) = 2; + } + RedoPlayerVision(); + return; + } + if ( !deltaload ) + PlaySfxLoc(IS_DOORCLOS, object[v3]._ox, object[v3]._oy); +} +// 676190: using guessed type int deltaload; + +//----- (0044443C) -------------------------------------------------------- +void __fastcall OperateL1LDoor(int pnum, int oi, unsigned char sendflag) +{ + int v3; // esi + int v4; // eax + int v5; // ebx + int v6; // edi + int v7; // ST04_4 + int v8; // [esp+Ch] [ebp-Ch] + int v9; // [esp+10h] [ebp-8h] + int param1; // [esp+14h] [ebp-4h] + + v3 = oi; + param1 = oi; + v9 = pnum; + v4 = object[oi]._oVar4; + if ( v4 != 2 ) + { + v5 = object[v3]._ox; + v6 = object[v3]._oy; + if ( v4 ) + { + if ( !deltaload ) + PlaySfxLoc(IS_DOORCLOS, v5, object[v3]._oy); + v8 = v6 + 112 * v5; + if ( dDead[v5][v6] != 0 || dMonster[0][v8] != 0 || dItem[v5][v6] != 0 ) + { + object[v3]._oVar4 = 2; + return; + } + if ( v9 == myplr && sendflag ) + NetSendCmdParam1(1u, CMD_CLOSEDOOR, param1); + v7 = object[v3]._oVar1; + object[v3]._oVar4 = 0; + _LOBYTE(object[v3]._oSelFlag) = 3; + ObjSetMicro(v5, v6, v7); + if ( object[v3]._oVar2 == 50 ) + { + if ( *(_DWORD *)&dflags[39][v8 * 4 + 36] == 396 ) + ObjSetMicro(v5, v6 - 1, 412); + else + ObjSetMicro(v5, v6 - 1, 50); + } + else + { + ObjSetMicro(v5, v6 - 1, object[v3]._oVar2); + } + object[v3]._oAnimFrame -= 2; + object[v3]._oPreFlag = 0; + } + else + { + if ( pnum == myplr && sendflag ) + NetSendCmdParam1(1u, CMD_OPENDOOR, oi); + if ( !deltaload ) + PlaySfxLoc(IS_DOOROPEN, object[v3]._ox, object[v3]._oy); + if ( object[v3]._oVar1 == 214 ) + ObjSetMicro(v5, v6, 408); + else + ObjSetMicro(v5, v6, 393); + dArch[v5][v6] = 7; + objects_set_door_piece(v5 - 1, v6); + object[v3]._oAnimFrame += 2; + object[v3]._oPreFlag = 1; + DoorSet(param1, v5, v6 - 1); + object[v3]._oVar4 = 1; + _LOBYTE(object[v3]._oSelFlag) = 2; + } + RedoPlayerVision(); + return; + } + if ( !deltaload ) + PlaySfxLoc(IS_DOORCLOS, object[v3]._ox, object[v3]._oy); +} +// 676190: using guessed type int deltaload; + +//----- (00444613) -------------------------------------------------------- +void __fastcall OperateL2RDoor(int pnum, int oi, unsigned char sendflag) +{ + int v3; // esi + int v4; // eax + int v5; // ebx + short param1; // [esp+Ch] [ebp-Ch] + int v7; // [esp+10h] [ebp-8h] + int v8; // [esp+14h] [ebp-4h] + + v3 = oi; + param1 = oi; + v7 = pnum; + v4 = object[oi]._oVar4; + if ( v4 != 2 ) + { + v5 = object[v3]._oy; + v8 = object[v3]._ox; + if ( v4 ) + { + if ( !deltaload ) + PlaySfxLoc(IS_DOORCLOS, object[v3]._ox, v5); + if ( dDead[v8][v5] != 0 || dMonster[0][v5 + 112 * v8] != 0 || dItem[v8][v5] != 0 ) + { + object[v3]._oVar4 = 2; + return; + } + if ( v7 == myplr && sendflag ) + NetSendCmdParam1(1u, CMD_CLOSEDOOR, param1); + object[v3]._oVar4 = 0; + _LOBYTE(object[v3]._oSelFlag) = 3; + ObjSetMicro(v8, v5, 540); + object[v3]._oAnimFrame -= 2; + object[v3]._oPreFlag = 0; + } + else + { + if ( pnum == myplr && sendflag ) + NetSendCmdParam1(1u, CMD_OPENDOOR, oi); + if ( !deltaload ) + PlaySfxLoc(IS_DOOROPEN, object[v3]._ox, object[v3]._oy); + ObjSetMicro(v8, v5, 17); + object[v3]._oAnimFrame += 2; + object[v3]._oPreFlag = 1; + object[v3]._oVar4 = 1; + _LOBYTE(object[v3]._oSelFlag) = 2; + } + RedoPlayerVision(); + return; + } + if ( !deltaload ) + PlaySfxLoc(IS_DOORCLOS, object[v3]._ox, object[v3]._oy); +} +// 676190: using guessed type int deltaload; + +//----- (00444775) -------------------------------------------------------- +void __fastcall OperateL2LDoor(int pnum, int oi, unsigned char sendflag) +{ + int v3; // esi + int v4; // eax + int v5; // ebx + short param1; // [esp+Ch] [ebp-Ch] + int v7; // [esp+10h] [ebp-8h] + int v8; // [esp+14h] [ebp-4h] + + v3 = oi; + param1 = oi; + v7 = pnum; + v4 = object[oi]._oVar4; + if ( v4 != 2 ) + { + v5 = object[v3]._oy; + v8 = object[v3]._ox; + if ( v4 ) + { + if ( !deltaload ) + PlaySfxLoc(IS_DOORCLOS, object[v3]._ox, v5); + if ( dDead[v8][v5] != 0 || dMonster[0][v5 + 112 * v8] != 0 || dItem[v8][v5] != 0 ) + { + object[v3]._oVar4 = 2; + return; + } + if ( v7 == myplr && sendflag ) + NetSendCmdParam1(1u, CMD_CLOSEDOOR, param1); + object[v3]._oVar4 = 0; + _LOBYTE(object[v3]._oSelFlag) = 3; + ObjSetMicro(v8, v5, 538); + object[v3]._oAnimFrame -= 2; + object[v3]._oPreFlag = 0; + } + else + { + if ( pnum == myplr && sendflag ) + NetSendCmdParam1(1u, CMD_OPENDOOR, oi); + if ( !deltaload ) + PlaySfxLoc(IS_DOOROPEN, object[v3]._ox, object[v3]._oy); + ObjSetMicro(v8, v5, 13); + object[v3]._oAnimFrame += 2; + object[v3]._oPreFlag = 1; + object[v3]._oVar4 = 1; + _LOBYTE(object[v3]._oSelFlag) = 2; + } + RedoPlayerVision(); + return; + } + if ( !deltaload ) + PlaySfxLoc(IS_DOORCLOS, object[v3]._ox, object[v3]._oy); +} +// 676190: using guessed type int deltaload; + +//----- (004448D7) -------------------------------------------------------- +void __fastcall OperateL3RDoor(int pnum, int oi, unsigned char sendflag) +{ + int v3; // esi + int v4; // eax + int v5; // ebx + short param1; // [esp+Ch] [ebp-Ch] + int v7; // [esp+10h] [ebp-8h] + int v8; // [esp+14h] [ebp-4h] + + v3 = oi; + param1 = oi; + v7 = pnum; + v4 = object[oi]._oVar4; + if ( v4 != 2 ) + { + v5 = object[v3]._oy; + v8 = object[v3]._ox; + if ( v4 ) + { + if ( !deltaload ) + PlaySfxLoc(IS_DOORCLOS, object[v3]._ox, v5); + if ( dDead[v8][v5] != 0 || dMonster[0][v5 + 112 * v8] != 0 || dItem[v8][v5] != 0 ) + { + object[v3]._oVar4 = 2; + return; + } + if ( v7 == myplr && sendflag ) + NetSendCmdParam1(1u, CMD_CLOSEDOOR, param1); + object[v3]._oVar4 = 0; + _LOBYTE(object[v3]._oSelFlag) = 3; + ObjSetMicro(v8, v5, 534); + object[v3]._oAnimFrame -= 2; + object[v3]._oPreFlag = 0; + } + else + { + if ( pnum == myplr && sendflag ) + NetSendCmdParam1(1u, CMD_OPENDOOR, oi); + if ( !deltaload ) + PlaySfxLoc(IS_DOOROPEN, object[v3]._ox, object[v3]._oy); + ObjSetMicro(v8, v5, 541); + object[v3]._oAnimFrame += 2; + object[v3]._oPreFlag = 1; + object[v3]._oVar4 = 1; + _LOBYTE(object[v3]._oSelFlag) = 2; + } + RedoPlayerVision(); + return; + } + if ( !deltaload ) + PlaySfxLoc(IS_DOORCLOS, object[v3]._ox, object[v3]._oy); +} +// 676190: using guessed type int deltaload; + +//----- (00444A3C) -------------------------------------------------------- +void __fastcall OperateL3LDoor(int pnum, int oi, unsigned char sendflag) +{ + int v3; // esi + int v4; // eax + int v5; // ebx + short param1; // [esp+Ch] [ebp-Ch] + int v7; // [esp+10h] [ebp-8h] + int v8; // [esp+14h] [ebp-4h] + + v3 = oi; + param1 = oi; + v7 = pnum; + v4 = object[oi]._oVar4; + if ( v4 != 2 ) + { + v5 = object[v3]._oy; + v8 = object[v3]._ox; + if ( v4 ) + { + if ( !deltaload ) + PlaySfxLoc(IS_DOORCLOS, object[v3]._ox, v5); + if ( dDead[v8][v5] != 0 || dMonster[0][v5 + 112 * v8] != 0 || dItem[v8][v5] != 0 ) + { + object[v3]._oVar4 = 2; + return; + } + if ( v7 == myplr && sendflag ) + NetSendCmdParam1(1u, CMD_CLOSEDOOR, param1); + object[v3]._oVar4 = 0; + _LOBYTE(object[v3]._oSelFlag) = 3; + ObjSetMicro(v8, v5, 531); + object[v3]._oAnimFrame -= 2; + object[v3]._oPreFlag = 0; + } + else + { + if ( pnum == myplr && sendflag ) + NetSendCmdParam1(1u, CMD_OPENDOOR, oi); + if ( !deltaload ) + PlaySfxLoc(IS_DOOROPEN, object[v3]._ox, object[v3]._oy); + ObjSetMicro(v8, v5, 538); + object[v3]._oAnimFrame += 2; + object[v3]._oPreFlag = 1; + object[v3]._oVar4 = 1; + _LOBYTE(object[v3]._oSelFlag) = 2; + } + RedoPlayerVision(); + return; + } + if ( !deltaload ) + PlaySfxLoc(IS_DOORCLOS, object[v3]._ox, object[v3]._oy); +} +// 676190: using guessed type int deltaload; + +//----- (00444BA1) -------------------------------------------------------- +void __fastcall MonstCheckDoors(int m) +{ + int v1; // ecx + int v2; // eax + int v3; // ecx + int v4; // eax + char *v5; // ecx + int v6; // eax + int v7; // esi + int v8; // esi + int v9; // eax + int v10; // ebx + int v11; // eax + bool v12; // zf + bool v13; // sf + unsigned char v14; // of + int v15; // eax + int v16; // ebx + int v17; // eax + bool v18; // zf + bool v19; // sf + unsigned char v20; // of + int v21; // eax + int v22; // ebx + int v23; // eax + bool v24; // zf + bool v25; // sf + unsigned char v26; // of + int v27; // [esp+0h] [ebp-14h] + int v28; // [esp+4h] [ebp-10h] + int v29; // [esp+8h] [ebp-Ch] + int v30; // [esp+Ch] [ebp-8h] + int v31; // [esp+Ch] [ebp-8h] + int v32; // [esp+Ch] [ebp-8h] + int oi; // [esp+10h] [ebp-4h] + + v1 = m; + v2 = monster[v1]._mx; + v3 = monster[v1]._my; + v29 = v2; + v4 = v3 + 112 * v2; + v28 = v3; + v5 = (char *)dObject + v4; + if ( dObject[-1][v4 - 1] + || *(v5 - 1) + || dObject[0][v4 + 111] + || *(v5 - 112) + || dObject[1][v4] + || dObject[-1][v4 + 1] + || dObject[0][v4 + 1] + || dObject[1][v4 + 1] ) + { + v6 = 0; + v27 = 0; + if ( nobjects > 0 ) + { + while ( 1 ) + { + v7 = objectactive[v6]; + oi = v7; + v8 = v7; + v9 = object[v8]._otype; + if ( v9 != 1 && v9 != OBJ_L1RDOOR || object[v8]._oVar4 ) + goto LABEL_21; + v10 = abs(object[v8]._ox - v29); + v11 = abs(object[v8]._oy - v28); + v14 = __OFSUB__(v10, 1); + v12 = v10 == 1; + v13 = v10 - 1 < 0; + v30 = v11; + if ( v10 != 1 ) + goto LABEL_17; + if ( v11 <= 1 && object[v8]._otype == 1 ) + break; +LABEL_18: + if ( v30 == 1 && object[v8]._otype == OBJ_L1RDOOR ) + OperateL1RDoor(myplr, oi, 1u); +LABEL_21: + v15 = object[v8]._otype; + if ( v15 != OBJ_L2LDOOR && v15 != OBJ_L2RDOOR || object[v8]._oVar4 ) + goto LABEL_32; + v16 = abs(object[v8]._ox - v29); + v17 = abs(object[v8]._oy - v28); + v20 = __OFSUB__(v16, 1); + v18 = v16 == 1; + v19 = v16 - 1 < 0; + v31 = v17; + if ( v16 != 1 ) + goto LABEL_28; + if ( v17 <= 1 && object[v8]._otype == OBJ_L2LDOOR ) + { + OperateL2LDoor(myplr, oi, 1u); + v20 = 0; + v18 = 1; + v19 = 0; +LABEL_28: + if ( !((unsigned char)(v19 ^ v20) | v18) ) + goto LABEL_32; + } + if ( v31 == 1 && object[v8]._otype == OBJ_L2RDOOR ) + OperateL2RDoor(myplr, oi, 1u); +LABEL_32: + v21 = object[v8]._otype; + if ( v21 != OBJ_L3LDOOR && v21 != OBJ_L3RDOOR || object[v8]._oVar4 ) + goto LABEL_43; + v22 = abs(object[v8]._ox - v29); + v23 = abs(object[v8]._oy - v28); + v26 = __OFSUB__(v22, 1); + v24 = v22 == 1; + v25 = v22 - 1 < 0; + v32 = v23; + if ( v22 == 1 ) + { + if ( v23 > 1 || object[v8]._otype != OBJ_L3RDOOR ) + { +LABEL_40: + if ( v32 == 1 && object[v8]._otype == OBJ_L3LDOOR ) + OperateL3LDoor(myplr, oi, 1u); + goto LABEL_43; + } + OperateL3RDoor(myplr, oi, 1u); + v26 = 0; + v24 = 1; + v25 = 0; + } + if ( (unsigned char)(v25 ^ v26) | v24 ) + goto LABEL_40; +LABEL_43: + v6 = v27++ + 1; + if ( v27 >= nobjects ) + return; + } + OperateL1LDoor(myplr, oi, 1u); + v14 = 0; + v12 = 1; + v13 = 0; +LABEL_17: + if ( !((unsigned char)(v13 ^ v14) | v12) ) + goto LABEL_21; + goto LABEL_18; + } + } +} + +//----- (00444DC3) -------------------------------------------------------- +void __fastcall DRLG_MRectTrans(int x1, int y1, int x2, int y2) +{ + int v4; // ebx + int v5; // edi + int v6; // esi + int v7; // ecx + int v8; // edi + int v9; // ebx + int v10; // ecx + int v11; // [esp+Ch] [ebp-8h] + int a2; // [esp+10h] [ebp-4h] + int i; // [esp+1Ch] [ebp+8h] + int y_end; // [esp+20h] [ebp+Ch] + + v4 = y1; + v5 = x2; + v6 = x1; + for ( a2 = y1; a2 <= y2; ++a2 ) + { + i = v6; + if ( v6 <= v5 ) + { + v11 = a2 + 40 * v6; + do + { + ObjSetMini(i++, a2, (unsigned char)pdungeon[0][v11]); + dungeon[0][v11] = pdungeon[0][v11]; + v11 += 40; + } + while ( i <= v5 ); + } + } + if ( leveltype == 1 ) + { + ObjL1Special(2 * v6 + 16, 2 * v4 + 16, 2 * v5 + 17, 2 * y2 + 17); + AddL1Objs(v7, 2 * v4 + 16, 2 * v5 + 17, 2 * y2 + 17); + } + if ( leveltype == 2 ) + { + v8 = 2 * v5 + 17; + v9 = 2 * v4 + 16; + y_end = 2 * y2 + 17; + ObjL2Special(2 * v6 + 16, v9, v8, y_end); + AddL2Objs(v10, v9, v8, y_end); + } +} +// 5BB1ED: using guessed type char leveltype; + +//----- (00444E9E) -------------------------------------------------------- +void __fastcall ObjChangeMapResync(int x1, int y1, int x2, int y2) +{ + int v4; // edi + int v5; // esi + int v6; // ebx + int v7; // edi + int v8; // [esp+Ch] [ebp-Ch] + int i; // [esp+10h] [ebp-8h] + int a2; // [esp+14h] [ebp-4h] + + v4 = y2; + v5 = y1; + v6 = x1; + v8 = y1; + for ( a2 = y1; a2 <= v4; ++a2 ) + { + i = v6; + if ( v6 <= x2 ) + { + v7 = a2 + 40 * v6; + do + { + ObjSetMini(i++, a2, (unsigned char)pdungeon[0][v7]); + dungeon[0][v7] = pdungeon[0][v7]; + v7 += 40; + } + while ( i <= x2 ); + v4 = y2; + v5 = v8; + } + } + if ( leveltype == 1 ) + ObjL1Special(2 * v6 + 16, 2 * v5 + 16, 2 * x2 + 17, 2 * v4 + 17); + if ( leveltype == 2 ) + ObjL2Special(2 * v6 + 16, 2 * v5 + 16, 2 * x2 + 17, 2 * v4 + 17); +} +// 5BB1ED: using guessed type char leveltype; + +//----- (00444F4F) -------------------------------------------------------- +void __fastcall OperateL1Door(int pnum, int i, unsigned char sendflag) +{ + int v3; // ebx + int v4; // edi + int v5; // esi + int v6; // ST1C_4 + int v7; // eax + bool v8; // zf + bool v9; // sf + unsigned char v10; // of + int v11; // [esp+Ch] [ebp-Ch] + int pnuma; // [esp+10h] [ebp-8h] + + v3 = i; + v4 = i; + pnuma = pnum; + v5 = pnum; + v6 = abs(object[i]._ox - plr[pnum].WorldX); + v7 = abs(object[v4]._oy - plr[v5].WorldY); + v10 = __OFSUB__(v6, 1); + v8 = v6 == 1; + v9 = v6 - 1 < 0; + v11 = v7; + if ( v6 != 1 ) + { +LABEL_5: + if ( !((unsigned char)(v9 ^ v10) | v8) ) + return; + goto LABEL_6; + } + if ( v7 <= 1 && object[v4]._otype == 1 ) + { + OperateL1LDoor(pnuma, v3, sendflag); + v10 = 0; + v8 = 1; + v9 = 0; + goto LABEL_5; + } +LABEL_6: + if ( v11 == 1 && object[v4]._otype == OBJ_L1RDOOR ) + OperateL1RDoor(pnuma, v3, sendflag); +} + +//----- (00444FDE) -------------------------------------------------------- +void __fastcall OperateLever(int pnum, int i) +{ + int v2; // esi + int *v3; // edi + signed int v4; // edi + int v5; // ecx + int v6; // eax + short param1; // [esp+8h] [ebp-8h] + int v8; // [esp+Ch] [ebp-4h] + + param1 = i; + v2 = i; + v3 = &object[i]._oSelFlag; + v8 = pnum; + if ( *(_BYTE *)v3 ) + { + if ( !deltaload ) + PlaySfxLoc(IS_LEVER, object[v2]._ox, object[v2]._oy); + *(_BYTE *)v3 = 0; + ++object[v2]._oAnimFrame; + v4 = 1; + if ( currlevel != 16 ) + goto LABEL_17; + v5 = 0; + if ( nobjects <= 0 ) + goto LABEL_17; + do + { + v6 = objectactive[v5]; + if ( object[v6]._otype == OBJ_SWITCHSKL + && object[v2]._oVar8 == object[v6]._oVar8 + && _LOBYTE(object[v6]._oSelFlag) ) + { + v4 = 0; + } + ++v5; + } + while ( v5 < nobjects ); + if ( v4 ) +LABEL_17: + DRLG_MRectTrans(object[v2]._oVar1, object[v2]._oVar2, object[v2]._oVar3, object[v2]._oVar4); + if ( v8 == myplr ) + NetSendCmdParam1(0, CMD_OPERATEOBJ, param1); + } +} +// 676190: using guessed type int deltaload; + +//----- (004450AC) -------------------------------------------------------- +void __fastcall OperateBook(int pnum, int i) +{ + int esi1; // esi + int v3; // edx + signed int v4; // ecx + int v5; // eax + bool v6; // zf + int v7; // ecx + int *v8; // eax + int j; // esi + int v10; // [esp+Ch] [ebp-14h] + signed int v11; // [esp+10h] [ebp-10h] + signed int v1; // [esp+14h] [ebp-Ch] + signed int v2; // [esp+18h] [ebp-8h] + int v14; // [esp+1Ch] [ebp-4h] + + esi1 = i; + v3 = pnum; + v10 = pnum; + if ( !_LOBYTE(object[esi1]._oSelFlag) ) + return; + if ( !setlevel || setlvlnum != SL_VILEBETRAYER ) + goto LABEL_17; + v4 = 0; + v11 = 0; + v14 = 0; + if ( nobjects > 0 ) + { + while ( 1 ) + { + v5 = objectactive[v14]; + if ( object[v5]._otype == OBJ_MCIRCLE2 ) + { + if ( object[v5]._oVar6 == 1 ) + { + v1 = 27; + v2 = 29; + object[v5]._oVar6 = 4; + v4 = 1; + } + if ( object[v5]._oVar6 == 2 ) + { + v1 = 43; + v2 = 29; + object[v5]._oVar6 = 4; + v4 = 1; + } + } + if ( v4 ) + { + ++objectavail[30 * dObject[35][36] + 123]; + AddMissile(plr[v3].WorldX, plr[v3].WorldY, v1, v2, plr[v3]._pdir, 3, 0, v3, 0, 0); + v11 = 1; + v4 = 0; + } + if ( ++v14 >= nobjects ) + break; + v3 = v10; + } + if ( v11 ) + { + v3 = v10; +LABEL_17: + ++object[esi1]._oAnimFrame; + v6 = setlevel == 0; + _LOBYTE(object[esi1]._oSelFlag) = 0; + if ( !v6 ) + { + if ( setlvlnum == SL_BONECHAMB ) + { + v7 = 21720 * myplr; + v8 = plr[myplr]._pMemSpells; + *((_BYTE *)v8 + 1) |= 0x10u; + v8[1] = v8[1]; + if ( plr[v3]._pSplLvl[13] < 15 ) + ++plr[0]._pSplLvl[v7 + 13]; + quests[14]._qactive = 3; + if ( !deltaload ) + PlaySfxLoc(IS_QUESTDN, object[esi1]._ox, object[esi1]._oy); + _LOBYTE(v7) = 43; + InitDiabloMsg(v7); + AddMissile( + plr[myplr].WorldX, + plr[myplr].WorldY, + object[esi1]._ox - 2, + object[esi1]._oy - 4, + plr[myplr]._pdir, + 2, + 0, + myplr, + 0, + 0); + } + if ( setlevel ) + { + if ( setlvlnum == SL_VILEBETRAYER ) + { + ObjChangeMapResync( + object[esi1]._oVar1, + object[esi1]._oVar2, + object[esi1]._oVar3, + object[esi1]._oVar4); + for ( j = 0; j < nobjects; ++j ) + SyncObjectAnim(objectactive[j]); + } + } + } + return; + } + } +} +// 5CCB10: using guessed type char setlvlnum; +// 5CF31D: using guessed type char setlevel; +// 676190: using guessed type int deltaload; + +//----- (004452D1) -------------------------------------------------------- +void __fastcall OperateBookLever(int pnum, int i) +{ + int v2; // esi + int v3; // edi + int v4; // ebp + int v5; // edx + int v6; // eax + int v7; // ST0C_4 + int v8; // edx + char v9; // bl + int v10; // ST08_4 + int v11; // ecx + int v12; // ecx + int v13; // [esp+Ch] [ebp-8h] + short param1; // [esp+10h] [ebp-4h] + + param1 = i; + v2 = i; + v13 = pnum; + v3 = 2 * setpc_x + 16; + v4 = 2 * setpc_y + 16; + if ( _LOBYTE(object[i]._oSelFlag) && !qtextflag ) + { + v5 = object[v2]._otype; + if ( v5 == OBJ_BLINDBOOK && !quests[8]._qvar1 ) + { + quests[8]._qactive = 2; + quests[8]._qlog = 1; + quests[8]._qvar1 = 1; + } + if ( v5 == OBJ_BLOODBOOK && !quests[9]._qvar1 ) + { + quests[9]._qactive = 2; + quests[9]._qlog = 1; + quests[9]._qvar1 = 1; + SpawnQuestItem(21, 2 * setpc_x + 19, 2 * setpc_y + 26, 0, 1); + SpawnQuestItem(21, 2 * setpc_x + 31, 2 * setpc_y + 26, 0, 1); + SpawnQuestItem(21, 2 * setpc_x + 25, 2 * setpc_y + 33, 0, 1); + } + v6 = object[v2]._otype; + if ( v6 == OBJ_STEELTOME && !quests[11]._qvar1 ) + { + quests[11]._qactive = 2; + quests[11]._qlog = 1; + quests[11]._qvar1 = 1; + } + if ( object[v2]._oAnimFrame != object[v2]._oVar6 ) + { + if ( v6 != OBJ_BLOODBOOK ) + DRLG_MRectTrans(object[v2]._oVar1, object[v2]._oVar2, object[v2]._oVar3, object[v2]._oVar4); + if ( object[v2]._otype == OBJ_BLINDBOOK ) + { + CreateItem(3, v3 + 5, v4 + 5); + v7 = object[v2]._oVar4; + v8 = object[v2]._oVar2; + v9 = TransVal; + v10 = object[v2]._oVar3; + v11 = object[v2]._oVar1; + TransVal = 9; + Make_RectTrans(v11, v8, v10, v7); + TransVal = v9; + } + } + v12 = object[v2]._oVar7; + object[v2]._oAnimFrame = object[v2]._oVar6; + InitQTextMsg(v12); + if ( v13 == myplr ) + NetSendCmdParam1(0, CMD_OPERATEOBJ, param1); + } +} +// 5A5590: using guessed type char TransVal; +// 646D00: using guessed type char qtextflag; + +//----- (00445483) -------------------------------------------------------- +void __fastcall OperateSChambBk(int pnum, int i) +{ + int v2; // esi + int j; // edi + char v4; // al + signed int v5; // ecx + int speech_id; // [esp+4h] [ebp-4h] + + v2 = i; + if ( _LOBYTE(object[i]._oSelFlag) && !qtextflag ) + { + if ( object[v2]._oAnimFrame != object[v2]._oVar6 ) + { + ObjChangeMapResync(object[v2]._oVar1, object[v2]._oVar2, object[v2]._oVar3, object[v2]._oVar4); + for ( j = 0; j < nobjects; ++j ) + SyncObjectAnim(objectactive[j]); + } + object[v2]._oAnimFrame = object[v2]._oVar6; + if ( quests[14]._qactive == 1 ) + { + quests[14]._qactive = 2; + quests[14]._qlog = 1; + } + v4 = plr[myplr]._pClass; + if ( v4 ) + { + if ( v4 == 1 ) + { + v5 = 243; + } + else + { + v5 = 239; + if ( v4 != 2 ) + v5 = speech_id; + } + } + else + { + v5 = 235; + } + quests[14]._qmsg = v5; + InitQTextMsg(v5); + } +} +// 646D00: using guessed type char qtextflag; + +//----- (0044555A) -------------------------------------------------------- +void __fastcall OperateChest(int pnum, int i, unsigned char sendmsg) +{ + int v3; // esi + bool v4; // zf + int v5; // edi + int v6; // eax + int v7; // eax + int v8; // ecx + int v9; // ecx + int v10; // ecx + signed int v11; // [esp-8h] [ebp-18h] + short param2; // [esp+8h] [ebp-8h] + int param1; // [esp+Ch] [ebp-4h] + + param2 = i; + v3 = i; + param1 = pnum; + if ( _LOBYTE(object[i]._oSelFlag) ) + { + if ( !deltaload ) + PlaySfxLoc(IS_CHEST, object[v3]._ox, object[v3]._oy); + object[v3]._oAnimFrame += 2; + v4 = deltaload == 0; + _LOBYTE(object[v3]._oSelFlag) = 0; + if ( v4 ) + { + SetRndSeed(object[v3]._oRndSeed); + v5 = 0; + if ( setlevel ) + { + if ( object[v3]._oVar1 > 0 ) + { + do + { + CreateRndItem(object[v3]._ox, object[v3]._oy, 1u, sendmsg, 0); + ++v5; + } + while ( v5 < object[v3]._oVar1 ); + } + } + else if ( object[v3]._oVar1 > 0 ) + { + do + { + if ( object[v3]._oVar2 ) + CreateRndItem(object[v3]._ox, object[v3]._oy, 0, sendmsg, 0); + else + CreateRndUseful(param1, object[v3]._ox, object[v3]._oy, sendmsg); + ++v5; + } + while ( v5 < object[v3]._oVar1 ); + } + if ( !object[v3]._oTrapFlag ) + goto LABEL_26; + v6 = object[v3]._otype; + if ( v6 < OBJ_TCHEST1 || v6 > OBJ_TCHEST3 ) + goto LABEL_26; + v7 = GetDirection(object[v3]._ox, object[v3]._oy, plr[param1].WorldX, plr[param1].WorldY); + v8 = object[v3]._oVar4; + if ( v8 ) + { + v9 = v8 - 1; + if ( v9 ) + { + if ( v9 != 1 ) + { + v10 = sendmsg; + goto LABEL_25; + } + v11 = 42; + } + else + { + v11 = 27; + } + v10 = v11; + } + else + { + v10 = 0; + } +LABEL_25: + AddMissile(object[v3]._ox, object[v3]._oy, plr[param1].WorldX, plr[param1].WorldY, v7, v10, 1, -1, 0, 0); + object[v3]._oTrapFlag = 0; +LABEL_26: + if ( param1 == myplr ) + NetSendCmdParam2(0, CMD_PLROPOBJ, param1, param2); + return; + } + } +} +// 5CF31D: using guessed type char setlevel; +// 676190: using guessed type int deltaload; + +//----- (004456E3) -------------------------------------------------------- +void __fastcall OperateMushPatch(int pnum, int i) +{ + int v2; // esi + bool v3; // zf + char v4; // al + int v5; // ecx + int xx; // [esp+8h] [ebp-8h] + int yy; // [esp+Ch] [ebp-4h] + + if ( quests[1]._qactive != 2 || quests[1]._qvar1 < 2u ) + { + if ( !deltaload && pnum == myplr ) + { + v4 = plr[myplr]._pClass; + if ( v4 ) + { + if ( v4 == 1 ) + { + v5 = PS_ROGUE13; + } + else + { + if ( v4 != 2 ) + return; + v5 = PS_MAGE13; + } + } + else + { + v5 = PS_WARR13; + } + PlaySFX(v5); + } + } + else + { + v2 = i; + if ( _LOBYTE(object[i]._oSelFlag) ) + { + if ( !deltaload ) + PlaySfxLoc(IS_CHEST, object[v2]._ox, object[v2]._oy); + ++object[v2]._oAnimFrame; + v3 = deltaload == 0; + _LOBYTE(object[v2]._oSelFlag) = 0; + if ( v3 ) + { + GetSuperItemLoc(object[v2]._ox, object[v2]._oy, &xx, &yy); + SpawnQuestItem(17, xx, yy, 0, 0); + quests[1]._qvar1 = 3; + } + } + } +} +// 676190: using guessed type int deltaload; + +//----- (004457B8) -------------------------------------------------------- +void __fastcall OperateInnSignChest(int pnum, int i) +{ + char v2; // al + int v3; // ecx + int v4; // esi + bool v5; // zf + int xx; // [esp+8h] [ebp-8h] + int yy; // [esp+Ch] [ebp-4h] + + if ( quests[7]._qvar1 == 2 ) + { + v4 = i; + if ( _LOBYTE(object[i]._oSelFlag) ) + { + if ( !deltaload ) + PlaySfxLoc(IS_CHEST, object[v4]._ox, object[v4]._oy); + object[v4]._oAnimFrame += 2; + v5 = deltaload == 0; + _LOBYTE(object[v4]._oSelFlag) = 0; + if ( v5 ) + { + GetSuperItemLoc(object[v4]._ox, object[v4]._oy, &xx, &yy); + SpawnQuestItem(12, xx, yy, 0, 0); + } + } + } + else if ( !deltaload && pnum == myplr ) + { + v2 = plr[myplr]._pClass; + switch ( v2 ) + { + case UI_WARRIOR: + v3 = PS_WARR24; +LABEL_8: + PlaySFX(v3); + return; + case UI_ROGUE: + v3 = PS_ROGUE24; + goto LABEL_8; + case UI_SORCERER: + v3 = PS_MAGE24; + goto LABEL_8; + } + } +} +// 676190: using guessed type int deltaload; + +//----- (00445880) -------------------------------------------------------- +void __fastcall OperateSlainHero(int pnum, int i, unsigned char sendmsg) +{ + unsigned short v3; // di + int v4; // esi + int v5; // eax + bool v6; // zf + char v7; // cl + int v8; // ecx + + v3 = i; + v4 = pnum; + v5 = i; + if ( _LOBYTE(object[i]._oSelFlag) ) + { + v6 = deltaload == 0; + _LOBYTE(object[v5]._oSelFlag) = 0; + if ( v6 ) + { + v7 = plr[pnum]._pClass; + if ( v7 ) + { + if ( v7 == 1 ) + { + CreateMagicItem(object[v5]._ox, object[v5]._oy, 3, 119, 0, 1); + v8 = PS_ROGUE9; + } + else + { + if ( v7 != 2 ) + goto LABEL_10; + CreateSpellBook(object[v5]._ox, object[v5]._oy, 3, 0, 1); + v8 = PS_MAGE9; + } + } + else + { + CreateMagicItem(object[v5]._ox, object[v5]._oy, 9, 153, 0, 1); + v8 = PS_WARR9; + } + PlaySfxLoc(v8, plr[myplr].WorldX, plr[myplr].WorldY); +LABEL_10: + if ( v4 == myplr ) + NetSendCmdParam1(0, CMD_OPERATEOBJ, v3); + return; + } + } +} +// 676190: using guessed type int deltaload; + +//----- (00445954) -------------------------------------------------------- +void __fastcall OperateTrapLvr(int i) +{ + int v1; // ecx + int v2; // eax + int v3; // esi + int v4; // edx + int v5; // eax + int v6; // eax + + v1 = i; + v2 = object[v1]._oAnimFrame; + v3 = nobjects; + v4 = 0; + if ( v2 == 1 ) + { + object[v1]._oAnimFrame = 2; + if ( v3 > 0 ) + { + do + { + v5 = objectactive[v4]; + if ( object[v5]._otype == object[v1]._oVar2 && object[v5]._oVar1 == object[v1]._oVar1 ) + { + object[v5]._oAnimFlag = 0; + object[v5]._oVar2 = 1; + } + ++v4; + } + while ( v4 < v3 ); + } + } + else + { + object[v1]._oAnimFrame = v2 - 1; + if ( v3 > 0 ) + { + do + { + v6 = objectactive[v4]; + if ( object[v6]._otype == object[v1]._oVar2 && object[v6]._oVar1 == object[v1]._oVar1 ) + { + object[v6]._oVar2 = 0; + if ( object[v6]._oVar4 ) + object[v6]._oAnimFlag = 1; + } + ++v4; + } + while ( v4 < v3 ); + } + } +} + +//----- (00445A0B) -------------------------------------------------------- +void __fastcall OperateSarc(int pnum, int i, unsigned char sendmsg) +{ + unsigned short v3; // bp + int v4; // esi + bool v5; // zf + int v6; // ecx + int v7; // [esp+Ch] [ebp-4h] + + v3 = i; + v4 = i; + v7 = pnum; + if ( _LOBYTE(object[i]._oSelFlag) ) + { + if ( !deltaload ) + PlaySfxLoc(IS_SARC, object[v4]._ox, object[v4]._oy); + v5 = deltaload == 0; + _LOBYTE(object[v4]._oSelFlag) = 0; + if ( v5 ) + { + v6 = object[v4]._oRndSeed; + object[v4]._oAnimFlag = 1; + object[v4]._oAnimDelay = 3; + SetRndSeed(v6); + if ( object[v4]._oVar1 <= 2 ) + CreateRndItem(object[v4]._ox, object[v4]._oy, 0, sendmsg, 0); + if ( object[v4]._oVar1 >= 8 ) + SpawnSkeleton(object[v4]._oVar2, object[v4]._ox, object[v4]._oy); + if ( v7 == myplr ) + NetSendCmdParam1(0, CMD_OPERATEOBJ, v3); + } + else + { + object[v4]._oAnimFrame = object[v4]._oAnimLen; + } + } +} +// 676190: using guessed type int deltaload; + +//----- (00445ADC) -------------------------------------------------------- +void __fastcall OperateL2Door(int pnum, int i, unsigned char sendflag) +{ + int v3; // ebx + int v4; // edi + int v5; // esi + int v6; // ST1C_4 + int v7; // eax + bool v8; // zf + bool v9; // sf + unsigned char v10; // of + int v11; // [esp+Ch] [ebp-Ch] + int pnuma; // [esp+10h] [ebp-8h] + + v3 = i; + v4 = i; + pnuma = pnum; + v5 = pnum; + v6 = abs(object[i]._ox - plr[pnum].WorldX); + v7 = abs(object[v4]._oy - plr[v5].WorldY); + v10 = __OFSUB__(v6, 1); + v8 = v6 == 1; + v9 = v6 - 1 < 0; + v11 = v7; + if ( v6 != 1 ) + { +LABEL_5: + if ( !((unsigned char)(v9 ^ v10) | v8) ) + return; + goto LABEL_6; + } + if ( v7 <= 1 && object[v4]._otype == OBJ_L2LDOOR ) + { + OperateL2LDoor(pnuma, v3, sendflag); + v10 = 0; + v8 = 1; + v9 = 0; + goto LABEL_5; + } +LABEL_6: + if ( v11 == 1 && object[v4]._otype == OBJ_L2RDOOR ) + OperateL2RDoor(pnuma, v3, sendflag); +} + +//----- (00445B6C) -------------------------------------------------------- +void __fastcall OperateL3Door(int pnum, int i, unsigned char sendflag) +{ + int v3; // ebx + int v4; // edi + int v5; // esi + int v6; // ST1C_4 + int v7; // eax + bool v8; // zf + bool v9; // sf + unsigned char v10; // of + int v11; // [esp+Ch] [ebp-Ch] + int pnuma; // [esp+10h] [ebp-8h] + + v3 = i; + v4 = i; + pnuma = pnum; + v5 = pnum; + v6 = abs(object[i]._ox - plr[pnum].WorldX); + v7 = abs(object[v4]._oy - plr[v5].WorldY); + v10 = __OFSUB__(v6, 1); + v8 = v6 == 1; + v9 = v6 - 1 < 0; + v11 = v7; + if ( v6 != 1 ) + { +LABEL_5: + if ( !((unsigned char)(v9 ^ v10) | v8) ) + return; + goto LABEL_6; + } + if ( v7 <= 1 && object[v4]._otype == OBJ_L3RDOOR ) + { + OperateL3RDoor(pnuma, v3, sendflag); + v10 = 0; + v8 = 1; + v9 = 0; + goto LABEL_5; + } +LABEL_6: + if ( v11 == 1 && object[v4]._otype == OBJ_L3LDOOR ) + OperateL3LDoor(pnuma, v3, sendflag); +} + +//----- (00445BFC) -------------------------------------------------------- +void __fastcall OperatePedistal(int pnum, int i) +{ + int v2; // esi + int v3; // edi + unsigned char *v4; // edi + int inv_item_num; // [esp+8h] [ebp-4h] + + v2 = i; + v3 = pnum; + if ( object[i]._oVar6 != 3 ) + { + if ( PlrHasItem(pnum, 21, &inv_item_num) ) + { + RemoveInvItem(v3, inv_item_num); + ++object[v2]._oAnimFrame; + ++object[v2]._oVar6; + } + if ( object[v2]._oVar6 == 1 ) + { + if ( !deltaload ) + PlaySfxLoc(LS_PUDDLE, object[v2]._ox, object[v2]._oy); + DRLG_MRectTrans(setpc_x, setpc_y + 3, setpc_x + 2, setpc_y + 7); + } + if ( object[v2]._oVar6 == 2 ) + { + if ( !deltaload ) + PlaySfxLoc(LS_PUDDLE, object[v2]._ox, object[v2]._oy); + DRLG_MRectTrans(setpc_x + 6, setpc_y + 3, setpc_x + setpc_w, setpc_y + 7); + } + if ( object[v2]._oVar6 == 3 ) + { + if ( !deltaload ) + PlaySfxLoc(LS_BLODSTAR, object[v2]._ox, object[v2]._oy); + DRLG_MRectTrans(object[v2]._oVar1, object[v2]._oVar2, object[v2]._oVar3, object[v2]._oVar4); + v4 = LoadFileInMem("Levels\\L2Data\\Blood2.DUN", 0); + LoadMapObjs(v4, 2 * setpc_x, 2 * setpc_y); + mem_free_dbg(v4); + CreateItem(7, 2 * setpc_x + 25, 2 * setpc_y + 19); + _LOBYTE(object[v2]._oSelFlag) = 0; + } + } +} +// 5CF334: using guessed type int setpc_w; +// 676190: using guessed type int deltaload; + +//----- (00445D5F) -------------------------------------------------------- +void __fastcall TryDisarm(int pnum, int i) +{ + int v2; // edi + int v3; // esi + int v4; // esi + int v5; // edi + int v6; // ebx + int j; // edx + signed int v8; // edi + int v9; // eax + int v10; // ecx + int v11; // eax + int v12; // [esp+Ch] [ebp-4h] + + v2 = pnum; + v3 = i; + v12 = i; + if ( pnum == myplr ) + SetCursor(1); + v4 = v3; + if ( object[v4]._oTrapFlag ) + { + _LOBYTE(pnum) = -102; + v5 = 2 * plr[v2]._pDexterity - 5 * currlevel; + if ( random(pnum, 100) <= v5 ) + { + v6 = nobjects; + for ( j = 0; j < v6; ++j ) + { + v8 = 0; + v9 = objectactive[j]; + v10 = object[v9]._otype; + if ( v10 == OBJ_TRAPL ) + v8 = 1; + if ( v10 == OBJ_TRAPR ) + v8 = 1; + if ( v8 && dObject[object[v9]._oVar1][object[v9]._oVar2] - 1 == v12 ) + { + object[v9]._oVar4 = 1; + object[v4]._oTrapFlag = 0; + } + } + v11 = object[v4]._otype; + if ( v11 >= OBJ_TCHEST1 && v11 <= OBJ_TCHEST3 ) + object[v4]._oTrapFlag = 0; + } + } +} + +//----- (00445E33) -------------------------------------------------------- +int __fastcall ItemMiscIdIdx(int imiscid) +{ + int result; // eax + int *i; // edx + + result = 0; + for ( i = &AllItemsList[0].iMiscId; !*(i - 14) || *i != imiscid; i += 19 ) + ++result; + return result; +} + +//----- (00445E4B) -------------------------------------------------------- +void __fastcall OperateShrine(int player_num, int object_num, int sfx_id) +{ + int v3; // esi + int *v4; // ebx + int v5; // eax + int v6; // ecx + int v7; // ecx + int v8; // ecx + int v9; // eax + int v10; // eax + int v11; // eax + int v12; // edx + int v13; // esi + signed int v14; // ebx + int *v15; // eax + int *v16; // eax + int v17; // edx + int v18; // ebx + int *v19; // eax + signed int v20; // edx + int v21; // eax + int v22; // ecx + int *v23; // eax + int v24; // edx + int v25; // esi + int v26; // eax + int v27; // ecx + int v28; // edx + int *v29; // ecx + int v30; // edx + int v31; // ebx + signed int v32; // edx + int v33; // edx + int v34; // eax + int v35; // ecx + int v36; // esi + signed int v37; // edx + int v38; // eax + int *v39; // ecx + signed int v40; // esi + int v41; // esi + int *v42; // ecx + int *v43; // eax + signed int v44; // ecx + int v45; // eax + int *v46; // ecx + signed int v47; // edx + int v48; // ebx + int *v49; // ecx + int *v50; // eax + signed int v51; // ecx + signed int v52; // edi + int v53; // esi + int v54; // ebx + int v55; // eax + bool v56; // zf + signed int v57; // ebx + unsigned int v58; // edi + signed int v59; // edx + int v60; // ebx + char *v61; // esi + int j; // edi + int v63; // esi + int v64; // eax + int *v65; // eax + int v66; // edx + char v67; // al + char v68; // al + int v69; // esi + int v70; // edx + int v71; // ebx + int v72; // edi + int v73; // eax + int v74; // edx + int v75; // edx + int v76; // edx + int v77; // esi + int v78; // ebx + int *v79; // eax + int v80; // eax + int v81; // eax + int *v82; // eax + int v83; // eax + int v84; // eax + int v85; // ecx + int v86; // edx + int v87; // eax + int v88; // ebx + int v89; // eax + int v90; // ecx + int v91; // esi + int v92; // eax + int v93; // edx + int *v94; // eax + int v95; // edx + char v96; // al + char v97; // al + int v98; // esi + int v99; // edx + int v100; // ebx + int v101; // edi + int v102; // eax + int v103; // edx + int v104; // edx + int v105; // edx + int v106; // ebx + int v107; // ST38_4 + int v108; // ST34_4 + int v109; // ST3C_4 + int v110; // eax + _BYTE *v111; // eax + signed int v112; // edx + int *v113; // eax + int v114; // edx + char v115; // al + char v116; // al + int v117; // esi + int v118; // edx + int v119; // ebx + int v120; // edi + int v121; // eax + int v122; // edx + int v123; // edx + int v124; // edx + int v125; // eax + int *v126; // ecx + signed int v127; // esi + int v128; // esi + int *v129; // ecx + int *v130; // eax + signed int v131; // ecx + int v132; // ecx + int v133; // eax + int v134; // ebx + int v135; // edi + int v136; // esi + unsigned short param2; // [esp+Ch] [ebp-18h] + int i; // [esp+14h] [ebp-10h] + signed int v139; // [esp+1Ch] [ebp-8h] + int *v140; // [esp+1Ch] [ebp-8h] + signed int v141; // [esp+1Ch] [ebp-8h] + int arglist; // [esp+20h] [ebp-4h] + int sfx_ida; // [esp+2Ch] [ebp+8h] + int sfx_ide; // [esp+2Ch] [ebp+8h] + int sfx_idb; // [esp+2Ch] [ebp+8h] + int *sfx_idc; // [esp+2Ch] [ebp+8h] + int sfx_idf; // [esp+2Ch] [ebp+8h] + int sfx_idd; // [esp+2Ch] [ebp+8h] + int sfx_idg; // [esp+2Ch] [ebp+8h] + + param2 = object_num; + arglist = player_num; + if ( dropGoldFlag ) + { + dropGoldFlag = 0; + dropGoldValue = 0; + } + v3 = object_num; + v4 = &object[object_num]._oSelFlag; + if ( _LOBYTE(object[object_num]._oSelFlag) ) + { + SetRndSeed(object[v3]._oRndSeed); + v5 = deltaload; + *(_BYTE *)v4 = 0; + if ( v5 ) + { + v6 = object[v3]._oAnimLen; + object[v3]._oAnimFlag = 0; + object[v3]._oAnimFrame = v6; + } + else + { + PlaySfxLoc(sfx_id, object[v3]._ox, object[v3]._oy); + object[v3]._oAnimFlag = 1; + object[v3]._oAnimDelay = 1; + v5 = deltaload; + } + v7 = object[v3]._oVar1; + switch ( v7 ) + { + case 0: + if ( !v5 && arglist == myplr ) + { + ModifyPlrStr(arglist, -1); + ModifyPlrMag(arglist, -1); + ModifyPlrDex(arglist, -1); + ModifyPlrVit(arglist, -1); + _LOBYTE(v8) = 0; + v9 = random(v8, 4); + if ( v9 ) + { + v10 = v9 - 1; + if ( v10 ) + { + v11 = v10 - 1; + if ( v11 ) + { + if ( v11 == 1 ) + ModifyPlrVit(arglist, 6); + } + else + { + ModifyPlrDex(arglist, 6); + } + } + else + { + ModifyPlrMag(arglist, 6); + } + } + else + { + ModifyPlrStr(arglist, 6); + } + CheckStats(arglist); + _LOBYTE(v7) = 12; + goto LABEL_221; + } + return; + case 1: + v12 = 0; + if ( v5 || arglist != myplr ) + return; + v13 = arglist; + v14 = 7; + v15 = &plr[arglist].InvBody[0]._itype; + v7 = 7; + do + { + if ( *v15 != -1 ) + ++v12; + v15 += 92; + --v7; + } + while ( v7 ); + if ( v12 <= 0 ) + goto LABEL_47; + v16 = &plr[v13].InvBody[0]._iMaxDur; + do + { + if ( *(v16 - 58) != -1 ) + { + v7 = *v16; + if ( *v16 != 255 ) + { + if ( v7 ) + { + *(v16 - 1) += 10; + v17 = *(v16 - 1); + v7 += 10; + *v16 = v7; + if ( v17 > v7 ) + *(v16 - 1) = v7; + } + } + } + v16 += 92; + --v14; + } + while ( v14 ); + while ( 1 ) + { + v18 = 0; + v19 = &plr[v13].InvBody[0]._iMaxDur; + v20 = 7; + do + { + if ( *(v19 - 58) != -1 ) + { + v7 = *v19; + if ( *v19 != 255 ) + { + if ( v7 ) + ++v18; + } + } + v19 += 92; + --v20; + } + while ( v20 ); + if ( !v18 ) + goto LABEL_47; + _LOBYTE(v7) = 0; + v21 = random(v7, 7); + v7 = v13 * 21720 + 368 * v21; + if ( *(int *)((char *)&plr[0].InvBody[0]._itype + v7) != -1 ) + { + v7 = *(int *)((char *)&plr[0].InvBody[0]._iMaxDur + v7); + if ( v7 != 255 ) + { + if ( v7 ) + break; + } + } + } + v22 = 368 * v21 + v13 * 21720; + v23 = (int *)((char *)&plr[0].InvBody[0]._iDurability + v22); + v7 = (int)&plr[0].InvBody[0]._iMaxDur + v22; + *v23 -= 20; + v24 = *v23; + *(_DWORD *)v7 -= 20; + v25 = *(_DWORD *)v7; + if ( v24 <= 0 ) + *v23 = 1; + if ( v25 <= 0 ) + *(_DWORD *)v7 = 1; +LABEL_47: + _LOBYTE(v7) = 13; + goto LABEL_221; + case 2: + if ( v5 ) + return; + if ( arglist != myplr ) + goto LABEL_280; + v26 = arglist; + if ( plr[arglist].InvBody[0]._itype != ITYPE_NONE ) + plr[v26].InvBody[0]._iAC += 2; + if ( plr[v26].InvBody[6]._itype != ITYPE_NONE ) + plr[v26].InvBody[6]._iAC += 2; + v27 = plr[v26].InvBody[4]._itype; + if ( v27 != ITYPE_NONE ) + { + if ( v27 == ITYPE_SHIELD ) + { + plr[v26].InvBody[4]._iAC += 2; + } + else + { + v28 = plr[v26].InvBody[4]._iMinDam; + v29 = &plr[v26].InvBody[4]._iMaxDam; + --*v29; + if ( plr[v26].InvBody[4]._iMaxDam < v28 ) + *v29 = v28; + } + } + v7 = plr[v26].InvBody[5]._itype; + if ( v7 != ITYPE_NONE ) + { + if ( v7 == ITYPE_SHIELD ) + { + plr[v26].InvBody[5]._iAC += 2; + } + else + { + v30 = plr[v26].InvBody[5]._iMinDam; + v7 = (int)&plr[v26].InvBody[5]._iMaxDam; + --*(_DWORD *)v7; + if ( plr[v26].InvBody[5]._iMaxDam < v30 ) + *(_DWORD *)v7 = v30; + } + } + v31 = 0; + if ( plr[v26]._pNumInv <= 0 ) + goto LABEL_73; + v7 = (int)&plr[v26].InvList[0]._iAC; + break; + case 3: + if ( v5 ) + return; + if ( arglist != myplr ) + goto LABEL_280; + v34 = arglist; + v35 = plr[arglist].InvBody[4]._itype; + if ( v35 != ITYPE_NONE && v35 != ITYPE_SHIELD ) + ++plr[v34].InvBody[4]._iMaxDam; + v7 = plr[v34].InvBody[5]._itype; + if ( v7 != ITYPE_NONE && v7 != ITYPE_SHIELD ) + ++plr[v34].InvBody[5]._iMaxDam; + v36 = 0; + if ( plr[v34]._pNumInv > 0 ) + { + v7 = (int)&plr[v34].InvList[0]._iMaxDam; + do + { + v37 = *(_DWORD *)(v7 - 200); + if ( v37 > 0 && (v37 <= 4 || v37 == 10) ) + ++*(_DWORD *)v7; + ++v36; + v7 += 368; + } + while ( v36 < plr[v34]._pNumInv ); + } + _LOBYTE(v7) = 15; + goto LABEL_221; + case 4: + case 11: + if ( v5 ) + return; + AddMissile( + plr[arglist].WorldX, + plr[arglist].WorldY, + plr[arglist].WorldX, + plr[arglist].WorldY, + plr[arglist]._pdir, + 13, + -1, + arglist, + 0, + 2 * (unsigned char)leveltype); + if ( arglist != myplr ) + return; + _LOBYTE(v7) = 16; + goto LABEL_221; + case 5: + if ( v5 ) + return; + if ( arglist != myplr ) + goto LABEL_280; + v38 = arglist; + v39 = &plr[arglist].InvBody[0]._iMaxCharges; + v40 = 7; + do + { + if ( *(v39 - 56) == 10 ) + *(v39 - 1) = *v39; + v39 += 92; + --v40; + } + while ( v40 ); + v41 = 0; + if ( plr[v38]._pNumInv > 0 ) + { + v42 = &plr[v38].InvList[0]._iMaxCharges; + do + { + if ( *(v42 - 56) == 10 ) + *(v42 - 1) = *v42; + ++v41; + v42 += 92; + } + while ( v41 < plr[v38]._pNumInv ); + } + v43 = &plr[v38].SpdList[0]._iMaxCharges; + v44 = 8; + do + { + if ( *(v43 - 56) == 10 ) + *(v43 - 1) = *v43; + v43 += 92; + --v44; + } + while ( v44 ); + v7 = 17; + goto LABEL_221; + case 6: + if ( v5 ) + return; + if ( arglist != myplr ) + goto LABEL_280; + v45 = arglist; + v46 = &plr[arglist].InvBody[0]._iDurability; + v47 = 7; + do + { + *v46 = v46[1]; + v46 += 92; + --v47; + } + while ( v47 ); + v48 = 0; + if ( plr[v45]._pNumInv > 0 ) + { + v49 = &plr[v45].InvList[0]._iDurability; + do + { + ++v48; + *v49 = v49[1]; + v49 += 92; + } + while ( v48 < plr[v45]._pNumInv ); + } + v50 = &plr[v45].SpdList[0]._iDurability; + v51 = 8; + do + { + *v50 = v50[1]; + v50 += 92; + --v51; + } + while ( v51 ); + v7 = 18; + goto LABEL_221; + case 7: + if ( v5 || arglist != myplr ) + return; + sfx_ida = 0; + i = 0; + v52 = 1; + v53 = arglist; + v54 = plr[arglist]._pMemSpells[1]; + v139 = 37; + do + { + v7 = i & v54; + if ( i & v54 | v52 & plr[arglist]._pMemSpells[0] ) + ++sfx_ida; + v55 = __PAIR__((unsigned int)i, v52) >> 31; + v52 *= 2; + v56 = v139-- == 1; + i = v55; + } + while ( !v56 ); + v57 = 1; + if ( sfx_ida > 1 ) + { + v58 = 0; + v59 = 1; + do + { + v7 = v58 & plr[v53]._pMemSpells[1]; + if ( v7 | v57 & plr[v53]._pMemSpells[0] ) + { + v7 = (int)&plr[v53]._pSplLvl[v59]; + if ( *(_BYTE *)v7 < 15 ) + ++*(_BYTE *)v7; + } + v58 = __PAIR__(v58, v57) >> 31; + v57 *= 2; + ++v59; + } + while ( v59 <= 37 ); + do + { + _LOBYTE(v7) = 0; + v60 = random(v7, 37); + v7 = v60; + } + while ( !(plr[v53]._pMemSpells[1] & ((unsigned __int64)(1i64 << v60) >> 32) | plr[v53]._pMemSpells[0] & (unsigned int)(1i64 << v60)) ); + v61 = &plr[v53]._pSplLvl[v60 + 1]; + if ( *v61 < 2 ) + *v61 = 0; + else + *v61 -= 2; + } + _LOBYTE(v7) = 19; + goto LABEL_221; + case 8: + for ( j = 0; j < nobjects; ++j ) + { + v63 = objectactive[j]; + v7 = object[v63]._otype; + if ( (v7 == OBJ_CHEST1 || v7 == OBJ_CHEST2 || v7 == OBJ_CHEST3) && !_LOBYTE(object[v63]._oSelFlag) ) + { + v64 = GetRndSeed(); + object[v63]._oAnimFrame -= 2; + object[v63]._oRndSeed = v64; + v5 = deltaload; + _LOBYTE(object[v63]._oSelFlag) = 1; + } + } + if ( v5 ) + return; + if ( arglist != myplr ) + goto LABEL_280; + _LOBYTE(v7) = 20; + goto LABEL_221; + case 9: + if ( v5 || arglist != myplr ) + return; + v7 = 21720 * arglist; + v65 = plr[arglist]._pMemSpells; + v66 = plr[arglist]._pMemSpells[1]; + *v65 |= 1u; + v65[1] = v66; + v67 = plr[arglist]._pSplLvl[1]; + if ( v67 < 15 ) + plr[0]._pSplLvl[v7 + 1] = v67 + 1; + v68 = plr[0]._pSplLvl[v7 + 1]; + if ( v68 < 15 ) + plr[0]._pSplLvl[v7 + 1] = v68 + 1; + v69 = *(int *)((char *)&plr[0]._pMaxManaBase + v7); + v70 = *(int *)((char *)&plr[0]._pManaBase + v7); + v71 = *(int *)((char *)&plr[0]._pMana + v7) - v70; + v72 = *(int *)((char *)&plr[0]._pMaxManaBase + v7) / 10; + v73 = *(int *)((char *)&plr[0]._pMaxMana + v7) - v69; + *(int *)((char *)&plr[0]._pManaBase + v7) = v70 - v72; + v74 = *(int *)((char *)&plr[0]._pMana + v7) - v72; + sfx_ide = v74; + *(int *)((char *)&plr[0]._pMana + v7) = v74; + v75 = *(int *)((char *)&plr[0]._pMaxMana + v7); + *(int *)((char *)&plr[0]._pMaxManaBase + v7) = v69 - v72; + v76 = v75 - v72; + *(int *)((char *)&plr[0]._pMaxMana + v7) = v76; + if ( (signed int)(sfx_ide & 0xFFFFFFC0) <= 0 ) + { + *(int *)((char *)&plr[0]._pManaBase + v7) = 0; + *(int *)((char *)&plr[0]._pMana + v7) = v71; + } + if ( (signed int)(v76 & 0xFFFFFFC0) <= 0 ) + { + *(int *)((char *)&plr[0]._pMaxManaBase + v7) = 0; + *(int *)((char *)&plr[0]._pMaxMana + v7) = v73; + } + _LOBYTE(v7) = 21; + goto LABEL_221; + case 10: + if ( v5 ) + return; + v77 = arglist; + AddMissile( + plr[arglist].WorldX, + plr[arglist].WorldY, + plr[arglist].WorldX, + plr[arglist].WorldY, + plr[arglist]._pdir, + 42, + -1, + arglist, + 0, + 2 * (unsigned char)leveltype); + if ( arglist != myplr ) + return; + _LOBYTE(v7) = 22; + plr[v77]._pMana = plr[v77]._pMaxMana; + plr[v77]._pManaBase = plr[v77]._pMaxManaBase; + goto LABEL_221; + case 12: + if ( v5 ) + return; + if ( arglist != myplr ) + goto LABEL_280; + sfx_idb = 0; + v78 = arglist; + if ( plr[arglist]._pNumInv > 0 ) + { + v79 = &plr[v78].InvList[0]._iMiscId; + v140 = &plr[v78].InvList[0]._iMiscId; + do + { + if ( !*(v79 - 53) ) + { + if ( *v79 == IMISC_HEAL || *v79 == IMISC_MANA ) + { + v80 = ItemMiscIdIdx(18); + SetPlrHandItem(&plr[v78].HoldItem, v80); + GetPlrHandSeed(&plr[v78].HoldItem); + v79 = v140; + plr[v78].HoldItem._iStatFlag = 1; + qmemcpy(v140 - 55, &plr[v78].HoldItem, 0x170u); + } + if ( *v79 == IMISC_FULLHEAL || *v79 == IMISC_FULLMANA ) + { + v81 = ItemMiscIdIdx(19); + SetPlrHandItem(&plr[v78].HoldItem, v81); + GetPlrHandSeed(&plr[v78].HoldItem); + v79 = v140; + plr[v78].HoldItem._iStatFlag = 1; + qmemcpy(v140 - 55, &plr[v78].HoldItem, 0x170u); + } + } + ++sfx_idb; + v79 += 92; + v7 = sfx_idb; + v140 = v79; + } + while ( sfx_idb < plr[v78]._pNumInv ); + } + v82 = &plr[v78].SpdList[0]._iMiscId; + v141 = 8; + sfx_idc = &plr[v78].SpdList[0]._iMiscId; + do + { + if ( !*(v82 - 53) ) + { + if ( *v82 == IMISC_HEAL || *v82 == IMISC_MANA ) + { + v83 = ItemMiscIdIdx(18); + SetPlrHandItem(&plr[v78].HoldItem, v83); + GetPlrHandSeed(&plr[v78].HoldItem); + v82 = sfx_idc; + plr[v78].HoldItem._iStatFlag = 1; + qmemcpy(sfx_idc - 55, &plr[v78].HoldItem, 0x170u); + } + v7 = *v82; + if ( *v82 == IMISC_FULLHEAL || v7 == IMISC_FULLMANA ) + { + v84 = ItemMiscIdIdx(19); + SetPlrHandItem(&plr[v78].HoldItem, v84); + GetPlrHandSeed(&plr[v78].HoldItem); + v82 = sfx_idc; + plr[v78].HoldItem._iStatFlag = 1; + qmemcpy(sfx_idc - 55, &plr[v78].HoldItem, 0x170u); + v7 = 0; + } + } + v82 += 92; + v56 = v141-- == 1; + sfx_idc = v82; + } + while ( !v56 ); + _LOBYTE(v7) = 24; + goto LABEL_221; + case 13: + if ( v5 || arglist != myplr ) + return; + ModifyPlrMag(arglist, 2); + CheckStats(arglist); + _LOBYTE(v7) = 25; + goto LABEL_221; + case 14: + if ( v5 || arglist != myplr ) + return; + v85 = object[v3]._ox; + v86 = object[v3]._oy; + if ( 2 * currlevel >= 7 ) + { + CreateTypeItem(v85, v86, 0, 0, 19, 0, 1); + CreateTypeItem(object[v3]._ox, object[v3]._oy, 0, 0, 19, 0, 1); + } + else + { + CreateTypeItem(v85, v86, 0, 0, 7, 0, 1); + CreateTypeItem(object[v3]._ox, object[v3]._oy, 0, 0, 2, 0, 1); + } + v87 = arglist; + plr[v87]._pMana = plr[arglist]._pMaxMana; + plr[v87]._pManaBase = plr[arglist]._pMaxManaBase; + plr[v87]._pHitPoints = plr[arglist]._pMaxHP; + v7 = plr[arglist]._pMaxHPBase; + plr[v87]._pHPBase = v7; + _LOBYTE(v7) = 26; + goto LABEL_221; + case 15: + if ( v5 ) + return; + v88 = 0; + do + { + _LOBYTE(v7) = -97; + v89 = random(v7, 112); + _LOBYTE(v90) = -97; + v91 = v89; + v92 = random(v90, 112); + if ( ++v88 > 12544 ) + break; + v7 = v92 + 112 * v91; + v93 = v92 + 112 * v91; + } + while ( nSolidTable[dPiece[0][v93]] || dObject[0][v7] || dMonster[0][v93] ); + AddMissile( + plr[arglist].WorldX, + plr[arglist].WorldY, + v91, + v92, + plr[arglist]._pdir, + 3, + -1, + arglist, + 0, + 2 * (unsigned char)leveltype); + if ( arglist != myplr ) + return; + _LOBYTE(v7) = 27; + goto LABEL_221; + case 16: + if ( v5 || arglist != myplr ) + return; + v7 = 21720 * arglist; + v94 = plr[arglist]._pMemSpells; + v95 = plr[arglist]._pMemSpells[1]; + *((_BYTE *)v94 + 3) |= 0x20u; + v94[1] = v95; + v96 = plr[arglist]._pSplLvl[30]; + if ( v96 < 15 ) + plr[0]._pSplLvl[v7 + 30] = v96 + 1; + v97 = plr[0]._pSplLvl[v7 + 30]; + if ( v97 < 15 ) + plr[0]._pSplLvl[v7 + 30] = v97 + 1; + v98 = *(int *)((char *)&plr[0]._pMaxManaBase + v7); + v99 = *(int *)((char *)&plr[0]._pManaBase + v7); + v100 = *(int *)((char *)&plr[0]._pMana + v7) - v99; + v101 = *(int *)((char *)&plr[0]._pMaxManaBase + v7) / 10; + v102 = *(int *)((char *)&plr[0]._pMaxMana + v7) - v98; + *(int *)((char *)&plr[0]._pManaBase + v7) = v99 - v101; + v103 = *(int *)((char *)&plr[0]._pMana + v7) - v101; + sfx_idf = v103; + *(int *)((char *)&plr[0]._pMana + v7) = v103; + v104 = *(int *)((char *)&plr[0]._pMaxMana + v7); + *(int *)((char *)&plr[0]._pMaxManaBase + v7) = v98 - v101; + v105 = v104 - v101; + *(int *)((char *)&plr[0]._pMaxMana + v7) = v105; + if ( (signed int)(sfx_idf & 0xFFFFFFC0) <= 0 ) + { + *(int *)((char *)&plr[0]._pManaBase + v7) = 0; + *(int *)((char *)&plr[0]._pMana + v7) = v100; + } + if ( (signed int)(v105 & 0xFFFFFFC0) <= 0 ) + { + *(int *)((char *)&plr[0]._pMaxManaBase + v7) = 0; + *(int *)((char *)&plr[0]._pMaxMana + v7) = v102; + } + _LOBYTE(v7) = 28; + goto LABEL_221; + case 17: + if ( v5 || arglist != myplr ) + return; + sfx_idd = 0; + v106 = arglist; + do + { + if ( !plr[v106].InvGrid[sfx_idd] ) + { + _LOBYTE(v7) = -96; + v107 = 5 * (unsigned char)leveltype + random(v7, 10 * (unsigned char)leveltype); + v108 = plr[v106]._pNumInv; + v109 = v106 * 21720 + 368 * v108; + qmemcpy((char *)plr[0].InvList + v109, &golditem, 0x170u); + *(int *)((char *)&plr[0].InvList[0]._iSeed + v109) = GetRndSeed(); + ++plr[v106]._pNumInv; + plr[v106].InvGrid[sfx_idd] = plr[v106]._pNumInv; + *(int *)((char *)&plr[0].InvList[0]._ivalue + v109) = v107; + plr[v106]._pGold += v107; + SetGoldCurs(arglist, v108); + } + ++sfx_idd; + } + while ( sfx_idd < 40 ); + _LOBYTE(v7) = 29; + goto LABEL_221; + case 18: + if ( v5 ) + return; + if ( arglist == myplr ) + { + _LOBYTE(v7) = 30; + goto LABEL_221; + } + _LOBYTE(v7) = 31; + InitDiabloMsg(v7); + v110 = myplr; + plr[v110]._pHitPoints = plr[myplr]._pMaxHP; + plr[v110]._pHPBase = plr[v110]._pMaxHPBase; + plr[v110]._pMana = plr[v110]._pMaxMana; + plr[v110]._pManaBase = plr[v110]._pMaxManaBase; + goto LABEL_280; + case 19: + if ( v5 || arglist != myplr ) + return; + ModifyPlrDex(arglist, 2); + CheckStats(arglist); + if ( arglist != myplr ) + goto LABEL_280; + _LOBYTE(v7) = 32; + goto LABEL_221; + case 20: + if ( v5 || arglist != myplr ) + return; + ModifyPlrStr(arglist, 2); + CheckStats(arglist); + if ( arglist != myplr ) + goto LABEL_280; + _LOBYTE(v7) = 33; + goto LABEL_221; + case 21: + if ( v5 || arglist != myplr ) + return; + ModifyPlrVit(arglist, 2); + CheckStats(arglist); + if ( arglist != myplr ) + goto LABEL_280; + _LOBYTE(v7) = 34; + goto LABEL_221; + case 22: + if ( v5 ) + return; + if ( arglist != myplr ) + goto LABEL_280; + v7 = 0; + do + { + v111 = (unsigned char *)automapview + v7; + v112 = 40; + do + { + *v111 = 1; + v111 += 40; + --v112; + } + while ( v112 ); + ++v7; + } + while ( v7 < 40 ); + _LOBYTE(v7) = 35; + goto LABEL_221; + case 23: + if ( v5 || arglist != myplr ) + return; + v7 = 21720 * arglist; + v113 = plr[arglist]._pMemSpells; + v114 = plr[arglist]._pMemSpells[1]; + *((_BYTE *)v113 + 3) |= 0x40u; + v113[1] = v114; + v115 = plr[arglist]._pSplLvl[31]; + if ( v115 < 15 ) + plr[0]._pSplLvl[v7 + 31] = v115 + 1; + v116 = plr[0]._pSplLvl[v7 + 31]; + if ( v116 < 15 ) + plr[0]._pSplLvl[v7 + 31] = v116 + 1; + v117 = *(int *)((char *)&plr[0]._pMaxManaBase + v7); + v118 = *(int *)((char *)&plr[0]._pManaBase + v7); + v119 = *(int *)((char *)&plr[0]._pMana + v7) - v118; + v120 = *(int *)((char *)&plr[0]._pMaxManaBase + v7) / 10; + v121 = *(int *)((char *)&plr[0]._pMaxMana + v7) - v117; + *(int *)((char *)&plr[0]._pManaBase + v7) = v118 - v120; + v122 = *(int *)((char *)&plr[0]._pMana + v7) - v120; + sfx_idg = v122; + *(int *)((char *)&plr[0]._pMana + v7) = v122; + v123 = *(int *)((char *)&plr[0]._pMaxMana + v7); + *(int *)((char *)&plr[0]._pMaxManaBase + v7) = v117 - v120; + v124 = v123 - v120; + *(int *)((char *)&plr[0]._pMaxMana + v7) = v124; + if ( (signed int)(sfx_idg & 0xFFFFFFC0) <= 0 ) + { + *(int *)((char *)&plr[0]._pManaBase + v7) = 0; + *(int *)((char *)&plr[0]._pMana + v7) = v119; + } + if ( (signed int)(v124 & 0xFFFFFFC0) <= 0 ) + { + *(int *)((char *)&plr[0]._pMaxManaBase + v7) = 0; + *(int *)((char *)&plr[0]._pMaxMana + v7) = v121; + } + _LOBYTE(v7) = 36; + goto LABEL_221; + case 24: + if ( v5 || arglist != myplr ) + return; + v125 = arglist; + v126 = &plr[arglist].InvBody[0]._iIdentified; + v127 = 7; + do + { + if ( *((_BYTE *)v126 + 4) && !*v126 ) + *v126 = 1; + v126 += 92; + --v127; + } + while ( v127 ); + v128 = 0; + if ( plr[v125]._pNumInv > 0 ) + { + v129 = &plr[v125].InvList[0]._iIdentified; + do + { + if ( *((_BYTE *)v129 + 4) && !*v129 ) + *v129 = 1; + ++v128; + v129 += 92; + } + while ( v128 < plr[v125]._pNumInv ); + } + v130 = &plr[v125].SpdList[0]._iIdentified; + v131 = 8; + do + { + if ( *((_BYTE *)v130 + 4) && !*v130 ) + *v130 = 1; + v130 += 92; + --v131; + } + while ( v131 ); + v7 = 37; + goto LABEL_221; + case 25: + if ( v5 ) + return; + if ( arglist == myplr ) + { + _LOBYTE(v7) = 38; + goto LABEL_221; + } + _LOBYTE(v7) = 39; + InitDiabloMsg(v7); + _LOBYTE(v132) = -101; + v133 = random(v132, 4); + v134 = 1; + v135 = 2 * (v133 == 1) - 1; + if ( v133 == 2 || (v134 = -1, v133 != 3) ) + v136 = -1; + else + v136 = 1; + ModifyPlrStr(myplr, 2 * (v133 == 0) - 1); + ModifyPlrMag(myplr, v135); + ModifyPlrDex(myplr, v134); + ModifyPlrVit(myplr, v136); + CheckStats(myplr); + goto LABEL_280; + default: + goto LABEL_280; + } + while ( 1 ) + { + v32 = *(_DWORD *)(v7 - 204); + if ( v32 > 0 ) + { + if ( v32 <= 4 ) + goto LABEL_70; + if ( v32 <= 9 ) + { + *(_DWORD *)v7 += 2; + } + else if ( v32 == 10 ) + { +LABEL_70: + --*(_DWORD *)(v7 - 4); + v33 = *(_DWORD *)(v7 - 8); + if ( *(_DWORD *)(v7 - 4) < v33 ) + *(_DWORD *)(v7 - 4) = v33; + goto LABEL_72; + } + } +LABEL_72: + ++v31; + v7 += 368; + if ( v31 >= plr[v26]._pNumInv ) + { +LABEL_73: + _LOBYTE(v7) = 14; +LABEL_221: + InitDiabloMsg(v7); +LABEL_280: + CalcPlrInv(arglist, 1u); + force_redraw = 255; + if ( arglist == myplr ) + NetSendCmdParam2(0, CMD_PLROPOBJ, arglist, param2); + return; + } + } + } +} +// 4B84DC: using guessed type int dropGoldFlag; +// 52571C: using guessed type int force_redraw; +// 5BB1ED: using guessed type char leveltype; +// 676190: using guessed type int deltaload; + +//----- (00446E6A) -------------------------------------------------------- +void __fastcall OperateSkelBook(int pnum, int i, unsigned char sendmsg) +{ + unsigned short v3; // di + int v4; // esi + bool v5; // zf + int v6; // ecx + int v7; // eax + int v8; // ecx + int v9; // edx + int v10; // [esp+Ch] [ebp-4h] + + v3 = i; + v4 = i; + v10 = pnum; + if ( _LOBYTE(object[i]._oSelFlag) ) + { + if ( !deltaload ) + PlaySfxLoc(IS_ISCROL, object[v4]._ox, object[v4]._oy); + object[v4]._oAnimFrame += 2; + v5 = deltaload == 0; + _LOBYTE(object[v4]._oSelFlag) = 0; + if ( v5 ) + { + SetRndSeed(object[v4]._oRndSeed); + _LOBYTE(v6) = -95; + v7 = random(v6, 5); + v8 = object[v4]._ox; + v9 = object[v4]._oy; + if ( v7 ) + CreateTypeItem(v8, v9, 0, 0, 21, sendmsg, 0); + else + CreateTypeItem(v8, v9, 0, 0, 24, sendmsg, 0); + if ( v10 == myplr ) + NetSendCmdParam1(0, CMD_OPERATEOBJ, v3); + } + } +} +// 676190: using guessed type int deltaload; + +//----- (00446F08) -------------------------------------------------------- +void __fastcall OperateBookCase(int pnum, int i, unsigned char sendmsg) +{ + unsigned short v3; // di + int v4; // ebp + int v5; // esi + bool v6; // zf + int v7; // eax + + v3 = i; + v4 = pnum; + v5 = i; + if ( _LOBYTE(object[i]._oSelFlag) ) + { + if ( !deltaload ) + PlaySfxLoc(IS_ISCROL, object[v5]._ox, object[v5]._oy); + object[v5]._oAnimFrame -= 2; + v6 = deltaload == 0; + _LOBYTE(object[v5]._oSelFlag) = 0; + if ( v6 ) + { + SetRndSeed(object[v5]._oRndSeed); + CreateTypeItem(object[v5]._ox, object[v5]._oy, 0, 0, 24, sendmsg, 0); + _LOBYTE(v7) = QuestStatus(3); + if ( v7 + && monster[4].mName == UniqMonst[2].mName + && _LOBYTE(monster[4]._msquelch) == -1 + && monster[4]._mhitpoints ) + { + monster[4].mtalkmsg = TEXT_ZHAR2; + M_StartStand(0, monster[4]._mdir); + _LOBYTE(monster[4]._mgoal) = 5; + monster[4]._mmode = MM_TALK; + } + if ( v4 == myplr ) + NetSendCmdParam1(0, CMD_OPERATEOBJ, v3); + } + } +} +// 676190: using guessed type int deltaload; + +//----- (00446FE8) -------------------------------------------------------- +void __fastcall OperateDecap(int pnum, int i, unsigned char sendmsg) +{ + unsigned short v3; // bp + int v4; // esi + int v5; // edi + int *v6; // eax + bool v7; // zf + + v3 = i; + v4 = i; + v5 = pnum; + v6 = &object[i]._oSelFlag; + if ( *(_BYTE *)v6 ) + { + v7 = deltaload == 0; + *(_BYTE *)v6 = 0; + if ( v7 ) + { + SetRndSeed(object[v4]._oRndSeed); + CreateRndItem(object[v4]._ox, object[v4]._oy, 0, sendmsg, 0); + if ( v5 == myplr ) + NetSendCmdParam1(0, CMD_OPERATEOBJ, v3); + } + } +} +// 676190: using guessed type int deltaload; + +//----- (00447046) -------------------------------------------------------- +void __fastcall OperateArmorStand(int pnum, int i, unsigned char sendmsg) +{ + unsigned short v3; // di + int v4; // esi + int *v5; // eax + bool v6; // zf + int v7; // ecx + unsigned char v8; // al + int v9; // [esp-10h] [ebp-20h] + int v10; // [esp-8h] [ebp-18h] + int v11; // [esp+Ch] [ebp-4h] + + v3 = i; + v4 = i; + v11 = pnum; + v5 = &object[i]._oSelFlag; + if ( *(_BYTE *)v5 ) + { + ++object[v4]._oAnimFrame; + v6 = deltaload == 0; + *(_BYTE *)v5 = 0; + if ( v6 ) + { + SetRndSeed(object[v4]._oRndSeed); + _LOBYTE(v7) = 0; + v8 = random(v7, 2); + if ( currlevel > 5u ) + { + if ( currlevel >= 6u && currlevel <= 9u ) + { + CreateTypeItem(object[v4]._ox, object[v4]._oy, v8, 8, 0, sendmsg, 0); + goto LABEL_15; + } + if ( currlevel >= 0xAu && currlevel <= 0xCu ) + { + CreateTypeItem(object[v4]._ox, object[v4]._oy, 0, 9, 0, sendmsg, 0); + goto LABEL_15; + } + if ( currlevel < 0xDu || currlevel > 0x10u ) + goto LABEL_15; + v10 = sendmsg; + v9 = 9; + } + else + { + v10 = sendmsg; + v9 = 6; + } + CreateTypeItem(object[v4]._ox, object[v4]._oy, 1u, v9, 0, v10, 0); +LABEL_15: + if ( v11 == myplr ) + NetSendCmdParam1(0, CMD_OPERATEOBJ, v3); + return; + } + } +} +// 676190: using guessed type int deltaload; + +//----- (0044710C) -------------------------------------------------------- +void __fastcall FindValidShrine() +{ + signed int v0; // esi + int v1; // eax + bool v2; // zf + + do + { + v0 = 0; + do + { + v1 = random(0, 26); + if ( currlevel >= (signed int)(char)shrinemin[v1] && currlevel <= (signed int)(char)shrinemax[v1] && v1 != 8 ) + v0 = 1; + } + while ( !v0 ); + if ( gbMaxPlayers == 1 ) + v2 = shrineavail[v1] == 2; + else + v2 = shrineavail[v1] == 1; + } + while ( v2 ); +} +// 679660: using guessed type char gbMaxPlayers; + +//----- (0044715F) -------------------------------------------------------- +void __fastcall OperateGoatShrine(int pnum, int i, int sType) +{ + int v3; // edi + int v4; // ebx + int v5; // esi + int v6; // eax + + v3 = i; + v4 = pnum; + v5 = i; + SetRndSeed(object[i]._oRndSeed); + FindValidShrine(); + object[v5]._oVar1 = v6; + OperateShrine(v4, v3, sType); + object[v5]._oAnimDelay = 2; + force_redraw = 255; +} +// 52571C: using guessed type int force_redraw; + +//----- (004471AA) -------------------------------------------------------- +void __fastcall OperateCauldron(int pnum, int i, int sType) +{ + int v3; // edi + int v4; // ebx + int v5; // esi + int v6; // eax + + v3 = i; + v4 = pnum; + v5 = i; + SetRndSeed(object[i]._oRndSeed); + FindValidShrine(); + object[v5]._oVar1 = v6; + OperateShrine(v4, v3, sType); + object[v5]._oAnimFlag = 0; + object[v5]._oAnimFrame = 3; + force_redraw = 255; +} +// 52571C: using guessed type int force_redraw; + +//----- (004471FC) -------------------------------------------------------- +unsigned char __fastcall OperateFountains(int pnum, int i) +{ + unsigned short v2; // bx + int v3; // esi + int v4; // edi + unsigned char v5; // bp + int v6; // ecx + signed int v7; // ebx + int v8; // ebp + int v10; // eax + int v11; // esi + int v12; // eax + int v13; // eax + int v14; // edi + int v15; // edx + int v16; // edx + int v17; // ecx + int *v18; // eax + int v19; // ecx + int v20; // edi + int v21; // edx + int v22; // ecx + int v23; // [esp-4h] [ebp-20h] + signed int v24; // [esp+10h] [ebp-Ch] + signed int v25; // [esp+14h] [ebp-8h] + short param1; // [esp+18h] [ebp-4h] + + v2 = i; + v3 = i; + v4 = pnum; + param1 = i; + v5 = 0; + SetRndSeed(object[i]._oRndSeed); + switch ( object[v3]._otype ) + { + case OBJ_BLOODFTN: + if ( !deltaload && v4 == myplr ) + { + v20 = v4; + v23 = object[v3]._oy; + v15 = object[v3]._ox; + if ( plr[v20]._pHitPoints < plr[v20]._pMaxHP ) + { + PlaySfxLoc(LS_FOUNTAIN, v15, v23); + plr[v20]._pHitPoints += 64; + v21 = plr[v20]._pHitPoints; + v22 = plr[v20]._pMaxHP; + v18 = &plr[v20]._pHPBase; + *v18 += 64; + if ( v21 <= v22 ) + goto LABEL_39; + plr[v20]._pHitPoints = v22; + v19 = plr[v20]._pMaxHPBase; + goto LABEL_38; + } +LABEL_45: + PlaySfxLoc(LS_FOUNTAIN, v15, v23); + break; + } + return 0; + case OBJ_PURIFYINGFTN: + if ( !deltaload && v4 == myplr ) + { + v14 = v4; + v23 = object[v3]._oy; + v15 = object[v3]._ox; + if ( plr[v14]._pMana < plr[v14]._pMaxMana ) + { + PlaySfxLoc(LS_FOUNTAIN, v15, v23); + plr[v14]._pMana += 64; + v16 = plr[v14]._pMana; + v17 = plr[v14]._pMaxMana; + v18 = &plr[v14]._pManaBase; + *v18 += 64; + if ( v16 <= v17 ) + { +LABEL_39: + v5 = 1; + break; + } + plr[v14]._pMana = v17; + v19 = plr[v14]._pMaxManaBase; +LABEL_38: + *v18 = v19; + goto LABEL_39; + } + goto LABEL_45; + } + return 0; + case OBJ_MURKYFTN: + if ( _LOBYTE(object[v3]._oSelFlag) ) + { + if ( !deltaload ) + PlaySfxLoc(LS_FOUNTAIN, object[v3]._ox, object[v3]._oy); + _LOBYTE(object[v3]._oSelFlag) = 0; + if ( deltaload ) + return 0; + AddMissile( + plr[v4].WorldX, + plr[v4].WorldY, + plr[v4].WorldX, + plr[v4].WorldY, + plr[v4]._pdir, + 39, + -1, + v4, + 0, + 2 * (unsigned char)leveltype); + v5 = 1; + if ( v4 == myplr ) + NetSendCmdParam1(0, CMD_OPERATEOBJ, v2); + } + break; + default: + if ( object[v3]._otype == 82 && _LOBYTE(object[v3]._oSelFlag) ) + { + v7 = -1; + v8 = -1; + v25 = 0; + v24 = 0; + if ( !deltaload ) + PlaySfxLoc(LS_FOUNTAIN, object[v3]._ox, object[v3]._oy); + _LOBYTE(object[v3]._oSelFlag) = 0; + if ( deltaload || v4 != myplr ) + return 0; + do + { + _LOBYTE(v6) = 0; + v10 = random(v6, 4); + v11 = v10; + if ( v10 != v7 ) + { + if ( v10 ) + { + v12 = v10 - 1; + if ( v12 ) + { + v13 = v12 - 1; + if ( v13 ) + { + if ( v13 == 1 ) + ModifyPlrVit(v4, v8); + } + else + { + ModifyPlrDex(v4, v8); + } + } + else + { + ModifyPlrMag(v4, v8); + } + } + else + { + ModifyPlrStr(v4, v8); + } + v7 = v11; + v8 = 1; + ++v24; + } + if ( v24 > 1 ) + v25 = 1; + } + while ( !v25 ); + CheckStats(v4); + v5 = 1; + if ( v4 == myplr ) + NetSendCmdParam1(0, CMD_OPERATEOBJ, param1); + } + break; + } + force_redraw = 255; + return v5; +} +// 52571C: using guessed type int force_redraw; +// 5BB1ED: using guessed type char leveltype; +// 676190: using guessed type int deltaload; + +//----- (004474AD) -------------------------------------------------------- +void __fastcall OperateWeaponRack(int pnum, int i, unsigned char sendmsg) +{ + unsigned short v3; // di + int v4; // esi + int v5; // ecx + int v6; // eax + int v7; // eax + int v8; // eax + int v9; // eax + bool v10; // zf + int v11; // ecx + int v12; // edx + signed int v13; // [esp-4h] [ebp-14h] + int v14; // [esp+Ch] [ebp-4h] + + v3 = i; + v4 = i; + v14 = pnum; + if ( !_LOBYTE(object[i]._oSelFlag) ) + return; + SetRndSeed(object[v4]._oRndSeed); + _LOBYTE(v5) = 0; + v6 = random(v5, 4); + if ( v6 ) + { + v7 = v6 - 1; + if ( !v7 ) + { + v13 = 2; + goto LABEL_7; + } + v8 = v7 - 1; + if ( !v8 ) + { + v13 = 3; + goto LABEL_7; + } + if ( v8 == 1 ) + { + v13 = 4; +LABEL_7: + v9 = v13; + goto LABEL_12; + } + v9 = sendmsg; + } + else + { + v9 = 1; + } +LABEL_12: + ++object[v4]._oAnimFrame; + v10 = deltaload == 0; + _LOBYTE(object[v4]._oSelFlag) = 0; + if ( v10 ) + { + v11 = object[v4]._ox; + v12 = object[v4]._oy; + if ( (unsigned char)leveltype <= 1u ) + CreateTypeItem(v11, v12, 0, v9, 0, sendmsg, 0); + else + CreateTypeItem(v11, v12, 1u, v9, 0, sendmsg, 0); + if ( v14 == myplr ) + NetSendCmdParam1(0, CMD_OPERATEOBJ, v3); + } +} +// 5BB1ED: using guessed type char leveltype; +// 676190: using guessed type int deltaload; + +//----- (00447558) -------------------------------------------------------- +void __fastcall OperateStoryBook(int pnum, int i) +{ + unsigned short v2; // di + int v3; // esi + int v4; // ST04_4 + int v5; // edx + + v2 = i; + v3 = i; + if ( _LOBYTE(object[i]._oSelFlag) && !deltaload && !qtextflag && pnum == myplr ) + { + v4 = object[v3]._oy; + v5 = object[v3]._ox; + object[v3]._oAnimFrame = object[v3]._oVar4; + PlaySfxLoc(IS_ISCROL, v5, v4); + InitQTextMsg(object[v3]._oVar2); + NetSendCmdParam1(0, CMD_OPERATEOBJ, v2); + } +} +// 646D00: using guessed type char qtextflag; +// 676190: using guessed type int deltaload; + +//----- (004475BB) -------------------------------------------------------- +void __fastcall OperateLazStand(int pnum, int i) +{ + int v2; // eax + int v3; // edx + int xx; // [esp+4h] [ebp-8h] + int yy; // [esp+8h] [ebp-4h] + + v2 = i; + if ( _LOBYTE(object[i]._oSelFlag) && !deltaload && !qtextflag && pnum == myplr ) + { + v3 = object[v2]._oy; + ++object[v2]._oAnimFrame; + _LOBYTE(object[v2]._oSelFlag) = 0; + GetSuperItemLoc(object[v2]._ox, v3, &xx, &yy); + SpawnQuestItem(33, xx, yy, 0, 0); + } +} +// 646D00: using guessed type char qtextflag; +// 676190: using guessed type int deltaload; + +//----- (00447620) -------------------------------------------------------- +void __fastcall OperateObject(int pnum, int i, unsigned char TeleFlag) +{ + int v3; // esi + int v4; // edi + ObjectStruct *v5; // ebx + int v6; // ecx + bool sendmsg; // [esp+Ch] [ebp-4h] + + v3 = pnum; + v4 = i; + sendmsg = pnum == myplr; + v5 = &object[i]; + v6 = v5->_otype; + switch ( v5->_otype ) + { + case OBJ_L1LDOOR: + case OBJ_L1RDOOR: + if ( TeleFlag ) + { + if ( v6 == OBJ_L1LDOOR ) + OperateL1LDoor(v3, i, OBJ_L1LDOOR); + if ( v5->_otype == OBJ_L1RDOOR ) + OperateL1RDoor(v3, v4, 1u); + } + else if ( v3 == myplr ) + { + OperateL1Door(v3, i, 1u); + } + break; + case OBJ_LEVER: + case OBJ_SWITCHSKL: + OperateLever(v3, i); + break; + case OBJ_CHEST1: + case OBJ_CHEST2: + case OBJ_CHEST3: + case OBJ_TCHEST1: + case OBJ_TCHEST2: + case OBJ_TCHEST3: + OperateChest(v3, i, sendmsg); + break; + case OBJ_BOOK2L: + OperateBook(v3, i); + break; + case OBJ_BOOK2R: + OperateSChambBk(v3, i); + break; + case OBJ_L2LDOOR: + case OBJ_L2RDOOR: + if ( TeleFlag ) + { + if ( v6 == OBJ_L2LDOOR ) + OperateL2LDoor(v3, i, 1u); + if ( v5->_otype == OBJ_L2RDOOR ) + OperateL2RDoor(v3, v4, 1u); + } + else if ( v3 == myplr ) + { + OperateL2Door(v3, i, 1u); + } + break; + case OBJ_SARC: + OperateSarc(v3, i, sendmsg); + break; + case OBJ_FLAMELVR: + OperateTrapLvr(i); + break; + case OBJ_SHRINEL: + case OBJ_SHRINER: + OperateShrine(v3, i, 63); + break; + case OBJ_SKELBOOK: + case OBJ_BOOKSTAND: + OperateSkelBook(v3, i, sendmsg); + break; + case OBJ_BOOKCASEL: + case OBJ_BOOKCASER: + OperateBookCase(v3, i, sendmsg); + break; + case OBJ_BLOODFTN: + case OBJ_PURIFYINGFTN: + case OBJ_MURKYFTN: + case OBJ_TEARFTN: + OperateFountains(v3, i); + break; + case OBJ_DECAP: + OperateDecap(v3, i, sendmsg); + break; + case OBJ_BLINDBOOK: + case OBJ_BLOODBOOK: + case OBJ_STEELTOME: + OperateBookLever(v3, i); + break; + case OBJ_PEDISTAL: + OperatePedistal(v3, i); + break; + case OBJ_L3LDOOR: + case OBJ_L3RDOOR: + if ( TeleFlag ) + { + if ( v6 == OBJ_L3LDOOR ) + OperateL3LDoor(v3, i, 1u); + if ( v5->_otype == OBJ_L3RDOOR ) + OperateL3RDoor(v3, v4, 1u); + } + else if ( v3 == myplr ) + { + OperateL3Door(v3, i, 1u); + } + break; + case OBJ_ARMORSTAND: + case OBJ_WARARMOR: + OperateArmorStand(v3, i, sendmsg); + break; + case OBJ_GOATSHRINE: + OperateGoatShrine(v3, i, 112); + break; + case OBJ_CAULDRON: + OperateCauldron(v3, i, 95); + break; + case OBJ_STORYBOOK: + OperateStoryBook(v3, i); + break; + case OBJ_WARWEAP: + case OBJ_WEAPONRACK: + OperateWeaponRack(v3, i, sendmsg); + break; + case OBJ_MUSHPATCH: + OperateMushPatch(v3, i); + break; + case OBJ_LAZSTAND: + OperateLazStand(v3, i); + break; + case OBJ_SLAINHERO: + OperateSlainHero(v3, i, sendmsg); + break; + case OBJ_SIGNCHEST: + OperateInnSignChest(v3, i); + break; + default: + return; + } +} + +//----- (00447932) -------------------------------------------------------- +void __fastcall SyncOpL1Door(int pnum, int cmd, int i) +{ + signed int v3; // eax + ObjectStruct *v4; // esi + + if ( pnum != myplr ) + { + v3 = 0; + if ( cmd == 43 ) + { + if ( object[i]._oVar4 ) + return; + v3 = 1; + } + if ( cmd == 44 && object[i]._oVar4 == 1 ) + v3 = 1; + if ( v3 ) + { + v4 = &object[i]; + if ( v4->_otype == 1 ) + OperateL1LDoor(-1, i, 0); + if ( v4->_otype == OBJ_L1RDOOR ) + OperateL1RDoor(-1, i, 0); + } + } +} + +//----- (004479A3) -------------------------------------------------------- +void __fastcall SyncOpL2Door(int pnum, int cmd, int i) +{ + signed int v3; // eax + ObjectStruct *v4; // esi + + if ( pnum != myplr ) + { + v3 = 0; + if ( cmd == 43 ) + { + if ( object[i]._oVar4 ) + return; + v3 = 1; + } + if ( cmd == 44 && object[i]._oVar4 == 1 ) + v3 = 1; + if ( v3 ) + { + v4 = &object[i]; + if ( v4->_otype == OBJ_L2LDOOR ) + OperateL2LDoor(-1, i, 0); + if ( v4->_otype == OBJ_L2RDOOR ) + OperateL2RDoor(-1, i, 0); + } + } +} + +//----- (00447A15) -------------------------------------------------------- +void __fastcall SyncOpL3Door(int pnum, int cmd, int i) +{ + signed int v3; // eax + ObjectStruct *v4; // esi + + if ( pnum != myplr ) + { + v3 = 0; + if ( cmd == 43 ) + { + if ( object[i]._oVar4 ) + return; + v3 = 1; + } + if ( cmd == 44 && object[i]._oVar4 == 1 ) + v3 = 1; + if ( v3 ) + { + v4 = &object[i]; + if ( v4->_otype == OBJ_L3LDOOR ) + OperateL3LDoor(-1, i, 0); + if ( v4->_otype == OBJ_L3RDOOR ) + OperateL3RDoor(-1, i, 0); + } + } +} + +//----- (00447A87) -------------------------------------------------------- +void __fastcall SyncOpObject(int pnum, int cmd, int i) +{ + switch ( object[i]._otype ) + { + case OBJ_L1LDOOR: + case OBJ_L1RDOOR: + SyncOpL1Door(pnum, cmd, i); + break; + case OBJ_LEVER: + case OBJ_SWITCHSKL: + OperateLever(pnum, i); + break; + case OBJ_CHEST1: + case OBJ_CHEST2: + case OBJ_CHEST3: + case OBJ_TCHEST1: + case OBJ_TCHEST2: + case OBJ_TCHEST3: + OperateChest(pnum, i, 0); + break; + case OBJ_L2LDOOR: + case OBJ_L2RDOOR: + SyncOpL2Door(pnum, cmd, i); + break; + case OBJ_SARC: + OperateSarc(pnum, i, 0); + break; + case OBJ_SHRINEL: + case OBJ_SHRINER: + OperateShrine(pnum, i, 63); + break; + case OBJ_SKELBOOK: + case OBJ_BOOKSTAND: + OperateSkelBook(pnum, i, 0); + break; + case OBJ_BOOKCASEL: + case OBJ_BOOKCASER: + OperateBookCase(pnum, i, 0); + break; + case OBJ_DECAP: + OperateDecap(pnum, i, 0); + break; + case OBJ_BLINDBOOK: + case OBJ_BLOODBOOK: + case OBJ_STEELTOME: + OperateBookLever(pnum, i); + break; + case OBJ_PEDISTAL: + OperatePedistal(pnum, i); + break; + case OBJ_L3LDOOR: + case OBJ_L3RDOOR: + SyncOpL3Door(pnum, cmd, i); + break; + case OBJ_ARMORSTAND: + case OBJ_WARARMOR: + OperateArmorStand(pnum, i, 0); + break; + case OBJ_GOATSHRINE: + OperateGoatShrine(pnum, i, 112); + break; + case OBJ_CAULDRON: + OperateCauldron(pnum, i, 95); + break; + case OBJ_MURKYFTN: + case OBJ_TEARFTN: + OperateFountains(pnum, i); + break; + case OBJ_STORYBOOK: + OperateStoryBook(pnum, i); + break; + case OBJ_WARWEAP: + case OBJ_WEAPONRACK: + OperateWeaponRack(pnum, i, 0); + break; + case OBJ_MUSHPATCH: + OperateMushPatch(pnum, i); + break; + case OBJ_SLAINHERO: + OperateSlainHero(pnum, i, 0); + break; + case OBJ_SIGNCHEST: + OperateInnSignChest(pnum, i); + break; + default: + return; + } +} + +//----- (00447C2D) -------------------------------------------------------- +void __fastcall BreakCrux(int i) +{ + int v1; // esi + int v2; // edi + int v3; // edx + signed int v4; // eax + int v5; // ecx + int v6; // ebx + + v1 = i; + v2 = nobjects; + _LOBYTE(object[v1]._oBreak) = -1; + _LOBYTE(object[v1]._oSelFlag) = 0; + v3 = 0; + v4 = 1; + object[v1]._oAnimFlag = 1; + object[v1]._oAnimFrame = 1; + object[v1]._oAnimDelay = 1; + object[v1]._oSolidFlag = 1; + object[v1]._oMissFlag = 1; + if ( v2 <= 0 ) + goto LABEL_15; + do + { + v5 = objectactive[v3]; + v6 = object[v5]._otype; + if ( (v6 == OBJ_CRUX1 || v6 == OBJ_CRUX2 || v6 == OBJ_CRUX3) + && object[v1]._oVar8 == object[v5]._oVar8 + && _LOBYTE(object[v5]._oBreak) != -1 ) + { + v4 = 0; + } + ++v3; + } + while ( v3 < v2 ); + if ( v4 ) + { +LABEL_15: + if ( !deltaload ) + PlaySfxLoc(IS_LEVER, object[v1]._ox, object[v1]._oy); + DRLG_MRectTrans(object[v1]._oVar1, object[v1]._oVar2, object[v1]._oVar3, object[v1]._oVar4); + } +} +// 676190: using guessed type int deltaload; + +//----- (00447CEF) -------------------------------------------------------- +void __fastcall BreakBarrel(int pnum, int i, int dam, unsigned char forcebreak, int sendmsg) +{ + int v5; // esi + bool v6; // zf + int v7; // eax + int v8; // edx + int v9; // eax + int v10; // eax + int v11; // eax + char v12; // al + char v13; // al + int v14; // edx + int v15; // [esp-4h] [ebp-24h] + short param2; // [esp+Ch] [ebp-14h] + int param1; // [esp+10h] [ebp-10h] + int v18; // [esp+14h] [ebp-Ch] + int *v19; // [esp+18h] [ebp-8h] + int v20; // [esp+1Ch] [ebp-4h] + int forcebreaka; // [esp+2Ch] [ebp+Ch] + + param2 = i; + v5 = i; + param1 = pnum; + if ( _LOBYTE(object[i]._oSelFlag) ) + { + if ( forcebreak ) + { + object[v5]._oVar1 = 0; + } + else + { + object[v5]._oVar1 -= dam; + if ( pnum != myplr && object[v5]._oVar1 <= 0 ) + object[v5]._oVar1 = 1; + } + if ( object[v5]._oVar1 <= 0 ) + { + _LOBYTE(object[v5]._oBreak) = -1; + v6 = deltaload == 0; + object[v5]._oVar1 = 0; + object[v5]._oAnimFlag = 1; + object[v5]._oAnimFrame = 1; + object[v5]._oAnimDelay = 1; + object[v5]._oSolidFlag = 0; + object[v5]._oMissFlag = 1; + _LOBYTE(object[v5]._oSelFlag) = 0; + object[v5]._oPreFlag = 1; + if ( v6 ) + { + v8 = object[v5]._ox; + v15 = object[v5]._oy; + if ( object[v5]._otype == OBJ_BARRELEX ) + { + PlaySfxLoc(IS_BARLFIRE, v8, v15); + v9 = object[v5]._oy; + v20 = v9 - 1; + if ( v9 - 1 <= v9 + 1 ) + { + do + { + v10 = object[v5]._ox; + v18 = v10 - 1; + if ( v10 - 1 <= v10 + 1 ) + { + forcebreaka = 112 * (v10 - 1) + v20; + v19 = (int *)((char *)dMonster + 4 * forcebreaka); + do + { + v11 = *v19; + if ( *v19 > 0 ) + MonsterTrapHit(v11 - 1, 1, 4, 0, 1, 0); + v12 = dPlayer[0][forcebreaka]; + if ( v12 > 0 ) + PlayerMHit(v12 - 1, -1, 0, 8, 16, 1, 0, 0); + v13 = dObject[0][forcebreaka]; + if ( v13 > 0 ) + { + v14 = v13 - 1; + if ( object[v14]._otype == OBJ_BARRELEX && _LOBYTE(object[v14]._oBreak) != -1 ) + BreakBarrel(param1, v14, dam, 1u, sendmsg); + } + ++v18; + v19 += 112; + forcebreaka += 112; + } + while ( v18 <= object[v5]._ox + 1 ); + } + ++v20; + } + while ( v20 <= object[v5]._oy + 1 ); + } + } + else + { + PlaySfxLoc(IS_BARREL, v8, v15); + SetRndSeed(object[v5]._oRndSeed); + if ( object[v5]._oVar2 <= 1 ) + { + if ( object[v5]._oVar3 ) + CreateRndItem(object[v5]._ox, object[v5]._oy, 0, sendmsg, 0); + else + CreateRndUseful(param1, object[v5]._ox, object[v5]._oy, sendmsg); + } + if ( object[v5]._oVar2 >= 8 ) + SpawnSkeleton(object[v5]._oVar4, object[v5]._ox, object[v5]._oy); + } + if ( param1 == myplr ) + NetSendCmdParam2(0, CMD_BREAKOBJ, param1, param2); + } + else + { + v7 = object[v5]._oAnimLen; + object[v5]._oAnimCnt = 0; + object[v5]._oAnimFrame = v7; + object[v5]._oAnimDelay = 1000; + } + } + else if ( !deltaload ) + { + PlaySfxLoc(IS_IBOW, object[v5]._ox, object[v5]._oy); + } + } +} +// 676190: using guessed type int deltaload; + +//----- (00447F63) -------------------------------------------------------- +void __fastcall BreakObject(int pnum, int oi) +{ + int v2; // ebx + int v3; // ebp + int v4; // esi + int v5; // edi + int v6; // ecx + int v7; // ecx + int v8; // eax + + v2 = pnum; + v3 = oi; + if ( pnum == -1 ) + { + v7 = 10; + } + else + { + v4 = pnum; + _LOBYTE(pnum) = -93; + v5 = plr[v2]._pIMinDam; + v6 = v5 + random(pnum, plr[v2]._pIMaxDam - v5 + 1); + v7 = plr[v4]._pIBonusDamMod + plr[v4]._pDamageMod + v6 * plr[v4]._pIBonusDam / 100 + v6; + } + v8 = object[v3]._otype; + if ( v8 >= OBJ_CRUX1 ) + { + if ( v8 <= OBJ_CRUX3 ) + { + BreakCrux(v3); + } + else if ( v8 > OBJ_WEAPRACK && v8 <= OBJ_BARRELEX ) + { + BreakBarrel(v2, v3, v7, 0, 1); + } + } +} + +//----- (00447FEF) -------------------------------------------------------- +void __fastcall SyncBreakObj(int pnum, int oi) +{ + int v2; // eax + + v2 = object[oi]._otype; + if ( v2 >= OBJ_BARREL && v2 <= OBJ_BARRELEX ) + BreakBarrel(pnum, oi, 0, 1u, 0); +} + +//----- (00448010) -------------------------------------------------------- +void __fastcall SyncL1Doors(int i) +{ + int v1; // ebx + int v2; // eax + int v3; // esi + int v4; // edi + bool v5; // zf + + v1 = i; + v2 = i; + if ( object[i]._oVar4 ) + { + v3 = object[v2]._oy; + v4 = object[v2]._ox; + v5 = object[v2]._otype == 1; + object[v2]._oMissFlag = 1; + _LOBYTE(object[v2]._oSelFlag) = 2; + if ( v5 ) + { + if ( object[v2]._oVar1 == 214 ) + ObjSetMicro(v4, v3, 408); + else + ObjSetMicro(v4, v3, 393); + dArch[v4][v3] = 7; + objects_set_door_piece(v4 - 1, v3--); + } + else + { + ObjSetMicro(v4, v3, 395); + dArch[v4][v3] = 8; + objects_set_door_piece(v4--, v3 - 1); + } + DoorSet(v1, v4, v3); + } + else + { + object[v2]._oMissFlag = 0; + } +} + +//----- (004480BB) -------------------------------------------------------- +void __fastcall SyncCrux(int i) +{ + signed int v1; // ebx + int v2; // edx + int v3; // eax + int v4; // esi + + v1 = 1; + v2 = 0; + if ( nobjects <= 0 ) + goto LABEL_13; + do + { + v3 = objectactive[v2]; + v4 = object[v3]._otype; + if ( (v4 == OBJ_CRUX1 || v4 == OBJ_CRUX2 || v4 == OBJ_CRUX3) + && object[i]._oVar8 == object[v3]._oVar8 + && _LOBYTE(object[v3]._oBreak) != -1 ) + { + v1 = 0; + } + ++v2; + } + while ( v2 < nobjects ); + if ( v1 ) +LABEL_13: + DRLG_MRectTrans(object[i]._oVar1, object[i]._oVar2, object[i]._oVar3, object[i]._oVar4); +} + +//----- (00448139) -------------------------------------------------------- +void __fastcall SyncLever(int i) +{ + int v1; // ecx + + v1 = i; + if ( !_LOBYTE(object[v1]._oSelFlag) ) + DRLG_MRectTrans(object[v1]._oVar1, object[v1]._oVar2, object[v1]._oVar3, object[v1]._oVar4); +} + +//----- (00448163) -------------------------------------------------------- +void __fastcall SyncQSTLever(int i) +{ + int v1; // esi + int v2; // edx + int v3; // ecx + int v4; // ST04_4 + char v5; // bl + int v6; // ST00_4 + + v1 = i; + if ( object[i]._oAnimFrame == object[i]._oVar6 ) + { + ObjChangeMapResync(object[v1]._oVar1, object[v1]._oVar2, object[v1]._oVar3, object[v1]._oVar4); + if ( object[v1]._otype == OBJ_BLINDBOOK ) + { + v2 = object[v1]._oVar2; + v3 = object[v1]._oVar1; + v4 = object[v1]._oVar4; + v5 = TransVal; + v6 = object[v1]._oVar3; + TransVal = 9; + Make_RectTrans(v3, v2, v6, v4); + TransVal = v5; + } + } +} +// 5A5590: using guessed type char TransVal; + +//----- (004481D2) -------------------------------------------------------- +void __fastcall SyncPedistal(int i) +{ + int v1; // esi + unsigned char *v2; // esi + + v1 = i; + if ( object[i]._oVar6 == 1 ) + ObjChangeMapResync(setpc_x, setpc_y + 3, setpc_x + 2, setpc_y + 7); + if ( object[v1]._oVar6 == 2 ) + { + ObjChangeMapResync(setpc_x, setpc_y + 3, setpc_x + 2, setpc_y + 7); + ObjChangeMapResync(setpc_x + 6, setpc_y + 3, setpc_x + setpc_w, setpc_y + 7); + } + if ( object[v1]._oVar6 == 3 ) + { + ObjChangeMapResync(object[v1]._oVar1, object[v1]._oVar2, object[v1]._oVar3, object[v1]._oVar4); + v2 = LoadFileInMem("Levels\\L2Data\\Blood2.DUN", 0); + LoadMapObjs(v2, 2 * setpc_x, 2 * setpc_y); + mem_free_dbg(v2); + } +} +// 5CF334: using guessed type int setpc_w; + +//----- (00448298) -------------------------------------------------------- +void __fastcall SyncL2Doors(int i) +{ + int v1; // eax + int v2; // esi + int v3; // ecx + int v4; // edx + int v5; // eax + + v1 = i; + v2 = object[i]._oVar4; + if ( v2 ) + object[v1]._oMissFlag = 1; + else + object[v1]._oMissFlag = 0; + v3 = object[v1]._ox; + v4 = object[v1]._oy; + _LOBYTE(object[v1]._oSelFlag) = 2; + v5 = object[v1]._otype; + if ( v5 != OBJ_L2LDOOR ) + goto LABEL_18; + if ( !v2 ) + { + ObjSetMicro(v3, v4, 538); + return; + } + if ( v2 != 1 && v2 != 2 ) + { +LABEL_18: + if ( v5 == OBJ_L2RDOOR ) + { + if ( v2 ) + { + if ( v2 == 1 || v2 == 2 ) + ObjSetMicro(v3, v4, 17); + } + else + { + ObjSetMicro(v3, v4, 540); + } + } + } + else + { + ObjSetMicro(v3, v4, 13); + } +} + +//----- (0044831E) -------------------------------------------------------- +void __fastcall SyncL3Doors(int i) +{ + int v1; // eax + int v2; // esi + int v3; // ecx + int v4; // edx + int v5; // ebx + int v6; // eax + + v1 = i; + v2 = object[i]._otype; + v3 = object[i]._ox; + v4 = object[v1]._oy; + object[v1]._oMissFlag = 1; + _LOBYTE(object[v1]._oSelFlag) = 2; + if ( v2 != OBJ_L3LDOOR ) + goto LABEL_15; + if ( !object[v1]._oVar4 ) + { + ObjSetMicro(v3, v4, 531); + return; + } + v5 = object[v1]._oVar4; + if ( v5 != 1 && v5 != 2 ) + { +LABEL_15: + if ( v2 == OBJ_L3RDOOR ) + { + if ( object[v1]._oVar4 ) + { + v6 = object[v1]._oVar4; + if ( v6 == 1 || v6 == 2 ) + ObjSetMicro(v3, v4, 541); + } + else + { + ObjSetMicro(v3, v4, 534); + } + } + } + else + { + ObjSetMicro(v3, v4, 538); + } +} + +//----- (004483B0) -------------------------------------------------------- +void __fastcall SyncObjectAnim(int o) +{ + int v1; // edx + int v2; // ebx + int v3; // esi + + v1 = object[o]._otype; + v2 = ObjFileList[0]; + v3 = 0; + while ( v2 != (char)AllObjects[object[o]._otype].ofindex ) + v2 = ObjFileList[v3++ + 1]; + object[o]._oAnimCel = pObjCels[v3]; + if ( v1 <= OBJ_BOOK2R ) + { + if ( v1 != OBJ_BOOK2R ) + { + if ( v1 > OBJ_L1LIGHT ) + { + if ( v1 <= OBJ_L1RDOOR ) + { + SyncL1Doors(o); + } + else + { + if ( v1 == OBJ_LEVER ) + goto LABEL_30; + if ( v1 > OBJ_SKSTICK5 ) + { + if ( v1 <= OBJ_CRUX3 ) + { + SyncCrux(o); + return; + } + if ( v1 == OBJ_BOOK2L || v1 == OBJ_SWITCHSKL ) +LABEL_30: + SyncLever(o); + } + } + } + return; + } +LABEL_24: + SyncQSTLever(o); + return; + } + if ( v1 >= OBJ_L2LDOOR ) + { + if ( v1 <= OBJ_L2RDOOR ) + { + SyncL2Doors(o); + return; + } + if ( v1 == OBJ_BLINDBOOK ) + goto LABEL_24; + if ( v1 == OBJ_PEDISTAL ) + { + SyncPedistal(o); + return; + } + if ( v1 > OBJ_PEDISTAL ) + { + if ( v1 <= OBJ_L3RDOOR ) + { + SyncL3Doors(o); + return; + } + if ( v1 == OBJ_STEELTOME ) + goto LABEL_24; + } + } +} + +//----- (0044845E) -------------------------------------------------------- +void __fastcall GetObjectStr(int i) +{ + int v1; // edi + + v1 = i; + switch ( object[i]._otype ) + { + case OBJ_L1LDOOR: + case OBJ_L1RDOOR: + case OBJ_L2LDOOR: + case OBJ_L2RDOOR: + case OBJ_L3LDOOR: + case OBJ_L3RDOOR: + if ( object[v1]._oVar4 == 1 ) + strcpy(infostr, "Open Door"); + if ( !object[v1]._oVar4 ) + strcpy(infostr, "Closed Door"); + if ( object[v1]._oVar4 == 2 ) + strcpy(infostr, "Blocked Door"); + break; + case OBJ_LEVER: + case OBJ_FLAMELVR: + strcpy(infostr, "Lever"); + break; + case OBJ_CHEST1: + case OBJ_TCHEST1: + strcpy(infostr, "Small Chest"); + break; + case OBJ_CHEST2: + case OBJ_TCHEST2: + strcpy(infostr, "Chest"); + break; + case OBJ_CHEST3: + case OBJ_TCHEST3: + case OBJ_SIGNCHEST: + strcpy(infostr, "Large Chest"); + break; + case OBJ_CRUX1: + case OBJ_CRUX2: + case OBJ_CRUX3: + strcpy(infostr, "Crucified Skeleton"); + break; + case OBJ_BOOK2L: + if ( setlevel ) + { + if ( setlvlnum == SL_BONECHAMB ) + { + strcpy(infostr, "Ancient Tome"); + } + else if ( setlvlnum == SL_VILEBETRAYER ) + { + strcpy(infostr, "Book of Vileness"); + } + } + break; + case OBJ_SWITCHSKL: + strcpy(infostr, "Skull Lever"); + break; + case OBJ_BOOK2R: + strcpy(infostr, "Mythical Book"); + break; + case OBJ_SARC: + strcpy(infostr, "Sarcophagus"); + break; + case OBJ_BOOKSHELF: + strcpy(infostr, "Bookshelf"); + break; + case OBJ_BARREL: + case OBJ_BARRELEX: + strcpy(infostr, "Barrel"); + break; + case OBJ_SHRINEL: + case OBJ_SHRINER: + sprintf(tempstr, "%s Shrine", shrinestrs[object[v1]._oVar1]); + strcpy(infostr, tempstr); + break; + case OBJ_SKELBOOK: + strcpy(infostr, "Skeleton Tome"); + break; + case OBJ_BOOKCASEL: + case OBJ_BOOKCASER: + strcpy(infostr, "Bookcase"); + break; + case OBJ_BOOKSTAND: + strcpy(infostr, "Library Book"); + break; + case OBJ_BLOODFTN: + strcpy(infostr, "Blood Fountain"); + break; + case OBJ_DECAP: + strcpy(infostr, "Decapitated Body"); + break; + case OBJ_BLINDBOOK: + strcpy(infostr, "Book of the Blind"); + break; + case OBJ_BLOODBOOK: + strcpy(infostr, "Book of Blood"); + break; + case OBJ_PEDISTAL: + strcpy(infostr, "Pedestal of Blood"); + break; + case OBJ_PURIFYINGFTN: + strcpy(infostr, "Purifying Spring"); + break; + case OBJ_ARMORSTAND: + case OBJ_WARARMOR: + strcpy(infostr, "Armor"); + break; + case OBJ_GOATSHRINE: + strcpy(infostr, "Goat Shrine"); + break; + case OBJ_CAULDRON: + strcpy(infostr, "Cauldron"); + break; + case OBJ_MURKYFTN: + strcpy(infostr, "Murky Pool"); + break; + case OBJ_TEARFTN: + strcpy(infostr, "Fountain of Tears"); + break; + case OBJ_STORYBOOK: + strcpy(infostr, StoryBookName[object[v1]._oVar3]); + break; + case OBJ_STEELTOME: + strcpy(infostr, "Steel Tome"); + break; + case OBJ_WARWEAP: + case OBJ_WEAPONRACK: + strcpy(infostr, "Weapon Rack"); + break; + case OBJ_MUSHPATCH: + strcpy(infostr, "Mushroom Patch"); + break; + case OBJ_LAZSTAND: + strcpy(infostr, "Vile Stand"); + break; + case OBJ_SLAINHERO: + strcpy(infostr, "Slain Hero"); + break; + default: + break; + } + if ( _LOBYTE(plr[myplr]._pClass) == 1 ) + { + if ( object[v1]._oTrapFlag ) + { + sprintf(tempstr, "Trapped %s", infostr); + strcpy(infostr, tempstr); + _LOBYTE(infoclr) = 2; + } + } +} +// 4B883C: using guessed type int infoclr; +// 5CCB10: using guessed type char setlvlnum; +// 5CF31D: using guessed type char setlevel; + +//----- (0044875A) -------------------------------------------------------- +void __cdecl pack_cpp_init() +{ + hero_cpp_init_value = hero_inf; +} +// 47F168: using guessed type int hero_inf; +// 67D7C8: using guessed type int hero_cpp_init_value; + +//----- (00448765) -------------------------------------------------------- +void __fastcall PackPlayer(PkPlayerStruct *pPack, int pnum, bool manashield) +{ + PkPlayerStruct *v3; // esi + int v4; // edi + PlayerStruct *v5; // edi + signed int v6; // eax + signed int v7; // eax + signed int i; // [esp+8h] [ebp-Ch] + signed int ia; // [esp+8h] [ebp-Ch] + signed int ib; // [esp+8h] [ebp-Ch] + ItemStruct *pi; // [esp+Ch] [ebp-8h] + ItemStruct *pia; // [esp+Ch] [ebp-8h] + ItemStruct *pib; // [esp+Ch] [ebp-8h] + PkItemStruct *pki; // [esp+10h] [ebp-4h] + PkItemStruct *pkia; // [esp+10h] [ebp-4h] + PkItemStruct *pkib; // [esp+10h] [ebp-4h] + + v3 = pPack; + v4 = pnum; + memset(pPack, 0, 0x4F2u); + v5 = &plr[v4]; + v3->destAction = v5->destAction; + v3->destParam1 = v5->destParam1; + v3->destParam2 = v5->destParam2; + v3->plrlevel = v5->plrlevel; + v3->px = v5->WorldX; + v3->py = v5->WorldY; + v3->targx = v5->_ptargx; + v3->targy = v5->_ptargy; + strcpy(v3->pName, v5->_pName); + v3->pClass = v5->_pClass; + v3->pBaseStr = v5->_pBaseStr; + v3->pBaseMag = v5->_pBaseMag; + v3->pBaseDex = v5->_pBaseDex; + v3->pBaseVit = v5->_pBaseVit; + v3->pLevel = v5->_pLevel; + v3->pStatPts = v5->_pStatPts; + v3->pExperience = v5->_pExperience; + v3->pGold = v5->_pGold; + v3->pHPBase = v5->_pHPBase; + v3->pMaxHPBase = v5->_pMaxHPBase; + v3->pManaBase = v5->_pManaBase; + v3->pMaxManaBase = v5->_pMaxManaBase; + v3->pMemSpells = v5->_pMemSpells[0]; + v3->pMemSpells2 = v5->_pMemSpells[1]; + v6 = 0; + do + { + v3->pSplLvl[v6] = v5->_pSplLvl[v6]; + ++v6; + } + while ( v6 < 37 ); + pki = v3->InvBody; + pi = v5->InvBody; + i = 7; + do + { + PackItem(pki, pi); + ++pki; + ++pi; + --i; + } + while ( i ); + ia = 40; + pkia = v3->InvList; + pia = v5->InvList; + do + { + PackItem(pkia, pia); + ++pkia; + ++pia; + --ia; + } + while ( ia ); + v7 = 0; + do + { + v3->InvGrid[v7] = v5->InvGrid[v7]; + ++v7; + } + while ( v7 < 40 ); + ib = 8; + v3->_pNumInv = v5->_pNumInv; + pkib = v3->SpdList; + pib = v5->SpdList; + do + { + PackItem(pkib, pib); + ++pkib; + ++pib; + --ib; + } + while ( ib ); + v3->pDiabloKillLevel = v5->pDiabloKillLevel; + if ( gbMaxPlayers == 1 || manashield ) + v3->pManaShield = v5->pManaShield; + else + v3->pManaShield = 0; +} +// 679660: using guessed type char gbMaxPlayers; + +//----- (00448953) -------------------------------------------------------- +void __fastcall PackItem(PkItemStruct *id, ItemStruct *is) +{ + short v2; // ax + short v3; // bx + + if ( is->_itype == -1 ) + { + id->idx = -1; + } + else + { + id->idx = is->IDidx; + if ( is->IDidx == IDI_EAR ) + { + _LOBYTE(v2) = 0; + _LOBYTE(v3) = 0; + _HIBYTE(v2) = is->_iName[7]; + id->iCreateInfo = is->_iName[8] | v2; + id->iSeed = is->_iName[12] | ((is->_iName[11] | ((is->_iName[10] | (is->_iName[9] << 8)) << 8)) << 8); + id->bId = is->_iName[13]; + id->bDur = is->_iName[14]; + id->bMDur = is->_iName[15]; + id->bCh = is->_iName[16]; + id->bMCh = is->_iName[17]; + _HIBYTE(v3) = is->_iName[18]; + id->wValue = _LOWORD(is->_ivalue) | v3 | ((_LOWORD(is->_iCurs) - 19) << 6); + id->dwBuff = is->_iName[22] | ((is->_iName[21] | ((is->_iName[20] | (is->_iName[19] << 8)) << 8)) << 8); + } + else + { + id->iSeed = is->_iSeed; + id->iCreateInfo = is->_iCreateInfo; + id->bId = _LOBYTE(is->_iIdentified) + 2 * is->_iMagical; + id->bDur = is->_iDurability; + id->bMDur = is->_iMaxDur; + id->bCh = is->_iCharges; + id->bMCh = is->_iMaxCharges; + if ( !is->IDidx ) + id->wValue = is->_ivalue; + } + } +} + +//----- (00448A5E) -------------------------------------------------------- +void __fastcall VerifyGoldSeeds(PlayerStruct *pPlayer) +{ + PlayerStruct *v1; // esi + int v2; // ebp + int v3; // eax + PlayerStruct *v4; // ebx + signed int v5; // ecx + int v6; // eax + + v1 = pPlayer; + v2 = 0; + v3 = pPlayer->_pNumInv; + if ( v3 > 0 ) + { + v4 = pPlayer; + do + { + v5 = 0; + if ( !v4->InvList[0].IDidx && v3 > 0 ) + { + do + { + if ( v2 != v5 ) + { + v6 = (int)v1 + 368 * v5; + if ( !*(_DWORD *)(v6 + 3828) && v4->InvList[0]._iSeed == *(_DWORD *)(v6 + 3468) ) + { + v4->InvList[0]._iSeed = GetRndSeed(); + v5 = -1; + } + } + ++v5; + } + while ( v5 < v1->_pNumInv ); + } + v3 = v1->_pNumInv; + ++v2; + v4 = (PlayerStruct *)((char *)v4 + 368); + } + while ( v2 < v3 ); + } +} + +//----- (00448AD0) -------------------------------------------------------- +void __fastcall UnPackPlayer(PkPlayerStruct *pPack, int pnum, bool killok) +{ + int v3; // ebx + PlayerStruct *v4; // esi + PkPlayerStruct *v5; // edi + signed int v6; // eax + signed int v7; // eax + signed int v8; // eax + int *v9; // eax + int pPlayer; // [esp+Ch] [ebp-Ch] + signed int i; // [esp+10h] [ebp-8h] + signed int ia; // [esp+10h] [ebp-8h] + signed int ib; // [esp+10h] [ebp-8h] + ItemStruct *pi; // [esp+14h] [ebp-4h] + ItemStruct *pia; // [esp+14h] [ebp-4h] + ItemStruct *pib; // [esp+14h] [ebp-4h] + PkItemStruct *pki; // [esp+20h] [ebp+8h] + PkItemStruct *pkia; // [esp+20h] [ebp+8h] + PkItemStruct *pkib; // [esp+20h] [ebp+8h] + + v3 = pnum; + v4 = &plr[pnum]; + v5 = pPack; + pPlayer = pnum; + ClearPlrRVars(&plr[pnum]); + v4->WorldX = (unsigned char)v5->px; + v4->WorldY = (unsigned char)v5->py; + v4->_px = (unsigned char)v5->px; + v4->_py = (unsigned char)v5->py; + v4->_ptargx = (unsigned char)v5->targx; + v4->_ptargy = (unsigned char)v5->targy; + v4->plrlevel = (unsigned char)v5->plrlevel; + ClrPlrPath(v3); + v4->destAction = -1; + strcpy(v4->_pName, v5->pName); + _LOBYTE(v4->_pClass) = v5->pClass; + InitPlayer(v3, 1); + v4->_pBaseStr = (unsigned char)v5->pBaseStr; + v4->_pStrength = (unsigned char)v5->pBaseStr; + v4->_pBaseMag = (unsigned char)v5->pBaseMag; + v4->_pMagic = (unsigned char)v5->pBaseMag; + v4->_pBaseDex = (unsigned char)v5->pBaseDex; + v4->_pDexterity = (unsigned char)v5->pBaseDex; + v4->_pBaseVit = (unsigned char)v5->pBaseVit; + v4->_pVitality = (unsigned char)v5->pBaseVit; + v4->_pLevel = v5->pLevel; + v4->_pStatPts = (unsigned char)v5->pStatPts; + v4->_pExperience = v5->pExperience; + v4->_pGold = v5->pGold; + v4->_pMaxHPBase = v5->pMaxHPBase; + v6 = v5->pHPBase; + v4->_pHPBase = v6; + if ( !killok ) + { + _LOBYTE(v6) = v6 & 0xC0; + if ( v6 < 64 ) + v4->_pHPBase = 64; + } + v4->_pMaxManaBase = v5->pMaxManaBase; + v4->_pManaBase = v5->pManaBase; + v4->_pMemSpells[0] = v5->pMemSpells; + v4->_pMemSpells[1] = v5->pMemSpells2; + v7 = 0; + do + { + v4->_pSplLvl[v7] = v5->pSplLvl[v7]; + ++v7; + } + while ( v7 < 37 ); + i = 7; + pki = v5->InvBody; + pi = v4->InvBody; + do + { + UnPackItem(pki, pi); + ++pki; + ++pi; + --i; + } + while ( i ); + ia = 40; + pkia = v5->InvList; + pia = v4->InvList; + do + { + UnPackItem(pkia, pia); + ++pkia; + ++pia; + --ia; + } + while ( ia ); + v8 = 0; + do + { + v4->InvGrid[v8] = v5->InvGrid[v8]; + ++v8; + } + while ( v8 < 40 ); + v4->_pNumInv = (unsigned char)v5->_pNumInv; + VerifyGoldSeeds(v4); + ib = 8; + pkib = v5->SpdList; + pib = v4->SpdList; + do + { + UnPackItem(pkib, pib); + ++pkib; + ++pib; + --ib; + } + while ( ib ); + if ( pPlayer == myplr ) + { + v9 = &witchitem[0]._itype; + do + { + *v9 = -1; + v9 += 92; + } + while ( (signed int)v9 < (signed int)healitem ); + } + CalcPlrInv(pPlayer, 0); + v4->pTownWarps = 0; + v4->pDungMsgs = 0; + v4->pLvlLoad = 0; + v4->pDiabloKillLevel = v5->pDiabloKillLevel; + v4->pBattleNet = v5->pBattleNet; + v4->pManaShield = v5->pManaShield; +} + +//----- (00448D48) -------------------------------------------------------- +void __fastcall UnPackItem(PkItemStruct *is, ItemStruct *id) +{ + PkItemStruct *v2; // esi + ItemStruct *v3; // edi + unsigned short v4; // ax + int v5; // ecx + + v2 = is; + v3 = id; + v4 = is->idx; + if ( v4 == -1 ) + { + id->_itype = -1; + } + else + { + if ( v4 == IDI_EAR ) + { + RecreateEar( + 127, + is->iCreateInfo, + is->iSeed, + is->bId, + (unsigned char)is->bDur, + (unsigned char)is->bMDur, + (unsigned char)is->bCh, + (unsigned char)is->bMCh, + (unsigned short)is->wValue, + is->dwBuff); + } + else + { + v5 = (unsigned short)is->wValue; + _LOWORD(v5) = v2->iCreateInfo; + TempItemGeneration(127, v4, v5, v2->iSeed, (unsigned short)v2->wValue); + items[127]._iMagical = (unsigned char)v2->bId >> 1; + items[127]._iIdentified = v2->bId & 1; + items[127]._iDurability = (unsigned char)v2->bDur; + items[127]._iMaxDur = (unsigned char)v2->bMDur; + items[127]._iCharges = (unsigned char)v2->bCh; + items[127]._iMaxCharges = (unsigned char)v2->bMCh; + } + qmemcpy(v3, &items[127], sizeof(ItemStruct)); + } +} + +//----- (00448DFA) -------------------------------------------------------- +void __cdecl palette_cpp_init() +{ + palette_cpp_init_value = palette_inf; +} +// 47F16C: using guessed type int palette_inf; +// 67DBCC: using guessed type int palette_cpp_init_value; + +//----- (00448E05) -------------------------------------------------------- +void __cdecl palette_save_gamme() +{ + SRegSaveValue("Diablo", "Gamma Correction", 0, gamma_correction); + SRegSaveValue("Diablo", "Color Cycling", 0, color_cycling_enabled); +} + +//----- (00448E33) -------------------------------------------------------- +void __cdecl palette_init() +{ + int v0; // eax + int v1; // eax + + palette_load_gamma(); + memcpy(system_palette, orig_palette, 0x400u); + palette_load_system_palette(); + v0 = lpDDPPrimary->Initialize( + (IDirectDraw *)68, + (unsigned long)system_palette, + (tagPALETTEENTRY *)&lpDDPRed); + if ( v0 ) + TermDlg(111, v0, "C:\\Src\\Diablo\\Source\\PALETTE.CPP", 143); + v1 = IDirectDrawSurface_SetPalette(lpDDSPrimary, lpDDPRed); + if ( v1 ) + TermDlg(111, v1, "C:\\Src\\Diablo\\Source\\PALETTE.CPP", 146); +} + +//----- (00448EAB) -------------------------------------------------------- +void __cdecl palette_load_gamma() +{ + int v0; // eax + int v1; // ecx + int v2; // eax + int v3; // eax + int value; // [esp+8h] [ebp-4h] + + value = gamma_correction; + _LOBYTE(v0) = SRegLoadValue("Diablo", "Gamma Correction", 0, &value); + if ( !v0 ) + value = 100; + v1 = value; + if ( value >= 30 ) + { + if ( value > 100 ) + v1 = 100; + } + else + { + v1 = 30; + } + gamma_correction = v1 - v1 % 5; + _LOBYTE(v2) = SRegLoadValue("Diablo", "Color Cycling", 0, &value); + if ( v2 ) + v3 = value; + else + v3 = 1; + color_cycling_enabled = v3; +} + +//----- (00448F20) -------------------------------------------------------- +void __cdecl palette_load_system_palette() +{ + BYTE *v0; // eax + HDC v1; // ebx + signed int v2; // eax + signed int i; // ecx + int v4; // esi + int v5; // edi + BYTE *v6; // eax + + v0 = &system_palette[0].peFlags; + do + { + *v0 = 5; + v0 += 4; + } + while ( (signed int)v0 < (signed int)&orig_palette[0].peFlags ); + if ( !exclusive ) + { + v1 = GetDC(0); + nsystem_reserve_palette_entries = GetDeviceCaps(v1, 106) / 2; + GetSystemPaletteEntries(v1, 0, nsystem_reserve_palette_entries, system_palette); + v2 = nsystem_reserve_palette_entries; + for ( i = 0; i < v2; ++i ) + system_palette[i].peFlags = 0; + v4 = 256 - v2; + v5 = 256 - v2; + GetSystemPaletteEntries(v1, 256 - v2, v2, &system_palette[v5]); + if ( v4 < 256 ) + { + v6 = &system_palette[v5].peFlags; + do + { + *v6 = 0; + v6 += 4; + } + while ( (signed int)v6 < (signed int)&orig_palette[0].peFlags ); + } + ReleaseDC(0, v1); + } +} +// 484364: using guessed type int exclusive; + +//----- (00448FC9) -------------------------------------------------------- +void __fastcall LoadPalette(char *pal_path) +{ + char *v1; // eax + char *v2; // ecx + char v3; // dl + char a2[768]; // [esp+0h] [ebp-304h] + void *a1; // [esp+300h] [ebp-4h] + + wave_open_file((LPARAM)pal_path, (DIABFILE *)&a1, 0); + wave_read_file((int)a1, a2, 768); + wave_close_file(a1); + v1 = (char *)&orig_palette[0].peGreen; + v2 = &a2[1]; + do + { + v3 = *(v2 - 1); + v1[2] = 0; + *(v1 - 1) = v3; + *v1 = *v2; + v1[1] = v2[1]; + v1 += 4; + v2 += 3; + } + while ( (signed int)v1 < (signed int)&nsystem_reserve_palette_entries + 1 ); +} + +//----- (00449025) -------------------------------------------------------- +void __fastcall LoadRndLvlPal(char dtype) +{ + int v1; // esi + char *v2; // ecx + int v3; // ecx + int v4; // eax + char v5[260]; // [esp+4h] [ebp-104h] + + v1 = dtype; + if ( (_DWORD)dtype ) + { + _LOBYTE(v3) = 0; + v4 = random(v3, 4); + sprintf(v5, "Levels\\L%iData\\L%i_%i.PAL", v1, v1, v4 + 1); + v2 = v5; + } + else + { + v2 = "Levels\\TownData\\Town.pal"; + } + LoadPalette(v2); +} + +//----- (0044906C) -------------------------------------------------------- +void __cdecl ResetPal() +{ + if ( !lpDDSPrimary + || IDirectDrawSurface_IsLost(lpDDSPrimary) != 0x887601C2 + || !IDirectDrawSurface_Restore(lpDDSPrimary) ) + { + SDrawRealizePalette(); + } +} + +//----- (00449097) -------------------------------------------------------- +void __cdecl palette_inc_gamma() +{ + if ( gamma_correction < 100 ) + { + gamma_correction += 5; + if ( gamma_correction > 100 ) + gamma_correction = 100; + palette_apply_gamma_correction(system_palette, logical_palette, 256); + palette_update(); + } +} + +//----- (004490D0) -------------------------------------------------------- +void __cdecl palette_update() +{ + int v0; // ecx + int v1; // eax + + if ( lpDDPRed ) + { + v0 = 0; + v1 = 256; + if ( !exclusive ) + { + v0 = nsystem_reserve_palette_entries; + v1 = 2 * (128 - nsystem_reserve_palette_entries); + } + SDrawUpdatePalette(v0, v1, &system_palette[v0], 0); + } +} +// 484364: using guessed type int exclusive; + +//----- (00449107) -------------------------------------------------------- +void __fastcall palette_apply_gamma_correction(PALETTEENTRY *dst, PALETTEENTRY *src, int n) +{ + PALETTEENTRY *v3; // edi + PALETTEENTRY *v4; // esi + double v5; // [esp+18h] [ebp-Ch] + + v3 = src; + v4 = dst; + v5 = (double)gamma_correction * 0.01; + if ( n > 0 ) + { + do + { + v4->peRed = (signed __int64)(pow((double)v3->peRed * 0.00390625, v5) * 256.0); + v4->peGreen = (signed __int64)(pow((double)v3->peGreen * 0.00390625, v5) * 256.0); + v4->peBlue = (signed __int64)(pow((double)v3->peBlue * 0.00390625, v5) * 256.0); + ++v4; + ++v3; + --n; + } + while ( n ); + } +} + +//----- (004491D0) -------------------------------------------------------- +void __cdecl palette_dec_gamma() +{ + if ( gamma_correction > 30 ) + { + gamma_correction -= 5; + if ( gamma_correction < 30 ) + gamma_correction = 30; + palette_apply_gamma_correction(system_palette, logical_palette, 256); + palette_update(); + } +} + +//----- (00449209) -------------------------------------------------------- +int __fastcall palette_update_gamma(int gamma) +{ + if ( gamma ) + { + gamma_correction = 130 - gamma; + palette_apply_gamma_correction(system_palette, logical_palette, 256); + palette_update(); + } + return 130 - gamma_correction; +} + +//----- (0044923E) -------------------------------------------------------- +void __cdecl BlackPalette() +{ + palette_set_brightness(0); +} + +//----- (00449245) -------------------------------------------------------- +void __fastcall palette_set_brightness(int brightness) +{ + signed int v1; // eax + + if ( lpDDPPrimary ) + { + v1 = 0; + do + { + system_palette[v1].peRed = (unsigned short)(brightness * logical_palette[v1].peRed) >> 8; + system_palette[v1].peGreen = (unsigned short)(brightness * logical_palette[v1].peGreen) >> 8; + system_palette[v1].peBlue = (unsigned short)(brightness * logical_palette[v1].peBlue) >> 8; + ++v1; + } + while ( v1 < 255 ); + Sleep(3u); + IDirectDrawPalette_AddRef( + lpDDPPrimary); + palette_update(); + } +} + +//----- (004492B0) -------------------------------------------------------- +void __fastcall PaletteFadeIn(int inc) +{ + int v1; // ebp + int v2; // [esp+10h] [ebp-4h] + + v2 = inc; + palette_apply_gamma_correction(logical_palette, orig_palette, 256); + v1 = 0; + do + { + palette_set_brightness(v1); + v1 += v2; + } + while ( v1 < 256 ); + palette_set_brightness(256); + memcpy(logical_palette, orig_palette, 0x400u); + palette_bright = 1; +} + +//----- (00449306) -------------------------------------------------------- +void __fastcall PaletteFadeOut(int dec) +{ + int v1; // edi + int v2; // esi + + v1 = dec; + if ( palette_bright ) + { + v2 = 256; + do + { + palette_set_brightness(v2); + v2 -= v1; + } + while ( v2 > 0 ); + palette_set_brightness(0); + palette_bright = 0; + } +} + +//----- (00449336) -------------------------------------------------------- +void __cdecl palette_update_caves() +{ + short v0; // cx + signed int v1; // esi + signed int v2; // eax + signed int v3; // eax + BYTE v4; // [esp+6h] [ebp-2h] + + v0 = *(_WORD *)&system_palette[1].peRed; + v4 = system_palette[1].peBlue; + v1 = 1; + do + { + v2 = v1++; + system_palette[v2].peRed = system_palette[v2 + 1].peRed; + system_palette[v2].peGreen = system_palette[v2 + 1].peGreen; + system_palette[v2].peBlue = system_palette[v2 + 1].peBlue; + } + while ( v1 < 31 ); + v3 = v1; + system_palette[v3].peRed = v0; + system_palette[v3].peGreen = _HIBYTE(v0); + system_palette[v3].peBlue = v4; + palette_update(); +} + +//----- (00449398) -------------------------------------------------------- +void __fastcall palette_update_quest_palette(int n) +{ + int i; // eax + + for ( i = 32 - n; i >= 0; --i ) + logical_palette[i] = orig_palette[i]; + palette_apply_gamma_correction(system_palette, logical_palette, 32); + palette_update(); +} + +//----- (004493C6) -------------------------------------------------------- +bool __cdecl palette_get_colour_cycling() +{ + return color_cycling_enabled; +} + +//----- (004493CC) -------------------------------------------------------- +void __fastcall palette_set_color_cycling(bool enabled) +{ + color_cycling_enabled = enabled; +} + +//----- (004493D4) -------------------------------------------------------- +int __fastcall FindPath(int (__fastcall *PosOk)(int, int, int), int PosOkArg, int sx, int sy, int dx, int dy, char *path) +{ + PATHNODE *v7; // eax + PATHNODE *v8; // esi + char v9; // al + char v10; // cl + PATHNODE *v11; // eax + int result; // eax + PATHNODE *v13; // edx + int v14; // eax + int v15; // edi + bool v16; // zf + int *v17; // ecx + char v18; // dl + int (__fastcall *a1)(int, int, int); // [esp+Ch] [ebp-8h] + int a2; // [esp+10h] [ebp-4h] + + pnode_vals[0] = 0; + a2 = PosOkArg; + a1 = PosOk; + *(_DWORD *)&path_2_nodes[0].f = (unsigned int)path_clear_node(); + v7 = path_clear_node(); + dword_6820C8 = 0; + pnode_ptr = v7; + v8 = path_clear_node(); + _LOBYTE(v8->g) = 0; + v9 = path_xycoord(sx, sy, dx, dy); + v10 = v8->g; + v8->h = v9; + v8->x = sx; + v8->f = v9 + v10; + v8->y = sy; + *(_DWORD *)(*(_DWORD *)&path_2_nodes[0].f + 48) = (unsigned int)v8; + while ( 1 ) + { + v11 = GetNextPath(); + if ( !v11 ) + return 0; + if ( v11->x == dx && v11->y == dy ) + break; + if ( !path_get_path(a1, a2, v11, dx, dy) ) + return 0; + } + v13 = v11; + v14 = (int)&v11->Parent; + v15 = 0; + if ( *(_DWORD *)v14 ) + { + while ( 1 ) + { + v16 = v15 == 25; + if ( v15 >= 25 ) + break; + pnode_vals[++v15] = (char)path_directions[3 * (v13->y - *(_DWORD *)(*(_DWORD *)v14 + 8)) + - *(_DWORD *)(*(_DWORD *)v14 + 4) + + 4 + + v13->x]; + v13 = *(PATHNODE **)v14; + v14 = *(_DWORD *)v14 + 12; + if ( !*(_DWORD *)v14 ) + { + v16 = v15 == 25; + break; + } + } + if ( v16 ) + return 0; + } + result = 0; + if ( v15 > 0 ) + { + v17 = &pnode_vals[v15]; + do + { + v18 = *(_BYTE *)v17; + --v17; + path[result++] = v18; + } + while ( result < v15 ); + } + return result; +} + +//----- (004494D3) -------------------------------------------------------- +int __fastcall path_xycoord(int x, int y, int xx, int yy) +{ + int v4; // esi + int v5; // edi + int v6; // eax + int v7; // ecx + + v4 = y; + v5 = abs(x - xx); + v6 = abs(v4 - yy); + v7 = v5; + if ( v5 >= v6 ) + { + v7 = v6; + if ( v5 > v6 ) + v6 = v5; + } + return 2 * (v7 + v6); +} + +//----- (00449504) -------------------------------------------------------- +int __fastcall path_check_equal(PATHNODE *pPath, int dx, int dy) +{ + int v4; // [esp-4h] [ebp-4h] + + if ( pPath->x == dx || pPath->y == dy ) + v4 = 2; + else + v4 = 3; + return v4; +} + +//----- (0044951C) -------------------------------------------------------- +PATHNODE *__cdecl GetNextPath() +{ + PATHNODE *result; // eax + + result = *(PATHNODE **)(*(_DWORD *)&path_2_nodes[0].f + 48); + if ( result ) + { + *(_DWORD *)(*(_DWORD *)&path_2_nodes[0].f + 48) = (unsigned int)result->NextNode; + result->NextNode = pnode_ptr->NextNode; + pnode_ptr->NextNode = result; + } + return result; +} + +//----- (00449546) -------------------------------------------------------- +PATHNODE *__fastcall path_solid_pieces(PATHNODE *pPath, int dx, int dy) +{ + PATHNODE *result; // eax + int v4; // ecx + int v5; // ecx + int v6; // ecx + int v7; // edx + int v8; // ecx + int v9; // ecx + int v10; // edx + int v11; // edx + + result = (PATHNODE *)1; + v4 = (char)path_directions[3 * (dy - pPath->y) - pPath->x + 4 + dx] - 5; + if ( !v4 ) + { + result = 0; + v11 = dy + 112 * dx; + if ( nSolidTable[dPiece[0][v11 + 1]] ) + return result; + v8 = dPiece[1][v11]; + goto LABEL_13; + } + v5 = v4 - 1; + if ( !v5 ) + { + v9 = 112 * dx + dy; + v10 = dPiece[0][v9 + 1]; + goto LABEL_9; + } + v6 = v5 - 1; + if ( !v6 ) + { + v9 = 112 * dx + dy; + v10 = *(_DWORD *)&dflags[39][4 * v9 + 36]; +LABEL_9: + result = 0; + if ( nSolidTable[v10] ) + return result; + v8 = *(_DWORD *)&dflags[28][4 * v9 + 32]; + goto LABEL_13; + } + if ( v6 == 1 ) + { + result = 0; + v7 = dy + 112 * dx; + if ( !nSolidTable[dPiece[1][v7]] ) + { + v8 = *(_DWORD *)&dflags[39][v7 * 4 + 36]; +LABEL_13: + if ( nSolidTable[v8] == (_BYTE)result ) + result = (PATHNODE *)1; + return result; + } + } + return result; +} + +//----- (004495ED) -------------------------------------------------------- +int __fastcall path_get_path(int (__fastcall *PosOk)(int, int, int), int PosOkArg, PATHNODE *pPath, int x, int y) +{ + int v5; // eax + int v6; // esi + int v7; // edi + int (__fastcall *v9)(int, int, int); // [esp+Ch] [ebp-Ch] + int v10; // [esp+10h] [ebp-8h] + int i; // [esp+14h] [ebp-4h] + + v5 = 0; + v10 = PosOkArg; + v9 = PosOk; + for ( i = 0; ; v5 = i ) + { + v6 = pPath->x + (char)pathxdir[v5]; + v7 = pPath->y + (char)pathydir[v5]; + if ( !v9(v10, v6, v7) ) + break; + if ( path_solid_pieces(pPath, v6, v7) ) + goto LABEL_8; +LABEL_9: + if ( ++i >= 8 ) + return 1; + } + if ( v6 != x || v7 != y ) + goto LABEL_9; +LABEL_8: + if ( path_parent_path(pPath, v6, v7, x, y) ) + goto LABEL_9; + return 0; +} + +//----- (0044966F) -------------------------------------------------------- +PATHNODE *__fastcall path_parent_path(PATHNODE *pPath, int dx, int dy, int sx, int sy) +{ + PATHNODE *v5; // edi + int v6; // ebx + PATHNODE *v7; // esi + signed int v8; // eax + struct PATHNODE **v9; // ecx + char v10; // al + PATHNODE *v11; // esi + signed int v12; // eax + struct PATHNODE **v13; // ecx + char v14; // al + PATHNODE *result; // eax + PATHNODE *v16; // esi + char v17; // al + signed int v18; // ecx + struct PATHNODE **v19; // eax + int a1; // [esp+Ch] [ebp-4h] + + a1 = dx; + v5 = pPath; + v6 = SLOBYTE(pPath->g) + path_check_equal(pPath, dx, dy); + v7 = path_get_node_xy(a1, dy); + if ( v7 ) + { + v8 = 0; + v9 = v5->Child; + do + { + if ( !*v9 ) + break; + ++v8; + ++v9; + } + while ( v8 < 8 ); + v5->Child[v8] = v7; + if ( v6 < SLOBYTE(v7->g) ) + { + if ( path_solid_pieces(v5, a1, dy) ) + { + v10 = v7->h; + v7->Parent = v5; + _LOBYTE(v7->g) = v6; + v7->f = v6 + v10; + } + } + } + else + { + v11 = path_get_node_xyptr(a1, dy); + if ( v11 ) + { + v12 = 0; + v13 = v5->Child; + do + { + if ( !*v13 ) + break; + ++v12; + ++v13; + } + while ( v12 < 8 ); + v5->Child[v12] = v11; + if ( v6 < SLOBYTE(v11->g) && path_solid_pieces(v5, a1, dy) ) + { + v14 = v6 + v11->h; + v11->Parent = v5; + _LOBYTE(v11->g) = v6; + v11->f = v14; + path_set_coords(v11); + } + } + else + { + result = path_clear_node(); + v16 = result; + if ( !result ) + return result; + result->Parent = v5; + _LOBYTE(result->g) = v6; + v17 = path_xycoord(a1, dy, sx, sy); + v16->h = v17; + v16->f = v6 + v17; + v16->x = a1; + v16->y = dy; + path_get_node2(v16); + v18 = 0; + v19 = v5->Child; + do + { + if ( !*v19 ) + break; + ++v18; + ++v19; + } + while ( v18 < 8 ); + v5->Child[v18] = v16; + } + } + return (PATHNODE *)1; +} + +//----- (0044979A) -------------------------------------------------------- +PATHNODE *__fastcall path_get_node_xy(int dx, int dy) +{ + PATHNODE *result; // eax + + result = *(PATHNODE **)&path_2_nodes[0].f; + do + result = result->NextNode; + while ( result && (result->x != dx || result->y != dy) ); + return result; +} + +//----- (004497B3) -------------------------------------------------------- +PATHNODE *__fastcall path_get_node_xyptr(int dx, int dy) +{ + PATHNODE *result; // eax + + result = pnode_ptr; + do + result = result->NextNode; + while ( result && (result->x != dx || result->y != dy) ); + return result; +} + +//----- (004497CC) -------------------------------------------------------- +PATHNODE *__fastcall path_get_node2(PATHNODE *pPath) +{ + PATHNODE *v1; // edx + PATHNODE *result; // eax + + v1 = *(PATHNODE **)&path_2_nodes[0].f; + result = *(PATHNODE **)(*(_DWORD *)&path_2_nodes[0].f + 48); + if ( result ) + { + do + { + if ( result->f >= pPath->f ) + break; + v1 = result; + result = result->NextNode; + } + while ( result ); + pPath->NextNode = result; + } + v1->NextNode = pPath; + return result; +} + +//----- (004497F7) -------------------------------------------------------- +PATHNODE *__fastcall path_set_coords(PATHNODE *pPath) +{ + PATHNODE *result; // eax + PATHNODE *v2; // edi + PATHNODE *v3; // esi + int v4; // ebx + int v5; // edx + int v6; // edx + char v7; // al + char v8; // cl + signed int v9; // [esp+0h] [ebp-8h] + PATHNODE *v10; // [esp+4h] [ebp-4h] + + result = path_set_node_ptr(pPath); + while ( dword_6820C8 ) + { + v9 = 0; + v2 = path_decrease_node(); + v10 = (PATHNODE *)((char *)v2 + 16); + do + { + result = v10; + v3 = *(PATHNODE **)&v10->f; + if ( !*(_DWORD *)&v10->f ) + break; + v4 = v3->y; + result = (PATHNODE *)(SLOBYTE(v2->g) + path_check_equal(v2, v3->x, v3->y)); + if ( (signed int)result < SLOBYTE(v3->g) ) + { + result = path_solid_pieces(v2, v5, v4); + if ( result ) + { + v6 = v3->x; + v3->Parent = v2; + v7 = _LOBYTE(v2->g) + path_check_equal(v2, v6, v4); + v8 = v3->h; + _LOBYTE(v3->g) = v7; + v3->f = v7 + v8; + result = path_set_node_ptr(v3); + } + } + ++v9; + v10 = (PATHNODE *)((char *)v10 + 4); + } + while ( v9 < 8 ); + } + return result; +} + +//----- (00449890) -------------------------------------------------------- +PATHNODE *__fastcall path_set_node_ptr(PATHNODE *pPath) +{ + PATHNODE *result; // eax + + result = (PATHNODE *)dword_6820C8++; + pnode_tblptr[(_DWORD)result] = pPath; + return result; +} + +//----- (004498A3) -------------------------------------------------------- +PATHNODE *__cdecl path_decrease_node() +{ + return pnode_tblptr[--dword_6820C8]; +} + +//----- (004498B6) -------------------------------------------------------- +PATHNODE *__cdecl path_clear_node() +{ + PATHNODE *v1; // esi + + if ( pnode_vals[0] == 300 ) + return 0; + v1 = &path_nodes[pnode_vals[0]++]; + memset(v1, 0, 0x34u); + return v1; +} + +//----- (004498F1) -------------------------------------------------------- +void __cdecl pfile_cpp_init() +{ + pfile_cpp_init_value = pfile_inf; +} +// 47F1C0: using guessed type int pfile_inf; + +//----- (004498FC) -------------------------------------------------------- +void __cdecl pfile_init_save_directory() +{ + char Buffer[260]; // [esp+4h] [ebp-104h] + + if ( GetWindowsDirectoryA(Buffer, 0x104u) + && (pfile_check_available_space(Buffer), GetModuleFileNameA(hInstance, Buffer, 0x104u)) ) + { + pfile_check_available_space(Buffer); + } + else + { + TermMsg("Unable to initialize save directory"); + } +} + +//----- (0044995B) -------------------------------------------------------- +void __fastcall pfile_check_available_space(char *pszDir) +{ + char *v1; // edi + char *v2; // eax + char v3; // cl + BOOL v4; // esi + DWORD TotalNumberOfClusters; // [esp+8h] [ebp-10h] + DWORD NumberOfFreeClusters; // [esp+Ch] [ebp-Ch] + DWORD BytesPerSector; // [esp+10h] [ebp-8h] + DWORD SectorsPerCluster; // [esp+14h] [ebp-4h] + + v1 = pszDir; + v2 = pszDir; + while ( 1 ) + { + v3 = *v2; + if ( !*v2 ) + break; + ++v2; + if ( v3 == 92 ) + { + *v2 = 0; + break; + } + } + v4 = GetDiskFreeSpaceA(v1, &SectorsPerCluster, &BytesPerSector, &NumberOfFreeClusters, &TotalNumberOfClusters); + if ( !v4 ) + goto LABEL_12; + if ( (signed __int64)(BytesPerSector * (unsigned __int64)SectorsPerCluster * NumberOfFreeClusters) < 0xA00000 ) + v4 = 0; + if ( !v4 ) +LABEL_12: + DiskFreeDlg(v1); +} + +//----- (004499C3) -------------------------------------------------------- +void __cdecl pfile_write_hero() +{ + int v0; // eax + int v1; // esi + int v2; // eax + PkPlayerStruct pkplr; // [esp+4h] [ebp-4F4h] + + v0 = pfile_get_save_num_from_name(plr[myplr]._pName); + v1 = v0; + _LOBYTE(v2) = pfile_open_archive(1, v0); + if ( v2 ) + { + PackPlayer(&pkplr, myplr, gbMaxPlayers == 1); + pfile_encode_hero(&pkplr); + pfile_flush(gbMaxPlayers == 1, v1); + } +} +// 679660: using guessed type char gbMaxPlayers; + +//----- (00449A33) -------------------------------------------------------- +int __fastcall pfile_get_save_num_from_name(char *name) +{ + char *v1; // ebx + unsigned int v2; // esi + char *v3; // edi + + v1 = name; + v2 = 0; + v3 = hero_names; + do + { + if ( !_strcmpi(v3, v1) ) + break; + ++v2; + v3 += 32; + } + while ( v2 < 0xA ); + return v2; +} + +//----- (00449A5B) -------------------------------------------------------- +void __fastcall pfile_encode_hero(PkPlayerStruct *pPack) +{ + int v1; // ebx + void *v2; // edi + char password[16]; // [esp+Ch] [ebp-14h] + void *v4; // [esp+1Ch] [ebp-4h] + + strcpy(password, "xrgyrkj1"); + *(_DWORD *)&password[9] = 0; + *(_WORD *)&password[13] = 0; + v4 = pPack; + password[15] = 0; + if ( (unsigned char)gbMaxPlayers > 1u ) + strcpy(password, "szqnlsk1"); + v1 = codec_get_encoded_len(1266); + v2 = DiabloAllocPtr(v1); + memcpy(v2, v4, 0x4F2u); + codec_encode(v2, 1266, v1, password); + mpqapi_write_file("hero", (char *)v2, v1); + mem_free_dbg(v2); +} +// 679660: using guessed type char gbMaxPlayers; + +//----- (00449ADF) -------------------------------------------------------- +bool __fastcall pfile_open_archive(bool a1, int save_num) +{ + int v2; // esi + BOOL v3; // edi + int v4; // eax + char FileName[260]; // [esp+8h] [ebp-104h] + + v2 = save_num; + v3 = a1; + pfile_get_save_path(FileName, 260, save_num); + _LOBYTE(v4) = mpqapi_open_archive(FileName, 0, v2); + if ( v4 ) + return 1; + if ( v3 ) + { + if ( (unsigned char)gbMaxPlayers > 1u ) + MI_Dummy(v2); + } + return 0; +} +// 679660: using guessed type char gbMaxPlayers; + +//----- (00449B30) -------------------------------------------------------- +void __fastcall pfile_get_save_path(char *pszBuf, int dwBufSize, int save_num) +{ + char *v3; // esi + const char *v4; // ebx + DWORD v5; // edi + char *v6; // eax + char v7[260]; // [esp+8h] [ebp-104h] + + v3 = pszBuf; + v4 = "\\multi_%d.sv"; + if ( (unsigned char)gbMaxPlayers <= 1u ) + v4 = "\\single_%d.sv"; + v5 = GetModuleFileNameA(hInstance, pszBuf, 0x104u); + v6 = strrchr(v3, 92); + if ( v6 ) + *v6 = 0; + if ( !v5 ) + TermMsg("Unable to get save directory"); + sprintf(v7, v4, save_num); + strcat(v3, v7); + strlwr(v3); +} +// 679660: using guessed type char gbMaxPlayers; + +//----- (00449BB2) -------------------------------------------------------- +void __fastcall pfile_flush(bool is_single_player, int save_num) +{ + int v2; // esi + bool v3; // di + char FileName[260]; // [esp+8h] [ebp-104h] + + v2 = save_num; + v3 = is_single_player; + pfile_get_save_path(FileName, 260, save_num); + mpqapi_flush_and_close(FileName, v3, v2); +} + +//----- (00449BE4) -------------------------------------------------------- +bool __fastcall pfile_create_player_description(char *dst, int len) +{ + int v2; // edi + char *v3; // ebx + int v4; // eax + char src[128]; // [esp+Ch] [ebp-ACh] + _uiheroinfo hero_info; // [esp+8Ch] [ebp-2Ch] + + myplr = 0; + v2 = len; + v3 = dst; + pfile_read_player_from_save(); + game_2_ui_player(plr, &hero_info, gbValidSaveFile); + UiSetupPlayerInfo(chr_name_str, &hero_info, 'DRTL'); + if ( !v3 || !v2 ) + goto LABEL_5; + v4 = UiCreatePlayerDescription(&hero_info, 'DRTL', src); + if ( v4 ) + { + SStrCopy(v3, src, v2); +LABEL_5: + _LOBYTE(v4) = 1; + } + return v4; +} + +//----- (00449C5A) -------------------------------------------------------- +int __fastcall pfile_create_save_file(char *name_1, char *name_2) +{ + char *v2; // edi + char *v3; // ebp + int v4; // esi + int v5; // eax + char *v7; // [esp+20h] [ebp-30h] + _uiheroinfo heroinfo; // [esp+24h] [ebp-2Ch] + + v2 = name_2; + v3 = name_1; + if ( pfile_get_save_num_from_name(name_2) != 10 ) + return 0; + v4 = 0; + v7 = plr[0]._pName; + while ( _strcmpi(v3, v7) ) + { + v7 += 21720; + ++v4; + if ( v7 == &plr_msgs[1].msg[115] ) + return 0; + } + v5 = pfile_get_save_num_from_name(v3); + if ( v5 == 10 ) + return 0; + SStrCopy(&hero_names[32 * v5], v2, 32); + SStrCopy(plr[v4]._pName, v2, 32); + if ( !_strcmpi(chr_name_str, v3) ) + SStrCopy(chr_name_str, v2, 16); + game_2_ui_player(plr, &heroinfo, gbValidSaveFile); + UiSetupPlayerInfo(chr_name_str, &heroinfo, 'DRTL'); + pfile_write_hero(); + return 1; +} + +//----- (00449D22) -------------------------------------------------------- +void __cdecl pfile_flush_W() +{ + int v0; // eax + + v0 = pfile_get_save_num_from_name(plr[myplr]._pName); + pfile_flush(1, v0); +} + +//----- (00449D43) -------------------------------------------------------- +void __fastcall game_2_ui_player(PlayerStruct *p, _uiheroinfo *heroinfo, bool bHasSaveFile) +{ + _uiheroinfo *v3; // esi + PlayerStruct *v4; // edi + char v5; // al + + v3 = heroinfo; + v4 = p; + memset(heroinfo, 0, 0x2Cu); + strncpy(v3->name, v4->_pName, 0xFu); + v3->name[15] = 0; + v3->level = v4->_pLevel; + v3->heroclass = game_2_ui_class(v4); + v3->strength = v4->_pStrength; + v3->magic = v4->_pMagic; + v3->dexterity = v4->_pDexterity; + v3->vitality = v4->_pVitality; + v3->gold = v4->_pGold; + v3->hassaved = bHasSaveFile; + v5 = v4->pDiabloKillLevel; + v3->spawned = 0; + v3->herorank = v5; +} + +//----- (00449DD0) -------------------------------------------------------- +char __fastcall game_2_ui_class(PlayerStruct *p) +{ + char result; // al + + result = p->_pClass; + if ( result ) + result = (result != 1) + 1; + return result; +} + +//----- (00449DE3) -------------------------------------------------------- +bool __stdcall pfile_ui_set_hero_infos(void (__stdcall *ui_add_hero_info)(_uiheroinfo *)) +{ + char *v1; // esi + int v2; // eax + int v3; // eax + DWORD v4; // eax + unsigned int v5; // esi + char *v6; // ebx + void *v7; // eax + void *v8; // edi + int v9; // eax + bool v10; // al + PkPlayerStruct pkplr; // [esp+Ch] [ebp-7BCh] + struct _OFSTRUCT ReOpenBuff; // [esp+500h] [ebp-2C8h] + char FileName[260]; // [esp+588h] [ebp-240h] + char NewFileName[260]; // [esp+68Ch] [ebp-13Ch] + _uiheroinfo hero_info; // [esp+790h] [ebp-38h] + int unused; // [esp+7BCh] [ebp-Ch] + LPCSTR lpSrcStr; // [esp+7C0h] [ebp-8h] + int save_num; // [esp+7C4h] [ebp-4h] + + memset(hero_names, 0, 0x140u); + if ( (unsigned char)gbMaxPlayers > 1u ) + { + lpSrcStr = 0; + save_num = 0; + do + { + if ( (unsigned int)save_num >= 0xA ) + break; + pfile_get_archive_path(FileName, 260, (int)lpSrcStr); + v1 = strrchr(FileName, 92) + 1; + if ( v1 != (char *)1 && OpenFile(FileName, &ReOpenBuff, 0x4000u) != -1 ) + { + _LOBYTE(v2) = SRegLoadString((const char *)"Diablo\\Converted", (const char *)v1, 0, NewFileName, 260); + if ( !v2 ) + { + while ( 1 ) + { + v3 = save_num++; + pfile_get_save_path(NewFileName, 260, v3); + if ( OpenFile(NewFileName, &ReOpenBuff, 0x4000u) == -1 ) + break; + if ( (unsigned int)save_num >= 0xA ) + goto LABEL_13; + } + if ( CopyFileA(FileName, NewFileName, 1) ) + { + SRegSaveString("Diablo\\Converted", v1, 0, NewFileName); + v4 = GetFileAttributesA(NewFileName); + if ( v4 != -1 ) + { + _LOBYTE(v4) = v4 & 0xF9; + SetFileAttributesA(NewFileName, v4); + } + } + } + } +LABEL_13: + ++lpSrcStr; + } + while ( (unsigned int)lpSrcStr < 0xA ); + } + unused = 1; + v5 = 0; + v6 = hero_names; + do + { + v7 = pfile_open_save_archive(&unused, v5); + v8 = v7; + if ( v7 ) + { + _LOBYTE(v9) = pfile_read_hero(v7, &pkplr); + if ( v9 ) + { + strcpy(v6, pkplr.pName); + UnPackPlayer(&pkplr, 0, 0); + v10 = pfile_archive_contains_game(v8); + game_2_ui_player(plr, &hero_info, v10); + ui_add_hero_info(&hero_info); + } + pfile_SFileCloseArchive(v8); + } + ++v5; + v6 += 32; + } + while ( v5 < 0xA ); + return 1; +} +// 679660: using guessed type char gbMaxPlayers; + +//----- (00449FAA) -------------------------------------------------------- +char *__fastcall pfile_get_archive_path(char *dst, int dst_size, int save_num) +{ + char *v3; // esi + const char *v4; // ebx + DWORD v5; // edi + char *v6; // eax + char path_buf[260]; // [esp+Ch] [ebp-104h] + + v3 = dst; + if ( (unsigned char)gbMaxPlayers <= 1u ) + { + v4 = "\\single_%d.sv"; + v5 = GetModuleFileNameA(hInstance, dst, 0x104u); + v6 = strrchr(v3, 92); + if ( v6 ) + *v6 = 0; + } + else + { + v4 = "\\dlinfo_%d.drv"; + v5 = GetWindowsDirectoryA(dst, 0x104u); + } + if ( !v5 ) + TermMsg("Unable to get save directory"); + sprintf(path_buf, v4, save_num); + strcat(v3, path_buf); + return strlwr(v3); +} +// 679660: using guessed type char gbMaxPlayers; + +//----- (0044A036) -------------------------------------------------------- +bool __fastcall pfile_read_hero(void *archive, PkPlayerStruct *hero) +{ + BOOL v2; // eax + int v3; // eax + int v4; // edi + char *v5; // eax + char *v6; // esi + int v7; // eax + int v8; // eax + char password[16]; // [esp+4h] [ebp-24h] + void *v11; // [esp+14h] [ebp-14h] + DWORD nSize; // [esp+18h] [ebp-10h] + int v13; // [esp+1Ch] [ebp-Ch] + int nread; // [esp+20h] [ebp-8h] + void *file; // [esp+24h] [ebp-4h] + + v11 = hero; + _LOBYTE(v2) = SFileOpenFileEx(archive, "hero", 0, &file); + if ( v2 ) + { + strcpy(password, "xrgyrkj1"); + v13 = 0; + *(_DWORD *)&password[9] = 0; + *(_WORD *)&password[13] = 0; + password[15] = 0; + nSize = 16; + if ( (unsigned char)gbMaxPlayers > 1u ) + strcpy(password, "szqnlsk1"); + v3 = SFileGetFileSize((int *)file, 0); + v4 = v3; + if ( !v3 ) + goto LABEL_15; + v5 = (char *)DiabloAllocPtr(v3); + v6 = v5; + _LOBYTE(v7) = SFileReadFile(file, v5, v4, (unsigned long *)&nread, 0); + if ( v7 ) + { + nread = codec_decode(v6, v4, password); + if ( nread ) + goto LABEL_11; + if ( (unsigned char)gbMaxPlayers > 1u ) + { + GetComputerNameA(password, &nSize); + if ( !SFileSetFilePointer((int)file, 0, 0, 0) ) + { + _LOBYTE(v8) = SFileReadFile(file, v6, v4, (unsigned long *)&nread, 0); + if ( v8 ) + { + nread = codec_decode(v6, v4, password); +LABEL_11: + if ( nread == 1266 ) + { + memcpy(v11, v6, 0x4F2u); + v13 = 1; + } + goto LABEL_13; + } + } + } + } +LABEL_13: + if ( v6 ) + mem_free_dbg(v6); +LABEL_15: + SFileCloseFile(file); + _LOBYTE(v2) = v13; + } + return v2; +} +// 679660: using guessed type char gbMaxPlayers; + +//----- (0044A158) -------------------------------------------------------- +void *__fastcall pfile_open_save_archive(int *unused, int save_num) +{ + int v2; // eax + char SrcStr[260]; // [esp+0h] [ebp-108h] + void *archive; // [esp+104h] [ebp-4h] + + pfile_get_save_path(SrcStr, 260, save_num); + _LOBYTE(v2) = SFileOpenArchive(SrcStr, 0x7000, 0, &archive); + return (void *)(v2 != 0 ? (unsigned int)archive : 0); +} + +//----- (0044A192) -------------------------------------------------------- +void __fastcall pfile_SFileCloseArchive(void *hsArchive) +{ + SFileCloseArchive(hsArchive); +} + +//----- (0044A199) -------------------------------------------------------- +bool __fastcall pfile_archive_contains_game(void *hsArchive) +{ + int v1; // eax + void *file; // [esp+0h] [ebp-4h] + + file = hsArchive; + if ( gbMaxPlayers != 1 ) + return 0; + _LOBYTE(v1) = SFileOpenFileEx(hsArchive, "game", 0, &file); + if ( !v1 ) + return 0; + SFileCloseFile(file); + return 1; +} +// 679660: using guessed type char gbMaxPlayers; + +//----- (0044A1CC) -------------------------------------------------------- +bool __stdcall pfile_ui_set_class_stats(int player_class_nr, _uidefaultstats *class_stats) +{ + int v2; // eax + + v2 = (char)pfile_get_player_class(player_class_nr); + class_stats->strength = StrengthTbl[v2]; + class_stats->magic = MagicTbl[v2]; + class_stats->dexterity = DexterityTbl[v2]; + class_stats->vitality = VitalityTbl[v2]; + return 1; +} + +//----- (0044A210) -------------------------------------------------------- +int __fastcall pfile_get_player_class(int player_class_nr) +{ + int result; // eax + + if ( player_class_nr ) + _LOBYTE(result) = (player_class_nr != 1) + 1; + else + _LOBYTE(result) = 0; + return result; +} + +//----- (0044A220) -------------------------------------------------------- +bool __stdcall pfile_ui_save_create(_uiheroinfo *heroinfo) +{ + unsigned int v1; // edi + char *v2; // eax + int v3; // eax + char v5; // al + PkPlayerStruct pkplr; // [esp+8h] [ebp-4F4h] + + v1 = pfile_get_save_num_from_name(heroinfo->name); + if ( v1 == 10 ) + { + v1 = 0; + v2 = hero_names; + do + { + if ( !*v2 ) + break; + ++v1; + v2 += 32; + } + while ( v1 < 0xA ); + if ( v1 == 10 ) + return 0; + } + _LOBYTE(v3) = pfile_open_archive(0, v1); + if ( !v3 ) + return 0; + mpqapi_remove_hash_entries(pfile_get_file_name); + strncpy(&hero_names[32 * v1], heroinfo->name, 0x20u); + hero_names[32 * v1 + 31] = 0; + v5 = pfile_get_player_class((unsigned char)heroinfo->heroclass); + CreatePlayer(0, v5); + strncpy(plr[0]._pName, heroinfo->name, 0x20u); + plr[0]._pName[31] = 0; + PackPlayer(&pkplr, 0, 1); + pfile_encode_hero(&pkplr); + game_2_ui_player(plr, heroinfo, 0); + pfile_flush(1, v1); + return 1; +} + +//----- (0044A2FF) -------------------------------------------------------- +bool __stdcall pfile_get_file_name(int lvl, char *dst) +{ + int v2; // ecx + bool v3; // zf + const char *v4; // eax + + v2 = lvl; + if ( (unsigned char)gbMaxPlayers > 1u ) + { + v3 = lvl == 0; + goto LABEL_10; + } + if ( (unsigned int)lvl < 0x11 ) + { + v4 = "perml%02d"; +LABEL_12: + sprintf(dst, v4, v2); + return 1; + } + if ( (unsigned int)lvl < 0x22 ) + { + v2 = lvl - 17; + v4 = "perms%02d"; + goto LABEL_12; + } + if ( lvl == 34 ) + { + v4 = "game"; + goto LABEL_12; + } + v3 = lvl == 35; +LABEL_10: + if ( v3 ) + { + v4 = "hero"; + goto LABEL_12; + } + return 0; +} +// 679660: using guessed type char gbMaxPlayers; + +//----- (0044A356) -------------------------------------------------------- +bool __stdcall pfile_delete_save(_uiheroinfo *hero_info) +{ + unsigned int v1; // eax + char FileName[260]; // [esp+0h] [ebp-104h] + + v1 = pfile_get_save_num_from_name(hero_info->name); + if ( v1 < 0xA ) + { + hero_names[32 * v1] = 0; + pfile_get_save_path(FileName, 260, v1); + DeleteFileA(FileName); + } + return 1; +} + +//----- (0044A3A0) -------------------------------------------------------- +void __cdecl pfile_read_player_from_save() +{ + int v0; // edi + void *v1; // esi + int v2; // eax + int v3; // eax + PkPlayerStruct pkplr; // [esp+8h] [ebp-4F4h] + + v0 = pfile_get_save_num_from_name(chr_name_str); + v1 = pfile_open_save_archive(0, v0); + if ( !v1 ) + TermMsg("Unable to open archive"); + _LOBYTE(v2) = pfile_read_hero(v1, &pkplr); + if ( !v2 ) + TermMsg("Unable to load character"); + UnPackPlayer(&pkplr, myplr, 0); + _LOBYTE(v3) = pfile_archive_contains_game(v1); + *(_DWORD *)&gbValidSaveFile = v3; + pfile_SFileCloseArchive(v1); +} + +//----- (0044A419) -------------------------------------------------------- +void __fastcall pfile_get_temp_level_name(char *dst) +{ + char *v1; // esi + + v1 = dst; + pfile_get_save_num_from_name(plr[myplr]._pName); + if ( setlevel ) + sprintf(v1, "temps%02d", (unsigned char)setlvlnum); + else + sprintf(v1, "templ%02d", currlevel); +} +// 5CCB10: using guessed type char setlvlnum; +// 5CF31D: using guessed type char setlevel; + +//----- (0044A463) -------------------------------------------------------- +void __fastcall pfile_get_perm_level_name(char *dst) +{ + char *v1; // esi + int v2; // ebx + int v3; // eax + int v4; // eax + int v5; // edi + + v1 = dst; + v2 = pfile_get_save_num_from_name(plr[myplr]._pName); + pfile_get_temp_level_name(v1); + _LOBYTE(v3) = pfile_open_archive(0, v2); + if ( !v3 ) + TermMsg("Unable to read to save file archive"); + _LOBYTE(v4) = mpqapi_has_file(v1); + v5 = v4; + pfile_flush(1, v2); + if ( !v5 ) + { + if ( setlevel ) + sprintf(v1, "perms%02d", (unsigned char)setlvlnum); + else + sprintf(v1, "perml%02d", currlevel); + } +} +// 5CCB10: using guessed type char setlvlnum; +// 5CF31D: using guessed type char setlevel; + +//----- (0044A4E9) -------------------------------------------------------- +void __fastcall pfile_get_game_name(char *dst) +{ + char *v1; // esi + + v1 = dst; + pfile_get_save_num_from_name(plr[myplr]._pName); + strcpy(v1, "game"); +} + +//----- (0044A512) -------------------------------------------------------- +void __cdecl pfile_remove_temp_files() +{ + int v0; // eax + int v1; // esi + int v2; // eax + + if ( (unsigned char)gbMaxPlayers <= 1u ) + { + v0 = pfile_get_save_num_from_name(plr[myplr]._pName); + v1 = v0; + _LOBYTE(v2) = pfile_open_archive(0, v0); + if ( !v2 ) + TermMsg("Unable to write to save file archive"); + mpqapi_remove_hash_entries(pfile_get_temp_name); + pfile_flush(1, v1); + } +} +// 679660: using guessed type char gbMaxPlayers; + +//----- (0044A563) -------------------------------------------------------- +bool __stdcall pfile_get_temp_name(int a1, char *dst) +{ + int v2; // eax + const char *v3; // ecx + + v2 = a1; + if ( (unsigned int)a1 < 0x11 ) + { + v3 = "templ%02d"; +LABEL_5: + sprintf(dst, v3, v2); + return 1; + } + if ( (unsigned int)a1 < 0x22 ) + { + v2 = a1 - 17; + v3 = "temps%02d"; + goto LABEL_5; + } + return 0; +} + +//----- (0044A598) -------------------------------------------------------- +void __cdecl pfile_rename_temp_to_perm() +{ + int v0; // eax + int v1; // edi + int v2; // eax + int v3; // esi + int v4; // eax + int v5; // eax + int v6; // eax + char v7[260]; // [esp+8h] [ebp-208h] + char v8[260]; // [esp+10Ch] [ebp-104h] + + v0 = pfile_get_save_num_from_name(plr[myplr]._pName); + v1 = v0; + _LOBYTE(v2) = pfile_open_archive(0, v0); + if ( !v2 ) + TermMsg("Unable to write to save file archive"); + v3 = 0; + while ( 1 ) + { + _LOBYTE(v6) = pfile_get_temp_name(v3, v7); + if ( !v6 ) + break; + GetPermSaveNames(v3++, v8); + _LOBYTE(v4) = mpqapi_has_file(v7); + if ( v4 ) + { + _LOBYTE(v5) = mpqapi_has_file(v8); + if ( v5 ) + mpqapi_remove_hash_entry(v8); + mpqapi_rename(v7, v8); + } + } + GetPermSaveNames(v3, v8); + pfile_flush(1, v1); +} + +//----- (0044A644) -------------------------------------------------------- +bool __stdcall GetPermSaveNames(int dwIndex, char *szPerm) +{ + int v2; // eax + const char *v3; // ecx + + v2 = dwIndex; + if ( (unsigned int)dwIndex < 0x11 ) + { + v3 = "perml%02d"; +LABEL_5: + sprintf(szPerm, v3, v2); + return 1; + } + if ( (unsigned int)dwIndex < 0x22 ) + { + v2 = dwIndex - 17; + v3 = "perms%02d"; + goto LABEL_5; + } + return 0; +} + +//----- (0044A679) -------------------------------------------------------- +void __fastcall pfile_write_save_file(char *pszName, void *pbData, int dwLen, int qwLen) +{ + void *v4; // ebx + int v5; // eax + int v6; // eax + char file_name[260]; // [esp+Ch] [ebp-118h] + char password[16]; // [esp+110h] [ebp-14h] + int v9; // [esp+120h] [ebp-4h] + + v4 = pbData; + pfile_strcpy(file_name, pszName); + v5 = pfile_get_save_num_from_name(plr[myplr]._pName); + strcpy(password, "xrgyrkj1"); + v9 = v5; + *(_DWORD *)&password[9] = 0; + *(_WORD *)&password[13] = 0; + password[15] = 0; + if ( (unsigned char)gbMaxPlayers > 1u ) + strcpy(password, "szqnlsk1"); + codec_encode(v4, dwLen, qwLen, password); + _LOBYTE(v6) = pfile_open_archive(0, v9); + if ( !v6 ) + TermMsg("Unable to write to save file archive"); + mpqapi_write_file(file_name, (char *)v4, qwLen); + pfile_flush(1, v9); +} +// 679660: using guessed type char gbMaxPlayers; + +//----- (0044A727) -------------------------------------------------------- +void __fastcall pfile_strcpy(char *dst, char *src) +{ + strcpy(dst, src); +} + +//----- (0044A731) -------------------------------------------------------- +char *__fastcall pfile_read(char *pszName, int *pdwLen) +{ + int *v2; // ebx + int v3; // eax + void *v4; // edi + int v5; // eax + int v6; // eax + void *v7; // eax + int v8; // eax + char *v9; // esi + int v10; // eax + int v11; // eax + char v13[260]; // [esp+Ch] [ebp-124h] + char password[16]; // [esp+110h] [ebp-20h] + void *src_dst; // [esp+120h] [ebp-10h] + int nread; // [esp+124h] [ebp-Ch] + DWORD nSize; // [esp+128h] [ebp-8h] + void *file; // [esp+12Ch] [ebp-4h] + + v2 = pdwLen; + pfile_strcpy(v13, pszName); + v3 = pfile_get_save_num_from_name(plr[myplr]._pName); + v4 = pfile_open_save_archive(0, v3); + if ( !v4 ) + TermMsg("Unable to open save file archive"); + _LOBYTE(v5) = SFileOpenFileEx(v4, v13, 0, &file); + if ( !v5 ) + TermMsg("Unable to open save file"); + v6 = SFileGetFileSize((int *)file, 0); + *v2 = v6; + if ( !v6 ) + TermMsg("Invalid save file"); + v7 = DiabloAllocPtr(*v2); + src_dst = v7; + _LOBYTE(v8) = SFileReadFile(file, (char *)v7, *v2, (unsigned long *)&nread, 0); + if ( !v8 ) + TermMsg("Unable to read save file"); + SFileCloseFile(file); + pfile_SFileCloseArchive(v4); + strcpy(password, "xrgyrkj1"); + nSize = 16; + *(_DWORD *)&password[9] = 0; + *(_WORD *)&password[13] = 0; + password[15] = 0; + if ( (unsigned char)gbMaxPlayers > 1u ) + strcpy(password, "szqnlsk1"); + v9 = (char *)src_dst; + v10 = codec_decode(src_dst, *v2, password); + *v2 = v10; + if ( !v10 ) + { + if ( (unsigned char)gbMaxPlayers > 1u ) + { + GetComputerNameA(password, &nSize); + if ( SFileSetFilePointer((int)file, 0, 0, 0) ) + TermMsg("Unable to read save file"); + _LOBYTE(v11) = SFileReadFile(file, v9, *v2, (unsigned long *)&nread, 0); + if ( !v11 ) + TermMsg("Unable to read save file"); + *v2 = codec_decode(v9, *v2, password); + } + if ( !*v2 ) + TermMsg("Invalid save file"); + } + return v9; +} +// 679660: using guessed type char gbMaxPlayers; + +//----- (0044A8B3) -------------------------------------------------------- +void __fastcall pfile_update(bool force_save) +{ + BOOL v1; // esi + DWORD v2; // eax + + v1 = force_save; + if ( gbMaxPlayers != 1 ) + { + v2 = GetTickCount(); + if ( v1 || (signed int)(v2 - save_prev_tc) > 60000 ) + { + save_prev_tc = v2; + pfile_write_hero(); + } + } +} +// 679660: using guessed type char gbMaxPlayers; +// 686428: using guessed type int save_prev_tc; + +//----- (0044A8EB) -------------------------------------------------------- +void __cdecl player_cpp_init() +{ + player_cpp_init_value = player_inf; +} +// 47F204: using guessed type int player_inf; +// 68643C: using guessed type int player_cpp_init_value; + +//----- (0044A8F6) -------------------------------------------------------- +void __fastcall player_copy_frames(char *src, char *dst) +{ + char *v2; // eax + int v3; // esi + signed int v4; // edx + + v2 = dst; + v3 = src - dst; + v4 = 8; + do + { + *(_DWORD *)v2 = (unsigned int)&src[*(_DWORD *)&v2[v3]]; + v2 += 4; + --v4; + } + while ( v4 ); +} + +//----- (0044A911) -------------------------------------------------------- +void __fastcall LoadPlrGFX(int pnum, int a2) +{ + int v2; // esi + PlayerStruct *v3; // esi + unsigned int v4; // ecx + char v5; // al + void *v6; // edi + char *v7; // ebx + int v8; // ecx + int v9; // ecx + int v10; // ecx + int v11; // ecx + int v12; // ecx + int v13; // ecx + char arglist[256]; // [esp+Ch] [ebp-120h] + char v15[16]; // [esp+10Ch] [ebp-20h] + int v16; // [esp+11Ch] [ebp-10h] + char *v17; // [esp+120h] [ebp-Ch] + unsigned int v18; // [esp+124h] [ebp-8h] + const char *v19; // [esp+128h] [ebp-4h] + + v2 = pnum; + v16 = a2; + if ( (unsigned int)pnum >= 4 ) + TermMsg("LoadPlrGFX: illegal player %d", pnum); + v3 = &plr[v2]; + sprintf( + v15, + "%c%c%c", + (char)CharChar[SLOBYTE(v3->_pClass)], + (char)ArmourChar[v3->_pgfxnum >> 4], + (char)WepChar[v3->_pgfxnum & 0xF]); + v4 = 1; + v17 = ClassNameTbl[SLOBYTE(v3->_pClass)]; + v5 = leveltype; + v6 = v17; + v7 = v17; + v18 = 1; + do + { + if ( !(v4 & v16) ) + goto LABEL_38; + if ( v4 <= 0x10 ) + { + if ( v4 == 16 ) + { + if ( !v5 ) + goto LABEL_38; + v6 = v3->pLFrame; + v19 = "LM"; + v7 = (char *)v3->_peqS2_LM; + } + else + { + v8 = v4 - 1; + if ( v8 ) + { + v9 = v8 - 1; + if ( v9 ) + { + v10 = v9 - 2; + if ( v10 ) + { + if ( v10 == 4 ) + { + if ( !v5 ) + goto LABEL_38; + v6 = v3->pHFrame; + v19 = "HT"; + v7 = (char *)v3->_peqH; + } + else + { +LABEL_27: + TermMsg("PLR:2"); + } + } + else + { + if ( !v5 ) + goto LABEL_38; + v6 = v3->pAFrame; + v19 = "AT"; + v7 = (char *)v3->_peqA; + } + } + else + { + v19 = "AW"; + if ( !v5 ) + v19 = "WL"; + v6 = v3->pWFrame; + v7 = (char *)v3->_peqW; + } + } + else + { + v19 = "AS"; + if ( !v5 ) + v19 = "ST"; + v6 = v3->pSFrame; + v7 = (char *)v3->_peqN; + } + } +LABEL_37: + sprintf(arglist, "PlrGFX\\%s\\%s\\%s%s.CL2", v17, v15, v15, v19); + LoadFileWithMem(arglist, v6); + player_copy_frames((char *)v6, v7); + v3->_pGFXLoad |= v18; + v5 = leveltype; + goto LABEL_38; + } + v11 = v4 - 32; + if ( !v11 ) + { + if ( !v5 ) + goto LABEL_38; + v6 = v3->pFFrame; + v19 = "FM"; + v7 = (char *)v3->_peqS1_FM; + goto LABEL_37; + } + v12 = v11 - 32; + if ( !v12 ) + { + if ( !v5 ) + goto LABEL_38; + v6 = v3->pQFrame; + v19 = "QM"; + v7 = (char *)v3->_peqS3_QM; + goto LABEL_37; + } + v13 = v12 - 64; + if ( !v13 ) + { + if ( v3->_pgfxnum & 0xF ) + goto LABEL_38; + v6 = v3->pDFrame; + v19 = "DT"; + v7 = (char *)v3->_peqD; + goto LABEL_37; + } + if ( v13 != 128 ) + goto LABEL_27; + if ( v5 && v3->_pBlockFlag ) + { + v6 = v3->pBFrame; + v19 = "BL"; + v7 = (char *)v3->_peqB; + goto LABEL_37; + } +LABEL_38: + v4 = 2 * v18; + v18 *= 2; + } + while ( v18 <= 0x17F ); +} +// 5BB1ED: using guessed type char leveltype; + +//----- (0044AB70) -------------------------------------------------------- +void __fastcall InitPlayerGFX(int pnum) +{ + int v1; // esi + int v2; // edx + + v1 = pnum; + if ( (unsigned int)pnum >= 4 ) + TermMsg("InitPlayerGFX: illegal player %d", pnum); + if ( plr[v1]._pHitPoints & 0xFFFFFFC0 ) + { + v2 = 383; + } + else + { + plr[v1]._pgfxnum = 0; + v2 = 128; + } + LoadPlrGFX(v1, v2); +} + +//----- (0044ABB4) -------------------------------------------------------- +void __fastcall InitPlrGFXMem(int pnum) +{ + int v1; // esi + unsigned int v2; // ebp + unsigned int v3; // eax + char *v4; // ecx + int v5; // esi + void *v6; // eax + bool v7; // zf + unsigned int v8; // ebx + unsigned int v9; // eax + char *v10; // ecx + void *v11; // eax + void *v12; // eax + void *v13; // eax + void *v14; // eax + void *v15; // eax + void *v16; // eax + void *v17; // eax + void *v18; // eax + + v1 = pnum; + if ( (unsigned int)pnum >= 4 ) + TermMsg("InitPlrGFXMem: illegal player %d", pnum); + if ( !(plr_gfx_flag & 1) ) + { + plr_gfx_flag |= 1u; + v2 = GetPlrGFXSize("ST"); + v3 = GetPlrGFXSize("AS"); + v4 = "AS"; + if ( v3 <= v2 ) + v4 = "ST"; + plr_sframe_size = GetPlrGFXSize(v4); + } + v5 = v1; + v6 = DiabloAllocPtr(plr_sframe_size); + v7 = (plr_gfx_flag & 2) == 0; + plr[v5].pSFrame = v6; + if ( v7 ) + { + plr_gfx_flag |= 2u; + v8 = GetPlrGFXSize("WL"); + v9 = GetPlrGFXSize("AW"); + v10 = "AW"; + if ( v9 <= v8 ) + v10 = "WL"; + plr_wframe_size = GetPlrGFXSize(v10); + } + v11 = DiabloAllocPtr(plr_wframe_size); + v7 = (plr_gfx_flag & 4) == 0; + plr[v5].pWFrame = v11; + if ( v7 ) + { + plr_gfx_flag |= 4u; + plr_aframe_size = GetPlrGFXSize("AT"); + } + v12 = DiabloAllocPtr(plr_aframe_size); + v7 = (plr_gfx_flag & 8) == 0; + plr[v5].pAFrame = v12; + if ( v7 ) + { + plr_gfx_flag |= 8u; + plr_hframe_size = GetPlrGFXSize("HT"); + } + v13 = DiabloAllocPtr(plr_hframe_size); + v7 = (plr_gfx_flag & 0x10) == 0; + plr[v5].pHFrame = v13; + if ( v7 ) + { + plr_gfx_flag |= 0x10u; + plr_lframe_size = GetPlrGFXSize("LM"); + } + v14 = DiabloAllocPtr(plr_lframe_size); + v7 = (plr_gfx_flag & 0x20) == 0; + plr[v5].pLFrame = v14; + if ( v7 ) + { + plr_gfx_flag |= 0x20u; + plr_fframe_size = GetPlrGFXSize("FM"); + } + v15 = DiabloAllocPtr(plr_fframe_size); + v7 = (plr_gfx_flag & 0x40) == 0; + plr[v5].pFFrame = v15; + if ( v7 ) + { + plr_gfx_flag |= 0x40u; + plr_qframe_size = GetPlrGFXSize("QM"); + } + v16 = DiabloAllocPtr(plr_qframe_size); + v7 = plr_gfx_flag >= 0; + plr[v5].pQFrame = v16; + if ( v7 ) + { + plr_gfx_flag |= 0x80u; + plr_dframe_size = GetPlrGFXSize("DT"); + } + v17 = DiabloAllocPtr(plr_dframe_size); + v7 = (plr_gfx_bflag & 1) == 0; + plr[v5].pDFrame = v17; + if ( v7 ) + { + plr_gfx_bflag |= 1u; + plr_bframe_size = GetPlrGFXSize("BL"); + } + v18 = DiabloAllocPtr(plr_bframe_size); + plr[v5]._pGFXLoad = 0; + plr[v5].pBFrame = v18; +} +// 686438: using guessed type char plr_gfx_flag; +// 69B7BC: using guessed type char plr_gfx_bflag; + +//----- (0044ADC8) -------------------------------------------------------- +int __fastcall GetPlrGFXSize(char *szCel) +{ + unsigned int v1; // ebx + unsigned char *v2; // edi + unsigned char *v3; // esi + int dwInitParam[64]; // [esp+Ch] [ebp-124h] + char v6[16]; // [esp+10Ch] [ebp-24h] + unsigned int v7; // [esp+11Ch] [ebp-14h] + char *v8; // [esp+120h] [ebp-10h] + void *a1; // [esp+124h] [ebp-Ch] + char **v10; // [esp+128h] [ebp-8h] + unsigned int v11; // [esp+12Ch] [ebp-4h] + + v1 = 0; + v8 = szCel; + v11 = 0; + v10 = ClassNameTbl; + do + { + v2 = ArmourChar; + do + { + v3 = WepChar; + do + { + sprintf(v6, "%c%c%c", (char)CharChar[v1], (char)*v2, (char)*v3); + sprintf((char *)dwInitParam, "PlrGFX\\%s\\%s\\%s%s.CL2", *v10, v6, v6, v8); + if ( wave_open_file((LPARAM)dwInitParam, (DIABFILE *)&a1, 1) ) + { + v7 = wave_get_file_size((int *)a1, 0); + wave_close_file(a1); + if ( v11 <= v7 ) + v11 = v7; + } + ++v3; + } + while ( *v3 ); + ++v2; + } + while ( *v2 ); + ++v10; + ++v1; + } + while ( v1 < 3 ); + return v11; +} + +//----- (0044AE89) -------------------------------------------------------- +void __fastcall FreePlayerGFX(int pnum) +{ + int v1; // esi + int v2; // esi + void *v3; // ecx + void *v4; // ecx + void *v5; // ecx + void *v6; // ecx + void *v7; // ecx + void *v8; // ecx + void *v9; // ecx + void *v10; // ecx + void *v11; // ecx + + v1 = pnum; + if ( (unsigned int)pnum >= 4 ) + TermMsg("FreePlayerGFX: illegal player %d", pnum); + v2 = v1; + v3 = plr[v2].pSFrame; + plr[v2].pSFrame = 0; + mem_free_dbg(v3); + v4 = plr[v2].pWFrame; + plr[v2].pWFrame = 0; + mem_free_dbg(v4); + v5 = plr[v2].pAFrame; + plr[v2].pAFrame = 0; + mem_free_dbg(v5); + v6 = plr[v2].pHFrame; + plr[v2].pHFrame = 0; + mem_free_dbg(v6); + v7 = plr[v2].pLFrame; + plr[v2].pLFrame = 0; + mem_free_dbg(v7); + v8 = plr[v2].pFFrame; + plr[v2].pFFrame = 0; + mem_free_dbg(v8); + v9 = plr[v2].pQFrame; + plr[v2].pQFrame = 0; + mem_free_dbg(v9); + v10 = plr[v2].pDFrame; + plr[v2].pDFrame = 0; + mem_free_dbg(v10); + v11 = plr[v2].pBFrame; + plr[v2].pBFrame = 0; + mem_free_dbg(v11); + plr[v2]._pGFXLoad = 0; +} + +//----- (0044AF37) -------------------------------------------------------- +void __fastcall NewPlrAnim(int pnum, int Peq, int numFrames, int Delay) +{ + int v4; // edi + int v5; // esi + int v6; // eax + int v7; // [esp+14h] [ebp+Ch] + + v4 = pnum; + v5 = Peq; + if ( (unsigned int)pnum >= 4 ) + TermMsg("NewPlrAnim: illegal player %d", pnum); + v6 = v4; + plr[v6]._pAnimLen = numFrames; + plr[v6]._pAnimCnt = 0; + plr[v6]._pAnimDelay = Delay; + plr[v6]._pAnimData = v5; + plr[v6]._pAnimWidth = v7; + plr[v6]._pAnimFrame = 1; + plr[v6]._pAnimWidth2 = (v7 - 64) >> 1; +} + +//----- (0044AF9C) -------------------------------------------------------- +void __fastcall ClearPlrPVars(int pnum) +{ + int v1; // esi + int v2; // eax + + v1 = pnum; + if ( (unsigned int)pnum >= 4 ) + TermMsg("ClearPlrPVars: illegal player %d", pnum); + v2 = v1; + plr[v2]._pVar1 = 0; + plr[v2]._pVar2 = 0; + plr[v2]._pVar3 = 0; + plr[v2]._pVar4 = 0; + plr[v2]._pVar5 = 0; + plr[v2]._pVar6 = 0; + plr[v2]._pVar7 = 0; + plr[v2]._pVar8 = 0; +} + +//----- (0044AFED) -------------------------------------------------------- +void __fastcall SetPlrAnims(int pnum) +{ + int v1; // esi + char v2; // bl + int v3; // eax + int v4; // esi + int v5; // ecx + bool v6; // zf + int v7; // ecx + + v1 = pnum; + if ( (unsigned int)pnum >= 4 ) + TermMsg("SetPlrAnims: illegal player %d", pnum); + v2 = leveltype; + v3 = v1; + v4 = SLOBYTE(plr[v1]._pClass); + v5 = v4; + v6 = leveltype == 0; + plr[v3]._pNFNum = 96; + plr[v3]._pWFNum = 96; + plr[v3].frame_9_unk = 128; + plr[v3]._pHFNum = 96; + plr[v3].frame_A_unk = 96; + plr[v3]._pDFNum = 128; + plr[v3]._pBFNum = 96; + if ( v6 ) + { + plr[v3]._pNFrames = (char)PlrGFXAnimLens[v5].TNFrame; + plr[v3]._pWFrames = (char)PlrGFXAnimLens[v5].TWFrame; + plr[v3]._pDFrames = (char)PlrGFXAnimLens[v5].DFrame; + plr[v3]._pSFrames = (char)PlrGFXAnimLens[v5].SFrame; + } + else + { + plr[v3]._pNFrames = (char)PlrGFXAnimLens[v5].NFrame; + plr[v3]._pWFrames = (char)PlrGFXAnimLens[v5].WFrame; + plr[v3]._pAFrames = (char)PlrGFXAnimLens[v5].AFrame; + plr[v3]._pHFrames = (char)PlrGFXAnimLens[v5].HFrame; + plr[v3]._pSFrames = (char)PlrGFXAnimLens[v5].SFrame; + plr[v3]._pDFrames = (char)PlrGFXAnimLens[v5].DFrame; + plr[v3]._pBFrames = (char)PlrGFXAnimLens[v5].BFrame; + plr[v3]._pAFNum = (char)PlrGFXAnimLens[v5].A2Frame; + } + plr[v3]._pSFNum = (char)PlrGFXAnimLens[v5].A3Frame; + v7 = plr[v3]._pgfxnum & 0xF; + if ( !v4 ) + { + if ( v7 == 4 ) + { + if ( v2 ) + plr[v3]._pNFrames = 8; + plr[v3].frame_9_unk = 96; + goto LABEL_11; + } + if ( v7 == 5 ) + { + plr[v3]._pAFrames = 20; + plr[v3]._pAFNum = 10; + return; + } +LABEL_19: + if ( v7 == 8 ) + { + plr[v3]._pAFrames = 16; +LABEL_11: + plr[v3]._pAFNum = 11; + return; + } + return; + } + if ( v4 == 1 ) + { + if ( v7 == 5 ) + { + plr[v3]._pAFrames = 22; + plr[v3]._pAFNum = 13; + return; + } + if ( v7 == 4 ) + { + plr[v3]._pAFrames = 12; + plr[v3]._pAFNum = 7; + return; + } + goto LABEL_19; + } + if ( v4 != 2 ) + return; + plr[v3].frame_A_unk = 128; + switch ( v7 ) + { + case 0: + plr[v3]._pAFrames = 20; + return; + case 1: + plr[v3]._pAFNum = 9; + return; + case 4: + plr[v3]._pAFrames = 20; + break; + case 5: + plr[v3]._pAFrames = 24; + break; + default: + return; + } + plr[v3]._pAFNum = 16; +} +// 5BB1ED: using guessed type char leveltype; + +//----- (0044B1FD) -------------------------------------------------------- +void __fastcall ClearPlrRVars(PlayerStruct *pPlayer) +{ + pPlayer->bReserved[0] = 0; + pPlayer->bReserved[1] = 0; + pPlayer->bReserved[2] = 0; + pPlayer->wReserved[0] = 0; + pPlayer->wReserved[1] = 0; + pPlayer->wReserved[2] = 0; + pPlayer->wReserved[3] = 0; + pPlayer->wReserved[4] = 0; + pPlayer->wReserved[5] = 0; + pPlayer->wReserved[6] = 0; + pPlayer->wReserved[7] = 0; + pPlayer->dwReserved[0] = 0; + pPlayer->dwReserved[1] = 0; + pPlayer->dwReserved[2] = 0; + pPlayer->dwReserved[3] = 0; + pPlayer->dwReserved[4] = 0; + pPlayer->dwReserved[5] = 0; + pPlayer->dwReserved[6] = 0; +} + +//----- (0044B274) -------------------------------------------------------- +void __fastcall CreatePlayer(int pnum, char c) +{ + unsigned int v2; // edi + char v3; // bl + int v4; // esi + int v5; // eax + int v6; // ecx + char v7; // al + char v8; // al + char v9; // al + char v10; // al + int v11; // edi + signed int v12; // ebp + int v13; // eax + int v14; // eax + int v15; // eax + int v16; // eax + int v17; // eax + bool v18; // zf + char v19; // [esp+Ch] [ebp-8h] + int arglist; // [esp+10h] [ebp-4h] + + v2 = pnum; + v3 = c; + v4 = pnum; + v19 = c; + arglist = pnum; + ClearPlrRVars(&plr[pnum]); + v5 = GetTickCount(); + SetRndSeed(v5); + if ( v2 >= 4 ) + TermMsg("CreatePlayer: illegal player %d", v2); + v6 = v3; + _LOBYTE(plr[v4]._pClass) = v3; + v7 = StrengthTbl[v6]; + if ( v7 < 0 ) + v7 = 0; + plr[v4]._pStrength = v7; + plr[v4]._pBaseStr = v7; + v8 = MagicTbl[v6]; + if ( v8 < 0 ) + v8 = 0; + plr[v4]._pMagic = v8; + plr[v4]._pBaseMag = v8; + v9 = DexterityTbl[v6]; + if ( v9 < 0 ) + v9 = 0; + plr[v4]._pDexterity = v9; + plr[v4]._pBaseDex = v9; + v10 = VitalityTbl[v6]; + if ( v10 < 0 ) + v10 = 0; + v11 = v10; + plr[v4]._pVitality = v10; + plr[v4]._pBaseVit = v10; + plr[v4]._pStatPts = 0; + plr[v4].pTownWarps = 0; + plr[v4].pDungMsgs = 0; + plr[v4].pLvlLoad = 0; + plr[v4].pDiabloKillLevel = 0; + if ( v19 == 1 ) + { + v12 = 200; + v13 = plr[v4]._pLevel * (plr[v4]._pStrength + plr[v4]._pDexterity); + } + else + { + v13 = plr[v4]._pStrength * plr[v4]._pLevel; + v12 = 100; + } + plr[v4]._pDamageMod = v13 / v12; + plr[v4]._pBaseToBlk = ToBlkTbl[v6]; + plr[v4]._pHitPoints = (v11 + 10) << 6; + if ( !v19 ) + plr[v4]._pHitPoints = (v11 + 10) << 7; + if ( v19 == 1 ) + plr[v4]._pHitPoints += plr[v4]._pHitPoints >> 1; + v14 = plr[v4]._pHitPoints; + plr[v4]._pMaxHP = v14; + plr[v4]._pHPBase = v14; + plr[v4]._pMaxHPBase = v14; + v15 = plr[v4]._pMagic << 6; + plr[v4]._pMana = v15; + if ( v19 == 2 ) + plr[v4]._pMana = 2 * v15; + if ( v19 == 1 ) + plr[v4]._pMana += plr[v4]._pMana >> 1; + v16 = plr[v4]._pMana; + plr[v4]._pMaxMana = v16; + plr[v4]._pManaBase = v16; + plr[v4]._pMaxManaBase = v16; + v17 = ExpLvlsTbl[1]; + plr[v4]._pLevel = 1; + plr[v4]._pMaxLvl = 1; + plr[v4]._pExperience = 0; + plr[v4]._pMaxExp = 0; + plr[v4]._pNextExper = v17; + plr[v4]._pArmorClass = 0; + plr[v4]._pMagResist = 0; + plr[v4]._pFireResist = 0; + plr[v4]._pLghtResist = 0; + plr[v4]._pLightRad = 10; + plr[v4]._pInfraFlag = 0; + if ( !v19 ) + { + plr[v4]._pAblSpells[0] = 0x2000000; +LABEL_26: + plr[v4]._pAblSpells[1] = 0; +LABEL_27: + plr[v4]._pMemSpells[0] = 0; + goto LABEL_28; + } + if ( v19 == 1 ) + { + plr[v4]._pAblSpells[0] = 0x8000000; + goto LABEL_26; + } + if ( v19 != 2 ) + goto LABEL_27; + plr[v4]._pAblSpells[0] = 0x4000000; + plr[v4]._pAblSpells[1] = 0; + plr[v4]._pMemSpells[0] = 1; +LABEL_28: + plr[v4]._pMemSpells[1] = 0; + memset(plr[v4]._pSplLvl, 0, sizeof(plr[v4]._pSplLvl)); + v18 = _LOBYTE(plr[v4]._pClass) == 2; + _LOBYTE(plr[v4]._pSpellFlags) = 0; + if ( v18 ) + plr[v4]._pSplLvl[1] = 2; + plr[v4]._pSplHotKey[0] = -1; + plr[v4]._pSplHotKey[1] = -1; + plr[v4]._pSplHotKey[2] = -1; + if ( v19 ) + { + if ( v19 == 1 ) + { + plr[v4]._pgfxnum = 4; + } + else if ( v19 == 2 ) + { + plr[v4]._pgfxnum = 8; + } + } + else + { + plr[v4]._pgfxnum = 3; + } + *(_DWORD *)plr[v4]._pLvlVisited = 0; + *(_DWORD *)&plr[v4]._pLvlVisited[4] = 0; + *(_DWORD *)&plr[v4]._pLvlVisited[8] = 0; + *(_DWORD *)&plr[v4]._pLvlVisited[12] = 0; + plr[v4]._pLvlVisited[16] = 0; + *(_DWORD *)plr[v4]._pSLvlVisited = 0; + *(_DWORD *)&plr[v4]._pSLvlVisited[4] = 0; + *(_WORD *)&plr[v4]._pSLvlVisited[8] = 0; + plr[v4]._pLvlChanging = 0; + plr[v4].pTownWarps = 0; + plr[v4].pLvlLoad = 0; + plr[v4].pBattleNet = 0; + plr[v4].pManaShield = 0; + InitDungMsgs(arglist); + CreatePlrItems(arglist); + SetRndSeed(0); +} + +//----- (0044B582) -------------------------------------------------------- +int __fastcall CalcStatDiff(int pnum) +{ + int v1; // ecx + int v2; // edx + + v1 = pnum; + v2 = SLOBYTE(plr[v1]._pClass); + return MaxStats[v2][0] + + MaxStats[v2][1] + + MaxStats[v2][2] + + MaxStats[v2][3] + - plr[v1]._pBaseVit + - plr[v1]._pBaseDex + - plr[v1]._pBaseMag + - plr[v1]._pBaseStr; +} + +//----- (0044B5C3) -------------------------------------------------------- +void __fastcall NextPlrLevel(int pnum) +{ + int v1; // edi + int v2; // esi + char *v3; // eax + char v4; // bl + int v5; // eax + char v6; // bl + char v7; // al + signed int v8; // edx + int v9; // ebp + signed int v10; // eax + int v11; // edx + + v1 = pnum; + if ( (unsigned int)pnum >= 4 ) + TermMsg("NextPlrLevel: illegal player %d", pnum); + v2 = v1; + v3 = &plr[v1]._pLevel; + v4 = ++*v3; + ++plr[v2]._pMaxLvl; + if ( CalcStatDiff(v1) >= 5 ) + plr[v2]._pStatPts += 5; + else + plr[v2]._pStatPts = CalcStatDiff(v1); + v5 = v4; + v6 = gbMaxPlayers; + plr[v2]._pNextExper = ExpLvlsTbl[v5]; + v7 = plr[v2]._pClass; + v8 = v7 != 2 ? 128 : 64; + if ( v6 == 1 ) + v8 = v7 != 2 ? 129 : 65; + v9 = myplr; + plr[v2]._pMaxHP += v8; + plr[v2]._pHitPoints = plr[v2]._pMaxHP; + plr[v2]._pMaxHPBase += v8; + plr[v2]._pHPBase = plr[v2]._pMaxHPBase; + if ( v1 == v9 ) + drawhpflag = 1; + v10 = v7 != 0 ? 128 : 64; + if ( v6 == 1 ) + ++v10; + plr[v2]._pMaxMana += v10; + plr[v2]._pMaxManaBase += v10; + v11 = plr[v2]._pMaxManaBase; + if ( !(plr[v1]._pIFlags & 0x8000000) ) + { + plr[v2]._pMana = plr[v2]._pMaxMana; + plr[v2]._pManaBase = v11; + } + if ( v1 == v9 ) + drawmanaflag = 1; +} +// 679660: using guessed type char gbMaxPlayers; + +//----- (0044B6C8) -------------------------------------------------------- +void __fastcall AddPlrExperience(int pnum, int lvl, __int32 exp) +{ + int v3; // eax + int v4; // esi + int v5; // esi + char v6; // bl + int v7; // edi + signed int v8; // ecx + int v9; // ecx + int *v10; // eax + int v11; // eax + int v12; // ecx + int v13; // ecx + int v14; // esi + int arglist; // [esp+4h] [ebp-Ch] + int v16; // [esp+8h] [ebp-8h] + + v3 = myplr; + v4 = pnum; + v16 = lvl; + arglist = pnum; + if ( pnum == myplr ) + { + if ( (unsigned int)myplr >= 4 ) + { + TermMsg("AddPlrExperience: illegal player %d", myplr); + v3 = myplr; + } + if ( plr[v3]._pHitPoints > 0 ) + { + v5 = v4; + v6 = plr[v5]._pLevel; + v7 = (signed __int64)((((double)v16 - (double)v6) * 0.1 + 1.0) * (double)exp); + if ( v7 < 0 ) + v7 = 0; + if ( (unsigned char)gbMaxPlayers > 1u ) + { + if ( v6 >= 0 ) + { + v8 = v6; + if ( v6 >= 50 ) + v8 = 50; + } + else + { + v8 = 0; + } + if ( v7 >= ExpLvlsTbl[v8] / 20 ) + v7 = ExpLvlsTbl[v8] / 20; + v9 = 200 * v8; + if ( v7 >= v9 ) + v7 = v9; + } + v10 = &plr[v5]._pExperience; + *v10 += v7; + if ( plr[v5]._pExperience > 2000000000u ) + *v10 = 2000000000; + v11 = *v10; + if ( v11 < ExpLvlsTbl[49] ) + { + v12 = 0; + if ( v11 >= ExpLvlsTbl[0] ) + { + do + ++v12; + while ( v11 >= ExpLvlsTbl[v12] ); + } + if ( v12 != v6 ) + { + v13 = v12 - v6; + if ( v13 > 0 ) + { + v14 = v13; + do + { + NextPlrLevel(arglist); + --v14; + } + while ( v14 ); + } + } + NetSendCmdParam1(0, CMD_PLRLEVEL, plr[myplr]._pLevel); + } + else + { + plr[v5]._pLevel = 50; + } + } + } +} +// 679660: using guessed type char gbMaxPlayers; + +//----- (0044B7F8) -------------------------------------------------------- +void __fastcall AddPlrMonstExper(int lvl, __int32 exp, char pmask) +{ + int v3; // ebx + int v4; // edi + signed int v5; // ecx + + v3 = lvl; + v4 = 0; + v5 = 0; + do + { + if ( (1 << v5) & pmask ) + ++v4; + ++v5; + } + while ( v5 < 4 ); + if ( v4 ) + { + if ( (1 << myplr) & pmask ) + AddPlrExperience(myplr, v3, exp / v4); + } +} + +//----- (0044B83C) -------------------------------------------------------- +void __fastcall InitPlayer(int pnum, bool FirstTime) +{ + int v2; // ebx + int v3; // esi + PlayerStruct *v4; // edi + int v5; // eax + int v6; // ST08_4 + int v7; // ecx + int v8; // eax + int v9; // ecx + int v10; // ST08_4 + int v11; // edx + int v12; // eax + unsigned int v13; // edi + bool v14; // zf + int v15; // eax + int v16; // ecx + int v17; // edx + char v18; // al + int v19; // eax + BOOL v20; // [esp+8h] [ebp-4h] + + v2 = pnum; + v20 = FirstTime; + if ( (unsigned int)pnum >= 4 ) + TermMsg("InitPlayer: illegal player %d", pnum); + v3 = v2; + v4 = &plr[v2]; + ClearPlrRVars(&plr[v2]); + if ( v20 ) + { + v5 = plr[v3]._pgfxnum; + plr[v3]._pRSpell = -1; + plr[v3]._pSBkSpell = -1; + plr[v3]._pSpell = -1; + _LOBYTE(plr[v3]._pRSplType) = 4; + plr[v3]._pSplType = 4; + plr[v3]._pwtype = (v5 & 0xF) == 4; + plr[v3].pManaShield = 0; + } + if ( plr[v3].plrlevel == currlevel || leveldebug ) + { + SetPlrAnims(v2); + plr[v3]._pxoff = 0; + plr[v3]._pyoff = 0; + plr[v3]._pxvel = 0; + plr[v3]._pyvel = 0; + ClearPlrPVars(v2); + if ( (signed int)(plr[v3]._pHitPoints & 0xFFFFFFC0) <= 0 ) + { + v10 = plr[v3]._pDFNum; + v11 = plr[v3]._peqD[0]; + v4->_pmode = 8; + NewPlrAnim(v2, v11, plr[v3]._pDFrames, 1); + v12 = plr[v3]._pAnimLen; + plr[v3]._pAnimFrame = v12 - 1; + plr[v3]._pVar8 = 2 * v12; + } + else + { + v6 = plr[v3]._pNFNum; + v4->_pmode = 0; + NewPlrAnim(v2, plr[v3]._peqN[0], plr[v3]._pNFrames, 3); + _LOBYTE(v7) = 2; + v8 = random(v7, plr[v3]._pNFrames - 1); + _LOBYTE(v9) = 2; + plr[v3]._pAnimFrame = v8 + 1; + plr[v3]._pAnimCnt = random(v9, 3); + } + v13 = 0; + v14 = v2 == myplr; + plr[v3]._pdir = 0; + plr[v3]._peflag = 0; + if ( v14 ) + { + if ( !v20 || currlevel ) + { + plr[v3].WorldX = ViewX; + plr[v3].WorldY = ViewY; + } + plr[v3]._ptargx = plr[v3].WorldX; + plr[v3]._ptargy = plr[v3].WorldY; + } + else + { + plr[v3]._ptargx = plr[v3].WorldX; + plr[v3]._ptargy = plr[v3].WorldY; + do + { + if ( PosOkPlayer(v2, plr[v3].WorldX + plrxoff2[v13], plr[v3].WorldY + plryoff2[v13]) ) + break; + ++v13; + } + while ( v13 < 8 ); + v15 = plryoff2[v13]; + plr[v3].WorldX += plrxoff2[v13]; + plr[v3].WorldY += v15; + } + v16 = plr[v3].WorldX; + v17 = plr[v3].WorldY; + plr[v3].walkpath[0] = -1; + plr[v3].destAction = -1; + v14 = v2 == myplr; + plr[v3]._px = v16; + plr[v3]._py = v17; + if ( v14 ) + plr[v3]._plid = AddLight(v16, v17, plr[v3]._pLightRad); + else + plr[v3]._plid = -1; + plr[v3]._pvid = AddVision(plr[v3].WorldX, plr[v3].WorldY, plr[v3]._pLightRad, v2 == myplr); + } + v18 = plr[v3]._pClass; + if ( v18 ) + { + if ( v18 == 1 ) + { + plr[v3]._pAblSpells[0] = 0x8000000; + } + else + { + if ( v18 != 2 ) + goto LABEL_33; + plr[v3]._pAblSpells[0] = 0x4000000; + } + } + else + { + plr[v3]._pAblSpells[0] = 0x2000000; + } + plr[v3]._pAblSpells[1] = 0; +LABEL_33: + v19 = plr[v3]._pLevel; + plr[v3]._pInvincible = 0; + v14 = v2 == myplr; + plr[v3]._pNextExper = ExpLvlsTbl[v19]; + if ( v14 ) + { + deathdelay = 0; + *(_DWORD *)&deathflag = 0; + ScrollInfo._sxoff = 0; + ScrollInfo._syoff = 0; + ScrollInfo._sdir = 0; + } +} +// 44B83C: could not find valid save-restore pair for edi +// 52572C: using guessed type int leveldebug; +// 69B7C4: using guessed type int deathdelay; + +//----- (0044BB33) -------------------------------------------------------- +void __cdecl InitMultiView() +{ + int v0; // eax + + if ( (unsigned int)myplr >= 4 ) + TermMsg("InitPlayer: illegal player %d", myplr); + v0 = plr[myplr].WorldY; + ViewX = plr[myplr].WorldX; + ViewY = v0; +} + +//----- (0044BB6D) -------------------------------------------------------- +int __fastcall CheckLeighSolid(int x, int y) +{ + int v2; // esi + int v3; // esi + int v4; // edi + int v5; // ebx + char *v6; // eax + int result; // eax + int v8; // ebx + int v9; // edi + char *v10; // eax + int v11; // edi + int v12; // ebx + char *v13; // eax + int v14; // [esp+Ch] [ebp-Ch] + int v15; // [esp+10h] [ebp-8h] + int v16; // [esp+10h] [ebp-8h] + int v17; // [esp+10h] [ebp-8h] + signed int v18; // [esp+14h] [ebp-4h] + signed int v19; // [esp+14h] [ebp-4h] + signed int v20; // [esp+14h] [ebp-4h] + + v2 = x; + v14 = y; + if ( (unsigned int)x >= 4 ) + TermMsg("InitPlayer: illegal player %d", x); + v3 = v2; + v15 = 0; + v4 = plr[v3].WorldX - 1; + v5 = plr[v3].WorldY + 1; + v6 = (char *)dpiece_defs_map_1 + 32 * gendung_41927A(v4, v5); + v18 = 2; + do + v15 |= *(unsigned short *)&v6[2 * v18++]; + while ( v18 < 10 ); + result = 1; + if ( v15 | dArch[v4][v5] | (unsigned char)nSolidTable[dPiece[0][v5 + 112 * v4]] ) + plr[v3]._peflag = 1; + else + plr[v3]._peflag = 0; + if ( v14 == 1 && plr[v3]._peflag == 1 ) + { + v8 = plr[v3].WorldX; + v16 = 0; + v9 = plr[v3].WorldY + 2; + v10 = (char *)dpiece_defs_map_1 + 32 * gendung_41927A(plr[v3].WorldX, v9); + v19 = 2; + do + v16 |= *(unsigned short *)&v10[2 * v19++]; + while ( v19 < 10 ); + result = v16 | dArch[v8][v9]; + if ( !result ) + { + v17 = 0; + v11 = plr[v3].WorldX - 2; + v12 = plr[v3].WorldY + 1; + v13 = (char *)dpiece_defs_map_1 + 32 * gendung_41927A(v11, v12); + v20 = 2; + do + v17 |= *(unsigned short *)&v13[2 * v20++]; + while ( v20 < 10 ); + result = v17 | dArch[v11][v12]; + if ( result ) + plr[v3]._peflag = 2; + } + } + return result; +} + +//----- (0044BCC2) -------------------------------------------------------- +int __fastcall SolidLoc(int x, int y) +{ + int result; // eax + + if ( x < 0 || y < 0 || x >= 112 || y >= 112 ) + result = 0; + else + result = (unsigned char)nSolidTable[dPiece[0][y + 112 * x]]; + return result; +} + +//----- (0044BCEB) -------------------------------------------------------- +int __fastcall PlrDirOK(int pnum, int dir) +{ + int v2; // esi + int v3; // ebx + int v4; // eax + int v5; // esi + int v6; // edi + int v7; // ebp + int result; // eax + bool v9; // zf + int p; // [esp+10h] [ebp-4h] + + v2 = pnum; + v3 = dir; + p = pnum; + if ( (unsigned int)pnum >= 4 ) + TermMsg("PlrDirOK: illegal player %d", pnum); + v4 = v2; + v5 = plr[v2].WorldX + offset_x[v3]; + v6 = plr[v4].WorldY + offset_y[v3]; + if ( v5 < 0 ) + return 0; + v7 = 112 * v5 + v6; + if ( !dPiece[0][v7] || !PosOkPlayer(p, v5, v6) ) + return 0; + result = 1; + if ( v3 == 6 ) + { + if ( SolidLoc(v5, v6 + 1) ) + return 0; + v9 = (dFlags[0][v7 + 1] & 0x20) == 0; + } + else + { + if ( v3 != 2 ) + return result; + if ( SolidLoc(v5 + 1, v6) ) + return 0; + v9 = (dFlags[1][v7] & 0x20) == 0; + } + if ( v9 ) + return 1; + return 0; +} + +//----- (0044BD9A) -------------------------------------------------------- +void __fastcall PlrClrTrans(int x, int y) +{ + int v2; // esi + int v3; // ebx + int v4; // edx + int v5; // edi + char *v6; // ecx + int v7; // eax + int v8; // ebp + + v2 = y - 1; + v3 = y + 1; + if ( (unsigned char)(__OFSUB__(y - 1, y + 1) ^ 1) | (y - 1 == y + 1) ) + { + v4 = x - 1; + v5 = x + 1; + do + { + if ( v4 <= v5 ) + { + v6 = &dung_map[v4][v2]; + v7 = v5 - v4 + 1; + do + { + v8 = *v6; + v6 += 112; + TransList[v8] = 0; + --v7; + } + while ( v7 ); + } + ++v2; + } + while ( v2 <= v3 ); + } +} + +//----- (0044BDDD) -------------------------------------------------------- +void __fastcall PlrDoTrans(int x, int y) +{ + int v2; // edi + int v3; // ebx + int v4; // eax + _BYTE *v5; // ecx + _DWORD *v6; // esi + int v7; // eax + int v8; // [esp+8h] [ebp-4h] + + if ( leveltype == 1 || leveltype == 2 ) + { + v2 = y - 1; + if ( y - 1 <= y + 1 ) + { + v3 = x - 1; + v8 = x + 1; + do + { + if ( v3 <= v8 ) + { + v4 = v2 + 112 * v3; + v5 = (unsigned char *)dung_map + v4; + v6 = (_DWORD *)((char *)dPiece + 4 * v4); + v7 = v8 - v3 + 1; + do + { + if ( !nSolidTable[*v6] ) + { + if ( *v5 ) + TransList[(char)*v5] = 1; + } + v6 += 112; + v5 += 112; + --v7; + } + while ( v7 ); + } + ++v2; + } + while ( v2 <= y + 1 ); + } + } + else + { + TransList[1] = 1; + } +} +// 5BB1ED: using guessed type char leveltype; + +//----- (0044BE5E) -------------------------------------------------------- +void __fastcall SetPlayerOld(int pnum) +{ + int v1; // esi + int v2; // eax + + v1 = pnum; + if ( (unsigned int)pnum >= 4 ) + TermMsg("SetPlayerOld: illegal player %d", pnum); + v2 = v1; + plr[v2]._poldx = plr[v1].WorldX; + plr[v2]._poldy = plr[v1].WorldY; +} + +//----- (0044BE95) -------------------------------------------------------- +void __fastcall FixPlayerLocation(int pnum, int a2) +{ + int v2; // edi + int v3; // ebx + int v4; // esi + int v5; // ecx + int v6; // eax + bool v7; // zf + int v8; // eax + int v9; // eax + + v2 = pnum; + v3 = a2; + if ( (unsigned int)pnum >= 4 ) + TermMsg("FixPlayerLocation: illegal player %d", pnum); + v4 = v2; + v5 = plr[v2].WorldY; + v6 = plr[v2].WorldX; + plr[v4]._py = v5; + plr[v4]._ptargy = v5; + plr[v4]._px = v6; + plr[v4]._ptargx = v6; + plr[v4]._pxoff = 0; + plr[v4]._pyoff = 0; + CheckLeighSolid(v2, 0); + v7 = v2 == myplr; + plr[v4]._pdir = v3; + if ( v7 ) + { + v8 = plr[v4].WorldX; + ScrollInfo._sxoff = 0; + ViewX = v8; + v9 = plr[v4].WorldY; + ScrollInfo._syoff = 0; + ScrollInfo._sdir = 0; + ViewY = v9; + } +} + +//----- (0044BF2D) -------------------------------------------------------- +void __fastcall StartStand(int pnum, int dir) +{ + int v2; // ebx + int v3; // edi + int v4; // esi + int v5; // ST08_4 + + v2 = pnum; + v3 = dir; + if ( (unsigned int)pnum >= 4 ) + TermMsg("StartStand: illegal player %d", pnum); + v4 = v2; + if ( !plr[v2]._pInvincible || plr[v4]._pHitPoints || v2 != myplr ) + { + if ( !(plr[v4]._pGFXLoad & 1) ) + LoadPlrGFX(v2, 1); + v5 = plr[v4]._pNFNum; + NewPlrAnim(v2, plr[0]._peqN[v3 + 5430 * v2], plr[v4]._pNFrames, 3); + plr[v4]._pmode = PM_STAND; + FixPlayerLocation(v2, v3); + FixPlrWalkTags(v2); + dPlayer[plr[v4].WorldX][plr[v4].WorldY] = v2 + 1; + SetPlayerOld(v2); + } + else + { + SyncPlrKill(v2, -1); + } +} + +//----- (0044BFE8) -------------------------------------------------------- +void __fastcall StartWalkStand(int pnum) +{ + int v1; // edi + int v2; // esi + int v3; // eax + int v4; // eax + int v5; // eax + + v1 = pnum; + if ( (unsigned int)pnum >= 4 ) + TermMsg("StartWalkStand: illegal player %d", pnum); + v2 = v1; + v3 = plr[v1].WorldX; + plr[v2]._pmode = 0; + plr[v2]._px = v3; + plr[v2]._py = plr[v1].WorldY; + plr[v2]._pxoff = 0; + plr[v2]._pyoff = 0; + CheckLeighSolid(v1, 0); + if ( v1 == myplr ) + { + v4 = plr[v2].WorldX; + ScrollInfo._sxoff = 0; + ViewX = v4; + v5 = plr[v2].WorldY; + ScrollInfo._syoff = 0; + ScrollInfo._sdir = 0; + ViewY = v5; + } +} + +//----- (0044C070) -------------------------------------------------------- +void __fastcall PM_ChangeLightOff(int pnum) +{ + int v1; // esi + int v2; // esi + signed int v3; // ebx + int v4; // edi + int v5; // edx + LightListStruct *v6; // eax + int v7; // ecx + int v8; // edx + signed int v9; // edi + int v10; // ebx + int v11; // edx + int v12; // ecx + int v13; // ebp + int ly; // [esp+10h] [ebp-Ch] + int lx; // [esp+18h] [ebp-4h] + + v1 = pnum; + if ( (unsigned int)pnum >= 4 ) + TermMsg("PM_ChangeLightOff: illegal player %d", pnum); + v2 = v1; + v3 = -1; + v4 = plr[v2]._pxoff; + v5 = 2 * plr[v2]._pyoff; + v6 = &LightList[plr[v2]._plid]; + v7 = v4 + v5; + v8 = v5 - v4; + if ( v7 >= 0 ) + { + v9 = 1; + } + else + { + v9 = -1; + v7 = -v7; + } + if ( v8 >= 0 ) + v3 = 1; + else + v8 = -v8; + v10 = v3 * (v8 >> 3); + v11 = 8 * v6->_ly; + ly = v11 + v10; + lx = v9 * (v7 >> 3); + v12 = 8 * v6->_lx; + v13 = v11 + v6->_yoff; + if ( abs(lx - v6->_xoff) >= 3 || abs(ly - v13) >= 3 ) + ChangeLightOff(plr[v2]._plid, lx, v10); +} + +//----- (0044C13D) -------------------------------------------------------- +void __fastcall PM_ChangeOffset(int pnum) +{ + int v1; // esi + int v2; // eax + int v3; // edi + int v4; // ebx + int v5; // ecx + int *v6; // esi + int v7; // edi + int v8; // ebx + int v9; // edx + int v10; // edi + int v11; // edi + int v12; // edi + int v13; // ecx + int v14; // edx + int arglist; // [esp+8h] [ebp-8h] + int v16; // [esp+Ch] [ebp-4h] + + v1 = pnum; + arglist = pnum; + if ( (unsigned int)pnum >= 4 ) + TermMsg("PM_ChangeOffset: illegal player %d", pnum); + v2 = v1; + v3 = plr[v1]._pVar6; + v4 = plr[v1]._pxvel; + v5 = v3; + v6 = &plr[v1]._pVar7; + v7 = v4 + v3; + v8 = plr[v2]._pyvel; + v9 = *v6; + v16 = v7; + plr[v2]._pVar6 = v7; + v10 = *v6; + ++plr[v2]._pVar8; + v11 = v8 + v10; + *v6 = v11; + v12 = v11 >> 8; + plr[v2]._pxoff = v16 >> 8; + plr[v2]._pyoff = v12; + v13 = v5 >> 8; + v14 = v9 >> 8; + if ( arglist == myplr && ScrollInfo._sdir ) + { + ScrollInfo._sxoff += v13 - (v16 >> 8); + ScrollInfo._syoff += v14 - v12; + } + PM_ChangeLightOff(arglist); +} + +//----- (0044C1E2) -------------------------------------------------------- +void __fastcall StartWalk(int pnum, int xvel, int yvel, int xadd, int yadd, int EndDir, int sdir) +{ + int v7; // edi + int v8; // esi + int v9; // edi + int v10; // ebx + int v11; // ecx + bool v12; // zf + int v13; // ST08_4 + int v14; // eax + bool v15; // sf + unsigned char v16; // of + int v17; // eax + int v18; // [esp+Ch] [ebp-8h] + int arglist; // [esp+10h] [ebp-4h] + + v7 = pnum; + v18 = xvel; + arglist = pnum; + if ( (unsigned int)pnum >= 4 ) + TermMsg("StartWalk: illegal player %d", pnum); + v8 = v7; + if ( plr[v7]._pInvincible && !plr[v8]._pHitPoints && v7 == myplr ) + { + SyncPlrKill(v7, -1); + return; + } + SetPlayerOld(v7); + v9 = xadd + plr[v8].WorldX; + v10 = yadd + plr[v8].WorldY; + if ( PlrDirOK(arglist, EndDir) ) + { + v11 = arglist; + plr[v8]._px = v9; + v12 = arglist == myplr; + plr[v8]._py = v10; + if ( v12 ) + { + ScrollInfo._sdx = plr[v8].WorldX - ViewX; + ScrollInfo._sdy = plr[v8].WorldY - ViewY; + } + plr[v8]._pmode = PM_WALK; + dPlayer[v9][v10] = -1 - arglist; + plr[v8]._pxvel = v18; + v12 = (plr[v8]._pGFXLoad & 2) == 0; + plr[v8]._pyvel = yvel; + plr[v8]._pVar1 = xadd; + plr[v8]._pxoff = 0; + plr[v8]._pyoff = 0; + plr[v8]._pVar2 = yadd; + plr[v8]._pVar3 = EndDir; + if ( v12 ) + { + LoadPlrGFX(arglist, 2); + v11 = arglist; + } + v13 = plr[v8]._pWFNum; + NewPlrAnim(v11, plr[0]._peqW[EndDir + 5430 * v11], plr[v8]._pWFrames, 0); + plr[v8]._pdir = EndDir; + plr[v8]._pVar6 = 0; + plr[v8]._pVar7 = 0; + plr[v8]._pVar8 = 0; + CheckLeighSolid(arglist, 0); + if ( arglist == myplr ) + { + if ( zoomflag ) + { + if ( abs(ScrollInfo._sdx) < 3 ) + { + v14 = abs(ScrollInfo._sdy); + v16 = __OFSUB__(v14, 3); + v15 = v14 - 3 < 0; + goto LABEL_18; + } + } + else if ( abs(ScrollInfo._sdx) < 2 ) + { + v17 = abs(ScrollInfo._sdy); + v16 = __OFSUB__(v17, 2); + v15 = v17 - 2 < 0; +LABEL_18: + if ( v15 ^ v16 ) + { + ScrollInfo._sdir = sdir; + return; + } + goto LABEL_20; + } +LABEL_20: + ScrollInfo._sdir = 0; + return; + } + } +} +// 52569C: using guessed type int zoomflag; + +//----- (0044C3AC) -------------------------------------------------------- +void __fastcall StartWalk2(int pnum, int xvel, int yvel, int xoff, int yoff, int xadd, int yadd, int EndDir, int sdir) +{ + int v9; // edi + int v10; // esi + int v11; // ebx + int v12; // edi + bool v13; // zf + int v14; // eax + int v15; // ecx + int v16; // ecx + int v17; // ecx + int v18; // ST08_4 + int v19; // edx + int v20; // eax + bool v21; // sf + unsigned char v22; // of + int v23; // eax + int v24; // [esp+Ch] [ebp-8h] + int arglist; // [esp+10h] [ebp-4h] + int x; // [esp+28h] [ebp+14h] + + v9 = pnum; + v24 = xvel; + arglist = pnum; + if ( (unsigned int)pnum >= 4 ) + TermMsg("StartWalk2: illegal player %d", pnum); + v10 = v9; + if ( plr[v9]._pInvincible && !plr[v10]._pHitPoints && v9 == myplr ) + { + SyncPlrKill(v9, -1); + return; + } + SetPlayerOld(v9); + v11 = xadd + plr[v10].WorldX; + v12 = yadd + plr[v10].WorldY; + x = xadd + plr[v10].WorldX; + if ( PlrDirOK(arglist, EndDir) ) + { + plr[v10]._px = v11; + v13 = arglist == myplr; + plr[v10]._py = v12; + if ( v13 ) + { + ScrollInfo._sdx = plr[v10].WorldX - ViewX; + ScrollInfo._sdy = plr[v10].WorldY - ViewY; + } + v14 = plr[v10].WorldY; + v15 = plr[v10].WorldX; + plr[v10]._pVar2 = v14; + dPlayer[v15][v14] = -1 - arglist; + v16 = plr[v10].WorldX; + plr[v10].WorldX = v11; + dPlayer[v11][v12] = arglist + 1; + plr[v10]._pVar1 = v16; + v17 = plr[v10]._plid; + plr[v10].WorldY = v12; + plr[v10]._pxoff = xoff; + plr[v10]._pyoff = yoff; + ChangeLightXY(v17, x, v12); + PM_ChangeLightOff(arglist); + plr[v10]._pxvel = v24; + plr[v10]._pyvel = yvel; + plr[v10]._pVar6 = xoff << 8; + v13 = (plr[v10]._pGFXLoad & 2) == 0; + plr[v10]._pmode = PM_WALK2; + plr[v10]._pVar7 = yoff << 8; + plr[v10]._pVar3 = EndDir; + if ( v13 ) + LoadPlrGFX(arglist, PM_WALK2); + v18 = plr[v10]._pWFNum; + NewPlrAnim(arglist, plr[0]._peqW[EndDir + 5430 * arglist], plr[v10]._pWFrames, 0); + plr[v10]._pVar8 = 0; + v19 = 0; + plr[v10]._pdir = EndDir; + if ( EndDir == 7 ) + v19 = 1; + CheckLeighSolid(arglist, v19); + if ( arglist == myplr ) + { + if ( zoomflag ) + { + if ( abs(ScrollInfo._sdx) < 3 ) + { + v20 = abs(ScrollInfo._sdy); + v22 = __OFSUB__(v20, 3); + v21 = v20 - 3 < 0; + goto LABEL_20; + } + } + else if ( abs(ScrollInfo._sdx) < PM_WALK2 ) + { + v23 = abs(ScrollInfo._sdy); + v22 = __OFSUB__(v23, 2); + v21 = v23 - PM_WALK2 < 0; +LABEL_20: + if ( v21 ^ v22 ) + { + ScrollInfo._sdir = sdir; + return; + } + goto LABEL_22; + } +LABEL_22: + ScrollInfo._sdir = 0; + return; + } + } +} +// 52569C: using guessed type int zoomflag; + +//----- (0044C5CF) -------------------------------------------------------- +void __fastcall StartWalk3(int pnum, int xvel, int yvel, int xoff, int yoff, int xadd, int yadd, int mapx, int mapy, int EndDir, int sdir) +{ + int v11; // edi + int v12; // esi + int v13; // eax + int v14; // ecx + int v15; // ebx + int v16; // edi + bool v17; // zf + int v18; // edx + int v19; // ecx + int v20; // ST08_4 + int v21; // eax + bool v22; // sf + unsigned char v23; // of + int v24; // eax + int v25; // [esp+10h] [ebp-8h] + int arglist; // [esp+14h] [ebp-4h] + int a6; // [esp+2Ch] [ebp+14h] + int x; // [esp+30h] [ebp+18h] + int y; // [esp+34h] [ebp+1Ch] + + v11 = pnum; + v25 = xvel; + arglist = pnum; + if ( (unsigned int)pnum >= 4 ) + TermMsg("StartWalk3: illegal player %d", pnum); + v12 = v11; + if ( plr[v11]._pInvincible && !plr[v12]._pHitPoints && v11 == myplr ) + { + SyncPlrKill(v11, -1); + return; + } + SetPlayerOld(v11); + v13 = plr[v12].WorldX; + a6 = v13 + xadd; + v14 = plr[v12].WorldY; + v15 = v14 + yadd; + x = mapx + v13; + v16 = v14 + mapy; + y = v14 + mapy; + if ( PlrDirOK(arglist, EndDir) ) + { + v17 = arglist == myplr; + plr[v12]._px = a6; + plr[v12]._py = v15; + if ( v17 ) + { + ScrollInfo._sdx = plr[v12].WorldX - ViewX; + ScrollInfo._sdy = plr[v12].WorldY - ViewY; + } + v18 = plr[v12].WorldY; + v19 = plr[v12].WorldX; + plr[v12]._pVar5 = v16; + dPlayer[v19][v18] = -1 - arglist; + dPlayer[a6][v15] = -1 - arglist; + plr[v12]._pVar4 = x; + plr[v12]._pyoff = yoff; + dFlags[x][v16] |= 0x20u; + v17 = leveltype == 0; + plr[v12]._pxoff = xoff; + if ( !v17 ) + { + ChangeLightXY(plr[v12]._plid, x, y); + PM_ChangeLightOff(arglist); + } + plr[v12]._pmode = PM_WALK3; + plr[v12]._pxvel = v25; + plr[v12]._pyvel = yvel; + plr[v12]._pVar1 = a6; + plr[v12]._pVar6 = xoff << 8; + v17 = (plr[v12]._pGFXLoad & 2) == 0; + plr[v12]._pVar7 = yoff << 8; + plr[v12]._pVar2 = v15; + plr[v12]._pVar3 = EndDir; + if ( v17 ) + LoadPlrGFX(arglist, 2); + v20 = plr[v12]._pWFNum; + NewPlrAnim(arglist, plr[0]._peqW[EndDir + 5430 * arglist], plr[v12]._pWFrames, 0); + plr[v12]._pdir = EndDir; + plr[v12]._pVar8 = 0; + CheckLeighSolid(arglist, 0); + if ( arglist == myplr ) + { + if ( zoomflag ) + { + if ( abs(ScrollInfo._sdx) < 3 ) + { + v21 = abs(ScrollInfo._sdy); + v23 = __OFSUB__(v21, 3); + v22 = v21 - 3 < 0; + goto LABEL_20; + } + } + else if ( abs(ScrollInfo._sdx) < 2 ) + { + v24 = abs(ScrollInfo._sdy); + v23 = __OFSUB__(v24, 2); + v22 = v24 - 2 < 0; +LABEL_20: + if ( v22 ^ v23 ) + { + ScrollInfo._sdir = sdir; + return; + } + goto LABEL_22; + } +LABEL_22: + ScrollInfo._sdir = 0; + return; + } + } +} +// 52569C: using guessed type int zoomflag; +// 5BB1ED: using guessed type char leveltype; + +//----- (0044C81E) -------------------------------------------------------- +void __fastcall StartAttack(int pnum, int d) +{ + int v2; // edi + int v3; // ebp + int v4; // esi + int v5; // ST08_4 + + v2 = pnum; + v3 = d; + if ( (unsigned int)pnum >= 4 ) + TermMsg("StartAttack: illegal player %d", pnum); + v4 = v2; + if ( !plr[v2]._pInvincible || plr[v4]._pHitPoints || v2 != myplr ) + { + if ( !(plr[v4]._pGFXLoad & 4) ) + LoadPlrGFX(v2, 4); + v5 = plr[v4].frame_9_unk; + NewPlrAnim(v2, plr[0]._peqA[v3 + 5430 * v2], plr[v4]._pAFrames, 0); + plr[v4]._pmode = 4; + FixPlayerLocation(v2, v3); + SetPlayerOld(v2); + } + else + { + SyncPlrKill(v2, -1); + } +} + +//----- (0044C8BB) -------------------------------------------------------- +void __fastcall StartRangeAttack(int pnum, int a2, int a3, int a4) +{ + int v4; // edi + int v5; // esi + int v6; // ST08_4 + int a2a; // [esp+8h] [ebp-4h] + + v4 = pnum; + a2a = a2; + if ( (unsigned int)pnum >= 4 ) + TermMsg("StartRangeAttack: illegal player %d", pnum); + v5 = v4; + if ( !plr[v4]._pInvincible || plr[v5]._pHitPoints || v4 != myplr ) + { + if ( !(plr[v5]._pGFXLoad & 4) ) + LoadPlrGFX(v4, 4); + v6 = plr[v5].frame_9_unk; + NewPlrAnim(v4, plr[0]._peqA[a2a + 5430 * v4], plr[v5]._pAFrames, 0); + plr[v5]._pmode = PM_RATTACK; + FixPlayerLocation(v4, a2a); + SetPlayerOld(v4); + plr[v5]._pVar1 = a3; + plr[v5]._pVar2 = a4; + } + else + { + SyncPlrKill(v4, -1); + } +} + +//----- (0044C973) -------------------------------------------------------- +void __fastcall StartPlrBlock(int pnum, int dir) +{ + int v2; // edi + int v3; // ebx + int v4; // esi + int v5; // ST08_4 + + v2 = pnum; + v3 = dir; + if ( (unsigned int)pnum >= 4 ) + TermMsg("StartPlrBlock: illegal player %d", pnum); + v4 = v2; + if ( !plr[v2]._pInvincible || plr[v4]._pHitPoints || v2 != myplr ) + { + PlaySfxLoc(IS_ISWORD, plr[v4].WorldX, plr[v4].WorldY); + if ( !(plr[v4]._pGFXLoad & 0x100) ) + LoadPlrGFX(v2, 256); + v5 = plr[v4]._pBFNum; + NewPlrAnim(v2, plr[0]._peqB[v3 + 5430 * v2], plr[v4]._pBFrames, 2); + plr[v4]._pmode = PM_BLOCK; + FixPlayerLocation(v2, v3); + SetPlayerOld(v2); + } + else + { + SyncPlrKill(v2, -1); + } +} + +//----- (0044CA26) -------------------------------------------------------- +void __fastcall StartSpell(int pnum, int d, int cx, int cy) +{ + int v4; // edi + int v5; // esi + int v6; // edx + int v7; // ST08_4 + int v8; // edx + int a2; // [esp+Ch] [ebp-4h] + + v4 = pnum; + a2 = d; + if ( (unsigned int)pnum >= 4 ) + TermMsg("StartSpell: illegal player %d", pnum); + v5 = v4; + if ( plr[v4]._pInvincible && !plr[v5]._pHitPoints && v4 == myplr ) + { + SyncPlrKill(v4, -1); + return; + } + if ( leveltype ) + { + switch ( spelldata[plr[v5]._pSpell].sType ) + { + case STYPE_FIRE: + if ( !(plr[v5]._pGFXLoad & 0x20) ) + LoadPlrGFX(v4, 32); + v6 = plr[0]._peqS1_FM[a2 + 5430 * v4]; + goto LABEL_20; + case STYPE_LIGHTNING: + if ( !(plr[v5]._pGFXLoad & 0x10) ) + LoadPlrGFX(v4, 16); + v6 = plr[0]._peqS2_LM[a2 + 5430 * v4]; + goto LABEL_20; + case STYPE_MAGIC: + if ( !(plr[v5]._pGFXLoad & 0x40) ) + LoadPlrGFX(v4, 64); + v6 = plr[0]._peqS3_QM[a2 + 5430 * v4]; +LABEL_20: + v7 = plr[v5].frame_A_unk; + NewPlrAnim(v4, v6, plr[v5]._pSFrames, 0); + break; + } + } + PlaySfxLoc((unsigned char)spelldata[plr[v5]._pSpell].sSFX, plr[v5].WorldX, plr[v5].WorldY); + plr[v5]._pmode = PM_SPELL; + FixPlayerLocation(v4, a2); + SetPlayerOld(v4); + v8 = plr[v5]._pSpell; + plr[v5]._pVar1 = cx; + plr[v5]._pVar2 = cy; + plr[v5]._pVar4 = GetSpellLevel(v4, v8); + plr[v5]._pVar8 = 1; +} +// 5BB1ED: using guessed type char leveltype; + +//----- (0044CB95) -------------------------------------------------------- +void __fastcall FixPlrWalkTags(int pnum) +{ + int v1; // esi + int v2; // edx + int v3; // ecx + int v4; // eax + int v5; // esi + int v6; // edi + int v7; // ebx + int v8; // edi + bool v9; // zf + bool v10; // sf + unsigned char v11; // of + int v12; // eax + int v13; // [esp+8h] [ebp-Ch] + int v14; // [esp+Ch] [ebp-8h] + char *v15; // [esp+10h] [ebp-4h] + + v1 = pnum; + if ( (unsigned int)pnum >= 4 ) + TermMsg("FixPlrWalkTags: illegal player %d", pnum); + v13 = v1 + 1; + v2 = -1 - v1; + v3 = plr[v1]._poldx; + v4 = plr[v1]._poldy; + v5 = v4 - 1; + if ( (unsigned char)(__OFSUB__(v4 - 1, v4 + 1) ^ 1) | (v4 - 1 == v4 + 1) ) + { + v6 = v3 + 1; + do + { + v7 = v3 - 1; + v14 = v3 - 1; + if ( v3 - 1 <= v6 ) + { + v15 = &dPlayer[v7][v5]; + do + { + if ( v7 >= 0 && v7 < 112 && v5 >= 0 && v5 < 112 ) + { + v8 = *v15; + if ( v8 == v13 || v8 == v2 ) + *v15 = 0; + } + v15 += 112; + v7 = v14 + 1; + v6 = v3 + 1; + v11 = __OFSUB__(v14 + 1, v3 + 1); + v9 = v14 + 1 == v3 + 1; + v10 = v14++ - v3 < 0; + } + while ( (unsigned char)(v10 ^ v11) | v9 ); + } + ++v5; + } + while ( v5 <= v4 + 1 ); + } + if ( v3 >= 0 && v3 < 111 && v4 >= 0 && v4 < 111 ) + { + v12 = 112 * v3 + v4; + dFlags[1][v12] &= 0xDFu; + dFlags[0][v12 + 1] &= 0xDFu; + } +} + +//----- (0044CC62) -------------------------------------------------------- +void __fastcall RemovePlrFromMap(int pnum) +{ + int v1; // esi + signed int v2; // edi + signed int v3; // edx + signed int v4; // ebx + char v5; // al + signed int v6; // edx + _BYTE *v7; // eax + signed int v8; // edi + int v9; // ecx + int v10; // [esp+Ch] [ebp-4h] + + v1 = -1 - pnum; + v10 = pnum + 1; + v2 = 1; + do + { + v3 = v2; + v4 = 111; + do + { + if ( dPlayer[0][v3 + 111] == v1 || dPlayer[0][v3] == v1 ) + { + v5 = dFlags[1][v3]; + if ( v5 & 0x20 ) + dFlags[1][v3] = v5 & 0xDF; + } + v3 += 112; + --v4; + } + while ( v4 ); + ++v2; + } + while ( v2 < 112 ); + v6 = 0; + do + { + v7 = (unsigned char *)dPlayer + v6; + v8 = 112; + do + { + v9 = (char)*v7; + if ( v9 == v10 || v9 == v1 ) + *v7 = 0; + v7 += 112; + --v8; + } + while ( v8 ); + ++v6; + } + while ( v6 < 112 ); +} + +//----- (0044CCD8) -------------------------------------------------------- +void __fastcall StartPlrHit(int pnum, int dam, unsigned char forcehit) +{ + int v3; // ebx + int v4; // edi + int v5; // esi + char v6; // al + int v7; // ecx + int v8; // eax + int v9; // edi + int v10; // ST08_4 + + v3 = pnum; + v4 = dam; + if ( (unsigned int)pnum >= 4 ) + TermMsg("StartPlrHit: illegal player %d", pnum); + v5 = v3; + if ( plr[v3]._pInvincible && !plr[v5]._pHitPoints && v3 == myplr ) + { + SyncPlrKill(v3, -1); + return; + } + v6 = plr[v5]._pClass; + switch ( v6 ) + { + case UI_WARRIOR: + v7 = PS_WARR69; +LABEL_13: + PlaySfxLoc(v7, plr[v5].WorldX, plr[v5].WorldY); + break; + case UI_ROGUE: + v7 = PS_ROGUE69; + goto LABEL_13; + case UI_SORCERER: + v7 = PS_MAGE69; + goto LABEL_13; + } + v8 = plr[v5]._pLevel; + drawhpflag = 1; + if ( v4 >> 6 >= v8 || forcehit ) + { + v9 = plr[v5]._pdir; + if ( !(plr[v5]._pGFXLoad & 8) ) + LoadPlrGFX(v3, 8); + v10 = plr[v5]._pHFNum; + NewPlrAnim(v3, plr[0]._peqH[v9 + 5430 * v3], plr[v5]._pHFrames, 0); + plr[v5]._pmode = PM_GOTHIT; + FixPlayerLocation(v3, v9); + plr[v5]._pVar8 = 1; + FixPlrWalkTags(v3); + dPlayer[plr[v5].WorldX][plr[v5].WorldY] = v3 + 1; + SetPlayerOld(v3); + } +} + +//----- (0044CDFD) -------------------------------------------------------- +void __fastcall DestroyDupeItem(ItemStruct *pItem, int ci, int a3) +{ + ItemStruct *v3; // ebx + int v4; // eax + int v5; // eax + int i; // ST10_4 + unsigned int v7; // ecx + int x; // [esp+8h] [ebp-4h] + + x = ci; + v3 = pItem; + if ( numitems < 127 ) + { + _LOWORD(ci) = pItem->_iCreateInfo; + FindGetItem(pItem->IDidx, ci, pItem->_iSeed); + if ( v4 >= 0 ) + { + DupeInvMsg("A duplicate item has been detected. Destroying duplicate..."); + SyncGetItem(x, a3, v3->IDidx, v3->_iCreateInfo, v3->_iSeed); + } + v5 = itemavail[0]; + i = itemavail[0]; + dItem[x][a3] = _LOBYTE(itemavail[0]) + 1; + v7 = 4 * numitems; + itemactive[v7 / 4] = v5; + v5 *= 368; + itemavail[0] = itemavail[v7 / 0xFFFFFFFC + 126]; + qmemcpy((char *)items + v5, v3, sizeof(ItemStruct)); + *(int *)((char *)&items[0]._ix + v5) = x; + *(int *)((char *)&items[0]._iy + v5) = a3; + RespawnItem(i, 1u); + ++numitems; + v3->_itype = -1; + } +} + +//----- (0044CEC9) -------------------------------------------------------- +void __fastcall StartPlayerKill(int pnum, int earflag) +{ + unsigned int v2; // edi + unsigned int v3; // esi + char v4; // al + int v5; // ecx + int v6; // ST0C_4 + bool v7; // zf + int *v8; // eax + signed int v9; // ecx + char *v10; // eax + char v11; // al + short v12; // cx + short v13; // ax + int v14; // ecx + int v15; // eax + int v16; // eax + signed int v17; // ebx + int v18; // eax + ItemStruct item; // [esp+Ch] [ebp-178h] + BOOL v20; // [esp+17Ch] [ebp-8h] + struct ItemStruct *itm; // [esp+180h] [ebp-4h] + + v2 = pnum; + v3 = 21720 * pnum; + itm = (struct ItemStruct *)earflag; + if ( plr[pnum]._pHitPoints <= 0 && plr[v3 / 0x54D8]._pmode == PM_DEATH ) + return; + if ( myplr == pnum ) + NetSendCmdParam1(1u, CMD_PLRDEAD, earflag); + v20 = (unsigned char)gbMaxPlayers > 1u && plr[v3 / 0x54D8].plrlevel == 16; + if ( v2 >= 4 ) + TermMsg("StartPlayerKill: illegal player %d", v2); + v4 = plr[v3 / 0x54D8]._pClass; + if ( v4 ) + { + if ( v4 == 1 ) + { + v5 = PS_ROGUE71; + } + else + { + if ( v4 != 2 ) + goto LABEL_18; + v5 = PS_MAGE71; + } + PlaySfxLoc(v5, plr[v3 / 0x54D8].WorldX, plr[v3 / 0x54D8].WorldY); + goto LABEL_18; + } + PlaySfxLoc(PS_DEAD, plr[v3 / 0x54D8].WorldX, plr[v3 / 0x54D8].WorldY); +LABEL_18: + if ( plr[v3 / 0x54D8]._pgfxnum ) + { + plr[v3 / 0x54D8]._pgfxnum = 0; + plr[v3 / 0x54D8]._pGFXLoad = 0; + SetPlrAnims(v2); + } + if ( SLOBYTE(plr[v3 / 0x54D8]._pGFXLoad) >= 0 ) + LoadPlrGFX(v2, 128); + v6 = plr[v3 / 0x54D8]._pDFNum; + NewPlrAnim(v2, plr[0]._peqD[plr[v3 / 0x54D8]._pdir + v3 / 4], plr[v3 / 0x54D8]._pDFrames, 1); + plr[v3 / 0x54D8]._pBlockFlag = 0; + plr[v3 / 0x54D8]._pmode = PM_DEATH; + plr[v3 / 0x54D8]._pInvincible = 1; + SetPlayerHitPoints(v2, 0); + v7 = v2 == myplr; + plr[v3 / 0x54D8]._pVar8 = 1; + if ( !v7 && !itm && !v20 ) + { + v8 = &plr[v3 / 0x54D8].InvBody[0]._itype; + v9 = 7; + do + { + *v8 = -1; + v8 += 92; + --v9; + } + while ( v9 ); + CalcPlrInv(v2, 0); + } + if ( plr[v3 / 0x54D8].plrlevel == currlevel ) + { + FixPlayerLocation(v2, plr[v3 / 0x54D8]._pdir); + RemovePlrFromMap(v2); + v10 = &dFlags[plr[v3 / 0x54D8].WorldX][plr[v3 / 0x54D8].WorldY]; + *v10 |= 4u; + SetPlayerOld(v2); + if ( v2 == myplr ) + { + drawhpflag = 1; + deathdelay = 30; + if ( pcurs >= CURSOR_FIRSTITEM ) + { + PlrDeadItem(v2, &plr[v3 / 0x54D8].HoldItem, 0, 0); + SetCursor(1); + } + if ( !v20 ) + { + DropHalfPlayersGold(v2); + if ( itm != (struct ItemStruct *)-1 ) + { + if ( itm ) + { + SetPlrHandItem(&item, 23); + sprintf(item._iName, "Ear of %s", plr[v3 / 0x54D8]._pName); + v11 = plr[v3 / 0x54D8]._pClass; + if ( v11 == 2 ) + { + item._iCurs = 19; + } + else if ( v11 ) + { + if ( v11 == 1 ) + item._iCurs = 21; + } + else + { + item._iCurs = 20; + } + _LOBYTE(v12) = 0; + _HIBYTE(v12) = plr[v3 / 0x54D8]._pName[0]; + v13 = v12 | plr[v3 / 0x54D8]._pName[1]; + v14 = plr[v3 / 0x54D8]._pName[3]; + item._iCreateInfo = v13; + v15 = plr[v3 / 0x54D8]._pName[5] | ((plr[v3 / 0x54D8]._pName[4] | ((v14 | (plr[v3 / 0x54D8]._pName[2] << 8)) << 8)) << 8); + item._ivalue = plr[v3 / 0x54D8]._pLevel; + item._iSeed = v15; + FindGetItem(23, *(int *)&item._iCreateInfo, v15); + if ( v16 == -1 ) + PlrDeadItem(v2, &item, 0, 0); + } + else + { + itm = plr[v3 / 0x54D8].InvBody; + v17 = 7; + do + { + v18 = ((_BYTE)--v17 + (unsigned char)plr[v3 / 0x54D8]._pdir) & 7; + PlrDeadItem(v2, itm, offset_x[v18], offset_y[v18]); + ++itm; + } + while ( v17 ); + CalcPlrInv(v2, 0); + } + } + } + } + } + SetPlayerHitPoints(v2, 0); +} +// 679660: using guessed type char gbMaxPlayers; +// 69B7C4: using guessed type int deathdelay; + +//----- (0044D1F4) -------------------------------------------------------- +void __fastcall PlrDeadItem(int pnum, struct ItemStruct *itm, int xx, int yy) +{ + int v4; // edi + int v5; // edi + int v6; // esi + int v7; // ebx + int v8; // eax + int v9; // ST04_4 + ItemStruct *v10; // esi + int v11; // eax + int v12; // ebx + int v13; // esi + int v14; // eax + int v15; // edx + unsigned char v16; // [esp-8h] [ebp-24h] + unsigned char v17; // [esp-4h] [ebp-20h] + int x; // [esp+Ch] [ebp-10h] + ItemStruct *pItem; // [esp+10h] [ebp-Ch] + int v20; // [esp+14h] [ebp-8h] + int v21; // [esp+14h] [ebp-8h] + int v22; // [esp+18h] [ebp-4h] + int xxa; // [esp+24h] [ebp+8h] + int yya; // [esp+28h] [ebp+Ch] + + pItem = itm; + v4 = pnum; + if ( itm->_itype != -1 ) + { + if ( (unsigned int)pnum >= 4 ) + TermMsg("PlrDeadItem: illegal player %d", pnum); + v5 = v4; + v6 = yy + plr[v5].WorldY; + v7 = xx + plr[v5].WorldX; + v20 = yy + plr[v5].WorldY; + if ( (xx || yy) && (_LOBYTE(v8) = ItemSpaceOk(v7, v6), v8) ) + { + v9 = v6; + v10 = pItem; + DestroyDupeItem(pItem, v7, v9); + v17 = v20; + v16 = v7; + } + else + { + yya = -1; + xxa = 1; + while ( 1 ) + { + v11 = yya; + v21 = yya; +LABEL_14: + if ( v11 <= xxa ) + break; + ++xxa; + if ( --yya <= -50 ) + return; + } + v12 = v21 + plr[v5].WorldY; + v22 = yya; + while ( 1 ) + { + v13 = v22 + plr[v5].WorldX; + x = v22 + plr[v5].WorldX; + _LOBYTE(v14) = ItemSpaceOk(v13, v12); + if ( v14 ) + break; + if ( ++v22 > xxa ) + { + v11 = ++v21; + goto LABEL_14; + } + } + v15 = v13; + v10 = pItem; + DestroyDupeItem(pItem, v15, v12); + v17 = v12; + v16 = x; + } + qmemcpy(&plr[v5].HoldItem, v10, sizeof(plr[v5].HoldItem)); + NetSendCmdPItem(0, CMD_RESPAWNITEM, v16, v17); + } +} + +//----- (0044D2F3) -------------------------------------------------------- +void __fastcall DropHalfPlayersGold(int pnum) +{ + int v1; // ebx + int v2; // esi + int v3; // edi + int v4; // ecx + int v5; // eax + int v6; // ecx + int v7; // eax + int v8; // edx + int v9; // ecx + int v10; // eax + int v11; // edx + int v12; // ecx + int v13; // eax + int v14; // [esp+Ch] [ebp-8h] + int v15; // [esp+Ch] [ebp-8h] + int v16; // [esp+Ch] [ebp-8h] + int v17; // [esp+Ch] [ebp-8h] + signed int i; // [esp+10h] [ebp-4h] + signed int ia; // [esp+10h] [ebp-4h] + signed int ib; // [esp+10h] [ebp-4h] + signed int ic; // [esp+10h] [ebp-4h] + + v1 = pnum; + if ( (unsigned int)pnum >= 4 ) + TermMsg("DropHalfPlayersGold: illegal player %d", pnum); + v2 = v1; + v3 = plr[v1]._pGold >> 1; + i = 0; + while ( v3 > 0 ) + { + v4 = 368 * i + v2 * 21720; + v14 = v4; + if ( *(int *)((char *)&plr[0].SpdList[0]._itype + v4) == ITYPE_GOLD ) + { + v5 = *(int *)((char *)&plr[0].SpdList[0]._ivalue + v4); + if ( v5 != 5000 ) + { + if ( v3 >= v5 ) + { + v3 -= v5; + RemoveSpdBarItem(v1, i); + SetPlrHandItem(&plr[v2].HoldItem, 0); + GetGoldSeed(v1, &plr[v2].HoldItem._iSeed); + SetPlrHandGoldCurs(&plr[v2].HoldItem); + plr[v2].HoldItem._ivalue = *(int *)((char *)&plr[0].SpdList[0]._ivalue + v14); + PlrDeadItem(v1, &plr[v2].HoldItem, 0, 0); + i = -1; + } + else + { + *(int *)((char *)&plr[0].SpdList[0]._ivalue + v4) = v5 - v3; + SetSpdbarGoldCurs(v1, i); + SetPlrHandItem(&plr[v2].HoldItem, 0); + GetGoldSeed(v1, &plr[v2].HoldItem._iSeed); + SetPlrHandGoldCurs(&plr[v2].HoldItem); + plr[v2].HoldItem._ivalue = v3; + v3 = 0; + PlrDeadItem(v1, &plr[v2].HoldItem, 0, 0); + } + } + } + if ( ++i >= 8 ) + { + if ( v3 > 0 ) + { + ia = 0; + do + { + if ( v3 <= 0 ) + break; + v6 = 368 * ia + v2 * 21720; + v15 = v6; + if ( *(int *)((char *)&plr[0].SpdList[0]._itype + v6) == ITYPE_GOLD ) + { + v7 = *(int *)((char *)&plr[0].SpdList[0]._ivalue + v6); + if ( v3 >= v7 ) + { + v3 -= v7; + RemoveSpdBarItem(v1, ia); + SetPlrHandItem(&plr[v2].HoldItem, 0); + GetGoldSeed(v1, &plr[v2].HoldItem._iSeed); + SetPlrHandGoldCurs(&plr[v2].HoldItem); + plr[v2].HoldItem._ivalue = *(int *)((char *)&plr[0].SpdList[0]._ivalue + v15); + PlrDeadItem(v1, &plr[v2].HoldItem, 0, 0); + ia = -1; + } + else + { + *(int *)((char *)&plr[0].SpdList[0]._ivalue + v6) = v7 - v3; + SetSpdbarGoldCurs(v1, ia); + SetPlrHandItem(&plr[v2].HoldItem, 0); + GetGoldSeed(v1, &plr[v2].HoldItem._iSeed); + SetPlrHandGoldCurs(&plr[v2].HoldItem); + plr[v2].HoldItem._ivalue = v3; + v3 = 0; + PlrDeadItem(v1, &plr[v2].HoldItem, 0, 0); + } + } + ++ia; + } + while ( ia < 8 ); + } + break; + } + } + v8 = 0; + force_redraw = 255; + if ( v3 > 0 ) + { + ib = 0; + if ( plr[v2]._pNumInv <= 0 ) + { +LABEL_28: + if ( v3 > 0 ) + { + v11 = 0; + for ( ic = 0; ic < plr[v2]._pNumInv; v11 = ic++ + 1 ) + { + if ( v3 <= 0 ) + break; + v12 = 368 * v11 + v2 * 21720; + v17 = v12; + if ( *(int *)((char *)&plr[0].InvList[0]._itype + v12) == ITYPE_GOLD ) + { + v13 = *(int *)((char *)&plr[0].InvList[0]._ivalue + v12); + if ( v3 >= v13 ) + { + v3 -= v13; + RemoveInvItem(v1, v11); + SetPlrHandItem(&plr[v2].HoldItem, 0); + GetGoldSeed(v1, &plr[v2].HoldItem._iSeed); + SetPlrHandGoldCurs(&plr[v2].HoldItem); + plr[v2].HoldItem._ivalue = *(int *)((char *)&plr[0].InvList[0]._ivalue + v17); + PlrDeadItem(v1, &plr[v2].HoldItem, 0, 0); + ic = -1; + } + else + { + *(int *)((char *)&plr[0].InvList[0]._ivalue + v12) = v13 - v3; + SetGoldCurs(v1, v11); + SetPlrHandItem(&plr[v2].HoldItem, 0); + GetGoldSeed(v1, &plr[v2].HoldItem._iSeed); + SetPlrHandGoldCurs(&plr[v2].HoldItem); + plr[v2].HoldItem._ivalue = v3; + v3 = 0; + PlrDeadItem(v1, &plr[v2].HoldItem, 0, 0); + } + } + } + } + } + else + { + while ( v3 > 0 ) + { + v9 = 368 * v8 + v2 * 21720; + v16 = v9; + if ( *(int *)((char *)&plr[0].InvList[0]._itype + v9) == ITYPE_GOLD ) + { + v10 = *(int *)((char *)&plr[0].InvList[0]._ivalue + v9); + if ( v10 != 5000 ) + { + if ( v3 >= v10 ) + { + v3 -= v10; + RemoveInvItem(v1, v8); + SetPlrHandItem(&plr[v2].HoldItem, 0); + GetGoldSeed(v1, &plr[v2].HoldItem._iSeed); + SetPlrHandGoldCurs(&plr[v2].HoldItem); + plr[v2].HoldItem._ivalue = *(int *)((char *)&plr[0].InvList[0]._ivalue + v16); + PlrDeadItem(v1, &plr[v2].HoldItem, 0, 0); + ib = -1; + } + else + { + *(int *)((char *)&plr[0].InvList[0]._ivalue + v9) = v10 - v3; + SetGoldCurs(v1, v8); + SetPlrHandItem(&plr[v2].HoldItem, 0); + GetGoldSeed(v1, &plr[v2].HoldItem._iSeed); + SetPlrHandGoldCurs(&plr[v2].HoldItem); + plr[v2].HoldItem._ivalue = v3; + v3 = 0; + PlrDeadItem(v1, &plr[v2].HoldItem, 0, 0); + } + } + } + v8 = ib++ + 1; + if ( ib >= plr[v2]._pNumInv ) + goto LABEL_28; + } + } + } + plr[v2]._pGold = CalculateGold(v1); +} +// 52571C: using guessed type int force_redraw; + +//----- (0044D70B) -------------------------------------------------------- +void __fastcall SyncPlrKill(int pnum, int earflag) +{ + int v2; // esi + int v3; // ebx + int v4; // edx + int v5; // eax + + v2 = pnum; + v3 = earflag; + if ( plr[pnum]._pHitPoints || currlevel ) + { + v4 = 0; + if ( nummissiles <= 0 ) + { +LABEL_9: + SetPlayerHitPoints(pnum, 0); + StartPlayerKill(v2, v3); + } + else + { + while ( 1 ) + { + v5 = missileactive[v4]; + if ( missile[v5]._mitype == 13 && missile[v5]._misource == pnum && !missile[v5]._miDelFlag ) + break; + if ( ++v4 >= nummissiles ) + goto LABEL_9; + } + if ( v3 != -1 ) + missile[missileactive[v4]]._miVar8 = v3; + } + } + else + { + SetPlayerHitPoints(pnum, 64); + } +} + +//----- (0044D7A0) -------------------------------------------------------- +void __fastcall RemovePlrMissiles(int pnum) +{ + int v1; // ebx + int v2; // ebp + int v3; // ecx + int v4; // edi + int v5; // esi + int v6; // eax + + v1 = 0; + v2 = pnum; + if ( currlevel && pnum == myplr && (monster[myplr]._mx != 1 || monster[myplr]._my) ) + { + M_StartKill(myplr, myplr); + AddDead(monster[myplr]._mx, monster[myplr]._my, monster[myplr].MType->mdeadval, (direction)monster[myplr]._mdir); + v3 = monster[myplr]._my + 112 * monster[myplr]._mx; + monster[myplr]._mDelFlag = 1; + dMonster[0][v3] = 0; + DeleteMonsterList(); + } + if ( nummissiles > 0 ) + { + do + { + v4 = missileactive[v1]; + v5 = missileactive[v1]; + v6 = missile[v5]._mitype; + if ( v6 == 30 && missile[v5]._misource == v2 ) + monster[missile[v5]._miVar2]._mmode = missile[v5]._miVar1; + if ( v6 == 13 && missile[v5]._misource == v2 ) + { + ClearMissileSpot(v4); + DeleteMissile(v4, v1); + } + if ( missile[v5]._mitype == 34 && missile[v5]._misource == v2 ) + { + ClearMissileSpot(v4); + DeleteMissile(v4, v1); + } + ++v1; + } + while ( v1 < nummissiles ); + } +} + +//----- (0044D8D1) -------------------------------------------------------- +int __fastcall InitLevelChange(int pnum) +{ + int v1; // esi + int result; // eax + bool v3; // zf + + v1 = pnum; + RemovePlrMissiles(pnum); + if ( v1 == myplr && qtextflag ) + { + qtextflag = 0; + sfx_stop(); + } + RemovePlrFromMap(v1); + SetPlayerOld(v1); + if ( v1 == myplr ) + dPlayer[plr[myplr].WorldX][plr[myplr].WorldY] = myplr + 1; + else + plr[v1]._pLvlVisited[plr[v1].plrlevel] = 1; + ClrPlrPath(v1); + result = v1; + plr[result].destAction = -1; + v3 = v1 == myplr; + plr[result]._pLvlChanging = 1; + if ( v3 ) + plr[result].pLvlLoad = 10; + return result * 21720; +} +// 646D00: using guessed type char qtextflag; + +//----- (0044D973) -------------------------------------------------------- +void __fastcall StartNewLvl(int pnum, int fom, int lvl) +{ + int v3; // edi + unsigned int v4; // esi + unsigned int v5; // eax + HWND v6; // ST00_4 + + v3 = fom; + v4 = pnum; + InitLevelChange(pnum); + if ( v4 >= 4 ) + TermMsg("StartNewLvl: illegal player %d", v4); + if ( v3 < WM_DIABNEXTLVL ) + { +LABEL_10: + TermMsg("StartNewLvl"); + goto LABEL_11; + } + if ( v3 <= WM_DIABPREVLVL || v3 == WM_DIABRTNLVL ) + goto LABEL_16; + if ( v3 != WM_DIABSETLVL ) + { + if ( v3 != WM_DIABTOWNWARP ) + { + if ( v3 != WM_DIABTWARPUP ) + { + if ( v3 == WM_DIABRETOWN ) + goto LABEL_11; + goto LABEL_10; + } + plr[myplr].pTownWarps |= 1 << (leveltype - 2); + } +LABEL_16: + plr[v4].plrlevel = lvl; + goto LABEL_11; + } + setlvlnum = lvl; +LABEL_11: + if ( v4 == myplr ) + { + v5 = v4; + v6 = ghMainWnd; + plr[v5]._pmode = PM_NEWLVL; + plr[v5]._pInvincible = 1; + PostMessageA(v6, v3, 0, 0); + if ( (unsigned char)gbMaxPlayers > 1u ) + NetSendCmdParam2(1u, CMD_NEWLVL, v3, lvl); + } +} +// 5BB1ED: using guessed type char leveltype; +// 5CCB10: using guessed type char setlvlnum; +// 679660: using guessed type char gbMaxPlayers; + +//----- (0044DA6F) -------------------------------------------------------- +void __fastcall RestartTownLvl(int pnum) +{ + unsigned int v1; // edi + unsigned int v2; // esi + int v3; // eax + HWND v4; // ST00_4 + + v1 = pnum; + InitLevelChange(pnum); + if ( v1 >= 4 ) + TermMsg("RestartTownLvl: illegal player %d", v1); + v2 = v1; + plr[v2].plrlevel = 0; + plr[v2]._pInvincible = 0; + SetPlayerHitPoints(v1, 64); + v3 = plr[v2]._pMaxManaBase - plr[v2]._pMaxMana; + plr[v2]._pMana = 0; + plr[v2]._pManaBase = v3; + CalcPlrInv(v1, 0); + if ( v1 == myplr ) + { + plr[v2]._pmode = PM_NEWLVL; + v4 = ghMainWnd; + plr[v2]._pInvincible = 1; + PostMessageA(v4, WM_DIABRETOWN, 0, 0); + } +} + +//----- (0044DAFC) -------------------------------------------------------- +void __fastcall StartWarpLvl(int pnum, int pidx) +{ + int v2; // edi + int v3; // esi + int *v4; // eax + int v5; // eax + HWND v6; // ST00_4 + + v2 = pidx; + v3 = pnum; + InitLevelChange(pnum); + if ( gbMaxPlayers != 1 ) + { + v4 = &plr[v3].plrlevel; + if ( *v4 ) + *v4 = 0; + else + *v4 = portal[v2].level; + } + if ( v3 == myplr ) + { + SetCurrentPortal(v2); + v5 = v3; + plr[v5]._pmode = PM_NEWLVL; + v6 = ghMainWnd; + plr[v5]._pInvincible = 1; + PostMessageA(v6, WM_DIABWARPLVL, 0, 0); + } +} +// 679660: using guessed type char gbMaxPlayers; + +//----- (0044DB74) -------------------------------------------------------- +int __fastcall PM_DoNothing(int pnum) +{ + return 0; +} + +//----- (0044DB77) -------------------------------------------------------- +int __fastcall PM_DoWalk(int pnum) +{ + int v1; // ebx + int v2; // esi + int v3; // eax + int v4; // eax + int v5; // ecx + int v6; // eax + int v7; // edx + int v8; // eax + bool v9; // zf + int result; // eax + + v1 = pnum; + if ( (unsigned int)pnum >= 4 ) + TermMsg("PM_DoWalk: illegal player %d", pnum); + v2 = v1; + v3 = plr[v1]._pAnimFrame; + if ( v3 == 3 ) + goto LABEL_8; + if ( plr[v2]._pWFrames != 8 ) + { + if ( v3 != 4 ) + goto LABEL_9; + goto LABEL_8; + } + if ( v3 == 7 ) +LABEL_8: + PlaySfxLoc(0, plr[v2].WorldX, plr[v2].WorldY); +LABEL_9: + v4 = 8; + if ( currlevel ) + v4 = PWVel[3][SLOBYTE(plr[v2]._pClass)]; + if ( plr[v2]._pVar8 == v4 ) + { + v5 = plr[v2].WorldX; + v6 = plr[v2].WorldY; + dPlayer[plr[v2].WorldX][v6] = 0; + v7 = v5 + plr[v2]._pVar1; + v8 = plr[v2]._pVar2 + v6; + plr[v2].WorldX = v7; + v9 = leveltype == 0; + dPlayer[v7][v8] = v1 + 1; + plr[v2].WorldY = v8; + if ( !v9 ) + { + ChangeLightXY(plr[v2]._plid, v7, v8); + ChangeVisionXY(plr[v2]._pvid, plr[v2].WorldX, plr[v2].WorldY); + } + if ( v1 == myplr && ScrollInfo._sdir ) + { + ViewX = plr[v2].WorldX - ScrollInfo._sdx; + ViewY = plr[v2].WorldY - ScrollInfo._sdy; + } + if ( plr[v2].walkpath[0] == -1 ) + StartStand(v1, plr[v2]._pVar3); + else + StartWalkStand(v1); + ClearPlrPVars(v1); + if ( leveltype ) + ChangeLightOff(plr[v2]._plid, 0, 0); + result = 1; + } + else + { + PM_ChangeOffset(v1); + result = 0; + } + return result; +} +// 5BB1ED: using guessed type char leveltype; + +//----- (0044DCE5) -------------------------------------------------------- +int __fastcall PM_DoWalk2(int pnum) +{ + int v1; // ebx + int v2; // esi + int v3; // eax + int v4; // eax + int result; // eax + + v1 = pnum; + if ( (unsigned int)pnum >= 4 ) + TermMsg("PM_DoWalk2: illegal player %d", pnum); + v2 = v1; + v3 = plr[v1]._pAnimFrame; + if ( v3 == 3 ) + goto LABEL_8; + if ( plr[v2]._pWFrames != 8 ) + { + if ( v3 != 4 ) + goto LABEL_9; + goto LABEL_8; + } + if ( v3 == 7 ) +LABEL_8: + PlaySfxLoc(0, plr[v2].WorldX, plr[v2].WorldY); +LABEL_9: + v4 = 8; + if ( currlevel ) + v4 = PWVel[3][SLOBYTE(plr[v2]._pClass)]; + if ( plr[v2]._pVar8 == v4 ) + { + dPlayer[plr[v2]._pVar1][plr[v2]._pVar2] = 0; + if ( leveltype ) + { + ChangeLightXY(plr[v2]._plid, plr[v2].WorldX, plr[v2].WorldY); + ChangeVisionXY(plr[v2]._pvid, plr[v2].WorldX, plr[v2].WorldY); + } + if ( v1 == myplr && ScrollInfo._sdir ) + { + ViewX = plr[v2].WorldX - ScrollInfo._sdx; + ViewY = plr[v2].WorldY - ScrollInfo._sdy; + } + if ( plr[v2].walkpath[0] == -1 ) + StartStand(v1, plr[v2]._pVar3); + else + StartWalkStand(v1); + ClearPlrPVars(v1); + if ( leveltype ) + ChangeLightOff(plr[v2]._plid, 0, 0); + result = 1; + } + else + { + PM_ChangeOffset(v1); + result = 0; + } + return result; +} +// 5BB1ED: using guessed type char leveltype; + +//----- (0044DE30) -------------------------------------------------------- +int __fastcall PM_DoWalk3(int pnum) +{ + int v1; // ebx + int v2; // esi + int v3; // eax + int v4; // eax + int v5; // edx + char *v6; // eax + int v7; // eax + bool v8; // zf + int result; // eax + + v1 = pnum; + if ( (unsigned int)pnum >= 4 ) + TermMsg("PM_DoWalk3: illegal player %d", pnum); + v2 = v1; + v3 = plr[v1]._pAnimFrame; + if ( v3 == 3 ) + goto LABEL_8; + if ( plr[v2]._pWFrames != 8 ) + { + if ( v3 != 4 ) + goto LABEL_9; + goto LABEL_8; + } + if ( v3 == 7 ) +LABEL_8: + PlaySfxLoc(0, plr[v2].WorldX, plr[v2].WorldY); +LABEL_9: + v4 = 8; + if ( currlevel ) + v4 = PWVel[3][SLOBYTE(plr[v2]._pClass)]; + if ( plr[v2]._pVar8 == v4 ) + { + v5 = plr[v2]._pVar1; + dPlayer[plr[v2].WorldX][plr[v2].WorldY] = 0; + v6 = &dFlags[plr[v2]._pVar4][plr[v2]._pVar5]; + plr[v2].WorldX = v5; + *v6 &= 0xDFu; + v7 = plr[v2]._pVar2; + v8 = leveltype == 0; + dPlayer[v5][v7] = v1 + 1; + plr[v2].WorldY = v7; + if ( !v8 ) + { + ChangeLightXY(plr[v2]._plid, v5, v7); + ChangeVisionXY(plr[v2]._pvid, plr[v2].WorldX, plr[v2].WorldY); + } + if ( v1 == myplr && ScrollInfo._sdir ) + { + ViewX = plr[v2].WorldX - ScrollInfo._sdx; + ViewY = plr[v2].WorldY - ScrollInfo._sdy; + } + if ( plr[v2].walkpath[0] == -1 ) + StartStand(v1, plr[v2]._pVar3); + else + StartWalkStand(v1); + ClearPlrPVars(v1); + if ( leveltype ) + ChangeLightOff(plr[v2]._plid, 0, 0); + result = 1; + } + else + { + PM_ChangeOffset(v1); + result = 0; + } + return result; +} +// 5BB1ED: using guessed type char leveltype; + +//----- (0044DFB1) -------------------------------------------------------- +unsigned char __fastcall WeaponDur(int pnum, int durrnd) +{ + unsigned int v2; // edi + unsigned int v3; // esi + int v4; // ebp + int v5; // ecx + int v6; // ecx + int v7; // ecx + int v8; // ecx + int v9; // ecx + int v10; // ecx + int v11; // ecx + int v12; // ecx + + v2 = pnum; + if ( pnum != myplr ) + return 0; + _LOBYTE(pnum) = 3; + if ( random(pnum, durrnd) ) + return 0; + if ( v2 >= 4 ) + TermMsg("WeaponDur: illegal player %d", v2); + v3 = v2; + v4 = plr[v2].InvBody[4]._itype; + if ( v4 != ITYPE_NONE && plr[v3].InvBody[4]._iClass == 1 ) + { + v5 = plr[v3].InvBody[4]._iDurability; + if ( v5 == 255 ) + return 0; + v6 = v5 - 1; + plr[v3].InvBody[4]._iDurability = v6; + if ( !v6 ) + { +LABEL_22: + NetSendCmdDelItem(1u, 4u); + plr[v3].InvBody[4]._itype = -1; + goto LABEL_23; + } + } + if ( plr[v3].InvBody[5]._itype != -1 && plr[v3].InvBody[5]._iClass == 1 ) + { + v7 = plr[v3].InvBody[5]._iDurability; + if ( v7 == 255 ) + return 0; + v8 = v7 - 1; + plr[v3].InvBody[5]._iDurability = v8; + if ( !v8 ) + { +LABEL_13: + NetSendCmdDelItem(1u, 5u); + plr[v3].InvBody[5]._itype = -1; +LABEL_23: + CalcPlrInv(v2, 1u); + return 1; + } + } + if ( v4 == -1 && plr[v3].InvBody[5]._itype == ITYPE_SHIELD ) + { + v9 = plr[v3].InvBody[5]._iDurability; + if ( v9 == 255 ) + return 0; + v10 = v9 - 1; + plr[v3].InvBody[5]._iDurability = v10; + if ( !v10 ) + goto LABEL_13; + } + if ( plr[v3].InvBody[5]._itype == -1 && v4 == 5 ) + { + v11 = plr[v3].InvBody[4]._iDurability; + if ( v11 != 255 ) + { + v12 = v11 - 1; + plr[v3].InvBody[4]._iDurability = v12; + if ( !v12 ) + goto LABEL_22; + } + } + return 0; +} + +//----- (0044E0BC) -------------------------------------------------------- +unsigned char __fastcall PlrHitMonst(int pnum, int m) +{ + int v2; // ebx + unsigned int v3; // esi + int v4; // ST04_4 + int v5; // ebx + int v7; // ST04_4 + int v8; // eax + unsigned int v9; // esi + int v10; // ecx + int v11; // eax + int v12; // edi + int v13; // edi + int v14; // eax + int v15; // ecx + int v16; // edx + int v17; // eax + int v18; // ecx + int v19; // edi + int v20; // eax + int v21; // eax + char v22; // dl + bool v23; // zf + int v24; // eax + int v25; // ecx + int v26; // edi + int v27; // eax + int v28; // edx + int *v29; // ecx + int v30; // edx + int *v31; // ecx + int v32; // ecx + int v33; // edx + int *v34; // ecx + int v35; // edx + int *v36; // ecx + int v37; // edx + int *v38; // ecx + int *v39; // ecx + int v40; // esi + unsigned char ret[4]; // [esp+Ch] [ebp-18h] + int v42; // [esp+10h] [ebp-14h] + int v43; // [esp+14h] [ebp-10h] + int pnuma; // [esp+18h] [ebp-Ch] + char arglist[4]; // [esp+1Ch] [ebp-8h] + int v46; // [esp+20h] [ebp-4h] + + v2 = m; + v3 = pnum; + *(_DWORD *)arglist = m; + pnuma = pnum; + if ( (unsigned int)m >= 0xC8 ) + { + TermMsg("PlrHitMonst: illegal monster %d", m); + pnum = v4; + } + v5 = 228 * v2; + v43 = v5; + if ( (signed int)(*(int *)((_BYTE *)&monster[0]._mhitpoints + v5) & 0xFFFFFFC0) <= 0 + || **(_BYTE **)((char *)&monster[0].MType + v5) == MON_SNEAKD && *((_BYTE *)&monster[0]._mgoal + v5) == 2 + || *(MON_MODE *)((char *)&monster[0]._mmode + v5) == MM_CHARGE ) + { + return 0; + } + if ( v3 >= 4 ) + { + TermMsg("PlrHitMonst: illegal player %d", v3); + pnum = v7; + } + v42 = 0; + _LOBYTE(pnum) = 4; + v8 = random(pnum, 100); + v23 = *(MON_MODE *)((char *)&monster[0]._mmode + v5) == MM_STONE; + v46 = v8; + if ( v23 ) + v46 = 0; + v9 = v3; + v10 = plr[v9]._pLevel; + v11 = plr[v9]._pIEnAc + (plr[v9]._pDexterity >> 1) - *((unsigned char *)&monster[0].mArmorClass + v5); + v12 = v11 + v10 + 50; + if ( !_LOBYTE(plr[v9]._pClass) ) + v12 = v11 + v10 + 70; + v13 = plr[v9]._pIBonusToHit + v12; + if ( v13 < 5 ) + v13 = 5; + if ( v13 > 95 ) + v13 = 95; + _LOBYTE(v14) = CheckMonsterHit(*(int *)arglist, ret); + if ( v14 ) + return ret[0]; + if ( (signed int)v46 < v13 ) + { + _LOBYTE(v15) = 5; + v16 = plr[v9]._pIMaxDam - plr[v9]._pIMinDam + 1; + v42 = plr[v9]._pIMinDam; + v17 = random(v15, v16); + v18 = 100; + v19 = plr[v9]._pIBonusDamMod + plr[v9]._pDamageMod + (v42 + v17) * plr[v9]._pIBonusDam / 100 + v42 + v17; + if ( !_LOBYTE(plr[v9]._pClass) ) + { + _LOBYTE(v18) = 6; + v42 = plr[v9]._pLevel; + v20 = random(v18, 100); + if ( v20 < v42 ) + v19 *= 2; + } + v21 = plr[v9].InvBody[4]._itype; + v46 = -1; + if ( v21 == 1 || plr[v9].InvBody[5]._itype == 1 ) + v46 = 1; + if ( v21 == ITYPE_MACE || plr[v9].InvBody[5]._itype == ITYPE_MACE ) + v46 = ITYPE_MACE; + v22 = (*(MonsterData **)((char *)&monster[0].MData + v5))->mMonstClass; + if ( v22 ) + { + if ( v22 != 2 ) + goto LABEL_40; + if ( v46 == ITYPE_MACE ) + v19 -= v19 >> 1; + v23 = v46 == 1; + } + else + { + if ( v46 == 1 ) + v19 -= v19 >> 1; + v23 = v46 == ITYPE_MACE; + } + if ( v23 ) + v19 += v19 >> 1; +LABEL_40: + v24 = plr[v9]._pIFlags; + if ( v24 & 0x40000000 && v22 == 1 ) + v19 *= 3; + v25 = pnuma; + v26 = v19 << 6; + if ( pnuma == myplr ) + *(int *)((char *)&monster[0]._mhitpoints + v5) -= v26; + if ( v24 & 2 ) + { + _LOBYTE(v25) = 7; + v27 = random(v25, v26 >> 3); + v28 = plr[v9]._pMaxHP; + v29 = &plr[v9]._pHitPoints; + *v29 += v27; + if ( plr[v9]._pHitPoints > v28 ) + *v29 = v28; + v30 = plr[v9]._pMaxHPBase; + v31 = &plr[v9]._pHPBase; + *v31 += v27; + if ( plr[v9]._pHPBase > v30 ) + *v31 = v30; + v5 = v43; + drawhpflag = 1; + } + else + { + v27 = *(_DWORD *)ret; + } + v46 = plr[v9]._pIFlags; + v32 = v46; + if ( v32 & 0x6000 && !(v46 & 0x8000000) ) + { + if ( v32 & 0x2000 ) + v27 = 3 * v26 / 100; + if ( v32 & 0x4000 ) + v27 = 5 * v26 / 100; + v33 = plr[v9]._pMaxMana; + v34 = &plr[v9]._pMana; + *v34 += v27; + if ( plr[v9]._pMana > v33 ) + *v34 = v33; + v35 = plr[v9]._pMaxManaBase; + v36 = &plr[v9]._pManaBase; + *v36 += v27; + if ( plr[v9]._pManaBase > v35 ) + *v36 = v35; + v5 = v43; + v32 = v46; + drawmanaflag = 1; + } + if ( v32 & 0x18000 ) + { + if ( (v32 & 0x8000) != 0 ) + v27 = 3 * v26 / 100; + if ( v32 & 0x10000 ) + v27 = 5 * v26 / 100; + v37 = plr[v9]._pMaxHP; + v38 = &plr[v9]._pHitPoints; + *v38 += v27; + if ( plr[v9]._pHitPoints > v37 ) + *v38 = v37; + v39 = &plr[v9]._pHPBase; + v40 = plr[v9]._pMaxHPBase; + *v39 += v27; + if ( *v39 > v40 ) + *v39 = v40; + BYTE1(v32) = BYTE1(v46); + v5 = v43; + drawhpflag = 1; + } + if ( v32 & 0x100 ) + *(int *)((char *)&monster[0]._mFlags + v5) |= 8u; + if ( (signed int)(*(int *)((_BYTE *)&monster[0]._mhitpoints + v5) & 0xFFFFFFC0) > 0 ) + { + if ( *(MON_MODE *)((char *)&monster[0]._mmode + v5) != MM_STONE ) + { + if ( v32 & 0x800 ) + M_GetKnockback(*(int *)arglist); + M_StartHit(*(int *)arglist, pnuma, v26); + goto LABEL_85; + } + M_StartHit(*(int *)arglist, pnuma, v26); + } + else + { + if ( *(MON_MODE *)((char *)&monster[0]._mmode + v5) != MM_STONE ) + { + M_StartKill(*(int *)arglist, pnuma); + goto LABEL_85; + } + M_StartKill(*(int *)arglist, pnuma); + } + *(MON_MODE *)((char *)&monster[0]._mmode + v5) = MM_STONE; +LABEL_85: + v42 = 1; + } + return v42; +} + +//----- (0044E442) -------------------------------------------------------- +unsigned char __fastcall PlrHitPlr(int pnum, char p) +{ + char v2; // bl + unsigned int v3; // esi + int v4; // ST04_4 + int v5; // edi + int v7; // ST04_4 + unsigned int v8; // esi + int v9; // ecx + int v10; // eax + int v11; // ebx + int v12; // ebx + int v13; // eax + int v14; // eax + int v15; // ecx + int v16; // eax + int v17; // ebx + int v18; // eax + int v19; // ecx + int v20; // edi + int v21; // ebx + signed __int32 v22; // edi + int v23; // eax + int v24; // edx + int *v25; // ecx + int *v26; // ecx + int v27; // esi + int v28; // [esp+Ch] [ebp-14h] + int v29; // [esp+10h] [ebp-10h] + unsigned char v30; // [esp+14h] [ebp-Ch] + int arglist; // [esp+18h] [ebp-8h] + char bPlr; // [esp+1Ch] [ebp-4h] + + v2 = p; + v3 = pnum; + bPlr = p; + v28 = pnum; + if ( (unsigned char)p >= 4u ) + { + TermMsg("PlrHitPlr: illegal target player %d", p); + pnum = v4; + } + arglist = v2; + v5 = v2; + v30 = 0; + if ( plr[v5]._pInvincible || plr[v5]._pSpellFlags & 1 ) + return 0; + if ( v3 >= 4 ) + { + TermMsg("PlrHitPlr: illegal attacking player %d", v3); + pnum = v7; + } + _LOBYTE(pnum) = 4; + v8 = v3; + v29 = random(pnum, 100); + v9 = (plr[v8]._pDexterity >> 1) - plr[v5]._pIBonusAC - plr[v5]._pIAC - plr[v5]._pDexterity / 5; + v10 = plr[v8]._pLevel; + v11 = v9 + v10 + 50; + if ( !_LOBYTE(plr[v8]._pClass) ) + v11 = v9 + v10 + 70; + v12 = plr[v8]._pIBonusToHit + v11; + if ( v12 < 5 ) + v12 = 5; + if ( v12 > 95 ) + v12 = 95; + v13 = plr[v5]._pmode; + if ( v13 && v13 != 4 || !plr[v5]._pBlockFlag ) + { + v14 = 100; + } + else + { + _LOBYTE(v9) = 5; + v14 = random(v9, 100); + } + v15 = plr[v5]._pDexterity + plr[v5]._pBaseToBlk + 2 * plr[v5]._pLevel - 2 * plr[v8]._pLevel; + if ( v15 < 0 ) + v15 = 0; + if ( v15 > 100 ) + v15 = 100; + if ( v29 < v12 ) + { + if ( v14 >= v15 ) + { + v17 = plr[v8]._pIMinDam; + _LOBYTE(v15) = 5; + v18 = random(v15, plr[v8]._pIMaxDam - v17 + 1); + v19 = 100; + v20 = plr[v8]._pIBonusDamMod + plr[v8]._pDamageMod + (v17 + v18) * plr[v8]._pIBonusDam / 100 + v17 + v18; + if ( !_LOBYTE(plr[v8]._pClass) ) + { + v21 = plr[v8]._pLevel; + _LOBYTE(v19) = 6; + if ( random(v19, 100) < v21 ) + v20 *= 2; + } + v22 = v20 << 6; + if ( plr[v8]._pIFlags & 2 ) + { + _LOBYTE(v19) = 7; + v23 = random(v19, v22 >> 3); + v24 = plr[v8]._pMaxHP; + v25 = &plr[v8]._pHitPoints; + *v25 += v23; + if ( plr[v8]._pHitPoints > v24 ) + *v25 = v24; + v26 = &plr[v8]._pHPBase; + v27 = plr[v8]._pMaxHPBase; + *v26 += v23; + if ( *v26 > v27 ) + *v26 = v27; + drawhpflag = 1; + } + if ( v28 == myplr ) + NetSendCmdDamage(1u, bPlr, v22); + StartPlrHit(arglist, v22, 0); + } + else + { + v16 = GetDirection(plr[v5].WorldX, plr[v5].WorldY, plr[v8].WorldX, plr[v8].WorldY); + StartPlrBlock(arglist, v16); + } + v30 = 1; + } + return v30; +} + +//----- (0044E669) -------------------------------------------------------- +unsigned char __fastcall PlrHitObj(int pnum, int mx, int my) +{ + char v3; // dl + int v4; // edx + + v3 = dObject[mx][my]; + if ( v3 <= 0 ) + v4 = -1 - v3; + else + v4 = v3 - 1; + if ( _LOBYTE(object[v4]._oBreak) != 1 ) + return 0; + BreakObject(pnum, v4); + return 1; +} + +//----- (0044E6A6) -------------------------------------------------------- +int __fastcall PM_DoAttack(int pnum) +{ + int v1; // esi + int v2; // esi + int v3; // ecx + int v4; // eax + int v5; // eax + int v6; // ebx + int v7; // edi + int v8; // eax + int v9; // edx + int v10; // ecx + int v11; // eax + int v12; // edx + int v13; // eax + int v14; // eax + int v15; // edx + char v16; // al + int v17; // eax + int v19; // [esp+Ch] [ebp-8h] + int arglist; // [esp+10h] [ebp-4h] + + v1 = pnum; + arglist = pnum; + if ( (unsigned int)pnum >= 4 ) + TermMsg("PM_DoAttack: illegal player %d", pnum); + v2 = v1; + v3 = plr[v2]._pIFlags; + v4 = plr[v2]._pAnimFrame; + if ( v3 & 0x20000 && v4 == 1 ) + plr[v2]._pAnimFrame = 2; + if ( v3 & 0x40000 && (v4 == 1 || v4 == 3) ) + ++plr[v2]._pAnimFrame; + if ( v3 & 0x80000 && (v4 == 1 || v4 == 3 || v4 == 5) ) + ++plr[v2]._pAnimFrame; + if ( v3 & 0x100000 && (v4 == 1 || v4 == 4) ) + plr[v2]._pAnimFrame += 2; + if ( plr[v2]._pAnimFrame == plr[v2]._pAFNum - 1 ) + PlaySfxLoc(PS_SWING, plr[v2].WorldX, plr[v2].WorldY); + if ( plr[v2]._pAnimFrame != plr[v2]._pAFNum ) + goto LABEL_49; + v5 = plr[v2]._pdir; + v6 = plr[v2].WorldX + offset_x[v5]; + v7 = plr[v2].WorldY + offset_y[v5]; + v8 = v7 + 112 * v6; + v19 = v8; + v9 = dMonster[0][v8]; + if ( !v9 ) + { +LABEL_29: + if ( plr[v2]._pIFlags & 0x10 ) + { + AddMissile(v6, v7, 1, 0, 0, 64, 0, arglist, 0, 0); + v8 = v19; + } + if ( plr[v2]._pIFlags & 0x20 ) + { + AddMissile(v6, v7, 2, 0, 0, 64, 0, arglist, 0, 0); + v8 = v19; + } + v12 = dMonster[0][v8]; + if ( v12 ) + { + if ( v12 <= 0 ) + v13 = -1 - v12; + else + v13 = v12 - 1; + _LOBYTE(v14) = PlrHitMonst(arglist, v13); + goto LABEL_46; + } + v15 = (unsigned char)dPlayer[0][v8]; + if ( (_BYTE)v15 && !FriendlyMode ) + { + if ( (char)v15 <= 0 ) + v16 = -1 - v15; + else + v16 = v15 - 1; + _LOBYTE(v14) = PlrHitPlr(arglist, v16); +LABEL_46: + if ( v14 ) + { + _LOBYTE(v17) = WeaponDur(arglist, 30); + if ( v17 ) + goto LABEL_48; + } + goto LABEL_49; + } + if ( dObject[0][v8] > 0 ) + { + _LOBYTE(v14) = PlrHitObj(arglist, v6, v7); + goto LABEL_46; + } +LABEL_49: + if ( plr[v2]._pAnimFrame != plr[v2]._pAFrames ) + return 0; +LABEL_48: + StartStand(arglist, plr[v2]._pdir); + ClearPlrPVars(arglist); + return 1; + } + if ( v9 <= 0 ) + v10 = -1 - v9; + else + v10 = v9 - 1; + _LOBYTE(v11) = CanTalkToMonst(v10); + if ( !v11 ) + { + v8 = v19; + goto LABEL_29; + } + plr[v2]._pVar1 = 0; + return 0; +} +// 484368: using guessed type int FriendlyMode; + +//----- (0044E8B8) -------------------------------------------------------- +int __fastcall PM_DoRangeAttack(int pnum) +{ + int v1; // edi + int v2; // esi + int v3; // ecx + int v4; // eax + int v5; // eax + int v6; // eax + + v1 = pnum; + if ( (unsigned int)pnum >= 4 ) + TermMsg("PM_DoRangeAttack: illegal player %d", pnum); + v2 = v1; + v3 = plr[v1]._pIFlags; + v4 = plr[v1]._pAnimFrame; + if ( v3 & 0x20000 && v4 == 1 ) + plr[v2]._pAnimFrame = 2; + if ( v3 & 0x40000 && (v4 == 1 || v4 == 3) ) + ++plr[v2]._pAnimFrame; + if ( plr[v2]._pAnimFrame != plr[v2]._pAFNum ) + goto LABEL_21; + v5 = 0; + if ( v3 & 8 ) + v5 = 27; + if ( v3 & 0x2000000 ) + v5 = 56; + AddMissile(plr[v2].WorldX, plr[v2].WorldY, plr[v2]._pVar1, plr[v2]._pVar2, plr[v2]._pdir, v5, 0, v1, 4, 0); + PlaySfxLoc(PS_BFIRE, plr[v2].WorldX, plr[v2].WorldY); + _LOBYTE(v6) = WeaponDur(v1, 40); + if ( !v6 ) + { +LABEL_21: + if ( plr[v2]._pAnimFrame < plr[v2]._pAFrames ) + return 0; + } + StartStand(v1, plr[v2]._pdir); + ClearPlrPVars(v1); + return 1; +} + +//----- (0044E9AC) -------------------------------------------------------- +void __fastcall ShieldDur(int pnum) +{ + int v1; // edi + int v2; // esi + int v3; // ecx + int v4; // ecx + int v5; // ecx + int v6; // ecx + + v1 = pnum; + if ( pnum == myplr ) + { + if ( (unsigned int)pnum >= 4 ) + TermMsg("ShieldDur: illegal player %d", pnum); + v2 = v1; + if ( plr[v1].InvBody[4]._itype == ITYPE_SHIELD ) + { + v3 = plr[v2].InvBody[4]._iDurability; + if ( v3 == 255 ) + return; + v4 = v3 - 1; + plr[v2].InvBody[4]._iDurability = v4; + if ( !v4 ) + { + NetSendCmdDelItem(1u, 4u); + plr[v2].InvBody[4]._itype = ITYPE_NONE; + CalcPlrInv(v1, 1u); + } + } + if ( plr[v2].InvBody[5]._itype == ITYPE_SHIELD ) + { + v5 = plr[v2].InvBody[5]._iDurability; + if ( v5 != 255 ) + { + v6 = v5 - 1; + plr[v2].InvBody[5]._iDurability = v6; + if ( !v6 ) + { + NetSendCmdDelItem(1u, 5u); + plr[v2].InvBody[5]._itype = ITYPE_NONE; + CalcPlrInv(v1, 1u); + } + } + } + } +} + +//----- (0044EA4D) -------------------------------------------------------- +int __fastcall PM_DoBlock(int pnum) +{ + int v1; // esi + int v2; // eax + int v3; // ecx + + v1 = pnum; + if ( (unsigned int)pnum >= 4 ) + TermMsg("PM_DoBlock: illegal player %d", pnum); + v2 = v1; + if ( plr[v1]._pIFlags & 0x1000000 && plr[v2]._pAnimFrame != 1 ) + plr[v2]._pAnimFrame = plr[v2]._pBFrames; + if ( plr[v2]._pAnimFrame < plr[v2]._pBFrames ) + return 0; + StartStand(v1, plr[v2]._pdir); + ClearPlrPVars(v1); + _LOBYTE(v3) = 3; + if ( !random(v3, 10) ) + ShieldDur(v1); + return 1; +} + +//----- (0044EAC6) -------------------------------------------------------- +int __fastcall PM_DoSpell(int pnum) +{ + int v1; // edi + int v2; // esi + + v1 = pnum; + if ( (unsigned int)pnum >= 4 ) + TermMsg("PM_DoSpell: illegal player %d", pnum); + v2 = v1; + if ( plr[v1]._pVar8 == plr[v1]._pSFNum ) + { + CastSpell( + v1, + plr[v2]._pSpell, + plr[v2].WorldX, + plr[v2].WorldY, + plr[v2]._pVar1, + plr[v2]._pVar2, + 0, + plr[v2]._pVar4); + if ( !plr[v2]._pSplFrom ) + { + if ( _LOBYTE(plr[v2]._pRSplType) == 2 + && !(plr[v2]._pScrlSpells[1] & ((unsigned __int64)(1i64 << (_LOBYTE(plr[v2]._pRSpell) - 1)) >> 32) | plr[v2]._pScrlSpells[0] & (unsigned int)(1i64 << (_LOBYTE(plr[v2]._pRSpell) - 1))) ) + { + plr[v2]._pRSpell = -1; + _LOBYTE(plr[v2]._pRSplType) = 4; + force_redraw = 255; + } + if ( _LOBYTE(plr[v2]._pRSplType) == 3 + && !(plr[v2]._pISpells[1] & ((unsigned __int64)(1i64 << (_LOBYTE(plr[v2]._pRSpell) - 1)) >> 32) | plr[v2]._pISpells[0] & (unsigned int)(1i64 << (_LOBYTE(plr[v2]._pRSpell) - 1))) ) + { + plr[v2]._pRSpell = -1; + _LOBYTE(plr[v2]._pRSplType) = 4; + force_redraw = 255; + } + } + } + ++plr[v2]._pVar8; + if ( leveltype ) + { + if ( plr[v2]._pAnimFrame == plr[v2]._pSFrames ) + { + StartStand(v1, plr[v2]._pdir); + goto LABEL_16; + } + } + else if ( plr[v2]._pVar8 > plr[v2]._pSFrames ) + { + StartWalkStand(v1); +LABEL_16: + ClearPlrPVars(v1); + return 1; + } + return 0; +} +// 52571C: using guessed type int force_redraw; +// 5BB1ED: using guessed type char leveltype; + +//----- (0044EC06) -------------------------------------------------------- +int __fastcall PM_DoGotHit(int pnum) +{ + int v1; // esi + int v2; // eax + int v3; // edx + int v4; // ecx + int v5; // ecx + + v1 = pnum; + if ( (unsigned int)pnum >= 4 ) + TermMsg("PM_DoGotHit: illegal player %d", pnum); + v2 = v1; + v3 = plr[v1]._pIFlags; + v4 = plr[v1]._pAnimFrame; + if ( v3 & 0x200000 && v4 == 3 ) + plr[v2]._pAnimFrame = 4; + if ( v3 & 0x400000 && (v4 == 3 || v4 == 5) ) + ++plr[v2]._pAnimFrame; + if ( v3 & 0x800000 && (v4 == 1 || v4 == 3 || v4 == 5) ) + ++plr[v2]._pAnimFrame; + if ( plr[v2]._pAnimFrame < plr[v2]._pHFrames ) + return 0; + StartStand(v1, plr[v2]._pdir); + ClearPlrPVars(v1); + _LOBYTE(v5) = 3; + if ( random(v5, 4) ) + ArmorDur(v1); + return 1; +} + +//----- (0044ECBC) -------------------------------------------------------- +void __fastcall ArmorDur(int pnum) +{ + int v1; // ebp + int v2; // ST04_4 + PlayerStruct *v3; // esi + int v4; // eax + int v5; // edi + int v6; // esi + int v7; // ecx + int v8; // ecx + unsigned char v9; // dl + + v1 = pnum; + if ( pnum == myplr ) + { + if ( (unsigned int)pnum >= 4 ) + { + TermMsg("ArmorDur: illegal player %d", pnum); + pnum = v2; + } + v3 = &plr[v1]; + if ( v3->InvBody[6]._itype != -1 || v3->InvBody[0]._itype != -1 ) + { + _LOBYTE(pnum) = 8; + v4 = random(pnum, 3); + v5 = v3->InvBody[6]._itype; + if ( v5 == -1 ) + goto LABEL_23; + if ( v3->InvBody[0]._itype == -1 ) + v4 = 1; + if ( v5 == -1 ) + { +LABEL_23: + if ( v3->InvBody[0]._itype != -1 ) + v4 = 0; + } + if ( v4 ) + v6 = (int)&v3->InvBody[6]; + else + v6 = (int)v3->InvBody; + v7 = *(_DWORD *)(v6 + 236); + if ( v7 != 255 ) + { + v8 = v7 - 1; + *(_DWORD *)(v6 + 236) = v8; + if ( !v8 ) + { + if ( v4 ) + v9 = 6; + else + v9 = 0; + NetSendCmdDelItem(1u, v9); + *(_DWORD *)(v6 + 8) = -1; + CalcPlrInv(v1, 1u); + } + } + } + } +} + +//----- (0044ED7B) -------------------------------------------------------- +int __fastcall PM_DoDeath(int pnum) +{ + int v1; // edi + int v2; // esi + int v3; // ecx + int v4; // eax + int v5; // eax + + v1 = pnum; + if ( (unsigned int)pnum >= 4 ) + TermMsg("PM_DoDeath: illegal player %d", pnum); + v2 = v1; + if ( plr[v1]._pVar8 >= 2 * plr[v1]._pDFrames ) + { + if ( deathdelay > 1 && v1 == myplr && --deathdelay == 1 ) + { + *(_DWORD *)&deathflag = 1; + if ( gbMaxPlayers == 1 ) + gamemenu_previous(); + } + v3 = plr[v2].WorldY; + plr[v2]._pAnimFrame = plr[v2]._pAnimLen; + v4 = plr[v2].WorldX; + plr[v2]._pAnimDelay = 10000; + dFlags[v4][v3] |= 4u; + } + v5 = plr[v2]._pVar8; + if ( v5 < 100 ) + plr[v2]._pVar8 = v5 + 1; + return 0; +} +// 679660: using guessed type char gbMaxPlayers; +// 69B7C4: using guessed type int deathdelay; + +//----- (0044EE22) -------------------------------------------------------- +void __fastcall CheckNewPath(int pnum) +{ + int v1; // edi + int v2; // ebx + int v3; // eax + int v4; // ecx + bool v5; // zf + int v6; // eax + int v7; // esi + int v8; // eax + int v9; // edx + int v10; // esi + int v11; // esi + int v12; // eax + int v13; // eax + int v14; // ecx + int v15; // edx + int v16; // eax + int v17; // eax + int v18; // eax + int v19; // ecx + int v20; // eax + int v21; // edi + int v22; // esi + int v23; // ST38_4 + int v24; // eax + int v25; // esi + int v26; // esi + int v27; // ST38_4 + int v28; // eax + int v29; // ecx + int v30; // edx + int v31; // ecx + int *v32; // esi + int *v33; // edi + int v34; // esi + int v35; // eax + int v36; // ecx + int v37; // eax + int v38; // eax + int v39; // eax + int v40; // eax + int v41; // eax + int *v42; // esi + int *v43; // edi + int v44; // eax + int v45; // eax + int v46; // esi + int v47; // esi + int v48; // eax + int v49; // ecx + int v50; // esi + int v51; // eax + int v52; // ecx + int v53; // edi + int v54; // esi + int v55; // ST38_4 + int v56; // eax + int v57; // edi + int v58; // esi + int v59; // ST38_4 + int v60; // eax + int v61; // eax + int v62; // ecx + int v63; // esi + int v64; // ST38_4 + int v65; // eax + int v66; // esi + int v67; // edi + int v68; // eax + int v69; // esi + int v70; // esi + int v71; // eax + int v72; // ecx + int v73; // eax + int v74; // eax + int *v75; // esi + int *v76; // edi + int v77; // eax + int v78; // eax + int v79; // eax + int v80; // eax + int *v81; // esi + int *v82; // edi + int v83; // eax + int v84; // eax + int v85; // eax + int v86; // [esp-18h] [ebp-34h] + int v87; // [esp-10h] [ebp-2Ch] + int v88; // [esp-10h] [ebp-2Ch] + int v89; // [esp-Ch] [ebp-28h] + int v90; // [esp-Ch] [ebp-28h] + int v91; // [esp-8h] [ebp-24h] + int v92; // [esp-8h] [ebp-24h] + int v93; // [esp-8h] [ebp-24h] + int v94; // [esp-4h] [ebp-20h] + int v95; // [esp-4h] [ebp-20h] + int v96; // [esp-4h] [ebp-20h] + signed int v97; // [esp+Ch] [ebp-10h] + int arglist; // [esp+10h] [ebp-Ch] + int arglista; // [esp+10h] [ebp-Ch] + int arglistb; // [esp+10h] [ebp-Ch] + int v101; // [esp+14h] [ebp-8h] + int v102; // [esp+14h] [ebp-8h] + int v103; // [esp+14h] [ebp-8h] + int v104; // [esp+14h] [ebp-8h] + int p; // [esp+18h] [ebp-4h] + + v1 = pnum; + p = pnum; + if ( (unsigned int)pnum >= 4 ) + TermMsg("CheckNewPath: illegal player %d", pnum); + v2 = v1; + if ( plr[v1].destAction == 20 ) + MakePlrPath(v1, monster[plr[v2].destParam1]._mfutx, monster[plr[v2].destParam1]._mfuty, 0); + if ( plr[v2].destAction == 21 ) + MakePlrPath(v1, plr[plr[v2].destParam1]._px, plr[plr[v2].destParam1]._py, 0); + if ( plr[v2].walkpath[0] == -1 ) + { + v18 = plr[v2].destAction; + if ( v18 == -1 ) + return; + v19 = plr[v2]._pmode; + if ( v19 == PM_STAND ) + { + switch ( v18 ) + { + case 9: + v20 = GetDirection(plr[v2].WorldX, plr[v2].WorldY, plr[v2].destParam1, plr[v2].destParam2); + goto LABEL_52; + case 10: + v30 = plr[v2].WorldY; + v31 = plr[v2].WorldX; + v32 = &plr[v2].destParam2; + v33 = &plr[v2].destParam1; + goto LABEL_59; + case 12: + v39 = GetDirection(plr[v2].WorldX, plr[v2].WorldY, plr[v2].destParam1, plr[v2].destParam2); + StartSpell(p, v39, plr[v2].destParam1, plr[v2].destParam2); + v40 = plr[v2].destParam3; + goto LABEL_66; + case 13: + v46 = plr[v2].destParam1; + arglista = v46; + v47 = v46; + v102 = abs(plr[v2].WorldX - object[v47]._ox); + v48 = abs(plr[v2].WorldY - object[v47]._oy); + if ( v48 > 1 ) + { + v49 = object[v47]._oy; + if ( dungeon[39][112 * object[v47]._ox + 39 + v49] == -1 - arglista ) + v48 = abs(plr[v2].WorldY - v49 + 1); + } + if ( v102 > 1 || v48 > 1 ) + break; + if ( _LOBYTE(object[v47]._oBreak) != 1 ) + goto LABEL_73; + goto LABEL_80; + case 14: + v50 = plr[v2].destParam1; + arglista = v50; + v47 = v50; + v103 = abs(plr[v2].WorldX - object[v47]._ox); + v51 = abs(plr[v2].WorldY - object[v47]._oy); + if ( v51 > 1 ) + { + v52 = object[v47]._oy; + if ( dungeon[39][112 * object[v47]._ox + 39 + v52] == -1 - arglista ) + v51 = abs(plr[v2].WorldY - v52 + 1); + } + if ( v103 > 1 || v51 > 1 ) + break; + if ( _LOBYTE(object[v47]._oBreak) == 1 ) + { +LABEL_80: + v20 = GetDirection(plr[v2].WorldX, plr[v2].WorldY, object[v47]._ox, object[v47]._oy); +LABEL_81: + v29 = p; +LABEL_82: + StartAttack(v29, v20); + } + else + { + TryDisarm(p, arglista); +LABEL_73: + OperateObject(p, arglista, 0); + } + break; + case 15: + if ( v1 == myplr ) + { + v53 = plr[v2].destParam1; + v54 = plr[v2].destParam1; + v55 = abs(plr[v2].WorldX - items[v54]._ix); + v56 = abs(plr[v2].WorldY - items[v54]._iy); + if ( v55 <= 1 && v56 <= 1 && pcurs == 1 && !items[v54]._iRequest ) + { + NetSendCmdGItem(1u, CMD_REQUESTGITEM, myplr, myplr, v53); + items[v54]._iRequest = 1; + } + } + break; + case 16: + if ( v1 == myplr ) + { + v57 = plr[v2].destParam1; + v58 = plr[v2].destParam1; + v59 = abs(plr[v2].WorldX - items[v58]._ix); + v60 = abs(plr[v2].WorldY - items[v58]._iy); + if ( v59 <= 1 && v60 <= 1 && pcurs == 1 ) + NetSendCmdGItem(1u, CMD_REQUESTAGITEM, myplr, myplr, v57); + } + break; + case 17: + if ( v1 == myplr ) + TalkToTowner(v1, plr[v2].destParam1); + break; + case 18: + if ( _LOBYTE(object[plr[v2].destParam1]._oBreak) != 1 ) + OperateObject(v1, plr[v2].destParam1, 1u); + break; + case 20: + v21 = plr[v2].destParam1; + v22 = plr[v2].destParam1; + v23 = abs(plr[v2].WorldX - monster[v22]._mfutx); + v24 = abs(plr[v2].WorldY - monster[v22]._mfuty); + if ( v23 > 1 || v24 > 1 ) + break; + v20 = GetDirection(plr[v2]._px, plr[v2]._py, monster[v22]._mfutx, monster[v22]._mfuty); + v25 = monster[v22].mtalkmsg; + if ( v25 && v25 != TEXT_LAZ1_2 ) + goto LABEL_56; + goto LABEL_81; + case 21: + v26 = plr[v2].destParam1; + v27 = abs(plr[v2].WorldX - plr[v26]._px); + v28 = abs(plr[v2].WorldY - plr[v26]._py); + if ( v27 > 1 || v28 > 1 ) + break; + v20 = GetDirection(plr[v2]._px, plr[v2]._py, plr[v26]._px, plr[v26]._py); +LABEL_52: + v29 = v1; + goto LABEL_82; + case 22: + v21 = plr[v2].destParam1; + v34 = plr[v2].destParam1; + v35 = GetDirection(plr[v2]._px, plr[v2]._py, monster[v34]._mfutx, monster[v34]._mfuty); + v36 = monster[v34].mtalkmsg; + if ( v36 && v36 != TEXT_LAZ1_2 ) +LABEL_56: + TalktoMonster(v21); + else + StartRangeAttack(p, v35, monster[v34]._mfutx, monster[v34]._mfuty); + break; + case 23: + v30 = plr[v2]._py; + v37 = plr[v2].destParam1; + v31 = plr[v2]._px; + v32 = &plr[v37]._py; + v33 = &plr[v37]._px; +LABEL_59: + v38 = GetDirection(v31, v30, *v33, *v32); + StartRangeAttack(p, v38, *v33, *v32); + break; + case 24: + v41 = plr[v2].destParam1; + v42 = &monster[v41]._mfuty; + v43 = &monster[v41]._mfutx; + goto LABEL_65; + case 25: + v44 = plr[v2].destParam1; + v42 = &plr[v44]._py; + v43 = &plr[v44]._px; +LABEL_65: + v45 = GetDirection(plr[v2].WorldX, plr[v2].WorldY, *v43, *v42); + StartSpell(p, v45, *v43, *v42); + v40 = plr[v2].destParam2; + goto LABEL_66; + case 26: + StartSpell(v1, plr[v2].destParam3, plr[v2].destParam1, plr[v2].destParam2); + plr[v2]._pVar3 = plr[v2].destParam3; + v40 = plr[v2].destParam4; +LABEL_66: + plr[v2]._pVar4 = v40; + break; + default: + break; + } + FixPlayerLocation(p, plr[v2]._pdir); + goto LABEL_143; + } + if ( v19 == 4 && plr[v2]._pAnimFrame > plr[myplr]._pAFNum ) + { + switch ( v18 ) + { + case 9: + v61 = GetDirection(plr[v2]._px, plr[v2]._py, plr[v2].destParam1, plr[v2].destParam2); +LABEL_105: + v62 = v1; +LABEL_106: + StartAttack(v62, v61); +LABEL_107: + plr[v2].destAction = -1; + break; + case 20: + v63 = plr[v2].destParam1; + v64 = abs(plr[v2].WorldX - monster[v63]._mfutx); + v65 = abs(plr[v2].WorldY - monster[v63]._mfuty); + if ( v64 > 1 || v65 > 1 ) + goto LABEL_107; + v61 = GetDirection(plr[v2]._px, plr[v2]._py, monster[v63]._mfutx, monster[v63]._mfuty); + goto LABEL_105; + case 21: + v66 = plr[v2].destParam1; + v67 = abs(plr[v2].WorldX - plr[v66]._px); + v68 = abs(plr[v2].WorldY - plr[v66]._py); + if ( v67 > 1 || v68 > 1 ) + goto LABEL_107; + v61 = GetDirection(plr[v2]._px, plr[v2]._py, plr[v66]._px, plr[v66]._py); + v62 = p; + goto LABEL_106; + case 13: + v69 = plr[v2].destParam1; + arglistb = v69; + v70 = v69; + v104 = abs(plr[v2].WorldX - object[v70]._ox); + v71 = abs(plr[v2].WorldY - object[v70]._oy); + if ( v71 > 1 ) + { + v72 = object[v70]._oy; + if ( dungeon[39][112 * object[v70]._ox + 39 + v72] == -1 - arglistb ) + v71 = abs(plr[v2].WorldY - v72 + 1); + } + if ( v104 <= 1 && v71 <= 1 ) + { + if ( _LOBYTE(object[v70]._oBreak) == 1 ) + { + v73 = GetDirection(plr[v2].WorldX, plr[v2].WorldY, object[v70]._ox, object[v70]._oy); + StartAttack(p, v73); + } + else + { + OperateObject(p, arglistb, 0); + } + } + break; + } + } + if ( plr[v2]._pmode == PM_RATTACK && plr[v2]._pAnimFrame > plr[myplr]._pAFNum ) + { + v74 = plr[v2].destAction; + switch ( v74 ) + { + case 10: + v75 = &plr[v2].destParam2; + v76 = &plr[v2].destParam1; +LABEL_133: + v79 = GetDirection(plr[v2].WorldX, plr[v2].WorldY, *v76, *v75); + StartRangeAttack(p, v79, *v76, *v75); + plr[v2].destAction = -1; + break; + case 22: + v77 = plr[v2].destParam1; + v75 = &monster[v77]._mfuty; + v76 = &monster[v77]._mfutx; + goto LABEL_133; + case 23: + v78 = plr[v2].destParam1; + v75 = &plr[v78]._py; + v76 = &plr[v78]._px; + goto LABEL_133; + } + } + if ( plr[v2]._pmode == PM_SPELL && plr[v2]._pAnimFrame > plr[v2]._pSFNum ) + { + v80 = plr[v2].destAction; + switch ( v80 ) + { + case 12: + v81 = &plr[v2].destParam2; + v82 = &plr[v2].destParam1; + break; + case 24: + v83 = plr[v2].destParam1; + v81 = &monster[v83]._mfuty; + v82 = &monster[v83]._mfutx; + break; + case 25: + v84 = plr[v2].destParam1; + v81 = &plr[v84]._py; + v82 = &plr[v84]._px; + break; + default: + return; + } + v85 = GetDirection(plr[v2].WorldX, plr[v2].WorldY, *v82, *v81); + StartSpell(p, v85, *v82, *v81); + goto LABEL_143; + } + return; + } + if ( plr[v2]._pmode == PM_STAND ) + { + if ( v1 == myplr ) + { + v3 = plr[v2].destAction; + if ( v3 == 20 || v3 == 21 ) + { + v4 = plr[v2].destParam1; + v5 = v3 == 20; + v6 = plr[v2]._px; + arglist = plr[v2].destParam1; + if ( v5 ) + { + v7 = v4; + v101 = abs(v6 - monster[v4]._mfutx); + v8 = abs(plr[v2]._py - monster[v7]._mfuty); + v9 = plr[v2]._py; + v94 = monster[v7]._mfuty; + v91 = monster[v7]._mfutx; + } + else + { + v10 = v4; + v101 = abs(v6 - plr[v4]._px); + v8 = abs(plr[v2]._py - plr[v10]._py); + v9 = plr[v2]._py; + v94 = plr[v10]._py; + v91 = plr[v10]._px; + } + v97 = v8; + v11 = GetDirection(plr[v2]._px, v9, v91, v94); + if ( v101 < 2 && v97 < 2 ) + { + ClrPlrPath(p); + v12 = monster[arglist].mtalkmsg; + if ( v12 && v12 != TEXT_LAZ1_2 ) + TalktoMonster(arglist); + else + StartAttack(p, v11); + plr[v2].destAction = -1; + } + } + } + if ( currlevel ) + { + v13 = SLOBYTE(plr[v2]._pClass); + v14 = PWVel[v13][0]; + v15 = PWVel[v13][1]; + v16 = PWVel[v13][2]; + } + else + { + v14 = 2048; + v15 = 1024; + v16 = 512; + } + switch ( plr[v2].walkpath[0] ) + { + case WALK_NE: + v95 = 2; + v92 = DIR_NE; + v89 = -1; + v87 = 0; + v17 = -v16; + goto LABEL_37; + case WALK_NW: + v95 = 8; + v92 = DIR_NW; + v89 = 0; + v87 = -1; + v17 = -v16; + v15 = -v15; +LABEL_37: + StartWalk(p, v15, v17, v87, v89, v92, v95); + break; + case WALK_SE: + v96 = 4; + v93 = DIR_SE; + v90 = 0; + v88 = 1; + v86 = -32; + goto LABEL_32; + case WALK_SW: + v96 = 6; + v93 = DIR_SW; + v90 = 1; + v88 = 0; + v86 = 32; + v15 = -v15; +LABEL_32: + StartWalk2(p, v15, v16, v86, -16, v88, v90, v93, v96); + break; + case WALK_N: + StartWalk(p, 0, -v15, -1, -1, DIR_N, 1); + break; + case WALK_E: + StartWalk3(p, v14, 0, -32, -16, 1, -1, 1, 0, DIR_E, 3); + break; + case WALK_S: + StartWalk2(p, 0, v15, 0, -32, 1, 1, DIR_S, 5); + break; + case WALK_W: + StartWalk3(p, -v14, 0, 32, -16, -1, 1, 0, 1, DIR_W, 7); + break; + default: + break; + } + qmemcpy(plr[v2].walkpath, &plr[v2].walkpath[1], 0x18u); + plr[v2].walkpath[24] = -1; + if ( plr[v2]._pmode == PM_STAND ) + { + StartStand(p, plr[v2]._pdir); +LABEL_143: + plr[v2].destAction = -1; + return; + } + } +} + +//----- (0044F9BA) -------------------------------------------------------- +unsigned char __fastcall PlrDeathModeOK(int pnum) +{ + int v1; // esi + unsigned char result; // al + int v3; // esi + + v1 = pnum; + if ( pnum != myplr ) + goto LABEL_10; + if ( (unsigned int)pnum >= 4 ) + TermMsg("PlrDeathModeOK: illegal player %d", pnum); + v3 = plr[v1]._pmode; + if ( v3 == PM_DEATH || v3 == PM_QUIT ) +LABEL_10: + result = 1; + else + result = v3 == PM_NEWLVL; + return result; +} + +//----- (0044F9FC) -------------------------------------------------------- +void __cdecl ValidatePlayer() +{ + int v0; // edi + int v1; // esi + char *v2; // eax + int v3; // ecx + int v4; // ecx + int *v5; // eax + int v6; // eax + int v7; // edx + int v8; // edx + int v9; // edx + int v10; // eax + int *v11; // ebx + signed int v12; // edi + char *v13; // eax + __int64 v14; // [esp+Ch] [ebp-8h] + + v0 = 0; + v14 = 0i64; + if ( (unsigned int)myplr >= 4 ) + TermMsg("ValidatePlayer: illegal player %d", myplr); + v1 = myplr; + v2 = &plr[myplr]._pLevel; + if ( *v2 > 50 ) + *v2 = 50; + v3 = plr[v1]._pNextExper; + if ( plr[v1]._pExperience > v3 ) + plr[v1]._pExperience = v3; + v4 = 0; + if ( plr[v1]._pNumInv > 0 ) + { + v5 = &plr[v1].InvList[0]._ivalue; + do + { + if ( *(v5 - 47) == 11 ) + { + if ( *v5 > 5000 ) + *v5 = 5000; + v4 += *v5; + } + ++v0; + v5 += 92; + } + while ( v0 < plr[v1]._pNumInv ); + } + if ( v4 != plr[v1]._pGold ) + plr[v1]._pGold = v4; + v6 = SLOBYTE(plr[v1]._pClass); + v7 = MaxStats[v6][0]; + if ( plr[v1]._pBaseStr > v7 ) + plr[v1]._pBaseStr = v7; + v8 = MaxStats[v6][1]; + if ( plr[v1]._pBaseMag > v8 ) + plr[v1]._pBaseMag = v8; + v9 = MaxStats[v6][2]; + if ( plr[v1]._pBaseDex > v9 ) + plr[v1]._pBaseDex = v9; + v10 = MaxStats[v6][3]; + if ( plr[v1]._pBaseVit > v10 ) + plr[v1]._pBaseVit = v10; + v11 = &spelldata[1].sBookLvl; + v12 = 1; + do + { + if ( *v11 != -1 ) + { + v14 |= 1i64 << ((unsigned char)v12 - 1); + v13 = &plr[v1]._pSplLvl[v12]; + if ( *v13 > 15 ) + *v13 = 15; + } + v11 += 14; + ++v12; + } + while ( (signed int)v11 < (signed int)"Blood Star" ); + *(_QWORD *)plr[v1]._pMemSpells &= v14; +} + +//----- (0044FB32) -------------------------------------------------------- +void __cdecl ProcessPlayers() +{ + int v0; // eax + int v1; // eax + char *v2; // ecx + char v3; // al + int v4; // ebp + int *v5; // esi + int v6; // eax + int v7; // eax + int v8; // eax + int v9; // eax + int v10; // eax + int v11; // edi + int v12; // eax + char *v13; // eax + char *v14; // eax + + v0 = myplr; + if ( (unsigned int)myplr >= 4 ) + { + TermMsg("ProcessPlayers: illegal player %d", myplr); + v0 = myplr; + } + v1 = v0; + v2 = &plr[v1].pLvlLoad; + v3 = plr[v1].pLvlLoad; + if ( v3 ) + *v2 = v3 - 1; + v4 = 0; + if ( sfxdelay > 0 && !--sfxdelay ) + PlaySFX(sfxdnum); + ValidatePlayer(); + v5 = &plr[0]._pHitPoints; + do + { + v6 = (int)(v5 - 89); + if ( *((_BYTE *)v5 - 379) && currlevel == *(_DWORD *)v6 && (v4 == myplr || !*(_BYTE *)(v6 + 267)) ) + { + CheckCheatStats(v4); + _LOBYTE(v7) = PlrDeathModeOK(v4); + if ( !v7 && (signed int)(*v5 & 0xFFFFFFC0) <= 0 ) + SyncPlrKill(v4, -1); + if ( v4 == myplr ) + { + if ( v5[5294] & 0x40 && currlevel ) + { + *v5 -= 4; + v8 = *v5; + *(v5 - 2) -= 4; + if ( (signed int)(v8 & 0xFFFFFFC0) <= 0 ) + SyncPlrKill(v4, 0); + drawhpflag = 1; + } + if ( *((_BYTE *)v5 + 21179) & 8 ) + { + v9 = v5[3]; + if ( v9 > 0 ) + { + v10 = v9 - v5[5]; + v5[5] = 0; + drawmanaflag = 1; + v5[3] = v10; + } + } + } + v11 = 0; + do + { + switch ( *(v5 - 102) ) + { + case PM_STAND: + v12 = PM_DoNothing(v4); + goto LABEL_38; + case PM_WALK: + v12 = PM_DoWalk(v4); + goto LABEL_38; + case PM_WALK2: + v12 = PM_DoWalk2(v4); + goto LABEL_38; + case PM_WALK3: + v12 = PM_DoWalk3(v4); + goto LABEL_38; + case PM_ATTACK: + v12 = PM_DoAttack(v4); + goto LABEL_38; + case PM_RATTACK: + v12 = PM_DoRangeAttack(v4); + goto LABEL_38; + case PM_BLOCK: + v12 = PM_DoBlock(v4); + goto LABEL_38; + case PM_GOTHIT: + v12 = PM_DoGotHit(v4); + goto LABEL_38; + case PM_DEATH: + v12 = PM_DoDeath(v4); + goto LABEL_38; + case PM_SPELL: + v12 = PM_DoSpell(v4); + goto LABEL_38; + case PM_NEWLVL: + v12 = PM_DoNothing(v4); +LABEL_38: + v11 = v12; + break; + default: + break; + } + CheckNewPath(v4); + } + while ( v11 ); + v13 = (char *)(v5 - 69); + ++*(_DWORD *)v13; + if ( *(v5 - 69) > *(v5 - 70) ) + { + *(_DWORD *)v13 = 0; + v14 = (char *)(v5 - 67); + ++*(_DWORD *)v14; + if ( *(v5 - 67) > *(v5 - 68) ) + *(_DWORD *)v14 = 1; + } + } + v5 += 5430; + ++v4; + } + while ( (signed int)v5 < (signed int)&plr_msgs[2].msg[51] ); +} +// 52A554: using guessed type int sfxdelay; + +//----- (0044FD31) -------------------------------------------------------- +void __fastcall CheckCheatStats(int pnum) +{ + int v1; // ecx + int *v2; // ecx + + v1 = pnum; + if ( plr[v1]._pStrength > 750 ) + plr[v1]._pStrength = 750; + if ( plr[v1]._pDexterity > 750 ) + plr[v1]._pDexterity = 750; + if ( plr[v1]._pMagic > 750 ) + plr[v1]._pMagic = 750; + if ( plr[v1]._pVitality > 750 ) + plr[v1]._pVitality = 750; + if ( plr[v1]._pHitPoints > 128000 ) + plr[v1]._pHitPoints = 128000; + v2 = &plr[v1]._pMana; + if ( *v2 > 128000 ) + *v2 = 128000; +} + +//----- (0044FD8A) -------------------------------------------------------- +void __fastcall ClrPlrPath(int pnum) +{ + int v1; // esi + + v1 = pnum; + if ( (unsigned int)pnum >= 4 ) + TermMsg("ClrPlrPath: illegal player %d", pnum); + memset(plr[v1].walkpath, -1, 0x19u); +} + +//----- (0044FDBA) -------------------------------------------------------- +int __fastcall PosOkPlayer(int pnum, int px, int py) +{ + int v3; // esi + int v4; // edi + int v5; // edx + int v6; // eax + int v7; // esi + char v8; // cl + unsigned int v9; // ecx + int v10; // esi + char v11; // al + char v12; // cl + int result; // eax + + v3 = px; + v4 = pnum; + result = 0; + if ( px >= 0 && px < 112 && py >= 0 && py < 112 && !SolidLoc(px, py) ) + { + v6 = v3; + v7 = 112 * v3 + v5; + if ( dPiece[0][v7] ) + { + v8 = dPlayer[v6][v5]; + if ( !v8 || (v8 <= 0 ? (v9 = -1 - v8) : (v9 = v8 - 1), v9 == v4 || v9 >= 4 || !plr[v9]._pHitPoints) ) + { + v10 = dMonster[0][v7]; + if ( !v10 || currlevel && v10 > 0 && (signed int)(monstactive[57 * v10 + 182] & 0xFFFFFFC0) <= 0 ) + { + v11 = dObject[v6][v5]; + if ( !v11 || (v11 <= 0 ? (v12 = -1 - v11) : (v12 = v11 - 1), !object[v12]._oSolidFlag) ) + result = 1; + } + } + } + } + return result; +} + +//----- (0044FE9E) -------------------------------------------------------- +void __fastcall MakePlrPath(int pnum, int xx, int yy, unsigned char endspace) +{ + int v4; // esi + int v5; // ebx + int v6; // esi + int v7; // edi + int v8; // eax + int v9; // eax + int v10; // ecx + int a2; // [esp+Ch] [ebp-4h] + + v4 = pnum; + v5 = xx; + a2 = pnum; + if ( (unsigned int)pnum >= 4 ) + TermMsg("MakePlrPath: illegal player %d", pnum); + v6 = v4; + v7 = yy; + v8 = plr[v6]._px; + plr[v6]._ptargx = v5; + plr[v6]._ptargy = yy; + if ( v8 != v5 || plr[v6]._py != yy ) + { + v9 = FindPath(PosOkPlayer, a2, v8, plr[v6]._py, v5, yy, plr[v6].walkpath); + if ( v9 ) + { + if ( !endspace ) + { + v10 = *((char *)&plr[v6]._pmode + v9-- + 3); + switch ( v10 ) + { + case PM_WALK: + goto LABEL_12; + case PM_WALK2: + ++v5; + break; + case PM_WALK3: + --v5; + break; + case PM_ATTACK: + goto LABEL_15; + case PM_RATTACK: + ++v5; + goto LABEL_12; + case PM_BLOCK: + --v5; +LABEL_12: + v7 = yy + 1; + break; + case PM_GOTHIT: + --v5; + goto LABEL_15; + case PM_DEATH: + ++v5; +LABEL_15: + v7 = yy - 1; + break; + default: + break; + } + plr[v6]._ptargx = v5; + plr[v6]._ptargy = v7; + } + plr[v6].walkpath[v9] = -1; + } + } +} + +//----- (0044FF6F) -------------------------------------------------------- +void __fastcall CheckPlrSpell() +{ + int v0; // ecx + int v1; // eax + int v2; // edx + char v3; // al + int v4; // ecx + char v5; // al + int v6; // eax + int v7; // edx + int v8; // esi + int v9; // ST10_4 + int v10; // eax + int v11; // eax + int v12; // eax + int v13; // ST10_4 + int v14; // eax + char v15; // al + + v0 = myplr; + if ( (unsigned int)myplr >= 4 ) + { + TermMsg("CheckPlrSpell: illegal player %d", myplr); + v0 = myplr; + } + v1 = 21720 * v0; + v2 = plr[v0]._pRSpell; + if ( v2 != -1 ) + { + if ( !leveltype && !*(_DWORD *)&spelldata[v2].sTownSpell ) + { + v5 = *((_BYTE *)&plr[0]._pClass + v1); + switch ( v5 ) + { + case UI_WARRIOR: + v4 = PS_WARR27; + goto LABEL_53; + case UI_ROGUE: + v4 = PS_ROGUE27; + goto LABEL_53; + case UI_SORCERER: + v4 = PS_MAGE27; + goto LABEL_53; + } + return; + } + if ( pcurs != CURSOR_HAND + || MouseY >= 352 + || (chrflag && MouseX < 320 || invflag && MouseX > 320) + && v2 != 2 + && v2 != 5 + && v2 != 26 + && v2 != 9 + && v2 != 27 ) + { + return; + } + _LOBYTE(v1) = *((_BYTE *)&plr[0]._pRSplType + v1); + if ( (v1 & 0x80u) != 0 ) + goto LABEL_46; + if ( (char)v1 <= 1 ) + { + _LOBYTE(v6) = CheckSpell(v0, v2, v1, 0); + } + else + { + if ( (_BYTE)v1 != 2 ) + { + if ( (_BYTE)v1 == 3 ) + { + UseStaff(); + goto LABEL_36; + } +LABEL_46: + if ( _LOBYTE(plr[v0]._pRSplType) == 1 ) + { + v15 = plr[v0]._pClass; + switch ( v15 ) + { + case UI_WARRIOR: + v4 = PS_WARR35; + goto LABEL_53; + case UI_ROGUE: + v4 = PS_ROGUE35; + goto LABEL_53; + case UI_SORCERER: + v4 = PS_MAGE35; + goto LABEL_53; + } + } + return; + } + UseScroll(); + } +LABEL_36: + v0 = myplr; + if ( v6 ) + { + v7 = plr[myplr]._pRSpell; + if ( v7 == 6 ) + { + v8 = GetDirection(plr[myplr].WorldX, plr[myplr].WorldY, cursmx, cursmy); + v9 = GetSpellLevel(myplr, plr[myplr]._pRSpell); + v10 = 21720 * myplr; + _LOWORD(v10) = plr[myplr]._pRSpell; + NetSendCmdLocParam3(1u, CMD_SPELLXYD, cursmx, cursmy, v10, v8, v9); + } + else if ( *(_DWORD *)&pcursmonst == -1 ) + { + if ( pcursplr == -1 ) + { + v13 = GetSpellLevel(myplr, v7); + v14 = 21720 * myplr; + _LOWORD(v14) = plr[myplr]._pRSpell; + NetSendCmdLocParam2(1u, CMD_SPELLXY, cursmx, cursmy, v14, v13); + } + else + { + v12 = GetSpellLevel(myplr, v7); + NetSendCmdParam3(1u, CMD_SPELLPID, pcursplr, plr[myplr]._pRSpell, v12); + } + } + else + { + v11 = GetSpellLevel(myplr, v7); + NetSendCmdParam3(1u, CMD_SPELLID, pcursmonst, plr[myplr]._pRSpell, v11); + } + return; + } + goto LABEL_46; + } + v3 = *((_BYTE *)&plr[0]._pClass + v1); + switch ( v3 ) + { + case UI_WARRIOR: + v4 = PS_WARR34; +LABEL_53: + PlaySFX(v4); + return; + case UI_ROGUE: + v4 = PS_ROGUE34; + goto LABEL_53; + case UI_SORCERER: + v4 = PS_MAGE34; + goto LABEL_53; + } +} +// 4B8CC2: using guessed type char pcursplr; +// 5BB1ED: using guessed type char leveltype; + +//----- (00450217) -------------------------------------------------------- +void __fastcall SyncPlrAnim(int pnum) +{ + int v1; // esi + int v2; // eax + int v3; // ecx + int v4; // ecx + int v5; // edx + + v1 = pnum; + if ( (unsigned int)pnum >= 4 ) + TermMsg("SyncPlrAnim: illegal player %d", pnum); + v2 = v1; + v3 = plr[v1]._pdir; + switch ( plr[v1]._pmode ) + { + case PM_STAND: + case PM_NEWLVL: + case PM_QUIT: + v4 = plr[0]._peqN[v3 + 5430 * v1]; + goto LABEL_19; + case PM_WALK: + case PM_WALK2: + case PM_WALK3: + v4 = plr[0]._peqW[v3 + 5430 * v1]; + goto LABEL_19; + case PM_ATTACK: + case PM_RATTACK: + v4 = plr[0]._peqA[v3 + 5430 * v1]; + goto LABEL_19; + case PM_BLOCK: + v4 = plr[0]._peqB[v3 + 5430 * v1]; + goto LABEL_19; + case PM_GOTHIT: + v4 = plr[0]._peqH[v3 + 5430 * v1]; + goto LABEL_19; + case PM_DEATH: + v4 = plr[0]._peqD[v3 + 5430 * v1]; + goto LABEL_19; + case PM_SPELL: + if ( v1 == myplr ) + v5 = (unsigned char)spelldata[plr[v2]._pSpell].sType; + else + v5 = 0; + if ( !v5 ) + plr[v2]._pAnimData = plr[0]._peqS1_FM[v3 + 5430 * v1]; + if ( v5 == STYPE_LIGHTNING ) + plr[v2]._pAnimData = plr[0]._peqS2_LM[v3 + 5430 * v1]; + if ( v5 == STYPE_MAGIC ) + { + v4 = plr[0]._peqS3_QM[v3 + 5430 * v1]; +LABEL_19: + plr[v2]._pAnimData = v4; + } + break; + default: + TermMsg("SyncPlrAnim"); + break; + } +} + +//----- (0045036D) -------------------------------------------------------- +void __fastcall SyncInitPlrPos(int pnum) +{ + int v1; // esi + bool v2; // zf + unsigned int v3; // eax + int v4; // ebx + int v5; // edi + int v6; // eax + signed int v7; // [esp+Ch] [ebp-18h] + int p; // [esp+10h] [ebp-14h] + int v9; // [esp+14h] [ebp-10h] + signed int v10; // [esp+18h] [ebp-Ch] + signed int v11; // [esp+1Ch] [ebp-8h] + unsigned int i; // [esp+20h] [ebp-4h] + signed int v13; // [esp+20h] [ebp-4h] + + p = pnum; + v1 = pnum; + v2 = gbMaxPlayers == 1; + plr[v1]._ptargx = plr[pnum].WorldX; + plr[v1]._ptargy = plr[pnum].WorldY; + if ( !v2 && plr[v1].plrlevel == currlevel ) + { + v3 = 0; + for ( i = 0; ; v3 = i ) + { + v4 = plr[v1].WorldX + *(int *)((char *)plrxoff2 + v3); + v5 = plr[v1].WorldY + *(int *)((char *)plryoff2 + v3); + if ( PosOkPlayer(p, v4, v5) ) + break; + i += 4; + if ( i >= 0x20 ) + break; + } + if ( !PosOkPlayer(p, v4, v5) ) + { + v11 = 0; + v6 = -1; + v13 = 1; + v7 = -1; + do + { + if ( v11 ) + break; + v9 = v6; + while ( v6 <= v13 && !v11 ) + { + v5 = v9 + plr[v1].WorldY; + v10 = v7; + do + { + if ( v11 ) + break; + v4 = v10 + plr[v1].WorldX; + if ( PosOkPlayer(p, v10 + plr[v1].WorldX, v5) && !portal_pos_ok(currlevel, v4, v5) ) + v11 = 1; + ++v10; + } + while ( v10 <= v13 ); + v6 = ++v9; + } + ++v13; + v6 = v7-- - 1; + } + while ( v7 > -50 ); + } + plr[v1].WorldX = v4; + v2 = p == myplr; + plr[v1].WorldY = v5; + dPlayer[v4][v5] = p + 1; + if ( v2 ) + { + plr[v1]._px = v4; + plr[v1]._py = v5; + plr[v1]._ptargx = v4; + plr[v1]._ptargy = v5; + ViewX = v4; + ViewY = v5; + } + } +} +// 679660: using guessed type char gbMaxPlayers; + +//----- (004504E4) -------------------------------------------------------- +void __fastcall SyncInitPlr(int pnum) +{ + int v1; // esi + + v1 = pnum; + if ( (unsigned int)pnum >= 4 ) + TermMsg("SyncInitPlr: illegal player %d", pnum); + SetPlrAnims(v1); + SyncInitPlrPos(v1); +} + +//----- (00450508) -------------------------------------------------------- +void __fastcall CheckStats(int pnum) +{ + int v1; // esi + int v2; // eax + char v3; // cl + signed int v4; // esi + signed int v5; // edi + int v6; // edx + int v7; // ecx + int v8; // edx + int v9; // ecx + int v10; // edx + int v11; // ecx + int v12; // edx + int v13; // ecx + signed int v14; // [esp+Ch] [ebp-4h] + + v1 = pnum; + if ( (unsigned int)pnum >= 4 ) + TermMsg("CheckStats: illegal player %d", pnum); + v2 = v1; + v3 = plr[v1]._pClass; + if ( v3 ) + { + if ( v3 == 1 ) + { + v4 = 1; + } + else if ( v3 == 2 ) + { + v4 = 2; + } + else + { + v4 = v14; + } + } + else + { + v4 = 0; + } + v5 = 0; + do + { + if ( v5 ) + { + switch ( v5 ) + { + case ATTRIB_MAG: + v10 = plr[v2]._pBaseMag; + v11 = MaxStats[v4][1]; + if ( v10 <= v11 ) + { + if ( v10 < 0 ) + plr[v2]._pBaseMag = 0; + } + else + { + plr[v2]._pBaseMag = v11; + } + break; + case ATTRIB_DEX: + v8 = plr[v2]._pBaseDex; + v9 = MaxStats[v4][2]; + if ( v8 <= v9 ) + { + if ( v8 < 0 ) + plr[v2]._pBaseDex = 0; + } + else + { + plr[v2]._pBaseDex = v9; + } + break; + case ATTRIB_VIT: + v6 = plr[v2]._pBaseVit; + v7 = MaxStats[v4][3]; + if ( v6 <= v7 ) + { + if ( v6 < 0 ) + plr[v2]._pBaseVit = 0; + } + else + { + plr[v2]._pBaseVit = v7; + } + break; + } + } + else + { + v12 = plr[v2]._pBaseStr; + v13 = MaxStats[v4][0]; + if ( v12 <= v13 ) + { + if ( v12 < 0 ) + plr[v2]._pBaseStr = 0; + } + else + { + plr[v2]._pBaseStr = v13; + } + } + ++v5; + } + while ( v5 < 4 ); +} + +//----- (00450621) -------------------------------------------------------- +void __fastcall ModifyPlrStr(int pnum, int l) +{ + int v2; // esi + int v3; // edi + int v4; // esi + char v5; // dl + int v6; // ecx + int v7; // eax + int v8; // ebx + int v9; // eax + signed int v10; // ecx + int p; // [esp+8h] [ebp-4h] + + v2 = pnum; + v3 = l; + p = pnum; + if ( (unsigned int)pnum >= 4 ) + TermMsg("ModifyPlrStr: illegal player %d", pnum); + v4 = v2; + v5 = plr[v4]._pClass; + v6 = plr[v4]._pBaseStr; + v7 = MaxStats[v5][0]; + if ( v6 + v3 > v7 ) + v3 = v7 - v6; + plr[v4]._pBaseStr = v3 + v6; + plr[v4]._pStrength += v3; + v8 = plr[v4]._pStrength; + if ( v5 == 1 ) + { + v9 = plr[v4]._pLevel * (v8 + plr[v4]._pDexterity); + v10 = 200; + } + else + { + v9 = v8 * plr[v4]._pLevel; + v10 = 100; + } + plr[v4]._pDamageMod = v9 / v10; + CalcPlrInv(p, 1u); + if ( p == myplr ) + NetSendCmdParam1(0, CMD_SETSTR, plr[v4]._pBaseStr); +} + +//----- (004506DB) -------------------------------------------------------- +void __fastcall ModifyPlrMag(int pnum, int l) +{ + int v2; // esi + int v3; // edi + int v4; // esi + char v5; // dl + int v6; // ecx + int v7; // eax + int v8; // eax + int v9; // edi + int p; // [esp+8h] [ebp-4h] + + v2 = pnum; + v3 = l; + p = pnum; + if ( (unsigned int)pnum >= 4 ) + TermMsg("ModifyPlrMag: illegal player %d", pnum); + v4 = v2; + v5 = plr[v4]._pClass; + v6 = MaxStats[v5][1]; + v7 = plr[v4]._pBaseMag; + if ( v7 + v3 > v6 ) + v3 = v6 - v7; + plr[v4]._pMagic += v3; + v8 = v3 + v7; + v9 = v3 << 6; + plr[v4]._pBaseMag = v8; + if ( v5 == 2 ) + v9 *= 2; + plr[v4]._pMaxManaBase += v9; + plr[v4]._pMaxMana += v9; + if ( !(plr[v4]._pIFlags & 0x8000000) ) + { + plr[v4]._pManaBase += v9; + plr[v4]._pMana += v9; + } + CalcPlrInv(p, 1u); + if ( p == myplr ) + NetSendCmdParam1(0, CMD_SETMAG, plr[v4]._pBaseMag); +} + +//----- (00450788) -------------------------------------------------------- +void __fastcall ModifyPlrDex(int pnum, int l) +{ + int v2; // ebx + int v3; // edi + int v4; // esi + int v5; // ecx + int v6; // eax + + v2 = pnum; + v3 = l; + if ( (unsigned int)pnum >= 4 ) + TermMsg("ModifyPlrDex: illegal player %d", pnum); + v4 = v2; + v5 = MaxStats[SLOBYTE(plr[v2]._pClass)][2]; + v6 = plr[v2]._pBaseDex; + if ( v6 + v3 > v5 ) + v3 = v5 - v6; + plr[v4]._pDexterity += v3; + plr[v4]._pBaseDex = v3 + v6; + CalcPlrInv(v2, 1u); + if ( _LOBYTE(plr[v4]._pClass) == 1 ) + plr[v4]._pDamageMod = plr[v4]._pLevel * (plr[v4]._pDexterity + plr[v4]._pStrength) / 200; + if ( v2 == myplr ) + NetSendCmdParam1(0, CMD_SETDEX, plr[v4]._pBaseDex); +} + +//----- (0045082C) -------------------------------------------------------- +void __fastcall ModifyPlrVit(int pnum, int l) +{ + int v2; // esi + int v3; // edi + int v4; // esi + char v5; // dl + int v6; // ecx + int v7; // eax + int v8; // eax + int v9; // edi + int p; // [esp+8h] [ebp-4h] + + v2 = pnum; + v3 = l; + p = pnum; + if ( (unsigned int)pnum >= 4 ) + TermMsg("ModifyPlrVit: illegal player %d", pnum); + v4 = v2; + v5 = plr[v4]._pClass; + v6 = MaxStats[v5][3]; + v7 = plr[v4]._pBaseVit; + if ( v7 + v3 > v6 ) + v3 = v6 - v7; + plr[v4]._pVitality += v3; + v8 = v3 + v7; + v9 = v3 << 6; + plr[v4]._pBaseVit = v8; + if ( !v5 ) + v9 *= 2; + plr[v4]._pHPBase += v9; + plr[v4]._pMaxHPBase += v9; + plr[v4]._pHitPoints += v9; + plr[v4]._pMaxHP += v9; + CalcPlrInv(p, 1u); + if ( p == myplr ) + NetSendCmdParam1(0, CMD_SETVIT, plr[v4]._pBaseVit); +} + +//----- (004508CF) -------------------------------------------------------- +void __fastcall SetPlayerHitPoints(int pnum, int newhp) +{ + int v2; // esi + int v3; // edi + int v4; // eax + int v5; // ecx + bool v6; // zf + + v2 = pnum; + v3 = newhp; + if ( (unsigned int)pnum >= 4 ) + TermMsg("SetPlayerHitPoints: illegal player %d", pnum); + v4 = v2; + v5 = plr[v2]._pMaxHPBase; + plr[v4]._pHitPoints = v3; + v6 = v2 == myplr; + plr[v4]._pHPBase = v3 + v5 - plr[v2]._pMaxHP; + if ( v6 ) + drawhpflag = 1; +} + +//----- (0045091E) -------------------------------------------------------- +void __fastcall SetPlrStr(int pnum, int v) +{ + int v2; // edi + int v3; // ebx + int v4; // esi + int v5; // eax + signed int v6; // ecx + + v2 = pnum; + v3 = v; + if ( (unsigned int)pnum >= 4 ) + TermMsg("SetPlrStr: illegal player %d", pnum); + v4 = v2; + plr[v2]._pBaseStr = v3; + CalcPlrInv(v2, 1u); + if ( _LOBYTE(plr[v2]._pClass) == 1 ) + { + v5 = plr[v4]._pLevel * (plr[v4]._pStrength + plr[v4]._pDexterity); + v6 = 200; + } + else + { + v5 = plr[v4]._pStrength * plr[v4]._pLevel; + v6 = 100; + } + plr[v4]._pDamageMod = v5 / v6; +} + +//----- (00450993) -------------------------------------------------------- +void __fastcall SetPlrMag(int pnum, int v) +{ + int v2; // edi + int v3; // esi + int v4; // eax + int v5; // esi + + v2 = pnum; + v3 = v; + if ( (unsigned int)pnum >= 4 ) + TermMsg("SetPlrMag: illegal player %d", pnum); + v4 = v2; + plr[v2]._pBaseMag = v3; + v5 = v3 << 6; + if ( _LOBYTE(plr[v2]._pClass) == 2 ) + v5 *= 2; + plr[v4]._pMaxManaBase = v5; + plr[v4]._pMaxMana = v5; + CalcPlrInv(v2, 1u); +} + +//----- (004509DF) -------------------------------------------------------- +void __fastcall SetPlrDex(int pnum, int v) +{ + int v2; // edi + int v3; // ebx + int v4; // esi + int v5; // eax + signed int v6; // ecx + + v2 = pnum; + v3 = v; + if ( (unsigned int)pnum >= 4 ) + TermMsg("SetPlrDex: illegal player %d", pnum); + v4 = v2; + plr[v2]._pBaseDex = v3; + CalcPlrInv(v2, 1u); + if ( _LOBYTE(plr[v2]._pClass) == 1 ) + { + v5 = plr[v4]._pLevel * (plr[v4]._pStrength + plr[v4]._pDexterity); + v6 = 200; + } + else + { + v5 = plr[v4]._pStrength * plr[v4]._pLevel; + v6 = 100; + } + plr[v4]._pDamageMod = v5 / v6; +} + +//----- (00450A54) -------------------------------------------------------- +void __fastcall SetPlrVit(int pnum, int v) +{ + int v2; // edi + int v3; // esi + int v4; // eax + int v5; // esi + + v2 = pnum; + v3 = v; + if ( (unsigned int)pnum >= 4 ) + TermMsg("SetPlrVit: illegal player %d", pnum); + v4 = v2; + plr[v2]._pBaseVit = v3; + v5 = v3 << 6; + if ( !_LOBYTE(plr[v2]._pClass) ) + v5 *= 2; + plr[v4]._pHPBase = v5; + plr[v4]._pMaxHPBase = v5; + CalcPlrInv(v2, 1u); +} + +//----- (00450AA0) -------------------------------------------------------- +void __fastcall InitDungMsgs(int pnum) +{ + int v1; // esi + + v1 = pnum; + if ( (unsigned int)pnum >= 4 ) + TermMsg("InitDungMsgs: illegal player %d", pnum); + plr[v1].pDungMsgs = 0; +} + +//----- (00450AC4) -------------------------------------------------------- +void __cdecl PlayDungMsgs() +{ + int v0; // eax + int v1; // eax + char v2; // cl + char v3; // dl + char v4; // cl + char v5; // cl + char v6; // dl + char v7; // cl + char v8; // dl + char v9; // cl + char v10; // dl + char v11; // cl + char v12; // dl + + v0 = myplr; + if ( (unsigned int)myplr >= 4 ) + { + TermMsg("PlayDungMsgs: illegal player %d", myplr); + v0 = myplr; + } + switch ( currlevel ) + { + case 1u: + v1 = v0; + if ( !plr[v1]._pLvlVisited[1] && gbMaxPlayers == currlevel ) + { + v2 = plr[v1].pDungMsgs; + if ( !(v2 & 1) ) + { + v3 = plr[v1]._pClass; + sfxdelay = 40; + if ( v3 ) + { + if ( v3 == 1 ) + { + sfxdnum = PS_ROGUE97; + } + else if ( v3 == 2 ) + { + sfxdnum = PS_MAGE97; + } + } + else + { + sfxdnum = PS_WARR97; + } + v4 = v2 | 1; +LABEL_14: + plr[v1].pDungMsgs = v4; + return; + } + } + break; + case 5u: + v1 = v0; + if ( !plr[v1]._pLvlVisited[5] && gbMaxPlayers == 1 ) + { + v5 = plr[v1].pDungMsgs; + if ( !(v5 & 2) ) + { + v6 = plr[v1]._pClass; + sfxdelay = 40; + if ( v6 ) + { + if ( v6 == 1 ) + { + sfxdnum = PS_ROGUE96; + } + else if ( v6 == 2 ) + { + sfxdnum = PS_MAGE96; + } + } + else + { + sfxdnum = PS_WARR96B; + } + v4 = v5 | 2; + goto LABEL_14; + } + } + break; + case 9u: + v1 = v0; + if ( !plr[v1]._pLvlVisited[9] && gbMaxPlayers == 1 ) + { + v7 = plr[v1].pDungMsgs; + if ( !(v7 & 4) ) + { + v8 = plr[v1]._pClass; + sfxdelay = 40; + if ( v8 ) + { + if ( v8 == 1 ) + { + sfxdnum = PS_ROGUE98; + } + else if ( v8 == 2 ) + { + sfxdnum = PS_MAGE98; + } + } + else + { + sfxdnum = PS_WARR98; + } + v4 = v7 | 4; + goto LABEL_14; + } + } + break; + case 13u: + v1 = v0; + if ( !plr[v1]._pLvlVisited[13] && gbMaxPlayers == 1 ) + { + v9 = plr[v1].pDungMsgs; + if ( !(v9 & 8) ) + { + v10 = plr[v1]._pClass; + sfxdelay = 40; + if ( v10 ) + { + if ( v10 == 1 ) + { + sfxdnum = PS_ROGUE99; + } + else if ( v10 == 2 ) + { + sfxdnum = PS_MAGE99; + } + } + else + { + sfxdnum = PS_WARR99; + } + v4 = v9 | 8; + goto LABEL_14; + } + } + break; + case 16u: + v1 = v0; + if ( !plr[v1]._pLvlVisited[15] && gbMaxPlayers == 1 ) + { + v11 = plr[v1].pDungMsgs; + if ( !(v11 & 0x10) ) + { + v12 = plr[v1]._pClass; + sfxdelay = 40; + if ( !v12 || v12 == 1 || v12 == 2 ) + sfxdnum = PS_DIABLVLINT; + v4 = v11 | 0x10; + goto LABEL_14; + } + } + break; + } + sfxdelay = 0; +} +// 52A554: using guessed type int sfxdelay; +// 679660: using guessed type char gbMaxPlayers; + +//----- (00450D33) -------------------------------------------------------- +void __fastcall plrmsg_delay(int a1) +{ + _plrmsg *v1; // eax + signed int v2; // ecx + + if ( a1 ) + { + plrmsg_ticks = -GetTickCount(); + } + else + { + plrmsg_ticks += GetTickCount(); + v1 = plr_msgs; + v2 = 8; + do + { + v1->time += plrmsg_ticks; + ++v1; + --v2; + } + while ( v2 ); + } +} +// 69B7D0: using guessed type int plrmsg_ticks; + +//----- (00450D6A) -------------------------------------------------------- +char *__fastcall ErrorPlrMsg(char *a1) +{ + _plrmsg *v1; // esi + char *v2; // edi + char *result; // eax + + v1 = &plr_msgs[(unsigned char)plr_msg_slot]; + v2 = a1; + plr_msg_slot = (plr_msg_slot + 1) & 7; + v1->player = 4; + v1->time = GetTickCount(); + result = strncpy(v1->msg, v2, 0x90u); + v1->msg[143] = 0; + return result; +} +// 69B7D4: using guessed type char plr_msg_slot; + +//----- (00450DB3) -------------------------------------------------------- +size_t EventPlrMsg(char *szMsg, ...) +{ + char *v1; // esi + va_list va; // [esp+Ch] [ebp+8h] + + va_start(va, szMsg); + v1 = (char *)&plr_msgs[(unsigned char)plr_msg_slot]; + plr_msg_slot = (plr_msg_slot + 1) & 7; + v1[4] = 4; + *(_DWORD *)v1 = GetTickCount(); + v1 += 5; + vsprintf(v1, szMsg, va); + return strlen(v1); +} +// 69B7D4: using guessed type char plr_msg_slot; + +//----- (00450DFA) -------------------------------------------------------- +void __fastcall SendPlrMsg(int pnum, const char *szMsg) +{ + _plrmsg *v2; // esi + int v3; // ebx + const char *v4; // ebp + int v5; // edi + const char *v6; // ebx + + v2 = &plr_msgs[(unsigned char)plr_msg_slot]; + v3 = pnum; + v4 = szMsg; + plr_msg_slot = (plr_msg_slot + 1) & 7; + v2->player = pnum; + v2->time = GetTickCount(); + v5 = v3; + v6 = plr[v3]._pName; + strlen(v6); + strlen(v4); + sprintf(v2->msg, "%s (lvl %d): %s", v6, plr[v5]._pLevel, v4); +} +// 69B7D4: using guessed type char plr_msg_slot; + +//----- (00450E64) -------------------------------------------------------- +void __cdecl ClearPlrMsg() +{ + _plrmsg *v0; // esi + DWORD v1; // eax + signed int v2; // ecx + + v0 = plr_msgs; + v1 = GetTickCount(); + v2 = 8; + do + { + if ( (signed int)(v1 - v0->time) > 10000 ) + v0->msg[0] = 0; + ++v0; + --v2; + } + while ( v2 ); +} + +//----- (00450E8E) -------------------------------------------------------- +void __cdecl InitPlrMsg() +{ + memset(plr_msgs, 0, 0x4C0u); + plr_msg_slot = 0; +} +// 69B7D4: using guessed type char plr_msg_slot; + +//----- (00450EAA) -------------------------------------------------------- +void __cdecl DrawPlrMsg() +{ + int v0; // ebx + int v1; // ebp + int v2; // edi + char *v3; // esi + signed int v4; // [esp+Ch] [ebp-4h] + + v0 = 74; + v1 = 230; + v2 = 620; + if ( chrflag || questlog ) + { + if ( invflag || sbookflag ) + return; + v0 = 394; + goto LABEL_9; + } + if ( invflag || sbookflag ) +LABEL_9: + v2 = 300; + v3 = plr_msgs[0].msg; + v4 = 8; + do + { + if ( *v3 ) + PrintPlrMsg(v0, v1, v2, v3, *((unsigned char *)text_color_from_player_num + (unsigned char)*(v3 - 1))); + v3 += 152; + v1 += 35; + --v4; + } + while ( v4 ); +} +// 4B8968: using guessed type int sbookflag; +// 69BD04: using guessed type int questlog; + +//----- (00450F37) -------------------------------------------------------- +void __fastcall PrintPlrMsg(int no, int x, int y, char *str, int just) +{ + char *v5; // edi + int *v6; // edx + int v7; // esi + char *v8; // edx + int v9; // esi + unsigned int v10; // eax + unsigned char v11; // cl + unsigned char v12; // cl + int v13; // eax + unsigned char v14; // bl + int v15; // [esp+Ch] [ebp-Ch] + int *v16; // [esp+10h] [ebp-8h] + int v17; // [esp+14h] [ebp-4h] + char *stra; // [esp+24h] [ebp+Ch] + + v17 = 0; + v5 = str; + v15 = no; + if ( *str ) + { + v6 = &screen_y_times_768[x]; + v16 = v6; + do + { + v7 = *v6; + v8 = v5; + v9 = v15 + v7; + v10 = 0; + stra = v5; + while ( 1 ) + { + v11 = *v8; + if ( !*v8 ) + break; + ++v8; + v12 = fontframe[fontidx[v11]]; + v10 += fontkern[v12] + 1; + if ( v12 ) + { + if ( v10 >= y ) + goto LABEL_13; + } + else + { + stra = v8; + } + } + stra = v8; +LABEL_13: + while ( v5 < stra ) + { + v13 = (unsigned char)*v5++; + v14 = fontframe[fontidx[v13]]; + if ( v14 ) + CPrintString(v9, (char *)v14, just); + v9 += fontkern[v14] + 1; + } + v6 = v16 + 10; + ++v17; + v16 += 10; + } + while ( v17 != 3 && *v5 ); + } +} + +//----- (00450FFE) -------------------------------------------------------- +void __cdecl InitPortals() +{ + int v0; // edi + PortalStruct *v1; // esi + int v2; // eax + + v0 = 0; + v1 = portal; + do + { + _LOBYTE(v2) = delta_portal_inited(v0); + if ( v2 ) + v1->open = 0; + ++v1; + ++v0; + } + while ( (signed int)v1 < (signed int)&portalindex ); +} + +//----- (00451024) -------------------------------------------------------- +void __fastcall SetPortalStats(int i, int o, int x, int y, int lvl, int lvltype) +{ + int v6; // eax + + v6 = i; + portal[v6].x = x; + portal[v6].setlvl = 0; + portal[v6].y = y; + portal[v6].open = o; + portal[v6].level = lvl; + portal[v6].ltype = lvltype; +} + +//----- (00451062) -------------------------------------------------------- +void __fastcall AddWarpMissile(int i, int x, int y) +{ + int v3; // eax + int v4; // esi + + missiledata[10].mlSFX = -1; + dMissile[x][y] = 0; + v3 = AddMissile(0, 0, x, y, 0, 10, 0, i, 0, 0); + v4 = v3; + if ( v3 != -1 ) + { + SetMissDir(v3, 1); + if ( currlevel ) + missile[v4]._mlid = AddLight(missile[v4]._mix, missile[v4]._miy, 15); + missiledata[10].mlSFX = 129; + } +} + +//----- (004510D6) -------------------------------------------------------- +void __cdecl SyncPortals() +{ + int v0; // edi + int *v1; // esi + int v2; // eax + + v0 = 0; + v1 = &portal[0].level; + do + { + if ( *(v1 - 3) ) + { + if ( currlevel ) + { + v2 = currlevel; + if ( setlevel ) + v2 = (unsigned char)setlvlnum; + if ( *v1 == v2 ) + AddWarpMissile(v0, *(v1 - 2), *(v1 - 1)); + } + else + { + AddWarpMissile(v0, WarpDropX[v0], WarpDropY[v0]); + } + } + v1 += 6; + ++v0; + } + while ( (signed int)v1 < (signed int)&questlog ); +} +// 5CCB10: using guessed type char setlvlnum; +// 5CF31D: using guessed type char setlevel; +// 69BD04: using guessed type int questlog; + +//----- (00451131) -------------------------------------------------------- +void __fastcall AddInTownPortal(int i) +{ + AddWarpMissile(i, WarpDropX[i], WarpDropY[i]); +} + +//----- (00451145) -------------------------------------------------------- +void __fastcall ActivatePortal(int i, int x, int y, int lvl, int lvltype, int sp) +{ + int v6; // eax + + v6 = i; + portal[i].open = 1; + if ( lvl ) + { + portal[v6].level = lvl; + portal[v6].x = x; + portal[v6].ltype = lvltype; + portal[v6].y = y; + portal[v6].setlvl = sp; + } +} + +//----- (0045118A) -------------------------------------------------------- +void __fastcall DeactivatePortal(int i) +{ + portal[i].open = 0; +} + +//----- (00451196) -------------------------------------------------------- +int __fastcall PortalOnLevel(int i) +{ + int result; // eax + + if ( portal[i].level == currlevel ) + result = 1; + else + result = currlevel == 0; + return result; +} + +//----- (004511B8) -------------------------------------------------------- +void __fastcall RemovePortalMissile(int id) +{ + int v1; // edi + int i; // esi + int v3; // ebx + int v4; // eax + int v5; // ecx + + v1 = 0; + for ( i = id; v1 < nummissiles; ++v1 ) + { + v3 = missileactive[v1]; + v4 = missileactive[v1]; + if ( missile[v4]._mitype == 10 && missile[v4]._misource == i ) + { + v5 = missile[v4]._miy + 112 * missile[v4]._mix; + dFlags[0][v5] &= 0xFEu; + dMissile[0][v5] = 0; + if ( portal[i].level ) + AddUnLight(missile[v4]._mlid); + DeleteMissile(v3, v1); + } + } +} + +//----- (00451234) -------------------------------------------------------- +void __fastcall SetCurrentPortal(int p) +{ + portalindex = p; +} + +//----- (0045123B) -------------------------------------------------------- +void __cdecl GetPortalLevel() +{ + int v0; // eax + unsigned char v1; // cl + char v2; // al + bool v3; // zf + + if ( currlevel ) + { + setlevel = 0; + currlevel = 0; + leveltype = 0; + plr[myplr].plrlevel = 0; + } + else + { + v0 = portalindex; + if ( portal[portalindex].setlvl ) + { + v1 = portal[v0].level; + setlevel = 1; + setlvlnum = v1; + } + else + { + setlevel = 0; + v1 = portal[v0].level; + } + v2 = portal[v0].ltype; + v3 = portalindex == myplr; + currlevel = v1; + leveltype = v2; + plr[myplr].plrlevel = v1; + if ( v3 ) + { + NetSendCmd(1u, CMD_DEACTIVATEPORTAL); + DeactivatePortal(portalindex); + } + } +} +// 5BB1ED: using guessed type char leveltype; +// 5CCB10: using guessed type char setlvlnum; +// 5CF31D: using guessed type char setlevel; + +//----- (004512E3) -------------------------------------------------------- +void __cdecl GetPortalLvlPos() +{ + int v0; // eax + int v1; // eax + + if ( currlevel ) + { + v1 = portal[portalindex].y; + ViewX = portal[portalindex].x; + ViewY = v1; + if ( portalindex != myplr ) + { + ++ViewX; + ++ViewY; + } + } + else + { + v0 = WarpDropY[portalindex] + 1; + ViewX = WarpDropX[portalindex] + 1; + ViewY = v0; + } +} + +//----- (00451346) -------------------------------------------------------- +int __fastcall portal_pos_ok(int level, int x, int y) +{ + int *v3; // eax + + v3 = &portal[0].x; + while ( !*(v3 - 1) || v3[2] != level || (*v3 != x || v3[1] != y) && (*v3 != x - 1 || v3[1] != y - 1) ) + { + v3 += 6; + if ( (signed int)v3 >= (signed int)&END_portalstruct ) + return 0; + } + return 1; +} +// 69BCFC: using guessed type int END_portalstruct; + +//----- (0045138E) -------------------------------------------------------- +void __cdecl InitQuests() +{ + char v0; // dl + char *v1; // esi + char *v2; // eax + char *v3; // ecx + unsigned char *v4; // eax + int v5; // ebp + unsigned int v6; // edi + int v7; // eax + unsigned char v8; // al + unsigned char v9; // al + char v10; // al + int v11; // ecx + int v12; // ecx + int v13; // eax + int v14; // ecx + int v15; // eax + int v16; // ecx + int v17; // eax + int v18; // ecx + int v19; // eax + char v20; // [esp+8h] [ebp-4h] + + v0 = gbMaxPlayers; + v1 = &quests[0]._qactive; + if ( gbMaxPlayers == 1 ) + { + v2 = &quests[0]._qactive; + do + { + *v2 = 0; + v2 += 24; + } + while ( (signed int)v2 < (signed int)&qline + 2 ); + } + else + { + v3 = &quests[0]._qactive; + v4 = &questlist[0]._qflags; + do + { + if ( !(*v4 & 1) ) + *v3 = 0; + v4 += 20; + v3 += 24; + } + while ( (signed int)v4 < (signed int)questyoff ); + } + v5 = 0; + questlog = 0; + ALLQUESTS = 1; + WaterDone = 0; + v20 = 0; + v6 = 0; + do + { + if ( (unsigned char)v0 <= 1u || questlist[v6]._qflags & 1 ) + { + *(v1 - 1) = questlist[v6]._qdtype; + if ( (unsigned char)v0 <= 1u ) + { + v8 = questlist[v6]._qdlvl; + *v1 = 1; + *(v1 - 2) = v8; + v1[13] = 0; + *(_DWORD *)(v1 + 18) = 0; + } + else + { + *(v1 - 2) = questlist[v6]._qdmultlvl; + _LOBYTE(v7) = delta_quest_inited(v5); + if ( !v7 ) + { + *v1 = 1; + v1[13] = 0; + *(_DWORD *)(v1 + 18) = 0; + } + v0 = gbMaxPlayers; + ++v5; + } + v9 = questlist[v6]._qslvl; + *(_DWORD *)(v1 + 2) = 0; + v1[10] = v9; + v1[11] = v20; + v1[1] = questlist[v6]._qlvlt; + v10 = questlist[v6]._qdmsg; + *(_DWORD *)(v1 + 6) = 0; + v1[14] = 0; + v1[12] = v10; + } + ++v20; + ++v6; + v1 += 24; + } + while ( v6 < 16 ); + if ( v0 == 1 ) + { + SetRndSeed(glSeedTbl[15]); + _LOBYTE(v11) = 0; + if ( random(v11, 2) ) + quests[13]._qactive = 0; + else + quests[12]._qactive = 0; + _LOBYTE(v12) = 0; + v13 = random(v12, 3); + _LOBYTE(v14) = 0; + quests[QuestGroup1[v13]]._qactive = 0; + v15 = random(v14, 3); + _LOBYTE(v16) = 0; + quests[QuestGroup2[v15]]._qactive = 0; + v17 = random(v16, 3); + _LOBYTE(v18) = 0; + quests[QuestGroup3[v17]]._qactive = 0; + v19 = random(v18, 2); + v0 = gbMaxPlayers; + quests[QuestGroup4[v19]]._qactive = 0; + } + if ( !quests[12]._qactive ) + quests[12]._qvar2 = 2; + if ( !quests[0]._qactive ) + quests[0]._qvar2 = 2; + quests[7]._qvar1 = 1; + if ( v0 != 1 ) + quests[15]._qvar1 = 2; +} +// 679660: using guessed type char gbMaxPlayers; +// 69BD04: using guessed type int questlog; +// 69BE90: using guessed type int qline; + +//----- (0045155C) -------------------------------------------------------- +void __cdecl CheckQuests() +{ + int v0; // eax + char *v1; // esi + unsigned char v2; // cl + + _LOBYTE(v0) = QuestStatus(15); + if ( v0 ) + { + if ( gbMaxPlayers == 1 ) + goto LABEL_6; + if ( quests[15]._qvar1 == 2 ) + { + AddObject(83, 2 * setpc_x + 20, 2 * setpc_y + 22); + quests[15]._qvar1 = 3; + NetSendCmdQuest(1u, 0xFu); + } + } + if ( gbMaxPlayers != 1 ) + return; +LABEL_6: + if ( currlevel == quests[15]._qlevel && !setlevel && quests[15]._qvar1 >= 2u ) + { + if ( quests[15]._qactive != 2 && quests[15]._qactive != 3 ) + goto LABEL_29; + if ( !quests[15]._qvar2 || quests[15]._qvar2 == 2 ) + { + quests[15]._qtx = 2 * quests[15]._qtx + 16; + quests[15]._qty = 2 * quests[15]._qty + 16; + AddMissile(quests[15]._qtx, quests[15]._qty, quests[15]._qtx, quests[15]._qty, 0, 65, 0, myplr, 0, 0); + quests[15]._qvar2 = 1; + if ( quests[15]._qactive == 2 ) + quests[15]._qvar1 = 3; + } + } + if ( quests[15]._qactive == 3 ) + { + if ( !setlevel ) + goto LABEL_29; + if ( setlvlnum == SL_VILEBETRAYER && quests[15]._qvar2 == 4 ) + { + AddMissile(35, 32, 35, 32, 0, 65, 0, myplr, 0, 0); + quests[15]._qvar2 = 3; + } + } + if ( setlevel ) + { + if ( setlvlnum == quests[13]._qslvl + && quests[13]._qactive != 1 + && leveltype == quests[13]._qlvltype + && nummonsters == 4 + && quests[13]._qactive != 3 ) + { + quests[13]._qactive = 3; + PlaySfxLoc(IS_QUESTDN, plr[myplr].WorldX, plr[myplr].WorldY); + LoadPalette("Levels\\L3Data\\L3pwater.pal"); + WaterDone = 32; + } + if ( WaterDone > 0 ) + { + palette_update_quest_palette(WaterDone); + --WaterDone; + } + return; + } +LABEL_29: + if ( plr[myplr]._pmode == PM_STAND ) + { + v1 = &quests[0]._qactive; + do + { + if ( currlevel == *(v1 - 2) ) + { + v2 = v1[10]; + if ( v2 ) + { + if ( *v1 && plr[myplr].WorldX == *(_DWORD *)(v1 + 2) && plr[myplr].WorldY == *(_DWORD *)(v1 + 6) ) + { + if ( v1[1] != -1 ) + setlvltype = v1[1]; + StartNewLvl(myplr, WM_DIABSETLVL, v2); + } + } + } + v1 += 24; + } + while ( (signed int)v1 < (signed int)&qline + 2 ); + } +} +// 5BB1ED: using guessed type char leveltype; +// 5CCB10: using guessed type char setlvlnum; +// 5CF31C: using guessed type char setlvltype; +// 5CF31D: using guessed type char setlevel; +// 679660: using guessed type char gbMaxPlayers; +// 69BE90: using guessed type int qline; + +//----- (0045178F) -------------------------------------------------------- +int __cdecl ForceQuests() +{ + QuestStruct *v0; // eax + int v1; // esi + int v2; // edi + int v3; // edx + + if ( gbMaxPlayers != 1 ) + return 0; + v0 = (QuestStruct *)((char *)quests + 12); + while ( v0 == (QuestStruct *)&quests[15]._qslvl || currlevel != v0[-1]._qslvl || !v0->_qlevel ) + { +LABEL_10: + ++v0; + if ( (signed int)v0 >= (signed int)&qlist[2] ) + return 0; + } + v1 = *(_DWORD *)&v0[-1]._qvar2; + v2 = v0[-1]._qlog; + v3 = 0; + while ( v1 + (char)questxoff[v3] != cursmx || v2 + (char)questyoff[v3] != cursmy ) + { + if ( ++v3 >= 7 ) + goto LABEL_10; + } + sprintf(infostr, "To %s", questtrigstr[(unsigned char)quests[(unsigned char)v0->_qtype]._qslvl - 1]); + cursmx = v1; + cursmy = v2; + return 1; +} +// 679660: using guessed type char gbMaxPlayers; + +//----- (00451831) -------------------------------------------------------- +bool __fastcall QuestStatus(int i) +{ + bool result; // al + + if ( setlevel + || currlevel != quests[i]._qlevel + || !quests[i]._qactive + || (result = 1, gbMaxPlayers != 1) && !(questlist[i]._qflags & 1) ) + { + result = 0; + } + return result; +} +// 5CF31D: using guessed type char setlevel; +// 679660: using guessed type char gbMaxPlayers; + +//----- (00451871) -------------------------------------------------------- +void __fastcall CheckQuestKill(int m, unsigned char sendmsg) +{ + int v2; // ecx + char v3; // al + char v4; // al + unsigned char v5; // dl + char v6; // al + char *v7; // ecx + char v8; // al + char v9; // al + int v10; // edi + int (*v11)[112]; // esi + signed int v12; // ecx + int *v13; // eax + int (*v14)[112]; // ebx + char v15; // al + char v16; // al + char v17; // al + + v2 = m; + v3 = monster[v2].MType->mtype; + if ( v3 == MON_SKING ) + { + quests[12]._qactive = 3; + sfxdelay = 30; + v4 = plr[myplr]._pClass; + if ( v4 ) + { + if ( v4 == 1 ) + { + sfxdnum = PS_ROGUE82; + } + else if ( v4 == 2 ) + { + sfxdnum = PS_MAGE82; + } + } + else + { + sfxdnum = PS_WARR82; + } + if ( sendmsg ) + { + v5 = 12; +LABEL_10: + NetSendCmdQuest(1u, v5); + return; + } + } + else + { + if ( v3 != MON_BUTCH ) + { + v7 = monster[v2].mName; + if ( v7 == UniqMonst[0].mName ) + { + quests[2]._qactive = 3; + sfxdelay = 30; + v8 = plr[myplr]._pClass; + if ( v8 ) + { + if ( v8 == 1 ) + { + sfxdnum = PS_ROGUE61; + } + else if ( v8 == 2 ) + { + sfxdnum = PS_MAGE61; + } + } + else + { + sfxdnum = PS_WARR61; + } + return; + } + if ( v7 == UniqMonst[2].mName ) + { + quests[3]._qactive = 3; + sfxdelay = 30; + v9 = plr[myplr]._pClass; + if ( v9 ) + { + if ( v9 == 1 ) + { + sfxdnum = PS_ROGUE62; + } + else if ( v9 == 2 ) + { + sfxdnum = PS_MAGE62; + } + } + else + { + sfxdnum = PS_WARR62; + } + return; + } + if ( v7 == UniqMonst[4].mName ) + { + if ( gbMaxPlayers != 1 ) + { + quests[15]._qactive = 3; + quests[15]._qvar1 = 7; + sfxdelay = 30; + quests[5]._qactive = 2; + v10 = 0; + v11 = dPiece; + do + { + v12 = 0; + v13 = &trigs[trigflag[4]]._ty; + v14 = v11; + do + { + if ( (*v14)[0] == 370 ) + { + ++trigflag[4]; + *(v13 - 1) = v12; + *v13 = v10; + v13[1] = 1026; + v13 += 4; + } + ++v12; + ++v14; + } + while ( v12 < 112 ); + v11 = (int (*)[112])((char *)v11 + 4); + ++v10; + } + while ( (signed int)v11 < (signed int)dPiece[1] ); + v15 = plr[myplr]._pClass; + if ( v15 ) + { + if ( v15 == 1 ) + { + sfxdnum = PS_ROGUE83; + } + else if ( v15 == 2 ) + { + sfxdnum = PS_MAGE83; + } + } + else + { + sfxdnum = PS_WARR83; + } + if ( sendmsg ) + { + NetSendCmdQuest(1u, 0xFu); + v5 = 5; + goto LABEL_10; + } + return; + } + if ( v7 == UniqMonst[4].mName && gbMaxPlayers == 1 ) + { + quests[15]._qactive = 3; + sfxdelay = 30; + InitVPTriggers(); + quests[15]._qvar1 = 7; + quests[15]._qvar2 = 4; + quests[5]._qactive = 2; + AddMissile(35, 32, 35, 32, 0, 65, 0, myplr, 0, 0); + v16 = plr[myplr]._pClass; + if ( v16 ) + { + if ( v16 == 1 ) + { + sfxdnum = PS_ROGUE83; + } + else if ( v16 == 2 ) + { + sfxdnum = PS_MAGE83; + } + } + else + { + sfxdnum = PS_WARR83; + } + return; + } + } + if ( v7 == UniqMonst[8].mName ) + { + quests[11]._qactive = 3; + sfxdelay = 30; + v17 = plr[myplr]._pClass; + if ( v17 ) + { + if ( v17 == 1 ) + { + sfxdnum = PS_ROGUE94; + } + else if ( v17 == 2 ) + { + sfxdnum = PS_MAGE94; + } + } + else + { + sfxdnum = PS_WARR94; + } + } + return; + } + quests[6]._qactive = 3; + sfxdelay = 30; + v6 = plr[myplr]._pClass; + if ( v6 ) + { + if ( v6 == 1 ) + { + sfxdnum = PS_ROGUE80; + } + else if ( v6 == 2 ) + { + sfxdnum = PS_MAGE80; + } + } + else + { + sfxdnum = PS_WARR80; + } + if ( sendmsg ) + { + v5 = 6; + goto LABEL_10; + } + } +} +// 52A554: using guessed type int sfxdelay; +// 679660: using guessed type char gbMaxPlayers; + +//----- (00451BEA) -------------------------------------------------------- +void __cdecl DrawButcher() +{ + DRLG_RectTrans(2 * setpc_x + 19, 2 * setpc_y + 19, 2 * setpc_x + 26, 2 * setpc_y + 26); +} + +//----- (00451C11) -------------------------------------------------------- +void __fastcall DrawSkelKing(int quest_id, int xx, int yy) +{ + int v3; // eax + + v3 = quest_id; + quests[v3]._qtx = 2 * xx + 28; + quests[v3]._qty = 2 * yy + 23; +} + +//----- (00451C32) -------------------------------------------------------- +void __fastcall DrawWarLord(int xx, int yy) +{ + int v2; // esi + int v3; // edi + unsigned char *v4; // eax + int v5; // ebx + int v6; // edx + int v7; // edx + char *v8; // eax + int v9; // ecx + char *v10; // esi + char v11; // bl + unsigned char *ptr; // [esp+Ch] [ebp-Ch] + int v13; // [esp+10h] [ebp-8h] + int v14; // [esp+14h] [ebp-4h] + + v2 = yy; + v3 = xx; + v4 = LoadFileInMem("Levels\\L4Data\\Warlord2.DUN", 0); + v5 = *v4; + ptr = v4; + v4 += 2; + v14 = v2; + v6 = *v4; + setpc_h = v6; + v7 = v2 + v6; + v8 = (char *)(v4 + 2); + setpc_w = v5; + setpc_x = v3; + setpc_y = v2; + if ( v2 < v7 ) + { + v13 = v3 + v5; + do + { + if ( v3 < v13 ) + { + v9 = v13 - v3; + v10 = &dungeon[v3][v14]; + do + { + v11 = *v8; + if ( !*v8 ) + v11 = 6; + *v10 = v11; + v8 += 2; + v10 += 40; + --v9; + } + while ( v9 ); + } + ++v14; + } + while ( v14 < v7 ); + } + mem_free_dbg(ptr); +} +// 5CF330: using guessed type int setpc_h; +// 5CF334: using guessed type int setpc_w; + +//----- (00451CC2) -------------------------------------------------------- +void __fastcall DrawSChamber(int quest_id, int xx, int yy) +{ + int v3; // esi + unsigned char *v4; // eax + int v5; // edi + int v6; // ebx + int v7; // eax + char *v8; // ecx + int v9; // eax + char *v10; // edx + char v11; // bl + int v12; // edx + unsigned char *ptr; // [esp+Ch] [ebp-10h] + int v14; // [esp+10h] [ebp-Ch] + int v15; // [esp+14h] [ebp-8h] + int v16; // [esp+18h] [ebp-4h] + + v3 = xx; + v14 = quest_id; + v4 = LoadFileInMem("Levels\\L2Data\\Bonestr1.DUN", 0); + v5 = yy; + ptr = v4; + v6 = yy; + v7 = *v4; + setpc_h = ptr[2]; + v8 = (char *)(ptr + 4); + setpc_w = v7; + setpc_x = v3; + setpc_y = yy; + v15 = yy + setpc_h; + if ( yy < yy + setpc_h ) + { + v16 = v3 + v7; + do + { + if ( v3 < v16 ) + { + v9 = v16 - v3; + v10 = &dungeon[v3][v6]; + do + { + v11 = *v8; + if ( !*v8 ) + v11 = 3; + *v10 = v11; + v8 += 2; + v10 += 40; + --v9; + } + while ( v9 ); + } + v6 = yy++ + 1; + } + while ( yy < v15 ); + } + v12 = v14; + quests[v12]._qtx = 2 * v3 + 22; + quests[v12]._qty = 2 * v5 + 23; + mem_free_dbg(ptr); +} +// 5CF330: using guessed type int setpc_h; +// 5CF334: using guessed type int setpc_w; + +//----- (00451D7C) -------------------------------------------------------- +void __fastcall DrawLTBanner(int xx, int yy) +{ + int v2; // ebx + int v3; // esi + unsigned char *v4; // eax + unsigned char *v5; // ecx + int v6; // edi + int v7; // edx + int v8; // eax + char *v9; // edx + char *v10; // ecx + unsigned char *ptr; // [esp+Ch] [ebp-10h] + int v12; // [esp+10h] [ebp-Ch] + int v13; // [esp+14h] [ebp-8h] + int v14; // [esp+18h] [ebp-4h] + + v2 = yy; + v3 = xx; + v12 = yy; + v4 = LoadFileInMem("Levels\\L1Data\\Banner1.DUN", 0); + v5 = v4; + v14 = 0; + ptr = v4; + v6 = *v4; + v7 = (int)(v4 + 2); + v8 = v4[2]; + setpc_w = v6; + v9 = (char *)(v7 + 2); + setpc_h = v8; + setpc_x = v3; + setpc_y = v2; + if ( v8 > 0 ) + { + do + { + if ( v6 > 0 ) + { + v13 = v6; + v10 = &pdungeon[v3][v14 + v12]; + do + { + if ( *v9 ) + *v10 = *v9; + v10 += 40; + v9 += 2; + --v13; + } + while ( v13 ); + v5 = ptr; + } + ++v14; + } + while ( v14 < v8 ); + } + mem_free_dbg(v5); +} +// 5CF330: using guessed type int setpc_h; +// 5CF334: using guessed type int setpc_w; + +//----- (00451E08) -------------------------------------------------------- +void __fastcall DrawBlind(int xx, int yy) +{ + int v2; // ebx + int v3; // esi + unsigned char *v4; // eax + unsigned char *v5; // ecx + int v6; // edi + int v7; // edx + int v8; // eax + char *v9; // edx + char *v10; // ecx + unsigned char *ptr; // [esp+Ch] [ebp-10h] + int v12; // [esp+10h] [ebp-Ch] + int v13; // [esp+14h] [ebp-8h] + int v14; // [esp+18h] [ebp-4h] + + v2 = yy; + v3 = xx; + v12 = yy; + v4 = LoadFileInMem("Levels\\L2Data\\Blind1.DUN", 0); + v5 = v4; + v14 = 0; + ptr = v4; + v6 = *v4; + v7 = (int)(v4 + 2); + v8 = v4[2]; + setpc_x = v3; + v9 = (char *)(v7 + 2); + setpc_y = v2; + setpc_w = v6; + setpc_h = v8; + if ( v8 > 0 ) + { + do + { + if ( v6 > 0 ) + { + v13 = v6; + v10 = &pdungeon[v3][v14 + v12]; + do + { + if ( *v9 ) + *v10 = *v9; + v10 += 40; + v9 += 2; + --v13; + } + while ( v13 ); + v5 = ptr; + } + ++v14; + } + while ( v14 < v8 ); + } + mem_free_dbg(v5); +} +// 5CF330: using guessed type int setpc_h; +// 5CF334: using guessed type int setpc_w; + +//----- (00451E94) -------------------------------------------------------- +void __fastcall DrawBlood(int xx, int yy) +{ + int v2; // ebx + int v3; // esi + unsigned char *v4; // eax + unsigned char *v5; // ecx + int v6; // edi + int v7; // edx + int v8; // eax + char *v9; // edx + char *v10; // ecx + unsigned char *ptr; // [esp+Ch] [ebp-10h] + int v12; // [esp+10h] [ebp-Ch] + int v13; // [esp+14h] [ebp-8h] + int v14; // [esp+18h] [ebp-4h] + + v2 = yy; + v3 = xx; + v12 = yy; + v4 = LoadFileInMem("Levels\\L2Data\\Blood2.DUN", 0); + v5 = v4; + v14 = 0; + ptr = v4; + v6 = *v4; + v7 = (int)(v4 + 2); + v8 = v4[2]; + setpc_x = v3; + v9 = (char *)(v7 + 2); + setpc_y = v2; + setpc_w = v6; + setpc_h = v8; + if ( v8 > 0 ) + { + do + { + if ( v6 > 0 ) + { + v13 = v6; + v10 = &dungeon[v3][v14 + v12]; + do + { + if ( *v9 ) + *v10 = *v9; + v10 += 40; + v9 += 2; + --v13; + } + while ( v13 ); + v5 = ptr; + } + ++v14; + } + while ( v14 < v8 ); + } + mem_free_dbg(v5); +} +// 5CF330: using guessed type int setpc_h; +// 5CF334: using guessed type int setpc_w; + +//----- (00451F20) -------------------------------------------------------- +void __fastcall DRLG_CheckQuests(int xx, int yy) +{ + int v2; // esi + int v3; // edi + int v4; // ebx + char *v5; // ebp + int v6; // eax + + v2 = yy; + v3 = xx; + v4 = 0; + v5 = &quests[0]._qtype; + do + { + _LOBYTE(v6) = QuestStatus(v4); + if ( v6 ) + { + switch ( *v5 ) + { + case QTYPE_BUTCH: + DrawButcher(); + break; + case QTYPE_BOL: + DrawLTBanner(v3, v2); + break; + case QTYPE_BLIND: + DrawBlind(v3, v2); + break; + case QTYPE_BLOOD: + DrawBlood(v3, v2); + break; + case QTYPE_WARLRD: + DrawWarLord(v3, v2); + break; + case QTYPE_KING: + DrawSkelKing(v4, v3, v2); + break; + case QTYPE_BONE: + DrawSChamber(v4, v3, v2); + break; + } + } + v5 += 24; + ++v4; + } + while ( (signed int)v5 < (signed int)&qline + 1 ); +} +// 69BE90: using guessed type int qline; + +//----- (00451FB1) -------------------------------------------------------- +void __cdecl SetReturnLvlPos() +{ + int v0; // eax + + switch ( setlvlnum ) + { + case SL_SKELKING: + ReturnLvlX = quests[12]._qtx + 1; + ReturnLvlY = quests[12]._qty; + v0 = (unsigned char)quests[12]._qlevel; + goto LABEL_9; + case SL_BONECHAMB: + ReturnLvlT = 2; + ReturnLvlX = quests[14]._qtx + 1; + ReturnLvlY = quests[14]._qty; + v0 = (unsigned char)quests[14]._qlevel; + goto LABEL_10; + case SL_POISONWATER: + ReturnLvlX = quests[13]._qtx; + ReturnLvlY = quests[13]._qty + 1; + v0 = (unsigned char)quests[13]._qlevel; +LABEL_9: + ReturnLvlT = 1; + goto LABEL_10; + } + if ( setlvlnum != 5 ) + return; + ReturnLvlT = 4; + ReturnLvlX = quests[15]._qtx + 1; + ReturnLvlY = quests[15]._qty - 1; + v0 = (unsigned char)quests[15]._qlevel; +LABEL_10: + ReturnLvl = v0; +} +// 5CCB10: using guessed type char setlvlnum; + +//----- (00452064) -------------------------------------------------------- +void __cdecl GetReturnLvlPos() +{ + if ( quests[15]._qactive == 3 ) + quests[15]._qvar2 = 2; + ViewX = ReturnLvlX; + ViewY = ReturnLvlY; + currlevel = ReturnLvl; + leveltype = ReturnLvlT; +} +// 5BB1ED: using guessed type char leveltype; + +//----- (0045209D) -------------------------------------------------------- +void __cdecl ResyncMPQuests() +{ + int v0; // eax + + if ( quests[12]._qactive == 1 + && currlevel >= (unsigned char)quests[12]._qlevel - 1 + && currlevel <= (unsigned char)quests[12]._qlevel + 1 ) + { + quests[12]._qactive = 2; + NetSendCmdQuest(1u, 0xCu); + } + if ( quests[6]._qactive == 1 + && currlevel >= (unsigned char)quests[6]._qlevel - 1 + && currlevel <= (unsigned char)quests[6]._qlevel + 1 ) + { + quests[6]._qactive = 2; + NetSendCmdQuest(1u, 6u); + } + if ( quests[15]._qactive == 1 && currlevel == (unsigned char)quests[15]._qlevel - 1 ) + { + quests[15]._qactive = 2; + NetSendCmdQuest(1u, 0xFu); + } + _LOBYTE(v0) = QuestStatus(15); + if ( v0 ) + AddObject(83, 2 * setpc_x + 20, 2 * setpc_y + 22); +} + +//----- (00452159) -------------------------------------------------------- +void __cdecl ResyncQuests() +{ + char *v0; // ecx + int v1; // esi + int v2; // eax + int i; // esi + char v4; // bl + int j; // esi + char v6; // bl + int k; // esi + + if ( setlevel && setlvlnum == quests[13]._qslvl && quests[13]._qactive != 1 && leveltype == quests[13]._qlvltype ) + { + v0 = "Levels\\L3Data\\L3pwater.pal"; + if ( quests[13]._qactive != 3 ) + v0 = "Levels\\L3Data\\L3pfoul.pal"; + LoadPalette(v0); + v1 = 0; + do + palette_update_quest_palette(v1++); + while ( v1 <= 32 ); + } + _LOBYTE(v2) = QuestStatus(7); + if ( v2 ) + { + if ( quests[7]._qvar1 == 1 ) + ObjChangeMapResync( + setpc_w + setpc_x - 2, + setpc_h + setpc_y - 2, + setpc_w + setpc_x + 1, + setpc_h + setpc_y + 1); + if ( quests[7]._qvar1 == 2 ) + { + ObjChangeMapResync( + setpc_w + setpc_x - 2, + setpc_h + setpc_y - 2, + setpc_w + setpc_x + 1, + setpc_h + setpc_y + 1); + ObjChangeMapResync(setpc_x, setpc_y, (setpc_w >> 1) + setpc_x + 2, (setpc_h >> 1) + setpc_y - 2); + for ( i = 0; i < nobjects; ++i ) + SyncObjectAnim(objectactive[i]); + v4 = TransVal; + TransVal = 9; + Make_RectTrans(setpc_x, setpc_y, (setpc_w >> 1) + setpc_x + 4, setpc_y + (setpc_h >> 1)); + TransVal = v4; + } + if ( quests[7]._qvar1 == 3 ) + { + ObjChangeMapResync(setpc_x, setpc_y, setpc_w + setpc_x + 1, setpc_h + setpc_y + 1); + for ( j = 0; j < nobjects; ++j ) + SyncObjectAnim(objectactive[j]); + v6 = TransVal; + TransVal = 9; + Make_RectTrans(setpc_x, setpc_y, (setpc_w >> 1) + setpc_x + 4, setpc_y + (setpc_h >> 1)); + TransVal = v6; + } + } + if ( currlevel == quests[1]._qlevel ) + { + if ( quests[1]._qactive == 1 ) + { + if ( !quests[1]._qvar1 ) + { + SpawnQuestItem(19, 0, 0, 5, 1); + quests[1]._qvar1 = 1; + } + } + else if ( quests[1]._qactive == 2 ) + { + if ( quests[1]._qvar1 < 5u ) + { + if ( quests[1]._qvar1 >= 7u ) + Qtalklist[1]._qblkm = -1; + } + else + { + Qtalklist[6]._qblkm = -1; + Qtalklist[1]._qblkm = 123; + } + } + } + if ( currlevel == (unsigned char)quests[4]._qlevel + 1 && quests[4]._qactive == 2 && !quests[4]._qvar1 ) + { + quests[4]._qvar1 = 1; + SpawnQuestItem(15, 0, 0, 5, 1); + } + if ( setlevel && setlvlnum == 5 ) + { + if ( quests[15]._qvar1 >= 4u ) + ObjChangeMapResync(1, 11, 20, 18); + if ( quests[15]._qvar1 >= 6u ) + ObjChangeMapResync(1, 18, 20, 24); + if ( quests[15]._qvar1 >= 7u ) + InitVPTriggers(); + for ( k = 0; k < nobjects; ++k ) + SyncObjectAnim(objectactive[k]); + } + if ( currlevel == quests[15]._qlevel + && !setlevel + && (quests[15]._qvar2 == 1 || quests[15]._qvar2 >= 3u) + && (quests[15]._qactive == 2 || quests[15]._qactive == 3) ) + { + quests[15]._qvar2 = 2; + } +} +// 5A5590: using guessed type char TransVal; +// 5BB1ED: using guessed type char leveltype; +// 5CCB10: using guessed type char setlvlnum; +// 5CF31D: using guessed type char setlevel; +// 5CF330: using guessed type int setpc_h; +// 5CF334: using guessed type int setpc_w; + +//----- (0045247F) -------------------------------------------------------- +void __fastcall PrintQLString(int x, int y, unsigned char cjustflag, char *str, int col) +{ + int v5; // ebx + int v6; // edi + size_t v7; // eax + int v8; // esi + signed int v9; // ecx + signed int v10; // eax + int v11; // edx + int v12; // ecx + signed int v13; // ecx + unsigned char v14; // al + int v15; // edi + int v16; // ecx + int v17; // [esp+Ch] [ebp-14h] + int v18; // [esp+10h] [ebp-10h] + signed int v19; // [esp+14h] [ebp-Ch] + signed int v20; // [esp+18h] [ebp-8h] + int width; // [esp+1Ch] [ebp-4h] + + v5 = SStringY[y]; + v6 = x; + v18 = y; + v17 = x; + width = screen_y_times_768[v5 + 204] + x + 96; + v7 = strlen(str); + v8 = 0; + v9 = 0; + v20 = v7; + if ( cjustflag ) + { + v10 = 0; + if ( v20 <= 0 ) + goto LABEL_24; + do + { + v11 = (unsigned char)str[v9++]; + v10 += fontkern[fontframe[fontidx[v11]]] + 1; + } + while ( v9 < v20 ); + if ( v10 < 257 ) +LABEL_24: + v8 = (257 - v10) >> 1; + width += v8; + } + if ( qline == v18 ) + { + v12 = v8 + v6 + 76; + if ( !cjustflag ) + v12 = v6 + 76; + Cel_decode(v12, v5 + 205, pCelBuff, ALLQUESTS, 12); + } + v13 = 0; + v19 = 0; + if ( v20 > 0 ) + { + do + { + v14 = fontframe[fontidx[(unsigned char)str[v13]]]; + v15 = v14; + v8 += fontkern[v14] + 1; + if ( v14 && v8 <= 257 ) + { + CPrintString(width, (char *)v14, col); + v13 = v19; + } + v19 = ++v13; + width += fontkern[v15] + 1; + } + while ( v13 < v20 ); + v6 = v17; + } + if ( qline == v18 ) + { + if ( cjustflag ) + v16 = v8 + v6 + 100; + else + v16 = 340 - v6; + Cel_decode(v16, v5 + 205, pCelBuff, ALLQUESTS, 12); + } +} +// 69BE90: using guessed type int qline; + +//----- (004525CD) -------------------------------------------------------- +void __cdecl DrawQuestLog() +{ + int v0; // edi + int i; // esi + + PrintQLString(0, 2, 1u, "Quest Log", 3); + Cel_decode(64, 511, pQLogCel, 1, 320); + v0 = qtopline; + for ( i = 0; i < numqlines; ++i ) + { + PrintQLString(0, v0, 1u, questlist[qlist[i]]._qlstr, 0); + v0 += 2; + } + PrintQLString(0, 22, 1u, "Close Quest Log", 0); + ALLQUESTS = (ALLQUESTS & 7) + 1; +} +// 69BED4: using guessed type int numqlines; + +//----- (00452659) -------------------------------------------------------- +void __cdecl StartQuestlog() +{ + signed int v0; // eax + int v1; // edx + unsigned int v2; // ecx + int v3; // ecx + + v0 = 0; + v1 = 0; + numqlines = 0; + v2 = 0; + do + { + if ( quests[v2]._qactive == 2 && quests[v2]._qlog ) + qlist[v0++] = v1; + ++v2; + ++v1; + } + while ( v2 < 16 ); + numqlines = v0; + if ( v0 <= 5 ) + v3 = 8; + else + v3 = 5 - (v0 >> 1); + qtopline = v3; + qline = 22; + if ( v0 ) + qline = v3; + questlog = 1; + ALLQUESTS = 1; +} +// 69BD04: using guessed type int questlog; +// 69BE90: using guessed type int qline; +// 69BED4: using guessed type int numqlines; + +//----- (004526C9) -------------------------------------------------------- +void __cdecl QuestlogUp() +{ + if ( numqlines ) + { + if ( qline == qtopline ) + { + qline = 22; + } + else if ( qline == 22 ) + { + qline = qtopline + 2 * numqlines - 2; + } + else + { + qline -= 2; + } + PlaySFX(IS_TITLEMOV); + } +} +// 69BE90: using guessed type int qline; +// 69BED4: using guessed type int numqlines; + +//----- (00452710) -------------------------------------------------------- +void __cdecl QuestlogDown() +{ + if ( numqlines ) + { + if ( qline == 22 ) + { + qline = qtopline; + } + else if ( qline == qtopline + 2 * numqlines - 2 ) + { + qline = 22; + } + else + { + qline += 2; + } + PlaySFX(IS_TITLEMOV); + } +} +// 69BE90: using guessed type int qline; +// 69BED4: using guessed type int numqlines; + +//----- (0045275A) -------------------------------------------------------- +void __cdecl QuestlogEnter() +{ + PlaySFX(IS_TITLSLCT); + if ( numqlines && qline != 22 ) + InitQTextMsg((unsigned char)quests[qlist[(qline - qtopline) >> 1]]._qmsg); + questlog = 0; +} +// 69BD04: using guessed type int questlog; +// 69BE90: using guessed type int qline; +// 69BED4: using guessed type int numqlines; + +//----- (0045279C) -------------------------------------------------------- +void __cdecl QuestlogESC() +{ + int v0; // esi + int i; // edi + + v0 = (MouseY - 32) / 12; + if ( numqlines ) + { + for ( i = 0; i < numqlines; ++i ) + { + if ( v0 == qtopline + 2 * i ) + { + qline = v0; + QuestlogEnter(); + } + } + } + if ( v0 == 22 ) + { + qline = 22; + QuestlogEnter(); + } +} +// 69BE90: using guessed type int qline; +// 69BED4: using guessed type int numqlines; + +//----- (004527F1) -------------------------------------------------------- +void __fastcall SetMultiQuest(int q, int s, unsigned char l, int v1) +{ + int v4; // eax + char *v5; // ecx + char *v6; // eax + + v4 = q; + v5 = &quests[q]._qactive; + if ( *v5 != 3 ) + { + if ( s > (unsigned char)*v5 ) + *v5 = s; + quests[v4]._qlog |= l; + v6 = &quests[v4]._qvar1; + if ( v1 > (unsigned char)*v6 ) + *v6 = v1; + } +} + +//----- (00452831) -------------------------------------------------------- +bool __cdecl SystemSupported() +{ + bool v0; // di + struct _OSVERSIONINFOA VersionInformation; // [esp+4h] [ebp-94h] + + v0 = 0; + memset(&VersionInformation, 0, 0x94u); + VersionInformation.dwOSVersionInfoSize = 148; + if ( GetVersionExA(&VersionInformation) + && VersionInformation.dwPlatformId == 2 + && VersionInformation.dwMajorVersion >= 5 ) + { + v0 = 1; + } + return v0; +} + +//----- (00452885) -------------------------------------------------------- +bool __cdecl RestrictedTest() +{ + bool v0; // si + int v1; // eax + FILE *v2; // eax + char Buffer[260]; // [esp+4h] [ebp-104h] + + v0 = 0; + _LOBYTE(v1) = SystemSupported(); + if ( v1 && GetWindowsDirectoryA(Buffer, 0x104u) ) + { + strcat(Buffer, "\\Diablo1RestrictedTest.foo"); + v2 = fopen(Buffer, "wt"); + if ( v2 ) + { + fclose(v2); + remove(Buffer); + } + else + { + v0 = 1; + } + } + return v0; +} + +//----- (004528F7) -------------------------------------------------------- +bool __cdecl ReadOnlyTest() +{ + bool v0; // si + char *v1; // eax + FILE *v2; // eax + char Filename[260]; // [esp+4h] [ebp-104h] + + v0 = 0; + if ( GetModuleFileNameA(hInstance, Filename, 0x104u) ) + { + v1 = strrchr(Filename, 92); + if ( v1 ) + { + strcpy(v1 + 1, "Diablo1ReadOnlyTest.foo"); + v2 = fopen(Filename, "wt"); + if ( v2 ) + { + fclose(v2); + remove(Filename); + } + else + { + v0 = 1; + } + } + } + return v0; +} + +//----- (0045297A) -------------------------------------------------------- +void __cdecl scrollrt_cpp_init() +{ + scrollrt_cpp_init_value = scrollrt_inf; +} +// 47F238: using guessed type int scrollrt_inf; +// 69CEFC: using guessed type int scrollrt_cpp_init_value; + +//----- (00452985) -------------------------------------------------------- +void __cdecl ClearCursor() +{ + sgdwCursWdt = 0; + sgdwCursWdtOld = 0; +} + +//----- (00452994) -------------------------------------------------------- +void __fastcall scrollrt_452994(int x, int y, int a3, int a4, int a5, int a6, int del_flag) +{ + int v7; // ebx + char v8; // al + int v9; // eax + int v10; // eax + MissileStruct *v11; // eax + int *v12; // edi + int v13; // edx + int v14; // esi + int v15; // ecx + int *v16; // eax + int *v17; // edi + int v18; // edx + int v19; // esi + int v20; // ecx + int v21; // [esp-10h] [ebp-28h] + int v22; // [esp-10h] [ebp-28h] + int v23; // [esp-Ch] [ebp-24h] + int v24; // [esp-Ch] [ebp-24h] + int v25; // [esp+Ch] [ebp-Ch] + int v26; // [esp+10h] [ebp-8h] + int i; // [esp+14h] [ebp-4h] + + v26 = x; + v7 = y; + v8 = dMissile[x][y]; + v25 = y; + if ( v8 == -1 ) + { + v9 = 0; + for ( i = 0; i < nummissiles; v9 = i++ + 1 ) + { + v10 = missileactive[v9]; + if ( v10 >= 125 ) + break; + v11 = &missile[v10]; + if ( v11->_mix == v26 && v11->_miy == v7 && v11->_miPreFlag == del_flag && v11->_miDrawFlag ) + { + v12 = (int *)v11->_miAnimCel; + if ( !v12 ) + return; + v13 = v11->_miAnimFrame; + if ( v13 < 1 || (unsigned int)*v12 > 0x32 || v13 > *v12 ) + return; + v14 = a4 + v11->_miyoff; + v15 = a3 + v11->_mixoff - v11->_miAnimWidth2; + if ( v11->_miUniqTrans ) + { + engine_417981(v15, v14, v12, v13, v11->_miAnimWidth, a5, a6, _LOBYTE(v11->_miUniqTrans) + 3); + v7 = v25; + } + else + { + v23 = v11->_miAnimWidth; + v21 = v11->_miAnimFrame; + if ( v11->_miLightFlag ) + engine_417AE9(v15, v14, v12, v21, v23, a5, a6); + else + engine_417745(v15, v14, v12, v21, v23, a5, a6); + } + } + } + } + else + { + v16 = &missileavail[44 * v8 + 81]; + if ( v16[26] == del_flag ) + { + if ( v16[24] ) + { + v17 = (int *)v16[16]; + if ( v17 ) + { + v18 = v16[23]; + if ( v18 >= 1 && (unsigned int)*v17 <= 0x32 && v18 <= *v17 ) + { + v19 = a4 + v16[4]; + v20 = a3 + v16[3] - v16[20]; + if ( v16[27] ) + { + engine_417981(v20, v19, v17, v18, v16[19], a5, a6, *((_BYTE *)v16 + 108) + 3); + } + else + { + v24 = v16[19]; + v22 = v16[23]; + if ( v16[25] ) + engine_417AE9(v20, v19, v17, v22, v24, a5, a6); + else + engine_417745(v20, v19, v17, v22, v24, a5, a6); + } + } + } + } + } + } +} + +//----- (00452B2A) -------------------------------------------------------- +void __fastcall scrollrt_452B2A(int x, int y, int sx, int sy, int a5, int a6, int a7) +{ + int v7; // ebx + char v8; // al + int v9; // eax + int v10; // eax + MissileStruct *v11; // eax + int *v12; // edi + int v13; // edx + int v14; // esi + int v15; // ecx + int *v16; // eax + int *v17; // edi + int v18; // edx + int v19; // esi + int v20; // ecx + int v21; // [esp-10h] [ebp-28h] + int v22; // [esp-10h] [ebp-28h] + int v23; // [esp-Ch] [ebp-24h] + int v24; // [esp-Ch] [ebp-24h] + int v25; // [esp+Ch] [ebp-Ch] + int v26; // [esp+10h] [ebp-8h] + int i; // [esp+14h] [ebp-4h] + + v26 = x; + v7 = y; + v8 = dMissile[x][y]; + v25 = y; + if ( v8 == -1 ) + { + v9 = 0; + for ( i = 0; i < nummissiles; v9 = i++ + 1 ) + { + v10 = missileactive[v9]; + if ( v10 >= 125 ) + break; + v11 = &missile[v10]; + if ( v11->_mix == v26 && v11->_miy == v7 && v11->_miPreFlag == a7 && v11->_miDrawFlag ) + { + v12 = (int *)v11->_miAnimCel; + if ( !v12 ) + return; + v13 = v11->_miAnimFrame; + if ( v13 < 1 || (unsigned int)*v12 > 0x32 || v13 > *v12 ) + return; + v14 = sy + v11->_miyoff; + v15 = sx + v11->_mixoff - v11->_miAnimWidth2; + if ( v11->_miUniqTrans ) + { + engine_417DF8(v15, v14, v12, v13, v11->_miAnimWidth, a5, a6, _LOBYTE(v11->_miUniqTrans) + 3); + v7 = v25; + } + else + { + v23 = v11->_miAnimWidth; + v21 = v11->_miAnimFrame; + if ( v11->_miLightFlag ) + engine_417F78(v15, v14, v12, v21, v23, a5, a6); + else + engine_417B83(v15, v14, v12, v21, v23, a5, a6); + } + } + } + } + else + { + v16 = &missileavail[44 * v8 + 81]; + if ( v16[26] == a7 ) + { + if ( v16[24] ) + { + v17 = (int *)v16[16]; + if ( v17 ) + { + v18 = v16[23]; + if ( v18 >= 1 && (unsigned int)*v17 <= 0x32 && v18 <= *v17 ) + { + v19 = sy + v16[4]; + v20 = sx + v16[3] - v16[20]; + if ( v16[27] ) + { + engine_417DF8(v20, v19, v17, v18, v16[19], a5, a6, *((_BYTE *)v16 + 108) + 3); + } + else + { + v24 = v16[19]; + v22 = v16[23]; + if ( v16[25] ) + engine_417F78(v20, v19, v17, v22, v24, a5, a6); + else + engine_417B83(v20, v19, v17, v22, v24, a5, a6); + } + } + } + } + } + } +} + +//----- (00452CC0) -------------------------------------------------------- +void __fastcall scrollrt_452CC0(int x, int y, int sx, int sy, int a5, int a6, int some_flag) +{ + int v7; // ebx + int *v8; // esi + char *v9; // edi + int *v10; // eax + int v11; // ecx + int xa; // [esp+Ch] [ebp-4h] + int player_num; // [esp+28h] [ebp+18h] + + v7 = y; + xa = x; + draw_player = (int (__fastcall *)(int, int, int, int, int, void *, int, int, int, int))scrollrt_draw_player_b; + if ( !some_flag ) + draw_player = (int (__fastcall *)(int, int, int, int, int, void *, int, int, int, int))scrollrt_draw_player_a; + v8 = &plr[0]._pHitPoints; + v9 = &dFlags[x][y]; + *v9 &= 0xFBu; + player_num = 0; + do + { + if ( !*((_BYTE *)v8 - 379) || *v8 || *(v8 - 89) != currlevel || *(v8 - 88) != xa || *(v8 - 87) != v7 ) + goto LABEL_14; + v10 = (int *)*(v8 - 71); + if ( !v10 ) + break; + v11 = *(v8 - 67); + if ( v11 < 1 || (unsigned int)*v10 > 0x32 || v11 > *v10 ) + break; + *v9 |= 4u; + draw_player(player_num, xa, v7, sx + *(v8 - 78) - *(v8 - 65), sy + *(v8 - 77), v10, v11, *(v8 - 66), a5, a6); +LABEL_14: + ++player_num; + v8 += 5430; + } + while ( (signed int)v8 < (signed int)&plr_msgs[2].msg[51] ); +} + +//----- (00452DA0) -------------------------------------------------------- +void __fastcall scrollrt_draw_player_a(int pnum, int x, int y, int px, int py, int animdata, int animframe, int animwidth, int a9, int a10) +{ + char *v10; // edx + int v11; // eax + void *v12; // ecx + int v13; // [esp+Ch] [ebp-4h] + int ya; // [esp+18h] [ebp+8h] + int animdataa; // [esp+24h] [ebp+14h] + + v10 = &dFlags[x][y]; + v11 = myplr; + v13 = pnum; + ya = (int)v10; + if ( *v10 & 0x40 || plr[myplr]._pInfraFlag || !setlevel && !currlevel ) + { + v12 = (void *)animdata; + if ( animdata ) + { + if ( animframe >= 1 && *(_DWORD *)animdata <= 0x32u && animframe <= *(_DWORD *)animdata ) + { + if ( v13 == pcursplr ) + { + engine_417847(165, px, py, (void *)animdata, animframe, animwidth, a9, a10); + v11 = myplr; + v12 = (void *)animdata; + v10 = (char *)ya; + } + if ( v13 == v11 ) + { + engine_417745(px, py, v12, animframe, animwidth, a9, a10); + if ( plr[v13].pManaShield ) + engine_417745( + px + plr[v13]._pAnimWidth2 - misfiledata[9].mAnimWidth2[0], + py, + (void *)misfiledata[9].mAnimCel[0], + 1, + misfiledata[9].mAnimWidth[0], + a9, + a10); + } + else if ( !(*v10 & 0x40) || plr[v11]._pInfraFlag && light_table_index > 8 ) + { + engine_417981(px, py, v12, animframe, animwidth, a9, a10, 1); + if ( plr[v13].pManaShield ) + engine_417981( + px + plr[v13]._pAnimWidth2 - misfiledata[9].mAnimWidth2[0], + py, + (void *)misfiledata[9].mAnimCel[0], + 1, + misfiledata[9].mAnimWidth[0], + a9, + a10, + 1); + } + else + { + animdataa = light_table_index; + if ( light_table_index >= 5 ) + light_table_index -= 5; + else + light_table_index = 0; + engine_417AE9(px, py, v12, animframe, animwidth, a9, a10); + if ( plr[v13].pManaShield ) + engine_417AE9( + px + plr[v13]._pAnimWidth2 - misfiledata[9].mAnimWidth2[0], + py, + (void *)misfiledata[9].mAnimCel[0], + 1, + misfiledata[9].mAnimWidth[0], + a9, + a10); + light_table_index = animdataa; + } + } + } + } +} +// 4B8CC2: using guessed type char pcursplr; +// 5CF31D: using guessed type char setlevel; +// 69BEF8: using guessed type int light_table_index; + +//----- (00452F8B) -------------------------------------------------------- +void __fastcall scrollrt_draw_player_b(int pnum, int x, int y, int px, int py, int animdata, int animframe, int animwidth, int a9, int a10) +{ + char *v10; // edx + int v11; // eax + void *v12; // ecx + int v13; // [esp+Ch] [ebp-4h] + int ya; // [esp+18h] [ebp+8h] + int animdataa; // [esp+24h] [ebp+14h] + + v10 = &dFlags[x][y]; + v11 = myplr; + v13 = pnum; + ya = (int)v10; + if ( *v10 & 0x40 || plr[myplr]._pInfraFlag ) + { + v12 = (void *)animdata; + if ( animdata ) + { + if ( animframe >= 1 && *(_DWORD *)animdata <= 0x32u && animframe <= *(_DWORD *)animdata ) + { + if ( v13 == pcursplr ) + { + engine_417C99(165, px, py, (void *)animdata, animframe, animwidth, a9, a10); + v11 = myplr; + v12 = (void *)animdata; + v10 = (char *)ya; + } + if ( v13 == v11 ) + { + engine_417B83(px, py, v12, animframe, animwidth, a9, a10); + if ( plr[v13].pManaShield ) + engine_417B83( + px + plr[v13]._pAnimWidth2 - misfiledata[9].mAnimWidth2[0], + py, + (void *)misfiledata[9].mAnimCel[0], + 1, + misfiledata[9].mAnimWidth[0], + a9, + a10); + } + else if ( !(*v10 & 0x40) || plr[v11]._pInfraFlag && light_table_index > 8 ) + { + engine_417DF8(px, py, v12, animframe, animwidth, a9, a10, 1); + if ( plr[v13].pManaShield ) + engine_417DF8( + px + plr[v13]._pAnimWidth2 - misfiledata[9].mAnimWidth2[0], + py, + (void *)misfiledata[9].mAnimCel[0], + 1, + misfiledata[9].mAnimWidth[0], + a9, + a10, + 1); + } + else + { + animdataa = light_table_index; + if ( light_table_index >= 5 ) + light_table_index -= 5; + else + light_table_index = 0; + engine_417F78(px, py, v12, animframe, animwidth, a9, a10); + if ( plr[v13].pManaShield ) + engine_417F78( + px + plr[v13]._pAnimWidth2 - misfiledata[9].mAnimWidth2[0], + py, + (void *)misfiledata[9].mAnimCel[0], + 1, + misfiledata[9].mAnimWidth[0], + a9, + a10); + light_table_index = animdataa; + } + } + } + } +} +// 4B8CC2: using guessed type char pcursplr; +// 69BEF8: using guessed type int light_table_index; + +//----- (00453160) -------------------------------------------------------- +void __fastcall DrawView(int StartX, int StartY) +{ + if ( zoomflag ) + DrawGame(StartX, StartY); + else + DrawZoom(StartX, StartY); + if ( *(_DWORD *)&automapflag ) + DrawAutomap(); + if ( invflag ) + { + DrawInv(); + } + else if ( sbookflag ) + { + DrawSpellBook(); + } + DrawDurIcon(); + if ( chrflag ) + { + DrawChr(); + } + else if ( questlog ) + { + DrawQuestLog(); + } + else if ( plr[myplr]._pStatPts && !spselflag ) + { + DrawLevelUpIcon(); + } + if ( uitemflag ) + DrawUniqueInfo(); + if ( qtextflag ) + DrawQText(); + if ( spselflag ) + DrawSpellList(); + if ( dropGoldFlag ) + DrawGoldSplit(dropGoldValue); + if ( helpflag ) + DrawHelp(); + if ( msgflag ) + DrawDiabloMsg(); + if ( *(_DWORD *)&deathflag ) + { + RedBack(); + } + else if ( PauseMode ) + { + gmenu_draw_pause(); + } + DrawPlrMsg(); + gmenu_draw(); + doom_draw(); + DrawInfoBox(); + DrawLifeFlask(); + DrawManaFlask(); +} +// 4B84DC: using guessed type int dropGoldFlag; +// 4B8968: using guessed type int sbookflag; +// 4B8C98: using guessed type int spselflag; +// 52569C: using guessed type int zoomflag; +// 525740: using guessed type int PauseMode; +// 52B9F1: using guessed type char msgflag; +// 646D00: using guessed type char qtextflag; +// 69BD04: using guessed type int questlog; + +//----- (00453272) -------------------------------------------------------- +void __fastcall DrawGame(int x, int y) +{ + int v2; // esi + int v3; // ebx + int v4; // edi + int v5; // edi + int v6; // esi + int v7; // edi + int v8; // esi + int v9; // edi + int v10; // esi + signed int v11; // [esp+Ch] [ebp-10h] + signed int a6; // [esp+10h] [ebp-Ch] + signed int a6a; // [esp+10h] [ebp-Ch] + signed int a5; // [esp+14h] [ebp-8h] + int ya; // [esp+18h] [ebp-4h] + + dword_5C2FF8 = 10; + v2 = ScrollInfo._sxoff + 64; + v3 = x - 10; + ya = y - 1; + a5 = 10; + v4 = ScrollInfo._syoff + 175; + scr_pix_width = 640; + scr_pix_height = 352; + dword_5C2FFC = 11; + v11 = 8; + if ( chrflag || questlog ) + { + ya = y - 3; + v3 += 2; + v2 = ScrollInfo._sxoff + 352; + a5 = 6; + } + if ( invflag || sbookflag ) + { + ya -= 2; + v3 += 2; + v2 -= 32; + a5 = 6; + } + switch ( ScrollInfo._sdir ) + { + case DIR_SW: + goto LABEL_9; + case DIR_W: + ++a5; +LABEL_9: + v4 = ScrollInfo._syoff + 143; + --v3; + --ya; + goto LABEL_15; + case DIR_NW: + goto LABEL_13; + case DIR_N: + v11 = 9; + goto LABEL_13; + case DIR_NE: + goto LABEL_15; + case DIR_E: + v11 = 9; + goto LABEL_12; + case DIR_SE: +LABEL_12: + v2 -= 64; + --v3; + ++ya; +LABEL_13: + ++a5; + break; + case DIR_OMNI: + v2 -= 64; + v4 = ScrollInfo._syoff + 143; + v3 -= 2; + ++a5; +LABEL_15: + v11 = 9; + break; + default: + break; + } + a6 = 0; + screen_buf_end = (int)gpBuffer + screen_y_times_768[160]; + do + { + scrollrt_454D9D(v3, ya++, v2, v4, a5, a6, 0); + v5 = v4 + 16; + v6 = v2 - 32; + scrollrt_454D9D(v3++, ya, v6, v5, a5, a6, 1); + v2 = v6 + 32; + v4 = v5 + 16; + ++a6; + } + while ( a6 < 4 ); + screen_buf_end = (int)gpBuffer + screen_y_times_768[512]; + if ( v11 > 0 ) + { + do + { + scrollrt_levels(v3, ya++, v2, v4, a5, 0); + v7 = v4 + 16; + v8 = v2 - 32; + scrollrt_levels(v3++, ya, v8, v7, a5, 1); + v2 = v8 + 32; + v4 = v7 + 16; + --v11; + } + while ( v11 ); + } + arch_draw_type = 0; + a6a = 0; + do + { + scrollrt_454229(v3, ya++, v2, v4, a5, a6a, 0); + v9 = v4 + 16; + v10 = v2 - 32; + scrollrt_454229(v3++, ya, v10, v9, a5, a6a, 1); + v2 = v10 + 32; + v4 = v9 + 16; + ++a6a; + } + while ( a6a < 4 ); +} +// 4B8968: using guessed type int sbookflag; +// 5C2FF8: using guessed type int dword_5C2FF8; +// 5C2FFC: using guessed type int dword_5C2FFC; +// 5C3000: using guessed type int scr_pix_width; +// 5C3004: using guessed type int scr_pix_height; +// 69BD04: using guessed type int questlog; +// 69CF0C: using guessed type int screen_buf_end; +// 69CF20: using guessed type char arch_draw_type; + +//----- (00453477) -------------------------------------------------------- +void __fastcall scrollrt_levels(int x, int y, int sx, int sy, int a5, int some_flag) +{ + unsigned int v6; // edi + unsigned int v7; // ebx + unsigned short *v8; // esi + unsigned int v9; // ebx + int v10; // eax + int v11; // ecx + int v12; // edx + char *v13; // edx + int v14; // edi + int v15; // eax + char *v16; // edi + char *v17; // edi + char *v18; // edi + char *v19; // edi + int v20; // eax + int v21; // edi + int v22; // ecx + int v23; // ecx + int v24; // eax + int *v25; // ebx + int v26; // ecx + int v27; // eax + int v28; // edi + char *v29; // edi + int v30; // eax + int v31; // eax + int v32; // eax + int v33; // ecx + int v34; // eax + int *v35; // edi + int v36; // ecx + int v37; // eax + char *v38; // edi + char *v39; // edi + int v40; // eax + char *v41; // edi + char *v42; // edi + char *v43; // edi + char *v44; // edi + int v45; // eax + int v46; // [esp+Ch] [ebp-10h] + int v47; // [esp+10h] [ebp-Ch] + signed int sya; // [esp+14h] [ebp-8h] + unsigned int sxa; // [esp+18h] [ebp-4h] + signed int i; // [esp+2Ch] [ebp+10h] + int *v51; // [esp+2Ch] [ebp+10h] + + v6 = y; + v7 = x; + sya = y; + sxa = x; + v8 = (unsigned short *)((char *)dpiece_defs_map_1 + 32 * gendung_41927A(x, y)); + if ( some_flag ) + { + if ( v6 < 0x70 && v7 < 0x70 ) + { + v9 = v7; + v10 = dPiece[0][v9 * 112 + v6]; + light_table_index = dTransVal[v9][v6]; + level_piece_id = v10; + if ( v10 ) + { + v11 = (unsigned char)(nTransTable[v10] & TransList[dung_map[v9][v6]]); + arch_draw_type = 2; + v12 = screen_y_times_768[sy]; + cel_transparency_active = v11; + v13 = (char *)gpBuffer + v12; + level_cel_block = v8[1]; + v14 = (int)&v13[sx + 32]; + if ( level_cel_block ) + drawLowerScreen(&v13[sx + 32]); + v15 = v8[3]; + arch_draw_type = 0; + v16 = (char *)(v14 - 24576); + level_cel_block = v15; + if ( v15 ) + drawLowerScreen(v16); + v17 = v16 - 24576; + level_cel_block = v8[5]; + if ( level_cel_block ) + drawLowerScreen(v17); + v18 = v17 - 24576; + level_cel_block = v8[7]; + if ( level_cel_block ) + drawLowerScreen(v18); + v19 = v18 - 24576; + level_cel_block = v8[9]; + if ( level_cel_block ) + drawLowerScreen(v19); + v20 = v8[11]; + level_cel_block = v8[11]; + if ( v20 && leveltype == 4 ) + drawLowerScreen(v19 - 24576); + v21 = sy; + scrollrt_dead((char *)gpBuffer + screen_y_times_768[sy] + sx, sxa, sya, sx, sy, 0); + goto LABEL_21; + } + world_levelrelated((char *)gpBuffer + screen_y_times_768[sy] + sx); + } + v21 = sy; +LABEL_21: + ++sxa; + --sya; + sx += 64; + v8 += 16; + --a5; + goto LABEL_23; + } + v21 = sy; +LABEL_23: + v46 = a5; + if ( a5 ) + { + v22 = 112 * sxa; + v47 = 112 * sxa; + do + { + --v46; + if ( sya < 0 || v22 >= 12544 ) + break; + if ( sya < 112 && v22 >= 0 ) + { + v23 = sya + v22; + v24 = dPiece[0][v23]; + light_table_index = dTransVal[0][v23]; + level_piece_id = v24; + if ( v24 ) + { + v25 = &screen_y_times_768[v21]; + v26 = (unsigned char)(nTransTable[v24] & TransList[dung_map[0][v23]]); + v27 = *v8; + v28 = *v25; + cel_transparency_active = v26; + arch_draw_type = 1; + level_cel_block = v27; + v29 = (char *)gpBuffer + v28 + sx; + if ( v27 ) + drawLowerScreen(v29); + v30 = v8[1]; + arch_draw_type = 2; + level_cel_block = v30; + if ( v30 ) + drawLowerScreen(v29 + 32); + arch_draw_type = 0; + v31 = 2; + for ( i = 2; i < dword_5A5594; i += 2 ) + { + v29 -= 24576; + level_cel_block = v8[v31]; + if ( level_cel_block ) + drawLowerScreen(v29); + v32 = v8[i + 1]; + level_cel_block = v8[i + 1]; + if ( v32 ) + drawLowerScreen(v29 + 32); + v31 = i + 2; + } + scrollrt_dead((char *)gpBuffer + *v25 + sx, sxa, sya, sx, sy, 1); + v21 = sy; + } + else + { + world_levelrelated((char *)gpBuffer + screen_y_times_768[v21] + sx); + } + v22 = v47; + } + ++sxa; + sx += 64; + v22 += 112; + --sya; + v8 += 16; + v47 = v22; + } + while ( v46 ); + } + if ( some_flag && (unsigned int)sya < 0x70 && sxa < 0x70 ) + { + v33 = sya + 112 * sxa; + v34 = dPiece[0][v33]; + light_table_index = dTransVal[0][v33]; + level_piece_id = v34; + if ( v34 ) + { + v35 = &screen_y_times_768[v21]; + v36 = (unsigned char)(nTransTable[v34] & TransList[dung_map[0][v33]]); + v37 = *v8; + v51 = v35; + v38 = (char *)gpBuffer + *v35; + cel_transparency_active = v36; + arch_draw_type = 1; + level_cel_block = v37; + v39 = &v38[sx]; + if ( v37 ) + drawLowerScreen(v39); + v40 = v8[2]; + arch_draw_type = 0; + v41 = v39 - 24576; + level_cel_block = v40; + if ( v40 ) + drawLowerScreen(v41); + v42 = v41 - 24576; + level_cel_block = v8[4]; + if ( level_cel_block ) + drawLowerScreen(v42); + v43 = v42 - 24576; + level_cel_block = v8[6]; + if ( level_cel_block ) + drawLowerScreen(v43); + v44 = v43 - 24576; + level_cel_block = v8[8]; + if ( level_cel_block ) + drawLowerScreen(v44); + v45 = v8[10]; + level_cel_block = v8[10]; + if ( v45 ) + { + if ( leveltype == 4 ) + drawLowerScreen(v44 - 24576); + } + scrollrt_dead((char *)gpBuffer + *v51 + sx, sxa, sya, sx, sy, 0); + } + else + { + world_levelrelated((char *)gpBuffer + screen_y_times_768[v21] + sx); + } + } +} +// 5BB1ED: using guessed type char leveltype; +// 69BEF8: using guessed type int light_table_index; +// 69CF14: using guessed type int level_cel_block; +// 69CF20: using guessed type char arch_draw_type; +// 69CF94: using guessed type int cel_transparency_active; +// 69CF98: using guessed type int level_piece_id; + +//----- (004538E2) -------------------------------------------------------- +void __fastcall scrollrt_dead(char *a1, int sx, int sy, int a4, int a5, int a6) +{ + int v6; // eax + char v7; // bl + char v8; // cl + char v9; // dl + int *v10; // eax + void **v11; // eax + int *v12; // esi + int v13; // ecx + int v14; // edx + char v15; // bl + ItemStruct *v16; // esi + char *v17; // eax + signed int v18; // ebx + int v19; // ebx + unsigned int v20; // ecx + PlayerStruct *v21; // esi + int v22; // esi + int v23; // eax + MonsterStruct *v24; // esi + CMonster *v25; // ecx + int v26; // ebx + int v27; // edi + unsigned int v28; // ecx + PlayerStruct *v29; // esi + int v30; // esi + int v31; // eax + MonsterStruct *v32; // esi + CMonster *v33; // ecx + int v34; // ebx + int v35; // edi + ItemStruct *v36; // esi + char *v37; // ecx + signed int v38; // ebx + int v39; // ebx + int v40; // [esp+Ch] [ebp-18h] + int v41; // [esp+10h] [ebp-14h] + char *dst_buf; // [esp+14h] [ebp-10h] + int a1a; // [esp+18h] [ebp-Ch] + char v44; // [esp+1Dh] [ebp-7h] + char v45; // [esp+1Eh] [ebp-6h] + char v46; // [esp+1Fh] [ebp-5h] + char v47; // [esp+20h] [ebp-4h] + char v48; // [esp+21h] [ebp-3h] + char v49; // [esp+22h] [ebp-2h] + char v50; // [esp+23h] [ebp-1h] + + a1a = sx; + dst_buf = a1; + v6 = 112 * sx + sy; + v7 = dDead[0][v6]; + v50 = dFlags[0][v6]; + v47 = dObject[0][v6]; + v49 = dItem[0][v6]; + v8 = dPlayer[0][v6 - 1]; + v48 = dPlayer[0][v6]; + v46 = dArch[0][v6]; + v9 = dung_map[0][v6]; + v10 = (int *)((char *)dMonster + 4 * v6); + v44 = v9; + v45 = v8; + v40 = *v10; + v41 = *(v10 - 1); + if ( visiondebug && v50 & 0x40 ) + Cel2_header_into_buf(dst_buf, (char *)pSquareCel, 1, 64, 0, 8); + if ( MissilePreFlag && v50 & 1 ) + scrollrt_452B2A(a1a, sy, a4, a5, 0, 8, 1); + if ( light_table_index < lightmax ) + { + if ( v7 ) + { + v11 = &pCursCels + 12 * (v7 & 0x1F); + v12 = (int *)v11[(v7 >> 5) & 7]; + v13 = a4 - (_DWORD)v11[10]; + if ( v12 ) + { + v14 = (int)v11[8]; + if ( v14 >= 1 && (unsigned int)*v12 <= 0x32 && v14 <= *v12 ) + { + v15 = *((_BYTE *)v11 + 44); + if ( v15 ) + engine_417DF8(v13, a5, v12, v14, (int)v11[9], 0, 8, v15); + else + engine_417F78(v13, a5, v12, v14, (int)v11[9], 0, 8); + } + } + } + if ( v47 ) + scrollrt_objects(a1a, sy, a4, a5, 1, 0, 8); + } + if ( v49 ) + { + v16 = &item_stru_6358B8 + v49; + if ( !v16->_iPostDraw && (unsigned char)v49 <= 0x7Fu ) + { + v17 = (char *)v16->ItemFrame; + if ( v17 ) + { + v18 = v16->_iAnimFrame; + if ( v18 >= 1 && *(_DWORD *)v17 <= 0x32u && v18 <= *(_DWORD *)v17 ) + { + v19 = a4 - v16->_iAnimXOff; + if ( v49 - 1 == pcursitem ) + Cel_header_and_colour_highlight(181, v19, a5, v17, v16->_iAnimFrame, v16->_iAnimWidth, 0, 8); + Cel2_header_and_light(v19, a5, (char *)v16->ItemFrame, v16->_iAnimFrame, v16->_iAnimWidth, 0, 8); + } + } + } + } + if ( v50 & 0x20 ) + { + v20 = -1 - v45; + if ( v20 < 4 ) + { + v21 = &plr[v20]; + scrollrt_draw_player_b( + v20, + a1a, + sy - 1, + a4 + v21->_pxoff - v21->_pAnimWidth2, + a5 + v21->_pyoff, + v21->_pAnimData, + v21->_pAnimFrame, + v21->_pAnimWidth, + 0, + 8); + if ( a6 ) + { + v22 = v21->_peflag; + if ( v22 ) + { + if ( v22 == 2 ) + scrollrt_4540E5(dst_buf - 12384, a1a - 2, sy + 1, a4 - 96, a5 - 16); + scrollrt_4540E5(dst_buf - 64, a1a - 1, sy + 1, a4 - 64, a5); + } + } + } + } + if ( v50 & 0x10 && (v50 & 0x40 || plr[myplr]._pInfraFlag) && v41 < 0 ) + { + v23 = -1 - v41; + draw_monster_num = -1 - v41; + if ( (unsigned int)(-1 - v41) < 0xC8 ) + { + v24 = &monster[v23]; + if ( !(v24->_mFlags & 1) ) + { + v25 = v24->MType; + if ( v25 ) + { + v26 = a5 + v24->_myoff; + v27 = a4 + v24->_mxoff - v25->flags_2; + if ( v23 == *(_DWORD *)&pcursmonst ) + { + engine_417C99(233, v27, v26, (void *)v24->_mAFNum, v24->_mAnimFrame, v25->flags_1, 0, 8); + v23 = draw_monster_num; + } + scrollrt_monsters(a1a, sy, v27, v26, v23, 0, 8); + if ( a6 && v24->_meflag ) + scrollrt_4540E5(dst_buf - 64, a1a - 1, sy + 1, a4 - 64, a5); + } + } + } + } + if ( v50 & 4 ) + scrollrt_452CC0(a1a, sy, a4, a5, 0, 8, 1); + if ( v48 > 0 ) + { + v28 = v48 - 1; + if ( v28 < 4 ) + { + v29 = &plr[v28]; + scrollrt_draw_player_b( + v28, + a1a, + sy, + a4 + v29->_pxoff - v29->_pAnimWidth2, + a5 + v29->_pyoff, + v29->_pAnimData, + v29->_pAnimFrame, + v29->_pAnimWidth, + 0, + 8); + if ( a6 ) + { + v30 = v29->_peflag; + if ( v30 ) + { + if ( v30 == 2 ) + scrollrt_4540E5(dst_buf - 12384, a1a - 2, sy + 1, a4 - 96, a5 - 16); + scrollrt_4540E5(dst_buf - 64, a1a - 1, sy + 1, a4 - 64, a5); + } + } + } + } + if ( v40 > 0 && (v50 & 0x40 || plr[myplr]._pInfraFlag) ) + { + v31 = v40 - 1; + draw_monster_num = v40 - 1; + if ( (unsigned int)(v40 - 1) < 0xC8 ) + { + v32 = &monster[v31]; + if ( !(v32->_mFlags & 1) ) + { + v33 = v32->MType; + if ( v33 ) + { + v34 = a5 + v32->_myoff; + v35 = a4 + v32->_mxoff - v33->flags_2; + if ( v31 == *(_DWORD *)&pcursmonst ) + { + engine_417C99(233, v35, v34, (void *)v32->_mAFNum, v32->_mAnimFrame, v33->flags_1, 0, 8); + v31 = draw_monster_num; + } + scrollrt_monsters(a1a, sy, v35, v34, v31, 0, 8); + if ( a6 && v32->_meflag ) + scrollrt_4540E5(dst_buf - 64, a1a - 1, sy + 1, a4 - 64, a5); + } + } + } + } + if ( v50 & 1 ) + scrollrt_452B2A(a1a, sy, a4, a5, 0, 8, 0); + if ( v47 && light_table_index < lightmax ) + scrollrt_objects(a1a, sy, a4, a5, 0, 0, 8); + if ( v49 ) + { + v36 = &item_stru_6358B8 + v49; + if ( v36->_iPostDraw ) + { + if ( (unsigned char)v49 <= 0x7Fu ) + { + v37 = (char *)v36->ItemFrame; + if ( v37 ) + { + v38 = v36->_iAnimFrame; + if ( v38 >= 1 && *(_DWORD *)v37 <= 0x32u && v38 <= *(_DWORD *)v37 ) + { + v39 = a4 - v36->_iAnimXOff; + if ( v49 - 1 == pcursitem ) + Cel_header_and_colour_highlight(181, v39, a5, v37, v36->_iAnimFrame, v36->_iAnimWidth, 0, 8); + Cel2_header_and_light( + v39, + a5, + (char *)v36->ItemFrame, + v36->_iAnimFrame, + v36->_iAnimWidth, + 0, + 8); + } + } + } + } + } + if ( v46 ) + { + cel_transparency_active = (unsigned char)TransList[v44]; + Cel2_header_light_and_trans_into_buf(dst_buf, (char *)level_special_cel, v46, 64, 0, 8); + } +} +// 4B8CC0: using guessed type char pcursitem; +// 525720: using guessed type int visiondebug; +// 642A14: using guessed type char lightmax; +// 64CCD4: using guessed type int MissilePreFlag; +// 69BEF8: using guessed type int light_table_index; +// 69CF94: using guessed type int cel_transparency_active; +// 69EFA4: using guessed type int draw_monster_num; + +//----- (00453ED9) -------------------------------------------------------- +void __fastcall scrollrt_monsters(int x, int y, int a3, int a4, int mon_id, int a6, int a7) +{ + int v7; // eax + signed int *v8; // esi + signed int v9; // ebx + char v10; // cl + CMonster *v11; // eax + char mon_ida; // [esp+1Ch] [ebp+10h] + + if ( (unsigned int)mon_id < 0xC8 ) + { + v7 = mon_id; + v8 = (signed int *)monster[mon_id]._mAFNum; + if ( v8 ) + { + v9 = monster[v7]._mAnimFrame; + if ( v9 >= 1 && (unsigned int)*v8 <= 0x32 && v9 <= *v8 ) + { + if ( dFlags[x][y] & 0x40 ) + { + v10 = 0; + mon_ida = 0; + if ( monster[v7]._uniqtype ) + { + v10 = monster[v7]._uniqtrans + 4; + mon_ida = monster[v7]._uniqtrans + 4; + } + if ( monster[v7]._mmode == MM_STONE ) + { + v10 = 2; + mon_ida = 2; + } + if ( plr[myplr]._pInfraFlag && light_table_index > 8 ) + { + v10 = 1; + mon_ida = 1; + } + v11 = monster[v7].MType; + if ( v10 ) + engine_417DF8(a3, a4, v8, v9, v11->flags_1, a6, a7, mon_ida); + else + engine_417F78(a3, a4, v8, v9, v11->flags_1, a6, a7); + } + else + { + engine_417DF8(a3, a4, v8, v9, monster[v7].MType->flags_1, a6, a7, 1); + } + } + } + } +} +// 69BEF8: using guessed type int light_table_index; + +//----- (00453FCC) -------------------------------------------------------- +void __fastcall scrollrt_objects(int x, int y, int a3, int a4, int pre_flag, int a6, int dir) +{ + int v7; // edi + char v8; // al + unsigned char v9; // dl + int v10; // esi + int v11; // ebx + int v12; // edi + int v13; // eax + int v14; // ecx + char *v15; // eax + signed int v16; // ecx + char *v17; // [esp-14h] [ebp-24h] + int v18; // [esp-10h] [ebp-20h] + int v19; // [esp-Ch] [ebp-1Ch] + char v20; // [esp+Fh] [ebp-1h] + + v7 = y; + v8 = dObject[x][y]; + if ( v8 <= 0 ) + { + v9 = -1 - v8; + v10 = (char)(-1 - v8); + v20 = -1 - v8; + if ( object[v10]._oPreFlag != pre_flag ) + return; + dir = 8; + v13 = object[v10]._ox - x; + v14 = object[v10]._oy - v7; + v12 = a3 + 32 * v13 - object[v10]._oAnimWidth2 - 32 * v14; + v11 = a4 + 16 * (v14 + v13); + a6 = 0; + } + else + { + v9 = v8 - 1; + v10 = (char)(v8 - 1); + v20 = v8 - 1; + if ( object[v10]._oPreFlag != pre_flag ) + return; + v11 = a4; + v12 = a3 - object[v10]._oAnimWidth2; + } + if ( v9 < 0x7Fu ) + { + v15 = (char *)object[v10]._oAnimCel; + if ( v15 ) + { + v16 = object[v10]._oAnimFrame; + if ( v16 >= 1 && *(_DWORD *)v15 <= 0x32u && v16 <= *(_DWORD *)v15 ) + { + if ( v20 == pcursobj ) + Cel_header_and_colour_highlight(194, v12, v11, v15, v16, object[v10]._oAnimWidth, a6, dir); + v19 = object[v10]._oAnimWidth; + v18 = object[v10]._oAnimFrame; + v17 = (char *)object[v10]._oAnimCel; + if ( object[v10]._oLight ) + Cel2_header_and_light(v12, v11, v17, v18, v19, a6, dir); + else + Cel2_header(v12, v11, v17, v18, v19, a6, dir); + } + } + } +} +// 4B8CC1: using guessed type char pcursobj; + +//----- (004540E5) -------------------------------------------------------- +void __fastcall scrollrt_4540E5(char *buffer, int x, int y, int a4, int a5) +{ + int v5; // eax + int v6; // ebx + int v7; // ecx + int v8; // esi + int v9; // eax + int v10; // edi + int v11; // eax + int v12; // eax + unsigned short *v13; // esi + int v14; // eax + int v15; // eax + int v16; // eax + int v17; // eax + int v18; // [esp+Ch] [ebp-14h] + int xa; // [esp+10h] [ebp-10h] + int i; // [esp+14h] [ebp-Ch] + char *a1; // [esp+18h] [ebp-8h] + char *v22; // [esp+1Ch] [ebp-4h] + + xa = x; + v18 = level_piece_id; + v5 = y + 112 * x; + a1 = buffer; + v6 = cel_transparency_active; + v7 = dPiece[0][v5]; + v8 = dTransVal[0][v5]; + v9 = dung_map[0][v5]; + v10 = light_table_index; + level_piece_id = v7; + v11 = (unsigned char)(nTransTable[v7] & TransList[v9]); + light_table_index = v8; + cel_transparency_active = v11; + v12 = gendung_41927A(x, y); + arch_draw_type = 1; + v13 = (unsigned short *)((char *)dpiece_defs_map_1 + 32 * v12); + v14 = *v13; + level_cel_block = *v13; + if ( v14 ) + drawLowerScreen(a1); + v15 = v13[1]; + arch_draw_type = 2; + level_cel_block = v15; + if ( v15 ) + drawLowerScreen(a1 + 32); + arch_draw_type = 0; + v22 = a1; + v16 = 2; + for ( i = 2; i < dword_5A5594; i += 2 ) + { + v22 -= 24576; + level_cel_block = v13[v16]; + if ( level_cel_block ) + drawLowerScreen(v22); + v17 = v13[i + 1]; + level_cel_block = v13[i + 1]; + if ( v17 ) + drawLowerScreen(v22 + 32); + v16 = i + 2; + } + scrollrt_dead(a1, xa, y, a4, a5, 0); + light_table_index = v10; + cel_transparency_active = v6; + level_piece_id = v18; +} +// 69BEF8: using guessed type int light_table_index; +// 69CF14: using guessed type int level_cel_block; +// 69CF20: using guessed type char arch_draw_type; +// 69CF94: using guessed type int cel_transparency_active; +// 69CF98: using guessed type int level_piece_id; + +//----- (00454229) -------------------------------------------------------- +void __fastcall scrollrt_454229(int x, int y, int sx, int sy, int a5, int a6, int some_flag) +{ + signed int v7; // ebx + int v8; // edi + int v9; // ecx + int v10; // eax + int v11; // eax + int v12; // eax + int v13; // ecx + int v14; // ecx + int v15; // eax + char *v16; // ebx + int v17; // eax + int v18; // eax + int v19; // ecx + int v20; // eax + int v21; // eax + int v22; // eax + int v23; // [esp+Ch] [ebp-14h] + unsigned short *v24; // [esp+10h] [ebp-10h] + int v25; // [esp+10h] [ebp-10h] + int a1; // [esp+14h] [ebp-Ch] + char *a1a; // [esp+14h] [ebp-Ch] + char *a1b; // [esp+14h] [ebp-Ch] + char *v29; // [esp+18h] [ebp-8h] + signed int xa; // [esp+1Ch] [ebp-4h] + int a6a; // [esp+28h] [ebp+8h] + int a6b; // [esp+28h] [ebp+8h] + int a6c; // [esp+28h] [ebp+8h] + unsigned short *a5a; // [esp+30h] [ebp+10h] + unsigned short *a5b; // [esp+30h] [ebp+10h] + + v7 = y; + a1 = y; + xa = x; + v8 = sx; + v29 = (char *)dpiece_defs_map_1 + 32 * gendung_41927A(x, y); + if ( some_flag ) + { + if ( v7 >= 0 && v7 < 112 && xa >= 0 && xa < 112 ) + { + v9 = 112 * xa + v7; + v10 = dPiece[0][v9]; + light_table_index = dTransVal[0][v9]; + level_piece_id = v10; + if ( v10 ) + { + a6a = 0; + cel_transparency_active = (unsigned char)(nTransTable[v10] & TransList[dung_map[0][v9]]); + a1a = (char *)gpBuffer + screen_y_times_768[sy] + v8 - 24544; + if ( (dword_5A5594 >> 1) - 1 > 0 ) + { + v24 = (unsigned short *)(v29 + 6); + do + { + if ( a6 <= a6a ) + { + v11 = *v24; + level_cel_block = *v24; + if ( v11 ) + drawLowerScreen(a1a); + } + a1a -= 24576; + ++a6a; + v24 += 2; + } + while ( a6a < (dword_5A5594 >> 1) - 1 ); + } + v12 = 2 * a6 + 2; + if ( v12 < 8 ) + scrollrt_4545D2( + (char *)gpBuffer + screen_y_times_768[sy] - 12288 * v12 + v8, + xa, + v7, + a6, + 2 * a6 + 2, + v8, + sy, + 0); + } + } + ++xa; + --v7; + v8 += 64; + --a5; + v29 += 32; + a1 = v7; + } + v25 = a5; + if ( a5 ) + { + v13 = 112 * xa; + v23 = 112 * xa; + do + { + --v25; + if ( v13 >= 12544 || v7 < 0 ) + break; + if ( v7 < 112 && v13 >= 0 ) + { + v14 = v7 + v13; + v15 = dPiece[0][v14]; + light_table_index = dTransVal[0][v14]; + level_piece_id = v15; + if ( v15 ) + { + a6b = 0; + cel_transparency_active = (unsigned char)(nTransTable[v15] & TransList[dung_map[0][v14]]); + v16 = (char *)gpBuffer + screen_y_times_768[sy] + v8 - 24576; + if ( (dword_5A5594 >> 1) - 1 > 0 ) + { + a5a = (unsigned short *)(v29 + 6); + do + { + if ( a6 <= a6b ) + { + v17 = *(a5a - 1); + level_cel_block = *(a5a - 1); + if ( v17 ) + drawLowerScreen(v16); + v18 = *a5a; + level_cel_block = *a5a; + if ( v18 ) + drawLowerScreen(v16 + 32); + } + ++a6b; + a5a += 2; + v16 -= 24576; + } + while ( a6b < (dword_5A5594 >> 1) - 1 ); + } + if ( 2 * a6 + 2 < 8 ) + scrollrt_4545D2( + (char *)gpBuffer + screen_y_times_768[sy] - ((3 * a6 + 3) << 13) + v8, + xa, + a1, + a6, + 2 * a6 + 2, + v8, + sy, + 1); + v7 = a1; + } + } + ++xa; + v29 += 32; + v13 = v23 + 112; + --v7; + v8 += 64; + v23 += 112; + a1 = v7; + } + while ( v25 ); + } + if ( some_flag ) + { + if ( (unsigned int)v7 < 0x70 && (unsigned int)xa < 0x70 ) + { + v19 = 112 * xa + v7; + v20 = dPiece[0][v19]; + light_table_index = dTransVal[0][v19]; + level_piece_id = v20; + if ( v20 ) + { + a6c = 0; + cel_transparency_active = (unsigned char)(nTransTable[v20] & TransList[dung_map[0][v19]]); + a1b = (char *)gpBuffer + screen_y_times_768[sy] + v8 - 24576; + if ( (dword_5A5594 >> 1) - 1 > 0 ) + { + a5b = (unsigned short *)(v29 + 4); + do + { + if ( a6 <= a6c ) + { + v21 = *a5b; + level_cel_block = *a5b; + if ( v21 ) + drawLowerScreen(a1b); + } + a1b -= 24576; + ++a6c; + a5b += 2; + } + while ( a6c < (dword_5A5594 >> 1) - 1 ); + } + v22 = 2 * a6 + 2; + if ( v22 < 8 ) + scrollrt_4545D2( + (char *)gpBuffer + screen_y_times_768[sy] - 12288 * v22 + v8, + xa, + v7, + a6, + 2 * a6 + 2, + v8, + sy, + 0); + } + } + } +} +// 69BEF8: using guessed type int light_table_index; +// 69CF14: using guessed type int level_cel_block; +// 69CF94: using guessed type int cel_transparency_active; +// 69CF98: using guessed type int level_piece_id; + +//----- (004545D2) -------------------------------------------------------- +void __fastcall scrollrt_4545D2(char *buffer, int x, int y, int a4, int a5, int sx, int sy, int me_flag) +{ + int v8; // eax + char v9; // bl + char v10; // cl + char v11; // dl + int *v12; // eax + int v13; // edi + void **v14; // eax + int *v15; // esi + int v16; // ecx + int v17; // edx + char v18; // bl + ItemStruct *v19; // esi + char *v20; // eax + signed int v21; // ebx + int v22; // ebx + unsigned int v23; // ecx + PlayerStruct *v24; // esi + int v25; // esi + int v26; // eax + MonsterStruct *v27; // esi + CMonster *v28; // ecx + int v29; // ebx + int v30; // edi + unsigned int v31; // ecx + PlayerStruct *v32; // esi + int v33; // esi + int v34; // eax + MonsterStruct *v35; // esi + CMonster *v36; // ecx + int v37; // ebx + int v38; // edi + ItemStruct *v39; // esi + char *v40; // eax + int v41; // ecx + int v42; // edi + int v43; // [esp+Ch] [ebp-18h] + int v44; // [esp+10h] [ebp-14h] + char *dst_buf; // [esp+14h] [ebp-10h] + int a1; // [esp+18h] [ebp-Ch] + char v47; // [esp+1Dh] [ebp-7h] + char v48; // [esp+1Eh] [ebp-6h] + char v49; // [esp+1Fh] [ebp-5h] + char v50; // [esp+20h] [ebp-4h] + char v51; // [esp+21h] [ebp-3h] + char v52; // [esp+22h] [ebp-2h] + char v53; // [esp+23h] [ebp-1h] + + a1 = x; + dst_buf = buffer; + v8 = 112 * x + y; + v9 = dDead[0][v8]; + v53 = dFlags[0][v8]; + v50 = dObject[0][v8]; + v52 = dItem[0][v8]; + v10 = dPlayer[0][v8 - 1]; + v51 = dPlayer[0][v8]; + v49 = dArch[0][v8]; + v11 = dung_map[0][v8]; + v12 = (int *)((char *)dMonster + 4 * v8); + v47 = v11; + v48 = v10; + v43 = *v12; + v44 = *(v12 - 1); + if ( visiondebug && v53 & 0x40 ) + Cel2_header_into_buf(dst_buf, (char *)pSquareCel, 1, 64, a5, 8); + if ( MissilePreFlag && v53 & 1 ) + { + v13 = sx; + scrollrt_452B2A(a1, y, sx, sy, a5, 8, 1); + } + else + { + v13 = sx; + } + if ( light_table_index < lightmax ) + { + if ( v9 ) + { + v14 = &pCursCels + 12 * (v9 & 0x1F); + v15 = (int *)v14[(v9 >> 5) & 7]; + v16 = v13 - (_DWORD)v14[10]; + if ( v15 ) + { + v17 = (int)v14[8]; + if ( v17 >= 1 && (unsigned int)*v15 <= 0x32 && v17 <= *v15 ) + { + v18 = *((_BYTE *)v14 + 44); + if ( v18 ) + engine_417DF8(v16, sy, v15, v17, (int)v14[9], a5, 8, v18); + else + engine_417F78(v16, sy, v15, v17, (int)v14[9], a5, 8); + } + } + } + if ( v50 ) + scrollrt_objects(a1, y, v13, sy, 1, a5, 8); + } + if ( v52 ) + { + v19 = &item_stru_6358B8 + v52; + if ( !v19->_iPostDraw && (unsigned char)v52 <= 0x7Fu ) + { + v20 = (char *)v19->ItemFrame; + if ( v20 ) + { + v21 = v19->_iAnimFrame; + if ( v21 >= 1 && *(_DWORD *)v20 <= 0x32u && v21 <= *(_DWORD *)v20 ) + { + v22 = v13 - v19->_iAnimXOff; + if ( v52 - 1 == pcursitem ) + Cel_header_and_colour_highlight(181, v22, sy, v20, v19->_iAnimFrame, v19->_iAnimWidth, a5, 8); + Cel2_header_and_light(v22, sy, (char *)v19->ItemFrame, v19->_iAnimFrame, v19->_iAnimWidth, a5, 8); + } + } + } + } + if ( v53 & 0x20 ) + { + v23 = -1 - v48; + if ( v23 < 4 ) + { + v24 = &plr[v23]; + scrollrt_draw_player_b( + v23, + a1, + y - 1, + v13 + v24->_pxoff - v24->_pAnimWidth2, + sy + v24->_pyoff, + v24->_pAnimData, + v24->_pAnimFrame, + v24->_pAnimWidth, + a5, + 8); + if ( me_flag ) + { + v25 = v24->_peflag; + if ( v25 ) + { + if ( v25 == 2 ) + scrollrt_454C09(dst_buf - 12384, a1 - 2, y + 1, a4, a5, v13 - 96, sy - 16); + scrollrt_454C09(dst_buf - 64, a1 - 1, y + 1, a4, a5, v13 - 64, sy); + } + } + } + } + if ( v53 & 0x10 && (v53 & 0x40 || plr[myplr]._pInfraFlag) && v44 < 0 ) + { + v26 = -1 - v44; + draw_monster_num = -1 - v44; + if ( (unsigned int)(-1 - v44) < 0xC8 ) + { + v27 = &monster[v26]; + if ( !(v27->_mFlags & 1) ) + { + v28 = v27->MType; + if ( v28 ) + { + v29 = sy + v27->_myoff; + v30 = sx + v27->_mxoff - v28->flags_2; + if ( v26 == *(_DWORD *)&pcursmonst ) + { + engine_417C99(233, v30, v29, (void *)v27->_mAFNum, v27->_mAnimFrame, v28->flags_1, a5, 8); + v26 = draw_monster_num; + } + scrollrt_monsters(a1, y, v30, v29, v26, a5, 8); + if ( me_flag && !v27->_meflag ) + scrollrt_454C09(dst_buf - 64, a1 - 1, y + 1, a4, a5, sx - 64, sy); + v13 = sx; + } + } + } + } + if ( v53 & 4 ) + scrollrt_452CC0(a1, y, v13, sy, a5, 8, 1); + if ( v51 > 0 ) + { + v31 = v51 - 1; + if ( v31 < 4 ) + { + v32 = &plr[v31]; + scrollrt_draw_player_b( + v31, + a1, + y, + v13 + v32->_pxoff - v32->_pAnimWidth2, + sy + v32->_pyoff, + v32->_pAnimData, + v32->_pAnimFrame, + v32->_pAnimWidth, + a5, + 8); + if ( me_flag ) + { + v33 = v32->_peflag; + if ( v33 ) + { + if ( v33 == 2 ) + scrollrt_454C09(dst_buf - 12384, a1 - 2, y + 1, a4, a5, v13 - 96, sy - 16); + scrollrt_454C09(dst_buf - 64, a1 - 1, y + 1, a4, a5, v13 - 64, sy); + } + } + } + } + if ( v43 > 0 && (v53 & 0x40 || plr[myplr]._pInfraFlag) ) + { + v34 = v43 - 1; + draw_monster_num = v43 - 1; + if ( (unsigned int)(v43 - 1) < 0xC8 ) + { + v35 = &monster[v34]; + if ( !(v35->_mFlags & 1) ) + { + v36 = v35->MType; + if ( v36 ) + { + v37 = sy + v35->_myoff; + v38 = sx + v35->_mxoff - v36->flags_2; + if ( v34 == *(_DWORD *)&pcursmonst ) + { + engine_417C99(233, v38, v37, (void *)v35->_mAFNum, v35->_mAnimFrame, v36->flags_1, a5, 8); + v34 = draw_monster_num; + } + scrollrt_monsters(a1, y, v38, v37, v34, a5, 8); + if ( me_flag && !v35->_meflag ) + scrollrt_454C09(dst_buf - 64, a1 - 1, y + 1, a4, a5, sx - 64, sy); + v13 = sx; + } + } + } + } + if ( v53 & 1 ) + scrollrt_452B2A(a1, y, v13, sy, a5, 8, 0); + if ( v50 && light_table_index < lightmax ) + scrollrt_objects(a1, y, v13, sy, 0, a5, 8); + if ( v52 ) + { + v39 = &item_stru_6358B8 + v52; + if ( v39->_iPostDraw ) + { + if ( (unsigned char)v52 <= 0x7Fu ) + { + v40 = (char *)v39->ItemFrame; + if ( v40 ) + { + v41 = v39->_iAnimFrame; + if ( v41 >= 1 && *(_DWORD *)v40 <= 0x32u && v41 <= *(_DWORD *)v40 ) + { + v42 = v13 - v39->_iAnimXOff; + if ( v52 - 1 == pcursitem ) + Cel_header_and_colour_highlight(181, v42, sy, v40, v41, v39->_iAnimWidth, a5, 8); + Cel2_header_and_light( + v42, + sy, + (char *)v39->ItemFrame, + v39->_iAnimFrame, + v39->_iAnimWidth, + a5, + 8); + } + } + } + } + } + if ( v49 ) + { + cel_transparency_active = (unsigned char)TransList[v47]; + Cel2_header_light_and_trans_into_buf(dst_buf, (char *)level_special_cel, v49, 64, a5, 8); + } +} +// 4B8CC0: using guessed type char pcursitem; +// 525720: using guessed type int visiondebug; +// 642A14: using guessed type char lightmax; +// 64CCD4: using guessed type int MissilePreFlag; +// 69BEF8: using guessed type int light_table_index; +// 69CF94: using guessed type int cel_transparency_active; +// 69EFA4: using guessed type int draw_monster_num; + +//----- (00454C09) -------------------------------------------------------- +int __fastcall scrollrt_454C09(char *buffer, int x, int y, int a4, signed int a5, int sx, int sy) +{ + int v7; // eax + int v8; // ecx + int v9; // esi + int v10; // eax + int v11; // edi + int v12; // eax + unsigned short *v13; // esi + int v14; // eax + int v15; // eax + int v16; // eax + int v17; // eax + int v18; // edi + int v19; // eax + int result; // eax + int v21; // [esp+Ch] [ebp-14h] + int v22; // [esp+10h] [ebp-10h] + int v23; // [esp+14h] [ebp-Ch] + char *a1; // [esp+18h] [ebp-8h] + int xa; // [esp+1Ch] [ebp-4h] + + xa = x; + v23 = light_table_index; + v22 = cel_transparency_active; + v21 = level_piece_id; + v7 = y + 112 * x; + a1 = buffer; + v8 = dPiece[0][v7]; + v9 = dTransVal[0][v7]; + v10 = dung_map[0][v7]; + level_piece_id = v8; + v11 = (int)&a1[24576 * a4]; + v12 = (unsigned char)(nTransTable[v8] & TransList[v10]); + light_table_index = v9; + cel_transparency_active = v12; + v13 = (unsigned short *)((char *)dpiece_defs_map_1 + 32 * gendung_41927A(x, y)); + if ( !a4 ) + { + v14 = v13[2]; + level_cel_block = v13[2]; + if ( v14 ) + drawLowerScreen((void *)v11); + v15 = v13[3]; + level_cel_block = v13[3]; + if ( v15 ) + drawLowerScreen((void *)(v11 + 32)); + goto LABEL_10; + } + if ( a4 == 1 ) + { +LABEL_10: + v11 -= 24576; + level_cel_block = v13[4]; + if ( level_cel_block ) + drawLowerScreen((void *)v11); + v16 = v13[5]; + level_cel_block = v13[5]; + if ( v16 ) + drawLowerScreen((void *)(v11 + 32)); + goto LABEL_14; + } + if ( a4 != 2 ) + { + if ( a4 != 3 ) + goto LABEL_22; + goto LABEL_18; + } +LABEL_14: + v11 -= 24576; + level_cel_block = v13[6]; + if ( level_cel_block ) + drawLowerScreen((void *)v11); + v17 = v13[7]; + level_cel_block = v13[7]; + if ( v17 ) + drawLowerScreen((void *)(v11 + 32)); +LABEL_18: + v18 = v11 - 24576; + level_cel_block = v13[8]; + if ( level_cel_block ) + drawLowerScreen((void *)v18); + v19 = v13[9]; + level_cel_block = v13[9]; + if ( v19 ) + drawLowerScreen((void *)(v18 + 32)); +LABEL_22: + if ( a5 < 8 ) + scrollrt_4545D2(a1, xa, y, a4, a5, sx, sy, 0); + light_table_index = v23; + cel_transparency_active = v22; + result = v21; + level_piece_id = v21; + return result; +} +// 69BEF8: using guessed type int light_table_index; +// 69CF14: using guessed type int level_cel_block; +// 69CF94: using guessed type int cel_transparency_active; +// 69CF98: using guessed type int level_piece_id; + +//----- (00454D9D) -------------------------------------------------------- +void __fastcall scrollrt_454D9D(int x, int y, int sx, int sy, int a5, int a6, int some_flag) +{ + int v7; // edi + int v8; // esi + unsigned short *v9; // ebx + int v10; // ecx + int v11; // eax + char *v12; // edx + int v13; // edi + int v14; // eax + char *v15; // edi + int v16; // eax + char *v17; // edi + int v18; // eax + int v19; // eax + int v20; // esi + int v21; // eax + int v22; // ecx + int v23; // ecx + int v24; // eax + int v25; // esi + char *v26; // esi + int v27; // eax + int v28; // eax + int v29; // eax + bool v30; // zf + int v31; // ecx + int v32; // eax + char *v33; // esi + int v34; // eax + char *v35; // esi + int v36; // eax + char *v37; // esi + int v38; // eax + int v39; // eax + int v40; // [esp+Ch] [ebp-14h] + int v41; // [esp+10h] [ebp-10h] + int a5a; // [esp+14h] [ebp-Ch] + int ya; // [esp+18h] [ebp-8h] + signed int xa; // [esp+1Ch] [ebp-4h] + int i; // [esp+30h] [ebp+10h] + + v7 = y; + v8 = x; + ya = y; + xa = x; + v9 = (unsigned short *)((char *)dpiece_defs_map_1 + 32 * gendung_41927A(x, y)); + a5a = 2 * a6 + 2; + if ( a5a > 8 ) + a5a = 8; + if ( some_flag ) + { + if ( v7 >= 0 && v7 < 112 && v8 >= 0 && v8 < 112 ) + { + v10 = 112 * v8 + v7; + v11 = dPiece[0][v10]; + light_table_index = dTransVal[0][v10]; + level_piece_id = v11; + if ( v11 ) + { + cel_transparency_active = (unsigned char)(nTransTable[v11] & TransList[dung_map[0][v10]]); + v12 = (char *)gpBuffer + screen_y_times_768[sy]; + v13 = (int)&v12[sx + 32]; + if ( a6 >= 0 ) + { + v14 = v9[1]; + level_cel_block = v9[1]; + if ( v14 ) + { + arch_draw_type = 2; + drawUpperScreen(&v12[sx + 32]); + arch_draw_type = 0; + } + } + v15 = (char *)(v13 - 24576); + if ( a6 >= 1 ) + { + v16 = v9[3]; + level_cel_block = v9[3]; + if ( v16 ) + drawUpperScreen(v15); + } + v17 = v15 - 24576; + if ( a6 >= 2 ) + { + v18 = v9[5]; + level_cel_block = v9[5]; + if ( v18 ) + drawUpperScreen(v17); + } + if ( a6 >= 3 ) + { + v19 = v9[7]; + level_cel_block = v9[7]; + if ( v19 ) + drawUpperScreen(v17 - 24576); + } + v7 = ya; + scrollrt_dead2((char *)gpBuffer + screen_y_times_768[sy] + sx, xa, ya, a6, a5a, sx, sy, 0); + } + else + { + world_levelrelated((char *)gpBuffer + screen_y_times_768[sy] + sx); + } + } + sx += 64; + v8 = xa + 1; + --v7; + --a5; + ++xa; + ya = v7; + v9 += 16; + } + if ( a5 > 0 ) + { + v20 = 112 * v8; + v41 = v20; + v40 = a5; + do + { + if ( v7 >= 0 && v7 < 112 && v20 >= 0 && v20 < 12544 ) + { + v21 = dPiece[0][v20 + v7]; + light_table_index = dTransVal[0][v20 + v7]; + level_piece_id = v21; + if ( v21 ) + { + v22 = dung_map[0][v20 + v7]; + arch_draw_type = 1; + v23 = (unsigned char)(nTransTable[v21] & TransList[v22]); + v24 = *v9; + v25 = screen_y_times_768[sy]; + cel_transparency_active = v23; + level_cel_block = v24; + v26 = (char *)gpBuffer + v25 + sx; + if ( v24 ) + drawUpperScreen(v26); + v27 = v9[1]; + arch_draw_type = 2; + level_cel_block = v27; + if ( v27 ) + drawUpperScreen(v26 + 32); + arch_draw_type = 0; + for ( i = 1; i < (dword_5A5594 >> 1) - 1; ++i ) + { + v26 -= 24576; + if ( a6 >= i ) + { + v28 = v9[2 * i]; + level_cel_block = v9[2 * i]; + if ( v28 ) + drawUpperScreen(v26); + v29 = v9[2 * i + 1]; + level_cel_block = v9[2 * i + 1]; + if ( v29 ) + drawUpperScreen(v26 + 32); + } + } + scrollrt_dead2((char *)gpBuffer + screen_y_times_768[sy] + sx, xa, ya, a6, a5a, sx, sy, 1); + v7 = ya; + v20 = v41; + } + else + { + world_levelrelated((char *)gpBuffer + screen_y_times_768[sy] + sx); + } + } + ++xa; + sx += 64; + v20 += 112; + --v7; + v9 += 16; + v30 = v40-- == 1; + v41 = v20; + ya = v7; + } + while ( !v30 ); + } + if ( some_flag && v7 >= 0 && v7 < 112 && xa >= 0 && xa < 112 ) + { + v31 = 112 * xa + v7; + v32 = dPiece[0][v31]; + light_table_index = dTransVal[0][v31]; + level_piece_id = v32; + if ( v32 ) + { + arch_draw_type = 1; + cel_transparency_active = (unsigned char)(nTransTable[v32] & TransList[dung_map[0][v31]]); + v33 = (char *)gpBuffer + screen_y_times_768[sy] + sx; + if ( a6 >= 0 ) + { + v34 = *v9; + level_cel_block = *v9; + if ( v34 ) + drawUpperScreen(v33); + } + arch_draw_type = 0; + v35 = v33 - 24576; + if ( a6 >= 1 ) + { + v36 = v9[2]; + level_cel_block = v9[2]; + if ( v36 ) + drawUpperScreen(v35); + } + v37 = v35 - 24576; + if ( a6 >= 2 ) + { + v38 = v9[4]; + level_cel_block = v9[4]; + if ( v38 ) + drawUpperScreen(v37); + } + if ( a6 >= 3 ) + { + v39 = v9[6]; + level_cel_block = v9[6]; + if ( v39 ) + drawUpperScreen(v37 - 24576); + } + scrollrt_dead2((char *)gpBuffer + screen_y_times_768[sy] + sx, xa, ya, a6, a5a, sx, sy, 0); + } + else + { + world_levelrelated((char *)gpBuffer + screen_y_times_768[sy] + sx); + } + } +} +// 69BEF8: using guessed type int light_table_index; +// 69CF14: using guessed type int level_cel_block; +// 69CF20: using guessed type char arch_draw_type; +// 69CF94: using guessed type int cel_transparency_active; +// 69CF98: using guessed type int level_piece_id; + +//----- (00455217) -------------------------------------------------------- +void __fastcall scrollrt_dead2(char *buffer, int x, int y, int a4, int a5, int sx, int sy, int me_flag) +{ + int v8; // eax + char v9; // bl + char v10; // cl + char v11; // dl + int *v12; // eax + void **v13; // eax + int *v14; // esi + int v15; // ecx + int v16; // edx + char v17; // bl + ItemStruct *v18; // esi + char *v19; // eax + signed int v20; // ebx + int v21; // ebx + unsigned int v22; // ecx + PlayerStruct *v23; // esi + int v24; // esi + int v25; // eax + MonsterStruct *v26; // esi + CMonster *v27; // ecx + int v28; // ebx + int v29; // edi + unsigned int v30; // ecx + PlayerStruct *v31; // esi + int v32; // esi + int v33; // eax + MonsterStruct *v34; // esi + CMonster *v35; // ecx + int v36; // ebx + int v37; // edi + ItemStruct *v38; // esi + char *v39; // ecx + signed int v40; // ebx + int v41; // ebx + int v42; // [esp+Ch] [ebp-18h] + int v43; // [esp+10h] [ebp-14h] + char *dst_buf; // [esp+14h] [ebp-10h] + int xa; // [esp+18h] [ebp-Ch] + char v46; // [esp+1Dh] [ebp-7h] + char v47; // [esp+1Eh] [ebp-6h] + char v48; // [esp+1Fh] [ebp-5h] + char v49; // [esp+20h] [ebp-4h] + char v50; // [esp+21h] [ebp-3h] + char v51; // [esp+22h] [ebp-2h] + char v52; // [esp+23h] [ebp-1h] + + xa = x; + dst_buf = buffer; + v8 = 112 * x + y; + v9 = dDead[0][v8]; + v52 = dFlags[0][v8]; + v49 = dObject[0][v8]; + v51 = dItem[0][v8]; + v10 = dPlayer[0][v8 - 1]; + v50 = dPlayer[0][v8]; + v48 = dArch[0][v8]; + v11 = dung_map[0][v8]; + v12 = (int *)((char *)dMonster + 4 * v8); + v46 = v11; + v47 = v10; + v42 = *v12; + v43 = *(v12 - 1); + if ( visiondebug && v52 & 0x40 ) + Cel_header_into_buf(dst_buf, (char *)pSquareCel, 1, 64, 0, a5); + if ( MissilePreFlag && v52 & 1 ) + scrollrt_452994(xa, y, sx, sy, 0, a5, 1); + if ( light_table_index < lightmax ) + { + if ( v9 ) + { + v13 = &pCursCels + 12 * (v9 & 0x1F); + v14 = (int *)v13[(v9 >> 5) & 7]; + v15 = sx - (_DWORD)v13[10]; + if ( v14 ) + { + v16 = (int)v13[8]; + if ( v16 >= 1 && (unsigned int)*v14 <= 0x32 && v16 <= *v14 ) + { + v17 = *((_BYTE *)v13 + 44); + if ( v17 ) + engine_417981(v15, sy, v14, v16, (int)v13[9], 0, a5, v17); + else + engine_417AE9(v15, sy, v14, v16, (int)v13[9], 0, a5); + } + } + } + if ( v49 ) + scrollrt_objects2(xa, y, sx, sy, 1, 0, a5); + } + if ( v51 ) + { + v18 = &item_stru_6358B8 + v51; + if ( !v18->_iPostDraw && (unsigned char)v51 <= 0x7Fu ) + { + v19 = (char *)v18->ItemFrame; + if ( v19 ) + { + v20 = v18->_iAnimFrame; + if ( v20 >= 1 && *(_DWORD *)v19 <= 0x32u && v20 <= *(_DWORD *)v19 ) + { + v21 = sx - v18->_iAnimXOff; + if ( v51 - 1 == pcursitem ) + Cel_colour(181, v21, sy, v19, v18->_iAnimFrame, v18->_iAnimWidth, 0, a5); + Cel_header_and_light(v21, sy, (char *)v18->ItemFrame, v18->_iAnimFrame, v18->_iAnimWidth, 0, a5); + } + } + } + } + if ( v52 & 0x20 ) + { + v22 = -1 - v47; + if ( v22 < 4 ) + { + v23 = &plr[v22]; + scrollrt_draw_player_a( + v22, + xa, + y - 1, + sx + v23->_pxoff - v23->_pAnimWidth2, + sy + v23->_pyoff, + v23->_pAnimData, + v23->_pAnimFrame, + v23->_pAnimWidth, + 0, + a5); + if ( me_flag ) + { + v24 = v23->_peflag; + if ( v24 ) + { + if ( v24 == 2 ) + scrollrt_455A7D(dst_buf - 12384, xa - 2, y + 1, a4, a5, sx - 96, sy - 16); + scrollrt_455A7D(dst_buf - 64, xa - 1, y + 1, a4, a5, sx - 64, sy); + } + } + } + } + if ( v52 & 0x10 && (v52 & 0x40 || plr[myplr]._pInfraFlag) && v43 < 0 ) + { + v25 = -1 - v43; + draw_monster_num = -1 - v43; + if ( (unsigned int)(-1 - v43) < 0xC8 ) + { + v26 = &monster[v25]; + if ( !(v26->_mFlags & 1) ) + { + v27 = v26->MType; + if ( v27 ) + { + v28 = sy + v26->_myoff; + v29 = sx + v26->_mxoff - v27->flags_2; + if ( v25 == *(_DWORD *)&pcursmonst ) + { + engine_417847(233, v29, v28, (void *)v26->_mAFNum, v26->_mAnimFrame, v27->flags_1, 0, a5); + v25 = draw_monster_num; + } + scrollrt_monsters2(xa, y, v29, v28, v25, 0, a5); + if ( me_flag && !v26->_meflag ) + scrollrt_455A7D(dst_buf - 64, xa - 1, y + 1, a4, a5, sx - 64, sy); + } + } + } + } + if ( v52 & 4 ) + scrollrt_452CC0(xa, y, sx, sy, 0, a5, 0); + if ( v50 > 0 ) + { + v30 = v50 - 1; + if ( v30 < 4 ) + { + v31 = &plr[v30]; + scrollrt_draw_player_a( + v30, + xa, + y, + sx + v31->_pxoff - v31->_pAnimWidth2, + sy + v31->_pyoff, + v31->_pAnimData, + v31->_pAnimFrame, + v31->_pAnimWidth, + 0, + a5); + if ( me_flag ) + { + v32 = v31->_peflag; + if ( v32 ) + { + if ( v32 == 2 ) + scrollrt_455A7D(dst_buf - 12384, xa - 2, y + 1, a4, a5, sx - 96, sy - 16); + scrollrt_455A7D(dst_buf - 64, xa - 1, y + 1, a4, a5, sx - 64, sy); + } + } + } + } + if ( v42 > 0 && (v52 & 0x40 || plr[myplr]._pInfraFlag) ) + { + v33 = v42 - 1; + draw_monster_num = v42 - 1; + if ( (unsigned int)(v42 - 1) < 0xC8 ) + { + v34 = &monster[v33]; + if ( !(v34->_mFlags & 1) ) + { + v35 = v34->MType; + if ( v35 ) + { + v36 = sy + v34->_myoff; + v37 = sx + v34->_mxoff - v35->flags_2; + if ( v33 == *(_DWORD *)&pcursmonst ) + { + engine_417847(233, v37, v36, (void *)v34->_mAFNum, v34->_mAnimFrame, v35->flags_1, 0, a5); + v33 = draw_monster_num; + } + scrollrt_monsters2(xa, y, v37, v36, v33, 0, a5); + if ( me_flag && !v34->_meflag ) + scrollrt_455A7D(dst_buf - 64, xa - 1, y + 1, a4, a5, sx - 64, sy); + } + } + } + } + if ( v52 & 1 ) + scrollrt_452994(xa, y, sx, sy, 0, a5, 0); + if ( v49 && light_table_index < lightmax ) + scrollrt_objects2(xa, y, sx, sy, 0, 0, a5); + if ( v51 ) + { + v38 = &item_stru_6358B8 + v51; + if ( v38->_iPostDraw ) + { + if ( (unsigned char)v51 <= 0x7Fu ) + { + v39 = (char *)v38->ItemFrame; + if ( v39 ) + { + v40 = v38->_iAnimFrame; + if ( v40 >= 1 && *(_DWORD *)v39 <= 0x32u && v40 <= *(_DWORD *)v39 ) + { + v41 = sx - v38->_iAnimXOff; + if ( v51 - 1 == pcursitem ) + Cel_colour(181, v41, sy, v39, v38->_iAnimFrame, v38->_iAnimWidth, 0, a5); + Cel_header_and_light( + v41, + sy, + (char *)v38->ItemFrame, + v38->_iAnimFrame, + v38->_iAnimWidth, + 0, + a5); + } + } + } + } + } + if ( v48 ) + { + cel_transparency_active = (unsigned char)TransList[v46]; + Cel_header_light_and_trans_into_buf(dst_buf, (char *)level_special_cel, v48, 64, 0, a5); + } +} +// 4B8CC0: using guessed type char pcursitem; +// 525720: using guessed type int visiondebug; +// 642A14: using guessed type char lightmax; +// 64CCD4: using guessed type int MissilePreFlag; +// 69BEF8: using guessed type int light_table_index; +// 69CF94: using guessed type int cel_transparency_active; +// 69EFA4: using guessed type int draw_monster_num; + +//----- (00455844) -------------------------------------------------------- +void __fastcall scrollrt_monsters2(int x, int y, int a3, int a4, int mon_id, int a6, int a7) +{ + int v7; // eax + signed int *v8; // esi + signed int v9; // ebx + char v10; // cl + CMonster *v11; // eax + char mon_ida; // [esp+1Ch] [ebp+10h] + + if ( (unsigned int)mon_id < 0xC8 ) + { + v7 = mon_id; + v8 = (signed int *)monster[mon_id]._mAFNum; + if ( v8 ) + { + v9 = monster[v7]._mAnimFrame; + if ( v9 >= 1 && (unsigned int)*v8 <= 0x32 && v9 <= *v8 ) + { + if ( dFlags[x][y] & 0x40 ) + { + v10 = 0; + mon_ida = 0; + if ( monster[v7]._uniqtype ) + { + v10 = monster[v7]._uniqtrans + 4; + mon_ida = monster[v7]._uniqtrans + 4; + } + if ( monster[v7]._mmode == MM_STONE ) + { + v10 = 2; + mon_ida = 2; + } + if ( plr[myplr]._pInfraFlag && light_table_index > 8 ) + { + v10 = 1; + mon_ida = 1; + } + v11 = monster[v7].MType; + if ( v10 ) + engine_417981(a3, a4, v8, v9, v11->flags_1, a6, a7, mon_ida); + else + engine_417AE9(a3, a4, v8, v9, v11->flags_1, a6, a7); + } + else + { + engine_417981(a3, a4, v8, v9, monster[v7].MType->flags_1, a6, a7, 1); + } + } + } + } +} +// 69BEF8: using guessed type int light_table_index; + +//----- (00455937) -------------------------------------------------------- +void __fastcall scrollrt_objects2(int x, int y, int a3, int a4, int pre_flag, int a6, int dir) +{ + int v7; // edi + char v8; // al + unsigned char v9; // dl + int v10; // esi + int v11; // ebx + int v12; // edi + int v13; // eax + int v14; // ecx + char *v15; // eax + signed int v16; // ecx + char *v17; // eax + char v18; // [esp+Fh] [ebp-1h] + + v7 = y; + v8 = dObject[x][y]; + if ( v8 <= 0 ) + { + v9 = -1 - v8; + v10 = (char)(-1 - v8); + v18 = -1 - v8; + if ( object[v10]._oPreFlag != pre_flag ) + return; + dir = 8; + v13 = object[v10]._ox - x; + v14 = object[v10]._oy - v7; + v12 = a3 + 32 * v13 - object[v10]._oAnimWidth2 - 32 * v14; + v11 = a4 + 16 * (v14 + v13); + a6 = 0; + } + else + { + v9 = v8 - 1; + v10 = (char)(v8 - 1); + v18 = v8 - 1; + if ( object[v10]._oPreFlag != pre_flag ) + return; + v11 = a4; + v12 = a3 - object[v10]._oAnimWidth2; + } + if ( v9 < 0x7Fu ) + { + v15 = (char *)object[v10]._oAnimCel; + if ( v15 ) + { + v16 = object[v10]._oAnimFrame; + if ( v16 >= 1 && *(_DWORD *)v15 <= 0x32u && v16 <= *(_DWORD *)v15 ) + { + if ( v18 == pcursobj ) + Cel_colour(194, v12, v11, v15, v16, object[v10]._oAnimWidth, a6, dir); + if ( object[v10]._oLight ) + { + Cel_header_and_light( + v12, + v11, + (char *)object[v10]._oAnimCel, + object[v10]._oAnimFrame, + object[v10]._oAnimWidth, + a6, + dir); + } + else + { + v17 = (char *)object[v10]._oAnimCel; + if ( v17 ) + Cel_header(v12, v11, v17, object[v10]._oAnimFrame, object[v10]._oAnimWidth, a6, dir); + } + } + } + } +} +// 4B8CC1: using guessed type char pcursobj; + +//----- (00455A7D) -------------------------------------------------------- +void __fastcall scrollrt_455A7D(char *buffer, int x, int y, int a4, int a5, int sx, int sy) +{ + int v7; // eax + char *v8; // esi + int v9; // ecx + int v10; // ebx + int v11; // edx + int v12; // eax + int v13; // eax + int v14; // ecx + int v15; // edi + int v16; // eax + unsigned short *v17; // esi + int v18; // eax + int v19; // eax + int v20; // eax + int v21; // eax + int v22; // [esp+Ch] [ebp-14h] + int xa; // [esp+10h] [ebp-10h] + int *a1; // [esp+14h] [ebp-Ch] + char *v25; // [esp+18h] [ebp-8h] + int i; // [esp+1Ch] [ebp-4h] + + xa = x; + v22 = level_piece_id; + v7 = 112 * x + y; + v8 = buffer; + v9 = dPiece[0][v7]; + v10 = cel_transparency_active; + v11 = dTransVal[0][v7]; + v12 = dung_map[0][v7]; + level_piece_id = v9; + v13 = (unsigned char)TransList[v12]; + v14 = (unsigned char)nTransTable[v9]; + v15 = light_table_index; + light_table_index = v11; + a1 = (int *)v8; + v25 = v8; + cel_transparency_active = v14 & v13; + v16 = gendung_41927A(xa, y); + arch_draw_type = 1; + v17 = (unsigned short *)((char *)dpiece_defs_map_1 + 32 * v16); + v18 = *v17; + level_cel_block = *v17; + if ( v18 ) + drawUpperScreen(a1); + v19 = v17[1]; + arch_draw_type = 2; + level_cel_block = v19; + if ( v19 ) + drawUpperScreen(a1 + 8); + arch_draw_type = 0; + for ( i = 1; i < (dword_5A5594 >> 1) - 1; ++i ) + { + v25 -= 24576; + if ( a4 >= i ) + { + v20 = v17[2 * i]; + level_cel_block = v17[2 * i]; + if ( v20 ) + drawUpperScreen(v25); + v21 = v17[2 * i + 1]; + level_cel_block = v17[2 * i + 1]; + if ( v21 ) + drawUpperScreen(v25 + 32); + } + } + scrollrt_dead2((char *)a1, xa, y, a4, a5, sx, sy, 0); + light_table_index = v15; + cel_transparency_active = v10; + level_piece_id = v22; +} +// 69BEF8: using guessed type int light_table_index; +// 69CF14: using guessed type int level_cel_block; +// 69CF20: using guessed type char arch_draw_type; +// 69CF94: using guessed type int cel_transparency_active; +// 69CF98: using guessed type int level_piece_id; + +//----- (00455BD4) -------------------------------------------------------- +void __fastcall DrawZoom(int x, int y) +{ + int v2; // edi + int v3; // ebx + int v4; // esi + int v5; // esi + int v6; // edi + int v7; // esi + int v8; // edi + int v9; // esi + int v10; // edi + _WORD *v11; // edi + char *v12; // esi + char *v13; // ebx + signed int v14; // edx + signed int v15; // ecx + short v16; // ax + int v17; // eax + signed int v18; // [esp+Ch] [ebp-10h] + signed int v19; // [esp+Ch] [ebp-10h] + signed int a5; // [esp+10h] [ebp-Ch] + int a5a; // [esp+10h] [ebp-Ch] + signed int a6; // [esp+14h] [ebp-8h] + signed int a6a; // [esp+14h] [ebp-8h] + int a6b; // [esp+14h] [ebp-8h] + int ya; // [esp+18h] [ebp-4h] + + v2 = ScrollInfo._sxoff + 64; + dword_5C2FF8 = 6; + dword_5C2FFC = 6; + v3 = x - 6; + ya = y - 1; + a5 = 6; + v4 = ScrollInfo._syoff + 143; + scr_pix_width = 384; + scr_pix_height = 192; + v18 = 3; + switch ( ScrollInfo._sdir ) + { + case DIR_SW: + goto LABEL_3; + case DIR_W: + a5 = 7; +LABEL_3: + v4 = ScrollInfo._syoff + 111; + v3 = x - 7; + ya = y - 2; + goto LABEL_9; + case DIR_NW: + goto LABEL_7; + case DIR_N: + v18 = 4; + goto LABEL_7; + case DIR_NE: + goto LABEL_9; + case DIR_E: + v18 = 4; + goto LABEL_6; + case DIR_SE: +LABEL_6: + v2 = ScrollInfo._sxoff; + v3 = x - 7; + ya = y; +LABEL_7: + a5 = 7; + break; + case DIR_OMNI: + v2 = ScrollInfo._sxoff; + v4 = ScrollInfo._syoff + 111; + a5 = 7; + v3 = x - 8; +LABEL_9: + v18 = 4; + break; + default: + break; + } + a6 = 0; + screen_buf_end = (int)gpBuffer + screen_y_times_768[143]; + do + { + scrollrt_454D9D(v3, ya++, v2, v4, a5, a6, 0); + v5 = v4 + 16; + v6 = v2 - 32; + scrollrt_454D9D(v3++, ya, v6, v5, a5, a6, 1); + v2 = v6 + 32; + v4 = v5 + 16; + ++a6; + } + while ( a6 < 4 ); + screen_buf_end = (int)gpBuffer + screen_y_times_768[320]; + if ( v18 > 0 ) + { + do + { + scrollrt_levels(v3, ya++, v2, v4, a5, 0); + v7 = v4 + 16; + v8 = v2 - 32; + scrollrt_levels(v3++, ya, v8, v7, a5, 1); + v2 = v8 + 32; + v4 = v7 + 16; + --v18; + } + while ( v18 ); + } + arch_draw_type = 0; + a6a = 0; + do + { + scrollrt_454229(v3, ya++, v2, v4, a5, a6a, 0); + v9 = v4 + 16; + v10 = v2 - 32; + scrollrt_454229(v3++, ya, v10, v9, a5, a6a, 1); + v2 = v10 + 32; + v4 = v9 + 16; + ++a6a; + } + while ( a6a < 4 ); + if ( chrflag || questlog ) + { + a6b = 392064; + goto LABEL_23; + } + if ( invflag || sbookflag ) + { + a6b = 391744; +LABEL_23: + a5a = 245168; + v19 = 160; + goto LABEL_24; + } + a5a = 245088; + a6b = 391744; + v19 = 320; +LABEL_24: + v11 = (_WORD *)((char *)gpBuffer + a6b); + v12 = (char *)gpBuffer + a5a; + v13 = &gpBuffer->row_unused_1[1].col_unused_1[a6b]; + v14 = 176; + do + { + v15 = v19; + do + { + _LOBYTE(v16) = *v12++; + _HIBYTE(v16) = v16; + *v11 = v16; + *(_WORD *)v13 = v16; + ++v11; + v13 += 2; + --v15; + } + while ( v15 ); + v12 += -v19 - 768; + v17 = 2 * (v19 + 768); + v13 -= v17; + v11 = (_WORD *)((char *)v11 - v17); + --v14; + } + while ( v14 ); +} +// 4B8968: using guessed type int sbookflag; +// 5C2FF8: using guessed type int dword_5C2FF8; +// 5C2FFC: using guessed type int dword_5C2FFC; +// 5C3000: using guessed type int scr_pix_width; +// 5C3004: using guessed type int scr_pix_height; +// 69BD04: using guessed type int questlog; +// 69CF0C: using guessed type int screen_buf_end; +// 69CF20: using guessed type char arch_draw_type; + +//----- (00455E32) -------------------------------------------------------- +void __cdecl ClearScreenBuffer() +{ + char *v0; // edi + signed int v1; // edx + + dx_lock_mutex(); + v0 = gpBuffer->row[0].pixels; + v1 = 480; + do + { + memset(v0, 0, 0x280u); + v0 += 768; + --v1; + } + while ( v1 ); + dx_unlock_mutex(); +} + +//----- (00455E65) -------------------------------------------------------- +void __fastcall scrollrt_455E65(int some_flag) +{ + int v1; // ebx + int v2; // edi + + v1 = some_flag; + if ( force_redraw == 255 ) + { + force_redraw = 0; + v2 = 480; + } + else + { + v2 = 0; + } + if ( some_flag ) + { + dx_lock_mutex(); + scrollrt_455F56(); + dx_unlock_mutex(); + } + scrollrt_main_stuff(v2, 0, 0, 0, 0, 0); + if ( v1 ) + { + dx_lock_mutex(); + scrollrt_455EC7(); + dx_unlock_mutex(); + } +} +// 52571C: using guessed type int force_redraw; + +//----- (00455EC7) -------------------------------------------------------- +void __cdecl scrollrt_455EC7() +{ + int v0; // edx + int v1; // eax + char *v2; // edi + char *v3; // esi + int v4; // ecx + int v5; // ebx + + v0 = sgdwCursWdt; + if ( sgdwCursWdt ) + { + v1 = sgdwCursY; + v2 = cursor_draw_back_buffer; + v3 = &gpBuffer->row[sgdwCursY].pixels[sgdwCursX]; + v4 = sgdwCursHgt; + if ( sgdwCursHgt ) + { + v5 = sgdwCursHgt; + do + { + memcpy(v3, v2, v0); + v0 = sgdwCursWdt; + v2 += sgdwCursWdt; + v3 += 768; + --v5; + } + while ( v5 ); + v1 = sgdwCursY; + v4 = sgdwCursHgt; + } + sgdwCursWdt = 0; + sgdwCursXOld = sgdwCursX; + sgdwCursYOld = v1; + sgdwCursWdtOld = v0; + sgdwCursHgtOld = v4; + } +} + +//----- (00455F56) -------------------------------------------------------- +void __cdecl scrollrt_455F56() +{ + int v0; // ebp + int v1; // edx + int v2; // edi + int v3; // esi + unsigned int v4; // eax + unsigned int v5; // eax + int v6; // eax + char *v7; // ebx + int v8; // ebp + int v9; // edi + int v10; // esi + signed int v11; // ebx + int v12; // edi + int v13; // edx + char *v14; // [esp+10h] [ebp-4h] + + if ( pcurs > 0 ) + { + v0 = cursW; + if ( cursW ) + { + v1 = cursH; + if ( cursH ) + { + v2 = MouseX - 1; + if ( MouseX - 1 >= 0 ) + { + if ( v2 > 639 ) + return; + } + else + { + v2 = 0; + } + v3 = MouseY - 1; + if ( MouseY - 1 >= 0 ) + { + if ( v3 > 479 ) + return; + } + else + { + v3 = 0; + } + v4 = v2 + cursW + 1; + if ( v4 > 0x27F ) + v4 = 639; + _LOBYTE(v4) = v4 | 3; + sgdwCursY = v3; + sgdwCursX = v2 & 0xFFFFFFFC; + sgdwCursWdt = v4 - (v2 & 0xFFFFFFFC) + 1; + v5 = cursH + v3 + 1; + if ( v5 > 0x1DF ) + v5 = 479; + v14 = cursor_draw_back_buffer; + v6 = 1 - v3 + v5; + sgdwCursHgt = v6; + v7 = &gpBuffer->row[v3].pixels[v2 & 0xFFFFFFFC]; + if ( v6 ) + { + v8 = v6; + do + { + memcpy(v14, v7, sgdwCursWdt); + v14 += sgdwCursWdt; + v7 += 768; + --v8; + } + while ( v8 ); + v0 = cursW; + v1 = cursH; + } + v9 = v2 + 1; + v10 = v3 + 1; + screen_buf_end = (int)gpBuffer + screen_y_times_768[640] - v0 - 2; + if ( pcurs < 12 ) + { + Cel2_header(v9 + 64, v1 + v10 + 159, (char *)pCursCels, pcurs, v0, 0, 8); + } + else + { + v11 = 197; + if ( plr[myplr].HoldItem._iMagical ) + v11 = 181; + if ( !plr[myplr].HoldItem._iStatFlag ) + v11 = 229; + v12 = v9 + 64; + Cel_header_and_colour_highlight(v11, v12, v1 + v10 + 159, (char *)pCursCels, pcurs, v0, 0, 8); + v13 = cursH + v10 + 159; + if ( v11 == 229 ) + Cel2_header_and_light_not_equipable(v12, v13, (char *)pCursCels, pcurs, cursW, 0, 8, 1); + else + Cel2_header(v12, v13, (char *)pCursCels, pcurs, cursW, 0, 8); + } + } + } + } +} +// 4B8C9C: using guessed type int cursH; +// 69CF0C: using guessed type int screen_buf_end; + +//----- (00456124) -------------------------------------------------------- +void __fastcall scrollrt_main_stuff(int dwHgt, int some_flag, int draw_hp, int draw_mana, int draw_sbar, int draw_btn) +{ + signed int v6; // ebp + DWORD v7; // ebx + int v8; // esi + int v9; // eax + signed int a4; // [esp+1Ch] [ebp-8h] + int v11; // [esp+20h] [ebp-4h] + + v11 = some_flag; + a4 = dwHgt; + if ( window_activated && lpDDSPrimary ) + { + if ( IDirectDrawSurface_IsLost(lpDDSPrimary) == 0x887601C2 ) + { + if ( IDirectDrawSurface_Restore(lpDDSPrimary) ) + return; + ResetPal(); + a4 = 480; + } + if ( !lpDDSBackBuf ) + { + v6 = 1; +LABEL_8: + v7 = GetTickCount(); + while ( 1 ) + { + DDS_desc.dwSize = 108; + v8 = IDirectDrawSurface_Lock(lpDDSPrimary, 0, &DDS_desc, 33, 0); + if ( !v8 ) + break; + if ( v7 - GetTickCount() > 5000 ) + goto LABEL_17; + Sleep(1u); + if ( v8 == 0x887601C2 ) + return; + if ( v8 != 0x8876021C && v8 != 0x887601AE ) + { + if ( v6 && v8 == 0x80004005 ) + { + v6 = 0; + dx_reinit(); + a4 = 480; + goto LABEL_8; + } +LABEL_17: + if ( v8 != 0x887601C2 && v8 != 0x8876021C && v8 != 0x887601AE ) + { + DDErrDlg(v8, 3707, "C:\\Src\\Diablo\\Source\\SCROLLRT.CPP"); + break; + } + return; + } + } + } + if ( a4 > 0 ) + scrollrt_draw_item(0, 0, 640, a4); + if ( a4 < 480 ) + { + if ( draw_sbar ) + scrollrt_draw_item(204, 357, 232, 28); + if ( v11 ) + scrollrt_draw_item(176, 398, 288, 60); + if ( draw_mana ) + { + scrollrt_draw_item(460, 352, 88, 72); + scrollrt_draw_item(564, 416, 56, 56); + } + if ( draw_hp ) + scrollrt_draw_item(96, 352, 88, 72); + if ( draw_btn ) + { + scrollrt_draw_item(8, 357, 72, 119); + scrollrt_draw_item(556, 357, 72, 48); + if ( (unsigned char)gbMaxPlayers > 1u ) + { + scrollrt_draw_item(84, 443, 36, 32); + scrollrt_draw_item(524, 443, 36, 32); + } + } + if ( sgdwCursWdtOld ) + scrollrt_draw_item(sgdwCursXOld, sgdwCursYOld, sgdwCursWdtOld, sgdwCursHgtOld); + if ( sgdwCursWdt ) + scrollrt_draw_item(sgdwCursX, sgdwCursY, sgdwCursWdt, sgdwCursHgt); + } + if ( !lpDDSBackBuf ) + { + v9 = IDirectDrawSurface_Unlock(lpDDSPrimary, 0); + if ( v9 != 0x887601C2 ) + { + if ( v9 ) + DDErrDlg(v9, 3779, "C:\\Src\\Diablo\\Source\\SCROLLRT.CPP"); + } + } + } +} +// 634980: using guessed type int window_activated; +// 679660: using guessed type char gbMaxPlayers; + +//----- (004563B3) -------------------------------------------------------- +void __fastcall scrollrt_draw_item(int dwX, int dwY, int dwWdt, int dwHgt) +{ + int v4; // esi + int v5; // edi + int v6; // ecx + char *v7; // esi + char *v8; // edi + int v9; // edx + int v10; // [esp+Ch] [ebp-20h] + int v11; // [esp+10h] [ebp-1Ch] + int v12; // [esp+14h] [ebp-18h] + int v13; // [esp+18h] [ebp-14h] + int v14; // [esp+1Ch] [ebp-10h] + LONG v15; // [esp+20h] [ebp-Ch] + int v16; // [esp+24h] [ebp-8h] + LONG v17; // [esp+28h] [ebp-4h] + HRESULT error_code; // [esp+34h] [ebp+8h] + int error_codea; // [esp+34h] [ebp+8h] + int a4; // [esp+38h] [ebp+Ch] + + v4 = dwY; + v5 = dwX; + if ( lpDDSBackBuf ) + { + v10 = dwX + 64; + v12 = dwX + 64 + dwWdt - 1; + v11 = dwY + 160; + v13 = dwY + 160 + dwHgt - 1; + a4 = GetTickCount(); + while ( 1 ) + { + error_code = IDirectDrawSurface_BltFast(lpDDSPrimary, v5, v4, lpDDSBackBuf, (LPRECT)&v10, 16); + if ( !error_code ) + break; + if ( a4 - GetTickCount() <= 0x1388 ) + { + Sleep(1u); + if ( error_code == 0x887601C2 ) + return; + if ( error_code == 0x8876021C || error_code == 0x887601AE ) + continue; + } + if ( error_code != 0x887601C2 && error_code != 0x8876021C && error_code != 0x887601AE ) + DDErrDlg(error_code, 3596, "C:\\Src\\Diablo\\Source\\SCROLLRT.CPP"); + return; + } + } + else + { + v14 = 768 * dwY + dwX + 0x1E040; + v17 = DDS_desc.lPitch - dwWdt; + v15 = dwX + dwY * DDS_desc.lPitch; + v6 = 768 - dwWdt; + error_codea = (unsigned int)dwWdt >> 2; + v16 = v6; + dx_lock_mutex(); + v7 = (char *)gpBuffer + v14; + v8 = (char *)DDS_desc.lpSurface + v15; + v9 = dwHgt; + do + { + qmemcpy(v8, v7, 4 * error_codea); + v7 += 4 * error_codea + v16; + v8 += 4 * error_codea + v17; + --v9; + } + while ( v9 ); + dx_unlock_mutex(); + } +} + +//----- (004564F9) -------------------------------------------------------- +void __cdecl DrawAndBlit() +{ + int v0; // ebp + signed int v1; // esi + int v2; // edi + + if ( gbRunGame ) + { + if ( force_redraw == 255 ) + { + drawhpflag = 1; + drawmanaflag = 1; + drawbtnflag = 1; + drawsbarflag = 1; + v0 = 0; + v1 = 1; + v2 = 480; + } + else + { + if ( force_redraw != 1 ) + return; + v0 = 1; + v1 = 0; + v2 = 352; + } + force_redraw = 0; + dx_lock_mutex(); + if ( leveltype ) + DrawView(ViewX, ViewY); + else + T_DrawView(ViewX, ViewY); + if ( v1 ) + ClearCtrlPan(); + if ( drawhpflag ) + UpdateLifeFlask(); + if ( drawmanaflag ) + UpdateManaFlask(); + if ( drawbtnflag ) + DrawCtrlPan(); + if ( drawsbarflag ) + DrawInvBelt(); + if ( talkflag ) + { + DrawTalkPan(); + v2 = 480; + } + scrollrt_455F56(); + dx_unlock_mutex(); + scrollrt_main_stuff(v2, v0, drawhpflag, drawmanaflag, drawsbarflag, drawbtnflag); + dx_lock_mutex(); + scrollrt_455EC7(); + dx_unlock_mutex(); + drawhpflag = 0; + drawmanaflag = 0; + drawbtnflag = 0; + drawsbarflag = 0; + } +} +// 4B8960: using guessed type int talkflag; +// 525650: using guessed type int gbRunGame; +// 52571C: using guessed type int force_redraw; +// 5BB1ED: using guessed type char leveltype; + +//----- (00456625) -------------------------------------------------------- +int __fastcall ObjIndex(int x, int y) +{ + int v2; // edi + int result; // eax + int v4; // esi + + v2 = 0; + if ( nobjects <= 0 ) + { +LABEL_5: + TermMsg("ObjIndex: Active object not found at (%d,%d)", x, y); + result = -1; + } + else + { + while ( 1 ) + { + result = objectactive[v2]; + v4 = objectactive[v2]; + if ( object[v4]._ox == x && object[v4]._oy == y ) + break; + if ( ++v2 >= nobjects ) + goto LABEL_5; + } + } + return result; +} + +//----- (0045666B) -------------------------------------------------------- +void __cdecl AddSKingObjs() +{ + int v0; // eax + int v1; // eax + int v2; // eax + int v3; // eax + int v4; // eax + int v5; // eax + + v0 = ObjIndex(64, 34); + SetObjMapRange(v0, 20, 7, 23, 10, 1); + v1 = ObjIndex(64, 59); + SetObjMapRange(v1, 20, 14, 21, 16, 2); + v2 = ObjIndex(27, 37); + SetObjMapRange(v2, 8, 1, 15, 11, 3); + v3 = ObjIndex(46, 35); + SetObjMapRange(v3, 8, 1, 15, 11, 3); + v4 = ObjIndex(49, 53); + SetObjMapRange(v4, 8, 1, 15, 11, 3); + v5 = ObjIndex(27, 53); + SetObjMapRange(v5, 8, 1, 15, 11, 3); +} + +//----- (0045671A) -------------------------------------------------------- +void __cdecl AddSChamObjs() +{ + int v0; // eax + int v1; // eax + + v0 = ObjIndex(37, 30); + SetObjMapRange(v0, 17, 0, 21, 5, 1); + v1 = ObjIndex(37, 46); + SetObjMapRange(v1, 13, 0, 16, 5, 2); +} + +//----- (00456755) -------------------------------------------------------- +void __cdecl AddVileObjs() +{ + int v0; // eax + int v1; // eax + int v2; // eax + + v0 = ObjIndex(26, 45); + SetObjMapRange(v0, 1, 1, 9, 10, 1); + v1 = ObjIndex(45, 46); + SetObjMapRange(v1, 11, 1, 20, 10, 2); + v2 = ObjIndex(35, 36); + SetObjMapRange(v2, 7, 11, 13, 18, 3); +} + +//----- (004567AD) -------------------------------------------------------- +void __fastcall DRLG_SetMapTrans(char *dun_path) +{ + unsigned char *v1; // ecx + int v2; // ebx + int v3; // edi + int v4; // eax + int v5; // edi + int v6; // eax + int v7; // ebx + char *v8; // esi + char *v9; // eax + int v10; // [esp+Ch] [ebp-8h] + int v11; // [esp+10h] [ebp-4h] + + v1 = LoadFileInMem(dun_path, 0); + v11 = 0; + v2 = *v1; + v3 = v1[2]; + v4 = v3; + v5 = 2 * v3; + v6 = v2 * v4; + v7 = 2 * v2; + v8 = (char *)&v1[6 * v7 * v5 + 4 + 2 * v6]; + if ( v5 > 0 ) + { + do + { + if ( v7 > 0 ) + { + v10 = v7; + v9 = &dung_map[16][v11 + 16]; + do + { + *v9 = *v8; + v8 += 2; + v9 += 112; + --v10; + } + while ( v10 ); + } + ++v11; + } + while ( v11 < v5 ); + } + mem_free_dbg(v1); +} + +//----- (00456819) -------------------------------------------------------- +void __cdecl LoadSetMap() +{ + switch ( setlvlnum ) + { + case SL_SKELKING: + if ( quests[12]._qactive == 1 ) + { + quests[12]._qactive = 2; + quests[12]._qvar1 = 1; + } + LoadPreL1Dungeon("Levels\\L1Data\\SklKng1.DUN", 83, 45); + LoadL1Dungeon("Levels\\L1Data\\SklKng2.DUN", 83, 45); + LoadPalette("Levels\\L1Data\\L1_2.pal"); + DRLG_AreaTrans(2, (unsigned char *)QSRects); + DRLG_ListTrans(2, (unsigned char *)&QSRects[2]); + DRLG_AreaTrans(5, (unsigned char *)&QSRects[4]); + DRLG_ListTrans(7, (unsigned char *)&QSRects[9]); + AddL1Objs(0, 0, 112, 112); + AddSKingObjs(); + InitSKingTriggers(); + break; + case SL_BONECHAMB: + LoadPreL2Dungeon("Levels\\L2Data\\Bonecha2.DUN", 69, 39); + LoadL2Dungeon("Levels\\L2Data\\Bonecha1.DUN", 69, 39); + LoadPalette("Levels\\L2Data\\L2_2.pal"); + DRLG_ListTrans(5, (unsigned char *)&QSRects[16]); + DRLG_AreaTrans(2, (unsigned char *)&QSRects[21]); + DRLG_ListTrans(9, (unsigned char *)&QSRects[23]); + AddL2Objs(0, 0, 112, 112); + AddSChamObjs(); + InitSChambTriggers(); + break; + case SL_MAZE: + LoadPreL1Dungeon("Levels\\L1Data\\Lv1MazeA.DUN", 20, 50); + LoadL1Dungeon("Levels\\L1Data\\Lv1MazeB.DUN", 20, 50); + LoadPalette("Levels\\L1Data\\L1_5.pal"); + AddL1Objs(0, 0, 112, 112); + DRLG_SetMapTrans("Levels\\L1Data\\Lv1MazeA.DUN"); + break; + case SL_POISONWATER: + if ( quests[13]._qactive == 1 ) + quests[13]._qactive = 2; + LoadPreL3Dungeon("Levels\\L3Data\\Foulwatr.DUN", 19, 50); + LoadL3Dungeon("Levels\\L3Data\\Foulwatr.DUN", 20, 50); + LoadPalette("Levels\\L3Data\\L3pfoul.pal"); + InitPWaterTriggers(); + break; + case SL_VILEBETRAYER: + if ( quests[15]._qactive == 3 ) + { + quests[15]._qvar2 = 4; + } + else if ( quests[15]._qactive == 2 ) + { + quests[15]._qvar2 = 3; + } + LoadPreL1Dungeon("Levels\\L1Data\\Vile1.DUN", 35, 36); + LoadL1Dungeon("Levels\\L1Data\\Vile2.DUN", 35, 36); + LoadPalette("Levels\\L1Data\\L1_2.pal"); + AddL1Objs(0, 0, 112, 112); + AddVileObjs(); + DRLG_SetMapTrans("Levels\\L1Data\\Vile1.DUN"); + InitNoTriggers(); + break; + } +} +// 5CCB10: using guessed type char setlvlnum; + +//----- (00456A16) -------------------------------------------------------- +void __cdecl sha1_reset() +{ + memset(sha1_contexts, 0, 0x114u); +} + +//----- (00456A2B) -------------------------------------------------------- +void __fastcall sha1_final(int ctx_id, char (*dst)[20]) +{ + char (*v2)[20]; // eax + SHA1Context *v3; // ecx + signed int v4; // edx + int v5; // esi + + v2 = dst; + if ( dst ) + { + v3 = &sha1_contexts[ctx_id]; + v4 = 5; + do + { + v5 = v3->state[0]; + v3 = (SHA1Context *)((char *)v3 + 4); + *(_DWORD *)v2 = v5; + v2 = (char (*)[20])((char *)v2 + 4); + --v4; + } + while ( v4 ); + } +} + +//----- (00456A4D) -------------------------------------------------------- +void __fastcall sha1(int ctx_id, const char *data, char (*dst)[20]) +{ + int v3; // esi + + v3 = ctx_id; + sha1_update(&sha1_contexts[ctx_id], data, 64); + if ( dst ) + sha1_final(v3, dst); +} + +//----- (00456A73) -------------------------------------------------------- +void __fastcall sha1_update(SHA1Context *ctx, const char *data, int len) +{ + SHA1Context *v3; // esi + const char *v4; // ebx + int v5; // ecx + int v6; // edx + unsigned int v7; // ebp + + v3 = ctx; + v4 = data; + v5 = ctx->count[0]; + v6 = v5 + 8 * len; + if ( v6 < v5 ) + ++v3->count[1]; + v3->count[0] = v6; + v3->count[1] += len >> 29; + if ( len >= 64 ) + { + v7 = (unsigned int)len >> 6; + do + { + memcpy(v3->buffer, v4, 0x40u); + sha1_transform(v3); + v4 += 64; + --v7; + } + while ( v7 ); + } +} + +//----- (00456AC4) -------------------------------------------------------- +void __fastcall sha1_transform(SHA1Context *ctx) +{ + SHA1Context *v1; // eax + char *v2; // ecx + signed int v3; // edx + int v4; // esi + int v5; // ecx + int v6; // edx + int v7; // edi + int v8; // ecx + int v9; // edx + int v10; // esi + int v11; // ebx + int v12; // esi + int v13; // ecx + int v14; // esi + int v15; // ecx + char v16[320]; // [esp+Ch] [ebp-150h] + int v17; // [esp+14Ch] [ebp-10h] + int v18; // [esp+150h] [ebp-Ch] + int v19; // [esp+154h] [ebp-8h] + int v20; // [esp+158h] [ebp-4h] + + v1 = ctx; + qmemcpy(v16, ctx->buffer, 0x40u); + v2 = &v16[8]; + v3 = 64; + do + { + v4 = *(_DWORD *)v2 ^ *((_DWORD *)v2 - 2) ^ *((_DWORD *)v2 + 6) ^ *((_DWORD *)v2 + 11); + v2 += 4; + --v3; + *((_DWORD *)v2 + 13) = v4; + } + while ( v3 ); + v5 = v1->state[0]; + v6 = v1->state[3]; + v7 = v1->state[2]; + v20 = 0; + v18 = v5; + v8 = v1->state[1]; + v19 = v6; + v9 = v1->state[4]; + v17 = v7; + do + { + v10 = *(_DWORD *)&v16[4 * v20] + (32 * v18 | (v18 >> 27)) + (v8 & v7 | v19 & ~v8) + v9 + 0x5A827999; + v9 = v19; + v19 = v17; + v7 = (v8 >> 2) | (v8 << 30); + ++v20; + v8 = v18; + v17 = v7; + v18 = v10; + } + while ( v20 < 20 ); + v20 = 20; + do + { + v10 = *(_DWORD *)&v16[4 * v20] + (v8 ^ v7 ^ v19) + (32 * v10 | (v10 >> 27)) + v9 + 0x6ED9EBA1; + v9 = v19; + v19 = v7; + v7 = (v8 >> 2) | (v8 << 30); + ++v20; + v8 = v18; + v18 = v10; + } + while ( v20 < 40 ); + v17 = v7; + v20 = 40; + do + { + v10 = *(_DWORD *)&v16[4 * v20] + (32 * v10 | (v10 >> 27)) + (v8 & v7 | v19 & (v8 | v7)) + v9 - 0x70E44324; + v9 = v19; + v19 = v17; + v7 = (v8 >> 2) | (v8 << 30); + ++v20; + v8 = v18; + v17 = v7; + v18 = v10; + } + while ( v20 < 60 ); + v20 = 60; + do + { + v10 = *(_DWORD *)&v16[4 * v20] + (v8 ^ v7 ^ v19) + (32 * v10 | (v10 >> 27)) + v9 - 0x359D3E2A; + v9 = v19; + v19 = v7; + v7 = (v8 >> 2) | (v8 << 30); + ++v20; + v8 = v18; + v18 = v10; + } + while ( v20 < 80 ); + v11 = v10 + v1->state[0]; + v12 = v8 + v1->state[1]; + v13 = v7 + v1->state[2]; + v1->state[1] = v12; + v14 = v19; + v1->state[2] = v13; + v15 = v14 + v1->state[3]; + v1->state[0] = v11; + v1->state[3] = v15; + v1->state[4] += v9; +} + +//----- (00456C82) -------------------------------------------------------- +void __fastcall sha1_init(int ctx_id) +{ + SHA1Context *v1; // ecx + + v1 = &sha1_contexts[ctx_id]; + v1->count[0] = 0; + v1->count[1] = 0; + v1->state[0] = 0x67452301; + v1->state[1] = 0xEFCDAB89; + v1->state[2] = 0x98BADCFE; + v1->state[3] = 0x10325476; + v1->state[4] = 0xC3D2E1F0; +} + +//----- (00456CC0) -------------------------------------------------------- +void __cdecl sound_cpp_init() +{ + LODWORD(sound_cpp_init_value) = sound_inf; +} +// 47F24C: using guessed type int sound_inf; + +//----- (00456CCB) -------------------------------------------------------- +void __fastcall snd_update(bool bStopAll) +{ + BOOL v1; // edi + unsigned int v2; // esi + IDirectSoundBuffer *v3; // eax + int v4; // [esp+8h] [ebp-4h] + + v1 = bStopAll; + v2 = 0; + do + { + v3 = DSBs[v2]; + if ( v3 && (v1 || IDirectSoundBuffer_GetStatus(v3, (unsigned long *)&v4) || v4 != 1) ) + { + IDirectSoundBuffer_Stop(DSBs[v2]); + IDirectSoundBuffer_Release(DSBs[v2]); + DSBs[v2] = 0; + } + ++v2; + } + while ( v2 < 8 ); +} + +//----- (00456D22) -------------------------------------------------------- +void __fastcall snd_stop_snd(TSnd *pSnd) +{ + IDirectSoundBuffer *v1; // eax + + if ( pSnd ) + { + v1 = pSnd->DSB; + if ( v1 ) + IDirectSoundBuffer_Stop(v1); + } +} + +//----- (00456D34) -------------------------------------------------------- +bool __fastcall snd_playing(TSnd *pSnd) +{ + IDirectSoundBuffer *v1; // eax + bool result; // al + TSnd *v3; // [esp+0h] [ebp-4h] + + v3 = pSnd; + if ( pSnd + && (v1 = pSnd->DSB) != 0 + && !IDirectSoundBuffer_GetStatus(v1, (unsigned long *)&v3) ) + { + result = v3 == (TSnd *)1; + } + else + { + result = 0; + } + return result; +} + +//----- (00456D60) -------------------------------------------------------- +void __fastcall snd_play_snd(TSnd *pSnd, int lVolume, int lPan) +{ + TSnd *v3; // edi + int v4; // ebp + IDirectSoundBuffer *v5; // esi + int v6; // eax + int v7; // ebp + int v8; // eax + int v9; // eax + DWORD v10; // [esp+30h] [ebp-4h] + + v3 = pSnd; + v4 = lVolume; + if ( pSnd ) + { + if ( gbSoundOn ) + { + v5 = pSnd->DSB; + if ( v5 ) + { + v10 = GetTickCount(); + if ( v10 - v3->start_tc >= 0x50 ) + { + _LOBYTE(v6) = snd_playing(v3); + if ( !v6 || (v5 = sound_dup_channel(v3->DSB)) != 0 ) + { + v7 = sglSoundVolume + v4; + if ( v7 >= -1600 ) + { + if ( v7 > 0 ) + v7 = 0; + } + else + { + v7 = -1600; + } + IDirectSoundBuffer_SetVolume(v5, v7); + IDirectSoundBuffer_SetPan(v5, lPan); + v8 = IDirectSoundBuffer_Play( + v5, + 0, + 0, + 0); + if ( v8 == 0x88780096 ) + { + _LOBYTE(v9) = sound_file_reload(v3, v5); + if ( v9 ) + IDirectSoundBuffer_Play( + v5, + 0, + 0, + 0); + } + else if ( v8 ) + { + DSErrDlg(v8, 261, "C:\\Src\\Diablo\\Source\\SOUND.CPP"); + } + v3->start_tc = v10; + } + } + else + { + GetTickCount(); + } + } + } + } +} +// 4A22D5: using guessed type char gbSoundOn; + +//----- (00456E39) -------------------------------------------------------- +IDirectSoundBuffer *__fastcall sound_dup_channel(IDirectSoundBuffer *DSB) +{ + IDirectSoundBuffer *result; // eax + IDirectSoundBuffer **v2; // esi + + result = 0; + if ( gbDupSounds ) + { + while ( DSBs[(_DWORD)result] ) + { + result = (IDirectSoundBuffer *)((char *)result + 1); + if ( (unsigned int)result >= 8 ) + return 0; + } + v2 = &DSBs[(_DWORD)result]; + if ( IDirectSound_DuplicateSoundBuffer( + sglpDS, + DSB, + &DSBs[(_DWORD)result]) ) + { + return 0; + } + result = *v2; + } + return result; +} +// 4A22D6: using guessed type char gbDupSounds; + +//----- (00456E74) -------------------------------------------------------- +bool __fastcall sound_file_reload(TSnd *sound_file, IDirectSoundBuffer *DSB) +{ + IDirectSoundBuffer *v2; // edi + TSnd *v3; // esi + LPARAM v5; // ecx + int v6; // [esp+8h] [ebp-18h] + int v7; // [esp+Ch] [ebp-14h] + BOOL v8; // [esp+10h] [ebp-10h] + char *a2; // [esp+14h] [ebp-Ch] + int a3; // [esp+18h] [ebp-8h] + void *a1; // [esp+1Ch] [ebp-4h] + + v2 = DSB; + v3 = sound_file; + if ( IDirectSoundBuffer_Restore(DSB) ) + return 0; + v5 = v3->sound_path; + v8 = 0; + wave_open_file(v5, (DIABFILE *)&a1, 0); + wave_file_pointer((int)a1, v3->offset, 0, 0); + if ( !IDirectSoundBuffer_Lock( + v2, + 0, + (unsigned long)v3->len, + (void **)&a2, + (unsigned long *)&a3, + (void **)&v6, + (unsigned long *)&v7, + 0) ) + { + wave_read_file((int)a1, a2, a3); + if ( !IDirectSoundBuffer_Unlock(v2, a2, (unsigned long)a3, (void *)v6, v7) ) + v8 = 1; + } + wave_close_file(a1); + return v8; +} + +//----- (00456F07) -------------------------------------------------------- +TSnd *__fastcall sound_file_load(char *path) +{ + int v1; // esi + char *v2; // edi + TSnd *v4; // esi + int v5; // eax + int v6; // eax + int v7; // [esp-4h] [ebp-24h] + int v8; // [esp+8h] [ebp-18h] + int v9; // [esp+Ch] [ebp-14h] + void *a1; // [esp+10h] [ebp-10h] + void *ptr; // [esp+14h] [ebp-Ch] + void *v12; // [esp+18h] [ebp-8h] + size_t v13; // [esp+1Ch] [ebp-4h] + + v2 = path; + if ( !sglpDS ) + return 0; + v7 = v1; + wave_open_file((LPARAM)path, (DIABFILE *)&a1, 0); + v4 = (TSnd *)DiabloAllocPtr(40); + memset(v4, 0, 0x28u); + v4->sound_path = (int)v2; + v4->start_tc = GetTickCount() - 81; + ptr = (void *)wave_load_file((int)a1, v4, (int)&v4->len); + if ( !ptr ) + TermMsg("Invalid sound format on file %s", v4->sound_path); + sound_CreateSoundBuffer(v4); + v5 = IDirectSoundBuffer_Lock( + v4->DSB, + 0, + v4->len, + (void **)&v12, + (unsigned long *)&v13, + (void **)&v8, + (unsigned long *)&v9, + 0); + //v7); + if ( v5 ) + DSErrDlg(v5, 318, "C:\\Src\\Diablo\\Source\\SOUND.CPP"); + memcpy(v12, (char *)ptr + v4->offset, v13); + v6 = IDirectSoundBuffer_Unlock(v4->DSB, v12, v13, (void *)v8, 0); + if ( v6 ) + DSErrDlg(v6, 325, "C:\\Src\\Diablo\\Source\\SOUND.CPP"); + mem_free_dbg(ptr); + wave_close_file(a1); + return v4; +} +// 456F07: could not find valid save-restore pair for esi + +//----- (00457003) -------------------------------------------------------- +void __fastcall sound_CreateSoundBuffer(TSnd *sound_file) +{ + TSnd *v1; // esi + int v2; // eax + int v3; // [esp+4h] [ebp-14h] + int v4; // [esp+8h] [ebp-10h] + int v5; // [esp+Ch] [ebp-Ch] + TSnd *v6; // [esp+14h] [ebp-4h] + + v1 = sound_file; + memset(&v3, 0, 0x14u); + v5 = v1->len; + v6 = v1; + v3 = 20; + v4 = 194; + v2 = IDirectSound_CreateSoundBuffer( + sglpDS, + (_DSBUFFERDESC *)&v3, + &v1->DSB, + 0); + if ( v2 ) + DSErrDlg(v2, 282, "C:\\Src\\Diablo\\Source\\SOUND.CPP"); +} + +//----- (00457060) -------------------------------------------------------- +void __fastcall sound_file_cleanup(TSnd *sound_file) +{ + TSnd *v1; // esi + IDirectSoundBuffer *v2; // eax + + v1 = sound_file; + if ( sound_file ) + { + v2 = sound_file->DSB; + if ( v2 ) + { + IDirectSoundBuffer_Stop(sound_file->DSB); + IDirectSoundBuffer_Release(v1->DSB); + v1->DSB = 0; + } + mem_free_dbg(v1); + } +} + +//----- (0045708B) -------------------------------------------------------- +void __fastcall snd_init(HWND hWnd) +{ + HWND v1; // edi + + v1 = hWnd; + sound_load_volume("Sound Volume", &sglSoundVolume); + gbSoundOn = sglSoundVolume > -1600; + sound_load_volume("Music Volume", &sglMusicVolume); + gbMusicOn = sglMusicVolume > -1600; + if ( sound_DirectSoundCreate(0, &sglpDS, 0) ) + sglpDS = 0; + if ( sglpDS && !IDirectSound_SetCooperativeLevel(sglpDS, v1, 3) ) + sound_create_primary_buffer(0); + SVidInitialize(sglpDS); + SFileDdaInitialize(sglpDS); + gbSndInited = sglpDS != 0; +} +// 4A22D4: using guessed type char gbMusicOn; +// 4A22D5: using guessed type char gbSoundOn; + +//----- (0045712B) -------------------------------------------------------- +void __fastcall sound_load_volume(char *value_name, int *value) +{ + int *v2; // esi + int v3; // eax + int v4; // ecx + int valuea; // [esp+8h] [ebp-4h] + + v2 = value; + valuea = *value; + _LOBYTE(v3) = SRegLoadValue("Diablo", value_name, 0, &valuea); + if ( v3 ) + v4 = valuea; + else + v4 = 0; + *v2 = v4; + if ( v4 >= -1600 ) + { + if ( v4 > 0 ) + *v2 = 0; + } + else + { + *v2 = -1600; + } + *v2 -= *v2 % 100; +} + +//----- (0045717C) -------------------------------------------------------- +void __fastcall sound_create_primary_buffer(int music_track) +{ + int v1; // eax + int v2; // eax + int v3[24]; // [esp+4h] [ebp-8Ch] + int v4; // [esp+64h] [ebp-2Ch] + int v5[4]; // [esp+68h] [ebp-28h] + int a1; // [esp+78h] [ebp-18h] + short v7; // [esp+7Ch] [ebp-14h] + short v8; // [esp+7Eh] [ebp-12h] + int v9; // [esp+80h] [ebp-10h] + int v10; // [esp+84h] [ebp-Ch] + unsigned short v11; // [esp+88h] [ebp-8h] + unsigned short v12; // [esp+8Ah] [ebp-6h] + int v13; // [esp+8Ch] [ebp-4h] + + a1 = music_track; + if ( !music_track ) + { + memset(&v4, 0, 0x14u); + v4 = 20; + v5[0] = 1; + v1 = IDirectSound_CreateSoundBuffer( + sglpDS, + (_DSBUFFERDESC *)&v4, + (IDirectSoundBuffer **)&dword_69F100, + 0); + if ( v1 ) + DSErrDlg(v1, 375, "C:\\Src\\Diablo\\Source\\SOUND.CPP"); + } + if ( dword_69F100 ) + { + v3[0] = 96; + v2 = IDirectSound_GetCaps(sglpDS, (_DSCAPS *)v3); + if ( v2 ) + DSErrDlg(v2, 383, "C:\\Src\\Diablo\\Source\\SOUND.CPP"); + if ( !a1 || !wave_do_buffer(a1, (TSnd *)&v7) ) + { + memset(&v7, 0, 0x12u); + v7 = 1; + v9 = 22050; + v12 = 16; + _LOWORD(v13) = 0; + } + v8 = 2; + v11 = 2 * v12 / 8; + v10 = v9 * v11; + (*(void (__stdcall **)(int, short *))(*(_DWORD *)dword_69F100 + 56))(dword_69F100, &v7); + } +} +// 69F100: using guessed type int dword_69F100; + +//----- (0045727E) -------------------------------------------------------- +int __fastcall sound_DirectSoundCreate(GUID *guid, IDirectSound **DS, int always_null) +{ + IDirectSound **v3; // ebp + int v4; // eax + FARPROC v5; // ebx + int v6; // eax + GUID *v8; // [esp+10h] [ebp-4h] + + v3 = DS; + v8 = guid; + if ( !hDsound_dll ) + { + hDsound_dll = LoadLibraryA("dsound.dll"); + if ( !hDsound_dll ) + { + v4 = GetLastError(); + TermDlg(108, v4, "C:\\Src\\Diablo\\Source\\SOUND.CPP", 422); + } + } + v5 = GetProcAddress(hDsound_dll, "DirectSoundCreate"); + if ( !v5 ) + { + v6 = GetLastError(); + TermDlg(108, v6, "C:\\Src\\Diablo\\Source\\SOUND.CPP", 427); + } + return ((int (__stdcall *)(GUID *, IDirectSound **, int))v5)(v8, v3, always_null); +} + +//----- (004572FF) -------------------------------------------------------- +void __cdecl sound_cleanup() +{ + snd_update(1); + SVidDestroy(); + SFileDdaDestroy(); + if ( sglpDS ) + { + IDirectSound_Release(sglpDS); + sglpDS = 0; + } + if ( gbSndInited ) + { + gbSndInited = 0; + sound_store_volume("Sound Volume", sglSoundVolume); + sound_store_volume("Music Volume", sglMusicVolume); + } +} + +//----- (00457358) -------------------------------------------------------- +void __fastcall sound_store_volume(char *key, int value) +{ + SRegSaveValue("Diablo", key, 0, value); +} + +//----- (00457367) -------------------------------------------------------- +void __cdecl music_stop() +{ + if ( sgpMusicTrack ) + { + SFileDdaEnd(sgpMusicTrack); + SFileCloseFile(sgpMusicTrack); + sgpMusicTrack = 0; + sgnMusicTrack = 6; + } +} + +//----- (00457393) -------------------------------------------------------- +void __fastcall music_start(int nTrack) +{ + int v1; // esi + int v2; // eax + int v3; // edi + + v1 = nTrack; + music_stop(); + if ( sglpDS && gbMusicOn ) + { + _LOBYTE(v2) = SFileOpenFile(sgszMusicTracks[v1], &sgpMusicTrack); + v3 = v2; + sound_create_primary_buffer((int)sgpMusicTrack); + if ( v3 ) + { + SFileDdaBeginEx(sgpMusicTrack, 0x40000, 0x40000, 0, sglMusicVolume, 0, 0); + sgnMusicTrack = v1; + } + else + { + sgpMusicTrack = 0; + } + } +} +// 4A22D4: using guessed type char gbMusicOn; + +//----- (004573FE) -------------------------------------------------------- +void __fastcall sound_disable_music(bool disable) +{ + if ( disable ) + { + music_stop(); + } + else if ( sgnMusicTrack != 6 ) + { + music_start(sgnMusicTrack); + } +} + +//----- (00457418) -------------------------------------------------------- +int __fastcall sound_get_or_set_music_volume(int volume) +{ + if ( volume != 1 ) + { + sglMusicVolume = volume; + if ( sgpMusicTrack ) + SFileDdaSetVolume(sgpMusicTrack, volume, 0); + } + return sglMusicVolume; +} + +//----- (0045743B) -------------------------------------------------------- +int __fastcall sound_get_or_set_sound_volume(int volume) +{ + int result; // eax + + result = volume; + if ( volume == 1 ) + return sglSoundVolume; + sglSoundVolume = volume; + return result; +} + +//----- (0045744E) -------------------------------------------------------- +int __fastcall GetManaAmount(int id, int sn) +{ + int v2; // eax + int v3; // esi + int v4; // ecx + bool v5; // zf + bool v6; // sf + int v7; // ecx + int v8; // ecx + int v9; // edx + + v2 = id; + v3 = 0; + v4 = plr[id]._pSplLvl[sn] + plr[id]._pISplLvlAdd - 1; + v5 = v4 == 0; + v6 = v4 < 0; + if ( v4 < 0 ) + { + v4 = 0; + v5 = 1; + v6 = 0; + } + if ( !v6 && !v5 ) + v3 = v4 * spelldata[sn].sManaAdj; + if ( sn == SPL_FIREBOLT ) + v3 >>= 1; + if ( sn == SPL_RESURRECT && v4 > 0 ) + v3 = v4 * ((unsigned int)spelldata[32].sManaCost >> 3); + _LOBYTE(v7) = spelldata[sn].sManaCost; + if ( (_BYTE)v7 == -1 ) + v7 = _LOBYTE(plr[v2]._pMaxManaBase); + else + v7 = (unsigned char)v7; + v8 = (v7 - v3) << 6; + if ( sn == SPL_HEAL ) + v8 = (spelldata[2].sManaCost + 2 * plr[v2]._pLevel - v3) << 6; + if ( sn == SPL_HEALOTHER ) + v8 = (spelldata[2].sManaCost + 2 * plr[v2]._pLevel - v3) << 6; + if ( _LOBYTE(plr[v2]._pClass) == 1 ) + v8 -= v8 >> 2; + v9 = spelldata[sn].sMinMana; + if ( v9 > v8 >> 6 ) + v8 = v9 << 6; + return v8 * (100 - plr[v2]._pISplCost) / 100; +} + +//----- (0045753A) -------------------------------------------------------- +void __fastcall UseMana(int id, int sn) +{ + int v2; // esi + int v3; // eax + + if ( id == myplr ) + { + v2 = id; + switch ( plr[id]._pSplType ) + { + case RSPLTYPE_SPELL: + v3 = GetManaAmount(id, sn); + plr[v2]._pMana -= v3; + plr[v2]._pManaBase -= v3; + drawmanaflag = 1; + break; + case RSPLTYPE_SCROLL: + RemoveScroll(id); + break; + case RSPLTYPE_CHARGES: + UseStaffCharge(id); + break; + } + } +} + +//----- (00457584) -------------------------------------------------------- +bool __fastcall CheckSpell(int player_num, int spell_id, int spell_type, bool mana_only) +{ + bool result; // al + int v5; // edi + int v6; // esi + + result = 1; + v5 = spell_id; + v6 = player_num; + if ( !mana_only && pcurs != 1 ) + return 0; + if ( (_BYTE)spell_type ) + { + if ( GetSpellLevel(player_num, spell_id) <= 0 ) + return 0; + result = plr[v6]._pMana >= GetManaAmount(v6, v5); + } + return result; +} + +//----- (004575D5) -------------------------------------------------------- +void __fastcall CastSpell(int player_num, int spell_id, int x, int y, int target_x, int target_y, int target_num, int spell_lvl) +{ + int v8; // eax + signed int v9; // edi + char *v10; // esi + int v11; // esi + int midir; // [esp+8h] [ebp-8h] + int id; // [esp+Ch] [ebp-4h] + + id = player_num; + if ( target_num ) + { + if ( target_num != 1 ) + goto LABEL_7; + v8 = monster[player_num]._mdir; + } + else + { + target_num = 0; + midir = plr[player_num]._pdir; + if ( spell_id != 6 ) + goto LABEL_7; + v8 = plr[player_num]._pVar3; + } + midir = v8; +LABEL_7: + v9 = 0; + v10 = spelldata[spell_id].sMissiles; + if ( *v10 ) + { + do + { + if ( v9 >= 3 ) + break; + AddMissile(x, y, target_x, target_y, midir, (unsigned char)v10[v9++], target_num, id, 0, spell_lvl); + } + while ( v10[v9] ); + } + if ( *v10 == 10 ) + UseMana(id, 7); + if ( *v10 == 52 ) + { + UseMana(id, 30); + if ( (spell_lvl >> 1) + 3 > 0 ) + { + v11 = (spell_lvl >> 1) + 3; + do + { + AddMissile(x, y, target_x, target_y, midir, 52, target_num, id, 0, spell_lvl); + --v11; + } + while ( v11 ); + } + } +} + +//----- (004576B1) -------------------------------------------------------- +void __fastcall DoResurrect(int pnum, int rid) +{ + int v2; // ebx + int v3; // esi + int v4; // esi + signed int v5; // edx + int v6; // eax + + v2 = rid; + v3 = pnum; + if ( (_BYTE)rid != -1 ) + AddMissile(plr[rid].WorldX, plr[rid].WorldY, plr[rid].WorldX, plr[rid].WorldY, 0, 62, 0, pnum, 0, 0); + if ( v3 == myplr ) + SetCursor(1); + if ( (_BYTE)v2 != -1 ) + { + v4 = v2; + if ( !plr[v2]._pHitPoints ) + { + if ( v2 == myplr ) + { + *(_DWORD *)&deathflag = 0; + gamemenu_off(); + drawhpflag = 1; + drawmanaflag = 1; + } + ClrPlrPath(v2); + plr[v4].destAction = -1; + plr[v4]._pInvincible = 0; + PlacePlayer(v2); + v5 = 640; + if ( plr[v4]._pMaxHPBase < 640 ) + v5 = plr[v4]._pMaxHPBase; + SetPlayerHitPoints(v2, v5); + v6 = plr[v4]._pMaxHPBase - plr[v4]._pMaxHP; + plr[v4]._pMana = 0; + plr[v4]._pHPBase = plr[v4]._pHitPoints + v6; + plr[v4]._pManaBase = plr[v4]._pMaxManaBase - plr[v4]._pMaxMana; + CalcPlrInv(v2, 1u); + if ( plr[v4].plrlevel == currlevel ) + StartStand(v2, plr[v4]._pdir); + else + plr[v4]._pmode = 0; + } + } +} + +//----- (004577CB) -------------------------------------------------------- +void __fastcall PlacePlayer(int pnum) +{ + int v1; // ebx + unsigned int v2; // eax + int v3; // edi + int v4; // esi + int v5; // eax + bool v6; // zf + signed int v7; // [esp+Ch] [ebp-18h] + int p; // [esp+10h] [ebp-14h] + int v9; // [esp+14h] [ebp-10h] + signed int v10; // [esp+18h] [ebp-Ch] + signed int v11; // [esp+1Ch] [ebp-8h] + unsigned int i; // [esp+20h] [ebp-4h] + signed int v13; // [esp+20h] [ebp-4h] + + p = pnum; + v1 = pnum; + if ( plr[pnum].plrlevel == currlevel ) + { + v2 = 0; + for ( i = 0; ; v2 = i ) + { + v3 = plr[v1].WorldX + *(int *)((char *)plrxoff2 + v2); + v4 = plr[v1].WorldY + *(int *)((char *)plryoff2 + v2); + if ( PosOkPlayer(p, v3, v4) ) + break; + i += 4; + if ( i >= 0x20 ) + break; + } + if ( !PosOkPlayer(p, v3, v4) ) + { + v11 = 0; + v5 = -1; + v13 = 1; + v7 = -1; + do + { + if ( v11 ) + break; + v9 = v5; + while ( v5 <= v13 && !v11 ) + { + v4 = v9 + plr[v1].WorldY; + v10 = v7; + do + { + if ( v11 ) + break; + v3 = v10 + plr[v1].WorldX; + if ( PosOkPlayer(p, v10 + plr[v1].WorldX, v4) ) + v11 = 1; + ++v10; + } + while ( v10 <= v13 ); + v5 = ++v9; + } + ++v13; + v5 = v7-- - 1; + } + while ( v7 > -50 ); + } + plr[v1].WorldX = v3; + v6 = p == myplr; + plr[v1].WorldY = v4; + dPlayer[v3][v4] = p + 1; + if ( v6 ) + { + ViewX = v3; + ViewY = v4; + } + } +} + +//----- (004578EE) -------------------------------------------------------- +void __fastcall DoHealOther(int pnum, int rid) +{ + int v2; // ebx + int v3; // esi + int v4; // ebx + int v5; // ecx + int v6; // edi + int v7; // ecx + char v8; // bl + int v9; // eax + int *v10; // eax + int v11; // esi + int id; // [esp+8h] [ebp-8h] + int v13; // [esp+Ch] [ebp-4h] + signed int v14; // [esp+Ch] [ebp-4h] + int i; // [esp+Ch] [ebp-4h] + + v2 = pnum; + v13 = rid; + id = pnum; + if ( pnum == myplr ) + SetCursor(1); + if ( (_BYTE)v13 != -1 ) + { + v3 = v13; + if ( (signed int)(plr[v13]._pHitPoints & 0xFFFFFFC0) > 0 ) + { + _LOBYTE(pnum) = 57; + v4 = v2; + v14 = 0; + v6 = (random(pnum, 10) + 1) << 6; + if ( plr[v4]._pLevel > 0 ) + { + do + { + _LOBYTE(v5) = 57; + v6 += (random(v5, 4) + 1) << 6; + ++v14; + } + while ( v14 < plr[v4]._pLevel ); + } + for ( i = 0; i < GetSpellLevel(id, 34); ++i ) + { + _LOBYTE(v7) = 57; + v6 += (random(v7, 6) + 1) << 6; + } + v8 = plr[v4]._pClass; + if ( !v8 ) + v6 *= 2; + if ( v8 == 1 ) + v6 += v6 >> 1; + plr[v3]._pHitPoints += v6; + v9 = plr[v3]._pMaxHP; + if ( plr[v3]._pHitPoints > v9 ) + plr[v3]._pHitPoints = v9; + v10 = &plr[v3]._pHPBase; + v11 = plr[v3]._pMaxHPBase; + *v10 += v6; + if ( *v10 > v11 ) + *v10 = v11; + drawhpflag = 1; + } + } +} + +//----- (00457A01) -------------------------------------------------------- +void __cdecl InitStores() +{ + int *v0; // eax + + pSTextBoxCels = LoadFileInMem("Data\\TextBox2.CEL", 0); + pCelBuff = LoadFileInMem("Data\\PentSpn2.CEL", 0); + pSTextSlidCels = LoadFileInMem("Data\\TextSlid.CEL", 0); + ClearSText(0, 24); + stextflag = 0; + InStoreFlag = 1; + premiumlevel = 1; + stextsize = 0; + stextscrl = 0; + numpremium = 0; + v0 = &premiumitem[0]._itype; + do + { + *v0 = -1; + v0 += 92; + } + while ( (signed int)v0 < (signed int)&talker ); + boyitem._itype = -1; + boylevel = 0; +} +// 69FB38: using guessed type int talker; +// 6A09E0: using guessed type char stextsize; +// 6A6BB8: using guessed type int stextscrl; +// 6A8A3C: using guessed type int boylevel; +// 6AA705: using guessed type char stextflag; + +//----- (00457A87) -------------------------------------------------------- +void __cdecl SetupTownStores() +{ + DWORD v0; // eax + int v1; // esi + signed int v2; // eax + int v3; // esi + + v0 = GetTickCount(); + SetRndSeed(glSeedTbl[currlevel] * v0); + if ( gbMaxPlayers == 1 ) + { + v1 = 0; + v2 = 0; + do + { + if ( plr[myplr]._pLvlVisited[v2] ) + v1 = v2; + ++v2; + } + while ( v2 < 17 ); + } + else + { + v1 = plr[myplr]._pLevel >> 1; + } + v3 = v1 + 2; + if ( v3 < 6 ) + v3 = 6; + if ( v3 > 16 ) + v3 = 16; + SpawnStoreGold(); + SpawnSmith(v3); + SpawnWitch(v3); + SpawnHealer(v3); + SpawnBoy(plr[myplr]._pLevel); + SpawnPremium(plr[myplr]._pLevel); +} +// 679660: using guessed type char gbMaxPlayers; + +//----- (00457B42) -------------------------------------------------------- +void __cdecl FreeStoreMem() +{ + void *v0; // ecx + void *v1; // ecx + void *v2; // ecx + + v0 = pSTextBoxCels; + pSTextBoxCels = 0; + mem_free_dbg(v0); + v1 = pCelBuff; + pCelBuff = 0; + mem_free_dbg(v1); + v2 = pSTextSlidCels; + pSTextSlidCels = 0; + mem_free_dbg(v2); +} + +//----- (00457B78) -------------------------------------------------------- +void __cdecl DrawSTextBack() +{ + char *v0; // edi + signed int v1; // edx + signed int v2; // ecx + int v3; // edi + signed int v4; // ecx + _BYTE *v5; // edi + signed int v6; // ecx + + Cel_decode(408, 487, pSTextBoxCels, 1, 271); + v0 = &gpBuffer->row[324].pixels[347]; + v1 = 148; + do + { + v2 = 132; + do + { + *v0 = 0; + v0 += 2; + --v2; + } + while ( v2 ); + *v0 = 0; + v3 = (int)(v0 - 1032); + v4 = 132; + do + { + v5 = (_BYTE *)(v3 + 1); + *v5 = 0; + v3 = (int)(v5 + 1); + --v4; + } + while ( v4 ); + v0 = (char *)(v3 - 1032); + --v1; + } + while ( v1 ); + v6 = 132; + do + { + *v0 = 0; + v0 += 2; + --v6; + } + while ( v6 ); + *v0 = 0; +} + +//----- (00457BD6) -------------------------------------------------------- +void __fastcall PrintSString(int x, int y, unsigned char cjustflag, char *str, int col, int val) +{ + int v6; // edi + int v7; // eax + int v8; // ebx + int v9; // esi + int v10; // esi + int v11; // ecx + int v12; // eax + int v13; // edx + int v14; // ecx + unsigned char v15; // al + int v16; // ebx + int v17; // ecx + int v18; // eax + int v19; // esi + size_t v20; // ebx + char *v21; // edx + int v22; // ecx + char valstr[32]; // [esp+Ch] [ebp-3Ch] + int v24; // [esp+2Ch] [ebp-1Ch] + int v25; // [esp+30h] [ebp-18h] + int v26; // [esp+34h] [ebp-14h] + int v27; // [esp+38h] [ebp-10h] + int v28; // [esp+3Ch] [ebp-Ch] + int v29; // [esp+40h] [ebp-8h] + int v30; // [esp+44h] [ebp-4h] + + v6 = SStringY[y] + stext[y]._syoff; + v7 = -(stextsize != 0); + v8 = x; + v9 = screen_y_times_768[v6 + 204]; + _LOWORD(v7) = v7 & 0xFEC0; + v24 = y; + v26 = x; + v27 = v7 + 416; + v10 = x + v7 + 416 + v9; + v28 = strlen(str); + v11 = 0; + v25 = stextsize != 0 ? 577 : 257; + v30 = 0; + if ( cjustflag ) + { + v12 = 0; + if ( v28 > 0 ) + { + do + { + v13 = (unsigned char)str[v11++]; + v12 += fontkern[fontframe[fontidx[v13]]] + 1; + } + while ( v11 < v28 ); + } + if ( v12 < v25 ) + v30 = (v25 - v12) >> 1; + v10 += v30; + } + if ( stextsel == v24 ) + { + if ( cjustflag ) + v14 = v27 + v30 + v8 - 20; + else + v14 = v27 + v8 - 20; + Cel_decode(v14, v6 + 205, pCelBuff, InStoreFlag, 12); + } + v29 = 0; + if ( v28 > 0 ) + { + do + { + v15 = fontframe[fontidx[(unsigned char)str[v29]]]; + v16 = v15; + v17 = v30 + fontkern[v15] + 1; + v30 += fontkern[v15] + 1; + if ( v15 && v17 <= v25 ) + CPrintString(v10, (char *)v15, col); + v18 = fontkern[v16]; + ++v29; + v10 += v18 + 1; + } + while ( v29 < v28 ); + v8 = v26; + } + if ( !cjustflag && val >= 0 ) + { + sprintf(valstr, "%i", val); + v19 = screen_y_times_768[v6 + 204] - v8 + 656; + v20 = strlen(valstr); + while ( (--v20 & 0x80000000) == 0 ) + { + v21 = (char *)fontframe[fontidx[(unsigned char)valstr[v20]]]; + v19 += -1 - fontkern[(_DWORD)v21]; + if ( fontframe[fontidx[(unsigned char)valstr[v20]]] ) + CPrintString(v19, v21, col); + } + v8 = v26; + } + if ( stextsel == v24 ) + { + if ( cjustflag ) + v22 = v27 + v30 + v8 + 4; + else + v22 = 660 - v8; + Cel_decode(v22, v6 + 205, pCelBuff, InStoreFlag, 12); + } +} +// 6A09E0: using guessed type char stextsize; +// 6A8A28: using guessed type int stextsel; +// 457BD6: using guessed type char valstr[32]; + +//----- (00457DE2) -------------------------------------------------------- +void __fastcall DrawSLine(int y) +{ + int v1; // eax + int v2; // eax + char *v3; // esi + char *v4; // edi + signed int v5; // edx + char *v6; // edi + char *v7; // esi + signed int v8; // [esp+0h] [ebp-10h] + signed int v9; // [esp+8h] [ebp-8h] + signed int v10; // [esp+Ch] [ebp-4h] + + v1 = screen_y_times_768[SStringY[y] + 198]; + if ( stextsize == 1 ) + { + v8 = 142170; + v2 = v1 + 90; + v10 = 146; + v9 = 182; + } + else + { + v8 = 142490; + v2 = v1 + 410; + v10 = 66; + v9 = 502; + } + v3 = (char *)gpBuffer + v8; + v4 = (char *)gpBuffer + v2; + v5 = 3; + do + { + qmemcpy(v4, v3, 4 * v10); + v7 = &v3[4 * v10]; + v6 = &v4[4 * v10]; + *(_WORD *)v6 = *(_WORD *)v7; + v3 = &v7[v9 + 2]; + v4 = &v6[v9 + 2]; + --v5; + } + while ( v5 ); +} +// 6A09E0: using guessed type char stextsize; + +//----- (00457E62) -------------------------------------------------------- +void __fastcall DrawSArrows(int a1, int a2) +{ + int *v2; // ebp + int v3; // ebx + int v4; // edi + int v5; // esi + int v6; // eax + int v7; // eax + + v2 = &SStringY[a2]; + v3 = a1; + v4 = SStringY[a1] + 204; + v5 = *v2 + 204; + if ( stextscrlubtn == -1 ) + Cel_decode(665, v4, pSTextSlidCels, 10, 12); + else + Cel_decode(665, v4, pSTextSlidCels, 12, 12); + if ( stextscrldbtn == -1 ) + Cel_decode(665, v5, pSTextSlidCels, 9, 12); + else + Cel_decode(665, v5, pSTextSlidCels, 11, 12); + while ( 1 ) + { + v4 += 12; + if ( v4 >= v5 ) + break; + Cel_decode(665, v4, pSTextSlidCels, 14, 12); + } + v6 = stextsel; + if ( stextsel == 22 ) + v6 = stextlhold; + if ( storenumh <= 1 ) + v7 = 0; + else + v7 = (*v2 - SStringY[v3] - 24) * (1000 * (stextsval + ((v6 - stextup) >> 2)) / (storenumh - 1)) / 1000; + Cel_decode(665, SStringY[v3 + 1] + v7 + 204, pSTextSlidCels, 13, 12); +} +// 69F108: using guessed type int stextup; +// 69F10C: using guessed type int storenumh; +// 69F110: using guessed type int stextlhold; +// 6A8A28: using guessed type int stextsel; +// 6A8A2C: using guessed type char stextscrldbtn; +// 6AA704: using guessed type char stextscrlubtn; + +//----- (00457F52) -------------------------------------------------------- +void __cdecl DrawSTextHelp() +{ + stextsel = -1; + stextsize = 1; +} +// 6A09E0: using guessed type char stextsize; +// 6A8A28: using guessed type int stextsel; + +//----- (00457F61) -------------------------------------------------------- +void __fastcall ClearSText(int s, int e) +{ + int v2; // edx + int *v3; // eax + + if ( s < e ) + { + v2 = e - s; + v3 = &stext[s]._syoff; + do + { + v3[37] = -1; + *(v3 - 1) = 0; + *v3 = 0; + *((_BYTE *)v3 + 4) = 0; + v3[33] = 0; + *((_BYTE *)v3 + 136) = 0; + v3[35] = 0; + v3[36] = 0; + v3 += 39; + --v2; + } + while ( v2 ); + } +} + +//----- (00457FA6) -------------------------------------------------------- +void __fastcall AddSLine(int y) +{ + int v1; // ecx + + v1 = y; + stext[v1]._sx = 0; + stext[v1]._syoff = 0; + stext[v1]._sstr[0] = 0; + stext[v1]._sline = 1; +} + +//----- (00457FCB) -------------------------------------------------------- +void __fastcall AddSTextVal(int y, int val) +{ + stext[y]._sval = val; +} + +//----- (00457FD8) -------------------------------------------------------- +void __fastcall OffsetSTextY(int y, int yo) +{ + stext[y]._syoff = yo; +} + +//----- (00457FE5) -------------------------------------------------------- +void __fastcall AddSText(int x, int y, unsigned char j, char *str, int clr, int sel) +{ + int v6; // esi + + v6 = y; + stext[v6]._syoff = 0; + stext[v6]._sx = x; + strcpy(stext[y]._sstr, str); + stext[v6]._sline = 0; + stext[v6]._sjust = j; + _LOBYTE(stext[v6]._sclr) = clr; + stext[v6]._ssel = sel; +} + +//----- (00458036) -------------------------------------------------------- +unsigned char __cdecl StoreAutoPlace() +{ + int v0; // edi + int v1; // eax + int v2; // edx + ItemStruct *v3; // ebp + int v4; // esi + int v5; // esi + int v6; // esi + int v7; // esi + int v8; // esi + int v9; // esi + int v10; // esi + int v11; // esi + int *v12; // esi + int v13; // esi + int v14; // esi + int v15; // esi + int v16; // esi + int v17; // esi + signed int v19; // [esp+10h] [ebp-Ch] + int v20; // [esp+14h] [ebp-8h] + int v21; // [esp+18h] [ebp-4h] + + SetICursor(plr[myplr].HoldItem._iCurs + 12); + v0 = icursH28; + v1 = 0; + v21 = icursW28; + v20 = icursH28; + if ( icursW28 == 1 ) + { + if ( icursH28 == 1 ) + { + v2 = myplr; + if ( plr[myplr].HoldItem._iStatFlag && AllItemsList[plr[v2].HoldItem.IDidx].iUsable ) + { + v19 = 0; + v3 = plr[v2].SpdList; + do + { + if ( v1 ) + break; + if ( v3->_itype == -1 ) + { + qmemcpy(v3, &plr[v2].HoldItem, sizeof(ItemStruct)); + v0 = v20; + v1 = 1; + } + ++v19; + ++v3; + } + while ( v19 < 8 ); + } + v4 = 30; + do + { + if ( v1 ) + break; + v1 = AutoPlace(myplr, v4++, 1, 1, 1); + } + while ( v4 <= 39 ); + v5 = 20; + do + { + if ( v1 ) + break; + v1 = AutoPlace(myplr, v5++, 1, 1, 1); + } + while ( v5 <= 29 ); + v6 = 10; + do + { + if ( v1 ) + break; + v1 = AutoPlace(myplr, v6++, 1, 1, 1); + } + while ( v6 <= 19 ); + v7 = 0; + while ( !v1 ) + { + v1 = AutoPlace(myplr, v7++, 1, 1, 1); + if ( v7 > 9 ) + goto LABEL_22; + } + } + else + { +LABEL_22: + if ( v0 == 2 ) + { + v8 = 29; + do + { + if ( v1 ) + break; + v1 = AutoPlace(myplr, v8--, 1, 2, 1); + } + while ( v8 >= 20 ); + v9 = 9; + do + { + if ( v1 ) + break; + v1 = AutoPlace(myplr, v9--, 1, 2, 1); + } + while ( v9 >= 0 ); + v10 = 19; + while ( !v1 ) + { + v1 = AutoPlace(myplr, v10--, 1, 2, 1); + if ( v10 < 10 ) + goto LABEL_32; + } + } + else + { +LABEL_32: + if ( v0 == 3 ) + { + v11 = 0; + while ( !v1 ) + { + v1 = AutoPlace(myplr, v11++, 1, 3, 1); + if ( v11 >= 20 ) + goto LABEL_36; + } + } + } + } + } + else + { +LABEL_36: + if ( v21 == 2 ) + { + if ( v0 == 2 ) + { + v12 = AP2x2Tbl; + do + { + if ( v1 ) + break; + v1 = AutoPlace(myplr, *v12, 2, 2, 1); + ++v12; + } + while ( (signed int)v12 < (signed int)"Data\\Inv\\Inv_Sor.CEL" ); + v13 = 21; + do + { + if ( v1 ) + break; + v1 = AutoPlace(myplr, v13, 2, 2, 1); + v13 += 2; + } + while ( v13 < 29 ); + v14 = 1; + do + { + if ( v1 ) + break; + v1 = AutoPlace(myplr, v14, 2, 2, 1); + v14 += 2; + } + while ( v14 < 9 ); + v15 = 10; + while ( !v1 ) + { + v1 = AutoPlace(myplr, v15++, 2, 2, 1); + if ( v15 >= 19 ) + goto LABEL_50; + } + } + else + { +LABEL_50: + if ( v0 == 3 ) + { + v16 = 0; + do + { + if ( v1 ) + break; + v1 = AutoPlace(myplr, v16++, 2, 3, 1); + } + while ( v16 < 9 ); + v17 = 10; + do + { + if ( v1 ) + break; + v1 = AutoPlace(myplr, v17++, 2, 3, 1); + } + while ( v17 < 19 ); + } + } + } + } + return v1; +} +// 48E9A8: using guessed type int AP2x2Tbl[10]; + +//----- (004582B3) -------------------------------------------------------- +void __cdecl S_StartSmith() +{ + stextsize = 0; + stextscrl = 0; + AddSText(0, 1, 1u, "Welcome to the", COL_GOLD, 0); + AddSText(0, 3, 1u, "Blacksmith's shop", COL_GOLD, 0); + AddSText(0, 7, 1u, "Would you like to:", COL_GOLD, 0); + AddSText(0, 10, 1u, "Talk to Griswold", 1, 1); + AddSText(0, 12, 1u, "Buy basic items", 0, 1); + AddSText(0, 14, 1u, "Buy premium items", 0, 1); + AddSText(0, 16, 1u, "Sell items", 0, 1); + AddSText(0, 18, 1u, "Repair items", 0, 1); + AddSText(0, 20, 1u, "Leave the shop", 0, 1); + AddSLine(5); + storenumh = 20; +} +// 69F10C: using guessed type int storenumh; +// 6A09E0: using guessed type char stextsize; +// 6A6BB8: using guessed type int stextscrl; + +//----- (0045837D) -------------------------------------------------------- +void __fastcall S_ScrollSBuy(int idx) +{ + int v1; // esi + int v2; // edi + char *v3; // esi + char *v4; // eax + int iclr; // [esp+Ch] [ebp-4h] + + v1 = idx; + v2 = 5; + ClearSText(5, 21); + v3 = &smithitem[v1]._iMagical; + stextup = 5; + do + { + if ( *((_DWORD *)v3 - 13) != -1 ) + { + _LOBYTE(iclr) = 0; + if ( *v3 ) + _LOBYTE(iclr) = COL_BLUE; + if ( !*((_DWORD *)v3 + 74) ) + _LOBYTE(iclr) = COL_RED; + v4 = v3 + 65; + if ( !*v3 ) + v4 = v3 + 1; + AddSText(20, v2, 0, v4, iclr, 1); + AddSTextVal(v2, *((_DWORD *)v3 + 35)); + PrintStoreItem((ItemStruct *)(v3 - 60), v2 + 1, iclr); + stextdown = v2; + v3 += 368; + } + v2 += 4; + } + while ( v2 < 20 ); + if ( !stext[stextsel]._ssel && stextsel != 22 ) + stextsel = stextdown; +} +// 69F108: using guessed type int stextup; +// 6A8A28: using guessed type int stextsel; +// 6AA700: using guessed type int stextdown; + +//----- (00458439) -------------------------------------------------------- +void __fastcall PrintStoreItem(ItemStruct *x, int l, char iclr) +{ + ItemStruct *v3; // esi + bool v4; // zf + char v5; // cl + char v6; // cl + int v7; // eax + char v8; // al + unsigned char v9; // al + char v10; // al + int v11; // edi + char v12[128]; // [esp+Ch] [ebp-84h] + int y; // [esp+8Ch] [ebp-4h] + + v12[0] = 0; + v3 = x; + v4 = x->_iIdentified == 0; + y = l; + if ( !v4 ) + { + if ( x->_iMagical != 2 ) + { + v5 = x->_iPrePower; + if ( v5 != -1 ) + { + PrintItemPower(v5, v3); + strcat(v12, tempstr); + } + } + v6 = v3->_iSufPower; + if ( v6 != -1 ) + { + PrintItemPower(v6, v3); + if ( v12[0] ) + strcat(v12, ", "); + strcat(v12, tempstr); + } + } + if ( v3->_iMiscId == IMISC_STAFF && v3->_iMaxCharges ) + { + sprintf(tempstr, "Charges: %i/%i", v3->_iCharges, v3->_iMaxCharges); + if ( v12[0] ) + strcat(v12, ", "); + strcat(v12, tempstr); + } + if ( v12[0] ) + AddSText(40, y++, 0, v12, iclr, 0); + v12[0] = 0; + if ( v3->_iClass == 1 ) + sprintf(v12, "Damage: %i-%i ", v3->_iMinDam, v3->_iMaxDam); + if ( v3->_iClass == 2 ) + sprintf(v12, "Armor: %i ", v3->_iAC); + v7 = v3->_iMaxDur; + if ( v7 != 255 && v7 ) + { + sprintf(tempstr, "Dur: %i/%i, ", v3->_iDurability, v3->_iMaxDur); + strcat(v12, tempstr); + } + else + { + strcat(v12, "Indestructible, "); + } + if ( !v3->_itype ) + v12[0] = 0; + if ( v3->_iMinStr + (unsigned char)v3->_iMinMag + v3->_iMinDex ) + { + strcpy(tempstr, "Required:"); + v8 = v3->_iMinStr; + if ( v8 ) + sprintf(tempstr, "%s %i Str", tempstr, v8); + v9 = v3->_iMinMag; + if ( v9 ) + sprintf(tempstr, "%s %i Mag", tempstr, v9); + v10 = v3->_iMinDex; + if ( v10 ) + sprintf(tempstr, "%s %i Dex", tempstr, v10); + strcat(v12, tempstr); + } + else + { + strcat(v12, "No required attributes"); + } + v11 = y; + AddSText(40, y, 0, v12, iclr, 0); + if ( v3->_iMagical == 2 ) + { + if ( v3->_iIdentified ) + AddSText(40, v11 + 1, 0, "Unique Item", iclr, 0); + } +} + +//----- (004586B3) -------------------------------------------------------- +void __cdecl S_StartSBuy() +{ + int v0; // ST10_4 + int v1; // eax + int *v2; // ecx + + v0 = plr[myplr]._pGold; + stextsize = 1; + stextscrl = 1; + stextsval = 0; + sprintf(tempstr, "I have these items for sale : Your gold : %i", v0); + AddSText(0, 1, 1u, tempstr, COL_GOLD, 0); + AddSLine(3); + AddSLine(21); + S_ScrollSBuy(stextsval); + AddSText(0, 22, 1u, "Back", 0, 0); + OffsetSTextY(22, 6); + v1 = 0; + storenumh = 0; + if ( smithitem[0]._itype != -1 ) + { + v2 = &smithitem[0]._itype; + do + { + v2 += 92; + ++v1; + } + while ( *v2 != -1 ); + storenumh = v1; + } + stextsmax = v1 - 4; + if ( v1 - 4 < 0 ) + stextsmax = 0; +} +// 69F10C: using guessed type int storenumh; +// 6A09E0: using guessed type char stextsize; +// 6A09E4: using guessed type int stextsmax; +// 6A6BB8: using guessed type int stextscrl; + +//----- (00458773) -------------------------------------------------------- +void __fastcall S_ScrollSPBuy(int idx) +{ + int v1; // esi + int v2; // edi + int v3; // eax + int v4; // esi + int *v5; // ecx + char *v6; // esi + int iclr; // [esp+Ch] [ebp-4h] + + v1 = idx; + v2 = 5; + ClearSText(5, 21); + v3 = v1; + v4 = 0; + stextup = 5; + if ( v3 ) + { + v5 = &premiumitem[0]._itype; + do + { + if ( *v5 != -1 ) + --v3; + ++v4; + v5 += 92; + } + while ( v3 ); + } + v6 = &premiumitem[v4]._iMagical; + do + { + if ( (signed int)v6 >= (signed int)&stext[0]._sstr[36] ) + break; + if ( *((_DWORD *)v6 - 13) == -1 ) + { + v2 -= 4; + } + else + { + _LOBYTE(iclr) = 0; + if ( *v6 ) + _LOBYTE(iclr) = 1; + if ( !*((_DWORD *)v6 + 74) ) + _LOBYTE(iclr) = 2; + AddSText(20, v2, 0, v6 + 65, iclr, 1); + AddSTextVal(v2, *((_DWORD *)v6 + 35)); + PrintStoreItem((ItemStruct *)(v6 - 60), v2 + 1, iclr); + stextdown = v2; + } + v2 += 4; + v6 += 368; + } + while ( v2 < 20 ); + if ( !stext[stextsel]._ssel && stextsel != 22 ) + stextsel = stextdown; +} +// 69F108: using guessed type int stextup; +// 6A8A28: using guessed type int stextsel; +// 6AA700: using guessed type int stextdown; + +//----- (00458851) -------------------------------------------------------- +bool __cdecl S_StartSPBuy() +{ + int *v0; // eax + bool result; // al + int v2; // ST10_4 + + storenumh = 0; + v0 = &premiumitem[0]._itype; + do + { + if ( *v0 != -1 ) + ++storenumh; + v0 += 92; + } + while ( (signed int)v0 < (signed int)&talker ); + if ( storenumh ) + { + v2 = plr[myplr]._pGold; + stextsval = 0; + stextsize = 1; + stextscrl = 1; + sprintf(tempstr, "I have these premium items for sale : Your gold : %i", v2); + AddSText(0, 1, 1u, tempstr, 3, 0); + AddSLine(3); + AddSLine(21); + AddSText(0, 22, 1u, "Back", 0, 0); + OffsetSTextY(22, 6); + stextsmax = storenumh - 4; + if ( storenumh - 4 < 0 ) + stextsmax = 0; + S_ScrollSPBuy(stextsval); + result = 1; + } + else + { + StartStore(1); + stextsel = 14; + result = 0; + } + return result; +} +// 69F10C: using guessed type int storenumh; +// 69FB38: using guessed type int talker; +// 6A09E0: using guessed type char stextsize; +// 6A09E4: using guessed type int stextsmax; +// 6A6BB8: using guessed type int stextscrl; +// 6A8A28: using guessed type int stextsel; + +//----- (00458931) -------------------------------------------------------- +bool __fastcall SmithSellOk(int inv_num) +{ + int v1; // ecx + int v2; // eax + BOOL v3; // eax + + v1 = 21720 * myplr + 368 * inv_num; + v2 = *(int *)((char *)&plr[0].InvList[0]._itype + v1); + if ( v2 != ITYPE_NONE && v2 && v2 != ITYPE_GOLD && v2 != ITYPE_0E && v2 != ITYPE_STAFF ) + v3 = *(int *)((char *)&plr[0].InvList[0].IDidx + v1) != IDI_LAZSTAFF; + else + _LOBYTE(v3) = 0; + return v3; +} + +//----- (00458972) -------------------------------------------------------- +void __fastcall S_ScrollSSell(int idx) +{ + int v1; // esi + int v2; // edi + char *v3; // esi + int v4; // edx + int v5; // [esp+Ch] [ebp-8h] + int iclr; // [esp+10h] [ebp-4h] + + v1 = idx; + v5 = idx; + v2 = 5; + ClearSText(5, 21); + v3 = &storehold[v1]._iMagical; + stextup = 5; + do + { + if ( v5 >= storenumh ) + break; + if ( *((_DWORD *)v3 - 13) != -1 ) + { + _LOBYTE(iclr) = 0; + if ( *v3 ) + _LOBYTE(iclr) = 1; + if ( !*((_DWORD *)v3 + 74) ) + _LOBYTE(iclr) = 2; + if ( *v3 && *((_DWORD *)v3 - 1) ) + { + AddSText(20, v2, 0, v3 + 65, iclr, 1); + v4 = *((_DWORD *)v3 + 35); + } + else + { + AddSText(20, v2, 0, v3 + 1, iclr, 1); + v4 = *((_DWORD *)v3 + 34); + } + AddSTextVal(v2, v4); + PrintStoreItem((ItemStruct *)(v3 - 60), v2 + 1, iclr); + stextdown = v2; + } + ++v5; + v2 += 4; + v3 += 368; + } + while ( v2 < 20 ); + stextsmax = storenumh - 4; + if ( storenumh - 4 < 0 ) + stextsmax = 0; +} +// 69F108: using guessed type int stextup; +// 69F10C: using guessed type int storenumh; +// 6A09E4: using guessed type int stextsmax; +// 6AA700: using guessed type int stextdown; + +//----- (00458A59) -------------------------------------------------------- +void __cdecl S_StartSSell() +{ + int *v0; // eax + int v1; // edx + int *v2; // ebp + int v3; // eax + bool v4; // zf + int v5; // eax + int v6; // ecx + int v7; // ST10_4 + int v8; // ST10_4 + int inv_num; // [esp+Ch] [ebp-Ch] + ItemStruct *v10; // [esp+10h] [ebp-8h] + signed int v11; // [esp+14h] [ebp-4h] + + stextsize = 1; + v11 = 0; + storenumh = 0; + v0 = &storehold[0]._itype; + do + { + *v0 = -1; + v0 += 92; + } + while ( (signed int)v0 < (signed int)witchitem ); + inv_num = 0; + v1 = myplr; + if ( plr[myplr]._pNumInv <= 0 ) + goto LABEL_18; + v2 = &storehold[0]._ivalue; + v10 = plr[v1].InvList; + do + { + _LOBYTE(v3) = SmithSellOk(inv_num); + if ( v3 ) + { + v11 = 1; + qmemcpy(v2 - 49, v10, 0x170u); + if ( *((_BYTE *)v2 - 136) && *(v2 - 35) ) + *v2 = v2[1]; + v4 = *v2 >> 2 == 0; + *v2 >>= 2; + if ( v4 ) + *v2 = 1; + v5 = *v2; + v6 = storenumh++; + v2[1] = v5; + v2 += 92; + storehidx[v6] = inv_num; + } + ++inv_num; + ++v10; + } + while ( inv_num < plr[v1]._pNumInv ); + if ( v11 ) + { + v8 = plr[v1]._pGold; + stextsmax = plr[v1]._pNumInv; + stextscrl = 1; + stextsval = 0; + sprintf(tempstr, "Which item is for sale? Your gold : %i", v8); + AddSText(0, 1, 1u, tempstr, 3, 0); + AddSLine(3); + AddSLine(21); + S_ScrollSSell(stextsval); + AddSText(0, 22, 1u, "Back", 0, 1); + OffsetSTextY(22, 6); + } + else + { +LABEL_18: + v7 = plr[v1]._pGold; + stextscrl = 0; + sprintf(tempstr, "You have nothing I want. Your gold : %i", v7); + AddSText(0, 1, 1u, tempstr, 3, 0); + AddSLine(3); + AddSLine(21); + AddSText(0, 22, 1u, "Back", 0, 1); + OffsetSTextY(22, 6); + } +} +// 69F10C: using guessed type int storenumh; +// 6A09E0: using guessed type char stextsize; +// 6A09E4: using guessed type int stextsmax; +// 6A6BB8: using guessed type int stextscrl; + +//----- (00458C0B) -------------------------------------------------------- +bool __fastcall SmithRepairOk(int i) +{ + int v1; // eax + int v2; // ecx + bool result; // al + + v1 = 368 * i + 21720 * myplr; + v2 = *(int *)((char *)&plr[0].InvList[0]._itype + v1); + if ( v2 != ITYPE_NONE && v2 && v2 != ITYPE_GOLD && v2 != ITYPE_0E ) + result = *(int *)((char *)&plr[0].InvList[0]._iDurability + v1) != *(int *)((char *)&plr[0].InvList[0]._iMaxDur + + v1); + else + result = 0; + return result; +} + +//----- (00458C4E) -------------------------------------------------------- +void __cdecl S_StartSRepair() +{ + int v0; // ebp + int *v1; // eax + int v2; // esi + int v3; // eax + int v4; // eax + int v5; // eax + int v6; // eax + int v7; // edi + int v8; // eax + int v9; // esi + int v10; // eax + int v11; // [esp-4h] [ebp-1Ch] + signed int v12; // [esp+10h] [ebp-8h] + int v13; // [esp+14h] [ebp-4h] + + v0 = 0; + stextsize = 1; + v12 = 0; + storenumh = 0; + v1 = &storehold[0]._itype; + do + { + *v1 = -1; + v1 += 92; + } + while ( (signed int)v1 < (signed int)witchitem ); + v2 = myplr; + v3 = myplr; + if ( plr[myplr].InvBody[0]._itype != -1 && plr[v3].InvBody[0]._iDurability != plr[v3].InvBody[0]._iMaxDur ) + { + v12 = 1; + AddStoreHoldRepair(plr[v3].InvBody, -1); + v2 = myplr; + } + v4 = v2; + if ( plr[v2].InvBody[6]._itype != -1 && plr[v4].InvBody[6]._iDurability != plr[v4].InvBody[6]._iMaxDur ) + { + v12 = 1; + AddStoreHoldRepair(&plr[v4].InvBody[6], -2); + v2 = myplr; + } + v5 = v2; + if ( plr[v2].InvBody[4]._itype != -1 && plr[v5].InvBody[4]._iDurability != plr[v5].InvBody[4]._iMaxDur ) + { + v12 = 1; + AddStoreHoldRepair(&plr[v5].InvBody[4], -3); + v2 = myplr; + } + v6 = v2; + if ( plr[v2].InvBody[5]._itype != -1 && plr[v6].InvBody[5]._iDurability != plr[v6].InvBody[5]._iMaxDur ) + { + v12 = 1; + AddStoreHoldRepair(&plr[v6].InvBody[5], -4); + v2 = myplr; + } + v7 = 21720 * v2; + if ( plr[v2]._pNumInv > 0 ) + { + v13 = 0; + do + { + _LOBYTE(v8) = SmithRepairOk(v0); + if ( v8 ) + { + v12 = 1; + AddStoreHoldRepair((ItemStruct *)((char *)&plr[0].InvList[v13] + v7), v0); + v2 = myplr; + } + ++v13; + v7 = 21720 * v2; + ++v0; + } + while ( v0 < plr[v2]._pNumInv ); + } + v9 = v2; + v11 = plr[v9]._pGold; + if ( v12 ) + { + stextsval = 0; + v10 = plr[v9]._pNumInv; + stextscrl = 1; + stextsmax = v10; + sprintf(tempstr, "Repair which item? Your gold : %i", v11); + AddSText(0, 1, 1u, tempstr, COL_GOLD, 0); + AddSLine(3); + AddSLine(21); + S_ScrollSSell(stextsval); + } + else + { + stextscrl = 0; + sprintf(tempstr, "You have nothing to repair. Your gold : %i", v11); + AddSText(0, 1, 1u, tempstr, COL_GOLD, 0); + AddSLine(3); + AddSLine(21); + } + AddSText(0, 22, 1u, "Back", COL_WHITE, 1); + OffsetSTextY(22, 6); +} +// 69F10C: using guessed type int storenumh; +// 6A09E0: using guessed type char stextsize; +// 6A09E4: using guessed type int stextsmax; +// 6A6BB8: using guessed type int stextscrl; + +//----- (00458E9A) -------------------------------------------------------- +void __fastcall AddStoreHoldRepair(ItemStruct *itm, int i) +{ + int v2; // ebx + ItemStruct *v3; // ebp + int v4; // ecx + int v5; // eax + + v2 = storenumh; + v3 = &storehold[storenumh]; + qmemcpy(&storehold[storenumh], itm, sizeof(ItemStruct)); + v4 = (unsigned char)v3->_iMagical; + if ( (_BYTE)v4 && v3->_iIdentified ) + v3->_ivalue = 30 * v3->_iIvalue / 100; + v5 = v3->_ivalue * (100 * (v3->_iMaxDur - v3->_iDurability) / v3->_iMaxDur) / 100; + if ( !v5 ) + { + if ( (_BYTE)v4 && v3->_iIdentified ) + return; + v5 = 1; + } + if ( v5 > 1 ) + v5 >>= 1; + v3->_iIvalue = v5; + v3->_ivalue = v5; + storehidx[v2] = i; + storenumh = v2 + 1; +} +// 69F10C: using guessed type int storenumh; + +//----- (00458F3D) -------------------------------------------------------- +void __cdecl S_StartWitch() +{ + stextsize = 0; + stextscrl = 0; + AddSText(0, 2, 1u, "Witch's shack", COL_GOLD, 0); + AddSText(0, 9, 1u, "Would you like to:", COL_GOLD, 0); + AddSText(0, 12, 1u, "Talk to Adria", 1, 1); + AddSText(0, 14, 1u, "Buy items", 0, 1); + AddSText(0, 16, 1u, "Sell items", 0, 1); + AddSText(0, 18, 1u, "Recharge staves", 0, 1); + AddSText(0, 20, 1u, "Leave the shack", 0, 1); + AddSLine(5); + storenumh = 20; +} +// 69F10C: using guessed type int storenumh; +// 6A09E0: using guessed type char stextsize; +// 6A6BB8: using guessed type int stextscrl; + +//----- (00458FE3) -------------------------------------------------------- +void __fastcall S_ScrollWBuy(int idx) +{ + int v1; // esi + int v2; // edi + char *v3; // esi + char *v4; // eax + int iclr; // [esp+Ch] [ebp-4h] + + v1 = idx; + v2 = 5; + ClearSText(5, 21); + v3 = &witchitem[v1]._iMagical; + stextup = 5; + do + { + if ( *((_DWORD *)v3 - 13) != -1 ) + { + _LOBYTE(iclr) = 0; + if ( *v3 ) + _LOBYTE(iclr) = 1; + if ( !*((_DWORD *)v3 + 74) ) + _LOBYTE(iclr) = 2; + v4 = v3 + 65; + if ( !*v3 ) + v4 = v3 + 1; + AddSText(20, v2, 0, v4, iclr, 1); + AddSTextVal(v2, *((_DWORD *)v3 + 35)); + PrintStoreItem((ItemStruct *)(v3 - 60), v2 + 1, iclr); + stextdown = v2; + v3 += 368; + } + v2 += 4; + } + while ( v2 < 20 ); + if ( !stext[stextsel]._ssel && stextsel != 22 ) + stextsel = stextdown; +} +// 69F108: using guessed type int stextup; +// 6A8A28: using guessed type int stextsel; +// 6AA700: using guessed type int stextdown; + +//----- (0045909F) -------------------------------------------------------- +void __cdecl S_StartWBuy() +{ + int v0; // ST10_4 + int v1; // eax + int *v2; // ecx + + v0 = plr[myplr]._pGold; + stextsize = 1; + stextscrl = 1; + stextsval = 0; + stextsmax = 20; + sprintf(tempstr, "I have these items for sale : Your gold : %i", v0); + AddSText(0, 1, 1u, tempstr, 3, 0); + AddSLine(3); + AddSLine(21); + S_ScrollWBuy(stextsval); + AddSText(0, 22, 1u, "Back", 0, 0); + OffsetSTextY(22, 6); + v1 = 0; + storenumh = 0; + if ( witchitem[0]._itype != -1 ) + { + v2 = &witchitem[0]._itype; + do + { + v2 += 92; + ++v1; + } + while ( *v2 != -1 ); + storenumh = v1; + } + stextsmax = v1 - 4; + if ( v1 - 4 < 0 ) + stextsmax = 0; +} +// 69F10C: using guessed type int storenumh; +// 6A09E0: using guessed type char stextsize; +// 6A09E4: using guessed type int stextsmax; +// 6A6BB8: using guessed type int stextscrl; + +//----- (00459169) -------------------------------------------------------- +bool __fastcall WitchSellOk(int i) +{ + bool result; // al + int v2; // edx + ItemStruct *pI; // edx + int v4; // ecx + int v5; // edx + + result = 0; + v2 = 21720 * myplr; + if ( i < 0 ) + pI = (ItemStruct *)((char *)&plr[0].InvList[39] + v2 - 368 * i + 44); + else + pI = (ItemStruct *)((char *)&plr[0].InvList[i] + v2); + v4 = pI->_itype; + if ( !v4 ) + result = 1; + if ( v4 == ITYPE_STAFF ) + result = 1; + v5 = pI->IDidx; + if ( v5 >= IDI_FIRSTQUEST && v5 <= IDI_LASTQUEST ) + result = 0; + if ( v5 == IDI_LAZSTAFF ) + result = 0; + return result; +} + +//----- (004591C4) -------------------------------------------------------- +void __cdecl S_StartWSell() +{ + int v0; // ebp + int *v1; // eax + int v2; // ebx + int v3; // eax + int v4; // eax + int *v5; // ecx + bool v6; // zf + ItemStruct *v7; // esi + int v8; // eax + int v9; // eax + int *v10; // ecx + int v11; // eax + int v12; // [esp-4h] [ebp-24h] + int inv_or_belt_num; // [esp+10h] [ebp-10h] + char inv_or_belt_numa; // [esp+10h] [ebp-10h] + ItemStruct *i; // [esp+14h] [ebp-Ch] + signed int ia; // [esp+14h] [ebp-Ch] + signed int v17; // [esp+18h] [ebp-8h] + ItemStruct *v18; // [esp+1Ch] [ebp-4h] + + v0 = 0; + stextsize = 1; + v17 = 0; + storenumh = 0; + v1 = &storehold[0]._itype; + do + { + *v1 = -1; + v1 += 92; + } + while ( (signed int)v1 < (signed int)witchitem ); + inv_or_belt_num = 0; + v2 = myplr; + if ( plr[myplr]._pNumInv > 0 ) + { + i = plr[v2].InvList; + do + { + _LOBYTE(v3) = WitchSellOk(inv_or_belt_num); + if ( v3 ) + { + v4 = v0; + qmemcpy(&storehold[v0], i, sizeof(ItemStruct)); + v17 = 1; + if ( storehold[v0]._iMagical && storehold[v4]._iIdentified ) + storehold[v4]._ivalue = storehold[v4]._iIvalue; + v5 = &storehold[v4]._ivalue; + v6 = storehold[v4]._ivalue >> 2 == 0; + *v5 >>= 2; + if ( v6 ) + *v5 = 1; + ++v0; + storehold[v4]._iIvalue = *v5; + *((_BYTE *)&golditem.inactive_16C + v0 + 3) = inv_or_belt_num; + storenumh = v0; + } + ++inv_or_belt_num; + ++i; + } + while ( inv_or_belt_num < plr[v2]._pNumInv ); + } + ia = -1; + v7 = plr[v2].SpdList; + inv_or_belt_numa = 0; + v18 = plr[v2].SpdList; + do + { + if ( v7->_itype != -1 ) + { + _LOBYTE(v8) = WitchSellOk(ia); + if ( v8 ) + { + v9 = v0; + qmemcpy(&storehold[v0], v7, sizeof(ItemStruct)); + v17 = 1; + if ( storehold[v0]._iMagical && storehold[v9]._iIdentified ) + storehold[v9]._ivalue = storehold[v9]._iIvalue; + v10 = &storehold[v9]._ivalue; + v6 = storehold[v9]._ivalue >> 2 == 0; + *v10 >>= 2; + if ( v6 ) + *v10 = 1; + storehold[v9]._iIvalue = *v10; + storenumh = ++v0; + *((_BYTE *)&golditem.inactive_16C + v0 + 3) = -1 - inv_or_belt_numa; + } + } + ++inv_or_belt_numa; + --ia; + v7 = v18 + 1; + ++v18; + } + while ( ia > -9 ); + v12 = plr[v2]._pGold; + if ( v17 ) + { + v11 = plr[v2]._pNumInv; + stextscrl = 1; + stextsval = 0; + stextsmax = v11; + sprintf(tempstr, "Which item is for sale? Your gold : %i", v12); + AddSText(0, 1, 1u, tempstr, 3, 0); + AddSLine(3); + AddSLine(21); + S_ScrollSSell(stextsval); + } + else + { + stextscrl = 0; + sprintf(tempstr, "You have nothing I want. Your gold : %i", v12); + AddSText(0, 1, 1u, tempstr, COL_GOLD, 0); + AddSLine(3); + AddSLine(21); + } + AddSText(0, 22, 1u, "Back", 0, 1); + OffsetSTextY(22, 6); +} +// 69F10C: using guessed type int storenumh; +// 6A09E0: using guessed type char stextsize; +// 6A09E4: using guessed type int stextsmax; +// 6A6BB8: using guessed type int stextscrl; + +//----- (00459431) -------------------------------------------------------- +unsigned char __fastcall WitchRechargeOk(int i) +{ + int v1; // ecx + unsigned char result; // al + + v1 = 21720 * myplr + 368 * i; + result = 0; + if ( *(int *)((char *)&plr[0].InvList[0]._itype + v1) == ITYPE_STAFF + && *(int *)((char *)&plr[0].InvList[0]._iCharges + v1) != *(int *)((char *)&plr[0].InvList[0]._iMaxCharges + v1) ) + { + result = 1; + } + return result; +} + +//----- (00459460) -------------------------------------------------------- +void __fastcall AddStoreHoldRecharge(ItemStruct itm, int i) +{ + int v2; // ebx + int v3; // eax + char v4; // ST10_1 + int v5; // ecx + int v6; // eax + + v2 = storenumh; + v3 = spelldata[itm._iSpell].sStaffCost; + v4 = i; + qmemcpy(&storehold[storenumh], &itm, sizeof(ItemStruct)); + storehold[v2]._ivalue += v3; + v5 = storenumh; + v6 = storehold[v2]._ivalue + * (100 + * (storehold[v2]._iMaxCharges - storehold[v2]._iCharges) + / storehold[v2]._iMaxCharges) + / 100 >> 1; + ++storenumh; + storehold[v2]._ivalue = v6; + storehold[v2]._iIvalue = v6; + storehidx[v5] = v4; +} +// 69F108: using guessed type int stextup; +// 69F10C: using guessed type int storenumh; + +//----- (004594E6) -------------------------------------------------------- +void __cdecl S_StartWRecharge() +{ + int *v0; // eax + int v1; // ebp + int v2; // eax + int v3; // eax + ItemStruct v4; // [esp-170h] [ebp-18Ch] + int v5; // [esp-4h] [ebp-20h] + int inv_num; // [esp+10h] [ebp-Ch] + ItemStruct *v7; // [esp+14h] [ebp-8h] + int v8; // [esp+18h] [ebp-4h] + + stextsize = 1; + v8 = 0; + storenumh = 0; + v0 = &storehold[0]._itype; + do + { + *v0 = -1; + v0 += 92; + } + while ( (signed int)v0 < (signed int)witchitem ); + v1 = myplr; + if ( plr[myplr].InvBody[4]._itype == ITYPE_STAFF && plr[v1].InvBody[4]._iCharges != plr[v1].InvBody[4]._iMaxCharges ) + { + v8 = 1; + qmemcpy(&v4, &plr[v1].InvBody[4], sizeof(v4)); + AddStoreHoldRecharge(v4, -1); + } + v2 = plr[v1]._pNumInv; + inv_num = 0; + if ( v2 > 0 ) + { + v7 = plr[v1].InvList; + do + { + _LOBYTE(v3) = WitchRechargeOk(inv_num); + if ( v3 ) + { + v8 = 1; + qmemcpy(&v4, v7, sizeof(v4)); + AddStoreHoldRecharge(v4, inv_num); + } + ++inv_num; + v2 = plr[v1]._pNumInv; + ++v7; + } + while ( inv_num < v2 ); + } + v5 = plr[v1]._pGold; + if ( v8 ) + { + stextscrl = 1; + stextsval = 0; + stextsmax = v2; + sprintf(tempstr, "Recharge which item? Your gold : %i", v5); + AddSText(0, 1, 1u, tempstr, 3, 0); + AddSLine(3); + AddSLine(21); + S_ScrollSSell(stextsval); + } + else + { + stextscrl = 0; + sprintf(tempstr, "You have nothing to recharge. Your gold : %i", v5); + AddSText(0, 1, 1u, tempstr, COL_GOLD, 0); + AddSLine(3); + AddSLine(21); + } + AddSText(0, 22, 1u, "Back", 0, 1); + OffsetSTextY(22, 6); +} +// 69F10C: using guessed type int storenumh; +// 6A09E0: using guessed type char stextsize; +// 6A09E4: using guessed type int stextsmax; +// 6A6BB8: using guessed type int stextscrl; + +//----- (00459693) -------------------------------------------------------- +void __cdecl S_StartNoMoney() +{ + StartStore((unsigned char)stextshold); + stextscrl = 0; + stextsize = 1; + ClearSText(5, 23); + AddSText(0, 14, 1u, "You do not have enough gold", COL_WHITE, 1); +} +// 6A09E0: using guessed type char stextsize; +// 6A6BB8: using guessed type int stextscrl; + +//----- (004596CD) -------------------------------------------------------- +void __cdecl S_StartNoRoom() +{ + StartStore((unsigned char)stextshold); + stextscrl = 0; + ClearSText(5, 23); + AddSText(0, 14, 1u, "You do not have enough room in inventory", COL_WHITE, 1); +} +// 6A6BB8: using guessed type int stextscrl; + +//----- (00459700) -------------------------------------------------------- +void __cdecl S_StartConfirm() +{ + int v0; // eax + char v1; // dl + BOOL v2; // esi + char *v3; // eax + int v4; // eax + int iclr; // [esp+Ch] [ebp-4h] + + StartStore((unsigned char)stextshold); + stextscrl = 0; + ClearSText(5, 23); + _LOBYTE(iclr) = 0; + v0 = myplr; + v1 = plr[myplr].HoldItem._iMagical; + if ( v1 ) + _LOBYTE(iclr) = 1; + if ( !plr[v0].HoldItem._iStatFlag ) + _LOBYTE(iclr) = 2; + v2 = v1 != 0; + if ( stextshold == STORE_SIDENTIFY ) + v2 = 0; + if ( v1 && !plr[v0].HoldItem._iIdentified ) + { + if ( stextshold == STORE_SSELL ) + v2 = 0; + if ( stextshold == STORE_WSELL ) + v2 = 0; + if ( stextshold == STORE_SREPAIR ) + v2 = 0; + if ( stextshold == STORE_WRECHARGE ) + v2 = 0; + } + if ( v2 ) + v3 = plr[v0].HoldItem._iIName; + else + v3 = plr[v0].HoldItem._iName; + AddSText(20, STORE_WRECHARGE, 0, v3, iclr, 0); + AddSTextVal(STORE_WRECHARGE, plr[myplr].HoldItem._iIvalue); + PrintStoreItem((ItemStruct *)((char *)&plr[0].HoldItem + v4), 9, iclr); + if ( stextshold > STORE_WRECHARGE ) + { + if ( stextshold == STORE_BBOY ) + { + strcpy(tempstr, "Do we have a deal?"); + goto LABEL_37; + } + if ( stextshold != STORE_HBUY ) + { + if ( stextshold == STORE_SIDENTIFY ) + { + strcpy(tempstr, "Are you sure you want to identify this item?"); + goto LABEL_37; + } + if ( stextshold != 18 ) + goto LABEL_37; + } +LABEL_34: + strcpy(tempstr, "Are you sure you want to buy this item?"); + goto LABEL_37; + } + switch ( stextshold ) + { + case STORE_WRECHARGE: + strcpy(tempstr, "Are you sure you want to recharge this item?"); + break; + case STORE_SBUY: + goto LABEL_34; + case STORE_SSELL: +LABEL_27: + strcpy(tempstr, "Are you sure you want to sell this item?"); + break; + case STORE_SREPAIR: + strcpy(tempstr, "Are you sure you want to repair this item?"); + break; + case STORE_WBUY: + goto LABEL_34; + case STORE_WSELL: + goto LABEL_27; + } +LABEL_37: + AddSText(0, 15, 1u, tempstr, 0, 0); + AddSText(0, 18, 1u, "Yes", 0, 1); + AddSText(0, 20, 1u, "No", 0, 1); +} +// 6A6BB8: using guessed type int stextscrl; + +//----- (00459873) -------------------------------------------------------- +void __cdecl S_StartBoy() +{ + stextsize = 0; + stextscrl = 0; + AddSText(0, 2, 1u, "Wirt the Peg-legged boy", COL_GOLD, 0); + AddSLine(5); + if ( boyitem._itype == -1 ) + { + AddSText(0, 12, 1u, "Talk to Wirt", 1, 1); + AddSText(0, 18, 1u, "Say goodbye", 0, 1); + } + else + { + AddSText(0, 8, 1u, "Talk to Wirt", 1, 1); + AddSText(0, 12, 1u, "I have something for sale,", COL_GOLD, 0); + AddSText(0, 14, 1u, "but it will cost 50 gold", COL_GOLD, 0); + AddSText(0, 16, 1u, "just to take a look. ", COL_GOLD, 0); + AddSText(0, 18, 1u, "What have you got?", 0, 1); + AddSText(0, 20, 1u, "Say goodbye", 0, 1); + } +} +// 6A09E0: using guessed type char stextsize; +// 6A6BB8: using guessed type int stextscrl; + +//----- (00459930) -------------------------------------------------------- +void __cdecl S_StartBBoy() +{ + int v0; // ST10_4 + signed int v1; // esi + + v0 = plr[myplr]._pGold; + stextsize = 1; + stextscrl = 0; + sprintf(tempstr, "I have this item for sale : Your gold : %i", v0); + AddSText(0, 1, 1u, tempstr, COL_GOLD, 0); + AddSLine(3); + AddSLine(21); + v1 = 0; + if ( boyitem._iMagical ) + v1 = 1; + if ( !boyitem._iStatFlag ) + v1 = 2; + if ( boyitem._iMagical ) + AddSText(20, 10, 0, boyitem._iIName, v1, 1); + else + AddSText(20, 10, 0, boyitem._iName, v1, 1); + AddSTextVal(10, boyitem._iIvalue + (boyitem._iIvalue >> 1)); + PrintStoreItem(&boyitem, 11, v1); + AddSText(0, 22, 1u, "Leave", 0, 1); + OffsetSTextY(22, 6); +} +// 6A09E0: using guessed type char stextsize; +// 6A6BB8: using guessed type int stextscrl; + +//----- (004599FD) -------------------------------------------------------- +void __cdecl S_StartHealer() +{ + stextsize = 0; + stextscrl = 0; + AddSText(0, 1, 1u, "Welcome to the", COL_GOLD, 0); + AddSText(0, 3, 1u, "Healer's home", COL_GOLD, 0); + AddSText(0, 9, 1u, "Would you like to:", COL_GOLD, 0); + AddSText(0, 12, 1u, "Talk to Pepin", 1, 1); + AddSText(0, 14, 1u, "Receive healing", 0, 1); + AddSText(0, 16, 1u, "Buy items", 0, 1); + AddSText(0, 18, 1u, "Leave Healer's home", 0, 1); + AddSLine(5); + storenumh = 20; +} +// 69F10C: using guessed type int storenumh; +// 6A09E0: using guessed type char stextsize; +// 6A6BB8: using guessed type int stextscrl; + +//----- (00459AA5) -------------------------------------------------------- +void __fastcall S_ScrollHBuy(int idx) +{ + int v1; // esi + int v2; // edi + int *v3; // esi + int iclr; // [esp+8h] [ebp-4h] + + v1 = idx; + v2 = 5; + ClearSText(5, 21); + stextup = 5; + v3 = &healitem[v1]._iStatFlag; + do + { + if ( *(v3 - 87) != -1 ) + { + _LOBYTE(iclr) = 0; + if ( !*v3 ) + _LOBYTE(iclr) = 2; + AddSText(20, v2, 0, (char *)v3 - 295, iclr, 1); + AddSTextVal(v2, *(v3 - 39)); + PrintStoreItem((ItemStruct *)(v3 - 89), v2 + 1, iclr); + stextdown = v2; + v3 += 92; + } + v2 += 4; + } + while ( v2 < 20 ); + if ( !stext[stextsel]._ssel && stextsel != 22 ) + stextsel = stextdown; +} +// 69F108: using guessed type int stextup; +// 6A8A28: using guessed type int stextsel; +// 6AA700: using guessed type int stextdown; + +//----- (00459B55) -------------------------------------------------------- +void __cdecl S_StartHBuy() +{ + int v0; // ST10_4 + int v1; // eax + int *v2; // ecx + + v0 = plr[myplr]._pGold; + stextsize = 1; + stextscrl = 1; + stextsval = 0; + sprintf(tempstr, "I have these items for sale : Your gold : %i", v0); + AddSText(0, 1, 1u, tempstr, 3, 0); + AddSLine(3); + AddSLine(21); + S_ScrollHBuy(stextsval); + AddSText(0, 22, 1u, "Back", 0, 0); + OffsetSTextY(22, 6); + v1 = 0; + storenumh = 0; + if ( healitem[0]._itype != -1 ) + { + v2 = &healitem[0]._itype; + do + { + v2 += 92; + ++v1; + } + while ( *v2 != -1 ); + storenumh = v1; + } + stextsmax = v1 - 4; + if ( v1 - 4 < 0 ) + stextsmax = 0; +} +// 69F10C: using guessed type int storenumh; +// 6A09E0: using guessed type char stextsize; +// 6A09E4: using guessed type int stextsmax; +// 6A6BB8: using guessed type int stextscrl; + +//----- (00459C15) -------------------------------------------------------- +void __cdecl S_StartStory() +{ + stextsize = 0; + stextscrl = 0; + AddSText(0, 2, 1u, "The Town Elder", COL_GOLD, 0); + AddSText(0, 9, 1u, "Would you like to:", COL_GOLD, 0); + AddSText(0, 12, 1u, "Talk to Cain", 1, 1); + AddSText(0, 14, 1u, "Identify an item", 0, 1); + AddSText(0, 18, 1u, "Say goodbye", 0, 1); + AddSLine(5); +} +// 6A09E0: using guessed type char stextsize; +// 6A6BB8: using guessed type int stextscrl; + +//----- (00459C8E) -------------------------------------------------------- +bool __fastcall IdItemOk(ItemStruct *item) +{ + bool result; // al + + result = 0; + if ( item->_itype != -1 ) + { + if ( item->_iMagical ) + result = item->_iIdentified == 0; + } + return result; +} + +//----- (00459CA2) -------------------------------------------------------- +void __fastcall AddStoreHoldId(ItemStruct itm, int i) +{ + int v2; // edx + int v3; // eax + + v2 = storenumh; + v3 = storenumh; + qmemcpy(&storehold[storenumh], &itm, sizeof(ItemStruct)); + storehidx[v2] = i; + storehold[v3]._ivalue = 100; + storehold[v3]._iIvalue = 100; + storenumh = v2 + 1; +} +// 69F108: using guessed type int stextup; +// 69F10C: using guessed type int storenumh; + +//----- (00459CE6) -------------------------------------------------------- +void __cdecl S_StartSIdentify() +{ + int *v0; // eax + int v1; // ebp + ItemStruct *v2; // esi + int v3; // eax + int v4; // eax + int v5; // eax + int v6; // eax + int v7; // eax + int v8; // eax + int v9; // eax + int v10; // eax + ItemStruct *v11; // esi + int v12; // eax + ItemStruct v13; // [esp-170h] [ebp-18Ch] + int v14; // [esp-4h] [ebp-20h] + int v15; // [esp+10h] [ebp-Ch] + int i; // [esp+14h] [ebp-8h] + ItemStruct *v17; // [esp+18h] [ebp-4h] + + v15 = 0; + storenumh = 0; + stextsize = 1; + v0 = &storehold[0]._itype; + do + { + *v0 = -1; + v0 += 92; + } + while ( (signed int)v0 < (signed int)witchitem ); + v1 = myplr; + v2 = plr[myplr].InvBody; + _LOBYTE(v3) = IdItemOk(plr[myplr].InvBody); + if ( v3 ) + { + v15 = 1; + qmemcpy(&v13, v2, sizeof(v13)); + AddStoreHoldId(v13, -1); + } + _LOBYTE(v4) = IdItemOk(&plr[v1].InvBody[6]); + if ( v4 ) + { + v15 = 1; + qmemcpy(&v13, &plr[v1].InvBody[6], sizeof(v13)); + AddStoreHoldId(v13, -2); + } + _LOBYTE(v5) = IdItemOk(&plr[v1].InvBody[4]); + if ( v5 ) + { + v15 = 1; + qmemcpy(&v13, &plr[v1].InvBody[4], sizeof(v13)); + AddStoreHoldId(v13, -3); + } + _LOBYTE(v6) = IdItemOk(&plr[v1].InvBody[5]); + if ( v6 ) + { + v15 = 1; + qmemcpy(&v13, &plr[v1].InvBody[5], sizeof(v13)); + AddStoreHoldId(v13, -4); + } + _LOBYTE(v7) = IdItemOk(&plr[v1].InvBody[1]); + if ( v7 ) + { + v15 = 1; + qmemcpy(&v13, &plr[v1].InvBody[1], sizeof(v13)); + AddStoreHoldId(v13, -5); + } + _LOBYTE(v8) = IdItemOk(&plr[v1].InvBody[2]); + if ( v8 ) + { + v15 = 1; + qmemcpy(&v13, &plr[v1].InvBody[2], sizeof(v13)); + AddStoreHoldId(v13, -6); + } + _LOBYTE(v9) = IdItemOk(&plr[v1].InvBody[3]); + if ( v9 ) + { + v15 = 1; + qmemcpy(&v13, &plr[v1].InvBody[3], sizeof(v13)); + AddStoreHoldId(v13, -7); + } + v10 = plr[v1]._pNumInv; + i = 0; + if ( v10 > 0 ) + { + v11 = plr[v1].InvList; + v17 = plr[v1].InvList; + do + { + _LOBYTE(v12) = IdItemOk(v11); + if ( v12 ) + { + v15 = 1; + qmemcpy(&v13, v11, sizeof(v13)); + AddStoreHoldId(v13, i); + } + ++i; + v10 = plr[v1]._pNumInv; + v11 = v17 + 1; + ++v17; + } + while ( i < v10 ); + } + v14 = plr[v1]._pGold; + if ( v15 ) + { + stextscrl = 1; + stextsval = 0; + stextsmax = v10; + sprintf(tempstr, "Identify which item? Your gold : %i", v14); + AddSText(0, 1, 1u, tempstr, 3, 0); + AddSLine(3); + AddSLine(21); + S_ScrollSSell(stextsval); + } + else + { + stextscrl = 0; + sprintf(tempstr, "You have nothing to identify. Your gold : %i", v14); + AddSText(0, 1, 1u, tempstr, COL_GOLD, 0); + AddSLine(3); + AddSLine(21); + } + AddSText(0, 22, 1u, "Back", 0, 1); + OffsetSTextY(22, 6); +} +// 69F10C: using guessed type int storenumh; +// 6A09E0: using guessed type char stextsize; +// 6A09E4: using guessed type int stextsmax; +// 6A6BB8: using guessed type int stextscrl; + +//----- (00459F95) -------------------------------------------------------- +void __cdecl S_StartIdShow() +{ + int iclr; // [esp+4h] [ebp-4h] + + StartStore((unsigned char)stextshold); + stextscrl = 0; + ClearSText(5, 23); + _LOBYTE(iclr) = 0; + if ( plr[myplr].HoldItem._iMagical ) + _LOBYTE(iclr) = COL_BLUE; + if ( !plr[myplr].HoldItem._iStatFlag ) + _LOBYTE(iclr) = COL_RED; + AddSText(0, 7, 1u, "This item is:", 0, 0); + AddSText(20, 11, 0, plr[myplr].HoldItem._iIName, iclr, 0); + PrintStoreItem(&plr[myplr].HoldItem, 12, iclr); + AddSText(0, 18, 1u, "Done", 0, 1); +} +// 6A6BB8: using guessed type int stextscrl; + +//----- (0045A046) -------------------------------------------------------- +void __cdecl S_StartTalk() +{ + int *v0; // edi + signed int v1; // eax + int v2; // edx + int *v3; // ecx + char **v4; // ebp + int v5; // esi + int v6; // ebx + signed int v7; // [esp-4h] [ebp-1Ch] + signed int v8; // [esp+10h] [ebp-8h] + int y; // [esp+14h] [ebp-4h] + + stextsize = 0; + stextscrl = 0; + sprintf(tempstr, "Talk to %s", talkname[talker]); + AddSText(0, 2, 1u, tempstr, COL_GOLD, 0); + AddSLine(5); + v0 = &quests[0]._qlog; + v1 = 0; + v2 = 0; + v3 = &quests[0]._qlog; + do + { + if ( *((_BYTE *)v3 - 18) == 2 && *((_DWORD *)&Qtalklist[0]._qinfra + v2 + 16 * talker) != -1 && *v3 ) + ++v1; + v3 += 6; + ++v2; + } + while ( (signed int)v3 < (signed int)&qlist[4] ); + if ( v1 <= 6 ) + { + v7 = 15; + v8 = 2; + } + else + { + v1 >>= 1; + v7 = 14; + v8 = 1; + } + v4 = &questlist[0]._qlstr; + v5 = v7 - v1; + v6 = 0; + y = v7 - v1 - 2; + do + { + if ( *((_BYTE *)v0 - 18) == 2 && *((_DWORD *)&Qtalklist[0]._qinfra + v6 + 16 * talker) != -1 && *v0 ) + { + AddSText(0, v5, 1u, *v4, COL_WHITE, 1); + v5 += v8; + } + v0 += 6; + ++v6; + v4 += 5; + } + while ( (signed int)v0 < (signed int)&qlist[4] ); + AddSText(0, y, 1u, "Gossip", 1, 1); + AddSText(0, 22, 1u, "Back", COL_WHITE, 1); +} +// 69FB38: using guessed type int talker; +// 6A09E0: using guessed type char stextsize; +// 6A6BB8: using guessed type int stextscrl; + +//----- (0045A168) -------------------------------------------------------- +void __cdecl S_StartTavern() +{ + stextsize = 0; + stextscrl = 0; + AddSText(0, 1, 1u, "Welcome to the", COL_GOLD, 0); + AddSText(0, 3, 1u, "Rising Sun", COL_GOLD, 0); + AddSText(0, 9, 1u, "Would you like to:", COL_GOLD, 0); + AddSText(0, 12, 1u, "Talk to Ogden", 1, 1); + AddSText(0, 18, 1u, "Leave the tavern", 0, 1); + AddSLine(5); + storenumh = 20; +} +// 69F10C: using guessed type int storenumh; +// 6A09E0: using guessed type char stextsize; +// 6A6BB8: using guessed type int stextscrl; + +//----- (0045A1EC) -------------------------------------------------------- +void __cdecl S_StartBarMaid() +{ + stextsize = 0; + stextscrl = 0; + AddSText(0, 2, 1u, "Gillian", COL_GOLD, 0); + AddSText(0, 9, 1u, "Would you like to:", COL_GOLD, 0); + AddSText(0, 12, 1u, "Talk to Gillian", 1, 1); + AddSText(0, 18, 1u, "Say goodbye", 0, 1); + AddSLine(5); + storenumh = 20; +} +// 69F10C: using guessed type int storenumh; +// 6A09E0: using guessed type char stextsize; +// 6A6BB8: using guessed type int stextscrl; + +//----- (0045A25E) -------------------------------------------------------- +void __cdecl S_StartDrunk() +{ + stextsize = 0; + stextscrl = 0; + AddSText(0, 2, 1u, "Farnham the Drunk", COL_GOLD, 0); + AddSText(0, 9, 1u, "Would you like to:", COL_GOLD, 0); + AddSText(0, 12, 1u, "Talk to Farnham", 1, 1); + AddSText(0, 18, 1u, "Say Goodbye", 0, 1); + AddSLine(5); + storenumh = 20; +} +// 69F10C: using guessed type int storenumh; +// 6A09E0: using guessed type char stextsize; +// 6A6BB8: using guessed type int stextscrl; + +//----- (0045A2D0) -------------------------------------------------------- +void __fastcall StartStore(int talk_id) +{ + char i; // bl + int v2; // eax + signed int v3; // ecx + int *v4; // eax + + for ( i = talk_id; ; i = 1 ) + { + sbookflag = 0; + invflag = 0; + chrflag = 0; + questlog = 0; + dropGoldFlag = 0; + ClearSText(0, 24); + ReleaseStoreBtn(); + switch ( i ) + { + case STORE_SMITH: + S_StartSmith(); + break; + case STORE_SBUY: + if ( storenumh > 0 ) + S_StartSBuy(); + break; + case STORE_SSELL: + S_StartSSell(); + break; + case STORE_SREPAIR: + S_StartSRepair(); + break; + case STORE_WITCH: + S_StartWitch(); + break; + case STORE_WBUY: + if ( storenumh > 0 ) + S_StartWBuy(); + break; + case STORE_WSELL: + S_StartWSell(); + break; + case STORE_WRECHARGE: + S_StartWRecharge(); + break; + case STORE_NOMONEY: + S_StartNoMoney(); + break; + case STORE_NOROOM: + S_StartNoRoom(); + break; + case STORE_CONFIRM: + S_StartConfirm(); + break; + case STORE_BOY: + S_StartBoy(); + break; + case STORE_BBOY: + S_StartBBoy(); + break; + case STORE_HEALER: + S_StartHealer(); + break; + case STORE_STORY: + S_StartStory(); + break; + case STORE_HBUY: + if ( storenumh > 0 ) + S_StartHBuy(); + break; + case STORE_SIDENTIFY: + S_StartSIdentify(); + break; + case STORE_SPBUY: + _LOBYTE(v2) = S_StartSPBuy(); + if ( !v2 ) + return; + break; + case STORE_GOSSIP: + S_StartTalk(); + break; + case STORE_IDSHOW: + S_StartIdShow(); + break; + case STORE_TAVERN: + S_StartTavern(); + break; + case STORE_DRUNK: + S_StartDrunk(); + break; + case STORE_BARMAID: + S_StartBarMaid(); + break; + default: + break; + } + v3 = 0; + v4 = &stext[0]._ssel; + do + { + if ( *v4 ) + break; + v4 += 39; + ++v3; + } + while ( (signed int)v4 < (signed int)&storehold[0]._iIName[7] ); + stextsel = v3 == 24 ? -1 : v3; + stextflag = i; + if ( i != 2 || storenumh ) + break; + } +} +// 4B84DC: using guessed type int dropGoldFlag; +// 4B8968: using guessed type int sbookflag; +// 69BD04: using guessed type int questlog; +// 69F10C: using guessed type int storenumh; +// 6A8A28: using guessed type int stextsel; +// 6AA705: using guessed type char stextflag; + +//----- (0045A48F) -------------------------------------------------------- +void __cdecl DrawSText() +{ + int v0; // ecx + int v1; // edi + int *v2; // esi + + if ( stextsize ) + DrawQTextBack(); + else + DrawSTextBack(); + if ( !stextscrl ) + goto LABEL_19; + if ( stextflag > (signed int)STORE_WRECHARGE ) + { + switch ( stextflag ) + { + case STORE_HBUY: + S_ScrollHBuy(stextsval); + break; + case STORE_SIDENTIFY: + goto LABEL_17; + case STORE_SPBUY: + S_ScrollSPBuy(stextsval); + break; + } + } + else + { + if ( stextflag >= (signed int)STORE_WSELL ) + goto LABEL_17; + if ( stextflag == STORE_SBUY ) + { + S_ScrollSBuy(stextsval); + goto LABEL_19; + } + if ( stextflag > (signed int)STORE_SBUY ) + { + if ( stextflag > (signed int)STORE_SREPAIR ) + { + if ( stextflag == STORE_WBUY ) + S_ScrollWBuy(stextsval); + goto LABEL_19; + } +LABEL_17: + S_ScrollSSell(stextsval); + goto LABEL_19; + } + } +LABEL_19: + v1 = 0; + v2 = &stext[0]._sval; + do + { + if ( *(v2 - 2) ) + DrawSLine(v1); + if ( *((_BYTE *)v2 - 144) ) + { + _LOBYTE(v0) = *((_BYTE *)v2 - 12); + PrintSString(*(v2 - 38), v1, *(v2 - 4), (char *)v2 - 144, v0, *v2); + } + v2 += 39; + ++v1; + } + while ( (signed int)v2 < (signed int)&storehold[0]._iIName[11] ); + if ( stextscrl ) + DrawSArrows(4, 20); + InStoreFlag = (InStoreFlag & 7) + 1; +} +// 6A09E0: using guessed type char stextsize; +// 6A6BB8: using guessed type int stextscrl; +// 6AA705: using guessed type char stextflag; + +//----- (0045A584) -------------------------------------------------------- +void __cdecl STextESC() +{ + char v0; // cl + char v1; // cl + char v2; // cl + + if ( qtextflag ) + { + qtextflag = 0; + if ( !leveltype ) + sfx_stop(); + } + else + { + switch ( stextflag ) + { + case STORE_SMITH: + case STORE_WITCH: + case STORE_BOY: + case STORE_BBOY: + case STORE_HEALER: + case STORE_STORY: + case STORE_TAVERN: + case STORE_DRUNK: + case STORE_BARMAID: + stextflag = 0; + return; + case STORE_SBUY: + StartStore(1); + stextsel = 12; + return; + case STORE_SSELL: + v1 = 1; + goto LABEL_16; + case STORE_SREPAIR: + v2 = 1; + goto LABEL_14; + case STORE_WBUY: + v0 = 5; + goto LABEL_18; + case STORE_WSELL: + v1 = 5; + goto LABEL_16; + case STORE_WRECHARGE: + v2 = 5; +LABEL_14: + StartStore(v2); + stextsel = 18; + return; + case STORE_NOMONEY: + case STORE_NOROOM: + case STORE_CONFIRM: + StartStore((unsigned char)stextshold); + stextsel = stextlhold; + stextsval = stextvhold; + return; + case STORE_HBUY: + v1 = 14; +LABEL_16: + StartStore(v1); + stextsel = 16; + return; + case STORE_SIDENTIFY: + v0 = 15; + goto LABEL_18; + case STORE_SPBUY: + v0 = 1; +LABEL_18: + StartStore(v0); + stextsel = 14; + break; + case STORE_GOSSIP: + StartStore((unsigned char)stextshold); + stextsel = stextlhold; + break; + case STORE_IDSHOW: + StartStore(17); + break; + default: + return; + } + } +} +// 5BB1ED: using guessed type char leveltype; +// 646D00: using guessed type char qtextflag; +// 69F110: using guessed type int stextlhold; +// 6A8A24: using guessed type int stextvhold; +// 6A8A28: using guessed type int stextsel; +// 6AA705: using guessed type char stextflag; + +//----- (0045A6AF) -------------------------------------------------------- +void __cdecl STextUp() +{ + int v0; // eax + + PlaySFX(IS_TITLEMOV); + if ( stextsel != -1 ) + { + if ( stextscrl ) + { + if ( stextsel == stextup ) + { + if ( stextsval ) + --stextsval; + return; + } + v0 = stextsel - 1; + stextsel = v0; + if ( stext[v0]._ssel ) + return; + do + { + if ( v0 ) + --v0; + else + v0 = 23; + } + while ( !stext[v0]._ssel ); +LABEL_20: + stextsel = v0; + return; + } + if ( stextsel ) + v0 = stextsel - 1; + else + v0 = 23; + stextsel = v0; + if ( !stext[v0]._ssel ) + { + do + { + if ( v0 ) + --v0; + else + v0 = 23; + } + while ( !stext[v0]._ssel ); + goto LABEL_20; + } + } +} +// 69F108: using guessed type int stextup; +// 6A6BB8: using guessed type int stextscrl; +// 6A8A28: using guessed type int stextsel; + +//----- (0045A757) -------------------------------------------------------- +void __cdecl STextDown() +{ + int v0; // eax + + PlaySFX(IS_TITLEMOV); + if ( stextsel != -1 ) + { + if ( stextscrl ) + { + if ( stextsel == stextdown ) + { + if ( stextsval < stextsmax ) + ++stextsval; + return; + } + v0 = stextsel + 1; + stextsel = v0; + if ( stext[v0]._ssel ) + return; + do + { + if ( v0 == 23 ) + v0 = 0; + else + ++v0; + } + while ( !stext[v0]._ssel ); +LABEL_20: + stextsel = v0; + return; + } + if ( stextsel == 23 ) + v0 = 0; + else + v0 = stextsel + 1; + stextsel = v0; + if ( !stext[v0]._ssel ) + { + do + { + if ( v0 == 23 ) + v0 = 0; + else + ++v0; + } + while ( !stext[v0]._ssel ); + goto LABEL_20; + } + } +} +// 6A09E4: using guessed type int stextsmax; +// 6A6BB8: using guessed type int stextscrl; +// 6A8A28: using guessed type int stextsel; +// 6AA700: using guessed type int stextdown; + +//----- (0045A804) -------------------------------------------------------- +void __cdecl STextPrior() +{ + PlaySFX(IS_TITLEMOV); + if ( stextsel != -1 && stextscrl ) + { + if ( stextsel == stextup ) + { + if ( stextsval ) + { + stextsval -= 4; + if ( stextsval < 0 ) + stextsval = 0; + } + } + else + { + stextsel = stextup; + } + } +} +// 69F108: using guessed type int stextup; +// 6A6BB8: using guessed type int stextscrl; +// 6A8A28: using guessed type int stextsel; + +//----- (0045A84E) -------------------------------------------------------- +void __cdecl STextNext() +{ + bool v0; // zf + bool v1; // sf + unsigned char v2; // of + + PlaySFX(IS_TITLEMOV); + if ( stextsel != -1 && stextscrl ) + { + if ( stextsel == stextdown ) + { + v2 = __OFSUB__(stextsval, stextsmax); + v0 = stextsval == stextsmax; + v1 = stextsval - stextsmax < 0; + if ( stextsval < stextsmax ) + { + stextsval += 4; + v2 = __OFSUB__(stextsval, stextsmax); + v0 = stextsval == stextsmax; + v1 = stextsval - stextsmax < 0; + } + if ( !((unsigned char)(v1 ^ v2) | v0) ) + stextsval = stextsmax; + } + else + { + stextsel = stextdown; + } + } +} +// 6A09E4: using guessed type int stextsmax; +// 6A6BB8: using guessed type int stextscrl; +// 6A8A28: using guessed type int stextsel; +// 6AA700: using guessed type int stextdown; + +//----- (0045A89B) -------------------------------------------------------- +void __cdecl S_SmithEnter() +{ + int v0; // ecx + + v0 = 10; + if ( stextsel == 10 ) + { + talker = 0; + stextlhold = 10; + stextshold = 1; + gossipstart = 189; + gossipend = 199; + _LOBYTE(v0) = 19; + goto LABEL_13; + } + v0 = 2; + switch ( stextsel ) + { + case 12: +LABEL_13: + StartStore(v0); + return; + case 14: + _LOBYTE(v0) = 18; + goto LABEL_13; + case 16: + _LOBYTE(v0) = 3; + goto LABEL_13; + case 18: + _LOBYTE(v0) = 4; + goto LABEL_13; + case 20: + stextflag = 0; + break; + } +} +// 69F110: using guessed type int stextlhold; +// 69FB38: using guessed type int talker; +// 6A4EF0: using guessed type int gossipstart; +// 6A8A28: using guessed type int stextsel; +// 6A8A30: using guessed type int gossipend; +// 6AA705: using guessed type char stextflag; + +//----- (0045A904) -------------------------------------------------------- +void __fastcall SetGoldCurs(int pnum, int i) +{ + int v2; // eax + signed int v3; // ecx + + v2 = 21720 * pnum + 368 * i; + v3 = *(int *)((char *)&plr[0].InvList[0]._ivalue + v2); + if ( v3 < 2500 ) + { + if ( v3 > 1000 ) + *(int *)((char *)&plr[0].InvList[0]._iCurs + v2) = 5; + else + *(int *)((char *)&plr[0].InvList[0]._iCurs + v2) = 4; + } + else + { + *(int *)((char *)&plr[0].InvList[0]._iCurs + v2) = 6; + } +} + +//----- (0045A94A) -------------------------------------------------------- +void __fastcall SetSpdbarGoldCurs(int pnum, int i) +{ + int v2; // eax + signed int v3; // ecx + + v2 = 21720 * pnum + 368 * i; + v3 = *(int *)((char *)&plr[0].SpdList[0]._ivalue + v2); + if ( v3 < 2500 ) + { + if ( v3 > 1000 ) + *(int *)((char *)&plr[0].SpdList[0]._iCurs + v2) = 5; + else + *(int *)((char *)&plr[0].SpdList[0]._iCurs + v2) = 4; + } + else + { + *(int *)((char *)&plr[0].SpdList[0]._iCurs + v2) = 6; + } +} + +//----- (0045A990) -------------------------------------------------------- +void __fastcall TakePlrsMoney(int cost) +{ + int v1; // edi + int v2; // eax + int v3; // esi + int v4; // ebx + int v5; // eax + _DWORD *v6; // ecx + int v7; // eax + int v8; // ebx + int v9; // eax + _DWORD *v10; // ecx + int v11; // eax + signed int v12; // ebx + int v13; // eax + int v14; // eax + _DWORD *v15; // ecx + int v16; // eax + signed int v17; // ebx + int v18; // eax + int v19; // eax + _DWORD *v20; // ecx + int v21; // eax + + v1 = cost; + v2 = CalculateGold(myplr); + v3 = myplr; + v4 = 0; + plr[myplr]._pGold = v2 - v1; + while ( v1 > 0 ) + { + v5 = 368 * v4 + 21720 * v3; + if ( *(int *)((char *)&plr[0].SpdList[0]._itype + v5) == ITYPE_GOLD ) + { + v6 = (unsigned int *)((char *)&plr[0].SpdList[0]._ivalue + v5); + v7 = *(int *)((char *)&plr[0].SpdList[0]._ivalue + v5); + if ( v7 != 5000 ) + { + if ( v1 >= v7 ) + { + v1 -= v7; + RemoveSpdBarItem(v3, v4); + v3 = myplr; + v4 = -1; + } + else + { + *v6 = v7 - v1; + SetSpdbarGoldCurs(v3, v4); + v1 = 0; + } + } + } + if ( ++v4 >= 8 ) + { + if ( v1 > 0 ) + { + v8 = 0; + do + { + if ( v1 <= 0 ) + break; + v9 = 368 * v8 + 21720 * v3; + if ( *(int *)((char *)&plr[0].SpdList[0]._itype + v9) == ITYPE_GOLD ) + { + v10 = (unsigned int *)((char *)&plr[0].SpdList[0]._ivalue + v9); + v11 = *(int *)((char *)&plr[0].SpdList[0]._ivalue + v9); + if ( v1 >= v11 ) + { + v1 -= v11; + RemoveSpdBarItem(v3, v8); + v3 = myplr; + v8 = -1; + } + else + { + *v10 = v11 - v1; + SetSpdbarGoldCurs(v3, v8); + v1 = 0; + } + } + ++v8; + } + while ( v8 < 8 ); + } + break; + } + } + v12 = 0; + force_redraw = 255; + if ( v1 > 0 ) + { + v13 = 21720 * v3; + if ( plr[v3]._pNumInv <= 0 ) + { +LABEL_26: + v17 = 0; + if ( v1 > 0 ) + { + v18 = 21720 * v3; + if ( plr[v3]._pNumInv > 0 ) + { + do + { + if ( v1 <= 0 ) + break; + v19 = 368 * v17 + v18; + if ( *(int *)((char *)&plr[0].InvList[0]._itype + v19) == ITYPE_GOLD ) + { + v20 = (unsigned int *)((char *)&plr[0].InvList[0]._ivalue + v19); + v21 = *(int *)((char *)&plr[0].InvList[0]._ivalue + v19); + if ( v1 >= v21 ) + { + v1 -= v21; + RemoveInvItem(v3, v17); + v3 = myplr; + v17 = -1; + } + else + { + *v20 = v21 - v1; + SetGoldCurs(v3, v17); + v1 = 0; + } + } + ++v17; + v18 = 21720 * v3; + } + while ( v17 < plr[v3]._pNumInv ); + } + } + } + else + { + while ( v1 > 0 ) + { + v14 = 368 * v12 + v13; + if ( *(int *)((char *)&plr[0].InvList[0]._itype + v14) == ITYPE_GOLD ) + { + v15 = (unsigned int *)((char *)&plr[0].InvList[0]._ivalue + v14); + v16 = *(int *)((char *)&plr[0].InvList[0]._ivalue + v14); + if ( v16 != 5000 ) + { + if ( v1 >= v16 ) + { + v1 -= v16; + RemoveInvItem(v3, v12); + v3 = myplr; + v12 = -1; + } + else + { + *v15 = v16 - v1; + SetGoldCurs(v3, v12); + v1 = 0; + } + } + } + ++v12; + v13 = 21720 * v3; + if ( v12 >= plr[v3]._pNumInv ) + goto LABEL_26; + } + } + } +} +// 52571C: using guessed type int force_redraw; + +//----- (0045AB69) -------------------------------------------------------- +void __cdecl SmithBuyItem() +{ + int v0; // eax + ItemStruct *v1; // edx + ItemStruct *v2; // edi + bool v3; // zf + + TakePlrsMoney(plr[myplr].HoldItem._iIvalue); + if ( !plr[myplr].HoldItem._iMagical ) + plr[myplr].HoldItem._iIdentified = 0; + StoreAutoPlace(); + v0 = stextvhold + ((stextlhold - stextup) >> 2); + if ( v0 == 19 ) + { + smithitem[19]._itype = -1; + } + else + { + if ( smithitem[v0 + 1]._itype != -1 ) + { + v1 = &smithitem[v0]; + do + { + v2 = v1; + ++v1; + ++v0; + v3 = v1[1]._itype == -1; + qmemcpy(v2, v1, sizeof(ItemStruct)); + } + while ( !v3 ); + } + smithitem[v0]._itype = -1; + } + CalcPlrInv(myplr, 1u); +} +// 69F108: using guessed type int stextup; +// 69F110: using guessed type int stextlhold; +// 6A8A24: using guessed type int stextvhold; + +//----- (0045AC14) -------------------------------------------------------- +void __cdecl S_SBuyEnter() +{ + int v0; // eax + int v1; // ecx + int v2; // eax + int v3; // esi + char v4; // cl + + if ( stextsel == 22 ) + { + StartStore(1); + stextsel = 12; + } + else + { + stextlhold = stextsel; + stextvhold = stextsval; + stextshold = 2; + v0 = myplr; + v1 = stextsval + ((stextsel - stextup) >> 2); + if ( plr[myplr]._pGold >= smithitem[v1]._iIvalue ) + { + qmemcpy(&plr[v0].HoldItem, &smithitem[v1], sizeof(plr[v0].HoldItem)); + SetCursor(plr[v0].HoldItem._iCurs + 12); + v2 = 0; + v3 = 0; + do + { + if ( v2 ) + goto LABEL_9; + v2 = AutoPlace(myplr, v3++, cursW / 28, cursH / 28, 0); + } + while ( v3 < 40 ); + if ( v2 ) + { +LABEL_9: + v4 = 11; + goto LABEL_11; + } + v4 = 10; +LABEL_11: + StartStore(v4); + SetCursor(1); + } + else + { + StartStore(9); + } + } +} +// 4B8C9C: using guessed type int cursH; +// 69F108: using guessed type int stextup; +// 69F110: using guessed type int stextlhold; +// 6A8A24: using guessed type int stextvhold; +// 6A8A28: using guessed type int stextsel; + +//----- (0045ACE9) -------------------------------------------------------- +void __cdecl SmithBuyPItem() +{ + int v0; // ecx + int v1; // eax + bool v2; // sf + int v3; // eax + int v4; // edx + int *v5; // esi + int v6; // eax + + TakePlrsMoney(plr[myplr].HoldItem._iIvalue); + if ( !plr[myplr].HoldItem._iMagical ) + plr[myplr].HoldItem._iIdentified = 0; + StoreAutoPlace(); + v0 = 0; + v1 = (stextlhold - stextup) >> 2; + v2 = stextvhold + v1 < 0; + v3 = stextvhold + v1; + v4 = 0; + if ( !v2 ) + { + v5 = &premiumitem[0]._itype; + do + { + if ( *v5 != -1 ) + { + --v3; + v0 = v4; + } + ++v4; + v5 += 92; + } + while ( v3 >= 0 ); + } + v6 = myplr; + premiumitem[v0]._itype = -1; + --numpremium; + SpawnPremium(plr[v6]._pLevel); +} +// 69F108: using guessed type int stextup; +// 69F110: using guessed type int stextlhold; +// 6A8A24: using guessed type int stextvhold; + +//----- (0045AD7E) -------------------------------------------------------- +void __cdecl S_SPBuyEnter() +{ + int v0; // eax + bool v1; // sf + int v2; // eax + int v3; // ecx + int v4; // edx + int *v5; // esi + int v6; // ecx + int v7; // eax + int v8; // eax + int v9; // esi + char v10; // cl + + if ( stextsel == 22 ) + { + StartStore(1); + stextsel = 14; + } + else + { + stextlhold = stextsel; + stextshold = 18; + stextvhold = stextsval; + v0 = (stextsel - stextup) >> 2; + v1 = stextsval + v0 < 0; + v2 = stextsval + v0; + v3 = 0; + v4 = 0; + if ( !v1 ) + { + v5 = &premiumitem[0]._itype; + do + { + if ( *v5 != -1 ) + { + --v2; + v3 = v4; + } + ++v4; + v5 += 92; + } + while ( v2 >= 0 ); + } + v6 = v3; + v7 = myplr; + if ( plr[myplr]._pGold >= premiumitem[v6]._iIvalue ) + { + qmemcpy(&plr[v7].HoldItem, &premiumitem[v6], sizeof(plr[v7].HoldItem)); + SetCursor(plr[v7].HoldItem._iCurs + 12); + v8 = 0; + v9 = 0; + do + { + if ( v8 ) + goto LABEL_14; + v8 = AutoPlace(myplr, v9++, cursW / 28, cursH / 28, 0); + } + while ( v9 < 40 ); + if ( v8 ) + { +LABEL_14: + v10 = 11; + goto LABEL_16; + } + v10 = 10; +LABEL_16: + StartStore(v10); + SetCursor(1); + } + else + { + StartStore(9); + } + } +} +// 4B8C9C: using guessed type int cursH; +// 69F108: using guessed type int stextup; +// 69F110: using guessed type int stextlhold; +// 6A8A24: using guessed type int stextvhold; +// 6A8A28: using guessed type int stextsel; + +//----- (0045AE72) -------------------------------------------------------- +unsigned char __fastcall StoreGoldFit(int idx) +{ + int v1; // ecx + int v2; // edi + int v3; // ebx + signed int v5; // ecx + int v6; // eax + int v7; // edx + int *v8; // ecx + int v9; // eax + int v10; // eax + int v11; // [esp+Ch] [ebp-4h] + + v1 = idx; + v2 = storehold[v1]._iIvalue; + v3 = storehold[v1]._iIvalue / 5000; + if ( storehold[v1]._iIvalue % 5000 ) + ++v3; + SetCursor(storehold[v1]._iCurs + 12); + v11 = cursW / 28 * (cursH / 28); + SetCursor(1); + if ( v11 >= v3 ) + return 1; + v5 = 0; + v6 = myplr; + do + { + if ( !plr[v6].InvGrid[v5] ) + ++v11; + ++v5; + } + while ( v5 < 40 ); + v7 = plr[v6]._pNumInv; + if ( v7 > 0 ) + { + v8 = &plr[v6].InvList[0]._ivalue; + do + { + if ( *(v8 - 47) == 11 && *v8 != 5000 ) + { + v9 = v2 + *v8; + if ( v9 > 5000 ) + v2 = v9 - 5000; + else + v2 = 0; + } + v8 += 92; + --v7; + } + while ( v7 ); + } + v10 = v2 / 5000; + if ( v2 % 5000 ) + ++v10; + return v11 >= v10; +} +// 4B8C9C: using guessed type int cursH; + +//----- (0045AF48) -------------------------------------------------------- +void __fastcall PlaceStoreGold(int v) +{ + int v1; // ebx + signed int v2; // ecx + int v3; // eax + int v4; // ebp + int v5; // esi + int i; // ST20_4 + int v7; // eax + int v8; // edx + signed int v9; // [esp+10h] [ebp-10h] + int v10; // [esp+18h] [ebp-8h] + + v1 = myplr; + v10 = v; + v2 = 0; + v9 = 0; + do + { + if ( v2 ) + break; + v3 = v1; + v4 = 10 * (v9 / 10); + if ( !plr[v1].InvGrid[v9 % 10 + v4] ) + { + v5 = plr[v3]._pNumInv; + i = plr[v3]._pNumInv; + GetGoldSeed(v1, &golditem._iSeed); + v1 = myplr; + v7 = myplr; + v8 = 368 * v5 + 21720 * myplr; + qmemcpy((char *)plr[0].InvList + v8, &golditem, 0x170u); + ++plr[v7]._pNumInv; + plr[0].InvGrid[v9 % 10 + v7 * 21720 + v4] = plr[v7]._pNumInv; + *(int *)((char *)&plr[0].InvList[0]._ivalue + v8) = v10; + SetGoldCurs(v1, i); + v2 = 1; + } + ++v9; + } + while ( v9 < 40 ); +} + +//----- (0045B010) -------------------------------------------------------- +void __cdecl StoreSellItem() +{ + int v0; // ebx + char v1; // al + int v2; // eax + int v3; // ebp + bool v4; // sf + unsigned char v5; // of + unsigned int v6; // eax + int v7; // ebx + int v8; // edx + int v9; // esi + int *v10; // edi + int v11; // eax + unsigned int v12; // esi + int v13; // [esp+10h] [ebp-4h] + + v0 = stextvhold + ((stextlhold - stextup) >> 2); + v1 = storehidx[v0]; + if ( v1 < 0 ) + RemoveSpdBarItem(myplr, -1 - v1); + else + RemoveInvItem(myplr, v1); + v2 = storenumh - 1; + v3 = storehold[v0]._iIvalue; + v5 = __OFSUB__(v0, storenumh - 1); + v4 = v0 - (storenumh-- - 1) < 0; + if ( v4 ^ v5 ) + { + v6 = v2 - v0; + qmemcpy(&storehidx[v0], &storehidx[v0 + 1], v6); + qmemcpy(&storehold[v0], &storehold[v0 + 1], 4 * (368 * v6 >> 2)); + } + v7 = myplr; + v8 = 0; + v13 = 0; + v9 = myplr; + plr[v9]._pGold += v3; + if ( plr[v9]._pNumInv <= 0 ) + { +LABEL_15: + if ( v3 > 0 ) + { + if ( v3 > 5000 ) + { + v12 = (v3 - 5001) / 0x1388u + 1; + v3 += -5000 * v12; + do + { + PlaceStoreGold(5000); + --v12; + } + while ( v12 ); + } + PlaceStoreGold(v3); + } + } + else + { + v10 = &plr[v9].InvList[0]._ivalue; + while ( v3 > 0 ) + { + if ( *(v10 - 47) == 11 && *v10 != 5000 ) + { + v11 = v3 + *v10; + if ( v11 > 5000 ) + { + *v10 = 5000; + v3 = v11 - 5000; + SetGoldCurs(v7, v8); + } + else + { + *v10 = v11; + SetGoldCurs(v7, v8); + v3 = 0; + } + } + v10 += 92; + v8 = v13++ + 1; + if ( v13 >= plr[v9]._pNumInv ) + goto LABEL_15; + } + } +} +// 69F108: using guessed type int stextup; +// 69F10C: using guessed type int storenumh; +// 69F110: using guessed type int stextlhold; +// 6A8A24: using guessed type int stextvhold; + +//----- (0045B160) -------------------------------------------------------- +void __cdecl S_SSellEnter() +{ + int v0; // eax + int v1; // eax + char v2; // cl + + if ( stextsel == 22 ) + { + StartStore(1); + stextsel = 16; + } + else + { + stextlhold = stextsel; + v0 = stextsval + ((stextsel - stextup) >> 2); + stextshold = 3; + stextvhold = stextsval; + qmemcpy(&plr[myplr].HoldItem, &storehold[v0], sizeof(plr[myplr].HoldItem)); + _LOBYTE(v1) = StoreGoldFit(v0); + v2 = 11; + if ( !v1 ) + v2 = 10; + StartStore(v2); + } +} +// 69F108: using guessed type int stextup; +// 69F110: using guessed type int stextlhold; +// 6A8A24: using guessed type int stextvhold; +// 6A8A28: using guessed type int stextsel; + +//----- (0045B1DF) -------------------------------------------------------- +void __cdecl SmithRepairItem() +{ + int v0; // eax + int v1; // edx + + TakePlrsMoney(plr[myplr].HoldItem._iIvalue); + v0 = storehidx[stextvhold + ((stextlhold - stextup) >> 2)]; + storehold[stextvhold + ((stextlhold - stextup) >> 2)]._iDurability = storehold[stextvhold + + ((stextlhold - stextup) >> 2)]._iMaxDur; + if ( v0 >= 0 ) + { + plr[myplr].InvList[v0]._iDurability = plr[myplr].InvList[v0]._iMaxDur; + } + else + { + v1 = myplr; + if ( v0 == -1 ) + plr[myplr].InvBody[0]._iDurability = plr[myplr].InvBody[0]._iMaxDur; + if ( v0 == -2 ) + plr[v1].InvBody[6]._iDurability = plr[v1].InvBody[6]._iMaxDur; + if ( v0 == -3 ) + plr[v1].InvBody[4]._iDurability = plr[v1].InvBody[4]._iMaxDur; + if ( v0 == -4 ) + plr[v1].InvBody[5]._iDurability = plr[v1].InvBody[5]._iMaxDur; + } +} +// 69F108: using guessed type int stextup; +// 69F110: using guessed type int stextlhold; +// 6A8A24: using guessed type int stextvhold; + +//----- (0045B2B6) -------------------------------------------------------- +void __cdecl S_SRepairEnter() +{ + int v0; // eax + int v1; // edx + int v2; // ecx + bool v3; // sf + unsigned char v4; // of + char v5; // cl + + if ( stextsel == 22 ) + { + StartStore(1); + stextsel = 18; + } + else + { + stextlhold = stextsel; + stextshold = 4; + v0 = stextsval + ((stextsel - stextup) >> 2); + v1 = myplr; + stextvhold = stextsval; + qmemcpy(&plr[myplr].HoldItem, &storehold[v0], sizeof(plr[myplr].HoldItem)); + v2 = plr[v1]._pGold; + v4 = __OFSUB__(v2, storehold[v0]._iIvalue); + v3 = v2 - storehold[v0]._iIvalue < 0; + v5 = 9; + if ( !(v3 ^ v4) ) + v5 = 11; + StartStore(v5); + } +} +// 69F108: using guessed type int stextup; +// 69F110: using guessed type int stextlhold; +// 6A8A24: using guessed type int stextvhold; +// 6A8A28: using guessed type int stextsel; + +//----- (0045B337) -------------------------------------------------------- +void __cdecl S_WitchEnter() +{ + int v0; // ecx + + v0 = 12; + if ( stextsel == 12 ) + { + stextlhold = 12; + talker = 6; + stextshold = 5; + gossipstart = 213; + gossipend = 223; + _LOBYTE(v0) = 19; + goto LABEL_12; + } + v0 = 2; + switch ( stextsel ) + { + case 14: + _LOBYTE(v0) = 6; + goto LABEL_12; + case 16: + _LOBYTE(v0) = 7; + goto LABEL_12; + case 18: + _LOBYTE(v0) = 8; +LABEL_12: + StartStore(v0); + return; + case 20: + stextflag = 0; + break; + } +} +// 69F110: using guessed type int stextlhold; +// 69FB38: using guessed type int talker; +// 6A4EF0: using guessed type int gossipstart; +// 6A8A28: using guessed type int stextsel; +// 6A8A30: using guessed type int gossipend; +// 6AA705: using guessed type char stextflag; + +//----- (0045B39F) -------------------------------------------------------- +void __cdecl WitchBuyItem() +{ + int v0; // ebx + int v1; // eax + int v2; // ecx + ItemStruct *v3; // eax + ItemStruct *v4; // edi + bool v5; // zf + + v0 = stextvhold + ((stextlhold - stextup) >> 2); + if ( v0 >= 3 ) + { + v2 = myplr; + } + else + { + v1 = GetRndSeed(); + v2 = myplr; + plr[myplr].HoldItem._iSeed = v1; + } + TakePlrsMoney(plr[v2].HoldItem._iIvalue); + StoreAutoPlace(); + if ( v0 >= 3 ) + { + if ( v0 == 19 ) + { + witchitem[19]._itype = -1; + } + else + { + if ( witchitem[v0 + 1]._itype != -1 ) + { + v3 = &witchitem[v0]; + do + { + v4 = v3; + ++v3; + ++v0; + v5 = v3[1]._itype == -1; + qmemcpy(v4, v3, sizeof(ItemStruct)); + } + while ( !v5 ); + } + witchitem[v0]._itype = -1; + } + } + CalcPlrInv(myplr, 1u); +} +// 69F108: using guessed type int stextup; +// 69F110: using guessed type int stextlhold; +// 6A8A24: using guessed type int stextvhold; + +//----- (0045B457) -------------------------------------------------------- +void __cdecl S_WBuyEnter() +{ + int v0; // eax + int v1; // ecx + int v2; // eax + int v3; // esi + char v4; // cl + + if ( stextsel == 22 ) + { + StartStore(5); + stextsel = 14; + } + else + { + stextlhold = stextsel; + stextvhold = stextsval; + stextshold = 6; + v0 = myplr; + v1 = stextsval + ((stextsel - stextup) >> 2); + if ( plr[myplr]._pGold >= witchitem[v1]._iIvalue ) + { + qmemcpy(&plr[v0].HoldItem, &witchitem[v1], sizeof(plr[v0].HoldItem)); + SetCursor(plr[v0].HoldItem._iCurs + 12); + v2 = 0; + v3 = 0; + do + { + if ( v2 ) + goto LABEL_9; + v2 = SpecialAutoPlace(myplr, v3++, cursW / 28, cursH / 28, 0); + } + while ( v3 < 40 ); + if ( v2 ) + { +LABEL_9: + v4 = 11; + goto LABEL_11; + } + v4 = 10; +LABEL_11: + StartStore(v4); + SetCursor(1); + } + else + { + StartStore(9); + } + } +} +// 4B8C9C: using guessed type int cursH; +// 69F108: using guessed type int stextup; +// 69F110: using guessed type int stextlhold; +// 6A8A24: using guessed type int stextvhold; +// 6A8A28: using guessed type int stextsel; + +//----- (0045B52C) -------------------------------------------------------- +void __cdecl S_WSellEnter() +{ + int v0; // eax + int v1; // eax + char v2; // cl + + if ( stextsel == 22 ) + { + StartStore(5); + stextsel = 16; + } + else + { + stextlhold = stextsel; + v0 = stextsval + ((stextsel - stextup) >> 2); + stextshold = 7; + stextvhold = stextsval; + qmemcpy(&plr[myplr].HoldItem, &storehold[v0], sizeof(plr[myplr].HoldItem)); + _LOBYTE(v1) = StoreGoldFit(v0); + v2 = 11; + if ( !v1 ) + v2 = 10; + StartStore(v2); + } +} +// 69F108: using guessed type int stextup; +// 69F110: using guessed type int stextlhold; +// 6A8A24: using guessed type int stextvhold; +// 6A8A28: using guessed type int stextsel; + +//----- (0045B5AB) -------------------------------------------------------- +void __cdecl WitchRechargeItem() +{ + int v0; // eax + int v1; // ecx + + TakePlrsMoney(plr[myplr].HoldItem._iIvalue); + v0 = storehidx[stextvhold + ((stextlhold - stextup) >> 2)]; + storehold[stextvhold + ((stextlhold - stextup) >> 2)]._iCharges = storehold[stextvhold + + ((stextlhold - stextup) >> 2)]._iMaxCharges; + v1 = myplr; + if ( v0 >= 0 ) + plr[myplr].InvList[v0]._iCharges = plr[myplr].InvList[v0]._iMaxCharges; + else + plr[myplr].InvBody[4]._iCharges = plr[myplr].InvBody[4]._iMaxCharges; + CalcPlrInv(v1, 1u); +} +// 69F108: using guessed type int stextup; +// 69F110: using guessed type int stextlhold; +// 6A8A24: using guessed type int stextvhold; + +//----- (0045B634) -------------------------------------------------------- +void __cdecl S_WRechargeEnter() +{ + int v0; // eax + int v1; // edx + int v2; // ecx + bool v3; // sf + unsigned char v4; // of + char v5; // cl + + if ( stextsel == 22 ) + { + StartStore(5); + stextsel = 18; + } + else + { + stextlhold = stextsel; + stextshold = 8; + v0 = stextsval + ((stextsel - stextup) >> 2); + v1 = myplr; + stextvhold = stextsval; + qmemcpy(&plr[myplr].HoldItem, &storehold[v0], sizeof(plr[myplr].HoldItem)); + v2 = plr[v1]._pGold; + v4 = __OFSUB__(v2, storehold[v0]._iIvalue); + v3 = v2 - storehold[v0]._iIvalue < 0; + v5 = 9; + if ( !(v3 ^ v4) ) + v5 = 11; + StartStore(v5); + } +} +// 69F108: using guessed type int stextup; +// 69F110: using guessed type int stextlhold; +// 6A8A24: using guessed type int stextvhold; +// 6A8A28: using guessed type int stextsel; + +//----- (0045B6B5) -------------------------------------------------------- +void __cdecl S_BoyEnter() +{ + signed int v0; // ecx + + v0 = boyitem._itype; + if ( boyitem._itype != -1 && stextsel == 18 ) + { + v0 = 50; + if ( plr[myplr]._pGold >= 50 ) + { + TakePlrsMoney(50); + _LOBYTE(v0) = 13; + } + else + { + stextshold = 12; + stextlhold = 18; + stextvhold = stextsval; + _LOBYTE(v0) = 9; + } + goto LABEL_5; + } + if ( stextsel == 8 && boyitem._itype != -1 || stextsel == 12 && boyitem._itype == -1 ) + { + talker = 8; + stextshold = 12; + stextlhold = stextsel; + gossipstart = 225; + gossipend = 234; + _LOBYTE(v0) = 19; +LABEL_5: + StartStore(v0); + return; + } + stextflag = 0; +} +// 69F110: using guessed type int stextlhold; +// 69FB38: using guessed type int talker; +// 6A4EF0: using guessed type int gossipstart; +// 6A8A24: using guessed type int stextvhold; +// 6A8A28: using guessed type int stextsel; +// 6A8A30: using guessed type int gossipend; +// 6AA705: using guessed type char stextflag; + +//----- (0045B757) -------------------------------------------------------- +void __cdecl BoyBuyItem() +{ + TakePlrsMoney(plr[myplr].HoldItem._iIvalue); + StoreAutoPlace(); + boyitem._itype = -1; + stextshold = 12; + CalcPlrInv(myplr, 1u); +} + +//----- (0045B791) -------------------------------------------------------- +void __cdecl HealerBuyItem() +{ + int v0; // esi + bool v1; // sf + unsigned char v2; // of + int v3; // eax + int v4; // ecx + bool v5; // sf + unsigned char v6; // of + int v7; // eax + ItemStruct *v8; // edx + ItemStruct *v9; // edi + bool v10; // zf + + v0 = stextvhold + ((stextlhold - stextup) >> 2); + if ( gbMaxPlayers == 1 ) + { + v2 = __OFSUB__(v0, 2); + v1 = v0 - 2 < 0; + } + else + { + v2 = __OFSUB__(v0, 3); + v1 = v0 - 3 < 0; + } + if ( v1 ^ v2 ) + { + v3 = GetRndSeed(); + v4 = myplr; + plr[myplr].HoldItem._iSeed = v3; + } + else + { + v4 = myplr; + } + TakePlrsMoney(plr[v4].HoldItem._iIvalue); + if ( !plr[myplr].HoldItem._iMagical ) + plr[myplr].HoldItem._iIdentified = 0; + StoreAutoPlace(); + if ( gbMaxPlayers == 1 ) + { + v6 = __OFSUB__(v0, 2); + v5 = v0 - 2 < 0; + } + else + { + v6 = __OFSUB__(v0, 3); + v5 = v0 - 3 < 0; + } + if ( !(v5 ^ v6) ) + { + v7 = stextvhold + ((stextlhold - stextup) >> 2); + if ( v7 == 19 ) + { + healitem[19]._itype = -1; + } + else + { + if ( healitem[v7 + 1]._itype != -1 ) + { + v8 = &healitem[v7]; + do + { + v9 = v8; + ++v8; + ++v7; + v10 = v8[1]._itype == -1; + qmemcpy(v9, v8, sizeof(ItemStruct)); + } + while ( !v10 ); + } + healitem[v7]._itype = -1; + } + CalcPlrInv(myplr, 1u); + } +} +// 679660: using guessed type char gbMaxPlayers; +// 69F108: using guessed type int stextup; +// 69F110: using guessed type int stextlhold; +// 6A8A24: using guessed type int stextvhold; + +//----- (0045B895) -------------------------------------------------------- +void __cdecl S_BBuyEnter() +{ + int v0; // ecx + int v1; // eax + int v2; // ecx + int v3; // eax + int v4; // esi + + if ( stextsel == 10 ) + { + v0 = boyitem._iIvalue; + stextvhold = stextsval; + v1 = myplr; + stextshold = 13; + stextlhold = 10; + if ( plr[myplr]._pGold >= boyitem._iIvalue + (boyitem._iIvalue >> 1) ) + { + qmemcpy(&plr[v1].HoldItem, &boyitem, sizeof(plr[v1].HoldItem)); + plr[v1].HoldItem._iIvalue += plr[v1].HoldItem._iIvalue >> 1; + SetCursor(plr[v1].HoldItem._iCurs + 12); + v3 = 0; + v4 = 0; + do + { + if ( v3 ) + goto LABEL_8; + v3 = AutoPlace(myplr, v4++, cursW / 28, cursH / 28, 0); + } + while ( v4 < 40 ); + if ( v3 ) + { +LABEL_8: + _LOBYTE(v2) = 11; + goto LABEL_10; + } + _LOBYTE(v2) = 10; +LABEL_10: + StartStore(v2); + SetCursor(1); + } + else + { + _LOBYTE(v0) = 9; + StartStore(v0); + } + } + else + { + stextflag = 0; + } +} +// 4B8C9C: using guessed type int cursH; +// 69F110: using guessed type int stextlhold; +// 6A8A24: using guessed type int stextvhold; +// 6A8A28: using guessed type int stextsel; +// 6AA705: using guessed type char stextflag; + +//----- (0045B968) -------------------------------------------------------- +void __cdecl StoryIdItem() +{ + int v0; // ecx + int v1; // eax + int v2; // eax + + v0 = storehidx[((stextlhold - stextup) >> 2) + stextvhold]; + v1 = myplr; + if ( v0 >= 0 ) + { + plr[myplr].InvList[v0]._iIdentified = 1; + } + else + { + if ( v0 == -1 ) + plr[myplr].InvBody[0]._iIdentified = 1; + if ( v0 == -2 ) + plr[v1].InvBody[6]._iIdentified = 1; + if ( v0 == -3 ) + plr[v1].InvBody[4]._iIdentified = 1; + if ( v0 == -4 ) + plr[v1].InvBody[5]._iIdentified = 1; + if ( v0 == -5 ) + plr[v1].InvBody[1]._iIdentified = 1; + if ( v0 == -6 ) + plr[v1].InvBody[2]._iIdentified = 1; + if ( v0 == -7 ) + plr[v1].InvBody[3]._iIdentified = 1; + } + v2 = v1; + plr[v2].HoldItem._iIdentified = 1; + TakePlrsMoney(plr[v2].HoldItem._iIvalue); + CalcPlrInv(myplr, 1u); +} +// 69F108: using guessed type int stextup; +// 69F110: using guessed type int stextlhold; +// 6A8A24: using guessed type int stextvhold; + +//----- (0045BA57) -------------------------------------------------------- +void __cdecl S_ConfirmEnter() +{ + char v0; // cl + + if ( stextsel == 18 ) + { + if ( stextshold > STORE_WRECHARGE ) + { + switch ( stextshold ) + { + case STORE_BBOY: + BoyBuyItem(); + break; + case STORE_HBUY: + HealerBuyItem(); + break; + case STORE_SIDENTIFY: + StoryIdItem(); + v0 = 20; +LABEL_20: + StartStore(v0); + return; + case STORE_SPBUY: + SmithBuyPItem(); + break; + } + } + else + { + switch ( stextshold ) + { + case STORE_WRECHARGE: + WitchRechargeItem(); + break; + case STORE_SBUY: + SmithBuyItem(); + break; + case STORE_SSELL: + goto LABEL_27; + case STORE_SREPAIR: + SmithRepairItem(); + break; + case STORE_WBUY: + WitchBuyItem(); + break; + case STORE_WSELL: +LABEL_27: + StoreSellItem(); + break; + } + } + v0 = stextshold; + goto LABEL_20; + } + StartStore((unsigned char)stextshold); + stextsel = stextlhold; + stextsval = stextvhold; +} +// 69F110: using guessed type int stextlhold; +// 6A8A24: using guessed type int stextvhold; +// 6A8A28: using guessed type int stextsel; + +//----- (0045BAF7) -------------------------------------------------------- +void __cdecl S_HealerEnter() +{ + int v0; // ecx + int v1; // eax + + v0 = 12; + if ( stextsel == 12 ) + { + stextlhold = 12; + talker = 1; + stextshold = 14; + gossipstart = 170; + gossipend = 178; + _LOBYTE(v0) = 19; + goto LABEL_12; + } + if ( stextsel != 14 ) + { + if ( stextsel != 16 ) + { + if ( stextsel == 18 ) + stextflag = 0; + return; + } + _LOBYTE(v0) = 16; +LABEL_12: + StartStore(v0); + return; + } + if ( plr[myplr]._pHitPoints != plr[myplr]._pMaxHP ) + PlaySFX(IS_CAST8); + drawhpflag = 1; + v1 = myplr; + plr[v1]._pHitPoints = plr[myplr]._pMaxHP; + plr[v1]._pHPBase = plr[v1]._pMaxHPBase; +} +// 69F110: using guessed type int stextlhold; +// 69FB38: using guessed type int talker; +// 6A4EF0: using guessed type int gossipstart; +// 6A8A28: using guessed type int stextsel; +// 6A8A30: using guessed type int gossipend; +// 6AA705: using guessed type char stextflag; + +//----- (0045BB9F) -------------------------------------------------------- +void __cdecl S_HBuyEnter() +{ + int v0; // eax + int v1; // ecx + int v2; // eax + int v3; // esi + char v4; // cl + + if ( stextsel == 22 ) + { + StartStore(14); + stextsel = 16; + } + else + { + stextlhold = stextsel; + stextvhold = stextsval; + stextshold = 16; + v0 = myplr; + v1 = stextsval + ((stextsel - stextup) >> 2); + if ( plr[myplr]._pGold >= healitem[v1]._iIvalue ) + { + qmemcpy(&plr[v0].HoldItem, &healitem[v1], sizeof(plr[v0].HoldItem)); + SetCursor(plr[v0].HoldItem._iCurs + 12); + v2 = 0; + v3 = 0; + do + { + if ( v2 ) + goto LABEL_9; + v2 = SpecialAutoPlace(myplr, v3++, cursW / 28, cursH / 28, 0); + } + while ( v3 < 40 ); + if ( v2 ) + { +LABEL_9: + v4 = 11; + goto LABEL_11; + } + v4 = 10; +LABEL_11: + StartStore(v4); + SetCursor(1); + } + else + { + StartStore(9); + } + } +} +// 4B8C9C: using guessed type int cursH; +// 69F108: using guessed type int stextup; +// 69F110: using guessed type int stextlhold; +// 6A8A24: using guessed type int stextvhold; +// 6A8A28: using guessed type int stextsel; + +//----- (0045BC74) -------------------------------------------------------- +void __cdecl S_StoryEnter() +{ + int v0; // ecx + + v0 = 12; + switch ( stextsel ) + { + case 12: + stextlhold = 12; + talker = 4; + stextshold = 15; + gossipstart = 151; + gossipend = 159; + _LOBYTE(v0) = 19; + goto LABEL_8; + case 14: + _LOBYTE(v0) = 17; +LABEL_8: + StartStore(v0); + return; + case 18: + stextflag = 0; + break; + } +} +// 69F110: using guessed type int stextlhold; +// 69FB38: using guessed type int talker; +// 6A4EF0: using guessed type int gossipstart; +// 6A8A28: using guessed type int stextsel; +// 6A8A30: using guessed type int gossipend; +// 6AA705: using guessed type char stextflag; + +//----- (0045BCCA) -------------------------------------------------------- +void __cdecl S_SIDEnter() +{ + int v0; // eax + int v1; // edx + int v2; // ecx + bool v3; // sf + unsigned char v4; // of + char v5; // cl + + if ( stextsel == 22 ) + { + StartStore(15); + stextsel = 14; + } + else + { + stextlhold = stextsel; + stextshold = 17; + v0 = stextsval + ((stextsel - stextup) >> 2); + v1 = myplr; + stextvhold = stextsval; + qmemcpy(&plr[myplr].HoldItem, &storehold[v0], sizeof(plr[myplr].HoldItem)); + v2 = plr[v1]._pGold; + v4 = __OFSUB__(v2, storehold[v0]._iIvalue); + v3 = v2 - storehold[v0]._iIvalue < 0; + v5 = 9; + if ( !(v3 ^ v4) ) + v5 = 11; + StartStore(v5); + } +} +// 69F108: using guessed type int stextup; +// 69F110: using guessed type int stextlhold; +// 6A8A24: using guessed type int stextvhold; +// 6A8A28: using guessed type int stextsel; + +//----- (0045BD4B) -------------------------------------------------------- +void __cdecl S_TalkEnter() +{ + int v0; // edx + int *v1; // edi + signed int v2; // eax + int v3; // esi + int *v4; // ecx + int v5; // esi + signed int v6; // ebp + int v7; // ecx + int v8; // eax + int v9; // ebx + int v10; // ecx + + if ( stextsel == 22 ) + { + StartStore((unsigned char)stextshold); + stextsel = stextlhold; + } + else + { + v0 = talker; + v1 = &quests[0]._qlog; + v2 = 0; + v3 = 0; + v4 = &quests[0]._qlog; + do + { + if ( *((_BYTE *)v4 - 18) == 2 && *((_DWORD *)&Qtalklist[0]._qinfra + v3 + 16 * talker) != -1 && *v4 ) + ++v2; + v4 += 6; + ++v3; + } + while ( (signed int)v4 < (signed int)&qlist[4] ); + if ( v2 <= 6 ) + { + v5 = 15 - v2; + v6 = 2; + } + else + { + v5 = 14 - (v2 >> 1); + v6 = 1; + } + if ( stextsel == v5 - 2 ) + { + SetRndSeed(towner[talker]._tSeed); + _LOBYTE(v7) = 0; + v8 = random(v7, gossipend - gossipstart + 1); + InitQTextMsg(gossipstart + v8); + } + else + { + v9 = 0; + do + { + if ( *((_BYTE *)v1 - 18) == 2 ) + { + v10 = *((_DWORD *)&Qtalklist[0]._qinfra + v9 + 16 * v0); + if ( v10 != -1 ) + { + if ( *v1 ) + { + if ( v5 == stextsel ) + { + InitQTextMsg(v10); + v0 = talker; + } + v5 += v6; + } + } + } + v1 += 6; + ++v9; + } + while ( (signed int)v1 < (signed int)&qlist[4] ); + } + } +} +// 69F110: using guessed type int stextlhold; +// 69FB38: using guessed type int talker; +// 6A4EF0: using guessed type int gossipstart; +// 6A8A28: using guessed type int stextsel; +// 6A8A30: using guessed type int gossipend; + +//----- (0045BE4A) -------------------------------------------------------- +void __cdecl S_TavernEnter() +{ + int v0; // ecx + + v0 = 12; + if ( stextsel == 12 ) + { + stextlhold = 12; + talker = 3; + stextshold = 21; + gossipstart = 161; + gossipend = 168; + _LOBYTE(v0) = 19; + StartStore(v0); + } + else if ( stextsel == 18 ) + { + stextflag = 0; + } +} +// 69F110: using guessed type int stextlhold; +// 69FB38: using guessed type int talker; +// 6A4EF0: using guessed type int gossipstart; +// 6A8A28: using guessed type int stextsel; +// 6A8A30: using guessed type int gossipend; +// 6AA705: using guessed type char stextflag; + +//----- (0045BE98) -------------------------------------------------------- +void __cdecl S_BarmaidEnter() +{ + int v0; // ecx + + v0 = 12; + if ( stextsel == 12 ) + { + stextlhold = 12; + talker = 7; + stextshold = 23; + gossipstart = 180; + gossipend = 187; + _LOBYTE(v0) = 19; + StartStore(v0); + } + else if ( stextsel == 18 ) + { + stextflag = 0; + } +} +// 69F110: using guessed type int stextlhold; +// 69FB38: using guessed type int talker; +// 6A4EF0: using guessed type int gossipstart; +// 6A8A28: using guessed type int stextsel; +// 6A8A30: using guessed type int gossipend; +// 6AA705: using guessed type char stextflag; + +//----- (0045BEE6) -------------------------------------------------------- +void __cdecl S_DrunkEnter() +{ + int v0; // ecx + + v0 = 12; + if ( stextsel == 12 ) + { + stextlhold = 12; + talker = 5; + stextshold = 22; + gossipstart = 201; + gossipend = 211; + _LOBYTE(v0) = 19; + StartStore(v0); + } + else if ( stextsel == 18 ) + { + stextflag = 0; + } +} +// 69F110: using guessed type int stextlhold; +// 69FB38: using guessed type int talker; +// 6A4EF0: using guessed type int gossipstart; +// 6A8A28: using guessed type int stextsel; +// 6A8A30: using guessed type int gossipend; +// 6AA705: using guessed type char stextflag; + +//----- (0045BF34) -------------------------------------------------------- +void __cdecl STextEnter() +{ + int v0; // ecx + + if ( qtextflag ) + { + qtextflag = 0; + if ( !leveltype ) + sfx_stop(); + } + else + { + PlaySFX(IS_TITLSLCT); + switch ( stextflag ) + { + case STORE_SMITH: + S_SmithEnter(); + break; + case STORE_SBUY: + S_SBuyEnter(); + break; + case STORE_SSELL: + S_SSellEnter(); + break; + case STORE_SREPAIR: + S_SRepairEnter(); + break; + case STORE_WITCH: + S_WitchEnter(); + break; + case STORE_WBUY: + S_WBuyEnter(); + break; + case STORE_WSELL: + S_WSellEnter(); + break; + case STORE_WRECHARGE: + S_WRechargeEnter(); + break; + case STORE_NOMONEY: + case STORE_NOROOM: + _LOBYTE(v0) = stextshold; + StartStore(v0); + stextsel = stextlhold; + stextsval = stextvhold; + break; + case STORE_CONFIRM: + S_ConfirmEnter(); + break; + case STORE_BOY: + S_BoyEnter(); + break; + case STORE_BBOY: + S_BBuyEnter(); + break; + case STORE_HEALER: + S_HealerEnter(); + break; + case STORE_STORY: + S_StoryEnter(); + break; + case STORE_HBUY: + S_HBuyEnter(); + break; + case STORE_SIDENTIFY: + S_SIDEnter(); + break; + case STORE_SPBUY: + S_SPBuyEnter(); + break; + case STORE_GOSSIP: + S_TalkEnter(); + break; + case STORE_IDSHOW: + _LOBYTE(v0) = 17; + StartStore(v0); + break; + case STORE_TAVERN: + S_TavernEnter(); + break; + case STORE_DRUNK: + S_DrunkEnter(); + break; + case STORE_BARMAID: + S_BarmaidEnter(); + break; + default: + return; + } + } +} +// 5BB1ED: using guessed type char leveltype; +// 646D00: using guessed type char qtextflag; +// 69F110: using guessed type int stextlhold; +// 6A8A24: using guessed type int stextvhold; +// 6A8A28: using guessed type int stextsel; +// 6AA705: using guessed type char stextflag; + +//----- (0045C053) -------------------------------------------------------- +void __cdecl CheckStoreBtn() +{ + bool v0; // sf + unsigned char v1; // of + int v2; // eax + int *v3; // ecx + + if ( qtextflag ) + { + qtextflag = 0; + if ( !leveltype ) + sfx_stop(); + } + else if ( stextsel != -1 && MouseY >= 32 && MouseY <= 320 ) + { + if ( stextsize ) + { + v1 = __OFSUB__(MouseX, 24); + v0 = MouseX - 24 < 0; + } + else + { + v1 = __OFSUB__(MouseX, 344); + v0 = MouseX - 344 < 0; + } + if ( !(v0 ^ v1) && MouseX <= 616 ) + { + v2 = (MouseY - 32) / 12; + if ( stextscrl && MouseX > 600 ) + { + if ( v2 == 4 ) + { + if ( stextscrlubtn <= 0 ) + { + STextUp(); + stextscrlubtn = 10; + return; + } + --stextscrlubtn; + } + if ( v2 == 20 ) + { + if ( stextscrldbtn > 0 ) + { + --stextscrldbtn; + } + else + { + STextDown(); + stextscrldbtn = 10; + } + } + } + else if ( v2 >= 5 ) + { + if ( v2 >= 23 ) + v2 = 22; + if ( stextscrl ) + { + if ( v2 < 21 ) + { + v3 = &stext[v2]._ssel; + if ( !*v3 ) + { + if ( stext[v2 - 2]._ssel ) + { + v2 -= 2; + } + else if ( *(v3 - 39) ) + { + --v2; + } + } + } + } + if ( stext[v2]._ssel || stextscrl && v2 == 22 ) + { + stextsel = v2; + STextEnter(); + } + } + } + } +} +// 5BB1ED: using guessed type char leveltype; +// 646D00: using guessed type char qtextflag; +// 6A09E0: using guessed type char stextsize; +// 6A6BB8: using guessed type int stextscrl; +// 6A8A28: using guessed type int stextsel; +// 6A8A2C: using guessed type char stextscrldbtn; +// 6AA704: using guessed type char stextscrlubtn; + +//----- (0045C18A) -------------------------------------------------------- +void __cdecl ReleaseStoreBtn() +{ + stextscrlubtn = -1; + stextscrldbtn = -1; +} +// 6A8A2C: using guessed type char stextscrldbtn; +// 6AA704: using guessed type char stextscrlubtn; + +//----- (0045C199) -------------------------------------------------------- +int __fastcall sync_all_monsters(TSyncHeader *packet, int size) +{ + int result; // eax + TSyncHeader *v3; // esi + int v4; // ebx + TSyncMonster *v5; // edi + unsigned int v6; // [esp+4h] [ebp-4h] + + result = size; + if ( nummonsters >= 1 && (unsigned int)size >= 0x2B ) + { + v3 = packet; + v6 = size - 38; + v4 = 0; + packet->bCmd = CMD_SYNCDATA; + v5 = (TSyncMonster *)(&packet->wPInvCI + 1); + packet->bLevel = currlevel; + packet->wLen = 0; + SyncPlrInv(packet); + sync_one_monster(); + if ( nummonsters > 0 ) + { + do + { + if ( v6 < 5 || (v4 >= 2 || !sync_monster_active2(v5)) && !sync_monster_active(v5) ) + break; + v3->wLen += 5; + v6 -= 5; + ++v5; + ++v4; + } + while ( v4 < nummonsters ); + } + result = v6; + } + return result; +} + +//----- (0045C21E) -------------------------------------------------------- +void __cdecl sync_one_monster() +{ + int i; // ebx + int v1; // edi + int v2; // esi + short v3; // bp + short v4; // ax + bool v5; // zf + short *v6; // edx + short *v7; // eax + + for ( i = 0; i < nummonsters; ++i ) + { + v1 = monstactive[i]; + v2 = monstactive[i]; + v3 = abs(plr[myplr].WorldY - monster[v2]._my); + v4 = abs(plr[myplr].WorldX - monster[v2]._mx); + v5 = _LOBYTE(monster[v2]._msquelch) == 0; + v6 = &sync_word_6AA708[v1]; + *v6 = v4 + v3; + if ( v5 ) + { + *v6 = v4 + v3 + 4096; + } + else + { + v7 = &sync_word_6AA89C[v1]; + if ( *v7 ) + --*v7; + } + } +} + +//----- (0045C2C4) -------------------------------------------------------- +int __fastcall sync_monster_active(TSyncMonster *packet) +{ + unsigned int v1; // ebx + int v2; // esi + int v3; // edx + int v4; // eax + + v1 = -1; + v2 = 0; + v3 = -1; + if ( nummonsters <= 0 ) + return 0; + do + { + v4 = monstactive[v2]; + if ( (unsigned short)sync_word_6AA708[v4] < v1 && (unsigned short)sync_word_6AA89C[v4] < 0xFFFEu ) + { + v1 = (unsigned short)sync_word_6AA708[v4]; + v3 = monstactive[v2]; + } + ++v2; + } + while ( v2 < nummonsters ); + if ( v3 == -1 ) + return 0; + sync_monster_pos(packet, v3); + return 1; +} + +//----- (0045C317) -------------------------------------------------------- +int __fastcall sync_monster_pos(TSyncMonster *packet, int mon_id) +{ + int v2; // ebx + TSyncMonster *v3; // esi + int v4; // edi + int result; // eax + short v6; // cx + char v7; // cl + int v8; // [esp+0h] [ebp-Ch] + + v2 = mon_id; + v3 = packet; + v4 = mon_id; + packet->_mndx = mon_id; + packet->_mx = monster[mon_id]._mx; + packet->_my = monster[mon_id]._my; + packet->_menemy = encode_enemy(v8); + result = v2; + v6 = sync_word_6AA708[v2]; + if ( (unsigned short)v6 > 0xFFu ) + _LOBYTE(v6) = -1; + v3->_mdelta = v6; + v7 = monster[v4]._msquelch; + sync_word_6AA708[result] = -1; + sync_word_6AA89C[result] = -(v7 != 0) - 1; + return result * 2; +} + +//----- (0045C386) -------------------------------------------------------- +int __fastcall sync_monster_active2(TSyncMonster *packet) +{ + int v1; // edx + unsigned int v2; // ebp + int v3; // eax + int v4; // esi + int v6; // [esp+8h] [ebp-4h] + + v1 = -1; + v2 = 65534; + if ( nummonsters <= 0 ) + return 0; + v3 = dword_6AA898; + v6 = nummonsters; + do + { + if ( v3 >= nummonsters ) + v3 = 0; + v4 = monstactive[v3]; + if ( (unsigned short)sync_word_6AA89C[v4] < v2 ) + { + v2 = (unsigned short)sync_word_6AA89C[v4]; + v1 = monstactive[v3]; + } + ++v3; + --v6; + } + while ( v6 ); + dword_6AA898 = v3; + if ( v1 == -1 ) + return 0; + sync_monster_pos(packet, v1); + return 1; +} +// 6AA898: using guessed type int dword_6AA898; + +//----- (0045C3E6) -------------------------------------------------------- +char __fastcall SyncPlrInv(TSyncHeader *pItem) +{ + int v1; // edx + int v2; // eax + int v3; // eax + short v4; // dx + short v5; // bx + ItemStruct *v6; // eax + + if ( numitems <= 0 ) + { + pItem->bItemI = -1; + } + else + { + v1 = dword_6AAA2C[0]; + if ( dword_6AAA2C[0] >= numitems ) + v1 = 0; + v2 = itemactive[v1]; + dword_6AAA2C[0] = v1 + 1; + pItem->bItemI = v2; + v3 = v2; + pItem->bItemX = items[v3]._ix; + pItem->bItemY = items[v3]._iy; + *(_WORD *)(&pItem->bItemY + 1) = items[v3].IDidx; + if ( items[v3].IDidx == IDI_EAR ) + { + _LOBYTE(v4) = 0; + _HIBYTE(v4) = items[v3]._iName[7]; + _LOBYTE(v5) = 0; + *(unsigned short *)((char *)&pItem->wItemIndx + 1) = items[v3]._iName[8] | v4; + *(_DWORD *)((char *)&pItem->wItemCI + 1) = items[v3]._iName[12] | ((items[v3]._iName[11] | ((items[v3]._iName[10] | (items[v3]._iName[9] << 8)) << 8)) << 8); + BYTE1(pItem->dwItemSeed) = items[v3]._iName[13]; + BYTE2(pItem->dwItemSeed) = items[v3]._iName[14]; + _HIBYTE(pItem->dwItemSeed) = items[v3]._iName[15]; + pItem->bItemId = items[v3]._iName[16]; + pItem->bItemDur = items[v3]._iName[17]; + _HIBYTE(v5) = items[v3]._iName[18]; + *(_WORD *)&pItem->bItemMDur = _LOWORD(items[v3]._ivalue) | v5 | ((_LOWORD(items[v3]._iCurs) - 19) << 6); + *(_DWORD *)&pItem->bItemMCh = items[v3]._iName[22] | ((items[v3]._iName[21] | ((items[v3]._iName[20] | (items[v3]._iName[19] << 8)) << 8)) << 8); + } + else + { + *(unsigned short *)((char *)&pItem->wItemIndx + 1) = items[v3]._iCreateInfo; + *(_DWORD *)((char *)&pItem->wItemCI + 1) = items[v3]._iSeed; + BYTE1(pItem->dwItemSeed) = items[v3]._iIdentified; + BYTE2(pItem->dwItemSeed) = items[v3]._iDurability; + _HIBYTE(pItem->dwItemSeed) = items[v3]._iMaxDur; + pItem->bItemId = items[v3]._iCharges; + pItem->bItemDur = items[v3]._iMaxCharges; + if ( !items[v3].IDidx ) + *(_WORD *)&pItem->bItemMDur = items[v3]._ivalue; + } + } + v6 = &plr[myplr].InvBody[sgnSyncPInv]; + if ( v6->_itype == -1 ) + { + _LOBYTE(pItem->dwItemBuff) = -1; + } + else + { + _LOBYTE(pItem->dwItemBuff) = sgnSyncPInv; + *(_WORD *)((char *)&pItem->dwItemBuff + 1) = v6->IDidx; + *(_WORD *)((char *)&pItem->dwItemBuff + 3) = v6->_iCreateInfo; + *(_DWORD *)(&pItem->bPInvLoc + 1) = v6->_iSeed; + _LOBYTE(v6) = v6->_iIdentified; + _HIBYTE(pItem->wPInvCI) = (_BYTE)v6; + } + if ( ++sgnSyncPInv >= 7 ) + sgnSyncPInv = 0; + return (char)v6; +} +// 6AAA34: using guessed type int sgnSyncPInv; + +//----- (0045C5C7) -------------------------------------------------------- +int __fastcall SyncData(int pnum, TSyncHeader *packet) +{ + TSyncHeader *v2; // esi + TSyncMonster *v3; // edi + int v4; // ebp + unsigned short v5; // ax + unsigned int v6; // ebx + + v2 = packet; + v3 = (TSyncMonster *)(&packet->wPInvCI + 1); + v4 = pnum; + if ( packet->bCmd != CMD_SYNCDATA ) + TermMsg("bad sync command"); + if ( gbBufferMsgs != 1 && v4 != myplr ) + { + v5 = v2->wLen; + if ( v5 >= 5u ) + { + v6 = v5 / 5u; + do + { + if ( currlevel == v2->bLevel ) + sync_monster_data(v4, v3); + delta_sync_monster((TCmdLocParam1 *)v3, v2->bLevel); + ++v3; + --v6; + } + while ( v6 ); + } + } + return v2->wLen + 38; +} +// 676194: using guessed type char gbBufferMsgs; + +//----- (0045C63B) -------------------------------------------------------- +void __fastcall sync_monster_data(int pnum, TSyncMonster *packet) +{ + TSyncMonster *v2; // edi + int v3; // ecx + int v4; // ebx + int v5; // esi + int v6; // ST18_4 + unsigned int v7; // ecx + unsigned int v8; // eax + int v9; // eax + int v10; // ecx + signed int v11; // ST14_4 + int v12; // eax + int v13; // eax + int v14; // eax + int v15; // eax + int v16; // eax + int md; // [esp+Ch] [ebp-8h] + int mda; // [esp+Ch] [ebp-8h] + + v2 = packet; + md = pnum; + v3 = 0; + v4 = (unsigned char)packet->_mndx; + v5 = v4; + if ( monster[v5]._mhitpoints ) + { + if ( nummonsters > 0 ) + { + do + { + if ( monstactive[v3] == v4 ) + break; + ++v3; + } + while ( v3 < nummonsters ); + } + v6 = abs(plr[myplr].WorldY - monster[v5]._my); + v7 = abs(plr[myplr].WorldX - monster[v5]._mx) + v6; + if ( v7 > 0xFF ) + v7 = 255; + v8 = (unsigned char)v2->_mdelta; + if ( v7 >= v8 && (v7 != v8 || md <= myplr) ) + { + v9 = (unsigned char)v2->_mx; + if ( monster[v5]._mfutx != v9 || monster[v5]._mfuty != (unsigned char)v2->_my ) + { + v10 = monster[v5]._mmode; + if ( v10 != MM_CHARGE && v10 != MM_STONE ) + { + v11 = abs(monster[v5]._mx - v9); + v12 = abs(monster[v5]._my - (unsigned char)v2->_my); + if ( v11 > 2 || v12 > 2 ) + { + if ( dMonster[0][(unsigned char)v2->_my + 112 * (unsigned char)v2->_mx] ) + { +LABEL_23: + decode_enemy(v4, (unsigned char)v2->_menemy); + return; + } + M_ClearSquares(v4); + dMonster[0][(unsigned char)v2->_my + 112 * (unsigned char)v2->_mx] = v4 + 1; + monster[v5]._mx = (unsigned char)v2->_mx; + monster[v5]._my = (unsigned char)v2->_my; + decode_enemy(v4, (unsigned char)v2->_menemy); + v16 = GetDirection( + (unsigned char)v2->_mx, + (unsigned char)v2->_my, + (unsigned char)monster[v5]._menemyx, + (unsigned char)monster[v5]._menemyy); + M_StartStand(v4, v16); + } + else + { + v13 = monster[v5]._mmode; + if ( v13 >= MM_WALK && v13 <= MM_WALK3 ) + goto LABEL_23; + v14 = GetDirection( + monster[v5]._mx, + monster[v5]._my, + (unsigned char)v2->_mx, + (unsigned char)v2->_my); + mda = v14; + _LOBYTE(v15) = DirOK(v4, v14); + if ( !v15 ) + goto LABEL_23; + M_ClearSquares(v4); + dMonster[0][monster[v5]._my + 112 * monster[v5]._mx] = v4 + 1; + M_WalkDir(v4, mda); + } + _LOBYTE(monster[v5]._msquelch) = -1; + goto LABEL_23; + } + } + } + } +} + +//----- (0045C84B) -------------------------------------------------------- +void __cdecl sync_clear_pkt() +{ + dword_6AA898 = 16 * myplr; + memset(sync_word_6AA89C, 255, 0x190u); +} +// 6AA898: using guessed type int dword_6AA898; + +//----- (0045C870) -------------------------------------------------------- +unsigned char __fastcall TFit_Shrine(int i) +{ + int v1; // ecx + int v2; // esi + int v3; // eax + int v4; // edx + signed int v6; // [esp+Ch] [ebp-8h] + int v7; // [esp+10h] [ebp-4h] + + v1 = themes[i].ttval; + v7 = 0; + v2 = 0; + v6 = 0; + while ( 1 ) + { + v3 = v2 + 112 * v7; + if ( dung_map[0][v3] != v1 ) + goto LABEL_20; + v4 = *(_DWORD *)&dflags[39][4 * v3 + 36]; + if ( nTrapTable[v4] + && !nSolidTable[*(_DWORD *)&dflags[28][4 * v3 + 32]] + && !nSolidTable[dPiece[1][v3]] + && block_lvid[v3 + 1940] == v1 + && dung_map[1][v3] == v1 + && !dungeon[37][v3 + 7] + && !dObject[0][v3 + 111] ) + { + v6 = 1; + } + if ( v6 ) + break; + if ( !nTrapTable[*(_DWORD *)&dflags[28][4 * v3 + 32]] + || nSolidTable[v4] + || nSolidTable[dPiece[0][v3 + 1]] + || *(&byte_5B78EB + v3) != v1 + || dung_map[0][v3 + 1] != v1 + || dungeon[37][v3 + 7] + || dungeon[37][v3 + 9] ) + { + goto LABEL_21; + } + v6 = 2; +LABEL_20: + if ( v6 ) + break; +LABEL_21: + if ( ++v7 == 112 ) + { + ++v2; + v7 = 0; + if ( v2 == 112 ) + return 0; + } + } + themey = v2; + themex = v7; + themeVar1 = v6; + return 1; +} + +//----- (0045C993) -------------------------------------------------------- +bool __fastcall TFit_Obj5(int theme_num) +{ + int v1; // edi + int v2; // ebx + int v3; // esi + int v4; // eax + int v5; // edi + int v6; // ecx + signed int v7; // edx + int v8; // ecx + int v10; // [esp+Ch] [ebp-Ch] + int v11; // [esp+10h] [ebp-8h] + signed int v12; // [esp+14h] [ebp-4h] + + v1 = theme_num; + _LOBYTE(theme_num) = 0; + v2 = 0; + v3 = 0; + v4 = random(theme_num, 5) + 1; + v10 = v4; + if ( v4 <= 0 ) + { +LABEL_19: + themex = v2; + themey = v3; + return 1; + } + v5 = themes[v1].ttval; + v11 = v5; + while ( 1 ) + { + v6 = v3 + 112 * v2; + if ( dung_map[0][v6] == v5 && !nSolidTable[dPiece[0][v6]] ) + { + v12 = 1; + v7 = 0; + do + { + if ( v7 >= 25 ) + break; + v8 = v3 + trm5y[v7] + 112 * (v2 + trm5x[v7]); + if ( nSolidTable[dPiece[0][v8]] ) + v12 = 0; + v5 = v11; + if ( dung_map[0][v8] != v11 ) + v12 = 0; + ++v7; + } + while ( v12 ); + if ( v12 ) + { + --v4; + goto LABEL_18; + } + } + if ( ++v2 != 112 ) + goto LABEL_18; + v2 = 0; + if ( ++v3 != 112 ) + goto LABEL_18; + if ( v4 == v10 ) + return 0; + v3 = 0; +LABEL_18: + if ( v4 <= 0 ) + goto LABEL_19; + } +} + +//----- (0045CA72) -------------------------------------------------------- +unsigned char __fastcall TFit_SkelRoom(int i) +{ + int v1; // ebx + int v2; // esi + CMonster *v3; // edi + + v1 = i; + if ( leveltype != 1 && leveltype != 2 ) + return 0; + v2 = 0; + if ( nummtypes <= 0 ) + return 0; + v3 = Monsters; + while ( !IsSkel((unsigned char)v3->mtype) ) + { + ++v2; + ++v3; + if ( v2 >= nummtypes ) + return 0; + } + themeVar1 = v2; + return TFit_Obj5(v1); +} +// 5BB1ED: using guessed type char leveltype; + +//----- (0045CAC4) -------------------------------------------------------- +unsigned char __fastcall TFit_GoatShrine(int i) +{ + int v1; // esi + int v2; // ebx + CMonster *v3; // edi + + v1 = 0; + v2 = i; + if ( nummtypes <= 0 ) + return 0; + v3 = Monsters; + while ( !IsGoat((unsigned char)v3->mtype) ) + { + ++v1; + ++v3; + if ( v1 >= nummtypes ) + return 0; + } + themeVar1 = v1; + return TFit_Obj5(v2); +} + +//----- (0045CB09) -------------------------------------------------------- +unsigned char __fastcall CheckThemeObj3(int xp, int yp, int t, int f) +{ + int v4; // esi + int v5; // ebx + signed int v6; // edi + int v7; // eax + int v8; // ecx + int v9; // eax + int v10; // ecx + + v4 = yp; + v5 = xp; + v6 = 0; + while ( 1 ) + { + v7 = v5 + trm3x[v6]; + if ( v7 < 0 ) + break; + v8 = trm3y[v6]; + if ( v8 + v4 < 0 ) + break; + v9 = v4 + v8 + 112 * v7; + if ( nSolidTable[dPiece[0][v9]] ) + break; + v10 = dung_map[0][v9]; + if ( v10 != themes[t].ttval ) + break; + if ( dObject[0][v9] ) + break; + if ( f != -1 ) + { + _LOBYTE(v10) = 0; + if ( !random(v10, f) ) + break; + } + ++v6; + if ( v6 >= 9 ) + return 1; + } + return 0; +} + +//----- (0045CB88) -------------------------------------------------------- +bool __fastcall TFit_Obj3(int theme_num) +{ + int v1; // ebx + int v2; // edi + int v3; // esi + BOOL v4; // eax + char v6; // [esp+Bh] [ebp-5h] + char v7; // [esp+Ch] [ebp-4h] + char v8; // [esp+Dh] [ebp-3h] + char v9; // [esp+Eh] [ebp-2h] + char v10; // [esp+Fh] [ebp-1h] + + v1 = theme_num; + v7 = 4; + v8 = 4; + v9 = 3; + v10 = 5; + v2 = 1; + while ( 2 ) + { + v3 = 1; + do + { + _LOBYTE(v4) = CheckThemeObj3(v3, v2, v1, *(&v6 + (unsigned char)leveltype)); + if ( v4 ) + { + themex = v3; + themey = v2; + _LOBYTE(v4) = 1; + return v4; + } + ++v3; + } + while ( v3 < 111 ); + if ( ++v2 < 111 ) + continue; + break; + } + return v4; +} +// 5BB1ED: using guessed type char leveltype; + +//----- (0045CBE4) -------------------------------------------------------- +unsigned char __fastcall CheckThemeReqs(int t) +{ + unsigned char result; // al + int v2; // ecx + int v3; // ecx + int v4; // ecx + int v5; // ecx + bool v6; // zf + int v7; // ecx + int v8; // ecx + int v9; // ecx + + result = 1; + if ( t <= 10 ) + { + if ( t != 10 ) + { + v2 = t - 1; + if ( v2 ) + { + v3 = v2 - 2; + if ( v3 ) + { + v4 = v3 - 2; + if ( v4 ) + { + v5 = v4 - 2; + if ( v5 ) + { + if ( v5 != 2 ) + return result; + v6 = pFountainFlag == 0; + } + else + { + v6 = bFountainFlag == 0; + } +LABEL_21: + if ( !v6 ) + return result; + return 0; + } + } + } + if ( leveltype != 3 ) + { + v6 = leveltype == 4; + goto LABEL_21; + } + return 0; + } +LABEL_16: + v6 = leveltype == 1; + goto LABEL_21; + } + v7 = t - 12; + if ( v7 ) + { + v8 = v7 - 1; + if ( !v8 ) + { + v6 = mFountainFlag == 0; + goto LABEL_21; + } + v9 = v8 - 1; + if ( !v9 ) + { + v6 = tFountainFlag == 0; + goto LABEL_21; + } + if ( v9 != 2 ) + return result; + goto LABEL_16; + } + if ( leveltype == 4 ) + { + v6 = cauldronFlag == 0; + goto LABEL_21; + } + return 0; +} +// 5BB1ED: using guessed type char leveltype; +// 6AAA58: using guessed type int mFountainFlag; +// 6AAA5C: using guessed type int cauldronFlag; +// 6AAA60: using guessed type int tFountainFlag; +// 6AAC08: using guessed type int pFountainFlag; +// 6AAC0C: using guessed type int bFountainFlag; + +//----- (0045CC64) -------------------------------------------------------- +unsigned char __fastcall SpecialThemeFit(int i, int t) +{ + int v2; // edi + int v3; // esi + int v4; // eax + + v2 = t; + v3 = i; + _LOBYTE(v4) = CheckThemeReqs(t); + switch ( v2 ) + { + case THEME_SHRINE: + case THEME_LIBRARY: + if ( v4 ) + _LOBYTE(v4) = TFit_Shrine(v3); + break; + case THEME_SKELROOM: + if ( v4 ) + _LOBYTE(v4) = TFit_SkelRoom(v3); + break; + case THEME_TREASURE: + _LOBYTE(v4) = treasureFlag; + if ( treasureFlag ) + treasureFlag = 0; + break; + case THEME_TORTURE: + case THEME_DECAPITATED: + case THEME_ARMORSTAND: + case THEME_BRNCROSS: + case THEME_WEAPONRACK: + if ( v4 ) + _LOBYTE(v4) = TFit_Obj3(v3); + break; + case THEME_BLOODFOUNTAIN: + if ( v4 ) + { + _LOBYTE(v4) = TFit_Obj5(v3); + if ( v4 ) + bFountainFlag = 0; + } + break; + case THEME_PURIFYINGFOUNTAIN: + if ( v4 ) + { + _LOBYTE(v4) = TFit_Obj5(v3); + if ( v4 ) + pFountainFlag = 0; + } + break; + case THEME_GOATSHRINE: + if ( v4 ) + _LOBYTE(v4) = TFit_GoatShrine(v3); + break; + case THEME_CAULDRON: + if ( v4 ) + { + _LOBYTE(v4) = TFit_Obj5(v3); + if ( v4 ) + cauldronFlag = 0; + } + break; + case THEME_MURKYFOUNTAIN: + if ( v4 ) + { + _LOBYTE(v4) = TFit_Obj5(v3); + if ( v4 ) + mFountainFlag = 0; + } + break; + case THEME_TEARFOUNTAIN: + if ( v4 ) + { + _LOBYTE(v4) = TFit_Obj5(v3); + if ( v4 ) + tFountainFlag = 0; + } + break; + default: + return v4; + } + return v4; +} +// 6AAA54: using guessed type int treasureFlag; +// 6AAA58: using guessed type int mFountainFlag; +// 6AAA5C: using guessed type int cauldronFlag; +// 6AAA60: using guessed type int tFountainFlag; +// 6AAC08: using guessed type int pFountainFlag; +// 6AAC0C: using guessed type int bFountainFlag; + +//----- (0045CD9A) -------------------------------------------------------- +unsigned char __fastcall CheckThemeRoom(int tv) +{ + int v1; // esi + int *v2; // edx + signed int v3; // edi + signed int v4; // esi + signed int v5; // edx + signed int v6; // eax + int v7; // edi + int *v8; // esi + char *v9; // eax + int *v10; // edx + signed int v12; // [esp+Ch] [ebp-8h] + + v1 = 0; + if ( trigflag[4] <= 0 ) + { +LABEL_5: + v3 = 0; + v4 = 0; + do + { + v5 = 0; + v6 = v4; + do + { + if ( dung_map[0][v6] == tv ) + { + if ( dFlags[0][v6] & 8 ) + return 0; + ++v3; + } + ++v5; + v6 += 112; + } + while ( v5 < 112 ); + ++v4; + } + while ( v4 < 112 ); + if ( leveltype != 1 || v3 >= 9 && v3 <= 100 ) + { + v7 = 0; + v8 = &dPiece[-1][111]; +LABEL_16: + v12 = 0; + v9 = &dung_map[-1][v7 + 111]; + v10 = v8; + while ( v9[1] != tv + || nSolidTable[v10[1]] + || (*(v9 - 111) == tv || nSolidTable[*(v10 - 111)]) + && (v9[113] == tv || nSolidTable[v10[113]]) + && (*v9 == tv || nSolidTable[*v10]) + && (v9[2] == tv || nSolidTable[v10[2]]) ) + { + ++v12; + v10 += 112; + v9 += 112; + if ( v12 >= 112 ) + { + ++v8; + ++v7; + if ( (signed int)v8 < (signed int)&dPiece[0][111] ) + goto LABEL_16; + return 1; + } + } + } + } + else + { + v2 = &trigs[0]._ty; + while ( dung_map[*(v2 - 1)][*v2] != tv ) + { + ++v1; + v2 += 4; + if ( v1 >= trigflag[4] ) + goto LABEL_5; + } + } + return 0; +} +// 5BB1ED: using guessed type char leveltype; + +//----- (0045CED2) -------------------------------------------------------- +void __cdecl InitThemes() +{ + int v0; // esi + char v1; // bl + int v2; // edi + int v3; // eax + int v4; // ecx + int i; // ebx + int v6; // eax + int v7; // ecx + int v8; // esi + int v9; // ecx + int j; // eax + int v11; // eax + int v12; // ecx + int *v13; // edi + int v14; // esi + int *v15; // ebx + int v16; // eax + int v17; // eax + int k; // esi + int l; // ebx + int v20; // eax + + zharlib = -1; + v0 = 0; + bCrossFlag = 0; + numthemes = 0; + armorFlag = 1; + bFountainFlag = 1; + cauldronFlag = 1; + mFountainFlag = 1; + pFountainFlag = 1; + tFountainFlag = 1; + treasureFlag = 1; + weaponFlag = 1; + if ( currlevel != 16 ) + { + v1 = leveltype; + if ( leveltype == 1 ) + { + ThemeGoodIn[0] = 0; + ThemeGoodIn[1] = 0; + ThemeGoodIn[2] = 0; + ThemeGoodIn[3] = 0; + v2 = 0; + do + { + if ( v0 >= 50 ) + break; + _LOBYTE(v3) = CheckThemeRoom(v2); + if ( v3 ) + { + _LOBYTE(v4) = 0; + themes[v0].ttval = v2; + for ( i = ThemeGood[random(v4, 4)]; ; i = random(v7, 17) ) + { + _LOBYTE(v6) = SpecialThemeFit(numthemes, i); + if ( v6 ) + break; + _LOBYTE(v7) = 0; + } + v8 = numthemes; + _LOBYTE(themes[numthemes].ttype) = i; + v1 = leveltype; + v0 = v8 + 1; + numthemes = v0; + } + ++v2; + } + while ( v2 < 256 ); + } + if ( v1 == 2 || v1 == 3 || v1 == 4 ) + { + v9 = themeCount; + for ( j = 0; j < v9; ++j ) + _LOBYTE(themes[j].ttype) = -1; + _LOBYTE(v11) = QuestStatus(3); + v13 = &themeLoc[0].ttval; + if ( v11 ) + { + v14 = 0; + if ( themeCount > 0 ) + { + v15 = &themeLoc[0].ttval; + while ( 1 ) + { + themes[v14].ttval = *v15; + _LOBYTE(v16) = SpecialThemeFit(v14, 5); + if ( v16 ) + break; + ++v14; + v15 += 5; + if ( v14 >= themeCount ) + goto LABEL_23; + } + _LOBYTE(themes[v14].ttype) = 5; + zharlib = v14; + } + } +LABEL_23: + v17 = themeCount; + for ( k = 0; k < themeCount; v13 += 5 ) + { + if ( _LOBYTE(themes[k].ttype) == -1 ) + { + _LOBYTE(v12) = 0; + themes[k].ttval = *v13; + for ( l = ThemeGood[random(v12, 4)]; ; l = random(v12, 17) ) + { + _LOBYTE(v20) = SpecialThemeFit(k, l); + if ( v20 ) + break; + _LOBYTE(v12) = 0; + } + _LOBYTE(themes[k].ttype) = l; + } + v17 = themeCount; + ++k; + } + numthemes += v17; + } + } +} +// 5BB1ED: using guessed type char leveltype; +// 6AAA3C: using guessed type int armorFlag; +// 6AAA50: using guessed type int weaponFlag; +// 6AAA54: using guessed type int treasureFlag; +// 6AAA58: using guessed type int mFountainFlag; +// 6AAA5C: using guessed type int cauldronFlag; +// 6AAA60: using guessed type int tFountainFlag; +// 6AAA64: using guessed type int zharlib; +// 6AAC08: using guessed type int pFountainFlag; +// 6AAC0C: using guessed type int bFountainFlag; +// 6AAC10: using guessed type int bCrossFlag; + +//----- (0045D087) -------------------------------------------------------- +void __cdecl HoldThemeRooms() +{ + int v0; // ebx + int i; // esi + char v2; // dl + signed int v3; // ecx + signed int v4; // eax + signed int v5; // edi + + if ( currlevel != 16 ) + { + if ( leveltype == 1 ) + { + v0 = numthemes; + for ( i = 0; i < v0; ++i ) + { + v2 = themes[i].ttval; + v3 = 0; + do + { + v4 = v3; + v5 = 112; + do + { + if ( dung_map[0][v4] == v2 ) + dFlags[0][v4] |= 8u; + v4 += 112; + --v5; + } + while ( v5 ); + ++v3; + } + while ( v3 < 112 ); + } + } + else + { + DRLG_HoldThemeRooms(); + } + } +} +// 5BB1ED: using guessed type char leveltype; + +//----- (0045D0E1) -------------------------------------------------------- +void __fastcall PlaceThemeMonsts(int t, int f) +{ + int v2; // eax + int v3; // esi + int v4; // edx + int v5; // ecx + char *v6; // edi + int v7; // ebx + int v8; // edi + int v9; // esi + int v10; // ecx + int v11; // ecx + int v12; // ST04_4 + int v13; // eax + int v14[111]; // [esp+Ch] [ebp-1D0h] + int max; // [esp+1C8h] [ebp-14h] + int mtype; // [esp+1CCh] [ebp-10h] + int *v17; // [esp+1D0h] [ebp-Ch] + int (*v18)[112]; // [esp+1D4h] [ebp-8h] + int (*v19)[112]; // [esp+1D8h] [ebp-4h] + + v2 = nummtypes; + max = f; + v3 = t; + v4 = 0; + v5 = 0; + if ( nummtypes > 0 ) + { + v6 = &Monsters[0].mPlaceFlags; + do + { + if ( *v6 & 1 ) + v14[v4++] = v5; + ++v5; + v6 += 328; + } + while ( v5 < v2 ); + } + _LOBYTE(v5) = 0; + v7 = 0; + mtype = v14[random(v5, v4)]; + v17 = &themes[v3].ttval; + v19 = dPiece; + do + { + v8 = 0; + v18 = v19; + v9 = v7; + do + { + v10 = (int)v17; + if ( dung_map[0][v9] == *v17 && !nSolidTable[(*v18)[0]] && !dItem[0][v9] && !dObject[0][v9] ) + { + _LOBYTE(v10) = 0; + if ( !random(v10, max) ) + { + _LOBYTE(v11) = 0; + v12 = mtype; + v13 = random(v11, 8); + AddMonster(v8, v7, v13, v12, 1); + } + } + ++v18; + ++v8; + v9 += 112; + } + while ( v8 < 112 ); + v19 = (int (*)[112])((char *)v19 + 4); + ++v7; + } + while ( (signed int)v19 < (signed int)dPiece[1] ); +} +// 45D0E1: using guessed type int var_1D0[111]; + +//----- (0045D1C2) -------------------------------------------------------- +void __fastcall Theme_Barrel(int theme_num) +{ + int v1; // edi + int v2; // ebx + char *v3; // esi + int v4; // ecx + int v5; // ecx + int v6; // eax + char t[20]; // [esp+Ch] [ebp-14h] + + *(_DWORD *)t = theme_num; + t[16] = 2; + t[17] = 6; + t[18] = 4; + t[19] = 8; + t[8] = 5; + t[9] = 7; + t[10] = 3; + t[11] = 9; + v1 = 0; + *(_DWORD *)&t[12] = (unsigned int)dPiece; + do + { + v2 = 0; + v3 = (char *)dung_map + v1; + *(_DWORD *)&t[4] = *(_DWORD *)&t[12]; + do + { + v4 = *(_DWORD *)t; + if ( *v3 == themes[*(_DWORD *)t].ttval && !nSolidTable[**(_DWORD **)&t[4]] ) + { + _LOBYTE(v4) = 0; + if ( !random(v4, t[(unsigned char)leveltype + 15]) ) + { + _LOBYTE(v5) = 0; + v6 = random(v5, t[(unsigned char)leveltype + 15]); + AddObject((v6 != 0) + 57, v2, v1); + } + } + *(_DWORD *)&t[4] += 448; + ++v2; + v3 += 112; + } + while ( v2 < 112 ); + *(_DWORD *)&t[12] += 4; + ++v1; + } + while ( *(_DWORD *)&t[12] < (signed int)dPiece[1] ); + PlaceThemeMonsts(*(int *)t, t[(unsigned char)leveltype + 7]); +} +// 5BB1ED: using guessed type char leveltype; + +//----- (0045D29A) -------------------------------------------------------- +void __fastcall Theme_Shrine(int theme_num) +{ + int v1; // esi + char v2[5]; // [esp+3h] [ebp-5h] + + v1 = theme_num; + v2[1] = 6; + v2[2] = 6; + v2[3] = 3; + v2[4] = 9; + TFit_Shrine(theme_num); + if ( themeVar1 == 1 ) + { + AddObject(9, themex - 1, themey); + AddObject(60, themex, themey); + AddObject(9, themex + 1, themey); + } + else + { + AddObject(9, themex, themey - 1); + AddObject(59, themex, themey); + AddObject(9, themex, themey + 1); + } + PlaceThemeMonsts(v1, v2[(unsigned char)leveltype]); +} +// 5BB1ED: using guessed type char leveltype; + +//----- (0045D34D) -------------------------------------------------------- +void __fastcall Theme_MonstPit(int theme_num) +{ + int v1; // esi + int v2; // eax + int v3; // ecx + int v4; // edx + int v5; // edi + int v6; // esi + char t[8]; // [esp+4h] [ebp-8h] + + v1 = theme_num; + _LOBYTE(theme_num) = 0; + *(_DWORD *)t = v1; + t[4] = 6; + t[5] = 7; + t[6] = 3; + t[7] = 9; + v2 = random(theme_num, 100) + 1; + v3 = 0; + v4 = 0; + if ( v2 > 0 ) + { + v5 = themes[v1].ttval; + while ( 1 ) + { + v6 = v4 + 112 * v3; + if ( dung_map[0][v6] == v5 && !nSolidTable[dPiece[0][v6]] ) + --v2; + if ( v2 <= 0 ) + break; + if ( ++v3 == 112 ) + { + v3 = 0; + if ( ++v4 == 112 ) + v4 = 0; + } + } + } + CreateRndItem(v3, v4, 1u, 0, 1); + ItemNoFlippy(); + PlaceThemeMonsts(*(int *)t, t[(unsigned char)leveltype + 3]); +} +// 5BB1ED: using guessed type char leveltype; + +//----- (0045D3E6) -------------------------------------------------------- +void __fastcall Theme_SkelRoom(int theme_num) +{ + int v1; // esi + int v2; // edi + int v3; // ecx + int v4; // eax + int v5; // ebx + int v6; // eax + int v7; // ecx + int v8; // eax + int v9; // ecx + int v10; // eax + int v11; // ecx + int v12; // eax + int v13; // ecx + int v14; // eax + int v15; // ebx + int v16; // eax + int v17; // ecx + int v18; // eax + int v19; // ebx + char v20[5]; // [esp+Bh] [ebp-5h] + + v20[1] = 6; + v20[2] = 7; + v20[3] = 3; + v20[4] = 9; + TFit_SkelRoom(theme_num); + v1 = themey; + v2 = themex; + AddObject(3, themex, themey); + _LOBYTE(v3) = 0; + if ( random(v3, v20[(unsigned char)leveltype]) ) + { + v4 = PreSpawnSkeleton(); + v5 = v1 - 1; + SpawnSkeleton(v4, v2 - 1, v1 - 1); + } + else + { + v5 = v1 - 1; + AddObject(11, v2 - 1, v1 - 1); + } + v6 = PreSpawnSkeleton(); + SpawnSkeleton(v6, v2, v5); + _LOBYTE(v7) = 0; + if ( random(v7, v20[(unsigned char)leveltype]) ) + { + v8 = PreSpawnSkeleton(); + SpawnSkeleton(v8, v2 + 1, v5); + } + else + { + AddObject(13, v2 + 1, v5); + } + _LOBYTE(v9) = 0; + if ( random(v9, v20[(unsigned char)leveltype]) ) + { + v10 = PreSpawnSkeleton(); + SpawnSkeleton(v10, v2 - 1, v1); + } + else + { + AddObject(12, v2 - 1, v1); + } + _LOBYTE(v11) = 0; + if ( random(v11, v20[(unsigned char)leveltype]) ) + { + v12 = PreSpawnSkeleton(); + SpawnSkeleton(v12, v2 + 1, v1); + } + else + { + AddObject(12, v2 + 1, v1); + } + _LOBYTE(v13) = 0; + if ( random(v13, v20[(unsigned char)leveltype]) ) + { + v14 = PreSpawnSkeleton(); + v15 = v1 + 1; + SpawnSkeleton(v14, v2 - 1, v1 + 1); + } + else + { + v15 = v1 + 1; + AddObject(13, v2 - 1, v1 + 1); + } + v16 = PreSpawnSkeleton(); + SpawnSkeleton(v16, v2, v15); + _LOBYTE(v17) = 0; + if ( random(v17, v20[(unsigned char)leveltype]) ) + { + v18 = PreSpawnSkeleton(); + SpawnSkeleton(v18, v2 + 1, v15); + } + else + { + AddObject(11, v2 + 1, v15); + } + v19 = 112 * v2 + v1; + if ( !dungeon[39][v19 + 37] ) + AddObject(61, v2, v1 - 2); + if ( !dObject[0][v19 + 3] ) + AddObject(61, v2, v1 + 2); +} +// 5BB1ED: using guessed type char leveltype; + +//----- (0045D5BC) -------------------------------------------------------- +void __fastcall Theme_Treasure(int theme_num) +{ + int v1; // ecx + int v2; // esi + int v3; // edi + char *v4; // ebx + int v5; // eax + int v6; // ecx + int v7; // eax + char t[24]; // [esp+Ch] [ebp-18h] + + *(_DWORD *)t = theme_num; + t[20] = 4; + t[21] = 9; + t[22] = 7; + t[23] = 10; + t[12] = 6; + t[13] = 8; + t[14] = 3; + t[15] = 7; + GetRndSeed(); + _LOBYTE(v1) = leveltype; + v2 = 0; + *(_DWORD *)&t[16] = (unsigned int)dPiece; + do + { + v3 = 0; + v4 = (char *)dung_map + v2; + *(_DWORD *)&t[4] = *(_DWORD *)&t[16]; + do + { + if ( *v4 == themes[*(_DWORD *)t].ttval && !nSolidTable[**(_DWORD **)&t[4]] ) + { + v5 = (unsigned char)v1; + _LOBYTE(v1) = 0; + *(_DWORD *)&t[8] = random(v1, t[v5 + 19]); + _LOBYTE(v6) = 0; + if ( !(2 * random(v6, t[(unsigned char)leveltype + 19])) ) + { + CreateTypeItem(v3, v2, 0, 11, 0, 0, 1); + ItemNoFlippy(); + } + if ( *(_DWORD *)&t[8] ) + { + _LOBYTE(v1) = leveltype; + if ( *(_DWORD *)&t[8] < t[(unsigned char)leveltype + 19] - 2 ) + goto LABEL_13; + } + else + { + CreateRndItem(v3, v2, 0, 0, 1); + ItemNoFlippy(); + } + ItemNoFlippy(); + _LOBYTE(v1) = leveltype; + if ( *(_DWORD *)&t[8] >= t[(unsigned char)leveltype + 19] - 2 && leveltype != 1 ) + items[v7]._ivalue >>= 1; + } +LABEL_13: + *(_DWORD *)&t[4] += 448; + ++v3; + v4 += 112; + } + while ( v3 < 112 ); + *(_DWORD *)&t[16] += 4; + ++v2; + } + while ( *(_DWORD *)&t[16] < (signed int)dPiece[1] ); + PlaceThemeMonsts(*(int *)t, t[(unsigned char)v1 + 11]); +} +// 5BB1ED: using guessed type char leveltype; + +//----- (0045D707) -------------------------------------------------------- +void __fastcall Theme_Library(int theme_num) +{ + int v1; // edi + int v2; // ebx + char *v3; // esi + int v4; // eax + int v5; // ecx + int v6; // ecx + int v7; // eax + int v8; // eax + char t[20]; // [esp+Ch] [ebp-14h] + + *(_DWORD *)t = theme_num; + t[16] = 1; + t[17] = 2; + t[18] = 2; + t[19] = 5; + t[12] = 5; + t[13] = 7; + t[14] = 3; + t[15] = 9; + TFit_Shrine(theme_num); + v1 = 1; + if ( themeVar1 == 1 ) + { + AddObject(65, themex - 1, themey); + AddObject(63, themex, themey); + AddObject(65, themex + 1, themey); + } + else + { + AddObject(65, themex, themey - 1); + AddObject(62, themex, themey); + AddObject(65, themex, themey + 1); + } + *(_DWORD *)&t[8] = (unsigned int)&dMonster[1][1]; + do + { + v2 = 1; + v3 = &dObject[1][v1]; + *(_DWORD *)&t[4] = *(_DWORD *)&t[8]; + do + { + _LOBYTE(v4) = CheckThemeObj3(v2, v1, *(int *)t, -1); + if ( v4 ) + { + if ( !**(_DWORD **)&t[4] ) + { + _LOBYTE(v5) = 0; + if ( !random(v5, t[(unsigned char)leveltype + 15]) ) + { + AddObject(64, v2, v1); + _LOBYTE(v6) = 0; + if ( random(v6, 2 * t[(unsigned char)leveltype + 15]) ) + { + v7 = *v3 - 1; + _LOBYTE(object[v7]._oSelFlag) = 0; + object[v7]._oAnimFrame += 2; + } + } + } + } + *(_DWORD *)&t[4] += 448; + ++v2; + v3 += 112; + } + while ( v2 < 111 ); + *(_DWORD *)&t[8] += 4; + ++v1; + } + while ( *(_DWORD *)&t[8] < (signed int)&dMonster[1][111] ); + _LOBYTE(v8) = QuestStatus(3); + if ( !v8 || *(_DWORD *)t != zharlib ) + PlaceThemeMonsts(*(int *)t, t[(unsigned char)leveltype + 12]); +} +// 5BB1ED: using guessed type char leveltype; +// 6AAA64: using guessed type int zharlib; + +//----- (0045D88A) -------------------------------------------------------- +void __fastcall Theme_Torture(int theme_num) +{ + int v1; // ebx + int v2; // esi + char *v3; // edi + int v4; // eax + int v5; // ecx + char x[20]; // [esp+Ch] [ebp-14h] + + v1 = theme_num; + x[12] = 6; + x[13] = 8; + x[14] = 3; + x[15] = 8; + x[4] = 6; + x[5] = 8; + x[6] = 3; + x[7] = 9; + v2 = 1; + *(_DWORD *)&x[8] = (unsigned int)&dPiece[1][1]; + do + { + *(_DWORD *)&x[16] = 1; + v3 = &dung_map[1][v2]; + *(_DWORD *)x = *(_DWORD *)&x[8]; + do + { + if ( *v3 == themes[v1].ttval && !nSolidTable[**(_DWORD **)x] ) + { + _LOBYTE(v4) = CheckThemeObj3(*(int *)&x[16], v2, v1, -1); + if ( v4 ) + { + _LOBYTE(v5) = 0; + if ( !random(v5, x[(unsigned char)leveltype + 11]) ) + AddObject(30, *(int *)&x[16], v2); + } + } + ++*(_DWORD *)&x[16]; + *(_DWORD *)x += 448; + v3 += 112; + } + while ( *(_DWORD *)&x[16] < 111 ); + *(_DWORD *)&x[8] += 4; + ++v2; + } + while ( *(_DWORD *)&x[8] < (signed int)&dPiece[1][111] ); + PlaceThemeMonsts(v1, x[(unsigned char)leveltype + 3]); +} +// 5BB1ED: using guessed type char leveltype; + +//----- (0045D95D) -------------------------------------------------------- +void __fastcall Theme_BloodFountain(int theme_num) +{ + int v1; // esi + char v2[5]; // [esp+3h] [ebp-5h] + + v1 = theme_num; + v2[1] = 6; + v2[2] = 8; + v2[3] = 3; + v2[4] = 9; + TFit_Obj5(theme_num); + AddObject(66, themex, themey); + PlaceThemeMonsts(v1, v2[(unsigned char)leveltype]); +} +// 5BB1ED: using guessed type char leveltype; + +//----- (0045D9A3) -------------------------------------------------------- +void __fastcall Theme_Decap(int theme_num) +{ + int v1; // ebx + int v2; // esi + char *v3; // edi + int v4; // eax + int v5; // ecx + char x[20]; // [esp+Ch] [ebp-14h] + + v1 = theme_num; + x[12] = 6; + x[13] = 8; + x[14] = 3; + x[15] = 8; + x[4] = 6; + x[5] = 8; + x[6] = 3; + x[7] = 9; + v2 = 1; + *(_DWORD *)&x[8] = (unsigned int)&dPiece[1][1]; + do + { + *(_DWORD *)&x[16] = 1; + v3 = &dung_map[1][v2]; + *(_DWORD *)x = *(_DWORD *)&x[8]; + do + { + if ( *v3 == themes[v1].ttval && !nSolidTable[**(_DWORD **)x] ) + { + _LOBYTE(v4) = CheckThemeObj3(*(int *)&x[16], v2, v1, -1); + if ( v4 ) + { + _LOBYTE(v5) = 0; + if ( !random(v5, x[(unsigned char)leveltype + 11]) ) + AddObject(67, *(int *)&x[16], v2); + } + } + ++*(_DWORD *)&x[16]; + *(_DWORD *)x += 448; + v3 += 112; + } + while ( *(_DWORD *)&x[16] < 111 ); + *(_DWORD *)&x[8] += 4; + ++v2; + } + while ( *(_DWORD *)&x[8] < (signed int)&dPiece[1][111] ); + PlaceThemeMonsts(v1, x[(unsigned char)leveltype + 3]); +} +// 5BB1ED: using guessed type char leveltype; + +//----- (0045DA76) -------------------------------------------------------- +void __fastcall Theme_PurifyingFountain(int theme_num) +{ + int v1; // esi + char v2[5]; // [esp+3h] [ebp-5h] + + v1 = theme_num; + v2[1] = 6; + v2[2] = 7; + v2[3] = 3; + v2[4] = 9; + TFit_Obj5(theme_num); + AddObject(76, themex, themey); + PlaceThemeMonsts(v1, v2[(unsigned char)leveltype]); +} +// 5BB1ED: using guessed type char leveltype; + +//----- (0045DABC) -------------------------------------------------------- +void __fastcall Theme_ArmorStand(int theme_num) +{ + int v1; // esi + int v2; // ebx + char *v3; // edi + int v4; // eax + int v5; // ecx + char t[20]; // [esp+Ch] [ebp-14h] + + v1 = 0; + *(_DWORD *)t = theme_num; + t[16] = 6; + t[17] = 8; + t[18] = 3; + t[19] = 8; + t[8] = 6; + t[9] = 7; + t[10] = 3; + t[11] = 9; + if ( armorFlag ) + { + TFit_Obj3(theme_num); + AddObject(77, themex, themey); + } + *(_DWORD *)&t[12] = (unsigned int)dPiece; + do + { + v2 = 0; + v3 = (char *)dung_map + v1; + *(_DWORD *)&t[4] = *(_DWORD *)&t[12]; + do + { + if ( *v3 == themes[*(_DWORD *)t].ttval && !nSolidTable[**(_DWORD **)&t[4]] ) + { + _LOBYTE(v4) = CheckThemeObj3(v2, v1, *(int *)t, -1); + if ( v4 ) + { + _LOBYTE(v5) = 0; + if ( !random(v5, t[(unsigned char)leveltype + 15]) ) + AddObject(78, v2, v1); + } + } + *(_DWORD *)&t[4] += 448; + ++v2; + v3 += 112; + } + while ( v2 < 112 ); + *(_DWORD *)&t[12] += 4; + ++v1; + } + while ( *(_DWORD *)&t[12] < (signed int)dPiece[1] ); + PlaceThemeMonsts(*(int *)t, t[(unsigned char)leveltype + 7]); + armorFlag = 0; +} +// 5BB1ED: using guessed type char leveltype; +// 6AAA3C: using guessed type int armorFlag; + +//----- (0045DBAD) -------------------------------------------------------- +void __fastcall Theme_GoatShrine(int theme_num) +{ + int v1; // edx + int v2; // esi + int v3; // ecx + int v4; // edi + int v5; // eax + char *v6; // ebx + _DWORD *v7; // [esp+4h] [ebp-8h] + int v8; // [esp+8h] [ebp-4h] + + v8 = theme_num; + TFit_GoatShrine(theme_num); + AddObject(79, themex, themey); + v1 = themey; + v2 = themey - 1; + if ( themey - 1 <= themey + 1 ) + { + v3 = themex; + do + { + v4 = v3 - 1; + if ( (unsigned char)(__OFSUB__(v3 - 1, v3 + 1) ^ 1) | (v3 - 1 == v3 + 1) ) + { + v5 = v2 + 112 * v4; + v6 = (char *)dung_map + v5; + v7 = (_DWORD *)((char *)dPiece + 4 * v5); + do + { + if ( *v6 == themes[v8].ttval && !nSolidTable[*v7] && (v4 != v3 || v2 != v1) ) + { + AddMonster(v4, v2, 1, themeVar1, 1); + v1 = themey; + v3 = themex; + } + v7 += 112; + ++v4; + v6 += 112; + } + while ( v4 <= v3 + 1 ); + } + ++v2; + } + while ( v2 <= v1 + 1 ); + } +} + +//----- (0045DC7B) -------------------------------------------------------- +void __fastcall Theme_Cauldron(int theme_num) +{ + int v1; // esi + char v2[5]; // [esp+3h] [ebp-5h] + + v1 = theme_num; + v2[1] = 6; + v2[2] = 7; + v2[3] = 3; + v2[4] = 9; + TFit_Obj5(theme_num); + AddObject(80, themex, themey); + PlaceThemeMonsts(v1, v2[(unsigned char)leveltype]); +} +// 5BB1ED: using guessed type char leveltype; + +//----- (0045DCC1) -------------------------------------------------------- +void __fastcall Theme_MurkyFountain(int theme_num) +{ + int v1; // esi + char v2[5]; // [esp+3h] [ebp-5h] + + v1 = theme_num; + v2[1] = 6; + v2[2] = 7; + v2[3] = 3; + v2[4] = 9; + TFit_Obj5(theme_num); + AddObject(81, themex, themey); + PlaceThemeMonsts(v1, v2[(unsigned char)leveltype]); +} +// 5BB1ED: using guessed type char leveltype; + +//----- (0045DD07) -------------------------------------------------------- +void __fastcall Theme_TearFountain(int theme_num) +{ + int v1; // esi + char v2[5]; // [esp+3h] [ebp-5h] + + v1 = theme_num; + v2[1] = 6; + v2[2] = 7; + v2[3] = 3; + v2[4] = 9; + TFit_Obj5(theme_num); + AddObject(82, themex, themey); + PlaceThemeMonsts(v1, v2[(unsigned char)leveltype]); +} +// 5BB1ED: using guessed type char leveltype; + +//----- (0045DD4D) -------------------------------------------------------- +void __fastcall Theme_BrnCross(int theme_num) +{ + int v1; // esi + int v2; // ebx + char *v3; // edi + int v4; // eax + int v5; // ecx + char t[20]; // [esp+Ch] [ebp-14h] + + *(_DWORD *)t = theme_num; + t[8] = 6; + t[9] = 8; + t[10] = 3; + t[11] = 9; + t[16] = 5; + t[17] = 7; + t[18] = 3; + t[19] = 8; + v1 = 0; + *(_DWORD *)&t[12] = (unsigned int)dPiece; + do + { + v2 = 0; + v3 = (char *)dung_map + v1; + *(_DWORD *)&t[4] = *(_DWORD *)&t[12]; + do + { + if ( *v3 == themes[*(_DWORD *)t].ttval && !nSolidTable[**(_DWORD **)&t[4]] ) + { + _LOBYTE(v4) = CheckThemeObj3(v2, v1, *(int *)t, -1); + if ( v4 ) + { + _LOBYTE(v5) = 0; + if ( !random(v5, t[(unsigned char)leveltype + 15]) ) + AddObject(91, v2, v1); + } + } + *(_DWORD *)&t[4] += 448; + ++v2; + v3 += 112; + } + while ( v2 < 112 ); + *(_DWORD *)&t[12] += 4; + ++v1; + } + while ( *(_DWORD *)&t[12] < (signed int)dPiece[1] ); + PlaceThemeMonsts(*(int *)t, t[(unsigned char)leveltype + 7]); + bCrossFlag = 1; +} +// 5BB1ED: using guessed type char leveltype; +// 6AAC10: using guessed type int bCrossFlag; + +//----- (0045DE20) -------------------------------------------------------- +void __fastcall Theme_WeaponRack(int theme_num) +{ + int v1; // esi + int v2; // ebx + char *v3; // edi + int v4; // eax + int v5; // ecx + char t[20]; // [esp+Ch] [ebp-14h] + + v1 = 0; + *(_DWORD *)t = theme_num; + t[16] = 6; + t[17] = 8; + t[18] = 5; + t[19] = 8; + t[8] = 6; + t[9] = 7; + t[10] = 3; + t[11] = 9; + if ( weaponFlag ) + { + TFit_Obj3(theme_num); + AddObject(92, themex, themey); + } + *(_DWORD *)&t[12] = (unsigned int)dPiece; + do + { + v2 = 0; + v3 = (char *)dung_map + v1; + *(_DWORD *)&t[4] = *(_DWORD *)&t[12]; + do + { + if ( *v3 == themes[*(_DWORD *)t].ttval && !nSolidTable[**(_DWORD **)&t[4]] ) + { + _LOBYTE(v4) = CheckThemeObj3(v2, v1, *(int *)t, -1); + if ( v4 ) + { + _LOBYTE(v5) = 0; + if ( !random(v5, t[(unsigned char)leveltype + 15]) ) + AddObject(93, v2, v1); + } + } + *(_DWORD *)&t[4] += 448; + ++v2; + v3 += 112; + } + while ( v2 < 112 ); + *(_DWORD *)&t[12] += 4; + ++v1; + } + while ( *(_DWORD *)&t[12] < (signed int)dPiece[1] ); + PlaceThemeMonsts(*(int *)t, t[(unsigned char)leveltype + 7]); + weaponFlag = 0; +} +// 5BB1ED: using guessed type char leveltype; +// 6AAA50: using guessed type int weaponFlag; + +//----- (0045DF11) -------------------------------------------------------- +void __cdecl UpdateL4Trans() +{ + signed int v0; // ecx + _BYTE *v1; // eax + signed int v2; // edx + + v0 = 0; + do + { + v1 = (unsigned char *)dung_map + v0; + v2 = 112; + do + { + if ( *v1 ) + *v1 = 1; + v1 += 112; + --v2; + } + while ( v2 ); + ++v0; + } + while ( v0 < 112 ); +} + +//----- (0045DF31) -------------------------------------------------------- +void __cdecl CreateThemeRooms() +{ + int v0; // esi + int v1; // eax + + if ( currlevel != 16 ) + { + v0 = 0; + for ( InitObjFlag = 1; v0 < numthemes; ++v0 ) + { + v1 = SLOBYTE(themes[v0].ttype); + themex = 0; + themey = 0; + switch ( v1 ) + { + case THEME_BARREL: + Theme_Barrel(v0); + break; + case THEME_SHRINE: + Theme_Shrine(v0); + break; + case THEME_MONSTPIT: + Theme_MonstPit(v0); + break; + case THEME_SKELROOM: + Theme_SkelRoom(v0); + break; + case THEME_TREASURE: + Theme_Treasure(v0); + break; + case THEME_LIBRARY: + Theme_Library(v0); + break; + case THEME_TORTURE: + Theme_Torture(v0); + break; + case THEME_BLOODFOUNTAIN: + Theme_BloodFountain(v0); + break; + case THEME_DECAPITATED: + Theme_Decap(v0); + break; + case THEME_PURIFYINGFOUNTAIN: + Theme_PurifyingFountain(v0); + break; + case THEME_ARMORSTAND: + Theme_ArmorStand(v0); + break; + case THEME_GOATSHRINE: + Theme_GoatShrine(v0); + break; + case THEME_CAULDRON: + Theme_Cauldron(v0); + break; + case THEME_MURKYFOUNTAIN: + Theme_MurkyFountain(v0); + break; + case THEME_TEARFOUNTAIN: + Theme_TearFountain(v0); + break; + case THEME_BRNCROSS: + Theme_BrnCross(v0); + break; + case THEME_WEAPONRACK: + Theme_WeaponRack(v0); + break; + default: + continue; + } + } + InitObjFlag = 0; + if ( leveltype == 4 && themeCount > 0 ) + UpdateL4Trans(); + } +} +// 5BB1ED: using guessed type char leveltype; +// 67D7C0: using guessed type int InitObjFlag; + +//----- (0045E08C) -------------------------------------------------------- +int __fastcall tmsg_get(char *data, int size) +{ + char *v2; // ebx + DWORD v3; // eax + TMsg v4; // esi + size_t v6; // edi + + v2 = data; + if ( !*(_DWORD *)&sgpTimedMsgHead ) + return 0; + v3 = GetTickCount(); + v4 = sgpTimedMsgHead; + if ( (signed int)(*(_DWORD *)(*(_DWORD *)&sgpTimedMsgHead + 4) - v3) >= 0 ) + return 0; + sgpTimedMsgHead = **(TMsg **)&sgpTimedMsgHead; + //v6 = v4[8]; + //memcpy(v2, v4 + 9, v6); +// mem_free_dbg(v4); + return v6; +} + +//----- (0045E0D7) -------------------------------------------------------- +void __fastcall tmsg_add(char *msg, char len) +{ + char v2; // bl + char *v3; // ebp + size_t v4; // edi + _DWORD *v5; // eax + _DWORD *v6; // esi + DWORD v7; // eax + TMsg v8; // ecx + TMsg v9; // eax + + v2 = len; + v3 = msg; + v4 = (unsigned char)len; + v5 = (unsigned int *)DiabloAllocPtr((unsigned char)len + 12); + v6 = v5; + *v5 = 0; + v7 = GetTickCount(); + *((_BYTE *)v6 + 8) = v2; + v6[1] = v7 + 500; + memcpy((char *)v6 + 9, v3, v4); + v8 = sgpTimedMsgHead; + v9 = sgpTimedMsgHead; +/* while ( *v8 ) + { + v9 = v8; + v8 = (TMsg *)*v8; + } + *v9 = (TMsg)v6;*/ +} + +//----- (0045E12A) -------------------------------------------------------- +void __cdecl tmsg_cleanup() +{ + TMsg v0; // eax + TMsg v1; // esi + + v0 = sgpTimedMsgHead; +/* if ( sgpTimedMsgHead ) + { + do + { + v1 = v0; + sgpTimedMsgHead = 0; + mem_free_dbg(v0); + v0 = v1; + sgpTimedMsgHead = v1; + } + while ( v1 ); + }*/ +} + +//----- (0045E151) -------------------------------------------------------- +int __fastcall town_clear_upper_buf(int a1) +{ + unsigned int v1; // edi + signed int v2; // edx + signed int v3; // ebx + int result; // eax + char *v5; // edi + signed int v6; // edx + signed int v7; // ebx + char *v8; // edi + + v1 = a1; + v2 = 30; + v3 = 1; + result = 0; + while ( v1 >= screen_buf_end ) + { + v5 = (char *)(v2 + v1); + memset(v5, 0, 4 * v3); + v1 = (unsigned int)&v5[4 * v3 - 832 + v2]; + if ( !v2 ) + { + v6 = 2; + v7 = 15; + do + { + if ( v1 < screen_buf_end ) + break; + v8 = (char *)(v6 + v1); + memset(v8, 0, 4 * v7); + v1 = (unsigned int)&v8[4 * v7-- - 832 + v6]; + v6 += 2; + } + while ( v6 != 32 ); + return result; + } + v2 -= 2; + ++v3; + } + return result; +} +// 69CF0C: using guessed type int screen_buf_end; + +//----- (0045E1B7) -------------------------------------------------------- +void __fastcall town_clear_low_buf(int y_related) +{ + unsigned int v1; // edi + signed int v2; // edx + signed int i; // ebx + int v4; // edi + char *v5; // edi + signed int v6; // edx + signed int v7; // ebx + int v8; // edi + char *v9; // edi + + v1 = y_related; + v2 = 30; + for ( i = 1; ; ++i ) + { + if ( v1 < screen_buf_end ) + { + v5 = (char *)(v2 + v1); + memset(v5, 0, 4 * i); + v4 = (int)&v5[4 * i + v2]; + } + else + { + v4 = v1 + 64; + } + v1 = v4 - 832; + if ( !v2 ) + break; + v2 -= 2; + } + v6 = 2; + v7 = 15; + do + { + if ( v1 < screen_buf_end ) + { + v9 = (char *)(v6 + v1); + memset(v9, 0, 4 * v7); + v8 = (int)&v9[4 * v7 + v6]; + } + else + { + v8 = v1 + 64; + } + v1 = v8 - 832; + --v7; + v6 += 2; + } + while ( v6 != 32 ); +} +// 69CF0C: using guessed type int screen_buf_end; + +//----- (0045E226) -------------------------------------------------------- +void __fastcall town_draw_low_somepiece(void *buffer, int x, int y, int sx, int sy) +{ + int v5; // ebx + char *v6; // esi + signed int v7; // edi + int v8; // eax + int v9; // eax + void *unused; // [esp+Ch] [ebp-8h] + char *a1; // [esp+10h] [ebp-4h] + + v5 = x; + unused = buffer; + a1 = (char *)buffer; + v6 = (char *)dpiece_defs_map_1 + 32 * gendung_41927A(x, y); + v7 = 0; + do + { + v8 = *(unsigned short *)&v6[2 * v7]; + level_cel_block = *(unsigned short *)&v6[2 * v7]; + if ( v8 ) + drawLowerScreen(a1); + v9 = *(unsigned short *)&v6[2 * v7 + 2]; + level_cel_block = *(unsigned short *)&v6[2 * v7 + 2]; + if ( v9 ) + drawLowerScreen(a1 + 32); + a1 -= 24576; + v7 += 2; + } + while ( v7 < 12 ); + town_draw_low_something(unused, v5, y, sx, sy, 0); +} +// 69CF14: using guessed type int level_cel_block; + +//----- (0045E2A5) -------------------------------------------------------- +void __fastcall town_draw_low_something(void *unused, int x, int y, int sx, int sy, int some_flag) +{ + unsigned int v6; // edx + int v7; // edi + char v8; // al + char v9; // al + int v10; // esi + int v11; // ebx + int v12; // esi + int v13; // ebx + int v14; // eax + int v15; // eax + int v16; // esi + int v17; // ebx + char v18; // al + int v19; // esi + int v20; // ebx + int v21; // edi + char v22; // al + char v23; // al + int v24; // esi + int v25; // ebx + int v26; // edi + char *v27; // [esp+Ch] [ebp-Ch] + int xa; // [esp+10h] [ebp-8h] + int v29; // [esp+14h] [ebp-4h] + + xa = x; + v6 = 112 * x; + v27 = (char *)gpBuffer + screen_y_times_768[sy] + sx; + v7 = v6 + y; + v29 = v6 + y; + v8 = dItem[v6 / 0x70][y]; + if ( v8 ) + { + v9 = v8 - 1; + v10 = v9; + v11 = sx - items[v10]._iAnimXOff; + if ( v9 == pcursitem ) + Cel_header_and_colour_highlight( + 181, + v11, + sy, + (char *)items[v10].ItemFrame, + items[v10]._iAnimFrame, + items[v10]._iAnimWidth, + 0, + 8); + Cel2_header(v11, sy, (char *)items[v10].ItemFrame, items[v10]._iAnimFrame, items[v10]._iAnimWidth, 0, 8); + } + if ( dFlags[0][v7] & 0x10 ) + { + v12 = -1 - *(&dword_52D204 + v7); + v13 = sx - towner[v12]._tAnimWidth2; + if ( -1 - *(&dword_52D204 + v7) == *(_DWORD *)&pcursmonst ) + Cel_header_and_colour_highlight( + 166, + v13, + sy, + (char *)towner[v12]._tAnimCel, + towner[v12]._tAnimFrame, + towner[v12]._tAnimWidth, + 0, + 8); + Cel2_header(v13, sy, (char *)towner[v12]._tAnimCel, towner[v12]._tAnimFrame, towner[v12]._tAnimWidth, 0, 8); + } + v14 = dMonster[0][v7]; + if ( v14 > 0 ) + { + v15 = v14 - 1; + v16 = v15; + v17 = sx - towner[v15]._tAnimWidth2; + if ( v15 == *(_DWORD *)&pcursmonst ) + Cel_header_and_colour_highlight( + 166, + v17, + sy, + (char *)towner[v16]._tAnimCel, + towner[v16]._tAnimFrame, + towner[v16]._tAnimWidth, + 0, + 8); + Cel2_header(v17, sy, (char *)towner[v16]._tAnimCel, towner[v16]._tAnimFrame, towner[v16]._tAnimWidth, 0, 8); + } + if ( dFlags[0][v7] & 0x20 ) + { + v18 = -1 - *((_BYTE *)&themeLoc[49].height + v7 + 3); + v19 = v18; + v20 = sy + plr[v19]._pyoff; + v21 = sx + plr[v19]._pxoff - plr[v19]._pAnimWidth2; + if ( v18 == pcursplr ) + engine_417C99(165, v21, v20, (void *)plr[v19]._pAnimData, plr[v19]._pAnimFrame, plr[v19]._pAnimWidth, 0, 8); + engine_417B83(v21, v20, (void *)plr[v19]._pAnimData, plr[v19]._pAnimFrame, plr[v19]._pAnimWidth, 0, 8); + if ( some_flag && plr[v19]._peflag ) + town_draw_low_somepiece(v27 - 64, xa - 1, y + 1, sx - 64, sy); + v7 = v29; + } + if ( dFlags[0][v7] & 4 ) + scrollrt_452CC0(xa, y, sx, sy, 0, 8, 1); + v22 = dPlayer[0][v7]; + if ( v22 > 0 ) + { + v23 = v22 - 1; + v24 = v23; + v25 = sy + plr[v24]._pyoff; + v26 = sx + plr[v24]._pxoff - plr[v24]._pAnimWidth2; + if ( v23 == pcursplr ) + engine_417C99(165, v26, v25, (void *)plr[v24]._pAnimData, plr[v24]._pAnimFrame, plr[v24]._pAnimWidth, 0, 8); + engine_417B83(v26, v25, (void *)plr[v24]._pAnimData, plr[v24]._pAnimFrame, plr[v24]._pAnimWidth, 0, 8); + if ( some_flag && plr[v24]._peflag ) + town_draw_low_somepiece(v27 - 64, xa - 1, y + 1, sx - 64, sy); + v7 = v29; + } + if ( dFlags[0][v7] & 1 ) + scrollrt_452B2A(xa, y, sx, sy, 0, 8, 0); +} +// 4B8CC0: using guessed type char pcursitem; +// 4B8CC2: using guessed type char pcursplr; + +//----- (0045E5B0) -------------------------------------------------------- +void __fastcall town_draw_low_pieces(int x, int y, int sx, int sy, int a5, int some_flag) +{ + int v6; // ebx + int *v7; // edi + char *v8; // esi + int v9; // eax + int v10; // eax + int *v11; // ebx + int v12; // esi + char *v13; // esi + char *v14; // edi + int v15; // eax + int v16; // eax + bool v17; // zf + int *v18; // ebx + char *v19; // esi + char *v20; // edi + int v21; // eax + char *a1; // [esp+Ch] [ebp-10h] + int a1a; // [esp+Ch] [ebp-10h] + int ya; // [esp+10h] [ebp-Ch] + signed int v25; // [esp+14h] [ebp-8h] + signed int v26; // [esp+14h] [ebp-8h] + signed int v27; // [esp+14h] [ebp-8h] + signed int xa; // [esp+18h] [ebp-4h] + int a5a; // [esp+2Ch] [ebp+10h] + + ya = y; + xa = x; + if ( some_flag ) + { + if ( y >= 0 && y < 112 && x >= 0 && x < 112 && (level_cel_block = dPiece[0][y + 112 * x]) != 0 ) + { + v6 = sy; + v7 = &screen_y_times_768[sy]; + a1 = &gpBuffer->row_unused_1[0].col_unused_1[*v7 + 32 + sx]; + v25 = 1; + v8 = (char *)dpiece_defs_map_1 + 32 * gendung_41927A(x, y); + do + { + v9 = *(unsigned short *)&v8[2 * v25]; + level_cel_block = *(unsigned short *)&v8[2 * v25]; + if ( v9 ) + drawLowerScreen(a1); + v25 += 2; + a1 -= 24576; + } + while ( v25 < 17 ); + town_draw_low_something((char *)gpBuffer + *v7 + sx, xa, ya, sx, sy, 0); + } + else + { + town_clear_low_buf((int)gpBuffer + screen_y_times_768[sy] + sx); + v6 = sy; + } + ++xa; + y = ya - 1; + sx += 64; + --ya; + } + else + { + v6 = sy; + } + v10 = a5 - some_flag; + if ( a5 - some_flag > 0 ) + { + v11 = &screen_y_times_768[v6]; + v12 = 112 * xa; + a5a = 112 * xa; + a1a = v10; + do + { + if ( y >= 0 && y < 112 && v12 >= 0 && v12 < 12544 && (level_cel_block = dPiece[0][v12 + y]) != 0 ) + { + v13 = (char *)gpBuffer + *v11 + sx; + v14 = (char *)dpiece_defs_map_1 + 32 * gendung_41927A(xa, ya); + v26 = 0; + do + { + v15 = *(unsigned short *)&v14[2 * v26]; + level_cel_block = *(unsigned short *)&v14[2 * v26]; + if ( v15 ) + drawLowerScreen(v13); + v16 = *(unsigned short *)&v14[2 * v26 + 2]; + level_cel_block = *(unsigned short *)&v14[2 * v26 + 2]; + if ( v16 ) + drawLowerScreen(v13 + 32); + v26 += 2; + v13 -= 24576; + } + while ( v26 < 16 ); + town_draw_low_something((char *)gpBuffer + *v11 + sx, xa, ya, sx, sy, 1); + v12 = a5a; + } + else + { + town_clear_low_buf((int)gpBuffer + *v11 + sx); + } + ++xa; + sx += 64; + v12 += 112; + y = ya - 1; + v17 = a1a-- == 1; + a5a = v12; + --ya; + } + while ( !v17 ); + v6 = sy; + } + if ( some_flag ) + { + if ( y >= 0 && y < 112 && xa >= 0 && xa < 112 && (level_cel_block = dPiece[0][y + 112 * xa]) != 0 ) + { + v18 = &screen_y_times_768[v6]; + v19 = (char *)gpBuffer + *v18 + sx; + v20 = (char *)dpiece_defs_map_1 + 32 * gendung_41927A(xa, ya); + v27 = 0; + do + { + v21 = *(unsigned short *)&v20[2 * v27]; + level_cel_block = *(unsigned short *)&v20[2 * v27]; + if ( v21 ) + drawLowerScreen(v19); + v27 += 2; + v19 -= 24576; + } + while ( v27 < 16 ); + town_draw_low_something((char *)gpBuffer + *v18 + sx, xa, ya, sx, sy, 0); + } + else + { + town_clear_low_buf((int)gpBuffer + screen_y_times_768[v6] + sx); + } + } +} +// 69CF14: using guessed type int level_cel_block; + +//----- (0045E898) -------------------------------------------------------- +void __fastcall town_draw_lower_screen(void *buffer, int x, int y, int a4, int a5, int sx, int sy) +{ + int v7; // ebx + char *v8; // edi + short *v9; // esi + int v10; // eax + int v11; // eax + void *v12; // [esp+8h] [ebp-8h] + int xa; // [esp+Ch] [ebp-4h] + int a4a; // [esp+1Ch] [ebp+Ch] + + v7 = a4; + xa = x; + v12 = buffer; + if ( a4 ) + v8 = (char *)buffer + 24576 * a4; + else + v8 = (char *)buffer; + a4a = 0; + v9 = &dpiece_defs_map_1[0][0][16 * gendung_41927A(x, y) + 3]; + do + { + if ( v7 <= a4a ) + { + v10 = (unsigned short)*(v9 - 1); + level_cel_block = (unsigned short)*(v9 - 1); + if ( v10 ) + drawLowerScreen(v8); + v11 = (unsigned short)*v9; + level_cel_block = (unsigned short)*v9; + if ( v11 ) + drawLowerScreen(v8 + 32); + } + v8 -= 24576; + ++a4a; + v9 += 2; + } + while ( a4a < 6 ); + if ( a5 < 8 ) + town_draw_low_towners((int)v12, xa, y, v7, a5, sx, sy, 0); +} +// 69CF14: using guessed type int level_cel_block; + +//----- (0045E939) -------------------------------------------------------- +void __fastcall town_draw_low_towners(int x, int y, int a3, int a4, int a5, int sx, int sy, int some_flag) +{ + unsigned int v8; // edx + int v9; // ebx + char v10; // al + char v11; // al + int v12; // esi + int v13; // edi + int v14; // esi + int v15; // edi + int v16; // eax + int v17; // eax + int v18; // esi + int v19; // edi + char v20; // al + int v21; // esi + int v22; // ebx + int v23; // edi + char v24; // al + char v25; // al + int v26; // esi + int v27; // ebx + int v28; // edi + int v29; // [esp+Ch] [ebp-Ch] + int xa; // [esp+10h] [ebp-8h] + int v31; // [esp+14h] [ebp-4h] + + xa = y; + v8 = 112 * y; + v9 = v8 + a3; + v29 = x; + v31 = v8 + a3; + v10 = dItem[v8 / 0x70][a3]; + if ( v10 ) + { + v11 = v10 - 1; + v12 = v11; + v13 = sx - items[v12]._iAnimXOff; + if ( v11 == pcursitem ) + Cel_header_and_colour_highlight( + 181, + v13, + sy, + (char *)items[v12].ItemFrame, + items[v12]._iAnimFrame, + items[v12]._iAnimWidth, + a5, + 8); + Cel2_header(v13, sy, (char *)items[v12].ItemFrame, items[v12]._iAnimFrame, items[v12]._iAnimWidth, a5, 8); + } + if ( dFlags[0][v9] & 0x10 ) + { + v14 = -1 - *(&dword_52D204 + v9); + v15 = sx - towner[v14]._tAnimWidth2; + if ( -1 - *(&dword_52D204 + v9) == *(_DWORD *)&pcursmonst ) + Cel_header_and_colour_highlight( + 166, + v15, + sy, + (char *)towner[v14]._tAnimCel, + towner[v14]._tAnimFrame, + towner[v14]._tAnimWidth, + a5, + 8); + Cel2_header(v15, sy, (char *)towner[v14]._tAnimCel, towner[v14]._tAnimFrame, towner[v14]._tAnimWidth, a5, 8); + } + v16 = dMonster[0][v9]; + if ( v16 > 0 ) + { + v17 = v16 - 1; + v18 = v17; + v19 = sx - towner[v17]._tAnimWidth2; + if ( v17 == *(_DWORD *)&pcursmonst ) + Cel_header_and_colour_highlight( + 166, + v19, + sy, + (char *)towner[v18]._tAnimCel, + towner[v18]._tAnimFrame, + towner[v18]._tAnimWidth, + a5, + 8); + Cel2_header(v19, sy, (char *)towner[v18]._tAnimCel, towner[v18]._tAnimFrame, towner[v18]._tAnimWidth, a5, 8); + } + if ( dFlags[0][v9] & 0x20 ) + { + v20 = -1 - *((_BYTE *)&themeLoc[49].height + v9 + 3); + v21 = v20; + v22 = sy + plr[v21]._pyoff; + v23 = sx + plr[v21]._pxoff - plr[v21]._pAnimWidth2; + if ( v20 == pcursplr ) + engine_417C99(165, v23, v22, (void *)plr[v21]._pAnimData, plr[v21]._pAnimFrame, plr[v21]._pAnimWidth, a5, 8); + engine_417B83(v23, v22, (void *)plr[v21]._pAnimData, plr[v21]._pAnimFrame, plr[v21]._pAnimWidth, a5, 8); + if ( some_flag && plr[v21]._peflag ) + town_draw_lower_screen((void *)(v29 - 64), xa - 1, a3 + 1, a4, a5, sx - 64, sy); + v9 = v31; + } + if ( dFlags[0][v9] & 4 ) + scrollrt_452CC0(xa, a3, sx, sy, a5, 8, 1); + v24 = dPlayer[0][v9]; + if ( v24 > 0 ) + { + v25 = v24 - 1; + v26 = v25; + v27 = sy + plr[v26]._pyoff; + v28 = sx + plr[v26]._pxoff - plr[v26]._pAnimWidth2; + if ( v25 == pcursplr ) + engine_417C99(165, v28, v27, (void *)plr[v26]._pAnimData, plr[v26]._pAnimFrame, plr[v26]._pAnimWidth, a5, 8); + engine_417B83(v28, v27, (void *)plr[v26]._pAnimData, plr[v26]._pAnimFrame, plr[v26]._pAnimWidth, a5, 8); + if ( some_flag && plr[v26]._peflag ) + town_draw_lower_screen((void *)(v29 - 64), xa - 1, a3 + 1, a4, a5, sx - 64, sy); + v9 = v31; + } + if ( dFlags[0][v9] & 1 ) + scrollrt_452B2A(xa, a3, sx, sy, a5, 8, 0); +} +// 4B8CC0: using guessed type char pcursitem; +// 4B8CC2: using guessed type char pcursplr; + +//----- (0045EC49) -------------------------------------------------------- +void __fastcall town_draw_lower(int x, int y, int sx, int sy, int a5, int a6, int some_flag) +{ + int v7; // esi + int v8; // ebx + int *v9; // edi + short *v10; // eax + int v11; // esi + int v12; // eax + int *v13; // ebx + int v14; // edi + short *v15; // edi + int v16; // eax + int v17; // eax + int v18; // eax + bool v19; // zf + int *v20; // edi + short *v21; // ebx + int v22; // eax + short *v23; // [esp+Ch] [ebp-10h] + int v24; // [esp+Ch] [ebp-10h] + char *a1; // [esp+10h] [ebp-Ch] + char *a1a; // [esp+10h] [ebp-Ch] + char *a1b; // [esp+10h] [ebp-Ch] + signed int ya; // [esp+14h] [ebp-8h] + signed int xa; // [esp+18h] [ebp-4h] + signed int sxa; // [esp+24h] [ebp+8h] + signed int sxb; // [esp+24h] [ebp+8h] + signed int sxc; // [esp+24h] [ebp+8h] + int a5a; // [esp+2Ch] [ebp+10h] + + ya = y; + xa = x; + if ( some_flag ) + { + if ( y < 0 || y >= 112 || x < 0 || x >= 112 ) + { + v7 = sx; + } + else + { + v7 = sx; + level_cel_block = dPiece[0][y + 112 * x]; + if ( level_cel_block ) + { + v8 = sy; + v9 = &screen_y_times_768[sy]; + a1 = (char *)gpBuffer + *v9 + sx - 24544; + sxa = 0; + v10 = &dpiece_defs_map_1[0][0][16 * gendung_41927A(x, y) + 3]; + v23 = v10; + do + { + if ( a6 <= sxa ) + { + level_cel_block = (unsigned short)*v10; + if ( level_cel_block ) + drawLowerScreen(a1); + } + a1 -= 24576; + ++sxa; + v10 = v23 + 2; + v23 += 2; + } + while ( sxa < 7 ); + if ( 2 * a6 + 2 < 8 ) + town_draw_low_towners((int)gpBuffer + *v9 + v7, xa, ya, a6, 2 * a6 + 2, v7, sy, 0); + goto LABEL_16; + } + } + town_clear_low_buf((int)gpBuffer + screen_y_times_768[sy] + v7); + v8 = sy; +LABEL_16: + ++xa; + --ya; + v11 = v7 + 64; + goto LABEL_18; + } + v11 = sx; + v8 = sy; +LABEL_18: + v12 = a5 - some_flag; + if ( a5 - some_flag > 0 ) + { + v13 = &screen_y_times_768[v8]; + v14 = 112 * xa; + a5a = 112 * xa; + v24 = v12; + do + { + if ( ya >= 0 && ya < 112 && v14 >= 0 && v14 < 12544 && (level_cel_block = dPiece[0][v14 + ya]) != 0 ) + { + a1a = (char *)gpBuffer + *v13 + v11 - 24576; + sxb = 0; + v15 = &dpiece_defs_map_1[0][0][16 * gendung_41927A(xa, ya) + 3]; + do + { + if ( a6 <= sxb ) + { + v16 = (unsigned short)*(v15 - 1); + level_cel_block = (unsigned short)*(v15 - 1); + if ( v16 ) + drawLowerScreen(a1a); + v17 = (unsigned short)*v15; + level_cel_block = (unsigned short)*v15; + if ( v17 ) + drawLowerScreen(a1a + 32); + } + a1a -= 24576; + ++sxb; + v15 += 2; + } + while ( sxb < 7 ); + v18 = 2 * a6 + 2; + if ( v18 < 8 ) + town_draw_low_towners((int)gpBuffer + *v13 - 12288 * v18 + v11, xa, ya, a6, 2 * a6 + 2, v11, sy, 1); + v14 = a5a; + } + else + { + town_clear_low_buf((int)gpBuffer + *v13 + v11); + } + ++xa; + v14 += 112; + --ya; + v11 += 64; + v19 = v24-- == 1; + a5a = v14; + } + while ( !v19 ); + v8 = sy; + } + if ( some_flag ) + { + if ( ya >= 0 && ya < 112 && xa >= 0 && xa < 112 && (level_cel_block = dPiece[0][ya + 112 * xa]) != 0 ) + { + v20 = &screen_y_times_768[v8]; + a1b = (char *)gpBuffer + *v20 + v11 - 24576; + sxc = 0; + v21 = &dpiece_defs_map_1[0][0][16 * gendung_41927A(xa, ya) + 2]; + do + { + if ( a6 <= sxc ) + { + v22 = (unsigned short)*v21; + level_cel_block = (unsigned short)*v21; + if ( v22 ) + drawLowerScreen(a1b); + } + a1b -= 24576; + ++sxc; + v21 += 2; + } + while ( sxc < 7 ); + if ( 2 * a6 + 2 < 8 ) + town_draw_low_towners((int)gpBuffer + *v20 + v11, xa, ya, a6, 2 * a6 + 2, v11, sy, 0); + } + else + { + town_clear_low_buf((int)gpBuffer + screen_y_times_768[v8] + v11); + } + } +} +// 69CF14: using guessed type int level_cel_block; + +//----- (0045EF8A) -------------------------------------------------------- +void __fastcall town_draw_pieces(void *buffer, int x, int y, int a4, int dir, int sx, int sy) +{ + int v7; // ebx + char *v8; // esi + int v9; // edi + int v10; // eax + int v11; // eax + void *buffera; // [esp+Ch] [ebp-8h] + int *a1; // [esp+10h] [ebp-4h] + + v7 = x; + buffera = buffer; + a1 = (int *)buffer; + v8 = (char *)dpiece_defs_map_1 + 32 * gendung_41927A(x, y); + v9 = 0; + do + { + if ( a4 >= v9 ) + { + v10 = *(unsigned short *)&v8[4 * v9]; + level_cel_block = *(unsigned short *)&v8[4 * v9]; + if ( v10 ) + drawUpperScreen(a1); + v11 = *(unsigned short *)&v8[4 * v9 + 2]; + level_cel_block = *(unsigned short *)&v8[4 * v9 + 2]; + if ( v11 ) + drawUpperScreen(a1 + 8); + } + a1 -= 6144; + ++v9; + } + while ( v9 < 7 ); + town_draw_towners(buffera, v7, y, a4, dir, sx, sy, 0); +} +// 69CF14: using guessed type int level_cel_block; + +//----- (0045F013) -------------------------------------------------------- +void __fastcall town_draw_towners(void *buffer, int x, int y, int a4, int dir, int sx, int sy, int some_flag) +{ + unsigned int v8; // edx + int v9; // ebx + char v10; // al + char v11; // al + int v12; // esi + int v13; // edi + int v14; // esi + int v15; // edi + int v16; // eax + int v17; // eax + int v18; // esi + int v19; // edi + char v20; // al + int v21; // esi + int v22; // ebx + int v23; // edi + char v24; // al + char v25; // al + int v26; // esi + int v27; // ebx + int v28; // edi + char *v29; // [esp+Ch] [ebp-Ch] + int xa; // [esp+10h] [ebp-8h] + int v31; // [esp+14h] [ebp-4h] + + xa = x; + v8 = 112 * x; + v9 = v8 + y; + v29 = (char *)buffer; + v31 = v8 + y; + v10 = dItem[v8 / 0x70][y]; + if ( v10 ) + { + v11 = v10 - 1; + v12 = v11; + v13 = sx - items[v12]._iAnimXOff; + if ( v11 == pcursitem ) + Cel_colour( + 181, + v13, + sy, + (char *)items[v12].ItemFrame, + items[v12]._iAnimFrame, + items[v12]._iAnimWidth, + 0, + dir); + Cel_header(v13, sy, (char *)items[v12].ItemFrame, items[v12]._iAnimFrame, items[v12]._iAnimWidth, 0, dir); + } + if ( dFlags[0][v9] & 0x10 ) + { + v14 = -1 - *(&dword_52D204 + v9); + v15 = sx - towner[v14]._tAnimWidth2; + if ( -1 - *(&dword_52D204 + v9) == *(_DWORD *)&pcursmonst ) + Cel_colour( + 166, + v15, + sy, + (char *)towner[v14]._tAnimCel, + towner[v14]._tAnimFrame, + towner[v14]._tAnimWidth, + 0, + dir); + Cel_header(v15, sy, (char *)towner[v14]._tAnimCel, towner[v14]._tAnimFrame, towner[v14]._tAnimWidth, 0, dir); + } + v16 = dMonster[0][v9]; + if ( v16 > 0 ) + { + v17 = v16 - 1; + v18 = v17; + v19 = sx - towner[v17]._tAnimWidth2; + if ( v17 == *(_DWORD *)&pcursmonst ) + Cel_colour( + 166, + v19, + sy, + (char *)towner[v18]._tAnimCel, + towner[v18]._tAnimFrame, + towner[v18]._tAnimWidth, + 0, + dir); + Cel_header(v19, sy, (char *)towner[v18]._tAnimCel, towner[v18]._tAnimFrame, towner[v18]._tAnimWidth, 0, dir); + } + if ( dFlags[0][v9] & 0x20 ) + { + v20 = -1 - *((_BYTE *)&themeLoc[49].height + v9 + 3); + v21 = v20; + v22 = sy + plr[v21]._pyoff; + v23 = sx + plr[v21]._pxoff - plr[v21]._pAnimWidth2; + if ( v20 == pcursplr ) + engine_417847( + 165, + v23, + v22, + (void *)plr[v21]._pAnimData, + plr[v21]._pAnimFrame, + plr[v21]._pAnimWidth, + 0, + dir); + engine_417745(v23, v22, (void *)plr[v21]._pAnimData, plr[v21]._pAnimFrame, plr[v21]._pAnimWidth, 0, dir); + if ( some_flag && plr[v21]._peflag ) + town_draw_pieces(v29 - 64, xa - 1, y + 1, a4, dir, sx - 64, sy); + v9 = v31; + } + if ( dFlags[0][v9] & 4 ) + scrollrt_452CC0(xa, y, sx, sy, 0, dir, 0); + v24 = dPlayer[0][v9]; + if ( v24 > 0 ) + { + v25 = v24 - 1; + v26 = v25; + v27 = sy + plr[v26]._pyoff; + v28 = sx + plr[v26]._pxoff - plr[v26]._pAnimWidth2; + if ( v25 == pcursplr ) + engine_417847( + 165, + v28, + v27, + (void *)plr[v26]._pAnimData, + plr[v26]._pAnimFrame, + plr[v26]._pAnimWidth, + 0, + dir); + engine_417745(v28, v27, (void *)plr[v26]._pAnimData, plr[v26]._pAnimFrame, plr[v26]._pAnimWidth, 0, dir); + if ( some_flag && plr[v26]._peflag ) + town_draw_pieces(v29 - 64, xa - 1, y + 1, a4, dir, sx - 64, sy); + v9 = v31; + } + if ( dFlags[0][v9] & 1 ) + scrollrt_452994(xa, y, sx, sy, 0, dir, 0); +} +// 4B8CC0: using guessed type char pcursitem; +// 4B8CC2: using guessed type char pcursplr; + +//----- (0045F323) -------------------------------------------------------- +void __fastcall town_draw_screen(int x, int y, int sx, int sy, int a5, int a6, int some_flag) +{ + signed int v7; // ebx + int v8; // esi + int v9; // eax + bool v10; // zf + int v11; // eax + short *v12; // ebx + int v13; // eax + int v14; // esi + int v15; // edi + int v16; // eax + Screen *v17; // eax + char *v18; // ebx + char *v19; // edi + int v20; // eax + int v21; // eax + int v22; // eax + int v23; // eax + char *v24; // edi + char *v25; // ebx + int v26; // eax + int *a1; // [esp+Ch] [ebp-10h] + int *a1a; // [esp+Ch] [ebp-10h] + int dir; // [esp+10h] [ebp-Ch] + int ya; // [esp+14h] [ebp-8h] + signed int xa; // [esp+18h] [ebp-4h] + signed int sxa; // [esp+24h] [ebp+8h] + signed int sxb; // [esp+24h] [ebp+8h] + signed int sxc; // [esp+24h] [ebp+8h] + int a5a; // [esp+2Ch] [ebp+10h] + + xa = x; + v7 = y; + ya = y; + dir = 2 * a6 + 2; + if ( dir > 8 ) + dir = 8; + if ( some_flag ) + { + if ( y < 0 || y >= 112 || x < 0 || x >= 112 ) + { + v11 = sy; + v8 = sx; + } + else + { + v8 = sx; + v9 = dPiece[0][y + 112 * x]; + level_cel_block = v9; + v10 = v9 == 0; + v11 = sy; + if ( !v10 ) + { + a1 = (int *)&gpBuffer->row_unused_1[0].col_unused_1[sx + 32 + screen_y_times_768[sy]]; + sxa = 0; + v12 = &dpiece_defs_map_1[0][0][16 * gendung_41927A(x, y) + 1]; + do + { + if ( a6 >= sxa ) + { + v13 = (unsigned short)*v12; + level_cel_block = (unsigned short)*v12; + if ( v13 ) + drawUpperScreen(a1); + } + a1 -= 6144; + ++sxa; + v12 += 2; + } + while ( sxa < 7 ); + town_draw_towners((char *)gpBuffer + v8 + screen_y_times_768[sy], xa, ya, a6, dir, v8, sy, 0); + v7 = ya; + goto LABEL_17; + } + } + town_clear_upper_buf((int)gpBuffer + screen_y_times_768[v11] + v8); +LABEL_17: + ++xa; + ya = --v7; + v14 = v8 + 64; + goto LABEL_19; + } + v14 = sx; +LABEL_19: + if ( a5 - some_flag > 0 ) + { + a1a = (int *)(a5 - some_flag); + v15 = 112 * xa; + a5a = 112 * xa; + do + { + if ( v7 < 0 || v7 >= 112 || v15 < 0 || v15 >= 12544 ) + { + v17 = gpBuffer; + } + else + { + v16 = dPiece[0][v15 + v7]; + level_cel_block = v16; + v10 = v16 == 0; + v17 = gpBuffer; + if ( !v10 ) + { + v18 = (char *)gpBuffer + v14 + screen_y_times_768[sy]; + v19 = (char *)dpiece_defs_map_1 + 32 * gendung_41927A(xa, ya); + sxb = 0; + do + { + if ( a6 >= sxb ) + { + v20 = *(unsigned short *)&v19[4 * sxb]; + level_cel_block = *(unsigned short *)&v19[4 * sxb]; + if ( v20 ) + drawUpperScreen(v18); + v21 = *(unsigned short *)&v19[4 * sxb + 2]; + level_cel_block = *(unsigned short *)&v19[4 * sxb + 2]; + if ( v21 ) + drawUpperScreen(v18 + 32); + } + v18 -= 24576; + ++sxb; + } + while ( sxb < 7 ); + town_draw_towners((char *)gpBuffer + v14 + screen_y_times_768[sy], xa, ya, a6, dir, v14, sy, 1); + v15 = a5a; + v7 = ya; + goto LABEL_36; + } + } + town_clear_upper_buf((int)v17 + v14 + screen_y_times_768[sy]); +LABEL_36: + ++xa; + v15 += 112; + --v7; + v14 += 64; + v10 = a1a == (int *)1; + a1a = (int *)((char *)a1a - 1); + a5a = v15; + ya = v7; + } + while ( !v10 ); + } + if ( some_flag ) + { + if ( v7 < 0 || v7 >= 112 || xa < 0 || xa >= 112 ) + { + v23 = sy; + } + else + { + v22 = dPiece[0][v7 + 112 * xa]; + level_cel_block = v22; + v10 = v22 == 0; + v23 = sy; + if ( !v10 ) + { + v24 = (char *)gpBuffer + v14 + screen_y_times_768[sy]; + v25 = (char *)dpiece_defs_map_1 + 32 * gendung_41927A(xa, v7); + sxc = 0; + do + { + if ( a6 >= sxc ) + { + v26 = *(unsigned short *)&v25[4 * sxc]; + level_cel_block = *(unsigned short *)&v25[4 * sxc]; + if ( v26 ) + drawUpperScreen(v24); + } + v24 -= 24576; + ++sxc; + } + while ( sxc < 7 ); + town_draw_towners((char *)gpBuffer + v14 + screen_y_times_768[sy], xa, ya, a6, dir, v14, sy, 0); + return; + } + } + town_clear_upper_buf((int)gpBuffer + screen_y_times_768[v23] + v14); + } +} +// 69CF14: using guessed type int level_cel_block; + +//----- (0045F65D) -------------------------------------------------------- +void __fastcall T_DrawGame(int x, int y) +{ + int v2; // esi + int v3; // edi + int v4; // ebx + int v5; // ebx + int v6; // esi + int v7; // ebx + int v8; // esi + int v9; // ebx + int v10; // esi + signed int v11; // [esp+Ch] [ebp-10h] + signed int a6; // [esp+10h] [ebp-Ch] + signed int a6a; // [esp+10h] [ebp-Ch] + signed int a5; // [esp+14h] [ebp-8h] + int ya; // [esp+18h] [ebp-4h] + + v2 = ScrollInfo._sxoff + 64; + v3 = x - 10; + ya = y - 1; + v4 = ScrollInfo._syoff + 175; + dword_5C2FF8 = 10; + a5 = 10; + scr_pix_width = 640; + scr_pix_height = 352; + dword_5C2FFC = 11; + v11 = 5; + if ( chrflag || questlog ) + { + ya = y - 3; + v3 += 2; + v2 = ScrollInfo._sxoff + 352; + a5 = 6; + } + if ( invflag || sbookflag ) + { + ya -= 2; + v3 += 2; + v2 -= 32; + a5 = 6; + } + switch ( ScrollInfo._sdir ) + { + case DIR_SW: + v4 = ScrollInfo._syoff + 143; + --v3; + --ya; + goto LABEL_15; + case DIR_W: + v4 = ScrollInfo._syoff + 143; + --v3; + --ya; + goto LABEL_14; + case DIR_NW: + goto LABEL_12; + case DIR_N: + goto LABEL_14; + case DIR_NE: + goto LABEL_15; + case DIR_E: + v2 -= 64; + --v3; + ++ya; + goto LABEL_14; + case DIR_SE: + v2 -= 64; + --v3; + ++ya; +LABEL_12: + ++a5; + break; + case DIR_OMNI: + v2 -= 64; + v4 = ScrollInfo._syoff + 143; + v3 -= 2; +LABEL_14: + ++a5; +LABEL_15: + v11 = 6; + break; + default: + break; + } + a6 = 0; + screen_buf_end = (int)gpBuffer + screen_y_times_768[160]; + do + { + town_draw_screen(v3, ya++, v2, v4, a5, a6, 0); + v5 = v4 + 16; + v6 = v2 - 32; + town_draw_screen(v3++, ya, v6, v5, a5, a6, 1); + v2 = v6 + 32; + v4 = v5 + 16; + ++a6; + } + while ( a6 < 7 ); + screen_buf_end = (int)gpBuffer + screen_y_times_768[512]; + if ( v11 > 0 ) + { + do + { + town_draw_low_pieces(v3, ya++, v2, v4, a5, 0); + v7 = v4 + 16; + v8 = v2 - 32; + town_draw_low_pieces(v3++, ya, v8, v7, a5, 1); + v2 = v8 + 32; + v4 = v7 + 16; + --v11; + } + while ( v11 ); + } + a6a = 0; + do + { + town_draw_lower(v3, ya++, v2, v4, a5, a6a, 0); + v9 = v4 + 16; + v10 = v2 - 32; + town_draw_lower(v3++, ya, v10, v9, a5, a6a, 1); + v2 = v10 + 32; + v4 = v9 + 16; + ++a6a; + } + while ( a6a < 7 ); +} +// 4B8968: using guessed type int sbookflag; +// 5C2FF8: using guessed type int dword_5C2FF8; +// 5C2FFC: using guessed type int dword_5C2FFC; +// 5C3000: using guessed type int scr_pix_width; +// 5C3004: using guessed type int scr_pix_height; +// 69BD04: using guessed type int questlog; +// 69CF0C: using guessed type int screen_buf_end; + +//----- (0045F856) -------------------------------------------------------- +void __fastcall T_DrawZoom(int x, int y) +{ + int v2; // edi + int v3; // ebx + int v4; // esi + int v5; // esi + int v6; // edi + int v7; // esi + int v8; // edi + int v9; // esi + int v10; // edi + _WORD *v11; // edi + char *v12; // esi + char *v13; // ebx + signed int v14; // edx + signed int v15; // ecx + short v16; // ax + int v17; // eax + signed int v18; // [esp+Ch] [ebp-10h] + signed int v19; // [esp+Ch] [ebp-10h] + signed int a6; // [esp+10h] [ebp-Ch] + signed int a6a; // [esp+10h] [ebp-Ch] + int a6b; // [esp+10h] [ebp-Ch] + signed int a5; // [esp+14h] [ebp-8h] + int a5a; // [esp+14h] [ebp-8h] + int ya; // [esp+18h] [ebp-4h] + + v18 = 0; + v2 = ScrollInfo._sxoff + 64; + dword_5C2FF8 = 6; + dword_5C2FFC = 6; + v3 = x - 6; + a5 = 6; + v4 = ScrollInfo._syoff + 143; + ya = y - 1; + scr_pix_width = 384; + scr_pix_height = 192; + switch ( ScrollInfo._sdir ) + { + case DIR_SW: + v4 = ScrollInfo._syoff + 111; + v3 = x - 7; + ya = y - 2; + goto LABEL_9; + case DIR_W: + v4 = ScrollInfo._syoff + 111; + v3 = x - 7; + ya = y - 2; + goto LABEL_8; + case DIR_NW: + goto LABEL_6; + case DIR_N: + goto LABEL_8; + case DIR_NE: + goto LABEL_9; + case DIR_E: + v2 = ScrollInfo._sxoff; + v3 = x - 7; + ya = y; + goto LABEL_8; + case DIR_SE: + v2 = ScrollInfo._sxoff; + v3 = x - 7; + ya = y; +LABEL_6: + a5 = 7; + break; + case DIR_OMNI: + v2 = ScrollInfo._sxoff; + v4 = ScrollInfo._syoff + 111; + v3 = x - 8; +LABEL_8: + a5 = 7; +LABEL_9: + v18 = 1; + break; + default: + break; + } + a6 = 0; + screen_buf_end = (int)gpBuffer + screen_y_times_768[143]; + do + { + town_draw_screen(v3, ya++, v2, v4, a5, a6, 0); + v5 = v4 + 16; + v6 = v2 - 32; + town_draw_screen(v3++, ya, v6, v5, a5, a6, 1); + v2 = v6 + 32; + v4 = v5 + 16; + ++a6; + } + while ( a6 < 7 ); + screen_buf_end = (int)gpBuffer + screen_y_times_768[320]; + if ( v18 > 0 ) + { + do + { + town_draw_low_pieces(v3, ya++, v2, v4, a5, 0); + v7 = v4 + 16; + v8 = v2 - 32; + town_draw_low_pieces(v3++, ya, v8, v7, a5, 1); + v2 = v8 + 32; + v4 = v7 + 16; + --v18; + } + while ( v18 ); + } + a6a = 0; + do + { + town_draw_lower(v3, ya++, v2, v4, a5, a6a, 0); + v9 = v4 + 16; + v10 = v2 - 32; + town_draw_lower(v3++, ya, v10, v9, a5, a6a, 1); + v2 = v10 + 32; + v4 = v9 + 16; + ++a6a; + } + while ( a6a < 7 ); + if ( chrflag || questlog ) + { + a5a = 392064; + goto LABEL_23; + } + if ( invflag || sbookflag ) + { + a5a = 391744; +LABEL_23: + a6b = 245168; + v19 = 160; + goto LABEL_24; + } + a6b = 245088; + a5a = 391744; + v19 = 320; +LABEL_24: + v11 = (_WORD *)((char *)gpBuffer + a5a); + v12 = (char *)gpBuffer + a6b; + v13 = &gpBuffer->row_unused_1[1].col_unused_1[a5a]; + v14 = 176; + do + { + v15 = v19; + do + { + _LOBYTE(v16) = *v12++; + _HIBYTE(v16) = v16; + *v11 = v16; + *(_WORD *)v13 = v16; + ++v11; + v13 += 2; + --v15; + } + while ( v15 ); + v12 += -v19 - 768; + v17 = 2 * (v19 + 768); + v13 -= v17; + v11 = (_WORD *)((char *)v11 - v17); + --v14; + } + while ( v14 ); +} +// 4B8968: using guessed type int sbookflag; +// 5C2FF8: using guessed type int dword_5C2FF8; +// 5C2FFC: using guessed type int dword_5C2FFC; +// 5C3000: using guessed type int scr_pix_width; +// 5C3004: using guessed type int scr_pix_height; +// 69BD04: using guessed type int questlog; +// 69CF0C: using guessed type int screen_buf_end; + +//----- (0045FAAB) -------------------------------------------------------- +void __fastcall T_DrawView(int StartX, int StartY) +{ + light_table_index = 0; + cel_transparency_active = 0; + if ( zoomflag ) + T_DrawGame(StartX, StartY); + else + T_DrawZoom(StartX, StartY); + if ( *(_DWORD *)&automapflag ) + DrawAutomap(); + if ( stextflag && !qtextflag ) + DrawSText(); + if ( invflag ) + { + DrawInv(); + } + else if ( sbookflag ) + { + DrawSpellBook(); + } + DrawDurIcon(); + if ( chrflag ) + { + DrawChr(); + } + else if ( questlog ) + { + DrawQuestLog(); + } + else if ( plr[myplr]._pStatPts && !spselflag ) + { + DrawLevelUpIcon(); + } + if ( uitemflag ) + DrawUniqueInfo(); + if ( qtextflag ) + DrawQText(); + if ( spselflag ) + DrawSpellList(); + if ( dropGoldFlag ) + DrawGoldSplit(dropGoldValue); + if ( helpflag ) + DrawHelp(); + if ( msgflag ) + DrawDiabloMsg(); + if ( PauseMode && !*(_DWORD *)&deathflag ) + gmenu_draw_pause(); + DrawPlrMsg(); + gmenu_draw(); + doom_draw(); + DrawInfoBox(); + DrawLifeFlask(); + DrawManaFlask(); +} +// 4B84DC: using guessed type int dropGoldFlag; +// 4B8968: using guessed type int sbookflag; +// 4B8C98: using guessed type int spselflag; +// 52569C: using guessed type int zoomflag; +// 525740: using guessed type int PauseMode; +// 52B9F1: using guessed type char msgflag; +// 646D00: using guessed type char qtextflag; +// 69BD04: using guessed type int questlog; +// 69BEF8: using guessed type int light_table_index; +// 69CF94: using guessed type int cel_transparency_active; +// 6AA705: using guessed type char stextflag; + +//----- (0045FBD7) -------------------------------------------------------- +void __cdecl town_get_draw_size() +{ + int (*v0)[112]; // ebx + int v1; // ebp + int v2; // esi + char *v3; // edi + int v4; // ecx + signed int v5; // eax + int (*v6)[112]; // [esp+10h] [ebp-8h] + int y; // [esp+14h] [ebp-4h] + + y = 0; + v6 = dPiece; + do + { + v0 = v6; + v1 = 0; + do + { + v2 = (*v0)[0]; + v3 = (char *)dpiece_defs_map_1 + 32 * gendung_41927A(v1, y); + if ( v2 ) + { + v4 = 32 * v2 + *(_DWORD *)&dpiece_defs[0].blocks - 32; + v5 = 0; + do + { + *(_WORD *)&v3[2 * v5] = *(_WORD *)(v4 + 2 * ((v5 & 1) - (v5 & 0xE)) + 28); + ++v5; + } + while ( v5 < 16 ); + } + else + { + memset(v3, 0, 0x20u); + } + ++v1; + ++v0; + } + while ( v1 < 112 ); + v6 = (int (*)[112])((char *)v6 + 4); + ++y; + } + while ( (signed int)v6 < (signed int)dPiece[1] ); + if ( zoomflag ) + { + scr_pix_width = 640; + scr_pix_height = 352; + dword_5C2FF8 = 10; + dword_5C2FFC = 11; + } + else + { + scr_pix_width = 384; + scr_pix_height = 224; + dword_5C2FF8 = 6; + dword_5C2FFC = 7; + } +} +// 52569C: using guessed type int zoomflag; +// 5C2FF8: using guessed type int dword_5C2FF8; +// 5C2FFC: using guessed type int dword_5C2FFC; +// 5C3000: using guessed type int scr_pix_width; +// 5C3004: using guessed type int scr_pix_height; + +//----- (0045FCBF) -------------------------------------------------------- +void __fastcall T_FillSector(unsigned char *P3Tiles, unsigned char *pSector, int xi, int yi, int w, int h, int AddSec) +{ + int v7; // ebx + int v8; // edx + int v9; // edi + int *v10; // ecx + int v11; // eax + unsigned char *v12; // esi + unsigned short v13; // ax + int v14; // eax + int v15; // [esp+4h] [ebp-14h] + int v16; // [esp+8h] [ebp-10h] + unsigned char *v17; // [esp+Ch] [ebp-Ch] + unsigned char *v18; // [esp+10h] [ebp-8h] + signed int v19; // [esp+14h] [ebp-4h] + int a4; // [esp+24h] [ebp+Ch] + int a6; // [esp+2Ch] [ebp+14h] + + v7 = h; + v17 = pSector; + v8 = yi; + v18 = P3Tiles; + v19 = 4; + if ( h > 0 ) + { + do + { + v9 = w; + if ( w > 0 ) + { + v10 = &dPiece[1][v8 + 112 * xi]; + do + { + v11 = *(unsigned short *)&v17[v19]; + if ( (_WORD)v11 ) + { + v12 = &v18[8 * (v11 - 1)]; + v13 = *(_WORD *)v12; + v12 += 2; + v14 = v13 + 1; + a4 = v14; + _LOWORD(v14) = *(_WORD *)v12; + v12 += 2; + a6 = ++v14; + _LOWORD(v14) = *(_WORD *)v12; + v16 = ++v14; + _LOWORD(v14) = *((_WORD *)v12 + 1); + v15 = v14 + 1; + } + else + { + a4 = 0; + a6 = 0; + v16 = 0; + v15 = 0; + } + v19 += 2; + *(v10 - 112) = a4; + *v10 = a6; + *(v10 - 111) = v16; + v10[1] = v15; + v10 += 224; + --v9; + } + while ( v9 ); + } + v8 += 2; + --v7; + } + while ( v7 ); + } +} + +//----- (0045FD75) -------------------------------------------------------- +void __fastcall T_FillTile(unsigned char *P3Tiles, int xx, int yy, int t) +{ + unsigned char *v4; // esi + unsigned short v5; // ax + int v6; // eax + int v7; // ST10_4 + int v8; // ST0C_4 + int v9; // ST08_4 + int v10; // edx + + v4 = &P3Tiles[8 * (t - 1)]; + v5 = *(_WORD *)v4; + v4 += 2; + v6 = v5 + 1; + v7 = v6; + _LOWORD(v6) = *(_WORD *)v4; + v4 += 2; + v8 = ++v6; + _LOWORD(v6) = *(_WORD *)v4; + v9 = ++v6; + _LOWORD(v6) = *((_WORD *)v4 + 1); + v10 = yy + 112 * xx; + dPiece[0][v10] = v7; + dPiece[1][v10] = v8; + dPiece[0][v10 + 1] = v9; + dPiece[1][v10 + 1] = v6 + 1; +} + +//----- (0045FDE6) -------------------------------------------------------- +void __cdecl T_Pass3() +{ + int v0; // edi + int *v1; // esi + int *v2; // eax + signed int v3; // ecx + int v4; // ST10_4 + unsigned char *v5; // esi + unsigned char *v6; // edi + unsigned char *v7; // edi + unsigned char *v8; // edi + unsigned char *v9; // edi + int v10; // eax + int v11; // ecx + unsigned char *v12; // ecx + int v13; // edi + int v14; // eax + void *v15; // ecx + int v16; // [esp-10h] [ebp-14h] + int v17; // [esp-Ch] [ebp-10h] + int v18; // [esp-8h] [ebp-Ch] + + v1 = dPiece[1]; + do + { + v2 = v1; + v3 = 56; + do + { + *(v2 - 112) = 0; + *v2 = 0; + *(v2 - 111) = 0; + v2[1] = 0; + v2 += 224; + --v3; + } + while ( v3 ); + v1 += 2; + } + while ( (signed int)v1 < (signed int)dPiece[2] ); + v4 = v0; + v5 = LoadFileInMem("Levels\\TownData\\Town.TIL", 0); + v6 = LoadFileInMem("Levels\\TownData\\Sector1s.DUN", 0); + T_FillSector(v5, v6, 46, 46, 25, 25, v4); + mem_free_dbg(v6); + v7 = LoadFileInMem("Levels\\TownData\\Sector2s.DUN", 0); + T_FillSector(v5, v7, 46, 0, 25, 23, v16); + mem_free_dbg(v7); + v8 = LoadFileInMem("Levels\\TownData\\Sector3s.DUN", 0); + T_FillSector(v5, v8, 0, 46, 23, 25, v17); + mem_free_dbg(v8); + v9 = LoadFileInMem("Levels\\TownData\\Sector4s.DUN", 0); + T_FillSector(v5, v9, 0, 0, 23, 23, v18); + mem_free_dbg(v9); + if ( gbMaxPlayers == 1 ) + { + v10 = myplr; + if ( !(plr[myplr].pTownWarps & 1) ) + { + T_FillTile(v5, 48, 20, 320); + v10 = myplr; + } + v11 = 21720 * v10; + if ( !(plr[v10].pTownWarps & 2) ) + { + T_FillTile(v5, 16, 68, 332); + T_FillTile(v12, 16, 70, 331); + v10 = myplr; + } + if ( !(plr[v10].pTownWarps & 4) ) + { + v13 = 36; + do + { + _LOBYTE(v11) = 0; + v14 = random(v11, 4); + T_FillTile(v5, v13++, 78, v14 + 1); + } + while ( v13 < 46 ); + } + } + if ( quests[13]._qactive != 3 && quests[13]._qactive ) + T_FillTile(v5, 60, 70, 342); + else + T_FillTile(v5, 60, 70, 71); + mem_free_dbg(v15); +} +// 45FDE6: could not find valid save-restore pair for edi +// 679660: using guessed type char gbMaxPlayers; + +//----- (0045FF83) -------------------------------------------------------- +void __fastcall CreateTown(int entry) +{ + int v1; // edi + int (*v2)[112]; // esi + _BYTE *v3; // eax + int (*v4)[112]; // edx + signed int v5; // ebp + int v6; // ecx + + v1 = 0; + dminx = 10; + dminy = 10; + dmaxx = 84; + dmaxy = 84; + if ( entry ) + { + if ( entry == 1 ) + { + ViewX = 25; + ViewY = 31; + } + else if ( entry == 7 ) + { + if ( TWarpFrom == 5 ) + { + ViewX = 49; + ViewY = 22; + } + if ( TWarpFrom == 9 ) + { + ViewX = 18; + ViewY = 69; + } + if ( TWarpFrom == 13 ) + { + ViewX = 41; + ViewY = 81; + } + } + } + else + { + ViewX = 75; + ViewY = 68; + } + T_Pass3(); + memset(dTransVal, 0, 0x3100u); + memset(dFlags, 0, 0x3100u); + memset(dPlayer, 0, 0x3100u); + memset(dMonster, 0, 0xC400u); + memset(dObject, 0, 0x3100u); + memset(dItem, 0, 0x3100u); + memset(dArch, 0, 0x3100u); + v2 = dPiece; + do + { + v3 = (unsigned char *)dArch + v1; + v4 = v2; + v5 = 112; + do + { + v6 = (*v4)[0]; + if ( (*v4)[0] == 360 ) + { + *v3 = 1; + } + else + { + switch ( v6 ) + { + case 358: + *v3 = 2; + break; + case 129: + *v3 = 6; + break; + case 130: + *v3 = 7; + break; + case 128: + *v3 = 8; + break; + case 117: + *v3 = 9; + break; + case 157: + *v3 = 10; + break; + case 158: + *v3 = 11; + break; + case 156: + *v3 = 12; + break; + case 162: + *v3 = 13; + break; + case 160: + *v3 = 14; + break; + case 214: + *v3 = 15; + break; + case 212: + *v3 = 16; + break; + case 217: + *v3 = 17; + break; + case 216: + *v3 = 18; + break; + } + } + ++v4; + v3 += 112; + --v5; + } + while ( v5 ); + v2 = (int (*)[112])((char *)v2 + 4); + ++v1; + } + while ( (signed int)v2 < (signed int)dPiece[1] ); + town_get_draw_size(); +} +// 5CF328: using guessed type int dmaxx; +// 5CF32C: using guessed type int dmaxy; +// 5D2458: using guessed type int dminx; +// 5D245C: using guessed type int dminy; +// 6ABB30: using guessed type int TWarpFrom; + +//----- (0046019B) -------------------------------------------------------- +int __fastcall GetActiveTowner(int towner_id) +{ + int result; // eax + int *v2; // esi + + result = 0; + if ( numtowners <= 0 ) + return -1; + v2 = &towner[0]._ttype; + while ( *v2 != towner_id ) + { + ++result; + v2 += 58; + if ( result >= numtowners ) + return -1; + } + return result; +} + +//----- (004601C1) -------------------------------------------------------- +void __fastcall SetTownerGPtrs(void *towner_cel, void **cel_from_direction) +{ + void **v2; // esi + signed int v3; // edx + char *v4; // eax + signed int v5; // [esp+Ch] [ebp-4h] + + v5 = 0; + v2 = cel_from_direction; + do + { + v3 = v5; + v4 = (char *)towner_cel + *((_DWORD *)towner_cel + v5++); + v2[v3] = v4; + } + while ( v5 < 8 ); +} + +//----- (004601FB) -------------------------------------------------------- +void __fastcall NewTownerAnim(int tnum, void *pAnim, int numFrames, int Delay) +{ + int v4; // ecx + + v4 = tnum; + towner[v4]._tAnimCnt = 0; + towner[v4]._tAnimLen = numFrames; + towner[v4]._tAnimCel = pAnim; + towner[v4]._tAnimFrame = 1; + towner[v4]._tAnimDelay = Delay; +} + +//----- (0046022F) -------------------------------------------------------- +void __fastcall InitTownerInfo(int i, int w, bool sel, int t, int x, int y, int ao, int tp) +{ + int v8; // ebx + int v9; // esi + int v10; // edi + + v8 = i; + v9 = i; + v10 = w; + memset(&towner[i], 0, 0xE8u); + towner[v9]._tSelFlag = sel; + towner[v9]._ttype = t; + towner[v9]._tx = x; + towner[v9]._tMsgSaid = 0; + towner[v9]._tAnimWidth = v10; + towner[v9]._tAnimWidth2 = (v10 - 64) >> 1; + towner[v9]._ty = y; + dMonster[0][y + 112 * x] = v8 + 1; + _LOBYTE(towner[v9]._tAnimOrder) = ao; + towner[v9]._tTenPer = tp; + towner[v9]._tSeed = GetRndSeed(); +} + +//----- (004602C4) -------------------------------------------------------- +void __fastcall InitQstSnds(int towner_num) +{ + int v1; // eax + _BYTE *v2; // ecx + char *v3; // esi + QuestTalkData *v4; // eax + bool v5; // zf + + v1 = towner_num; + if ( boyloadflag ) + v1 = towner_num + 1; + v2 = (unsigned char *)&towner[towner_num].qsts[0]._qstmsgact; + v3 = &quests[0]._qtype; + v4 = &Qtalklist[v1]; + do + { + v5 = v4->_qinfra == -1; + *(v2 - 2) = *v3; + *(v2 - 1) = v4->_qinfra; + *v2 = !v5; + v3 += 24; + v4 = (QuestTalkData *)((char *)v4 + 4); + v2 += 3; + } + while ( (signed int)v3 < (signed int)&qline + 1 ); +} +// 69BE90: using guessed type int qline; +// 6AAC2C: using guessed type int boyloadflag; + +//----- (00460311) -------------------------------------------------------- +void __cdecl InitSmith() +{ + int v0; // esi + int v1; // esi + _DWORD *v2; // eax + signed int v3; // ecx + int v4; // ecx + + InitTownerInfo(numtowners, 96, 1, 0, 62, 63, 0, 10); + v0 = numtowners; + InitQstSnds(numtowners); + v1 = v0; + towner[v1]._tNData = (char *)LoadFileInMem("Towners\\Smith\\SmithN.CEL", 0); + v2 = (unsigned int *)towner[v1]._tNAnim; + v3 = 8; + do + { + *v2 = (unsigned int)towner[v1]._tNData; + ++v2; + --v3; + } + while ( v3 ); + v4 = numtowners; + towner[v1]._tNFrames = 16; + NewTownerAnim(v4, (void *)towner[v1]._tNAnim[1], 16, 3); + strcpy(towner[v1]._tName, "Griswold the Blacksmith"); + ++numtowners; +} + +//----- (004603A0) -------------------------------------------------------- +void __cdecl InitBarOwner() +{ + int v0; // esi + int v1; // esi + _DWORD *v2; // eax + signed int v3; // ecx + int v4; // ecx + + unused_6AAC28 = 0; + InitTownerInfo(numtowners, 96, 1, 3, 55, 62, 3, 10); + v0 = numtowners; + InitQstSnds(numtowners); + v1 = v0; + towner[v1]._tNData = (char *)LoadFileInMem("Towners\\TwnF\\TwnFN.CEL", 0); + v2 = (unsigned int *)towner[v1]._tNAnim; + v3 = 8; + do + { + *v2 = (unsigned int)towner[v1]._tNData; + ++v2; + --v3; + } + while ( v3 ); + v4 = numtowners; + towner[v1]._tNFrames = 16; + NewTownerAnim(v4, (void *)towner[v1]._tNAnim[1], 16, 3); + strcpy(towner[v1]._tName, "Ogden the Tavern owner"); + ++numtowners; +} +// 6AAC28: using guessed type int unused_6AAC28; + +//----- (00460436) -------------------------------------------------------- +void __cdecl InitTownDead() +{ + int v0; // esi + int v1; // esi + _DWORD *v2; // eax + signed int v3; // ecx + int v4; // ecx + + InitTownerInfo(numtowners, 96, 1, 2, 24, 32, -1, 10); + v0 = numtowners; + InitQstSnds(numtowners); + v1 = v0; + towner[v1]._tNData = (char *)LoadFileInMem("Towners\\Butch\\Deadguy.CEL", 0); + v2 = (unsigned int *)towner[v1]._tNAnim; + v3 = 8; + do + { + *v2 = (unsigned int)towner[v1]._tNData; + ++v2; + --v3; + } + while ( v3 ); + v4 = numtowners; + towner[v1]._tNFrames = 8; + NewTownerAnim(v4, (void *)towner[v1]._tNAnim[4], 8, 6); + strcpy(towner[v1]._tName, "Wounded Townsman"); + ++numtowners; +} + +//----- (004604C6) -------------------------------------------------------- +void __cdecl InitWitch() +{ + int v0; // esi + int v1; // esi + _DWORD *v2; // ecx + signed int v3; // edx + + InitTownerInfo(numtowners, 96, 1, 6, 80, 20, 5, 10); + v0 = numtowners; + InitQstSnds(numtowners); + v1 = v0; + towner[v1]._tNData = (char *)LoadFileInMem("Towners\\TownWmn1\\Witch.CEL", 0); + v2 = (unsigned int *)towner[v1]._tNAnim; + v3 = 8; + do + { + *v2 = (unsigned int)towner[v1]._tNData; + ++v2; + --v3; + } + while ( v3 ); + towner[v1]._tNFrames = 19; + NewTownerAnim(numtowners, (void *)towner[v1]._tNAnim[0], 19, 6); + strcpy(towner[v1]._tName, "Adria the Witch"); + ++numtowners; +} + +//----- (00460555) -------------------------------------------------------- +void __cdecl InitBarmaid() +{ + int v0; // esi + int v1; // esi + _DWORD *v2; // ecx + signed int v3; // edx + + InitTownerInfo(numtowners, 96, 1, 7, 43, 66, -1, 10); + v0 = numtowners; + InitQstSnds(numtowners); + v1 = v0; + towner[v1]._tNData = (char *)LoadFileInMem("Towners\\TownWmn1\\WmnN.CEL", 0); + v2 = (unsigned int *)towner[v1]._tNAnim; + v3 = 8; + do + { + *v2 = (unsigned int)towner[v1]._tNData; + ++v2; + --v3; + } + while ( v3 ); + towner[v1]._tNFrames = 18; + NewTownerAnim(numtowners, (void *)towner[v1]._tNAnim[0], 18, 6); + strcpy(towner[v1]._tName, "Gillian the Barmaid"); + ++numtowners; +} + +//----- (004605E4) -------------------------------------------------------- +void __cdecl InitBoy() +{ + int v0; // esi + int v1; // esi + _DWORD *v2; // ecx + signed int v3; // edx + + boyloadflag = 1; + InitTownerInfo(numtowners, 96, 1, 8, 11, 53, -1, 10); + v0 = numtowners; + InitQstSnds(numtowners); + v1 = v0; + towner[v1]._tNData = (char *)LoadFileInMem("Towners\\TownBoy\\PegKid1.CEL", 0); + v2 = (unsigned int *)towner[v1]._tNAnim; + v3 = 8; + do + { + *v2 = (unsigned int)towner[v1]._tNData; + ++v2; + --v3; + } + while ( v3 ); + towner[v1]._tNFrames = 20; + NewTownerAnim(numtowners, (void *)towner[v1]._tNAnim[0], 20, 6); + strcpy(towner[v1]._tName, "Wirt the Peg-legged boy"); + ++numtowners; +} +// 6AAC2C: using guessed type int boyloadflag; + +//----- (0046067A) -------------------------------------------------------- +void __cdecl InitHealer() +{ + int v0; // esi + int v1; // esi + _DWORD *v2; // eax + signed int v3; // ecx + int v4; // ecx + + InitTownerInfo(numtowners, 96, 1, 1, 55, 79, 1, 10); + v0 = numtowners; + InitQstSnds(numtowners); + v1 = v0; + towner[v1]._tNData = (char *)LoadFileInMem("Towners\\Healer\\Healer.CEL", 0); + v2 = (unsigned int *)towner[v1]._tNAnim; + v3 = 8; + do + { + *v2 = (unsigned int)towner[v1]._tNData; + ++v2; + --v3; + } + while ( v3 ); + v4 = numtowners; + towner[v1]._tNFrames = 20; + NewTownerAnim(v4, (void *)towner[v1]._tNAnim[7], 20, 6); + strcpy(towner[v1]._tName, "Pepin the Healer"); + ++numtowners; +} + +//----- (00460709) -------------------------------------------------------- +void __cdecl InitTeller() +{ + int v0; // esi + int v1; // esi + _DWORD *v2; // ecx + signed int v3; // edx + + InitTownerInfo(numtowners, 96, 1, 4, 62, 71, 2, 10); + v0 = numtowners; + InitQstSnds(numtowners); + v1 = v0; + towner[v1]._tNData = (char *)LoadFileInMem("Towners\\Strytell\\Strytell.CEL", 0); + v2 = (unsigned int *)towner[v1]._tNAnim; + v3 = 8; + do + { + *v2 = (unsigned int)towner[v1]._tNData; + ++v2; + --v3; + } + while ( v3 ); + towner[v1]._tNFrames = 25; + NewTownerAnim(numtowners, (void *)towner[v1]._tNAnim[0], 25, 3); + strcpy(towner[v1]._tName, "Cain the Elder"); + ++numtowners; +} + +//----- (00460798) -------------------------------------------------------- +void __cdecl InitDrunk() +{ + int v0; // esi + int v1; // esi + _DWORD *v2; // ecx + signed int v3; // edx + + InitTownerInfo(numtowners, 96, 1, 5, 71, 84, 4, 10); + v0 = numtowners; + InitQstSnds(numtowners); + v1 = v0; + towner[v1]._tNData = (char *)LoadFileInMem("Towners\\Drunk\\TwnDrunk.CEL", 0); + v2 = (unsigned int *)towner[v1]._tNAnim; + v3 = 8; + do + { + *v2 = (unsigned int)towner[v1]._tNData; + ++v2; + --v3; + } + while ( v3 ); + towner[v1]._tNFrames = 18; + NewTownerAnim(numtowners, (void *)towner[v1]._tNAnim[0], 18, 3); + strcpy(towner[v1]._tName, "Farnham the Drunk"); + ++numtowners; +} + +//----- (00460827) -------------------------------------------------------- +void __cdecl InitCows() +{ + unsigned char *v0; // eax + int v1; // ecx + signed int v2; // ebx + int v3; // esi + int v4; // ebp + int v5; // eax + void **v6; // ecx + int v7; // edi + int v8; // ecx + int v9; // edx + int v10; // eax + int v11; // ecx + _DWORD *v12; // esi + int v13; // edx + _DWORD *v14; // esi + _DWORD *v15; // eax + int v16; // [esp+10h] [ebp-4h] + + v0 = LoadFileInMem("Towners\\Animals\\Cow.CEL", 0); + v1 = numtowners; + pCowCels = v0; + v2 = 0; + do + { + v3 = TownCowX[v2]; + v4 = TownCowDir[v2]; + v16 = TownCowY[v2]; + InitTownerInfo(v1, 128, 0, 9, TownCowX[v2], v16, -1, 10); + v5 = numtowners; + v6 = (void **)&towner[numtowners]._tNData; + *v6 = pCowCels; + SetTownerGPtrs(*v6, (void **)towner[v5]._tNAnim); + v7 = numtowners; + towner[numtowners]._tNFrames = 12; + NewTownerAnim(v7, (void *)towner[0]._tNAnim[v4 + 58 * v7], 12, 3); + v7 *= 232; + _LOBYTE(v8) = 0; + *(int *)((char *)&towner[0]._tAnimFrame + v7) = random(v8, 11) + 1; + *(int *)((char *)&towner[0]._tSelFlag + v7) = 1; + strcpy(&towner[0]._tName[v7], "Cow"); + v9 = v3 + cowoffx[v4]; + v10 = v16 + cowoffy[v4]; + v11 = numtowners; + v12 = (_DWORD *)((char *)dMonster + 4 * (v10 + 112 * v3)); + if ( !*v12 ) + *v12 = -1 - numtowners; + v13 = 112 * v9; + v14 = (_DWORD *)((char *)dMonster + 4 * (v13 + v16)); + if ( !*v14 ) + *v14 = -1 - v11; + v15 = (_DWORD *)((char *)dMonster + 4 * (v10 + v13)); + if ( !*v15 ) + *v15 = -1 - v11; + ++v2; + v1 = v11 + 1; + numtowners = v1; + } + while ( v2 < 3 ); +} +// 6AAC2C: using guessed type int boyloadflag; + +//----- (00460976) -------------------------------------------------------- +void __cdecl InitTowners() +{ + numtowners = 0; + boyloadflag = 0; + InitSmith(); + InitHealer(); + if ( quests[6]._qactive && quests[6]._qactive != 3 ) + InitTownDead(); + InitBarOwner(); + InitTeller(); + InitDrunk(); + InitWitch(); + InitBarmaid(); + InitBoy(); + InitCows(); +} +// 6AAC2C: using guessed type int boyloadflag; + +//----- (004609C3) -------------------------------------------------------- +void __cdecl FreeTownerGFX() +{ + void **v0; // esi + void *v1; // ecx + void *v2; // ecx + + v0 = (void **)&towner[0]._tNData; + do + { + v1 = *v0; + if ( *v0 == pCowCels ) + { + *v0 = 0; + } + else if ( v1 ) + { + *v0 = 0; + mem_free_dbg(v1); + } + v0 += 58; + } + while ( (signed int)v0 < (signed int)&dword_6ABB9C ); + v2 = pCowCels; + pCowCels = 0; + mem_free_dbg(v2); +} +// 6ABB9C: using guessed type int dword_6ABB9C; + +//----- (00460A05) -------------------------------------------------------- +void __fastcall TownCtrlMsg(int towner_num) +{ + int v1; // esi + int v2; // edi + int v3; // ebx + int v4; // eax + + v1 = towner_num; + if ( towner[towner_num]._tbtcnt ) + { + v2 = towner[v1]._tVar1; + v3 = abs(towner[v1]._tx - plr[v2].WorldX); + v4 = abs(towner[v1]._ty - plr[v2].WorldY); + if ( v3 >= 2 || v4 >= 2 ) + towner[v1]._tbtcnt = 0; + if ( !towner[v1]._tbtcnt ) + { + qtextflag = 0; + sfx_stop(); + } + } +} +// 646D00: using guessed type char qtextflag; + +//----- (00460A78) -------------------------------------------------------- +void __cdecl TownBlackSmith() +{ + int v0; // eax + + v0 = GetActiveTowner(0); + TownCtrlMsg(v0); +} + +//----- (00460A86) -------------------------------------------------------- +void __cdecl TownBarOwner() +{ + int v0; // eax + + v0 = GetActiveTowner(TOWN_TAVERN); + TownCtrlMsg(v0); +} + +//----- (00460A95) -------------------------------------------------------- +void __cdecl TownDead() +{ + int v0; // esi + int v1; // eax + + v0 = GetActiveTowner(TOWN_DEADGUY); + TownCtrlMsg(v0); + if ( qtextflag ) + goto LABEL_6; + if ( (quests[6]._qactive != 2 || quests[6]._qlog) && quests[6]._qactive != 1 ) + { + v1 = v0; + towner[v1]._tAnimDelay = 1000; + towner[v1]._tAnimFrame = 1; + strcpy(towner[v0]._tName, "Slain Townsman"); +LABEL_6: + if ( quests[6]._qactive != 1 ) + towner[v0]._tAnimCnt = 0; + } +} +// 646D00: using guessed type char qtextflag; + +//----- (00460B0D) -------------------------------------------------------- +void __cdecl TownHealer() +{ + int v0; // eax + + v0 = GetActiveTowner(1); + TownCtrlMsg(v0); +} + +//----- (00460B1C) -------------------------------------------------------- +void __cdecl TownStory() +{ + int v0; // eax + + v0 = GetActiveTowner(TOWN_STORY); + TownCtrlMsg(v0); +} + +//----- (00460B2B) -------------------------------------------------------- +void __cdecl TownDrunk() +{ + int v0; // eax + + v0 = GetActiveTowner(TOWN_DRUNK); + TownCtrlMsg(v0); +} + +//----- (00460B3A) -------------------------------------------------------- +void __cdecl TownBoy() +{ + int v0; // eax + + v0 = GetActiveTowner(TOWN_PEGBOY); + TownCtrlMsg(v0); +} + +//----- (00460B49) -------------------------------------------------------- +void __cdecl TownWitch() +{ + int v0; // eax + + v0 = GetActiveTowner(TOWN_WITCH); + TownCtrlMsg(v0); +} + +//----- (00460B58) -------------------------------------------------------- +void __cdecl TownBarMaid() +{ + int v0; // eax + + v0 = GetActiveTowner(TOWN_BMAID); + TownCtrlMsg(v0); +} + +//----- (00460B67) -------------------------------------------------------- +void __cdecl TownCow() +{ + int v0; // eax + + v0 = GetActiveTowner(TOWN_COW); + TownCtrlMsg(v0); +} + +//----- (00460B76) -------------------------------------------------------- +void __cdecl ProcessTowners() +{ + int *v0; // esi + char v1; // al + int v2; // ecx + _DWORD *v3; // eax + + v0 = &towner[0]._tAnimCnt; + do + { + switch ( *(v0 - 10) ) + { + case TOWN_SMITH: + TownBlackSmith(); + break; + case TOWN_HEALER: + TownHealer(); + break; + case TOWN_DEADGUY: + TownDead(); + break; + case TOWN_TAVERN: + TownBarOwner(); + break; + case TOWN_STORY: + TownStory(); + break; + case TOWN_DRUNK: + TownDrunk(); + break; + case TOWN_WITCH: + TownWitch(); + break; + case TOWN_BMAID: + TownBarMaid(); + break; + case TOWN_PEGBOY: + TownBoy(); + break; + case TOWN_COW: + TownCow(); + break; + default: + break; + } + if ( ++*v0 >= *(v0 - 1) ) + { + v1 = *((_BYTE *)v0 + 16); + *v0 = 0; + if ( v1 < 0 ) + { + if ( ++v0[2] > v0[1] ) + v0[2] = 1; + } + else + { + v2 = 148 * v1; + v3 = (unsigned int *)v0 + 3; + ++*v3; + if ( AnimOrder[0][v0[3] + v2] == -1 ) + *v3 = 0; + v0[2] = (char)AnimOrder[0][*v3 + v2]; + } + } + v0 += 58; + } + while ( (signed int)v0 < (signed int)&trigs[0]._ty ); +} + +//----- (00460C5C) -------------------------------------------------------- +ItemStruct *__fastcall PlrHasItem(int pnum, int item, int *i) +{ + unsigned int v3; // eax + int v4; // ecx + + v3 = 21720 * pnum; + *i = 0; + if ( plr[pnum]._pNumInv <= 0 ) + return 0; + while ( *(int *)((char *)&plr[0].InvList[*i].IDidx + v3) != item ) + { + v4 = *i + 1; + *i = v4; + if ( v4 >= plr[v3 / 0x54D8]._pNumInv ) + return 0; + } + return (ItemStruct *)((char *)&plr[0].InvList[*i] + v3); +} + +//----- (00460CAC) -------------------------------------------------------- +void __fastcall TownerTalk(int t) +{ + sgdwCowClicks = 0; + sgnCowMsg = 0; + storeflag = 1; + InitQTextMsg(t); +} +// 6AAC18: using guessed type int storeflag; +// 6AAC1C: using guessed type int sgnCowMsg; +// 6AAC24: using guessed type int sgdwCowClicks; + +//----- (00460CC9) -------------------------------------------------------- +void __fastcall TalkToTowner(int p, int t) +{ + int v2; // ebx + int v3; // edi + int v4; // ecx + int v5; // ecx + int v6; // ebp + int v7; // esi + int v8; // eax + int v9; // ecx + char v10; // cl + bool v11; // zf + int v12; // edi + int v13; // eax + int v14; // eax + int v15; // eax + char v16; // cl + _speech_id v17; // ecx + ItemStruct *Item; // ebp + unsigned char v19; // dl + int inv_item_num; // [esp+10h] [ebp-8h] + int v21; // [esp+14h] [ebp-4h] + + v2 = t; + v3 = p; + _LOBYTE(p) = 6; + v21 = t; + random(p, 3); + _LOBYTE(v4) = 6; + random(v4, 4); + _LOBYTE(v5) = 6; + random(v5, 5); + v6 = v3; + v7 = v2; + inv_item_num = abs(plr[v3].WorldX - towner[v2]._tx); + v8 = abs(plr[v3].WorldY - towner[v2]._ty); + if ( inv_item_num >= 2 ) + return; + if ( v8 >= 2 ) + return; + if ( qtextflag ) + return; + towner[v7]._tMsgSaid = 0; + if ( pcurs >= CURSOR_FIRSTITEM && !DropItemBeforeTrig() ) + return; + if ( v2 == GetActiveTowner(TOWN_TAVERN) ) + { + if ( !plr[v6]._pLvlVisited[0] && !towner[v7]._tMsgSaid ) + { + towner[v7]._tbtcnt = 150; + towner[v7]._tVar1 = v3; + InitQTextMsg(TEXT_TAVERN0); + towner[v7]._tMsgSaid = 1; + } + if ( (plr[v6]._pLvlVisited[2] || plr[v6]._pLvlVisited[4]) && quests[12]._qactive ) + { + if ( !quests[12]._qvar2 && !towner[v7]._tMsgSaid ) + { + quests[12]._qvar2 = 1; + quests[12]._qlog = 1; + if ( quests[12]._qactive == 1 ) + { + quests[12]._qactive = 2; + quests[12]._qvar1 = 1; + } + towner[v7]._tbtcnt = 150; + towner[v7]._tVar1 = v3; + InitQTextMsg(1); + towner[v7]._tMsgSaid = 1; + NetSendCmdQuest(1u, 0xCu); + } + if ( quests[12]._qactive == 3 && quests[12]._qvar2 == 1 && !towner[v7]._tMsgSaid ) + { + quests[12]._qvar2 = 2; + quests[12]._qvar1 = 2; + towner[v7]._tbtcnt = 150; + towner[v7]._tVar1 = v3; + InitQTextMsg(TEXT_TAVERN23); + towner[v7]._tMsgSaid = 1; + NetSendCmdQuest(1u, 0xCu); + } + } + if ( gbMaxPlayers == 1 && plr[v6]._pLvlVisited[3] && quests[7]._qactive ) + { + if ( (quests[7]._qactive == 1 || quests[7]._qactive == 2) && !quests[7]._qvar2 ) + { + if ( towner[v7]._tMsgSaid ) + goto LABEL_36; + quests[7]._qvar2 = 1; + if ( quests[7]._qactive == 1 ) + { + quests[7]._qvar1 = 1; + quests[7]._qactive = 2; + } + quests[7]._qlog = 1; + towner[v7]._tbtcnt = 150; + towner[v7]._tVar1 = v3; + InitQTextMsg(TEXT_TAVERN24); + towner[v7]._tMsgSaid = 1; + } + if ( quests[7]._qvar2 == 1 && PlrHasItem(v3, IDI_BANNER, &inv_item_num) && !towner[v7]._tMsgSaid ) + { + quests[7]._qactive = 3; + quests[7]._qvar1 = 3; + RemoveInvItem(v3, inv_item_num); + CreateItem(UITEM_HARCREST, towner[v7]._tx, towner[v7]._ty + 1); + towner[v7]._tbtcnt = 150; + towner[v7]._tVar1 = v3; + InitQTextMsg(TEXT_TAVERN25); + towner[v7]._tMsgSaid = 1; + } + } +LABEL_36: + if ( !qtextflag ) + { + TownerTalk(TEXT_TAVERN36); + if ( storeflag ) + { + _LOBYTE(v9) = STORE_TAVERN; +LABEL_39: + StartStore(v9); + return; + } + } + return; + } + if ( v2 == GetActiveTowner(TOWN_DEADGUY) ) + { + if ( quests[6]._qactive == v10 ) + { + if ( quests[6]._qvar1 == 1 ) + { + v11 = _LOBYTE(plr[v6]._pClass) == 0; + towner[v7]._tbtcnt = 150; + towner[v7]._tVar1 = v3; + quests[6]._qvar1 = 1; + if ( v11 && (v12 = PS_WARR8, _LOBYTE(v13) = effect_is_playing(PS_WARR8), !v13) + || _LOBYTE(plr[v6]._pClass) == 1 && (v12 = PS_ROGUE8, _LOBYTE(v14) = effect_is_playing(PS_ROGUE8), !v14) + || _LOBYTE(plr[v6]._pClass) == 2 && (v12 = PS_MAGE8, _LOBYTE(v15) = effect_is_playing(PS_MAGE8), !v15) ) + { + PlaySFX(v12); + } +LABEL_53: + towner[v7]._tMsgSaid = 1; + return; + } + if ( quests[6]._qvar1 ) + return; + } + else + { + if ( quests[6]._qactive == 3 ) + { + if ( quests[6]._qvar1 != 1 ) + return; + quests[6]._qvar1 = 1; + towner[v7]._tbtcnt = 150; + towner[v7]._tVar1 = v3; + goto LABEL_53; + } + if ( quests[6]._qactive != 1 ) + return; + } + quests[6]._qactive = 2; + quests[6]._qlog = 1; + quests[6]._qmsg = TEXT_WOUND; + quests[6]._qvar1 = 1; + towner[v7]._tbtcnt = 50; + towner[v7]._tVar1 = v3; + towner[v7]._tVar2 = 3; + InitQTextMsg(TEXT_WOUND); + towner[v7]._tMsgSaid = 1; + NetSendCmdQuest(1u, 6u); + return; + } + if ( v2 != GetActiveTowner(0) ) + { + if ( v2 == GetActiveTowner(TOWN_WITCH) ) + { + if ( quests[1]._qactive == 1 ) + { + if ( PlrHasItem(v3, IDI_FUNGALTM, &inv_item_num) ) + { + RemoveInvItem(v3, inv_item_num); + quests[1]._qactive = 2; + quests[1]._qlog = 1; + quests[1]._qvar1 = 2; + v17 = TEXT_WITCH22; +LABEL_105: + towner[v7]._tVar1 = v3; + towner[v7]._tbtcnt = 150; + InitQTextMsg(v17); + towner[v7]._tMsgSaid = 1; + goto LABEL_106; + } + } + else if ( quests[1]._qactive == 2 ) + { + if ( quests[1]._qvar1 >= 2u && quests[1]._qvar1 <= 4u ) + { + if ( PlrHasItem(v3, IDI_MUSHROOM, &inv_item_num) ) + { + RemoveInvItem(v3, inv_item_num); + Qtalklist[6]._qblkm = -1; + quests[1]._qvar1 = 5; + Qtalklist[1]._qblkm = 123; + v17 = TEXT_WITCH24; + } + else + { + v17 = TEXT_WITCH23; + if ( quests[1]._qmsg == TEXT_WITCH23 ) + goto LABEL_106; + } + quests[1]._qmsg = v17; + goto LABEL_105; + } + Item = PlrHasItem(v3, IDI_SPECELIX, &inv_item_num); + if ( Item ) + { + towner[v7]._tbtcnt = 150; + towner[v7]._tVar1 = v3; + InitQTextMsg(TEXT_WITCH26); + quests[1]._qactive = 3; + towner[v7]._tMsgSaid = 1; + AllItemsList[Item->IDidx].iUsable = 1; + } + else if ( PlrHasItem(v3, IDI_BRAIN, &inv_item_num) ) + { + v17 = TEXT_WITCH25; + if ( quests[1]._qvar2 != TEXT_WITCH25 ) + { + quests[1]._qvar2 = TEXT_WITCH25; + goto LABEL_105; + } + } + } +LABEL_106: + if ( !qtextflag ) + { + TownerTalk(TEXT_WITCH38); + if ( storeflag ) + { + _LOBYTE(v9) = STORE_WITCH; + goto LABEL_39; + } + } + return; + } + if ( v2 == GetActiveTowner(TOWN_BMAID) ) + { + if ( !qtextflag ) + { + TownerTalk(TEXT_BMAID31); + if ( storeflag ) + { + _LOBYTE(v9) = STORE_BARMAID; + goto LABEL_39; + } + } + return; + } + if ( v2 == GetActiveTowner(TOWN_DRUNK) ) + { + if ( !qtextflag ) + { + TownerTalk(TEXT_DRUNK27); + if ( storeflag ) + { + _LOBYTE(v9) = STORE_DRUNK; + goto LABEL_39; + } + } + return; + } + if ( v21 == GetActiveTowner(1) ) + { + if ( gbMaxPlayers != 1 ) + goto LABEL_131; + if ( plr[v6]._pLvlVisited[1] && !towner[v7]._tMsgSaid ) + { + if ( quests[13]._qactive == 1 ) + { + quests[13]._qactive = 2; + quests[13]._qlog = 1; + quests[13]._qmsg = TEXT_HEALER20; + quests[13]._qvar1 = 1; + towner[v7]._tbtcnt = 150; + towner[v7]._tVar1 = v3; + InitQTextMsg(TEXT_HEALER20); +LABEL_126: + towner[v7]._tMsgSaid = 1; + goto LABEL_127; + } + if ( quests[13]._qactive == 3 && quests[13]._qvar1 != 2 ) + { + quests[13]._qvar1 = 2; + towner[v7]._tbtcnt = 150; + towner[v7]._tVar1 = v3; + InitQTextMsg(TEXT_HEALER22); + CreateItem(UITEM_TRING, towner[v7]._tx, towner[v7]._ty + 1); + goto LABEL_126; + } + } +LABEL_127: + if ( quests[1]._qactive == 2 && quests[1]._qmsg == TEXT_WITCH24 && PlrHasItem(v3, IDI_BRAIN, &inv_item_num) ) + { + RemoveInvItem(v3, inv_item_num); + SpawnQuestItem(IDI_SPECELIX, towner[v7]._tx, towner[v7]._ty + 1, 0, 0); + InitQTextMsg(TEXT_HEALER27); + Qtalklist[1]._qblkm = -1; + quests[1]._qvar1 = 7; + } +LABEL_131: + if ( !qtextflag ) + { + TownerTalk(TEXT_HEALER37); + if ( storeflag ) + { + _LOBYTE(v9) = STORE_HEALER; + goto LABEL_39; + } + } + return; + } + if ( v21 == GetActiveTowner(TOWN_PEGBOY) ) + { + if ( !qtextflag ) + { + TownerTalk(TEXT_PEGBOY32); + if ( storeflag ) + { + _LOBYTE(v9) = STORE_BOY; + goto LABEL_39; + } + } + return; + } + if ( v21 != GetActiveTowner(TOWN_STORY) ) + { + if ( towner[v7]._ttype == 9 && !qtextflag ) + CowSFX(v3); + return; + } + if ( gbMaxPlayers == 1 ) + { + if ( quests[15]._qactive == 1 ) + { + if ( !PlrHasItem(v3, IDI_LAZSTAFF, &inv_item_num) ) + goto LABEL_154; + RemoveInvItem(v3, inv_item_num); + quests[15]._qvar1 = 2; + towner[v7]._tbtcnt = TEXT_STORY25; + towner[v7]._tVar1 = v3; + InitQTextMsg(TEXT_STORY36); + quests[15]._qactive = 2; + quests[15]._qlog = 1; + } + else + { + if ( quests[15]._qactive != 3 || quests[15]._qvar1 != 7 ) + goto LABEL_154; + quests[15]._qvar1 = 8; + towner[v7]._tbtcnt = TEXT_STORY25; + towner[v7]._tVar1 = v3; + InitQTextMsg(TEXT_STORY38_1); + quests[5]._qlog = 1; + } + v11 = gbMaxPlayers == 1; + towner[v7]._tMsgSaid = 1; + if ( v11 ) + goto LABEL_154; + } + if ( quests[15]._qactive == 2 ) + { + if ( !quests[15]._qlog ) + { + towner[v7]._tbtcnt = TEXT_STORY25; + towner[v7]._tVar1 = v3; + InitQTextMsg(TEXT_STORY36); + towner[v7]._tMsgSaid = 1; + quests[15]._qlog = 1; + v19 = 15; +LABEL_153: + NetSendCmdQuest(1u, v19); + goto LABEL_154; + } + } + else if ( quests[15]._qactive == 3 && quests[15]._qvar1 == 7 ) + { + quests[15]._qvar1 = 8; + towner[v7]._tbtcnt = TEXT_STORY25; + towner[v7]._tVar1 = v3; + InitQTextMsg(TEXT_STORY38_1); + towner[v7]._tMsgSaid = 1; + NetSendCmdQuest(1u, 0xFu); + quests[5]._qlog = 1; + v19 = 5; + goto LABEL_153; + } +LABEL_154: + if ( !qtextflag ) + { + TownerTalk(TEXT_STORY25); + if ( storeflag ) + { + _LOBYTE(v9) = STORE_STORY; + goto LABEL_39; + } + } + return; + } + if ( gbMaxPlayers == 1 ) + { + if ( plr[v6]._pLvlVisited[4] != v16 && quests[0]._qactive ) + { + if ( quests[0]._qvar2 == v16 ) + { + quests[0]._qvar2 = 1; + quests[0]._qlog = 1; + if ( quests[0]._qactive == 1 ) + { + quests[0]._qactive = 2; + quests[0]._qvar1 = 1; + } + towner[v7]._tbtcnt = 150; + towner[v7]._tVar1 = v3; + InitQTextMsg(TEXT_SMITH24); + towner[v7]._tMsgSaid = 1; + } + if ( quests[0]._qvar2 == 1 && PlrHasItem(v3, IDI_ROCK, &inv_item_num) && !towner[v7]._tMsgSaid ) + { + quests[0]._qactive = 3; + quests[0]._qvar2 = 2; + quests[0]._qvar1 = 2; + RemoveInvItem(v3, inv_item_num); + CreateItem(UITEM_INFRARING, towner[v7]._tx, towner[v7]._ty + 1); + towner[v7]._tbtcnt = 150; + towner[v7]._tVar1 = v3; + InitQTextMsg(TEXT_SMITH26); + towner[v7]._tMsgSaid = 1; + } + } + if ( plr[v6]._pLvlVisited[9] && quests[10]._qactive ) + { + if ( (quests[10]._qactive == 1 || quests[10]._qactive == 2) && !quests[10]._qvar2 ) + { + if ( towner[v7]._tMsgSaid || quests[0]._qvar2 != 2 && (quests[0]._qactive != 2 || quests[0]._qvar2 != 1) ) + goto LABEL_86; + quests[10]._qvar2 = 1; + quests[10]._qlog = 1; + if ( quests[10]._qactive == 1 ) + { + quests[10]._qactive = 2; + quests[10]._qvar1 = 1; + } + towner[v7]._tbtcnt = 150; + towner[v7]._tVar1 = v3; + InitQTextMsg(TEXT_SMITH21); + towner[v7]._tMsgSaid = 1; + } + if ( quests[10]._qvar2 == 1 && PlrHasItem(v3, IDI_ANVIL, &inv_item_num) && !towner[v7]._tMsgSaid ) + { + quests[10]._qactive = 3; + quests[10]._qvar2 = 2; + quests[10]._qvar1 = 2; + RemoveInvItem(v3, inv_item_num); + CreateItem(UITEM_GRISWOLD, towner[v7]._tx, towner[v7]._ty + 1); + towner[v7]._tbtcnt = 150; + towner[v7]._tVar1 = v3; + InitQTextMsg(TEXT_SMITH23); + towner[v7]._tMsgSaid = 1; + } + } + } +LABEL_86: + if ( !qtextflag ) + { + TownerTalk(TEXT_SMITH44); + if ( storeflag ) + { + _LOBYTE(v9) = 1; + goto LABEL_39; + } + } +} +// 646D00: using guessed type char qtextflag; +// 679660: using guessed type char gbMaxPlayers; +// 6AAC18: using guessed type int storeflag; + +//----- (004617E8) -------------------------------------------------------- +void __fastcall CowSFX(int pnum) +{ + int v1; // edi + int v2; // eax + int v3; // ecx + bool v4; // sf + unsigned char v5; // of + int v6; // ecx + + v1 = pnum; + if ( CowPlaying == -1 || (_LOBYTE(v2) = effect_is_playing(CowPlaying), !v2) ) + { + if ( (unsigned int)++sgdwCowClicks < 8 ) + { + v6 = (sgdwCowClicks == 4) + TSFX_COW1; + CowPlaying = (sgdwCowClicks == 4) + TSFX_COW1; + } + else + { + PlaySfxLoc(TSFX_COW1, plr[v1].WorldX, plr[v1].WorldY + 5); + sgdwCowClicks = 4; + v3 = 3 * sgnCowMsg + SLOBYTE(plr[v1]._pClass); + v5 = __OFSUB__(sgnCowMsg + 1, 3); + v4 = sgnCowMsg++ - 2 < 0; + v6 = snSFX[0][v3]; + CowPlaying = v6; + if ( !(v4 ^ v5) ) + sgnCowMsg = 0; + } + PlaySfxLoc(v6, plr[v1].WorldX, plr[v1].WorldY); + } +} +// 6AAC1C: using guessed type int sgnCowMsg; +// 6AAC24: using guessed type int sgdwCowClicks; + +//----- (004618AA) -------------------------------------------------------- +void __cdecl track_cpp_init() +{ + track_cpp_init_value = track_inf; +} +// 4802D0: using guessed type int track_inf; +// 6ABABC: using guessed type int track_cpp_init_value; + +//----- (004618B5) -------------------------------------------------------- +void __cdecl track_repeat_walk() +{ + int v0; // eax + DWORD v1; // eax + + if ( dword_6ABAC4 ) + { + if ( cursmx >= 0 && cursmx < 111 && cursmy >= 0 && cursmy < 111 ) + { + v0 = myplr; + if ( (plr[myplr]._pVar8 > 6 || plr[v0]._pmode == PM_STAND) + && (cursmx != plr[v0]._ptargx || cursmy != plr[v0]._ptargy) ) + { + v1 = GetTickCount(); + if ( (signed int)(v1 - dword_6ABAC0) >= 300 ) + { + dword_6ABAC0 = v1; + NetSendCmdLoc(1u, CMD_WALKXY, cursmx, cursmy); + if ( !byte_6ABAB8 ) + byte_6ABAB8 = 1; + } + } + } + } +} +// 6ABAB8: using guessed type char byte_6ABAB8; +// 6ABAC0: using guessed type int dword_6ABAC0; +// 6ABAC4: using guessed type int dword_6ABAC4; + +//----- (00461953) -------------------------------------------------------- +void __fastcall track_mouse_stance(int a1) +{ + if ( dword_6ABAC4 != a1 ) + { + dword_6ABAC4 = a1; + if ( a1 ) + { + byte_6ABAB8 = 0; + dword_6ABAC0 = GetTickCount() - 50; + NetSendCmdLoc(1u, 1u, cursmx, cursmy); + } + else if ( byte_6ABAB8 ) + { + byte_6ABAB8 = 0; + } + } +} +// 6ABAB8: using guessed type char byte_6ABAB8; +// 6ABAC0: using guessed type int dword_6ABAC0; +// 6ABAC4: using guessed type int dword_6ABAC4; + +//----- (0046199F) -------------------------------------------------------- +int __cdecl track_isscrolling() +{ + return (unsigned char)byte_6ABAB8; +} +// 6ABAB8: using guessed type char byte_6ABAB8; + +//----- (004619A7) -------------------------------------------------------- +void __cdecl InitNoTriggers() +{ + trigflag[4] = 0; + trigflag[3] = 0; +} + +//----- (004619B6) -------------------------------------------------------- +void __cdecl InitTownTriggers() +{ + char v0; // bl + int v1; // eax + int v2; // eax + + trigs[0]._tx = 25; + trigs[0]._ty = 29; + trigs[0]._tmsg = 1026; + trigflag[4] = 1; + if ( gbMaxPlayers == 4 ) + { + trigs[1]._tx = 49; + trigflag[0] = 1; + trigflag[1] = 1; + trigflag[2] = 1; + trigs[1]._ty = 21; + trigs[1]._tmsg = 1031; + trigs[1]._tlvl = 5; + trigs[2]._tx = 17; + trigs[2]._ty = 69; + trigs[2]._tmsg = 1031; + trigs[2]._tlvl = 9; + trigs[3]._tx = 41; + trigs[3]._ty = 80; + trigs[3]._tmsg = 1031; + trigs[3]._tlvl = 13; + trigflag[4] = 4; + } + else + { + trigflag[0] = 0; + trigflag[1] = 0; + trigflag[2] = 0; + v0 = plr[myplr].pTownWarps; + if ( v0 & 1 ) + { + trigs[1]._tx = 49; + trigs[1]._ty = 21; + trigs[1]._tmsg = 1031; + trigs[1]._tlvl = 5; + trigflag[4] = 2; + trigflag[0] = 1; + } + if ( v0 & 2 ) + { + trigflag[1] = 1; + v1 = trigflag[4]++; + trigs[v1]._tx = 17; + trigs[v1]._ty = 69; + trigs[v1]._tmsg = 1031; + trigs[v1]._tlvl = 9; + } + if ( v0 & 4 ) + { + trigflag[2] = 1; + v2 = trigflag[4]++; + trigs[v2]._tx = 41; + trigs[v2]._ty = 80; + trigs[v2]._tmsg = 1031; + trigs[v2]._tlvl = 13; + } + } + trigflag[3] = 0; +} +// 679660: using guessed type char gbMaxPlayers; + +//----- (00461B45) -------------------------------------------------------- +void __cdecl InitL1Triggers() +{ + int v0; // edi + signed int v1; // esi + int *v2; // edx + int *v3; // ecx + TriggerStruct *v4; // eax + int (*v5)[112]; // [esp+Ch] [ebp-8h] + int (*v6)[112]; // [esp+10h] [ebp-4h] + + v0 = 0; + trigflag[4] = 0; + v5 = dPiece; + do + { + v1 = 0; + v6 = v5; + v2 = &trigs[trigflag[4]]._tmsg; + v3 = &trigs[trigflag[4]]._ty; + v4 = &trigs[trigflag[4]]; + do + { + if ( (*v6)[0] == 129 ) + { + ++trigflag[4]; + v4->_tx = v1; + *v3 = v0; + *v2 = 1027; + ++v4; + v3 += 4; + v2 += 4; + } + if ( (*v6)[0] == 115 ) + { + ++trigflag[4]; + v4->_tx = v1; + *v3 = v0; + *v2 = 1026; + ++v4; + v3 += 4; + v2 += 4; + } + ++v6; + ++v1; + } + while ( v1 < 112 ); + v5 = (int (*)[112])((char *)v5 + 4); + ++v0; + } + while ( (signed int)v5 < (signed int)dPiece[1] ); + trigflag[3] = 0; +} + +//----- (00461BEE) -------------------------------------------------------- +void __cdecl InitL2Triggers() +{ + signed int v0; // edi + int *v1; // esi + int *v2; // edx + TriggerStruct *v3; // ecx + int *v4; // eax + int (*v5)[112]; // [esp+Ch] [ebp-10h] + int (*v6)[112]; // [esp+10h] [ebp-Ch] + int v7; // [esp+14h] [ebp-8h] + int *v8; // [esp+18h] [ebp-4h] + + trigflag[4] = 0; + v7 = 0; + v5 = dPiece; + do + { + v0 = 0; + v1 = &trigs[trigflag[4]]._tmsg; + v2 = &trigs[trigflag[4]]._ty; + v3 = &trigs[trigflag[4]]; + v8 = &trigs[trigflag[4]]._tlvl; + v6 = v5; + do + { + if ( (*v6)[0] == 267 && (v0 != quests[14]._qtx || v7 != quests[14]._qty) ) + { + ++trigflag[4]; + v8 += 4; + v3->_tx = v0; + *v2 = v7; + *v1 = 1027; + ++v3; + v2 += 4; + v1 += 4; + } + if ( (*v6)[0] == 559 ) + { + v3->_tx = v0; + *v2 = v7; + v4 = v8; + v8 += 4; + *v1 = 1032; + *v4 = 0; + ++trigflag[4]; + ++v3; + v2 += 4; + v1 += 4; + } + if ( (*v6)[0] == 271 ) + { + ++trigflag[4]; + v8 += 4; + v3->_tx = v0; + *v2 = v7; + *v1 = 1026; + ++v3; + v2 += 4; + v1 += 4; + } + ++v6; + ++v0; + } + while ( v0 < 112 ); + v5 = (int (*)[112])((char *)v5 + 4); + ++v7; + } + while ( (signed int)v5 < (signed int)dPiece[1] ); + trigflag[3] = 0; +} + +//----- (00461CF6) -------------------------------------------------------- +void __cdecl InitL3Triggers() +{ + int v0; // edi + signed int v1; // esi + int *v2; // edx + int *v3; // ecx + TriggerStruct *v4; // eax + int (*v5)[112]; // [esp+Ch] [ebp-8h] + int (*v6)[112]; // [esp+10h] [ebp-4h] + + v0 = 0; + trigflag[4] = 0; + v5 = dPiece; + do + { + v1 = 0; + v6 = v5; + v2 = &trigs[trigflag[4]]._tmsg; + v3 = &trigs[trigflag[4]]._ty; + v4 = &trigs[trigflag[4]]; + do + { + if ( (*v6)[0] == 171 ) + { + ++trigflag[4]; + v4->_tx = v1; + *v3 = v0; + *v2 = 1027; + ++v4; + v3 += 4; + v2 += 4; + } + if ( (*v6)[0] == 168 ) + { + ++trigflag[4]; + v4->_tx = v1; + *v3 = v0; + *v2 = 1026; + ++v4; + v3 += 4; + v2 += 4; + } + if ( (*v6)[0] == 549 ) + { + ++trigflag[4]; + v4->_tx = v1; + *v3 = v0; + *v2 = 1032; + ++v4; + v3 += 4; + v2 += 4; + } + ++v6; + ++v1; + } + while ( v1 < 112 ); + v5 = (int (*)[112])((char *)v5 + 4); + ++v0; + } + while ( (signed int)v5 < (signed int)dPiece[1] ); + trigflag[3] = 0; +} + +//----- (00461DC6) -------------------------------------------------------- +void __cdecl InitL4Triggers() +{ + signed int v0; // edi + int *v1; // esi + int *v2; // edx + TriggerStruct *v3; // ecx + int *v4; // eax + int v5; // edx + int (*v6)[112]; // edi + signed int v7; // ecx + int *v8; // eax + int (*v9)[112]; // [esp+Ch] [ebp-Ch] + int (*v10)[112]; // [esp+Ch] [ebp-Ch] + int v11; // [esp+10h] [ebp-8h] + int (*v12)[112]; // [esp+14h] [ebp-4h] + + trigflag[4] = 0; + v11 = 0; + v9 = dPiece; + do + { + v0 = 0; + v12 = v9; + v1 = &trigs[trigflag[4]]._tmsg; + v2 = &trigs[trigflag[4]]._ty; + v3 = &trigs[trigflag[4]]; + v4 = &trigs[trigflag[4]]._tlvl; + do + { + if ( (*v12)[0] == 83 ) + { + ++trigflag[4]; + v3->_tx = v0; + *v2 = v11; + *v1 = 1027; + v4 += 4; + ++v3; + v2 += 4; + v1 += 4; + } + if ( (*v12)[0] == 422 ) + { + v3->_tx = v0; + *v2 = v11; + *v1 = 1032; + *v4 = 0; + ++trigflag[4]; + v4 += 4; + ++v3; + v2 += 4; + v1 += 4; + } + if ( (*v12)[0] == 120 ) + { + ++trigflag[4]; + v3->_tx = v0; + *v2 = v11; + *v1 = 1026; + v4 += 4; + ++v3; + v2 += 4; + v1 += 4; + } + ++v12; + ++v0; + } + while ( v0 < 112 ); + v9 = (int (*)[112])((char *)v9 + 4); + ++v11; + } + while ( (signed int)v9 < (signed int)dPiece[1] ); + v5 = 0; + v10 = dPiece; + do + { + v6 = v10; + v7 = 0; + v8 = &trigs[trigflag[4]]._ty; + do + { + if ( (*v6)[0] == 370 && quests[15]._qactive == 3 ) + { + ++trigflag[4]; + *(v8 - 1) = v7; + *v8 = v5; + v8[1] = 1026; + v8 += 4; + } + ++v7; + ++v6; + } + while ( v7 < 112 ); + v10 = (int (*)[112])((char *)v10 + 4); + ++v5; + } + while ( (signed int)v10 < (signed int)dPiece[1] ); + trigflag[3] = 0; +} + +//----- (00461F0A) -------------------------------------------------------- +void __cdecl InitSKingTriggers() +{ + trigflag[3] = 0; + trigflag[4] = 1; + trigs[0]._tx = 82; + trigs[0]._ty = 42; + trigs[0]._tmsg = 1028; +} + +//----- (00461F3A) -------------------------------------------------------- +void __cdecl InitSChambTriggers() +{ + trigflag[3] = 0; + trigflag[4] = 1; + trigs[0]._tx = 70; + trigs[0]._ty = 39; + trigs[0]._tmsg = 1028; +} + +//----- (00461F6A) -------------------------------------------------------- +void __cdecl InitPWaterTriggers() +{ + trigflag[3] = 0; + trigflag[4] = 1; + trigs[0]._tx = 30; + trigs[0]._ty = 83; + trigs[0]._tmsg = 1028; +} + +//----- (00461F9A) -------------------------------------------------------- +void __cdecl InitVPTriggers() +{ + trigflag[3] = 0; + trigflag[4] = 1; + trigs[0]._tx = 35; + trigs[0]._ty = 32; + trigs[0]._tmsg = 1028; +} + +//----- (00461FCA) -------------------------------------------------------- +unsigned char __cdecl ForceTownTrig() +{ + int v0; // edx + int *v1; // esi + int v2; // edx + int *v3; // esi + signed int v4; // esi + signed int v5; // edx + + v0 = TownDownList[0]; + if ( TownDownList[0] != -1 ) + { + v1 = TownDownList; + while ( dPiece[0][cursmy + 112 * cursmx] != v0 ) + { + ++v1; + v0 = *v1; + if ( *v1 == -1 ) + goto LABEL_5; + } + strcpy(infostr, "Down to dungeon"); + cursmx = 25; + cursmy = 29; + return 1; + } +LABEL_5: + if ( trigflag[0] ) + { + v2 = TownWarp1List[0]; + if ( TownWarp1List[0] != -1 ) + { + v3 = TownWarp1List; + while ( dPiece[0][cursmy + 112 * cursmx] != v2 ) + { + ++v3; + v2 = *v3; + if ( *v3 == -1 ) + goto LABEL_13; + } + strcpy(infostr, "Down to catacombs"); + cursmx = 49; + cursmy = 21; + return 1; + } + } +LABEL_13: + if ( trigflag[1] ) + { + v4 = 1199; + while ( dPiece[0][cursmy + 112 * cursmx] != v4 ) + { + if ( ++v4 > 1220 ) + goto LABEL_17; + } + strcpy(infostr, "Down to caves"); + cursmx = 17; + cursmy = 69; + return 1; + } +LABEL_17: + if ( trigflag[2] ) + { + v5 = 1240; + while ( dPiece[0][cursmy + 112 * cursmx] != v5 ) + { + if ( ++v5 > 1255 ) + return 0; + } + strcpy(infostr, "Down to hell"); + cursmx = 41; + cursmy = 80; + return 1; + } + return 0; +} + +//----- (00462130) -------------------------------------------------------- +unsigned char __cdecl ForceL1Trig() +{ + int *v0; // eax + int *v1; // esi + int v2; // eax + int *v3; // edx + int *v4; // eax + int *v5; // esi + int *v6; // edx + int v8; // eax + int v9; // ecx + + if ( L1UpList[0] == -1 ) + { +LABEL_12: + if ( L1DownList[0] == -1 ) + return 0; + v4 = L1DownList; + v5 = L1DownList; + while ( 1 ) + { + if ( dPiece[0][cursmy + 112 * cursmx] == *v4 ) + { + sprintf(infostr, "Down to level %i", currlevel + 1); + v2 = 0; + if ( trigflag[4] > 0 ) + break; + } +LABEL_19: + ++v5; + v4 = v5; + if ( *v5 == -1 ) + return 0; + } + v6 = &trigs[0]._tmsg; + while ( *v6 != 1026 ) + { + ++v2; + v6 += 4; + if ( v2 >= trigflag[4] ) + goto LABEL_19; + } + } + else + { + v0 = L1UpList; + v1 = L1UpList; + while ( 1 ) + { + if ( dPiece[0][cursmy + 112 * cursmx] == *v0 ) + { + if ( currlevel <= 1u ) + strcpy(infostr, "Up to town"); + else + sprintf(infostr, "Up to level %i", currlevel - 1); + v2 = 0; + if ( trigflag[4] > 0 ) + break; + } +LABEL_11: + ++v1; + v0 = v1; + if ( *v1 == -1 ) + goto LABEL_12; + } + v3 = &trigs[0]._tmsg; + while ( *v3 != 1027 ) + { + ++v2; + v3 += 4; + if ( v2 >= trigflag[4] ) + goto LABEL_11; + } + } + v8 = v2; + v9 = trigs[v8]._tx; + cursmy = trigs[v8]._ty; + cursmx = v9; + return 1; +} + +//----- (0046224C) -------------------------------------------------------- +unsigned char __cdecl ForceL2Trig() +{ + int *v0; // eax + int *v1; // ebp + int v2; // edi + TriggerStruct *v3; // esi + int v4; // ebx + int v5; // eax + int *v6; // eax + int *v7; // esi + int v8; // eax + int *v9; // ecx + int v10; // eax + int v11; // ecx + int v12; // eax + int *v13; // eax + int *v14; // ebp + TriggerStruct *v15; // esi + int v16; // ebx + int v17; // eax + int v19; // edi + + if ( L2UpList[0] == -1 ) + { +LABEL_11: + if ( L2DownList[0] != -1 ) + { + v6 = L2DownList; + v7 = L2DownList; + while ( 1 ) + { + if ( dPiece[0][cursmy + 112 * cursmx] == *v6 ) + { + sprintf(infostr, "Down to level %i", currlevel + 1); + v8 = 0; + if ( trigflag[4] > 0 ) + break; + } +LABEL_18: + ++v7; + v6 = v7; + if ( *v7 == -1 ) + goto LABEL_22; + } + v9 = &trigs[0]._tmsg; + while ( *v9 != 1026 ) + { + ++v8; + v9 += 4; + if ( v8 >= trigflag[4] ) + goto LABEL_18; + } + v10 = v8; + v11 = trigs[v10]._tx; + v12 = trigs[v10]._ty; + cursmx = v11; + goto LABEL_37; + } +LABEL_22: + if ( currlevel != 5 || L2TWarpUpList[0] == -1 ) + return 0; + v13 = L2TWarpUpList; + v14 = L2TWarpUpList; + while ( 1 ) + { + if ( dPiece[0][cursmy + 112 * cursmx] == *v13 ) + { + v2 = 0; + if ( trigflag[4] > 0 ) + break; + } +LABEL_32: + ++v14; + v13 = v14; + if ( *v14 == -1 ) + return 0; + } + v15 = trigs; + while ( 1 ) + { + if ( v15->_tmsg == 1032 ) + { + v16 = abs(v15->_tx - cursmx); + v17 = abs(v15->_ty - cursmy); + if ( v16 < 4 && v17 < 4 ) + break; + } + ++v2; + ++v15; + if ( v2 >= trigflag[4] ) + goto LABEL_32; + } + strcpy(infostr, "Up to town"); + } + else + { + v0 = L2UpList; + v1 = L2UpList; + while ( 1 ) + { + if ( dPiece[0][cursmy + 112 * cursmx] == *v0 ) + { + v2 = 0; + if ( trigflag[4] > 0 ) + break; + } +LABEL_10: + ++v1; + v0 = v1; + if ( *v1 == -1 ) + goto LABEL_11; + } + v3 = trigs; + while ( 1 ) + { + if ( v3->_tmsg == 1027 ) + { + v4 = abs(v3->_tx - cursmx); + v5 = abs(v3->_ty - cursmy); + if ( v4 < 4 && v5 < 4 ) + break; + } + ++v2; + ++v3; + if ( v2 >= trigflag[4] ) + goto LABEL_10; + } + sprintf(infostr, "Up to level %i", currlevel - 1); + } + v19 = v2; + cursmx = trigs[v19]._tx; + v12 = trigs[v19]._ty; +LABEL_37: + cursmy = v12; + return 1; +} + +//----- (0046244F) -------------------------------------------------------- +unsigned char __cdecl ForceL3Trig() +{ + int *v0; // eax + int *v1; // esi + int v2; // eax + int *v3; // ecx + int *v4; // ecx + int *v5; // esi + int v6; // ecx + int v7; // eax + int *v8; // ecx + int *v9; // eax + int *v10; // ebp + int v11; // edi + TriggerStruct *v12; // esi + int v13; // ebx + int v14; // eax + int v15; // eax + int v16; // ecx + int v17; // eax + int v18; // edi + + if ( L3UpList[0] != -1 ) + { + v0 = L3UpList; + v1 = L3UpList; + while ( 1 ) + { + if ( dPiece[0][cursmy + 112 * cursmx] == *v0 ) + { + sprintf(infostr, "Up to level %i", currlevel - 1); + v2 = 0; + if ( trigflag[4] > 0 ) + break; + } +LABEL_8: + ++v1; + v0 = v1; + if ( *v1 == -1 ) + goto LABEL_9; + } + v3 = &trigs[0]._tmsg; + while ( *v3 != 1027 ) + { + ++v2; + v3 += 4; + if ( v2 >= trigflag[4] ) + goto LABEL_8; + } + goto LABEL_31; + } +LABEL_9: + if ( L3DownList[0] != -1 ) + { + v4 = L3DownList; + v5 = L3DownList; + while ( 1 ) + { + v6 = *v4; + v7 = cursmy + 112 * cursmx; + if ( dPiece[0][v7] == v6 || dPiece[1][v7] == v6 || dPiece[2][v7] == v6 ) + { + sprintf(infostr, "Down to level %i", currlevel + 1); + v2 = 0; + if ( trigflag[4] > 0 ) + break; + } +LABEL_18: + ++v5; + v4 = v5; + if ( *v5 == -1 ) + goto LABEL_19; + } + v8 = &trigs[0]._tmsg; + while ( *v8 != 1026 ) + { + ++v2; + v8 += 4; + if ( v2 >= trigflag[4] ) + goto LABEL_18; + } +LABEL_31: + v15 = v2; + v16 = trigs[v15]._tx; + v17 = trigs[v15]._ty; + cursmx = v16; +LABEL_33: + cursmy = v17; + return 1; + } +LABEL_19: + if ( currlevel == 9 && L3TWarpUpList[0] != -1 ) + { + v9 = L3TWarpUpList; + v10 = L3TWarpUpList; + while ( 1 ) + { + if ( dPiece[0][cursmy + 112 * cursmx] == *v9 ) + { + v11 = 0; + if ( trigflag[4] > 0 ) + break; + } +LABEL_29: + ++v10; + v9 = v10; + if ( *v10 == -1 ) + return 0; + } + v12 = trigs; + while ( 1 ) + { + if ( v12->_tmsg == 1032 ) + { + v13 = abs(v12->_tx - cursmx); + v14 = abs(v12->_ty - cursmy); + if ( v13 < 4 && v14 < 4 ) + break; + } + ++v11; + ++v12; + if ( v11 >= trigflag[4] ) + goto LABEL_29; + } + strcpy(infostr, "Up to town"); + v18 = v11; + cursmx = trigs[v18]._tx; + v17 = trigs[v18]._ty; + goto LABEL_33; + } + return 0; +} + +//----- (0046262D) -------------------------------------------------------- +unsigned char __cdecl ForceL4Trig() +{ + int *v0; // eax + int *v1; // esi + int v2; // eax + int *v3; // ecx + int *v4; // eax + int *v5; // esi + int *v6; // ecx + int *v7; // eax + int *v8; // ebp + int v9; // edi + TriggerStruct *v10; // esi + int v11; // ebx + int v12; // eax + int *v13; // eax + int *v14; // esi + int *v15; // edx + int v16; // edi + int v17; // eax + int v18; // eax + int v19; // ecx + + if ( L4UpList[0] != -1 ) + { + v0 = L4UpList; + v1 = L4UpList; + while ( 1 ) + { + if ( dPiece[0][cursmy + 112 * cursmx] == *v0 ) + { + sprintf(infostr, "Up to level %i", currlevel - 1); + v2 = 0; + if ( trigflag[4] > 0 ) + break; + } +LABEL_8: + ++v1; + v0 = v1; + if ( *v1 == -1 ) + goto LABEL_9; + } + v3 = &trigs[0]._tmsg; + while ( *v3 != 1027 ) + { + ++v2; + v3 += 4; + if ( v2 >= trigflag[4] ) + goto LABEL_8; + } + goto LABEL_39; + } +LABEL_9: + if ( L4DownList[0] != -1 ) + { + v4 = L4DownList; + v5 = L4DownList; + while ( 1 ) + { + if ( dPiece[0][cursmy + 112 * cursmx] == *v4 ) + { + sprintf(infostr, "Down to level %i", currlevel + 1); + v2 = 0; + if ( trigflag[4] > 0 ) + break; + } +LABEL_16: + ++v5; + v4 = v5; + if ( *v5 == -1 ) + goto LABEL_17; + } + v6 = &trigs[0]._tmsg; + while ( *v6 != 1026 ) + { + ++v2; + v6 += 4; + if ( v2 >= trigflag[4] ) + goto LABEL_16; + } + goto LABEL_39; + } +LABEL_17: + if ( currlevel == 13 ) + { + if ( L4TWarpUpList[0] != -1 ) + { + v7 = L4TWarpUpList; + v8 = L4TWarpUpList; + while ( 1 ) + { + if ( dPiece[0][cursmy + 112 * cursmx] == *v7 ) + { + v9 = 0; + if ( trigflag[4] > 0 ) + break; + } +LABEL_27: + ++v8; + v7 = v8; + if ( *v8 == -1 ) + goto LABEL_28; + } + v10 = trigs; + while ( 1 ) + { + if ( v10->_tmsg == 1032 ) + { + v11 = abs(v10->_tx - cursmx); + v12 = abs(v10->_ty - cursmy); + if ( v11 < 4 && v12 < 4 ) + break; + } + ++v9; + ++v10; + if ( v9 >= trigflag[4] ) + goto LABEL_27; + } + strcpy(infostr, "Up to town"); + v16 = v9; + cursmx = trigs[v16]._tx; + v17 = trigs[v16]._ty; + goto LABEL_40; + } + } + else + { +LABEL_28: + if ( currlevel == 15 && L4PentaList[0] != -1 ) + { + v13 = L4PentaList; + v14 = L4PentaList; + while ( 1 ) + { + if ( dPiece[0][cursmy + 112 * cursmx] == *v13 ) + { + strcpy(infostr, "Down to Diablo"); + v2 = 0; + if ( trigflag[4] > 0 ) + break; + } +LABEL_36: + ++v14; + v13 = v14; + if ( *v14 == -1 ) + return 0; + } + v15 = &trigs[0]._tmsg; + while ( *v15 != 1026 ) + { + ++v2; + v15 += 4; + if ( v2 >= trigflag[4] ) + goto LABEL_36; + } +LABEL_39: + v18 = v2; + v19 = trigs[v18]._tx; + v17 = trigs[v18]._ty; + cursmx = v19; +LABEL_40: + cursmy = v17; + return 1; + } + } + return 0; +} + +//----- (00462876) -------------------------------------------------------- +void __cdecl Freeupstairs() +{ + int *v0; // ecx + int v1; // ebx + char *v2; // eax + signed int v3; // edi + char *v4; // edx + signed int v5; // esi + + if ( trigflag[4] > 0 ) + { + v0 = &trigs[0]._ty; + v1 = trigflag[4]; + do + { + v2 = &nBlockTable[112 * *(v0 - 1) + 1830 + *v0]; + v3 = 5; + do + { + v4 = v2; + v5 = 5; + do + { + *v4 |= 8u; + v4 += 112; + --v5; + } + while ( v5 ); + ++v2; + --v3; + } + while ( v3 ); + v0 += 4; + --v1; + } + while ( v1 ); + } +} + +//----- (004628B7) -------------------------------------------------------- +unsigned char __cdecl ForceSKingTrig() +{ + int v0; // eax + int *v1; // ecx + + v0 = L1UpList[0]; + if ( L1UpList[0] == -1 ) + return 0; + v1 = L1UpList; + while ( dPiece[0][cursmy + 112 * cursmx] != v0 ) + { + ++v1; + v0 = *v1; + if ( *v1 == -1 ) + return 0; + } + sprintf(infostr, "Back to Level %i", (unsigned char)quests[12]._qlevel); + cursmx = trigs[0]._tx; + cursmy = trigs[0]._ty; + return 1; +} + +//----- (0046291F) -------------------------------------------------------- +unsigned char __cdecl ForceSChambTrig() +{ + int v0; // eax + int *v1; // ecx + + v0 = L2DownList[0]; + if ( L2DownList[0] == -1 ) + return 0; + v1 = L2DownList; + while ( dPiece[0][cursmy + 112 * cursmx] != v0 ) + { + ++v1; + v0 = *v1; + if ( *v1 == -1 ) + return 0; + } + sprintf(infostr, "Back to Level %i", (unsigned char)quests[14]._qlevel); + cursmx = trigs[0]._tx; + cursmy = trigs[0]._ty; + return 1; +} + +//----- (00462987) -------------------------------------------------------- +unsigned char __cdecl ForcePWaterTrig() +{ + int v0; // eax + int *v1; // ecx + + v0 = L3DownList[0]; + if ( L3DownList[0] == -1 ) + return 0; + v1 = L3DownList; + while ( dPiece[0][cursmy + 112 * cursmx] != v0 ) + { + ++v1; + v0 = *v1; + if ( *v1 == -1 ) + return 0; + } + sprintf(infostr, "Back to Level %i", (unsigned char)quests[13]._qlevel); + cursmx = trigs[0]._tx; + cursmy = trigs[0]._ty; + return 1; +} + +//----- (004629EF) -------------------------------------------------------- +void __cdecl CheckTrigForce() +{ + int v0; // eax + int v1; // eax + + trigflag[3] = 0; + if ( MouseY <= 351 ) + { + if ( setlevel ) + { + switch ( setlvlnum ) + { + case SL_SKELKING: + _LOBYTE(v1) = ForceSKingTrig(); + break; + case SL_BONECHAMB: + _LOBYTE(v1) = ForceSChambTrig(); + break; + case SL_POISONWATER: + _LOBYTE(v1) = ForcePWaterTrig(); + break; + default: + return; + } + goto LABEL_23; + } + if ( leveltype ) + { + switch ( leveltype ) + { + case DTYPE_CATHEDRAL: + _LOBYTE(v0) = ForceL1Trig(); + break; + case DTYPE_CATACOMBS: + _LOBYTE(v0) = ForceL2Trig(); + break; + case DTYPE_CAVES: + _LOBYTE(v0) = ForceL3Trig(); + break; + case DTYPE_HELL: + _LOBYTE(v0) = ForceL4Trig(); + break; + default: +LABEL_14: + if ( !leveltype ) + goto LABEL_24; + if ( trigflag[3] ) + { +LABEL_25: + ClearPanel(); + return; + } + v1 = ForceQuests(); +LABEL_23: + trigflag[3] = v1; +LABEL_24: + if ( !trigflag[3] ) + return; + goto LABEL_25; + } + } + else + { + _LOBYTE(v0) = ForceTownTrig(); + } + trigflag[3] = v0; + goto LABEL_14; + } +} +// 5BB1ED: using guessed type char leveltype; +// 5CCB10: using guessed type char setlvlnum; +// 5CF31D: using guessed type char setlevel; + +//----- (00462A9D) -------------------------------------------------------- +void __cdecl CheckTriggers() +{ + int *v0; // edi + int v1; // esi + int v2; // ecx + int v3; // eax + int v4; // edx + signed int v5; // edx + int v6; // eax + char v7; // al + int v8; // ecx + int v9; // [esp-4h] [ebp-20h] + int x; // [esp+Ch] [ebp-10h] + int y; // [esp+10h] [ebp-Ch] + int v12; // [esp+14h] [ebp-8h] + int error_id; // [esp+1Bh] [ebp-1h] + + if ( plr[myplr]._pmode ) + return; + v12 = 0; + if ( trigflag[4] <= 0 ) + return; + v0 = &trigs[0]._tmsg; + while ( 1 ) + { + v1 = myplr; + v2 = plr[myplr].WorldX; + if ( v2 != *(v0 - 2) ) + goto LABEL_34; + v3 = plr[v1].WorldY; + if ( v3 != *(v0 - 1) ) + goto LABEL_34; + v4 = *v0; + if ( *v0 == WM_DIABNEXTLVL ) + { + if ( pcurs >= CURSOR_FIRSTITEM && DropItemBeforeTrig() ) + return; + v6 = currlevel + 1; + goto LABEL_32; + } + if ( *v0 == 1027 ) + { + if ( pcurs >= CURSOR_FIRSTITEM && DropItemBeforeTrig() ) + return; + v6 = currlevel - 1; +LABEL_32: + v9 = v6; + goto LABEL_33; + } + if ( *v0 != 1028 ) + break; + StartNewLvl(myplr, v4, ReturnLvl); +LABEL_34: + ++v12; + v0 += 4; + if ( v12 >= trigflag[4] ) + return; + } + if ( *v0 != 1031 ) + { + if ( *v0 == 1032 ) + { + TWarpFrom = currlevel; + StartNewLvl(myplr, v4, 0); + } + else + { + TermMsg("Unknown trigger msg"); + } + goto LABEL_34; + } + if ( gbMaxPlayers == 1 ) + goto LABEL_46; + v5 = 0; + if ( v0[1] == 5 && plr[v1]._pLevel < 8 ) + { + v5 = 1; + x = plr[myplr].WorldX; + _LOBYTE(y) = v3 + 1; + _LOBYTE(error_id) = 40; + } + if ( v0[1] == 9 && plr[v1]._pLevel < 13 ) + { + v5 = 1; + _LOBYTE(x) = v2 + 1; + y = plr[v1].WorldY; + _LOBYTE(error_id) = 41; + } + if ( v0[1] == 13 && plr[v1]._pLevel < 17 ) + { + x = plr[myplr].WorldX; + v5 = 1; + _LOBYTE(y) = v3 + 1; + _LOBYTE(error_id) = 42; + } + if ( !v5 ) + { +LABEL_46: + v9 = v0[1]; +LABEL_33: + StartNewLvl(myplr, *v0, v9); + goto LABEL_34; + } + v7 = plr[myplr]._pClass; + switch ( v7 ) + { + case UI_WARRIOR: + v8 = PS_WARR43; + goto LABEL_42; + case UI_ROGUE: + v8 = PS_ROGUE43; + goto LABEL_42; + case UI_SORCERER: + v8 = PS_MAGE43; +LABEL_42: + PlaySFX(v8); + break; + } + _LOBYTE(v2) = error_id; + InitDiabloMsg(v2); + NetSendCmdLoc(1u, 1u, x, y); +} +// 679660: using guessed type char gbMaxPlayers; +// 6ABB30: using guessed type int TWarpFrom; + +//----- (00462C72) -------------------------------------------------------- +void __cdecl wave_cpp_init() +{ + wave_cpp_init_value = wave_inf; +} +// 4802D4: using guessed type int wave_inf; +// 6ABB34: using guessed type int wave_cpp_init_value; + +//----- (00462C7D) -------------------------------------------------------- +bool __fastcall wave_close_file(void *file) +{ + return SFileCloseFile(file); +} + +//----- (00462C84) -------------------------------------------------------- +int __fastcall wave_get_file_size(int *a1, int *a2) +{ + int *v2; // edi + int *i; // esi + int result; // eax + int a2a; // [esp+8h] [ebp-4h] + + a2a = 0; + v2 = a2; + for ( i = a1; ; wave_get_file_archive((int)i, &a2a, 0) ) + { + result = SFileGetFileSize(i, (unsigned long *)v2); + if ( result ) + break; + } + return result; +} + +//----- (00462CAF) -------------------------------------------------------- +void __fastcall wave_get_file_archive(int a1, int *a2, char *dwInitParam) +{ + int *v3; // esi + int v4; // edi + int v5; // eax + int v6; // eax + int archive; // [esp+8h] [ebp-4h] + + v3 = a2; + v4 = a1; + if ( (unsigned int)*a2 >= 5 ) + FileErrDlg(dwInitParam); + if ( v4 && (_LOBYTE(v5) = SFileGetFileArchive((void *)v4, &archive), v5) && (void *)archive != diabdat_mpq ) + { + Sleep(0x14u); + ++*v3; + } + else + { + _LOBYTE(v6) = InsertCDDlg(); + if ( !v6 ) + FileErrDlg(dwInitParam); + } +} + +//----- (00462D06) -------------------------------------------------------- +int __fastcall wave_open_file(LPARAM dwInitParam, DIABFILE *a2, int a3) +{ + DIABFILE *v3; // edi + char *i; // esi + int v5; // eax + int a2a; // [esp+8h] [ebp-4h] + + a2a = 0; + v3 = a2; + for ( i = (char *)dwInitParam; ; wave_get_file_archive(0, &a2a, i) ) + { + _LOBYTE(v5) = SFileOpenFile(i, (void **)v3); + if ( v5 ) + return 1; + if ( a3 && SErrGetLastError() == 2 ) + break; + } + return 0; +} + +//----- (00462D48) -------------------------------------------------------- +char __fastcall wave_read_file(int a1, char *a2, int a3) +{ + char *v3; // ebx + void *v4; // edi + int v5; // eax + int nread; // [esp+Ch] [ebp-Ch] + int offset; // [esp+10h] [ebp-8h] + int a2a; // [esp+14h] [ebp-4h] + + v3 = a2; + v4 = (void *)a1; + a2a = 0; + for ( offset = wave_file_pointer(a1, 0, 0, 1); ; wave_file_pointer((int)v4, offset, 0, 0) ) + { + _LOBYTE(v5) = SFileReadFile(v4, v3, a3, (unsigned long *)&nread, 0); + if ( v5 ) + break; + wave_get_file_archive((int)v4, &a2a, 0); + } + return v5; +} + +//----- (00462D9A) -------------------------------------------------------- +int __fastcall wave_file_pointer(int file1, int offset, int file2, int whence) +{ + int v4; // edi + int i; // esi + int result; // eax + int a2; // [esp+8h] [ebp-4h] + + a2 = 0; + v4 = offset; + for ( i = file1; ; wave_get_file_archive(i, &a2, 0) ) + { + result = SFileSetFilePointer(i, v4, file2, whence); + if ( result != -1 ) + break; + } + return result; +} + +//----- (00462DCE) -------------------------------------------------------- +int __fastcall wave_do_buffer(int a1, TSnd *a2) +{ + TSnd *v2; // esi + int v3; // esi + DIABFILE wave_file; // [esp+4h] [ebp-1Ch] + + v2 = a2; + wave_alloc_buffer(a1, &wave_file, 0); + v3 = wave_read_buffer(&wave_file, v2, 0); + wave_free_buffer(&wave_file._cnt); + return v3; +} + +//----- (00462DFC) -------------------------------------------------------- +void *__fastcall wave_alloc_buffer(int a1, DIABFILE *a2, unsigned int a3) +{ + DIABFILE *v3; // esi + int *v4; // edi + unsigned int v5; // eax + unsigned int v6; // ecx + void *result; // eax + + v3 = a2; + v4 = (int *)a1; + memset(a2, 0, 0x1Cu); + v5 = wave_get_file_size(v4, 0); + v6 = 4096; + v3->_cnt = v5; + if ( a3 > 0x1000 ) + v6 = a3; + v3->_base = (char *)v6; + if ( v6 >= v5 ) + v6 = v5; + v3->_base = (char *)v6; + result = DiabloAllocPtr(v6); + v3->_name_to_remove = (char *)v4; + v3->_file = (int)result; + return result; +} + +//----- (00462E45) -------------------------------------------------------- +void __fastcall wave_free_buffer(int *a1) +{ + int *v1; // eax + void *v2; // ecx + + v1 = a1; + v2 = (void *)a1[5]; + v1[5] = 0; + mem_free_dbg(v2); +} + +//----- (00462E53) -------------------------------------------------------- +int __fastcall wave_read_buffer(DIABFILE *wave_file, TSnd *a2, int *a3) +{ + TSnd *v3; // esi + DIABFILE *v4; // edi + WORD v5; // ax + int result; // eax + int a2a[5]; // [esp+8h] [ebp-2Ch] + PCMWAVEFORMAT v8; // [esp+1Ch] [ebp-18h] + int v9[2]; // [esp+2Ch] [ebp-8h] + + v3 = a2; + v4 = wave_file; + if ( !wave_seek_section(wave_file, a2a, 0xCu) + || a2a[0] != 'FFIR' + || a2a[2] != 'EVAW' + || !wave_get_section_data(v4, ' tmf', v9) + || v9[0] < 0x10u + || !wave_seek_section(v4, &v8, 0x10u) + || wave_seek_position(v4, v9[0] - 16, 1) == -1 ) + { + return 0; + } + v5 = v8.wf.wFormatTag; + v3->fmt.cbSize = 0; + v3->fmt.wFormatTag = v5; + v3->fmt.nChannels = v8.wf.nChannels; + v3->fmt.nSamplesPerSec = v8.wf.nSamplesPerSec; + v3->fmt.nAvgBytesPerSec = v8.wf.nAvgBytesPerSec; + v3->fmt.nBlockAlign = v8.wf.nBlockAlign; + v3->fmt.wBitsPerSample = v8.wBitsPerSample; + if ( a3 ) + result = wave_get_section_data(v4, 'atad', a3); + else + result = 1; + return result; +} + +//----- (00462F1D) -------------------------------------------------------- +int __fastcall wave_seek_section(DIABFILE *a1, void *a2, size_t a3) +{ + size_t v3; // ebx + void *v4; // ebp + DIABFILE *v5; // esi + size_t v6; // edi + + v3 = a3; + v4 = a2; + v5 = a1; + if ( !a3 ) + return 1; + while ( 1 ) + { + if ( !v5->_flag ) + wave_read_section(v5); + v6 = v5->_flag; + if ( v3 < v6 ) + v6 = v3; + if ( !v6 ) + break; + memcpy(v4, (const void *)(v5->_bufsiz + v5->_file), v6); + v5->_ptr += v6; + v5->_bufsiz += v6; + v5->_flag -= v6; + v3 -= v6; + if ( !v3 ) + return 1; + } + return 0; +} + +//----- (00462F73) -------------------------------------------------------- +char __fastcall wave_read_section(DIABFILE *a1) +{ + DIABFILE *v1; // esi + char *v2; // eax + unsigned int v3; // edi + + v1 = a1; + wave_file_pointer((int)a1->_name_to_remove, (int)a1->_ptr, 0, 0); + v2 = v1->_base; + v3 = v1->_cnt - (unsigned int)v1->_ptr; + if ( (unsigned int)v2 < v3 ) + v3 = (unsigned int)v1->_base; + if ( v3 ) + _LOBYTE(v2) = wave_read_file((int)v1->_name_to_remove, (char *)v1->_file, v3); + v1->_bufsiz = 0; + v1->_flag = v3; + return (char)v2; +} + +//----- (00462FAE) -------------------------------------------------------- +int __fastcall wave_seek_position(DIABFILE *a1, unsigned int a2, int a3) +{ + unsigned int v3; // eax + + v3 = a1->_flag; + if ( a2 >= v3 ) + { + a1->_flag = 0; + } + else + { + a1->_bufsiz += a2; + a1->_flag = v3 - a2; + } + a1->_ptr += a2; + return (int)a1->_ptr; +} + +//----- (00462FCC) -------------------------------------------------------- +int __fastcall wave_get_section_data(DIABFILE *a1, int a2, int *a3) +{ + int v3; // esi + DIABFILE *v4; // edi + int v6; // eax + int a2a; // [esp+8h] [ebp-8h] + unsigned int v8; // [esp+Ch] [ebp-4h] + + v3 = a2; + v4 = a1; + while ( 1 ) + { + if ( !wave_seek_section(v4, &a2a, 8u) ) + return 0; + if ( a2a == v3 ) + break; + if ( wave_seek_position(v4, v8, 1) == -1 ) + return 0; + } + *a3 = v8; + v6 = wave_seek_position(v4, 0, 1); + a3[1] = v6; + return v6 != -1; +} + +//----- (00463023) -------------------------------------------------------- +int __fastcall wave_load_file(int a1, TSnd *a2, int a3) +{ + TSnd *v3; // esi + DIABFILE wave_file; // [esp+4h] [ebp-1Ch] + + v3 = a2; + wave_alloc_buffer(a1, &wave_file, 0xFFFFFFFF); + if ( wave_read_buffer(&wave_file, v3, (int *)a3) ) + return wave_file._file; + wave_free_buffer(&wave_file._cnt); + return 0; +} + +//----- (00463060) -------------------------------------------------------- +void __fastcall drawTopArchesUpperScreen(void *a1) +{ + int v1; // edx + unsigned int v2; // edi + _BYTE *v3; // esi + int v4; // ebx + short v5; // ax + char *v6; // esi + short v7; // ax + unsigned int v8; // eax + unsigned char *v9; // esi + unsigned int v10; // eax + int v11; // eax + signed int v12; // ebp + signed int v13; // ecx + unsigned int v14; // eax + _BYTE *v15; // edi + signed int v16; // ecx + int v17; // eax + signed int v18; // ebp + signed int v19; // edx + unsigned int v20; // eax + int v21; // edx + unsigned int v22; // ecx + unsigned char v23; // cf + unsigned int v24; // ecx + unsigned int v25; // eax + unsigned int v26; // ecx + int v27; // eax + unsigned int v28; // ecx + unsigned int v29; // ecx + int v30; // eax + unsigned int v31; // ecx + unsigned int v32; // eax + signed int v33; // ebp + _BYTE *v34; // edi + unsigned int v35; // ecx + int v36; // edx + unsigned int v37; // ecx + unsigned int v38; // ecx + unsigned int v39; // eax + unsigned int v40; // ecx + int v41; // eax + int v42; // edx + unsigned int v43; // ecx + unsigned int v44; // ecx + int v45; // eax + unsigned int v46; // ecx + unsigned int v47; // eax + unsigned char v48; // of + signed int v49; // ebp + _BYTE *v50; // edi + unsigned int v51; // ecx + int v52; // edx + unsigned int v53; // ecx + unsigned int v54; // ecx + unsigned int v55; // eax + unsigned int v56; // ecx + int v57; // eax + int v58; // edx + unsigned int v59; // ecx + unsigned int v60; // ecx + int v61; // eax + unsigned int v62; // ecx + unsigned int v63; // eax + signed int v64; // ebp + unsigned int v65; // ecx + unsigned int v66; // ecx + unsigned int v67; // ecx + unsigned int v68; // eax + unsigned int v69; // ecx + int v70; // eax + unsigned int v71; // ecx + unsigned int v72; // ecx + int v73; // eax + unsigned int v74; // ecx + unsigned int v75; // eax + signed int v76; // ebp + unsigned int v77; // ecx + unsigned int v78; // ecx + unsigned int v79; // ecx + unsigned int v80; // eax + unsigned int v81; // ecx + int v82; // eax + unsigned int v83; // ecx + unsigned int v84; // ecx + int v85; // eax + unsigned int v86; // ecx + unsigned int v87; // eax + signed int v88; // ebp + _BYTE *v89; // edi + unsigned int v90; // ecx + int v91; // edx + unsigned int v92; // ecx + unsigned int v93; // ecx + unsigned int v94; // eax + unsigned int v95; // ecx + int v96; // eax + unsigned int v97; // ecx + unsigned int v98; // ecx + int v99; // eax + unsigned int v100; // ecx + unsigned int v101; // eax + signed int v102; // ebp + signed int v103; // ecx + unsigned int v104; // eax + _BYTE *v105; // edi + signed int v106; // ecx + int v107; // eax + signed int v108; // ebp + unsigned int v109; // ecx + unsigned int v110; // ecx + unsigned int v111; // ecx + unsigned int v112; // eax + unsigned int v113; // ecx + int v114; // eax + unsigned int v115; // ecx + unsigned int v116; // ecx + int v117; // eax + unsigned int v118; // ecx + unsigned int v119; // eax + signed int v120; // ebp + signed int v121; // ecx + unsigned int v122; // eax + _BYTE *v123; // edi + signed int v124; // ecx + int v125; // eax + signed int v126; // edx + signed int v127; // ecx + int v128; // eax + _BYTE *v129; // edi + _BYTE *v130; // edi + signed int v131; // ecx + int v132; // eax + _BYTE *v133; // edi + signed int v134; // ebp + signed int v135; // edx + unsigned int v136; // eax + unsigned int v137; // ecx + unsigned int v138; // ecx + char *v139; // esi + _BYTE *v140; // edi + char v141; // al + int v142; // eax + _BYTE *v143; // edi + char v144; // al + unsigned int v145; // ecx + char v146; // al + int v147; // eax + _BYTE *v148; // edi + signed int v149; // edx + _BYTE *v150; // edi + unsigned int v151; // ecx + int v152; // eax + unsigned int v153; // ecx + _BYTE *v154; // edi + int v155; // eax + _BYTE *v156; // edi + unsigned int v157; // ecx + short v158; // ax + int v159; // eax + _BYTE *v160; // edi + signed int v161; // edx + _BYTE *v162; // edi + unsigned int v163; // ecx + int v164; // eax + unsigned int v165; // ecx + _BYTE *v166; // edi + int v167; // eax + _BYTE *v168; // edi + unsigned int v169; // ecx + short v170; // ax + int v171; // eax + _BYTE *v172; // edi + signed int v173; // edx + unsigned int v174; // ecx + int v175; // eax + char v176; // bp + unsigned int i; // ecx + int v178; // eax + _BYTE *v179; // edi + int v180; // ebp + _BYTE *v181; // edi + unsigned int j; // ecx + int v183; // eax + _BYTE *v184; // edi + short v185; // ax + signed int v186; // edx + unsigned int v187; // ecx + int v188; // eax + unsigned int k; // ecx + int v190; // eax + _BYTE *v191; // edi + _BYTE *v192; // edi + unsigned int l; // ecx + int v194; // eax + _BYTE *v195; // edi + short v196; // ax + signed int v197; // edx + _BYTE *v198; // edi + unsigned int v199; // ecx + int v200; // eax + unsigned int v201; // ecx + _BYTE *v202; // edi + int v203; // eax + _BYTE *v204; // edi + unsigned int v205; // ecx + short v206; // ax + int v207; // eax + _BYTE *v208; // edi + signed int v209; // edx + signed int v210; // ecx + int v211; // eax + _BYTE *v212; // edi + _BYTE *v213; // edi + signed int v214; // ecx + int v215; // eax + _BYTE *v216; // edi + signed int v217; // edx + unsigned int v218; // ecx + int v219; // eax + unsigned int m; // ecx + int v221; // eax + _BYTE *v222; // edi + _BYTE *v223; // edi + unsigned int n; // ecx + int v225; // eax + _BYTE *v226; // edi + short v227; // ax + signed int v228; // edx + signed int v229; // ecx + int v230; // eax + _BYTE *v231; // edi + _BYTE *v232; // edi + signed int v233; // ecx + int v234; // eax + _BYTE *v235; // edi + signed int v236; // edx + signed int v237; // ecx + _BYTE *v238; // edi + signed int v239; // ecx + signed int v240; // ebp + signed int v241; // edx + unsigned int v242; // eax + unsigned int v243; // ecx + unsigned int v244; // ecx + _BYTE *v245; // edi + unsigned int v246; // ecx + signed int ii; // edx + _BYTE *v248; // edi + unsigned int v249; // ecx + unsigned int v250; // ecx + _BYTE *v251; // edi + unsigned int v252; // ecx + signed int v253; // edx + _BYTE *v254; // edi + unsigned int v255; // ecx + unsigned int v256; // ecx + _BYTE *v257; // edi + unsigned int v258; // ecx + signed int jj; // edx + unsigned int v260; // ecx + unsigned int v261; // ecx + _BYTE *v262; // edi + unsigned int v263; // ecx + _BYTE *v264; // edi + signed int v265; // edx + unsigned int v266; // ecx + unsigned int v267; // ecx + _BYTE *v268; // edi + unsigned int v269; // ecx + signed int kk; // edx + _BYTE *v271; // edi + unsigned int v272; // ecx + unsigned int v273; // ecx + _BYTE *v274; // edi + unsigned int v275; // ecx + signed int v276; // edx + signed int v277; // ecx + _BYTE *v278; // edi + signed int v279; // ecx + signed int ll; // edx + unsigned int v281; // ecx + unsigned int v282; // ecx + _BYTE *v283; // edi + unsigned int v284; // ecx + unsigned int v285; // edi + signed int v286; // edx + signed int v287; // ecx + _BYTE *v288; // edi + signed int v289; // ecx + int v290; // [esp-14h] [ebp-18h] + int v291; // [esp-14h] [ebp-18h] + + world_4B3265 = (int)speed_cel_frame_num_from_light_index_frame_num; + v2 = (unsigned int)a1; + if ( !(_BYTE)light_table_index ) + { + if ( level_cel_block & 0x8000 ) + level_cel_block = *(_DWORD *)(((level_cel_block & 0xFFF) << 6) + world_4B3265) + + (unsigned short)(level_cel_block & 0xF000); + v6 = (char *)pDungeonCels + *((_DWORD *)pDungeonCels + (level_cel_block & 0xFFF)); + v8 = level_cel_block; + _LOBYTE(v8) = BYTE1(v8); + v7 = ((v8 >> 4) & 7) + 8; + goto LABEL_11; + } + if ( (_BYTE)light_table_index != lightmax ) + { + if ( !(level_cel_block & 0x8000) ) + { + v3 = (unsigned char *)pDungeonCels + *((_DWORD *)pDungeonCels + (level_cel_block & 0xFFF)); + v4 = dword_646A20 + (light_table_index << 8); + v5 = (unsigned char)(BYTE1(level_cel_block) >> 4); + if ( BYTE1(level_cel_block) >> 4 ) + { + switch ( v5 ) + { + case 1: + world_4B325C = (unsigned char)a1 & 1; + v18 = 32; + do + { + v19 = 32; + do + { + while ( 1 ) + { + v20 = (unsigned char)*v3++; + if ( (v20 & 0x80u) == 0 ) + break; + _LOBYTE(v20) = -(char)v20; + v2 += v20; + v19 -= v20; + if ( !v19 ) + goto LABEL_67; + } + v21 = v19 - v20; + if ( v2 < screen_buf_end ) + return; + if ( (v2 & 1) == world_4B325C ) + { + v290 = v21; + v22 = v20 >> 1; + if ( v20 & 1 ) + { + ++v3; + ++v2; + v23 = v22 & 1; + v26 = v20 >> 2; + if ( v23 ) + { + _LOBYTE(v21) = *v3; + v3 += 2; + *(_BYTE *)v2 = *(_BYTE *)(v4 + v21); + v2 += 2; + } + if ( (_BYTE)v26 ) + { + do + { + v27 = *(_DWORD *)v3; + v3 += 4; + _LOBYTE(v21) = v27; + *(_BYTE *)v2 = *(_BYTE *)(v4 + v21); + _LOBYTE(v21) = BYTE2(v27); + v2 += 4; + --v26; + *(_BYTE *)(v2 - 2) = *(_BYTE *)(v4 + v21); + } + while ( v26 ); + } + } + else + { + v23 = v22 & 1; + v24 = v20 >> 2; + if ( v23 ) + { + _LOBYTE(v21) = v3[1]; + v3 += 2; + *(_BYTE *)(v2 + 1) = *(_BYTE *)(v4 + v21); + v2 += 2; + } + if ( (_BYTE)v24 ) + { + do + { + v25 = *(_DWORD *)v3; + v3 += 4; + _LOBYTE(v21) = BYTE1(v25); + v25 >>= 16; + *(_BYTE *)(v2 + 1) = *(_BYTE *)(v4 + v21); + _LOBYTE(v21) = BYTE1(v25); + v2 += 4; + --v24; + *(_BYTE *)(v2 - 1) = *(_BYTE *)(v4 + v21); + } + while ( v24 ); + } + } + v19 = v290; + } + else + { + v291 = v21; + v28 = v20 >> 1; + if ( v20 & 1 ) + { + _LOBYTE(v21) = *v3++; + *(_BYTE *)v2++ = *(_BYTE *)(v4 + v21); + v23 = v28 & 1; + v31 = v20 >> 2; + if ( v23 ) + { + _LOBYTE(v21) = v3[1]; + v3 += 2; + *(_BYTE *)(v2 + 1) = *(_BYTE *)(v4 + v21); + v2 += 2; + } + if ( (_BYTE)v31 ) + { + do + { + v32 = *(_DWORD *)v3; + v3 += 4; + _LOBYTE(v21) = BYTE1(v32); + v32 >>= 16; + *(_BYTE *)(v2 + 1) = *(_BYTE *)(v4 + v21); + _LOBYTE(v21) = BYTE1(v32); + v2 += 4; + --v31; + *(_BYTE *)(v2 - 1) = *(_BYTE *)(v4 + v21); + } + while ( v31 ); + } + } + else + { + v23 = v28 & 1; + v29 = v20 >> 2; + if ( v23 ) + { + _LOBYTE(v21) = *v3; + v3 += 2; + *(_BYTE *)v2 = *(_BYTE *)(v4 + v21); + v2 += 2; + } + if ( (_BYTE)v29 ) + { + do + { + v30 = *(_DWORD *)v3; + v3 += 4; + _LOBYTE(v21) = v30; + *(_BYTE *)v2 = *(_BYTE *)(v4 + v21); + _LOBYTE(v21) = BYTE2(v30); + v2 += 4; + --v29; + *(_BYTE *)(v2 - 2) = *(_BYTE *)(v4 + v21); + } + while ( v29 ); + } + } + v19 = v291; + } + } + while ( v19 ); +LABEL_67: + world_4B325C = ((_BYTE)world_4B325C + 1) & 1; + v2 -= 800; + --v18; + } + while ( v18 ); + break; + case 2: + world_4B325C = 0; + v33 = 30; + while ( v2 >= screen_buf_end ) + { + v34 = (_BYTE *)(v33 + v2); + v35 = 32 - v33; + world_4B325C = ((_BYTE)world_4B325C + 1) & 1; + if ( world_4B325C ) + { + v36 = v35 & 2; + v3 += v36; + v23 = v35 & 1; + v37 = v35 >> 1; + if ( v23 ) + { + ++v3; + ++v34; + v23 = v37 & 1; + v40 = v37 >> 1; + if ( v23 ) + { + _LOBYTE(v36) = *v3; + v3 += 2; + *v34 = *(_BYTE *)(v4 + v36); + v34 += 2; + } + if ( (_BYTE)v40 ) + { + do + { + v41 = *(_DWORD *)v3; + v3 += 4; + _LOBYTE(v36) = v41; + *v34 = *(_BYTE *)(v4 + v36); + _LOBYTE(v36) = BYTE2(v41); + v34 += 4; + --v40; + *(v34 - 2) = *(_BYTE *)(v4 + v36); + } + while ( v40 ); + } + } + else + { + v23 = v37 & 1; + v38 = v37 >> 1; + if ( v23 ) + { + _LOBYTE(v36) = v3[1]; + v3 += 2; + v34[1] = *(_BYTE *)(v4 + v36); + v34 += 2; + } + if ( (_BYTE)v38 ) + { + do + { + v39 = *(_DWORD *)v3; + v3 += 4; + _LOBYTE(v36) = BYTE1(v39); + v39 >>= 16; + v34[1] = *(_BYTE *)(v4 + v36); + _LOBYTE(v36) = BYTE1(v39); + v34 += 4; + --v38; + *(v34 - 1) = *(_BYTE *)(v4 + v36); + } + while ( v38 ); + } + } + } + else + { + v42 = v35 & 2; + v3 += v42; + v23 = v35 & 1; + v43 = v35 >> 1; + if ( v23 ) + { + _LOBYTE(v42) = *v3++; + *v34++ = *(_BYTE *)(v4 + v42); + v23 = v43 & 1; + v46 = v43 >> 1; + if ( v23 ) + { + _LOBYTE(v42) = v3[1]; + v3 += 2; + v34[1] = *(_BYTE *)(v4 + v42); + v34 += 2; + } + if ( (_BYTE)v46 ) + { + do + { + v47 = *(_DWORD *)v3; + v3 += 4; + _LOBYTE(v42) = BYTE1(v47); + v47 >>= 16; + v34[1] = *(_BYTE *)(v4 + v42); + _LOBYTE(v42) = BYTE1(v47); + v34 += 4; + --v46; + *(v34 - 1) = *(_BYTE *)(v4 + v42); + } + while ( v46 ); + } + } + else + { + v23 = v43 & 1; + v44 = v43 >> 1; + if ( v23 ) + { + _LOBYTE(v42) = *v3; + v3 += 2; + *v34 = *(_BYTE *)(v4 + v42); + v34 += 2; + } + if ( (_BYTE)v44 ) + { + do + { + v45 = *(_DWORD *)v3; + v3 += 4; + _LOBYTE(v42) = v45; + *v34 = *(_BYTE *)(v4 + v42); + _LOBYTE(v42) = BYTE2(v45); + v34 += 4; + --v44; + *(v34 - 2) = *(_BYTE *)(v4 + v42); + } + while ( v44 ); + } + } + } + v2 = (unsigned int)(v34 - 800); + v48 = __OFSUB__(v33, 2); + v33 -= 2; + if ( (v33 < 0) ^ v48 ) + { + v49 = 2; + do + { + if ( v2 < screen_buf_end ) + break; + v50 = (_BYTE *)(v49 + v2); + v51 = 32 - v49; + world_4B325C = ((_BYTE)world_4B325C + 1) & 1; + if ( world_4B325C ) + { + v52 = v51 & 2; + v3 += v52; + v23 = v51 & 1; + v53 = v51 >> 1; + if ( v23 ) + { + ++v3; + ++v50; + v23 = v53 & 1; + v56 = v53 >> 1; + if ( v23 ) + { + _LOBYTE(v52) = *v3; + v3 += 2; + *v50 = *(_BYTE *)(v4 + v52); + v50 += 2; + } + if ( (_BYTE)v56 ) + { + do + { + v57 = *(_DWORD *)v3; + v3 += 4; + _LOBYTE(v52) = v57; + *v50 = *(_BYTE *)(v4 + v52); + _LOBYTE(v52) = BYTE2(v57); + v50 += 4; + --v56; + *(v50 - 2) = *(_BYTE *)(v4 + v52); + } + while ( v56 ); + } + } + else + { + v23 = v53 & 1; + v54 = v53 >> 1; + if ( v23 ) + { + _LOBYTE(v52) = v3[1]; + v3 += 2; + v50[1] = *(_BYTE *)(v4 + v52); + v50 += 2; + } + if ( (_BYTE)v54 ) + { + do + { + v55 = *(_DWORD *)v3; + v3 += 4; + _LOBYTE(v52) = BYTE1(v55); + v55 >>= 16; + v50[1] = *(_BYTE *)(v4 + v52); + _LOBYTE(v52) = BYTE1(v55); + v50 += 4; + --v54; + *(v50 - 1) = *(_BYTE *)(v4 + v52); + } + while ( v54 ); + } + } + } + else + { + v58 = v51 & 2; + v3 += v58; + v23 = v51 & 1; + v59 = v51 >> 1; + if ( v23 ) + { + _LOBYTE(v58) = *v3++; + *v50++ = *(_BYTE *)(v4 + v58); + v23 = v59 & 1; + v62 = v59 >> 1; + if ( v23 ) + { + _LOBYTE(v58) = v3[1]; + v3 += 2; + v50[1] = *(_BYTE *)(v4 + v58); + v50 += 2; + } + if ( (_BYTE)v62 ) + { + do + { + v63 = *(_DWORD *)v3; + v3 += 4; + _LOBYTE(v58) = BYTE1(v63); + v63 >>= 16; + v50[1] = *(_BYTE *)(v4 + v58); + _LOBYTE(v58) = BYTE1(v63); + v50 += 4; + --v62; + *(v50 - 1) = *(_BYTE *)(v4 + v58); + } + while ( v62 ); + } + } + else + { + v23 = v59 & 1; + v60 = v59 >> 1; + if ( v23 ) + { + _LOBYTE(v58) = *v3; + v3 += 2; + *v50 = *(_BYTE *)(v4 + v58); + v50 += 2; + } + if ( (_BYTE)v60 ) + { + do + { + v61 = *(_DWORD *)v3; + v3 += 4; + _LOBYTE(v58) = v61; + *v50 = *(_BYTE *)(v4 + v58); + _LOBYTE(v58) = BYTE2(v61); + v50 += 4; + --v60; + *(v50 - 2) = *(_BYTE *)(v4 + v58); + } + while ( v60 ); + } + } + } + v2 = (unsigned int)(v50 - 800); + v49 += 2; + } + while ( v49 != 32 ); + return; + } + } + break; + case 3: + world_4B325C = 0; + v64 = 30; + while ( v2 >= screen_buf_end ) + { + v65 = 32 - v64; + world_4B325C = ((_BYTE)world_4B325C + 1) & 1; + if ( world_4B325C ) + { + v23 = v65 & 1; + v66 = v65 >> 1; + if ( v23 ) + { + ++v3; + ++v2; + v23 = v66 & 1; + v69 = v66 >> 1; + if ( v23 ) + { + _LOBYTE(v1) = *v3; + v3 += 2; + *(_BYTE *)v2 = *(_BYTE *)(v4 + v1); + v2 += 2; + } + if ( (_BYTE)v69 ) + { + do + { + v70 = *(_DWORD *)v3; + v3 += 4; + _LOBYTE(v1) = v70; + *(_BYTE *)v2 = *(_BYTE *)(v4 + v1); + _LOBYTE(v1) = BYTE2(v70); + v2 += 4; + --v69; + *(_BYTE *)(v2 - 2) = *(_BYTE *)(v4 + v1); + } + while ( v69 ); + } + } + else + { + v23 = v66 & 1; + v67 = v66 >> 1; + if ( v23 ) + { + _LOBYTE(v1) = v3[1]; + v3 += 2; + *(_BYTE *)(v2 + 1) = *(_BYTE *)(v4 + v1); + v2 += 2; + } + if ( (_BYTE)v67 ) + { + do + { + v68 = *(_DWORD *)v3; + v3 += 4; + _LOBYTE(v1) = BYTE1(v68); + v68 >>= 16; + *(_BYTE *)(v2 + 1) = *(_BYTE *)(v4 + v1); + _LOBYTE(v1) = BYTE1(v68); + v2 += 4; + --v67; + *(_BYTE *)(v2 - 1) = *(_BYTE *)(v4 + v1); + } + while ( v67 ); + } + } + v1 = (unsigned char)v3 & 2; + v3 += v1; + } + else + { + v23 = v65 & 1; + v71 = v65 >> 1; + if ( v23 ) + { + _LOBYTE(v1) = *v3++; + *(_BYTE *)v2++ = *(_BYTE *)(v4 + v1); + v23 = v71 & 1; + v74 = v71 >> 1; + if ( v23 ) + { + _LOBYTE(v1) = v3[1]; + v3 += 2; + *(_BYTE *)(v2 + 1) = *(_BYTE *)(v4 + v1); + v2 += 2; + } + if ( (_BYTE)v74 ) + { + do + { + v75 = *(_DWORD *)v3; + v3 += 4; + _LOBYTE(v1) = BYTE1(v75); + v75 >>= 16; + *(_BYTE *)(v2 + 1) = *(_BYTE *)(v4 + v1); + _LOBYTE(v1) = BYTE1(v75); + v2 += 4; + --v74; + *(_BYTE *)(v2 - 1) = *(_BYTE *)(v4 + v1); + } + while ( v74 ); + } + } + else + { + v23 = v71 & 1; + v72 = v71 >> 1; + if ( v23 ) + { + _LOBYTE(v1) = *v3; + v3 += 2; + *(_BYTE *)v2 = *(_BYTE *)(v4 + v1); + v2 += 2; + } + if ( (_BYTE)v72 ) + { + do + { + v73 = *(_DWORD *)v3; + v3 += 4; + _LOBYTE(v1) = v73; + *(_BYTE *)v2 = *(_BYTE *)(v4 + v1); + _LOBYTE(v1) = BYTE2(v73); + v2 += 4; + --v72; + *(_BYTE *)(v2 - 2) = *(_BYTE *)(v4 + v1); + } + while ( v72 ); + } + } + v1 = (unsigned char)v3 & 2; + v3 += v1; + } + v2 = v64 + v2 - 800; + v48 = __OFSUB__(v64, 2); + v64 -= 2; + if ( (v64 < 0) ^ v48 ) + { + v76 = 2; + do + { + if ( v2 < screen_buf_end ) + break; + v77 = 32 - v76; + world_4B325C = ((_BYTE)world_4B325C + 1) & 1; + if ( world_4B325C ) + { + v23 = v77 & 1; + v78 = v77 >> 1; + if ( v23 ) + { + ++v3; + ++v2; + v23 = v78 & 1; + v81 = v78 >> 1; + if ( v23 ) + { + _LOBYTE(v1) = *v3; + v3 += 2; + *(_BYTE *)v2 = *(_BYTE *)(v4 + v1); + v2 += 2; + } + if ( (_BYTE)v81 ) + { + do + { + v82 = *(_DWORD *)v3; + v3 += 4; + _LOBYTE(v1) = v82; + *(_BYTE *)v2 = *(_BYTE *)(v4 + v1); + _LOBYTE(v1) = BYTE2(v82); + v2 += 4; + --v81; + *(_BYTE *)(v2 - 2) = *(_BYTE *)(v4 + v1); + } + while ( v81 ); + } + } + else + { + v23 = v78 & 1; + v79 = v78 >> 1; + if ( v23 ) + { + _LOBYTE(v1) = v3[1]; + v3 += 2; + *(_BYTE *)(v2 + 1) = *(_BYTE *)(v4 + v1); + v2 += 2; + } + if ( (_BYTE)v79 ) + { + do + { + v80 = *(_DWORD *)v3; + v3 += 4; + _LOBYTE(v1) = BYTE1(v80); + v80 >>= 16; + *(_BYTE *)(v2 + 1) = *(_BYTE *)(v4 + v1); + _LOBYTE(v1) = BYTE1(v80); + v2 += 4; + --v79; + *(_BYTE *)(v2 - 1) = *(_BYTE *)(v4 + v1); + } + while ( v79 ); + } + } + v1 = (unsigned char)v3 & 2; + v3 += v1; + } + else + { + v23 = v77 & 1; + v83 = v77 >> 1; + if ( v23 ) + { + _LOBYTE(v1) = *v3++; + *(_BYTE *)v2++ = *(_BYTE *)(v4 + v1); + v23 = v83 & 1; + v86 = v83 >> 1; + if ( v23 ) + { + _LOBYTE(v1) = v3[1]; + v3 += 2; + *(_BYTE *)(v2 + 1) = *(_BYTE *)(v4 + v1); + v2 += 2; + } + if ( (_BYTE)v86 ) + { + do + { + v87 = *(_DWORD *)v3; + v3 += 4; + _LOBYTE(v1) = BYTE1(v87); + v87 >>= 16; + *(_BYTE *)(v2 + 1) = *(_BYTE *)(v4 + v1); + _LOBYTE(v1) = BYTE1(v87); + v2 += 4; + --v86; + *(_BYTE *)(v2 - 1) = *(_BYTE *)(v4 + v1); + } + while ( v86 ); + } + } + else + { + v23 = v83 & 1; + v84 = v83 >> 1; + if ( v23 ) + { + _LOBYTE(v1) = *v3; + v3 += 2; + *(_BYTE *)v2 = *(_BYTE *)(v4 + v1); + v2 += 2; + } + if ( (_BYTE)v84 ) + { + do + { + v85 = *(_DWORD *)v3; + v3 += 4; + _LOBYTE(v1) = v85; + *(_BYTE *)v2 = *(_BYTE *)(v4 + v1); + _LOBYTE(v1) = BYTE2(v85); + v2 += 4; + --v84; + *(_BYTE *)(v2 - 2) = *(_BYTE *)(v4 + v1); + } + while ( v84 ); + } + } + v1 = (unsigned char)v3 & 2; + v3 += v1; + } + v2 = v76 + v2 - 800; + v76 += 2; + } + while ( v76 != 32 ); + return; + } + } + break; + case 4: + world_4B325C = 0; + v88 = 30; + while ( v2 >= screen_buf_end ) + { + v89 = (_BYTE *)(v88 + v2); + v90 = 32 - v88; + world_4B325C = ((_BYTE)world_4B325C + 1) & 1; + if ( world_4B325C ) + { + v91 = v90 & 2; + v3 += v91; + v23 = v90 & 1; + v92 = v90 >> 1; + if ( v23 ) + { + ++v3; + ++v89; + v23 = v92 & 1; + v95 = v92 >> 1; + if ( v23 ) + { + _LOBYTE(v91) = *v3; + v3 += 2; + *v89 = *(_BYTE *)(v4 + v91); + v89 += 2; + } + if ( (_BYTE)v95 ) + { + do + { + v96 = *(_DWORD *)v3; + v3 += 4; + _LOBYTE(v91) = v96; + *v89 = *(_BYTE *)(v4 + v91); + _LOBYTE(v91) = BYTE2(v96); + v89 += 4; + --v95; + *(v89 - 2) = *(_BYTE *)(v4 + v91); + } + while ( v95 ); + } + } + else + { + v23 = v92 & 1; + v93 = v92 >> 1; + if ( v23 ) + { + _LOBYTE(v91) = v3[1]; + v3 += 2; + v89[1] = *(_BYTE *)(v4 + v91); + v89 += 2; + } + if ( (_BYTE)v93 ) + { + do + { + v94 = *(_DWORD *)v3; + v3 += 4; + _LOBYTE(v91) = BYTE1(v94); + v94 >>= 16; + v89[1] = *(_BYTE *)(v4 + v91); + _LOBYTE(v91) = BYTE1(v94); + v89 += 4; + --v93; + *(v89 - 1) = *(_BYTE *)(v4 + v91); + } + while ( v93 ); + } + } + } + else + { + v91 = v90 & 2; + v3 += v91; + v23 = v90 & 1; + v97 = v90 >> 1; + if ( v23 ) + { + _LOBYTE(v91) = *v3++; + *v89++ = *(_BYTE *)(v4 + v91); + v23 = v97 & 1; + v100 = v97 >> 1; + if ( v23 ) + { + _LOBYTE(v91) = v3[1]; + v3 += 2; + v89[1] = *(_BYTE *)(v4 + v91); + v89 += 2; + } + if ( (_BYTE)v100 ) + { + do + { + v101 = *(_DWORD *)v3; + v3 += 4; + _LOBYTE(v91) = BYTE1(v101); + v101 >>= 16; + v89[1] = *(_BYTE *)(v4 + v91); + _LOBYTE(v91) = BYTE1(v101); + v89 += 4; + --v100; + *(v89 - 1) = *(_BYTE *)(v4 + v91); + } + while ( v100 ); + } + } + else + { + v23 = v97 & 1; + v98 = v97 >> 1; + if ( v23 ) + { + _LOBYTE(v91) = *v3; + v3 += 2; + *v89 = *(_BYTE *)(v4 + v91); + v89 += 2; + } + if ( (_BYTE)v98 ) + { + do + { + v99 = *(_DWORD *)v3; + v3 += 4; + _LOBYTE(v91) = v99; + *v89 = *(_BYTE *)(v4 + v91); + _LOBYTE(v91) = BYTE2(v99); + v89 += 4; + --v98; + *(v89 - 2) = *(_BYTE *)(v4 + v91); + } + while ( v98 ); + } + } + } + v2 = (unsigned int)(v89 - 800); + v48 = __OFSUB__(v88, 2); + v88 -= 2; + if ( (v88 < 0) ^ v48 ) + { + v102 = 8; + do + { + if ( v2 < screen_buf_end ) + break; + v103 = 8; + do + { + v104 = *(_DWORD *)v3; + v3 += 4; + _LOBYTE(v91) = BYTE1(v104); + v104 >>= 16; + *(_BYTE *)(v2 + 1) = *(_BYTE *)(v4 + v91); + _LOBYTE(v91) = BYTE1(v104); + v2 += 4; + --v103; + *(_BYTE *)(v2 - 1) = *(_BYTE *)(v4 + v91); + } + while ( v103 ); + v105 = (_BYTE *)(v2 - 800); + if ( (unsigned int)v105 < screen_buf_end ) + break; + v106 = 8; + do + { + v107 = *(_DWORD *)v3; + v3 += 4; + _LOBYTE(v91) = v107; + *v105 = *(_BYTE *)(v4 + v91); + _LOBYTE(v91) = BYTE2(v107); + v105 += 4; + --v106; + *(v105 - 2) = *(_BYTE *)(v4 + v91); + } + while ( v106 ); + v2 = (unsigned int)(v105 - 800); + --v102; + } + while ( v102 ); + return; + } + } + break; + default: + world_4B325C = 0; + v108 = 30; + while ( v2 >= screen_buf_end ) + { + v109 = 32 - v108; + world_4B325C = ((_BYTE)world_4B325C + 1) & 1; + if ( world_4B325C ) + { + v23 = v109 & 1; + v110 = v109 >> 1; + if ( v23 ) + { + ++v3; + ++v2; + v23 = v110 & 1; + v113 = v110 >> 1; + if ( v23 ) + { + _LOBYTE(v1) = *v3; + v3 += 2; + *(_BYTE *)v2 = *(_BYTE *)(v4 + v1); + v2 += 2; + } + if ( (_BYTE)v113 ) + { + do + { + v114 = *(_DWORD *)v3; + v3 += 4; + _LOBYTE(v1) = v114; + *(_BYTE *)v2 = *(_BYTE *)(v4 + v1); + _LOBYTE(v1) = BYTE2(v114); + v2 += 4; + --v113; + *(_BYTE *)(v2 - 2) = *(_BYTE *)(v4 + v1); + } + while ( v113 ); + } + } + else + { + v23 = v110 & 1; + v111 = v110 >> 1; + if ( v23 ) + { + _LOBYTE(v1) = v3[1]; + v3 += 2; + *(_BYTE *)(v2 + 1) = *(_BYTE *)(v4 + v1); + v2 += 2; + } + if ( (_BYTE)v111 ) + { + do + { + v112 = *(_DWORD *)v3; + v3 += 4; + _LOBYTE(v1) = BYTE1(v112); + v112 >>= 16; + *(_BYTE *)(v2 + 1) = *(_BYTE *)(v4 + v1); + _LOBYTE(v1) = BYTE1(v112); + v2 += 4; + --v111; + *(_BYTE *)(v2 - 1) = *(_BYTE *)(v4 + v1); + } + while ( v111 ); + } + } + v1 = (unsigned char)v3 & 2; + v3 += v1; + } + else + { + v23 = v109 & 1; + v115 = v109 >> 1; + if ( v23 ) + { + _LOBYTE(v1) = *v3++; + *(_BYTE *)v2++ = *(_BYTE *)(v4 + v1); + v23 = v115 & 1; + v118 = v115 >> 1; + if ( v23 ) + { + _LOBYTE(v1) = v3[1]; + v3 += 2; + *(_BYTE *)(v2 + 1) = *(_BYTE *)(v4 + v1); + v2 += 2; + } + if ( (_BYTE)v118 ) + { + do + { + v119 = *(_DWORD *)v3; + v3 += 4; + _LOBYTE(v1) = BYTE1(v119); + v119 >>= 16; + *(_BYTE *)(v2 + 1) = *(_BYTE *)(v4 + v1); + _LOBYTE(v1) = BYTE1(v119); + v2 += 4; + --v118; + *(_BYTE *)(v2 - 1) = *(_BYTE *)(v4 + v1); + } + while ( v118 ); + } + } + else + { + v23 = v115 & 1; + v116 = v115 >> 1; + if ( v23 ) + { + _LOBYTE(v1) = *v3; + v3 += 2; + *(_BYTE *)v2 = *(_BYTE *)(v4 + v1); + v2 += 2; + } + if ( (_BYTE)v116 ) + { + do + { + v117 = *(_DWORD *)v3; + v3 += 4; + _LOBYTE(v1) = v117; + *(_BYTE *)v2 = *(_BYTE *)(v4 + v1); + _LOBYTE(v1) = BYTE2(v117); + v2 += 4; + --v116; + *(_BYTE *)(v2 - 2) = *(_BYTE *)(v4 + v1); + } + while ( v116 ); + } + } + v1 = (unsigned char)v3 & 2; + v3 += v1; + } + v2 = v108 + v2 - 800; + v48 = __OFSUB__(v108, 2); + v108 -= 2; + if ( (v108 < 0) ^ v48 ) + { + v120 = 8; + do + { + if ( v2 < screen_buf_end ) + break; + v121 = 8; + do + { + v122 = *(_DWORD *)v3; + v3 += 4; + _LOBYTE(v1) = BYTE1(v122); + v122 >>= 16; + *(_BYTE *)(v2 + 1) = *(_BYTE *)(v4 + v1); + _LOBYTE(v1) = BYTE1(v122); + v2 += 4; + --v121; + *(_BYTE *)(v2 - 1) = *(_BYTE *)(v4 + v1); + } + while ( v121 ); + v123 = (_BYTE *)(v2 - 800); + if ( (unsigned int)v123 < screen_buf_end ) + break; + v124 = 8; + do + { + v125 = *(_DWORD *)v3; + v3 += 4; + _LOBYTE(v1) = v125; + *v123 = *(_BYTE *)(v4 + v1); + _LOBYTE(v1) = BYTE2(v125); + v123 += 4; + --v124; + *(v123 - 2) = *(_BYTE *)(v4 + v1); + } + while ( v124 ); + v2 = (unsigned int)(v123 - 800); + --v120; + } + while ( v120 ); + return; + } + } + break; + } + } + else + { + v12 = 16; + do + { + if ( v2 < screen_buf_end ) + break; + v13 = 8; + do + { + v14 = *(_DWORD *)v3; + v3 += 4; + _LOBYTE(v1) = BYTE1(v14); + v14 >>= 16; + *(_BYTE *)(v2 + 1) = *(_BYTE *)(v4 + v1); + _LOBYTE(v1) = BYTE1(v14); + v2 += 4; + --v13; + *(_BYTE *)(v2 - 1) = *(_BYTE *)(v4 + v1); + } + while ( v13 ); + v15 = (_BYTE *)(v2 - 800); + if ( (unsigned int)v15 < screen_buf_end ) + break; + v16 = 8; + do + { + v17 = *(_DWORD *)v3; + v3 += 4; + _LOBYTE(v1) = v17; + *v15 = *(_BYTE *)(v4 + v1); + _LOBYTE(v1) = BYTE2(v17); + v15 += 4; + --v16; + *(v15 - 2) = *(_BYTE *)(v4 + v1); + } + while ( v16 ); + v2 = (unsigned int)(v15 - 800); + --v12; + } + while ( v12 ); + } + return; + } + v6 = (char *)pSpeedCels + *(_DWORD *)(4 * (light_table_index + 16 * (level_cel_block & 0xFFF)) + world_4B3265); + v7 = (unsigned char)(BYTE1(level_cel_block) >> 4); +LABEL_11: + if ( v7 == 8 ) + { + v126 = 16; + do + { + if ( v2 < screen_buf_end ) + break; + v127 = 8; + do + { + v128 = *(_DWORD *)v6; + v6 += 4; + v129 = (_BYTE *)(v2 + 1); + v128 = __ROR4__(v128, 8); + *v129 = v128; + v129 += 2; + *v129 = __ROR4__(v128, 16); + v2 = (unsigned int)(v129 + 1); + --v127; + } + while ( v127 ); + v130 = (_BYTE *)(v2 - 800); + if ( (unsigned int)v130 < screen_buf_end ) + break; + v131 = 8; + do + { + v132 = *(_DWORD *)v6; + v6 += 4; + *v130 = v132; + v133 = v130 + 2; + *v133 = __ROR4__(v132, 16); + v130 = v133 + 2; + --v131; + } + while ( v131 ); + v2 = (unsigned int)(v130 - 800); + --v126; + } + while ( v126 ); + return; + } + if ( v7 != 9 ) + { + switch ( v7 ) + { + case 10: + world_4B325C = 0; + v149 = 30; + while ( v2 >= screen_buf_end ) + { + v150 = (_BYTE *)(v149 + v2); + v151 = 32 - v149; + v152 = ((_BYTE)world_4B325C + 1) & 1; + world_4B325C = ((_BYTE)world_4B325C + 1) & 1; + if ( world_4B325C ) + { + v23 = __CFSHR__(v151, 2); + v153 = v151 >> 2; + if ( !v23 + || (_LOWORD(v152) = *((_WORD *)v6 + 1), + v6 += 4, + v154 = v150 + 1, + *v154 = __ROR4__(v152, 8), + v150 = v154 + 1, + v153) ) + { + do + { + v155 = *(_DWORD *)v6; + v6 += 4; + v156 = v150 + 1; + v155 = __ROR4__(v155, 8); + *v156 = v155; + v156 += 2; + *v156 = __ROR4__(v155, 16); + v150 = v156 + 1; + --v153; + } + while ( v153 ); + } + } + else + { + v23 = __CFSHR__(v151, 2); + v157 = v151 >> 2; + if ( !v23 || (v158 = *((_WORD *)v6 + 1), v6 += 4, *v150 = v158, v150 += 2, v157) ) + { + do + { + v159 = *(_DWORD *)v6; + v6 += 4; + *v150 = v159; + v160 = v150 + 2; + *v160 = __ROR4__(v159, 16); + v150 = v160 + 2; + --v157; + } + while ( v157 ); + } + } + v2 = (unsigned int)(v150 - 800); + v48 = __OFSUB__(v149, 2); + v149 -= 2; + if ( (v149 < 0) ^ v48 ) + { + v161 = 2; + do + { + if ( v2 < screen_buf_end ) + break; + v162 = (_BYTE *)(v161 + v2); + v163 = 32 - v161; + v164 = ((_BYTE)world_4B325C + 1) & 1; + world_4B325C = ((_BYTE)world_4B325C + 1) & 1; + if ( world_4B325C ) + { + v23 = __CFSHR__(v163, 2); + v165 = v163 >> 2; + if ( !v23 + || (_LOWORD(v164) = *((_WORD *)v6 + 1), + v6 += 4, + v166 = v162 + 1, + *v166 = __ROR4__(v164, 8), + v162 = v166 + 1, + v165) ) + { + do + { + v167 = *(_DWORD *)v6; + v6 += 4; + v168 = v162 + 1; + v167 = __ROR4__(v167, 8); + *v168 = v167; + v168 += 2; + *v168 = __ROR4__(v167, 16); + v162 = v168 + 1; + --v165; + } + while ( v165 ); + } + } + else + { + v23 = __CFSHR__(v163, 2); + v169 = v163 >> 2; + if ( !v23 || (v170 = *((_WORD *)v6 + 1), v6 += 4, *v162 = v170, v162 += 2, v169) ) + { + do + { + v171 = *(_DWORD *)v6; + v6 += 4; + *v162 = v171; + v172 = v162 + 2; + *v172 = __ROR4__(v171, 16); + v162 = v172 + 2; + --v169; + } + while ( v169 ); + } + } + v2 = (unsigned int)(v162 - 800); + v161 += 2; + } + while ( v161 != 32 ); + return; + } + } + break; + case 11: + world_4B325C = 0; + v173 = 30; + while ( v2 >= screen_buf_end ) + { + v174 = 32 - v173; + v175 = ((_BYTE)world_4B325C + 1) & 1; + v176 = 32 - v173; + world_4B325C = ((_BYTE)world_4B325C + 1) & 1; + if ( v175 ) + { + for ( i = v174 >> 2; i; --i ) + { + v178 = *(_DWORD *)v6; + v6 += 4; + v179 = (_BYTE *)(v2 + 1); + v178 = __ROR4__(v178, 8); + *v179 = v178; + v179 += 2; + v175 = __ROR4__(v178, 16); + *v179 = v175; + v2 = (unsigned int)(v179 + 1); + } + v180 = v176 & 2; + if ( v180 ) + { + _LOWORD(v175) = *(_WORD *)v6; + v6 += 4; + v181 = (_BYTE *)(v2 + 1); + *v181 = __ROR4__(v175, 8); + v2 = (unsigned int)(v181 + 1); + } + } + else + { + for ( j = v174 >> 2; j; --j ) + { + v183 = *(_DWORD *)v6; + v6 += 4; + *(_BYTE *)v2 = v183; + v184 = (_BYTE *)(v2 + 2); + *v184 = __ROR4__(v183, 16); + v2 = (unsigned int)(v184 + 2); + } + v180 = v176 & 2; + if ( v180 ) + { + v185 = *(_WORD *)v6; + v6 += 4; + *(_BYTE *)v2 = v185; + v2 += 2; + } + } + v2 = v173 + v2 - 800; + v48 = __OFSUB__(v173, 2); + v173 -= 2; + if ( (v173 < 0) ^ v48 ) + { + v186 = 2; + do + { + if ( v2 < screen_buf_end ) + break; + v187 = 32 - v186; + v188 = ((_BYTE)world_4B325C + 1) & 1; + world_4B325C = ((_BYTE)world_4B325C + 1) & 1; + if ( world_4B325C ) + { + for ( k = v187 >> 2; k; --k ) + { + v190 = *(_DWORD *)v6; + v6 += 4; + v191 = (_BYTE *)(v2 + 1); + v190 = __ROR4__(v190, 8); + *v191 = v190; + v191 += 2; + v188 = __ROR4__(v190, 16); + *v191 = v188; + v2 = (unsigned int)(v191 + 1); + } + v180 &= 2u; + if ( v180 ) + { + _LOWORD(v188) = *(_WORD *)v6; + v6 += 4; + v192 = (_BYTE *)(v2 + 1); + *v192 = __ROR4__(v188, 8); + v2 = (unsigned int)(v192 + 1); + } + } + else + { + for ( l = v187 >> 2; l; --l ) + { + v194 = *(_DWORD *)v6; + v6 += 4; + *(_BYTE *)v2 = v194; + v195 = (_BYTE *)(v2 + 2); + *v195 = __ROR4__(v194, 16); + v2 = (unsigned int)(v195 + 2); + } + v180 &= 2u; + if ( v180 ) + { + v196 = *(_WORD *)v6; + v6 += 4; + *(_BYTE *)v2 = v196; + v2 += 2; + } + } + v2 = v186 + v2 - 800; + v186 += 2; + } + while ( v186 != 32 ); + return; + } + } + break; + case 12: + world_4B325C = 0; + v197 = 30; + while ( v2 >= screen_buf_end ) + { + v198 = (_BYTE *)(v197 + v2); + v199 = 32 - v197; + v200 = ((_BYTE)world_4B325C + 1) & 1; + world_4B325C = ((_BYTE)world_4B325C + 1) & 1; + if ( world_4B325C ) + { + v23 = __CFSHR__(v199, 2); + v201 = v199 >> 2; + if ( !v23 + || (_LOWORD(v200) = *((_WORD *)v6 + 1), + v6 += 4, + v202 = v198 + 1, + *v202 = __ROR4__(v200, 8), + v198 = v202 + 1, + v201) ) + { + do + { + v203 = *(_DWORD *)v6; + v6 += 4; + v204 = v198 + 1; + v203 = __ROR4__(v203, 8); + *v204 = v203; + v204 += 2; + *v204 = __ROR4__(v203, 16); + v198 = v204 + 1; + --v201; + } + while ( v201 ); + } + } + else + { + v23 = __CFSHR__(v199, 2); + v205 = v199 >> 2; + if ( !v23 || (v206 = *((_WORD *)v6 + 1), v6 += 4, *v198 = v206, v198 += 2, v205) ) + { + do + { + v207 = *(_DWORD *)v6; + v6 += 4; + *v198 = v207; + v208 = v198 + 2; + *v208 = __ROR4__(v207, 16); + v198 = v208 + 2; + --v205; + } + while ( v205 ); + } + } + v2 = (unsigned int)(v198 - 800); + v48 = __OFSUB__(v197, 2); + v197 -= 2; + if ( (v197 < 0) ^ v48 ) + { + v209 = 8; + do + { + if ( v2 < screen_buf_end ) + break; + v210 = 8; + do + { + v211 = *(_DWORD *)v6; + v6 += 4; + v212 = (_BYTE *)(v2 + 1); + v211 = __ROR4__(v211, 8); + *v212 = v211; + v212 += 2; + *v212 = __ROR4__(v211, 16); + v2 = (unsigned int)(v212 + 1); + --v210; + } + while ( v210 ); + v213 = (_BYTE *)(v2 - 800); + if ( (unsigned int)v213 < screen_buf_end ) + break; + v214 = 8; + do + { + v215 = *(_DWORD *)v6; + v6 += 4; + *v213 = v215; + v216 = v213 + 2; + *v216 = __ROR4__(v215, 16); + v213 = v216 + 2; + --v214; + } + while ( v214 ); + v2 = (unsigned int)(v213 - 800); + --v209; + } + while ( v209 ); + return; + } + } + break; + default: + world_4B325C = 0; + v217 = 30; + while ( v2 >= screen_buf_end ) + { + v218 = 32 - v217; + v219 = ((_BYTE)world_4B325C + 1) & 1; + world_4B325C = ((_BYTE)world_4B325C + 1) & 1; + if ( world_4B325C ) + { + for ( m = v218 >> 2; m; --m ) + { + v221 = *(_DWORD *)v6; + v6 += 4; + v222 = (_BYTE *)(v2 + 1); + v221 = __ROR4__(v221, 8); + *v222 = v221; + v222 += 2; + v219 = __ROR4__(v221, 16); + *v222 = v219; + v2 = (unsigned int)(v222 + 1); + } + if ( (32 - (_BYTE)v217) & 2 ) + { + _LOWORD(v219) = *(_WORD *)v6; + v6 += 4; + v223 = (_BYTE *)(v2 + 1); + *v223 = __ROR4__(v219, 8); + v2 = (unsigned int)(v223 + 1); + } + } + else + { + for ( n = v218 >> 2; n; --n ) + { + v225 = *(_DWORD *)v6; + v6 += 4; + *(_BYTE *)v2 = v225; + v226 = (_BYTE *)(v2 + 2); + *v226 = __ROR4__(v225, 16); + v2 = (unsigned int)(v226 + 2); + } + if ( (32 - (_BYTE)v217) & 2 ) + { + v227 = *(_WORD *)v6; + v6 += 4; + *(_BYTE *)v2 = v227; + v2 += 2; + } + } + v2 = v217 + v2 - 800; + v48 = __OFSUB__(v217, 2); + v217 -= 2; + if ( (v217 < 0) ^ v48 ) + { + v228 = 8; + do + { + if ( v2 < screen_buf_end ) + break; + v229 = 8; + do + { + v230 = *(_DWORD *)v6; + v6 += 4; + v231 = (_BYTE *)(v2 + 1); + v230 = __ROR4__(v230, 8); + *v231 = v230; + v231 += 2; + *v231 = __ROR4__(v230, 16); + v2 = (unsigned int)(v231 + 1); + --v229; + } + while ( v229 ); + v232 = (_BYTE *)(v2 - 800); + if ( (unsigned int)v232 < screen_buf_end ) + break; + v233 = 8; + do + { + v234 = *(_DWORD *)v6; + v6 += 4; + *v232 = v234; + v235 = v232 + 2; + *v235 = __ROR4__(v234, 16); + v232 = v235 + 2; + --v233; + } + while ( v233 ); + v2 = (unsigned int)(v232 - 800); + --v228; + } + while ( v228 ); + return; + } + } + break; + } + return; + } + world_4B325C = (unsigned char)a1 & 1; + v134 = 32; +LABEL_251: + v135 = 32; + while ( 1 ) + { + while ( 1 ) + { + v136 = (unsigned char)*v6++; + if ( (v136 & 0x80u) == 0 ) + break; + _LOBYTE(v136) = -(char)v136; + v2 += v136; + v135 -= v136; + if ( !v135 ) + { +LABEL_271: + world_4B325C = ((_BYTE)world_4B325C + 1) & 1; + v2 -= 800; + if ( !--v134 ) + return; + goto LABEL_251; + } + } + v135 -= v136; + if ( v2 < screen_buf_end ) + return; + if ( (v2 & 1) == world_4B325C ) + { + v137 = v136 >> 1; + if ( !(v136 & 1) ) + goto LABEL_258; + ++v6; + ++v2; + if ( v137 ) + { +LABEL_265: + v23 = v137 & 1; + v145 = v137 >> 1; + if ( !v23 || (v146 = *v6, v6 += 2, *(_BYTE *)v2 = v146, v2 += 2, v145) ) + { + do + { + v147 = *(_DWORD *)v6; + v6 += 4; + *(_BYTE *)v2 = v147; + v148 = (_BYTE *)(v2 + 2); + *v148 = __ROR4__(v147, 16); + v2 = (unsigned int)(v148 + 2); + --v145; + } + while ( v145 ); + } + goto LABEL_268; + } + } + else + { + v137 = v136 >> 1; + if ( !(v136 & 1) ) + goto LABEL_265; + v144 = *v6++; + *(_BYTE *)v2++ = v144; + if ( v137 ) + { +LABEL_258: + v23 = v137 & 1; + v138 = v137 >> 1; + if ( !v23 + || (v139 = v6 + 1, + v140 = (_BYTE *)(v2 + 1), + v141 = *v139, + v6 = v139 + 1, + *v140 = v141, + v2 = (unsigned int)(v140 + 1), + v138) ) + { + do + { + v142 = *(_DWORD *)v6; + v6 += 4; + v143 = (_BYTE *)(v2 + 1); + v142 = __ROR4__(v142, 8); + *v143 = v142; + v143 += 2; + *v143 = __ROR4__(v142, 16); + v2 = (unsigned int)(v143 + 1); + --v138; + } + while ( v138 ); + } + goto LABEL_268; + } + } +LABEL_268: + if ( !v135 ) + goto LABEL_271; + } + } + if ( level_cel_block & 0x8000 ) + level_cel_block = *(_DWORD *)(((level_cel_block & 0xFFF) << 6) + world_4B3265) + + (unsigned short)(level_cel_block & 0xF000); + v9 = (unsigned char *)pDungeonCels + *((_DWORD *)pDungeonCels + (level_cel_block & 0xFFF)); + v10 = level_cel_block; + _LOBYTE(v10) = BYTE1(v10); + v11 = (v10 >> 4) & 7; + if ( !v11 ) + { + v236 = 16; + do + { + if ( v2 < screen_buf_end ) + break; + v237 = 8; + do + { + *(_BYTE *)(v2 + 1) = 0; + *(_BYTE *)(v2 + 3) = 0; + v2 += 4; + --v237; + } + while ( v237 ); + v238 = (_BYTE *)(v2 - 800); + if ( (unsigned int)v238 < screen_buf_end ) + break; + v239 = 8; + do + { + *v238 = 0; + v238[2] = 0; + v238 += 4; + --v239; + } + while ( v239 ); + v2 = (unsigned int)(v238 - 800); + --v236; + } + while ( v236 ); + return; + } + switch ( (_WORD)v11 ) + { + case 1: + world_4B325C = (unsigned char)a1 & 1; + v240 = 32; + while ( 1 ) + { + v241 = 32; + do + { + while ( 1 ) + { + v242 = *v9++; + if ( (v242 & 0x80u) != 0 ) + break; + v241 -= v242; + if ( v2 < screen_buf_end ) + return; + v9 += v242; + if ( (v2 & 1) == world_4B325C ) + { + v243 = v242 >> 1; + if ( !(v242 & 1) ) + goto LABEL_378; + ++v2; + if ( v243 ) + { +LABEL_385: + v23 = v243 & 1; + v246 = v243 >> 1; + if ( !v23 || (*(_BYTE *)v2 = 0, v2 += 2, v246) ) + { + do + { + *(_BYTE *)v2 = 0; + *(_BYTE *)(v2 + 2) = 0; + v2 += 4; + --v246; + } + while ( v246 ); + } + goto LABEL_388; + } + } + else + { + v243 = v242 >> 1; + if ( !(v242 & 1) ) + goto LABEL_385; + *(_BYTE *)v2++ = 0; + if ( v243 ) + { +LABEL_378: + v23 = v243 & 1; + v244 = v243 >> 1; + if ( !v23 || (v245 = (_BYTE *)(v2 + 1), *v245 = 0, v2 = (unsigned int)(v245 + 1), v244) ) + { + do + { + *(_BYTE *)(v2 + 1) = 0; + *(_BYTE *)(v2 + 3) = 0; + v2 += 4; + --v244; + } + while ( v244 ); + } + goto LABEL_388; + } + } +LABEL_388: + if ( !v241 ) + goto LABEL_391; + } + _LOBYTE(v242) = -(char)v242; + v2 += v242; + v241 -= v242; + } + while ( v241 ); +LABEL_391: + world_4B325C = ((_BYTE)world_4B325C + 1) & 1; + v2 -= 800; + if ( !--v240 ) + return; + } + case 2: + world_4B325C = 0; + for ( ii = 30; ; ii -= 2 ) + { + if ( v2 < screen_buf_end ) + return; + v248 = (_BYTE *)(ii + v2); + v249 = 32 - ii; + world_4B325C = ((_BYTE)world_4B325C + 1) & 1; + if ( world_4B325C ) + { + v23 = __CFSHR__(v249, 2); + v250 = v249 >> 2; + if ( !v23 || (v251 = v248 + 1, *v251 = 0, v248 = v251 + 1, v250) ) + { + do + { + v248[1] = 0; + v248[3] = 0; + v248 += 4; + --v250; + } + while ( v250 ); + } + } + else + { + v23 = __CFSHR__(v249, 2); + v252 = v249 >> 2; + if ( !v23 || (*v248 = 0, v248 += 2, v252) ) + { + do + { + *v248 = 0; + v248[2] = 0; + v248 += 4; + --v252; + } + while ( v252 ); + } + } + v2 = (unsigned int)(v248 - 800); + if ( !ii ) + break; + } + v253 = 2; + do + { + if ( v2 < screen_buf_end ) + break; + v254 = (_BYTE *)(v253 + v2); + v255 = 32 - v253; + world_4B325C = ((_BYTE)world_4B325C + 1) & 1; + if ( world_4B325C ) + { + v23 = __CFSHR__(v255, 2); + v256 = v255 >> 2; + if ( !v23 || (v257 = v254 + 1, *v257 = 0, v254 = v257 + 1, v256) ) + { + do + { + v254[1] = 0; + v254[3] = 0; + v254 += 4; + --v256; + } + while ( v256 ); + } + } + else + { + v23 = __CFSHR__(v255, 2); + v258 = v255 >> 2; + if ( !v23 || (*v254 = 0, v254 += 2, v258) ) + { + do + { + *v254 = 0; + v254[2] = 0; + v254 += 4; + --v258; + } + while ( v258 ); + } + } + v2 = (unsigned int)(v254 - 800); + v253 += 2; + } + while ( v253 != 32 ); + break; + case 3: + world_4B325C = 0; + for ( jj = 30; ; jj -= 2 ) + { + if ( v2 < screen_buf_end ) + return; + v260 = 32 - jj; + world_4B325C = ((_BYTE)world_4B325C + 1) & 1; + if ( world_4B325C ) + { + v23 = __CFSHR__(v260, 2); + v261 = v260 >> 2; + if ( !v23 || (v262 = (_BYTE *)(v2 + 1), *v262 = 0, v2 = (unsigned int)(v262 + 1), v261) ) + { + do + { + *(_BYTE *)(v2 + 1) = 0; + *(_BYTE *)(v2 + 3) = 0; + v2 += 4; + --v261; + } + while ( v261 ); + } + } + else + { + v23 = __CFSHR__(v260, 2); + v263 = v260 >> 2; + if ( !v23 || (*(_BYTE *)v2 = 0, v2 += 2, v263) ) + { + do + { + *(_BYTE *)v2 = 0; + *(_BYTE *)(v2 + 2) = 0; + v2 += 4; + --v263; + } + while ( v263 ); + } + } + v264 = (_BYTE *)(v2 - 800); + if ( !jj ) + break; + v2 = (unsigned int)&v264[jj]; + } + v265 = 2; + do + { + if ( (unsigned int)v264 < screen_buf_end ) + break; + v266 = 32 - v265; + world_4B325C = ((_BYTE)world_4B325C + 1) & 1; + if ( world_4B325C ) + { + v23 = __CFSHR__(v266, 2); + v267 = v266 >> 2; + if ( !v23 || (v268 = v264 + 1, *v268 = 0, v264 = v268 + 1, v267) ) + { + do + { + v264[1] = 0; + v264[3] = 0; + v264 += 4; + --v267; + } + while ( v267 ); + } + } + else + { + v23 = __CFSHR__(v266, 2); + v269 = v266 >> 2; + if ( !v23 || (*v264 = 0, v264 += 2, v269) ) + { + do + { + *v264 = 0; + v264[2] = 0; + v264 += 4; + --v269; + } + while ( v269 ); + } + } + v264 = &v264[v265 - 800]; + v265 += 2; + } + while ( v265 != 32 ); + break; + case 4: + world_4B325C = 0; + for ( kk = 30; ; kk -= 2 ) + { + if ( v2 < screen_buf_end ) + return; + v271 = (_BYTE *)(kk + v2); + v272 = 32 - kk; + world_4B325C = ((_BYTE)world_4B325C + 1) & 1; + if ( world_4B325C ) + { + v23 = __CFSHR__(v272, 2); + v273 = v272 >> 2; + if ( !v23 || (v274 = v271 + 1, *v274 = 0, v271 = v274 + 1, v273) ) + { + do + { + v271[1] = 0; + v271[3] = 0; + v271 += 4; + --v273; + } + while ( v273 ); + } + } + else + { + v23 = __CFSHR__(v272, 2); + v275 = v272 >> 2; + if ( !v23 || (*v271 = 0, v271 += 2, v275) ) + { + do + { + *v271 = 0; + v271[2] = 0; + v271 += 4; + --v275; + } + while ( v275 ); + } + } + v2 = (unsigned int)(v271 - 800); + if ( !kk ) + break; + } + v276 = 8; + do + { + if ( v2 < screen_buf_end ) + break; + v277 = 8; + do + { + *(_BYTE *)(v2 + 1) = 0; + *(_BYTE *)(v2 + 3) = 0; + v2 += 4; + --v277; + } + while ( v277 ); + v278 = (_BYTE *)(v2 - 800); + if ( (unsigned int)v278 < screen_buf_end ) + break; + v279 = 8; + do + { + *v278 = 0; + v278[2] = 0; + v278 += 4; + --v279; + } + while ( v279 ); + v2 = (unsigned int)(v278 - 800); + --v276; + } + while ( v276 ); + break; + default: + world_4B325C = 0; + for ( ll = 30; ; ll -= 2 ) + { + if ( v2 < screen_buf_end ) + return; + v281 = 32 - ll; + world_4B325C = ((_BYTE)world_4B325C + 1) & 1; + if ( world_4B325C ) + { + v23 = __CFSHR__(v281, 2); + v282 = v281 >> 2; + if ( !v23 || (v283 = (_BYTE *)(v2 + 1), *v283 = 0, v2 = (unsigned int)(v283 + 1), v282) ) + { + do + { + *(_BYTE *)(v2 + 1) = 0; + *(_BYTE *)(v2 + 3) = 0; + v2 += 4; + --v282; + } + while ( v282 ); + } + } + else + { + v23 = __CFSHR__(v281, 2); + v284 = v281 >> 2; + if ( !v23 || (*(_BYTE *)v2 = 0, v2 += 2, v284) ) + { + do + { + *(_BYTE *)v2 = 0; + *(_BYTE *)(v2 + 2) = 0; + v2 += 4; + --v284; + } + while ( v284 ); + } + } + v285 = v2 - 800; + if ( !ll ) + break; + v2 = ll + v285; + } + v286 = 8; + do + { + if ( v285 < screen_buf_end ) + break; + v287 = 8; + do + { + *(_BYTE *)(v285 + 1) = 0; + *(_BYTE *)(v285 + 3) = 0; + v285 += 4; + --v287; + } + while ( v287 ); + v288 = (_BYTE *)(v285 - 800); + if ( (unsigned int)v288 < screen_buf_end ) + break; + v289 = 8; + do + { + *v288 = 0; + v288[2] = 0; + v288 += 4; + --v289; + } + while ( v289 ); + v285 = (unsigned int)(v288 - 800); + --v286; + } + while ( v286 ); + break; + } +} +// 642A14: using guessed type char lightmax; +// 69BEF8: using guessed type int light_table_index; +// 69CF0C: using guessed type int screen_buf_end; +// 69CF14: using guessed type int level_cel_block; + +//----- (0046468D) -------------------------------------------------------- +void __fastcall drawBottomArchesUpperScreen(void *a1, int a2) +{ + _BYTE *v2; // edi + char *v3; // esi + short v5; // ax + char *v6; // esi + short v7; // ax + unsigned int v8; // eax + unsigned char *v9; // esi + unsigned int v10; // eax + int v11; // eax + int v12; // edx + int v13; // edx + signed int v14; // ecx + unsigned char v16; // cf + int v18; // ecx + signed int v19; // edx + int v20; // eax + int v21; // edx + int v22; // ecx + int v23; // edx + signed int v26; // edx + _WORD *v27; // edi + unsigned int v28; // ecx + unsigned char v31; // of + signed int v32; // edx + _WORD *v33; // edi + unsigned int v34; // ecx + signed int v37; // edx + unsigned int l; // ecx + signed int v41; // edx + unsigned int m; // ecx + signed int v45; // edx + _WORD *v46; // edi + unsigned int v47; // ecx + int v50; // edx + int v51; // edx + signed int v52; // ecx + signed int v55; // edx + unsigned int n; // ecx + int v59; // edx + int v60; // edx + signed int v61; // ecx + int v64; // edx + int v65; // edx + signed int v66; // ecx + char v67; // al + int v68; // ecx + signed int v69; // edx + int v70; // eax + int v71; // edx + int v72; // edx + int v73; // ecx + char v74; // al + signed int v75; // edx + _DWORD *v76; // edi + unsigned int v77; // ecx + short v78; // ax + int v79; // eax + signed int v80; // edx + _WORD *v81; // edi + unsigned int v82; // ecx + short v83; // ax + int v84; // eax + signed int v85; // edx + unsigned int i; // ecx + int v87; // eax + short v88; // ax + signed int v89; // edx + unsigned int j; // ecx + int v91; // eax + short v92; // ax + signed int v93; // edx + _DWORD *v94; // edi + unsigned int v95; // ecx + short v96; // ax + int v97; // eax + int v98; // edx + int v99; // edx + signed int v100; // ecx + char v101; // al + signed int v102; // edx + unsigned int k; // ecx + int v104; // eax + short v105; // ax + int v106; // edx + int v107; // edx + signed int v108; // ecx + char v109; // al + int v110; // edx + int v111; // edx + signed int v112; // ecx + int v113; // ecx + signed int v114; // edx + int v115; // eax + int v116; // edx + int v117; // edx + int v118; // ecx + signed int v119; // edx + _DWORD *v120; // edi + unsigned int v121; // ecx + signed int v122; // edx + _WORD *v123; // edi + unsigned int v124; // ecx + signed int v125; // edx + unsigned int v126; // ecx + _WORD *v127; // edi + signed int v128; // edx + unsigned int v129; // ecx + signed int v130; // edx + _DWORD *v131; // edi + unsigned int v132; // ecx + int v133; // edx + int v134; // edx + signed int v135; // ecx + signed int v136; // edx + unsigned int v137; // ecx + _BYTE *v138; // edi + int v139; // edx + int v140; // edx + signed int v141; // ecx + int v142; // [esp-8h] [ebp-14h] + int v143; // [esp-8h] [ebp-14h] + int v144; // [esp-8h] [ebp-14h] + int v145; // [esp-8h] [ebp-14h] + int v146; // [esp-8h] [ebp-14h] + int v147; // [esp-4h] [ebp-10h] + int v148; // [esp-4h] [ebp-10h] + int v149; // [esp-4h] [ebp-10h] + int v150; // [esp-4h] [ebp-10h] + int v151; // [esp-4h] [ebp-10h] + int v152; // [esp-4h] [ebp-10h] + int v153; // [esp-4h] [ebp-10h] + int v154; // [esp-4h] [ebp-10h] + int v155; // [esp-4h] [ebp-10h] + int v156; // [esp-4h] [ebp-10h] + + world_4B3265 = (int)speed_cel_frame_num_from_light_index_frame_num; + v2 = (unsigned char *)a1; + world_4B3269[0] = a2; + if ( !(_BYTE)light_table_index ) + { + if ( level_cel_block & 0x8000 ) + level_cel_block = *(_DWORD *)(((level_cel_block & 0xFFF) << 6) + world_4B3265) + + (unsigned short)(level_cel_block & 0xF000); + v6 = (char *)pDungeonCels + *((_DWORD *)pDungeonCels + (level_cel_block & 0xFFF)); + v8 = level_cel_block; + _LOBYTE(v8) = BYTE1(v8); + v7 = ((v8 >> 4) & 7) + 8; +LABEL_12: + switch ( v7 ) + { + case 8: + v64 = 32; + do + { + if ( (unsigned int)v2 < screen_buf_end ) + break; + v150 = v64; + v65 = *(_DWORD *)world_4B3269[0]; + v66 = 32; + do + { + v67 = *v6++; + v16 = __CFSHL__(v65, 1); + v65 *= 2; + if ( v16 ) + *v2 = v67; + ++v2; + --v66; + } + while ( v66 ); + v2 -= 800; + world_4B3269[0] -= 4; + v64 = v150 - 1; + } + while ( v150 != 1 ); + break; + case 9: + v68 = 32; + do + { + v151 = v68; + *(_DWORD *)world_4B3260 = *(_DWORD *)world_4B3269[0]; + v69 = 32; + do + { + while ( 1 ) + { + v70 = (unsigned char)*v6++; + if ( (v70 & 0x80u) == 0 ) + break; + _LOBYTE(v70) = -(char)v70; + v2 += v70; + if ( v70 & 0x1F ) + *(_DWORD *)world_4B3260 <<= v70 & 0x1F; + v69 -= v70; + if ( !v69 ) + goto LABEL_129; + } + v71 = v69 - v70; + if ( (unsigned int)v2 < screen_buf_end ) + return; + v144 = v71; + v72 = *(_DWORD *)world_4B3260; + v73 = v70; + do + { + v74 = *v6++; + v16 = __CFSHL__(v72, 1); + v72 *= 2; + if ( v16 ) + *v2 = v74; + ++v2; + --v73; + } + while ( v73 ); + *(_DWORD *)world_4B3260 = v72; + v69 = v144; + } + while ( v144 ); +LABEL_129: + v2 -= 800; + world_4B3269[0] -= 4; + v68 = v151 - 1; + } + while ( v151 != 1 ); + break; + case 10: + v75 = 30; + while ( (unsigned int)v2 >= screen_buf_end ) + { + v76 = (unsigned int *)&v2[v75]; + v77 = (unsigned int)(32 - v75) >> 2; + if ( !__CFSHR__(32 - v75, 2) + || (v78 = *((_WORD *)v6 + 1), v6 += 4, *(_WORD *)v76 = v78, v76 = (_DWORD *)((char *)v76 + 2), v77) ) + { + do + { + v79 = *(_DWORD *)v6; + v6 += 4; + *v76 = v79; + --v77; + ++v76; + } + while ( v77 ); + } + v2 = (unsigned char *)v76 - 200; + v31 = __OFSUB__(v75, 2); + v75 -= 2; + if ( (v75 < 0) ^ v31 ) + { + v80 = 2; + do + { + if ( (unsigned int)v2 < screen_buf_end ) + break; + v81 = (unsigned short *)&v2[v80]; + v82 = (unsigned int)(32 - v80) >> 2; + if ( __CFSHR__(32 - v80, 2) ) + { + v83 = *((_WORD *)v6 + 1); + v6 += 4; + *v81 = v83; + ++v81; + if ( !v82 ) + continue; + } + do + { + v84 = *(_DWORD *)v6; + v6 += 4; + *(_DWORD *)v81 = v84; + v81 += 2; + --v82; + } + while ( v82 ); + v2 = (unsigned char *)v81 - 400; + v80 += 2; + } + while ( v80 != 32 ); + return; + } + } + break; + case 11: + v85 = 30; + while ( (unsigned int)v2 >= screen_buf_end ) + { + for ( i = (unsigned int)(32 - v85) >> 2; i; --i ) + { + v87 = *(_DWORD *)v6; + v6 += 4; + *(_DWORD *)v2 = v87; + v2 += 4; + } + if ( (32 - (_BYTE)v85) & 2 ) + { + v88 = *(_WORD *)v6; + v6 += 4; + *(_WORD *)v2 = v88; + v2 += 2; + } + v2 = &v2[v85 - 800]; + v31 = __OFSUB__(v85, 2); + v85 -= 2; + if ( (v85 < 0) ^ v31 ) + { + v89 = 2; + do + { + if ( (unsigned int)v2 < screen_buf_end ) + break; + for ( j = (unsigned int)(32 - v89) >> 2; j; --j ) + { + v91 = *(_DWORD *)v6; + v6 += 4; + *(_DWORD *)v2 = v91; + v2 += 4; + } + if ( (32 - (_BYTE)v89) & 2 ) + { + v92 = *(_WORD *)v6; + v6 += 4; + *(_WORD *)v2 = v92; + v2 += 2; + } + v2 = &v2[v89 - 800]; + v89 += 2; + } + while ( v89 != 32 ); + return; + } + } + break; + case 12: + v93 = 30; + while ( (unsigned int)v2 >= screen_buf_end ) + { + v94 = (unsigned int *)&v2[v93]; + v95 = (unsigned int)(32 - v93) >> 2; + if ( !__CFSHR__(32 - v93, 2) + || (v96 = *((_WORD *)v6 + 1), v6 += 4, *(_WORD *)v94 = v96, v94 = (_DWORD *)((char *)v94 + 2), v95) ) + { + do + { + v97 = *(_DWORD *)v6; + v6 += 4; + *v94 = v97; + ++v94; + --v95; + } + while ( v95 ); + } + v2 = (unsigned char *)v94 - 200; + v31 = __OFSUB__(v93, 2); + v93 -= 2; + if ( (v93 < 0) ^ v31 ) + { + world_4B3269[0] -= 64; + v98 = 16; + do + { + if ( (unsigned int)v2 < screen_buf_end ) + break; + v152 = v98; + v99 = *(_DWORD *)world_4B3269[0]; + v100 = 32; + do + { + v101 = *v6++; + v16 = __CFSHL__(v99, 1); + v99 *= 2; + if ( v16 ) + *v2 = v101; + ++v2; + --v100; + } + while ( v100 ); + v2 -= 800; + world_4B3269[0] -= 4; + v98 = v152 - 1; + } + while ( v152 != 1 ); + return; + } + } + break; + default: + v102 = 30; + while ( (unsigned int)v2 >= screen_buf_end ) + { + for ( k = (unsigned int)(32 - v102) >> 2; k; --k ) + { + v104 = *(_DWORD *)v6; + v6 += 4; + *(_DWORD *)v2 = v104; + v2 += 4; + } + if ( (32 - (_BYTE)v102) & 2 ) + { + v105 = *(_WORD *)v6; + v6 += 4; + *(_WORD *)v2 = v105; + v2 += 2; + } + v2 = &v2[v102 - 800]; + v31 = __OFSUB__(v102, 2); + v102 -= 2; + if ( (v102 < 0) ^ v31 ) + { + world_4B3269[0] -= 64; + v106 = 16; + do + { + if ( (unsigned int)v2 < screen_buf_end ) + break; + v145 = v106; + v107 = *(_DWORD *)world_4B3269[0]; + v108 = 32; + do + { + v109 = *v6++; + v16 = __CFSHL__(v107, 1); + v107 *= 2; + if ( v16 ) + *v2 = v109; + ++v2; + --v108; + } + while ( v108 ); + v6 += (unsigned char)v6 & 2; + v2 -= 800; + world_4B3269[0] -= 4; + v106 = v145 - 1; + } + while ( v145 != 1 ); + return; + } + } + break; + } + return; + } + if ( (_BYTE)light_table_index != lightmax ) + { + if ( !(level_cel_block & 0x8000) ) + { + v3 = (char *)pDungeonCels + *((_DWORD *)pDungeonCels + (level_cel_block & 0xFFF)); +/* _EBX = dword_646A20 + (light_table_index << 8); + v5 = (unsigned char)(BYTE1(level_cel_block) >> 4); + if ( !(BYTE1(level_cel_block) >> 4) ) + { + v12 = 32; + do + { + if ( (unsigned int)v2 < screen_buf_end ) + break; + v147 = v12; + v13 = *(_DWORD *)world_4B3269[0]; + v14 = 32; + do + { + _AL = *v3++; + v16 = __CFSHL__(v13, 1); + v13 *= 2; + if ( v16 ) + { + __asm { xlat } + *v2 = _AL; + } + ++v2; + --v14; + } + while ( v14 ); + v2 -= 800; + world_4B3269[0] -= 4; + v12 = v147 - 1; + } + while ( v147 != 1 ); + return; + } + if ( BYTE1(level_cel_block) >> 4 ) + { + switch ( v5 ) + { + case 1: + v18 = 32; + do + { + v148 = v18; + *(_DWORD *)world_4B3260 = *(_DWORD *)world_4B3269[0]; + v19 = 32; + do + { + while ( 1 ) + { + v20 = (unsigned char)*v3++; + if ( (v20 & 0x80u) == 0 ) + break; + _LOBYTE(v20) = -(char)v20; + v2 += v20; + if ( v20 & 0x1F ) + *(_DWORD *)world_4B3260 <<= v20 & 0x1F; + v19 -= v20; + if ( !v19 ) + goto LABEL_50; + } + v21 = v19 - v20; + if ( (unsigned int)v2 < screen_buf_end ) + return; + v22 = v20; + v142 = v21; + v23 = *(_DWORD *)world_4B3260; + do + { + _AL = *v3++; + v16 = __CFSHL__(v23, 1); + v23 *= 2; + if ( v16 ) + { + __asm { xlat } + *v2 = _AL; + } + ++v2; + --v22; + } + while ( v22 ); + *(_DWORD *)world_4B3260 = v23; + v19 = v142; + } + while ( v142 ); +LABEL_50: + v2 -= 800; + world_4B3269[0] -= 4; + v18 = v148 - 1; + } + while ( v148 != 1 ); + break; + case 2: + v26 = 30; + while ( (unsigned int)v2 >= screen_buf_end ) + { + v27 = &v2[v26]; + v28 = (unsigned int)(32 - v26) >> 2; + if ( !__CFSHR__(32 - v26, 2) ) + goto LABEL_268; + _AX = *((_WORD *)v3 + 1); + v3 += 4; + __asm { xlat } + _AX = __ROR2__(_AX, 8); + __asm { xlat } + *v27 = __ROR2__(_AX, 8); + ++v27; + if ( v28 ) + { +LABEL_268: + do + { + _EAX = *(_DWORD *)v3; + v3 += 4; + __asm { xlat } + _EAX = __ROR4__(_EAX, 8); + __asm { xlat } + _EAX = __ROR4__(_EAX, 8); + __asm { xlat } + _EAX = __ROR4__(_EAX, 8); + __asm { xlat } + *(_DWORD *)v27 = __ROR4__(_EAX, 8); + v27 += 2; + --v28; + } + while ( v28 ); + } + v2 = v27 - 400; + v31 = __OFSUB__(v26, 2); + v26 -= 2; + if ( (v26 < 0) ^ v31 ) + { + v32 = 2; + do + { + if ( (unsigned int)v2 < screen_buf_end ) + break; + v33 = &v2[v32]; + v34 = (unsigned int)(32 - v32) >> 2; + if ( !__CFSHR__(32 - v32, 2) ) + goto LABEL_269; + _AX = *((_WORD *)v3 + 1); + v3 += 4; + __asm { xlat } + _AX = __ROR2__(_AX, 8); + __asm { xlat } + *v33 = __ROR2__(_AX, 8); + ++v33; + if ( v34 ) + { +LABEL_269: + do + { + _EAX = *(_DWORD *)v3; + v3 += 4; + __asm { xlat } + _EAX = __ROR4__(_EAX, 8); + __asm { xlat } + _EAX = __ROR4__(_EAX, 8); + __asm { xlat } + _EAX = __ROR4__(_EAX, 8); + __asm { xlat } + *(_DWORD *)v33 = __ROR4__(_EAX, 8); + v33 += 2; + --v34; + } + while ( v34 ); + } + v2 = v33 - 400; + v32 += 2; + } + while ( v32 != 32 ); + return; + } + } + break; + case 3: + v37 = 30; + while ( (unsigned int)v2 >= screen_buf_end ) + { + for ( l = (unsigned int)(32 - v37) >> 2; l; --l ) + { + _EAX = *(_DWORD *)v3; + v3 += 4; + __asm { xlat } + _EAX = __ROR4__(_EAX, 8); + __asm { xlat } + _EAX = __ROR4__(_EAX, 8); + __asm { xlat } + _EAX = __ROR4__(_EAX, 8); + __asm { xlat } + *(_DWORD *)v2 = __ROR4__(_EAX, 8); + v2 += 4; + } + if ( (32 - (_BYTE)v37) & 2 ) + { + _AX = *(_WORD *)v3; + v3 += 4; + __asm { xlat } + _AX = __ROR2__(_AX, 8); + __asm { xlat } + *(_WORD *)v2 = __ROR2__(_AX, 8); + v2 += 2; + } + v2 = &v2[v37 - 800]; + v31 = __OFSUB__(v37, 2); + v37 -= 2; + if ( (v37 < 0) ^ v31 ) + { + v41 = 2; + do + { + if ( (unsigned int)v2 < screen_buf_end ) + break; + for ( m = (unsigned int)(32 - v41) >> 2; m; --m ) + { + _EAX = *(_DWORD *)v3; + v3 += 4; + __asm { xlat } + _EAX = __ROR4__(_EAX, 8); + __asm { xlat } + _EAX = __ROR4__(_EAX, 8); + __asm { xlat } + _EAX = __ROR4__(_EAX, 8); + __asm { xlat } + *(_DWORD *)v2 = __ROR4__(_EAX, 8); + v2 += 4; + } + if ( (32 - (_BYTE)v41) & 2 ) + { + _AX = *(_WORD *)v3; + v3 += 4; + __asm { xlat } + _AX = __ROR2__(_AX, 8); + __asm { xlat } + *(_WORD *)v2 = __ROR2__(_AX, 8); + v2 += 2; + } + v2 = &v2[v41 - 800]; + v41 += 2; + } + while ( v41 != 32 ); + return; + } + } + break; + case 4: + v45 = 30; + while ( (unsigned int)v2 >= screen_buf_end ) + { + v46 = &v2[v45]; + v47 = (unsigned int)(32 - v45) >> 2; + if ( !__CFSHR__(32 - v45, 2) ) + goto LABEL_270; + _AX = *((_WORD *)v3 + 1); + v3 += 4; + __asm { xlat } + _AX = __ROR2__(_AX, 8); + __asm { xlat } + *v46 = __ROR2__(_AX, 8); + ++v46; + if ( v47 ) + { +LABEL_270: + do + { + _EAX = *(_DWORD *)v3; + v3 += 4; + __asm { xlat } + _EAX = __ROR4__(_EAX, 8); + __asm { xlat } + _EAX = __ROR4__(_EAX, 8); + __asm { xlat } + _EAX = __ROR4__(_EAX, 8); + __asm { xlat } + *(_DWORD *)v46 = __ROR4__(_EAX, 8); + v46 += 2; + --v47; + } + while ( v47 ); + } + v2 = v46 - 400; + v31 = __OFSUB__(v45, 2); + v45 -= 2; + if ( (v45 < 0) ^ v31 ) + { + world_4B3269[0] -= 64; + v50 = 16; + do + { + if ( (unsigned int)v2 < screen_buf_end ) + break; + v149 = v50; + v51 = *(_DWORD *)world_4B3269[0]; + v52 = 32; + v3 += (unsigned char)v3 & 2; + do + { + _AL = *v3++; + v16 = __CFSHL__(v51, 1); + v51 *= 2; + if ( v16 ) + { + __asm { xlat } + *v2 = _AL; + } + ++v2; + --v52; + } + while ( v52 ); + v2 -= 800; + world_4B3269[0] -= 4; + v50 = v149 - 1; + } + while ( v149 != 1 ); + return; + } + } + break; + default: + v55 = 30; + while ( (unsigned int)v2 >= screen_buf_end ) + { + for ( n = (unsigned int)(32 - v55) >> 2; n; --n ) + { + _EAX = *(_DWORD *)v3; + v3 += 4; + __asm { xlat } + _EAX = __ROR4__(_EAX, 8); + __asm { xlat } + _EAX = __ROR4__(_EAX, 8); + __asm { xlat } + _EAX = __ROR4__(_EAX, 8); + __asm { xlat } + *(_DWORD *)v2 = __ROR4__(_EAX, 8); + v2 += 4; + } + if ( (32 - (_BYTE)v55) & 2 ) + { + _AX = *(_WORD *)v3; + v3 += 4; + __asm { xlat } + _AX = __ROR2__(_AX, 8); + __asm { xlat } + *(_WORD *)v2 = __ROR2__(_AX, 8); + v2 += 2; + } + v2 = &v2[v55 - 800]; + v31 = __OFSUB__(v55, 2); + v55 -= 2; + if ( (v55 < 0) ^ v31 ) + { + world_4B3269[0] -= 64; + v59 = 16; + do + { + if ( (unsigned int)v2 < screen_buf_end ) + break; + v143 = v59; + v60 = *(_DWORD *)world_4B3269[0]; + v61 = 32; + do + { + _AL = *v3++; + v16 = __CFSHL__(v60, 1); + v60 *= 2; + if ( v16 ) + { + __asm { xlat } + *v2 = _AL; + } + ++v2; + --v61; + } + while ( v61 ); + v3 += (unsigned char)v3 & 2; + v2 -= 800; + world_4B3269[0] -= 4; + v59 = v143 - 1; + } + while ( v143 != 1 ); + return; + } + } + break; + } + return; + }*/ +LABEL_187: + /*v110 = 32; + do + { + if ( (unsigned int)v2 < screen_buf_end ) + break; + v153 = v110; + v111 = *(_DWORD *)world_4B3269[0]; + v112 = 32; + do + { + v16 = __CFSHL__(v111, 1); + v111 *= 2; + if ( v16 ) + *v2 = 0; + ++v2; + --v112; + } + while ( v112 ); + v2 -= 800; + world_4B3269[0] -= 4; + v110 = v153 - 1; + } + while ( v153 != 1 );*/ + return; + } + v6 = (char *)pSpeedCels + *(_DWORD *)(4 * (light_table_index + 16 * (level_cel_block & 0xFFF)) + world_4B3265); + v7 = (unsigned char)(BYTE1(level_cel_block) >> 4); + goto LABEL_12; + } + if ( level_cel_block & 0x8000 ) + level_cel_block = *(_DWORD *)(((level_cel_block & 0xFFF) << 6) + world_4B3265) + + (unsigned short)(level_cel_block & 0xF000); + v9 = (unsigned char *)pDungeonCels + *((_DWORD *)pDungeonCels + (level_cel_block & 0xFFF)); + v10 = level_cel_block; + _LOBYTE(v10) = BYTE1(v10); + v11 = (v10 >> 4) & 7; + if ( !v11 ) + goto LABEL_187; + switch ( (_WORD)v11 ) + { + case 1: + v113 = 32; + do + { + v154 = v113; + *(_DWORD *)world_4B3260 = *(_DWORD *)world_4B3269[0]; + v114 = 32; + do + { + while ( 1 ) + { + v115 = *v9++; + if ( (v115 & 0x80u) == 0 ) + break; + _LOBYTE(v115) = -(char)v115; + v2 += v115; + if ( v115 & 0x1F ) + *(_DWORD *)world_4B3260 <<= v115 & 0x1F; + v114 -= v115; + if ( !v114 ) + goto LABEL_208; + } + v116 = v114 - v115; + if ( (unsigned int)v2 < screen_buf_end ) + return; + v146 = v116; + v117 = *(_DWORD *)world_4B3260; + v118 = v115; + v9 += v115; + do + { + v16 = __CFSHL__(v117, 1); + v117 *= 2; + if ( v16 ) + *v2 = 0; + ++v2; + --v118; + } + while ( v118 ); + *(_DWORD *)world_4B3260 = v117; + v114 = v146; + } + while ( v146 ); +LABEL_208: + v2 -= 800; + world_4B3269[0] -= 4; + v113 = v154 - 1; + } + while ( v154 != 1 ); + break; + case 2: + v119 = 30; + while ( (unsigned int)v2 >= screen_buf_end ) + { + v120 = (unsigned int *)&v2[v119]; + v121 = (unsigned int)(32 - v119) >> 2; + if ( !__CFSHR__(32 - v119, 2) || (*(_WORD *)v120 = 0, v120 = (_DWORD *)((char *)v120 + 2), v121) ) + { + do + { + *v120 = 0; + ++v120; + --v121; + } + while ( v121 ); + } + v2 = (unsigned char *)v120 - 200; + if ( !v119 ) + { + v122 = 2; + do + { + if ( (unsigned int)v2 < screen_buf_end ) + break; + v123 = (unsigned short *)&v2[v122]; + v124 = (unsigned int)(32 - v122) >> 2; + if ( __CFSHR__(32 - v122, 2) ) + { + *v123 = 0; + ++v123; + if ( !v124 ) + continue; + } + do + { + *(_DWORD *)v123 = 0; + v123 += 2; + --v124; + } + while ( v124 ); + v2 = (unsigned char *)v123 - 400; + v122 += 2; + } + while ( v122 != 32 ); + return; + } + v119 -= 2; + } + break; + case 3: + v125 = 30; + while ( (unsigned int)v2 >= screen_buf_end ) + { + v126 = (unsigned int)(32 - v125) >> 2; + if ( !__CFSHR__(32 - v125, 2) || (*(_WORD *)v2 = 0, v2 += 2, v126) ) + { + do + { + *(_DWORD *)v2 = 0; + v2 += 4; + --v126; + } + while ( v126 ); + } + v127 = (unsigned short *)v2 - 800; + if ( !v125 ) + { + v128 = 1; + do + { + if ( (unsigned int)v127 < screen_buf_end ) + break; + v129 = (unsigned int)(32 - v128 * 2) >> 2; + if ( __CFSHR__(32 - v128 * 2, 2) ) + { + *v127 = 0; + ++v127; + if ( !v129 ) + continue; + } + do + { + *(_DWORD *)v127 = 0; + v127 += 2; + --v129; + } + while ( v129 ); + v127 = &v127[v128 - 400]; + ++v128; + } + while ( v128 != 16 ); + return; + } + v2 = (unsigned char *)&v127[v125 / 2u]; + v125 -= 2; + } + break; + case 4: + v130 = 30; + while ( (unsigned int)v2 >= screen_buf_end ) + { + v131 = (unsigned int *)&v2[v130]; + v132 = (unsigned int)(32 - v130) >> 2; + if ( !__CFSHR__(32 - v130, 2) || (*(_WORD *)v131 = 0, v131 = (_DWORD *)((char *)v131 + 2), v132) ) + { + do + { + *v131 = 0; + ++v131; + --v132; + } + while ( v132 ); + } + v2 = (unsigned char *)v131 - 200; + if ( !v130 ) + { + world_4B3269[0] -= 64; + v133 = 16; + do + { + if ( (unsigned int)v2 < screen_buf_end ) + break; + v155 = v133; + v134 = *(_DWORD *)world_4B3269[0]; + v135 = 32; + do + { + v16 = __CFSHL__(v134, 1); + v134 *= 2; + if ( v16 ) + *v2 = 0; + ++v2; + --v135; + } + while ( v135 ); + v2 -= 800; + world_4B3269[0] -= 4; + v133 = v155 - 1; + } + while ( v155 != 1 ); + return; + } + v130 -= 2; + } + break; + default: + v136 = 30; + while ( (unsigned int)v2 >= screen_buf_end ) + { + v137 = (unsigned int)(32 - v136) >> 2; + if ( !__CFSHR__(32 - v136, 2) || (*(_WORD *)v2 = 0, v2 += 2, v137) ) + { + do + { + *(_DWORD *)v2 = 0; + v2 += 4; + --v137; + } + while ( v137 ); + } + v138 = v2 - 800; + if ( !v136 ) + { + world_4B3269[0] -= 64; + v139 = 16; + do + { + if ( (unsigned int)v138 < screen_buf_end ) + break; + v156 = v139; + v140 = *(_DWORD *)world_4B3269[0]; + v141 = 32; + do + { + v16 = __CFSHL__(v140, 1); + v140 *= 2; + if ( v16 ) + *v138 = 0; + ++v138; + --v141; + } + while ( v141 ); + v138 -= 800; + world_4B3269[0] -= 4; + v139 = v156 - 1; + } + while ( v156 != 1 ); + return; + } + v2 = &v138[v136]; + v136 -= 2; + } + break; + } +} +// 642A14: using guessed type char lightmax; +// 69BEF8: using guessed type int light_table_index; +// 69CF0C: using guessed type int screen_buf_end; +// 69CF14: using guessed type int level_cel_block; + +//----- (004652C5) -------------------------------------------------------- +void __fastcall drawUpperScreen(void *a1) +{ + int v1; // edx + char v2; // al + char v3; // al + _BYTE *v4; // edi + _BYTE *v5; // esi + int v6; // ebx + short v7; // ax + char *v8; // esi + short v9; // ax + unsigned int v10; // eax + unsigned char *v11; // esi + unsigned int v12; // eax + int v13; // edx + char v14; // cl + int v15; // eax + char v16; // ch + char v17; // ch + char v18; // ch + signed int v19; // ebp + signed int v20; // edx + int v21; // eax + int v22; // edx + char v23; // cl + int v24; // eax + char v25; // ch + char v26; // ch + char v27; // ch + signed int v28; // ebp + _BYTE *v29; // edi + char v30; // cl + int v31; // edx + int v32; // eax + char v33; // ch + char v34; // ch + char v35; // ch + unsigned char v36; // of + signed int v37; // ebp + _BYTE *v38; // edi + char v39; // cl + int v40; // edx + int v41; // eax + char v42; // ch + char v43; // ch + char v44; // ch + signed int v45; // ebp + char m; // cl + int v47; // eax + char v48; // ch + char v49; // ch + char v50; // ch + signed int v51; // ebp + char n; // cl + int v53; // eax + char v54; // ch + char v55; // ch + char v56; // ch + signed int v57; // ebp + _BYTE *v58; // edi + char v59; // cl + int v60; // edx + int v61; // eax + char v62; // ch + char v63; // ch + char v64; // ch + signed int v65; // ebp + char v66; // cl + int v67; // eax + char v68; // ch + char v69; // ch + char v70; // ch + signed int v71; // ebp + char ii; // cl + int v73; // eax + char v74; // ch + char v75; // ch + char v76; // ch + signed int v77; // ebp + char v78; // cl + int v79; // eax + char v80; // ch + char v81; // ch + char v82; // ch + signed int v83; // edx + signed int v84; // ecx + int v85; // eax + signed int v86; // ebp + signed int v87; // edx + unsigned int v88; // eax + unsigned int v89; // ecx + char v90; // al + char v91; // cf + unsigned int v92; // ecx + short v93; // ax + int v94; // eax + signed int v95; // edx + _DWORD *v96; // edi + unsigned int v97; // ecx + short v98; // ax + int v99; // eax + signed int v100; // edx + _WORD *v101; // edi + unsigned int v102; // ecx + short v103; // ax + int v104; // eax + signed int v105; // edx + unsigned int i; // ecx + int v107; // eax + short v108; // ax + signed int v109; // edx + unsigned int j; // ecx + int v111; // eax + short v112; // ax + signed int v113; // edx + _DWORD *v114; // edi + unsigned int v115; // ecx + short v116; // ax + int v117; // eax + signed int v118; // edx + signed int v119; // ecx + int v120; // eax + signed int v121; // edx + unsigned int k; // ecx + int v123; // eax + short v124; // ax + signed int v125; // edx + signed int v126; // ecx + int v127; // eax + signed int v128; // edx + signed int v129; // ecx + signed int v130; // ebp + signed int v131; // edx + unsigned int v132; // eax + unsigned int v133; // ecx + unsigned int v134; // ecx + signed int v135; // edx + _DWORD *v136; // edi + unsigned int v137; // ecx + signed int v138; // edx + _WORD *v139; // edi + unsigned int v140; // ecx + signed int v141; // edx + unsigned int v142; // ecx + _WORD *v143; // edi + signed int v144; // edx + unsigned int v145; // ecx + signed int v146; // edx + _DWORD *v147; // edi + unsigned int v148; // ecx + signed int v149; // edx + signed int v150; // ecx + signed int v151; // edx + unsigned int v152; // ecx + _DWORD *v153; // edi + signed int v154; // edx + signed int v155; // ecx + int l; // [esp-14h] [ebp-18h] + int v157; // [esp-10h] [ebp-14h] + + v1 = cel_transparency_active; + if ( cel_transparency_active ) + { + if ( !arch_draw_type ) + { + drawTopArchesUpperScreen(a1); + return; + } + if ( arch_draw_type == 1 ) + { + v2 = block_lvid[level_piece_id]; + if ( v2 == 1 || v2 == 3 ) + { + drawBottomArchesUpperScreen(a1, (int)&tile_draw_masks[63]); + return; + } + } + if ( arch_draw_type == 2 ) + { + v3 = block_lvid[level_piece_id]; + if ( v3 == 2 || v3 == 3 ) + { + drawBottomArchesUpperScreen(a1, (int)&tile_draw_masks[31]); + return; + } + } + } + world_4B3265 = (int)speed_cel_frame_num_from_light_index_frame_num; + v4 = (unsigned char *)a1; + if ( !(_BYTE)light_table_index ) + { + if ( level_cel_block & 0x8000 ) + level_cel_block = *(_DWORD *)(((level_cel_block & 0xFFF) << 6) + world_4B3265) + + (unsigned short)(level_cel_block & 0xF000); + v8 = (char *)pDungeonCels + *((_DWORD *)pDungeonCels + (level_cel_block & 0xFFF)); + v10 = level_cel_block; + _LOBYTE(v10) = BYTE1(v10); + v9 = ((v10 >> 4) & 7) + 8; +LABEL_22: + switch ( v9 ) + { + case 8: + v83 = 32; + do + { + if ( (unsigned int)v4 < screen_buf_end ) + break; + v84 = 8; + do + { + v85 = *(_DWORD *)v8; + v8 += 4; + *(_DWORD *)v4 = v85; + v4 += 4; + --v84; + } + while ( v84 ); + v4 -= 800; + --v83; + } + while ( v83 ); + break; + case 9: + v86 = 32; + do + { + v87 = 32; + do + { + while ( 1 ) + { + v88 = (unsigned char)*v8++; + if ( (v88 & 0x80u) == 0 ) + break; + _LOBYTE(v88) = -(char)v88; + v4 += v88; + v87 -= v88; + if ( !v87 ) + goto LABEL_133; + } + v87 -= v88; + if ( (unsigned int)v4 < screen_buf_end ) + return; + v89 = v88 >> 1; + if ( v88 & 1 ) + { + v90 = *v8++; + *v4++ = v90; + if ( !v89 ) + continue; + } + v91 = v89 & 1; + v92 = v89 >> 1; + if ( v91 ) + { + v93 = *(_WORD *)v8; + v8 += 2; + *(_WORD *)v4 = v93; + v4 += 2; + if ( !v92 ) + continue; + } + do + { + v94 = *(_DWORD *)v8; + v8 += 4; + *(_DWORD *)v4 = v94; + v4 += 4; + --v92; + } + while ( v92 ); + } + while ( v87 ); +LABEL_133: + v4 -= 800; + --v86; + } + while ( v86 ); + break; + case 10: + v95 = 30; + while ( (unsigned int)v4 >= screen_buf_end ) + { + v96 = (unsigned int *)&v4[v95]; + v97 = (unsigned int)(32 - v95) >> 2; + if ( !__CFSHR__(32 - v95, 2) + || (v98 = *((_WORD *)v8 + 1), v8 += 4, *(_WORD *)v96 = v98, v96 = (_DWORD *)((char *)v96 + 2), v97) ) + { + do + { + v99 = *(_DWORD *)v8; + v8 += 4; + *v96 = v99; + ++v96; + --v97; + } + while ( v97 ); + } + v4 = (unsigned char *)v96 - 200; + v36 = __OFSUB__(v95, 2); + v95 -= 2; + if ( (v95 < 0) ^ v36 ) + { + v100 = 2; + do + { + if ( (unsigned int)v4 < screen_buf_end ) + break; + v101 = (unsigned short *)&v4[v100]; + v102 = (unsigned int)(32 - v100) >> 2; + if ( __CFSHR__(32 - v100, 2) ) + { + v103 = *((_WORD *)v8 + 1); + v8 += 4; + *v101 = v103; + ++v101; + if ( !v102 ) + continue; + } + do + { + v104 = *(_DWORD *)v8; + v8 += 4; + *(_DWORD *)v101 = v104; + v101 += 2; + --v102; + } + while ( v102 ); + v4 = (unsigned char *)v101 - 400; + v100 += 2; + } + while ( v100 != 32 ); + return; + } + } + break; + case 11: + v105 = 30; + while ( (unsigned int)v4 >= screen_buf_end ) + { + for ( i = (unsigned int)(32 - v105) >> 2; i; --i ) + { + v107 = *(_DWORD *)v8; + v8 += 4; + *(_DWORD *)v4 = v107; + v4 += 4; + } + if ( (32 - (_BYTE)v105) & 2 ) + { + v108 = *(_WORD *)v8; + v8 += 4; + *(_WORD *)v4 = v108; + v4 += 2; + } + v4 = &v4[v105 - 800]; + v36 = __OFSUB__(v105, 2); + v105 -= 2; + if ( (v105 < 0) ^ v36 ) + { + v109 = 2; + do + { + if ( (unsigned int)v4 < screen_buf_end ) + break; + for ( j = (unsigned int)(32 - v109) >> 2; j; --j ) + { + v111 = *(_DWORD *)v8; + v8 += 4; + *(_DWORD *)v4 = v111; + v4 += 4; + } + if ( (32 - (_BYTE)v109) & 2 ) + { + v112 = *(_WORD *)v8; + v8 += 4; + *(_WORD *)v4 = v112; + v4 += 2; + } + v4 = &v4[v109 - 800]; + v109 += 2; + } + while ( v109 != 32 ); + return; + } + } + break; + case 12: + v113 = 30; + while ( (unsigned int)v4 >= screen_buf_end ) + { + v114 = (unsigned int *)&v4[v113]; + v115 = (unsigned int)(32 - v113) >> 2; + if ( !__CFSHR__(32 - v113, 2) + || (v116 = *((_WORD *)v8 + 1), + v8 += 4, + *(_WORD *)v114 = v116, + v114 = (_DWORD *)((char *)v114 + 2), + v115) ) + { + do + { + v117 = *(_DWORD *)v8; + v8 += 4; + *v114 = v117; + ++v114; + --v115; + } + while ( v115 ); + } + v4 = (unsigned char *)v114 - 200; + v36 = __OFSUB__(v113, 2); + v113 -= 2; + if ( (v113 < 0) ^ v36 ) + { + v118 = 16; + do + { + if ( (unsigned int)v4 < screen_buf_end ) + break; + v119 = 8; + do + { + v120 = *(_DWORD *)v8; + v8 += 4; + *(_DWORD *)v4 = v120; + v4 += 4; + --v119; + } + while ( v119 ); + v4 -= 800; + --v118; + } + while ( v118 ); + return; + } + } + break; + default: + v121 = 30; + while ( (unsigned int)v4 >= screen_buf_end ) + { + for ( k = (unsigned int)(32 - v121) >> 2; k; --k ) + { + v123 = *(_DWORD *)v8; + v8 += 4; + *(_DWORD *)v4 = v123; + v4 += 4; + } + if ( (32 - (_BYTE)v121) & 2 ) + { + v124 = *(_WORD *)v8; + v8 += 4; + *(_WORD *)v4 = v124; + v4 += 2; + } + v4 = &v4[v121 - 800]; + v36 = __OFSUB__(v121, 2); + v121 -= 2; + if ( (v121 < 0) ^ v36 ) + { + v125 = 16; + do + { + if ( (unsigned int)v4 < screen_buf_end ) + break; + v126 = 8; + do + { + v127 = *(_DWORD *)v8; + v8 += 4; + *(_DWORD *)v4 = v127; + v4 += 4; + --v126; + } + while ( v126 ); + v4 -= 800; + --v125; + } + while ( v125 ); + return; + } + } + break; + } + return; + } + if ( (_BYTE)light_table_index != lightmax ) + { + if ( !(level_cel_block & 0x8000) ) + { + v5 = (unsigned char *)pDungeonCels + *((_DWORD *)pDungeonCels + (level_cel_block & 0xFFF)); + v6 = dword_646A20 + (light_table_index << 8); + v7 = (unsigned short)level_cel_block >> 12; + if ( (unsigned short)level_cel_block >> 12 ) + { + switch ( v7 ) + { + case 1: + v19 = 32; + do + { + v20 = 32; + do + { + while ( 1 ) + { + v21 = (unsigned char)*v5++; + if ( (v21 & 0x80u) == 0 ) + break; + _LOBYTE(v21) = -(char)v21; + v4 += v21; + v20 -= v21; + if ( !v20 ) + goto LABEL_58; + } + v22 = v20 - v21; + if ( (unsigned int)v4 < screen_buf_end ) + return; + v23 = v21; + for ( l = v22; v23 >= 4; v23 -= 4 ) + { + v24 = *(_DWORD *)v5; + v5 += 4; + _LOBYTE(v22) = v24; + v25 = *(_BYTE *)(v6 + v22); + _LOBYTE(v22) = BYTE1(v24); + v24 = __ROR4__(v24, 16); + *v4 = v25; + v26 = *(_BYTE *)(v6 + v22); + _LOBYTE(v22) = v24; + v4[1] = v26; + v27 = *(_BYTE *)(v6 + v22); + _LOBYTE(v22) = BYTE1(v24); + v4[2] = v27; + v4[3] = *(_BYTE *)(v6 + v22); + v4 += 4; + } + if ( v23 >= 2 ) + { + _LOBYTE(v22) = *v5; + *v4 = *(_BYTE *)(v6 + v22); + _LOBYTE(v22) = v5[1]; + v4[1] = *(_BYTE *)(v6 + v22); + v5 += 2; + v4 += 2; + } + if ( v23 & 1 ) + { + _LOBYTE(v22) = *v5++; + *v4++ = *(_BYTE *)(v6 + v22); + } + v20 = l; + } + while ( l ); +LABEL_58: + v4 -= 800; + --v19; + } + while ( v19 ); + break; + case 2: + v28 = 30; + while ( (unsigned int)v4 >= screen_buf_end ) + { + v29 = &v4[v28]; + v30 = 32 - v28; + v31 = (32 - (_BYTE)v28) & 2; + v5 += v31; + if ( (char)(32 - v28) >= 4 ) + { + do + { + v32 = *(_DWORD *)v5; + v5 += 4; + _LOBYTE(v31) = v32; + v33 = *(_BYTE *)(v6 + v31); + _LOBYTE(v31) = BYTE1(v32); + v32 = __ROR4__(v32, 16); + *v29 = v33; + v34 = *(_BYTE *)(v6 + v31); + _LOBYTE(v31) = v32; + v29[1] = v34; + v35 = *(_BYTE *)(v6 + v31); + _LOBYTE(v31) = BYTE1(v32); + v29[2] = v35; + v29[3] = *(_BYTE *)(v6 + v31); + v29 += 4; + v30 -= 4; + } + while ( v30 >= 4 ); + } + if ( v30 >= 2 ) + { + _LOBYTE(v31) = *v5; + *v29 = *(_BYTE *)(v6 + v31); + _LOBYTE(v31) = v5[1]; + v29[1] = *(_BYTE *)(v6 + v31); + v5 += 2; + v29 += 2; + } + v4 = v29 - 800; + v36 = __OFSUB__(v28, 2); + v28 -= 2; + if ( (v28 < 0) ^ v36 ) + { + v37 = 2; + do + { + if ( (unsigned int)v4 < screen_buf_end ) + break; + v38 = &v4[v37]; + v39 = 32 - v37; + v40 = (32 - (_BYTE)v37) & 2; + v5 += v40; + if ( (char)(32 - v37) >= 4 ) + { + do + { + v41 = *(_DWORD *)v5; + v5 += 4; + _LOBYTE(v40) = v41; + v42 = *(_BYTE *)(v6 + v40); + _LOBYTE(v40) = BYTE1(v41); + v41 = __ROR4__(v41, 16); + *v38 = v42; + v43 = *(_BYTE *)(v6 + v40); + _LOBYTE(v40) = v41; + v38[1] = v43; + v44 = *(_BYTE *)(v6 + v40); + _LOBYTE(v40) = BYTE1(v41); + v38[2] = v44; + v38[3] = *(_BYTE *)(v6 + v40); + v38 += 4; + v39 -= 4; + } + while ( v39 >= 4 ); + } + if ( v39 >= 2 ) + { + _LOBYTE(v40) = *v5; + *v38 = *(_BYTE *)(v6 + v40); + _LOBYTE(v40) = v5[1]; + v38[1] = *(_BYTE *)(v6 + v40); + v5 += 2; + v38 += 2; + } + v4 = v38 - 800; + v37 += 2; + } + while ( v37 != 32 ); + return; + } + } + break; + case 3: + v45 = 30; + while ( (unsigned int)v4 >= screen_buf_end ) + { + for ( m = 32 - v45; m >= 4; m -= 4 ) + { + v47 = *(_DWORD *)v5; + v5 += 4; + _LOBYTE(v1) = v47; + v48 = *(_BYTE *)(v6 + v1); + _LOBYTE(v1) = BYTE1(v47); + v47 = __ROR4__(v47, 16); + *v4 = v48; + v49 = *(_BYTE *)(v6 + v1); + _LOBYTE(v1) = v47; + v4[1] = v49; + v50 = *(_BYTE *)(v6 + v1); + _LOBYTE(v1) = BYTE1(v47); + v4[2] = v50; + v4[3] = *(_BYTE *)(v6 + v1); + v4 += 4; + } + if ( m >= 2 ) + { + _LOBYTE(v1) = *v5; + *v4 = *(_BYTE *)(v6 + v1); + _LOBYTE(v1) = v5[1]; + v4[1] = *(_BYTE *)(v6 + v1); + v5 += 2; + v4 += 2; + } + v1 = (unsigned char)v5 & 2; + v5 += v1; + v4 = &v4[v45 - 800]; + v36 = __OFSUB__(v45, 2); + v45 -= 2; + if ( (v45 < 0) ^ v36 ) + { + v51 = 2; + do + { + if ( (unsigned int)v4 < screen_buf_end ) + break; + for ( n = 32 - v51; n >= 4; n -= 4 ) + { + v53 = *(_DWORD *)v5; + v5 += 4; + _LOBYTE(v1) = v53; + v54 = *(_BYTE *)(v6 + v1); + _LOBYTE(v1) = BYTE1(v53); + v53 = __ROR4__(v53, 16); + *v4 = v54; + v55 = *(_BYTE *)(v6 + v1); + _LOBYTE(v1) = v53; + v4[1] = v55; + v56 = *(_BYTE *)(v6 + v1); + _LOBYTE(v1) = BYTE1(v53); + v4[2] = v56; + v4[3] = *(_BYTE *)(v6 + v1); + v4 += 4; + } + if ( n >= 2 ) + { + _LOBYTE(v1) = *v5; + *v4 = *(_BYTE *)(v6 + v1); + _LOBYTE(v1) = v5[1]; + v4[1] = *(_BYTE *)(v6 + v1); + v5 += 2; + v4 += 2; + } + v1 = (unsigned char)v5 & 2; + v5 += v1; + v4 = &v4[v51 - 800]; + v51 += 2; + } + while ( v51 != 32 ); + return; + } + } + break; + case 4: + v57 = 30; + while ( (unsigned int)v4 >= screen_buf_end ) + { + v58 = &v4[v57]; + v59 = 32 - v57; + v60 = (32 - (_BYTE)v57) & 2; + v5 += v60; + if ( (char)(32 - v57) >= 4 ) + { + do + { + v61 = *(_DWORD *)v5; + v5 += 4; + _LOBYTE(v60) = v61; + v62 = *(_BYTE *)(v6 + v60); + _LOBYTE(v60) = BYTE1(v61); + v61 = __ROR4__(v61, 16); + *v58 = v62; + v63 = *(_BYTE *)(v6 + v60); + _LOBYTE(v60) = v61; + v58[1] = v63; + v64 = *(_BYTE *)(v6 + v60); + _LOBYTE(v60) = BYTE1(v61); + v58[2] = v64; + v58[3] = *(_BYTE *)(v6 + v60); + v58 += 4; + v59 -= 4; + } + while ( v59 >= 4 ); + } + if ( v59 >= 2 ) + { + _LOBYTE(v60) = *v5; + *v58 = *(_BYTE *)(v6 + v60); + _LOBYTE(v60) = v5[1]; + v58[1] = *(_BYTE *)(v6 + v60); + v5 += 2; + v58 += 2; + } + v4 = v58 - 800; + v36 = __OFSUB__(v57, 2); + v57 -= 2; + if ( (v57 < 0) ^ v36 ) + { + v65 = 16; + do + { + if ( (unsigned int)v4 < screen_buf_end ) + break; + v66 = 32; + do + { + v67 = *(_DWORD *)v5; + v5 += 4; + _LOBYTE(v60) = v67; + v68 = *(_BYTE *)(v6 + v60); + _LOBYTE(v60) = BYTE1(v67); + v67 = __ROR4__(v67, 16); + *v4 = v68; + v69 = *(_BYTE *)(v6 + v60); + _LOBYTE(v60) = v67; + v4[1] = v69; + v70 = *(_BYTE *)(v6 + v60); + _LOBYTE(v60) = BYTE1(v67); + v4[2] = v70; + v4[3] = *(_BYTE *)(v6 + v60); + v4 += 4; + v66 -= 4; + } + while ( v66 >= 4 ); + v4 -= 800; + --v65; + } + while ( v65 ); + return; + } + } + break; + default: + v71 = 30; + while ( (unsigned int)v4 >= screen_buf_end ) + { + for ( ii = 32 - v71; ii >= 4; ii -= 4 ) + { + v73 = *(_DWORD *)v5; + v5 += 4; + _LOBYTE(v1) = v73; + v74 = *(_BYTE *)(v6 + v1); + _LOBYTE(v1) = BYTE1(v73); + v73 = __ROR4__(v73, 16); + *v4 = v74; + v75 = *(_BYTE *)(v6 + v1); + _LOBYTE(v1) = v73; + v4[1] = v75; + v76 = *(_BYTE *)(v6 + v1); + _LOBYTE(v1) = BYTE1(v73); + v4[2] = v76; + v4[3] = *(_BYTE *)(v6 + v1); + v4 += 4; + } + if ( ii >= 2 ) + { + _LOBYTE(v1) = *v5; + *v4 = *(_BYTE *)(v6 + v1); + _LOBYTE(v1) = v5[1]; + v4[1] = *(_BYTE *)(v6 + v1); + v5 += 2; + v4 += 2; + } + v1 = (unsigned char)v5 & 2; + v5 += v1; + v4 = &v4[v71 - 800]; + v36 = __OFSUB__(v71, 2); + v71 -= 2; + if ( (v71 < 0) ^ v36 ) + { + v77 = 16; + do + { + if ( (unsigned int)v4 < screen_buf_end ) + break; + v78 = 32; + do + { + v79 = *(_DWORD *)v5; + v5 += 4; + _LOBYTE(v1) = v79; + v80 = *(_BYTE *)(v6 + v1); + _LOBYTE(v1) = BYTE1(v79); + v79 = __ROR4__(v79, 16); + *v4 = v80; + v81 = *(_BYTE *)(v6 + v1); + _LOBYTE(v1) = v79; + v4[1] = v81; + v82 = *(_BYTE *)(v6 + v1); + _LOBYTE(v1) = BYTE1(v79); + v4[2] = v82; + v4[3] = *(_BYTE *)(v6 + v1); + v4 += 4; + v78 -= 4; + } + while ( v78 >= 4 ); + v4 -= 800; + --v77; + } + while ( v77 ); + return; + } + } + break; + } + } + else + { + v13 = 32; + do + { + if ( (unsigned int)v4 < screen_buf_end ) + break; + v14 = 32; + v157 = v13; + do + { + v15 = *(_DWORD *)v5; + v5 += 4; + _LOBYTE(v13) = v15; + v16 = *(_BYTE *)(v6 + v13); + _LOBYTE(v13) = BYTE1(v15); + v15 = __ROR4__(v15, 16); + *v4 = v16; + v17 = *(_BYTE *)(v6 + v13); + _LOBYTE(v13) = v15; + v4[1] = v17; + v18 = *(_BYTE *)(v6 + v13); + _LOBYTE(v13) = BYTE1(v15); + v4[2] = v18; + v4[3] = *(_BYTE *)(v6 + v13); + v4 += 4; + v14 -= 4; + } + while ( v14 >= 4 ); + v4 -= 800; + v13 = v157 - 1; + } + while ( v157 != 1 ); + } + return; + } + v8 = (char *)pSpeedCels + *(_DWORD *)(4 * (light_table_index + 16 * (level_cel_block & 0xFFF)) + world_4B3265); + v9 = (unsigned short)level_cel_block >> 12; + goto LABEL_22; + } + if ( level_cel_block & 0x8000 ) + level_cel_block = *(_DWORD *)(((level_cel_block & 0xFFF) << 6) + world_4B3265) + + (unsigned short)(level_cel_block & 0xF000); + v11 = (unsigned char *)pDungeonCels + *((_DWORD *)pDungeonCels + (level_cel_block & 0xFFF)); + v12 = ((unsigned int)level_cel_block >> 12) & 7; + if ( v12 ) + { + switch ( (_WORD)v12 ) + { + case 1: + v130 = 32; + do + { + v131 = 32; + do + { + while ( 1 ) + { + v132 = *v11++; + if ( (v132 & 0x80u) == 0 ) + break; + _LOBYTE(v132) = -(char)v132; + v4 += v132; + v131 -= v132; + if ( !v131 ) + goto LABEL_205; + } + v131 -= v132; + if ( (unsigned int)v4 < screen_buf_end ) + return; + v11 += v132; + v133 = v132 >> 1; + if ( v132 & 1 ) + { + *v4++ = 0; + if ( !v133 ) + continue; + } + v91 = v133 & 1; + v134 = v132 >> 2; + if ( v91 ) + { + *(_WORD *)v4 = 0; + v4 += 2; + if ( !v134 ) + continue; + } + do + { + *(_DWORD *)v4 = 0; + v4 += 4; + --v134; + } + while ( v134 ); + } + while ( v131 ); +LABEL_205: + v4 -= 800; + --v130; + } + while ( v130 ); + break; + case 2: + v135 = 30; + while ( (unsigned int)v4 >= screen_buf_end ) + { + v136 = (unsigned int *)&v4[v135]; + v137 = (unsigned int)(32 - v135) >> 2; + if ( !__CFSHR__(32 - v135, 2) || (*(_WORD *)v136 = 0, v136 = (_DWORD *)((char *)v136 + 2), v137) ) + { + do + { + *v136 = 0; + ++v136; + --v137; + } + while ( v137 ); + } + v4 = (unsigned char *)v136 - 200; + if ( !v135 ) + { + v138 = 2; + do + { + if ( (unsigned int)v4 < screen_buf_end ) + break; + v139 = (unsigned short *)&v4[v138]; + v140 = (unsigned int)(32 - v138) >> 2; + if ( __CFSHR__(32 - v138, 2) ) + { + *v139 = 0; + ++v139; + if ( !v140 ) + continue; + } + do + { + *(_DWORD *)v139 = 0; + v139 += 2; + --v140; + } + while ( v140 ); + v4 = (unsigned char *)v139 - 400; + v138 += 2; + } + while ( v138 != 32 ); + return; + } + v135 -= 2; + } + break; + case 3: + v141 = 30; + while ( (unsigned int)v4 >= screen_buf_end ) + { + v142 = (unsigned int)(32 - v141) >> 2; + if ( !__CFSHR__(32 - v141, 2) || (*(_WORD *)v4 = 0, v4 += 2, v142) ) + { + do + { + *(_DWORD *)v4 = 0; + v4 += 4; + --v142; + } + while ( v142 ); + } + v143 = (unsigned short *)v4 - 800; + if ( !v141 ) + { + v144 = 1; + do + { + if ( (unsigned int)v143 < screen_buf_end ) + break; + v145 = (unsigned int)(32 - v144 * 2) >> 2; + if ( __CFSHR__(32 - v144 * 2, 2) ) + { + *v143 = 0; + ++v143; + if ( !v145 ) + continue; + } + do + { + *(_DWORD *)v143 = 0; + v143 += 2; + --v145; + } + while ( v145 ); + v143 = &v143[v144 - 400]; + ++v144; + } + while ( v144 != 16 ); + return; + } + v4 = (unsigned char *)&v143[v141 / 2u]; + v141 -= 2; + } + break; + case 4: + v146 = 30; + while ( (unsigned int)v4 >= screen_buf_end ) + { + v147 = (unsigned int *)&v4[v146]; + v148 = (unsigned int)(32 - v146) >> 2; + if ( !__CFSHR__(32 - v146, 2) || (*(_WORD *)v147 = 0, v147 = (_DWORD *)((char *)v147 + 2), v148) ) + { + do + { + *v147 = 0; + ++v147; + --v148; + } + while ( v148 ); + } + v4 = (unsigned char *)v147 - 200; + if ( !v146 ) + { + v149 = 16; + do + { + if ( (unsigned int)v4 < screen_buf_end ) + break; + v150 = 8; + do + { + *(_DWORD *)v4 = 0; + v4 += 4; + --v150; + } + while ( v150 ); + v4 -= 800; + --v149; + } + while ( v149 ); + return; + } + v146 -= 2; + } + break; + default: + v151 = 30; + while ( (unsigned int)v4 >= screen_buf_end ) + { + v152 = (unsigned int)(32 - v151) >> 2; + if ( !__CFSHR__(32 - v151, 2) || (*(_WORD *)v4 = 0, v4 += 2, v152) ) + { + do + { + *(_DWORD *)v4 = 0; + v4 += 4; + --v152; + } + while ( v152 ); + } + v153 = (unsigned int *)v4 - 800; + if ( !v151 ) + { + v154 = 16; + do + { + if ( (unsigned int)v153 < screen_buf_end ) + break; + v155 = 8; + do + { + *v153 = 0; + ++v153; + --v155; + } + while ( v155 ); + v153 -= 200; + --v154; + } + while ( v154 ); + return; + } + v4 = (unsigned char *)v153 + v151; + v151 -= 2; + } + break; + } + } + else + { + v128 = 32; + do + { + if ( (unsigned int)v4 < screen_buf_end ) + break; + v129 = 8; + do + { + *(_DWORD *)v4 = 0; + v4 += 4; + --v129; + } + while ( v129 ); + v4 -= 800; + --v128; + } + while ( v128 ); + } +} +// 642A14: using guessed type char lightmax; +// 69BEF8: using guessed type int light_table_index; +// 69CF0C: using guessed type int screen_buf_end; +// 69CF14: using guessed type int level_cel_block; +// 69CF20: using guessed type char arch_draw_type; +// 69CF94: using guessed type int cel_transparency_active; +// 69CF98: using guessed type int level_piece_id; + +//----- (00465F38) -------------------------------------------------------- +void __fastcall drawTopArchesLowerScreen(void *a1) +{ + int v1; // edx + unsigned int v2; // edi + _BYTE *v3; // esi + int v4; // ebx + short v5; // ax + char *v6; // esi + short v7; // ax + unsigned int v8; // eax + char *v9; // esi + unsigned int v10; // eax + int v11; // eax + signed int v12; // ebp + signed int v13; // ecx + unsigned int v14; // eax + _BYTE *v15; // edi + signed int v16; // ecx + int v17; // eax + int v18; // ecx + signed int v19; // ebp + unsigned int v20; // eax + unsigned int v21; // ecx + unsigned char v22; // cf + unsigned int v23; // ecx + unsigned int v24; // eax + unsigned int v25; // ecx + int v26; // eax + unsigned int v27; // ecx + unsigned int v28; // ecx + int v29; // eax + unsigned int v30; // ecx + unsigned int v31; // eax + int v32; // ebp + signed int v33; // eax + unsigned int v34; // ecx + int v35; // eax + _BYTE *v36; // edi + unsigned int v37; // ecx + int v38; // edx + unsigned int v39; // ecx + unsigned int v40; // ecx + unsigned int v41; // eax + unsigned int v42; // ecx + int v43; // eax + int v44; // edx + unsigned int v45; // ecx + unsigned int v46; // ecx + int v47; // eax + unsigned int v48; // ecx + unsigned int v49; // eax + unsigned char v50; // of + int v51; // ebp + signed int v52; // eax + unsigned int v53; // ecx + int v54; // eax + _BYTE *v55; // edi + unsigned int v56; // ecx + int v57; // edx + unsigned int v58; // ecx + unsigned int v59; // ecx + unsigned int v60; // eax + unsigned int v61; // ecx + int v62; // eax + int v63; // edx + unsigned int v64; // ecx + unsigned int v65; // ecx + int v66; // eax + unsigned int v67; // ecx + unsigned int v68; // eax + int v69; // ebp + signed int v70; // eax + unsigned int v71; // ecx + int v72; // eax + unsigned int v73; // ecx + unsigned int v74; // ecx + unsigned int v75; // ecx + unsigned int v76; // eax + unsigned int v77; // ecx + int v78; // eax + unsigned int v79; // ecx + unsigned int v80; // ecx + int v81; // eax + unsigned int v82; // ecx + unsigned int v83; // eax + int v84; // ebp + signed int v85; // eax + unsigned int v86; // ecx + int v87; // eax + unsigned int v88; // ecx + unsigned int v89; // ecx + unsigned int v90; // ecx + unsigned int v91; // eax + unsigned int v92; // ecx + int v93; // eax + unsigned int v94; // ecx + unsigned int v95; // ecx + int v96; // eax + unsigned int v97; // ecx + unsigned int v98; // eax + int v99; // ebp + signed int v100; // eax + unsigned int v101; // ecx + int v102; // eax + _BYTE *v103; // edi + unsigned int v104; // ecx + unsigned int v105; // ecx + unsigned int v106; // ecx + unsigned int v107; // eax + unsigned int v108; // ecx + int v109; // eax + unsigned int v110; // ecx + unsigned int v111; // ecx + int v112; // eax + unsigned int v113; // ecx + unsigned int v114; // eax + signed int v115; // ebp + signed int v116; // ecx + unsigned int v117; // eax + _BYTE *v118; // edi + signed int v119; // ecx + int v120; // eax + int v121; // ebp + signed int v122; // eax + unsigned int v123; // ecx + int v124; // eax + unsigned int v125; // ecx + unsigned int v126; // ecx + unsigned int v127; // ecx + unsigned int v128; // eax + unsigned int v129; // ecx + int v130; // eax + unsigned int v131; // ecx + unsigned int v132; // ecx + int v133; // eax + unsigned int v134; // ecx + unsigned int v135; // eax + signed int v136; // ebp + signed int v137; // ecx + unsigned int v138; // eax + _BYTE *v139; // edi + signed int v140; // ecx + int v141; // eax + signed int v142; // edx + signed int v143; // ecx + int v144; // eax + _BYTE *v145; // edi + _BYTE *v146; // edi + signed int v147; // ecx + int v148; // eax + _BYTE *v149; // edi + int v150; // ecx + signed int v151; // edx + unsigned int v152; // eax + unsigned int v153; // ecx + unsigned int v154; // ecx + char *v155; // esi + _BYTE *v156; // edi + char v157; // al + int v158; // eax + _BYTE *v159; // edi + char v160; // al + unsigned int v161; // ecx + char v162; // al + int v163; // eax + _BYTE *v164; // edi + int v165; // edx + signed int v166; // eax + unsigned int v167; // ecx + int v168; // eax + _BYTE *v169; // edi + unsigned int v170; // ecx + int v171; // eax + unsigned int v172; // ecx + _BYTE *v173; // edi + int v174; // eax + _BYTE *v175; // edi + unsigned int v176; // ecx + short v177; // ax + int v178; // eax + _BYTE *v179; // edi + int v180; // edx + signed int v181; // eax + unsigned int v182; // ecx + int v183; // eax + _BYTE *v184; // edi + unsigned int v185; // ecx + int v186; // eax + unsigned int v187; // ecx + _BYTE *v188; // edi + int v189; // eax + _BYTE *v190; // edi + unsigned int v191; // ecx + short v192; // ax + int v193; // eax + _BYTE *v194; // edi + int v195; // edx + signed int v196; // eax + unsigned int v197; // ecx + int v198; // eax + unsigned int v199; // ecx + int v200; // eax + unsigned int ii; // ecx + int v202; // eax + _BYTE *v203; // edi + _BYTE *v204; // edi + unsigned int jj; // ecx + int v206; // eax + _BYTE *v207; // edi + short v208; // ax + int v209; // edx + signed int v210; // eax + unsigned int v211; // ecx + int v212; // eax + unsigned int v213; // ecx + int v214; // eax + unsigned int kk; // ecx + int v216; // eax + _BYTE *v217; // edi + _BYTE *v218; // edi + unsigned int ll; // ecx + int v220; // eax + _BYTE *v221; // edi + short v222; // ax + int v223; // edx + signed int v224; // eax + unsigned int v225; // ecx + int v226; // eax + _BYTE *v227; // edi + unsigned int v228; // ecx + int v229; // eax + unsigned int v230; // ecx + _BYTE *v231; // edi + int v232; // eax + _BYTE *v233; // edi + unsigned int v234; // ecx + short v235; // ax + int v236; // eax + _BYTE *v237; // edi + signed int v238; // edx + signed int v239; // ecx + int v240; // eax + _BYTE *v241; // edi + _BYTE *v242; // edi + signed int v243; // ecx + int v244; // eax + _BYTE *v245; // edi + int v246; // edx + signed int v247; // eax + unsigned int v248; // ecx + int v249; // eax + unsigned int v250; // ecx + int v251; // eax + unsigned int m; // ecx + int v253; // eax + _BYTE *v254; // edi + _BYTE *v255; // edi + unsigned int n; // ecx + int v257; // eax + _BYTE *v258; // edi + short v259; // ax + signed int v260; // edx + signed int v261; // ecx + int v262; // eax + _BYTE *v263; // edi + _BYTE *v264; // edi + signed int v265; // ecx + int v266; // eax + _BYTE *v267; // edi + signed int v268; // edx + signed int v269; // ecx + _BYTE *v270; // edi + signed int v271; // ecx + int v272; // ecx + signed int v273; // edx + unsigned int v274; // eax + unsigned int v275; // ecx + unsigned int v276; // ecx + _BYTE *v277; // edi + unsigned int v278; // ecx + signed int i; // edx + _BYTE *v280; // edi + unsigned int v281; // ecx + unsigned int v282; // ecx + _BYTE *v283; // edi + unsigned int v284; // ecx + signed int v285; // edx + _BYTE *v286; // edi + unsigned int v287; // ecx + unsigned int v288; // ecx + _BYTE *v289; // edi + unsigned int v290; // ecx + signed int j; // edx + unsigned int v292; // ecx + unsigned int v293; // ecx + _BYTE *v294; // edi + unsigned int v295; // ecx + _BYTE *v296; // edi + signed int v297; // edx + unsigned int v298; // ecx + unsigned int v299; // ecx + _BYTE *v300; // edi + unsigned int v301; // ecx + signed int k; // edx + _BYTE *v303; // edi + unsigned int v304; // ecx + unsigned int v305; // ecx + _BYTE *v306; // edi + unsigned int v307; // ecx + signed int v308; // edx + signed int v309; // ecx + _BYTE *v310; // edi + signed int v311; // ecx + signed int l; // edx + unsigned int v313; // ecx + unsigned int v314; // ecx + _BYTE *v315; // edi + unsigned int v316; // ecx + unsigned int v317; // edi + signed int v318; // edx + signed int v319; // ecx + _BYTE *v320; // edi + signed int v321; // ecx + int v322; // [esp-14h] [ebp-18h] + int v323; // [esp-10h] [ebp-14h] + int v324; // [esp-10h] [ebp-14h] + + world_4B3265 = (int)speed_cel_frame_num_from_light_index_frame_num; + v2 = (unsigned int)a1; + if ( !(_BYTE)light_table_index ) + { + if ( level_cel_block & 0x8000 ) + level_cel_block = *(_DWORD *)(((level_cel_block & 0xFFF) << 6) + world_4B3265) + + (unsigned short)(level_cel_block & 0xF000); + v6 = (char *)pDungeonCels + *((_DWORD *)pDungeonCels + (level_cel_block & 0xFFF)); + v8 = level_cel_block; + _LOBYTE(v8) = BYTE1(v8); + v7 = ((v8 >> 4) & 7) + 8; + goto LABEL_11; + } + if ( (_BYTE)light_table_index == lightmax ) + { + if ( level_cel_block & 0x8000 ) + level_cel_block = *(_DWORD *)(((level_cel_block & 0xFFF) << 6) + world_4B3265) + + (unsigned short)(level_cel_block & 0xF000); + v9 = (char *)pDungeonCels + *((_DWORD *)pDungeonCels + (level_cel_block & 0xFFF)); + v10 = level_cel_block; + _LOBYTE(v10) = BYTE1(v10); + v11 = (v10 >> 4) & 7; + if ( !v11 ) + { + v268 = 16; + do + { + if ( v2 < screen_buf_end ) + { + v269 = 8; + do + { + *(_BYTE *)(v2 + 1) = 0; + *(_BYTE *)(v2 + 3) = 0; + v2 += 4; + --v269; + } + while ( v269 ); + } + else + { + v9 += 32; + v2 += 32; + } + v270 = (_BYTE *)(v2 - 800); + if ( (unsigned int)v270 < screen_buf_end ) + { + v271 = 8; + do + { + *v270 = 0; + v270[2] = 0; + v270 += 4; + --v271; + } + while ( v271 ); + } + else + { + v9 += 32; + v270 += 32; + } + v2 = (unsigned int)(v270 - 800); + --v268; + } + while ( v268 ); + return; + } + if ( (_WORD)v11 != 1 ) + { + switch ( (_WORD)v11 ) + { + case 2: + world_4B325C = 0; + for ( i = 30; ; i -= 2 ) + { + if ( v2 < screen_buf_end ) + { + v280 = (_BYTE *)(i + v2); + v281 = 32 - i; + world_4B325C = ((_BYTE)world_4B325C + 1) & 1; + if ( world_4B325C ) + { + v22 = __CFSHR__(v281, 2); + v282 = v281 >> 2; + if ( !v22 || (v283 = v280 + 1, *v283 = 0, v280 = v283 + 1, v282) ) + { + do + { + v280[1] = 0; + v280[3] = 0; + v280 += 4; + --v282; + } + while ( v282 ); + } + } + else + { + v22 = __CFSHR__(v281, 2); + v284 = v281 >> 2; + if ( !v22 || (*v280 = 0, v280 += 2, v284) ) + { + do + { + *v280 = 0; + v280[2] = 0; + v280 += 4; + --v284; + } + while ( v284 ); + } + } + } + else + { + v9 = &v9[-i + 32]; + v280 = (_BYTE *)(v2 + 32); + } + v2 = (unsigned int)(v280 - 800); + if ( !i ) + break; + } + v285 = 2; + do + { + if ( v2 < screen_buf_end ) + { + v286 = (_BYTE *)(v285 + v2); + v287 = 32 - v285; + world_4B325C = ((_BYTE)world_4B325C + 1) & 1; + if ( world_4B325C ) + { + v22 = __CFSHR__(v287, 2); + v288 = v287 >> 2; + if ( !v22 || (v289 = v286 + 1, *v289 = 0, v286 = v289 + 1, v288) ) + { + do + { + v286[1] = 0; + v286[3] = 0; + v286 += 4; + --v288; + } + while ( v288 ); + } + } + else + { + v22 = __CFSHR__(v287, 2); + v290 = v287 >> 2; + if ( !v22 || (*v286 = 0, v286 += 2, v290) ) + { + do + { + *v286 = 0; + v286[2] = 0; + v286 += 4; + --v290; + } + while ( v290 ); + } + } + } + else + { + v9 = &v9[-v285 + 32]; + v286 = (_BYTE *)(v2 + 32); + } + v2 = (unsigned int)(v286 - 800); + v285 += 2; + } + while ( v285 != 32 ); + break; + case 3: + world_4B325C = 0; + for ( j = 30; ; j -= 2 ) + { + if ( v2 < screen_buf_end ) + { + v292 = 32 - j; + world_4B325C = ((_BYTE)world_4B325C + 1) & 1; + if ( world_4B325C ) + { + v22 = __CFSHR__(v292, 2); + v293 = v292 >> 2; + if ( !v22 || (v294 = (_BYTE *)(v2 + 1), *v294 = 0, v2 = (unsigned int)(v294 + 1), v293) ) + { + do + { + *(_BYTE *)(v2 + 1) = 0; + *(_BYTE *)(v2 + 3) = 0; + v2 += 4; + --v293; + } + while ( v293 ); + } + } + else + { + v22 = __CFSHR__(v292, 2); + v295 = v292 >> 2; + if ( !v22 || (*(_BYTE *)v2 = 0, v2 += 2, v295) ) + { + do + { + *(_BYTE *)v2 = 0; + *(_BYTE *)(v2 + 2) = 0; + v2 += 4; + --v295; + } + while ( v295 ); + } + } + } + else + { + v9 = &v9[-j + 32]; + v2 = v2 + 32 - j; + } + v296 = (_BYTE *)(v2 - 800); + if ( !j ) + break; + v2 = (unsigned int)&v296[j]; + } + v297 = 2; + do + { + if ( (unsigned int)v296 < screen_buf_end ) + { + v298 = 32 - v297; + world_4B325C = ((_BYTE)world_4B325C + 1) & 1; + if ( world_4B325C ) + { + v22 = __CFSHR__(v298, 2); + v299 = v298 >> 2; + if ( !v22 || (v300 = v296 + 1, *v300 = 0, v296 = v300 + 1, v299) ) + { + do + { + v296[1] = 0; + v296[3] = 0; + v296 += 4; + --v299; + } + while ( v299 ); + } + } + else + { + v22 = __CFSHR__(v298, 2); + v301 = v298 >> 2; + if ( !v22 || (*v296 = 0, v296 += 2, v301) ) + { + do + { + *v296 = 0; + v296[2] = 0; + v296 += 4; + --v301; + } + while ( v301 ); + } + } + } + else + { + v9 = &v9[-v297 + 32]; + v296 = &v296[-v297 + 32]; + } + v296 = &v296[v297 - 800]; + v297 += 2; + } + while ( v297 != 32 ); + break; + case 4: + world_4B325C = 0; + for ( k = 30; ; k -= 2 ) + { + if ( v2 < screen_buf_end ) + { + v303 = (_BYTE *)(k + v2); + v304 = 32 - k; + world_4B325C = ((_BYTE)world_4B325C + 1) & 1; + if ( world_4B325C ) + { + v22 = __CFSHR__(v304, 2); + v305 = v304 >> 2; + if ( !v22 || (v306 = v303 + 1, *v306 = 0, v303 = v306 + 1, v305) ) + { + do + { + v303[1] = 0; + v303[3] = 0; + v303 += 4; + --v305; + } + while ( v305 ); + } + } + else + { + v22 = __CFSHR__(v304, 2); + v307 = v304 >> 2; + if ( !v22 || (*v303 = 0, v303 += 2, v307) ) + { + do + { + *v303 = 0; + v303[2] = 0; + v303 += 4; + --v307; + } + while ( v307 ); + } + } + } + else + { + v9 = &v9[-k + 32]; + v303 = (_BYTE *)(v2 + 32); + } + v2 = (unsigned int)(v303 - 800); + if ( !k ) + break; + } + v308 = 8; + do + { + if ( v2 < screen_buf_end ) + { + v309 = 8; + do + { + *(_BYTE *)(v2 + 1) = 0; + *(_BYTE *)(v2 + 3) = 0; + v2 += 4; + --v309; + } + while ( v309 ); + } + else + { + v9 += 32; + v2 += 32; + } + v310 = (_BYTE *)(v2 - 800); + if ( (unsigned int)v310 < screen_buf_end ) + { + v311 = 8; + do + { + *v310 = 0; + v310[2] = 0; + v310 += 4; + --v311; + } + while ( v311 ); + } + else + { + v9 += 32; + v310 += 32; + } + v2 = (unsigned int)(v310 - 800); + --v308; + } + while ( v308 ); + break; + default: + world_4B325C = 0; + for ( l = 30; ; l -= 2 ) + { + if ( v2 < screen_buf_end ) + { + v313 = 32 - l; + world_4B325C = ((_BYTE)world_4B325C + 1) & 1; + if ( world_4B325C ) + { + v22 = __CFSHR__(v313, 2); + v314 = v313 >> 2; + if ( !v22 || (v315 = (_BYTE *)(v2 + 1), *v315 = 0, v2 = (unsigned int)(v315 + 1), v314) ) + { + do + { + *(_BYTE *)(v2 + 1) = 0; + *(_BYTE *)(v2 + 3) = 0; + v2 += 4; + --v314; + } + while ( v314 ); + } + } + else + { + v22 = __CFSHR__(v313, 2); + v316 = v313 >> 2; + if ( !v22 || (*(_BYTE *)v2 = 0, v2 += 2, v316) ) + { + do + { + *(_BYTE *)v2 = 0; + *(_BYTE *)(v2 + 2) = 0; + v2 += 4; + --v316; + } + while ( v316 ); + } + } + } + else + { + v9 = &v9[-l + 32]; + v2 = v2 + 32 - l; + } + v317 = v2 - 800; + if ( !l ) + break; + v2 = l + v317; + } + v318 = 8; + do + { + if ( v317 < screen_buf_end ) + { + v319 = 8; + do + { + *(_BYTE *)(v317 + 1) = 0; + *(_BYTE *)(v317 + 3) = 0; + v317 += 4; + --v319; + } + while ( v319 ); + } + else + { + v9 += 32; + v317 += 32; + } + v320 = (_BYTE *)(v317 - 800); + if ( (unsigned int)v320 < screen_buf_end ) + { + v321 = 8; + do + { + *v320 = 0; + v320[2] = 0; + v320 += 4; + --v321; + } + while ( v321 ); + } + else + { + v9 += 32; + v320 += 32; + } + v317 = (unsigned int)(v320 - 800); + --v318; + } + while ( v318 ); + break; + } + return; + } + world_4B325C = (unsigned char)a1 & 1; + v272 = 32; +LABEL_412: + v324 = v272; + v273 = 32; + while ( 1 ) + { + while ( 1 ) + { + v274 = (unsigned char)*v9++; + if ( (v274 & 0x80u) == 0 ) + break; + _LOBYTE(v274) = -(char)v274; + v2 += v274; + v273 -= v274; + if ( !v273 ) + { +LABEL_433: + world_4B325C = ((_BYTE)world_4B325C + 1) & 1; + v2 -= 800; + v272 = v324 - 1; + if ( v324 == 1 ) + return; + goto LABEL_412; + } + } + v273 -= v274; + if ( v2 < screen_buf_end ) + { + v9 += v274; + if ( (v2 & 1) == world_4B325C ) + { + v275 = v274 >> 1; + if ( !(v274 & 1) ) + goto LABEL_420; + ++v2; + if ( v275 ) + { +LABEL_427: + v22 = v275 & 1; + v278 = v275 >> 1; + if ( !v22 || (*(_BYTE *)v2 = 0, v2 += 2, v278) ) + { + do + { + *(_BYTE *)v2 = 0; + *(_BYTE *)(v2 + 2) = 0; + v2 += 4; + --v278; + } + while ( v278 ); + } + goto LABEL_430; + } + } + else + { + v275 = v274 >> 1; + if ( !(v274 & 1) ) + goto LABEL_427; + *(_BYTE *)v2++ = 0; + if ( v275 ) + { +LABEL_420: + v22 = v275 & 1; + v276 = v275 >> 1; + if ( !v22 || (v277 = (_BYTE *)(v2 + 1), *v277 = 0, v2 = (unsigned int)(v277 + 1), v276) ) + { + do + { + *(_BYTE *)(v2 + 1) = 0; + *(_BYTE *)(v2 + 3) = 0; + v2 += 4; + --v276; + } + while ( v276 ); + } + goto LABEL_430; + } + } + } + else + { + v9 += v274; + v2 += v274; + } +LABEL_430: + if ( !v273 ) + goto LABEL_433; + } + } + if ( !(level_cel_block & 0x8000) ) + { + v3 = (unsigned char *)pDungeonCels + *((_DWORD *)pDungeonCels + (level_cel_block & 0xFFF)); + v4 = dword_646A20 + (light_table_index << 8); + v5 = (unsigned char)(BYTE1(level_cel_block) >> 4); + if ( !(BYTE1(level_cel_block) >> 4) ) + { + v12 = 16; + do + { + if ( v2 < screen_buf_end ) + { + v13 = 8; + do + { + v14 = *(_DWORD *)v3; + v3 += 4; + _LOBYTE(v1) = BYTE1(v14); + v14 >>= 16; + *(_BYTE *)(v2 + 1) = *(_BYTE *)(v4 + v1); + _LOBYTE(v1) = BYTE1(v14); + v2 += 4; + --v13; + *(_BYTE *)(v2 - 1) = *(_BYTE *)(v4 + v1); + } + while ( v13 ); + } + else + { + v3 += 32; + v2 += 32; + } + v15 = (_BYTE *)(v2 - 800); + if ( (unsigned int)v15 < screen_buf_end ) + { + v16 = 8; + do + { + v17 = *(_DWORD *)v3; + v3 += 4; + _LOBYTE(v1) = v17; + *v15 = *(_BYTE *)(v4 + v1); + _LOBYTE(v1) = BYTE2(v17); + v15 += 4; + --v16; + *(v15 - 2) = *(_BYTE *)(v4 + v1); + } + while ( v16 ); + } + else + { + v3 += 32; + v15 += 32; + } + v2 = (unsigned int)(v15 - 800); + --v12; + } + while ( v12 ); + return; + } + if ( v5 == 1 ) + { + world_4B325C = (unsigned char)a1 & 1; + v18 = 32; + do + { + v322 = v18; + v19 = 32; + do + { + while ( 1 ) + { + v20 = (unsigned char)*v3++; + if ( (v20 & 0x80u) == 0 ) + break; + _LOBYTE(v20) = -(char)v20; + v2 += v20; + v19 -= v20; + if ( !v19 ) + goto LABEL_69; + } + v19 -= v20; + if ( v2 < screen_buf_end ) + { + if ( (v2 & 1) == world_4B325C ) + { + v21 = v20 >> 1; + if ( v20 & 1 ) + { + ++v3; + ++v2; + v22 = v21 & 1; + v25 = v20 >> 2; + if ( v22 ) + { + _LOBYTE(v1) = *v3; + v3 += 2; + *(_BYTE *)v2 = *(_BYTE *)(v4 + v1); + v2 += 2; + } + if ( (_BYTE)v25 ) + { + do + { + v26 = *(_DWORD *)v3; + v3 += 4; + _LOBYTE(v1) = v26; + *(_BYTE *)v2 = *(_BYTE *)(v4 + v1); + _LOBYTE(v1) = BYTE2(v26); + v2 += 4; + --v25; + *(_BYTE *)(v2 - 2) = *(_BYTE *)(v4 + v1); + } + while ( v25 ); + } + } + else + { + v22 = v21 & 1; + v23 = v20 >> 2; + if ( v22 ) + { + _LOBYTE(v1) = v3[1]; + v3 += 2; + *(_BYTE *)(v2 + 1) = *(_BYTE *)(v4 + v1); + v2 += 2; + } + if ( (_BYTE)v23 ) + { + do + { + v24 = *(_DWORD *)v3; + v3 += 4; + _LOBYTE(v1) = BYTE1(v24); + v24 >>= 16; + *(_BYTE *)(v2 + 1) = *(_BYTE *)(v4 + v1); + _LOBYTE(v1) = BYTE1(v24); + v2 += 4; + --v23; + *(_BYTE *)(v2 - 1) = *(_BYTE *)(v4 + v1); + } + while ( v23 ); + } + } + } + else + { + v27 = v20 >> 1; + if ( v20 & 1 ) + { + _LOBYTE(v1) = *v3++; + *(_BYTE *)v2++ = *(_BYTE *)(v4 + v1); + v22 = v27 & 1; + v30 = v20 >> 2; + if ( v22 ) + { + _LOBYTE(v1) = v3[1]; + v3 += 2; + *(_BYTE *)(v2 + 1) = *(_BYTE *)(v4 + v1); + v2 += 2; + } + if ( (_BYTE)v30 ) + { + do + { + v31 = *(_DWORD *)v3; + v3 += 4; + _LOBYTE(v1) = BYTE1(v31); + v31 >>= 16; + *(_BYTE *)(v2 + 1) = *(_BYTE *)(v4 + v1); + _LOBYTE(v1) = BYTE1(v31); + v2 += 4; + --v30; + *(_BYTE *)(v2 - 1) = *(_BYTE *)(v4 + v1); + } + while ( v30 ); + } + } + else + { + v22 = v27 & 1; + v28 = v20 >> 2; + if ( v22 ) + { + _LOBYTE(v1) = *v3; + v3 += 2; + *(_BYTE *)v2 = *(_BYTE *)(v4 + v1); + v2 += 2; + } + if ( (_BYTE)v28 ) + { + do + { + v29 = *(_DWORD *)v3; + v3 += 4; + _LOBYTE(v1) = v29; + *(_BYTE *)v2 = *(_BYTE *)(v4 + v1); + _LOBYTE(v1) = BYTE2(v29); + v2 += 4; + --v28; + *(_BYTE *)(v2 - 2) = *(_BYTE *)(v4 + v1); + } + while ( v28 ); + } + } + } + } + else + { + v3 += v20; + v2 += v20; + } + } + while ( v19 ); +LABEL_69: + world_4B325C = ((_BYTE)world_4B325C + 1) & 1; + v2 -= 800; + v18 = v322 - 1; + } + while ( v322 != 1 ); + return; + } + if ( v5 != 2 ) + { + if ( v5 != 3 ) + { + if ( v5 != 4 ) + { + world_4B325C = 0; + v121 = 30; + if ( (unsigned int)a1 >= screen_buf_end ) + { + v122 = (unsigned int)((char *)a1 - screen_buf_end + 1023) >> 8; + if ( v122 > 45 ) + { + v2 = (unsigned int)a1 - 12288; + v3 += 288; +LABEL_249: + v136 = 8; + do + { + if ( v2 < screen_buf_end ) + { + v137 = 8; + do + { + v138 = *(_DWORD *)v3; + v3 += 4; + _LOBYTE(v1) = BYTE1(v138); + v138 >>= 16; + *(_BYTE *)(v2 + 1) = *(_BYTE *)(v4 + v1); + _LOBYTE(v1) = BYTE1(v138); + v2 += 4; + --v137; + *(_BYTE *)(v2 - 1) = *(_BYTE *)(v4 + v1); + } + while ( v137 ); + } + else + { + v3 += 32; + v2 += 32; + } + v139 = (_BYTE *)(v2 - 800); + if ( (unsigned int)v139 < screen_buf_end ) + { + v140 = 8; + do + { + v141 = *(_DWORD *)v3; + v3 += 4; + _LOBYTE(v1) = v141; + *v139 = *(_BYTE *)(v4 + v1); + _LOBYTE(v1) = BYTE2(v141); + v139 += 4; + --v140; + *(v139 - 2) = *(_BYTE *)(v4 + v1); + } + while ( v140 ); + } + else + { + v3 += 32; + v139 += 32; + } + v2 = (unsigned int)(v139 - 800); + --v136; + } + while ( v136 ); + return; + } + v123 = world_4B33FD[v122]; + v3 += *(int *)((char *)world_4B34BD + v123); + v124 = 192 * v123; + v123 >>= 1; + v2 -= v124; + v121 = 30 - v123; + world_4B325C += v123 >> 1; + } + do + { + v125 = 32 - v121; + world_4B325C = ((_BYTE)world_4B325C + 1) & 1; + if ( world_4B325C ) + { + v22 = v125 & 1; + v126 = v125 >> 1; + if ( v22 ) + { + ++v3; + ++v2; + v22 = v126 & 1; + v129 = v126 >> 1; + if ( v22 ) + { + _LOBYTE(v1) = *v3; + v3 += 2; + *(_BYTE *)v2 = *(_BYTE *)(v4 + v1); + v2 += 2; + } + if ( (_BYTE)v129 ) + { + do + { + v130 = *(_DWORD *)v3; + v3 += 4; + _LOBYTE(v1) = v130; + *(_BYTE *)v2 = *(_BYTE *)(v4 + v1); + _LOBYTE(v1) = BYTE2(v130); + v2 += 4; + --v129; + *(_BYTE *)(v2 - 2) = *(_BYTE *)(v4 + v1); + } + while ( v129 ); + } + } + else + { + v22 = v126 & 1; + v127 = v126 >> 1; + if ( v22 ) + { + _LOBYTE(v1) = v3[1]; + v3 += 2; + *(_BYTE *)(v2 + 1) = *(_BYTE *)(v4 + v1); + v2 += 2; + } + if ( (_BYTE)v127 ) + { + do + { + v128 = *(_DWORD *)v3; + v3 += 4; + _LOBYTE(v1) = BYTE1(v128); + v128 >>= 16; + *(_BYTE *)(v2 + 1) = *(_BYTE *)(v4 + v1); + _LOBYTE(v1) = BYTE1(v128); + v2 += 4; + --v127; + *(_BYTE *)(v2 - 1) = *(_BYTE *)(v4 + v1); + } + while ( v127 ); + } + } + v1 = (unsigned char)v3 & 2; + v3 += v1; + } + else + { + v22 = v125 & 1; + v131 = v125 >> 1; + if ( v22 ) + { + _LOBYTE(v1) = *v3++; + *(_BYTE *)v2++ = *(_BYTE *)(v4 + v1); + v22 = v131 & 1; + v134 = v131 >> 1; + if ( v22 ) + { + _LOBYTE(v1) = v3[1]; + v3 += 2; + *(_BYTE *)(v2 + 1) = *(_BYTE *)(v4 + v1); + v2 += 2; + } + if ( (_BYTE)v134 ) + { + do + { + v135 = *(_DWORD *)v3; + v3 += 4; + _LOBYTE(v1) = BYTE1(v135); + v135 >>= 16; + *(_BYTE *)(v2 + 1) = *(_BYTE *)(v4 + v1); + _LOBYTE(v1) = BYTE1(v135); + v2 += 4; + --v134; + *(_BYTE *)(v2 - 1) = *(_BYTE *)(v4 + v1); + } + while ( v134 ); + } + } + else + { + v22 = v131 & 1; + v132 = v131 >> 1; + if ( v22 ) + { + _LOBYTE(v1) = *v3; + v3 += 2; + *(_BYTE *)v2 = *(_BYTE *)(v4 + v1); + v2 += 2; + } + if ( (_BYTE)v132 ) + { + do + { + v133 = *(_DWORD *)v3; + v3 += 4; + _LOBYTE(v1) = v133; + *(_BYTE *)v2 = *(_BYTE *)(v4 + v1); + _LOBYTE(v1) = BYTE2(v133); + v2 += 4; + --v132; + *(_BYTE *)(v2 - 2) = *(_BYTE *)(v4 + v1); + } + while ( v132 ); + } + } + v1 = (unsigned char)v3 & 2; + v3 += v1; + } + v2 = v121 + v2 - 800; + v50 = __OFSUB__(v121, 2); + v121 -= 2; + } + while ( !((v121 < 0) ^ v50) ); + goto LABEL_249; + } + world_4B325C = 0; + v99 = 30; + if ( (unsigned int)a1 >= screen_buf_end ) + { + v100 = (unsigned int)((char *)a1 - screen_buf_end + 1023) >> 8; + if ( v100 > 45 ) + { + v2 = (unsigned int)a1 - 12288; + v3 += 288; +LABEL_210: + v115 = 8; + do + { + if ( v2 < screen_buf_end ) + { + v116 = 8; + do + { + v117 = *(_DWORD *)v3; + v3 += 4; + _LOBYTE(v1) = BYTE1(v117); + v117 >>= 16; + *(_BYTE *)(v2 + 1) = *(_BYTE *)(v4 + v1); + _LOBYTE(v1) = BYTE1(v117); + v2 += 4; + --v116; + *(_BYTE *)(v2 - 1) = *(_BYTE *)(v4 + v1); + } + while ( v116 ); + } + else + { + v3 += 32; + v2 += 32; + } + v118 = (_BYTE *)(v2 - 800); + if ( (unsigned int)v118 < screen_buf_end ) + { + v119 = 8; + do + { + v120 = *(_DWORD *)v3; + v3 += 4; + _LOBYTE(v1) = v120; + *v118 = *(_BYTE *)(v4 + v1); + _LOBYTE(v1) = BYTE2(v120); + v118 += 4; + --v119; + *(v118 - 2) = *(_BYTE *)(v4 + v1); + } + while ( v119 ); + } + else + { + v3 += 32; + v118 += 32; + } + v2 = (unsigned int)(v118 - 800); + --v115; + } + while ( v115 ); + return; + } + v101 = world_4B33FD[v100]; + v3 += *(int *)((char *)world_4B34BD + v101); + v102 = 192 * v101; + v101 >>= 1; + v2 -= v102; + v99 = 30 - v101; + world_4B325C += v101 >> 1; + } + do + { + v103 = (_BYTE *)(v99 + v2); + v104 = 32 - v99; + world_4B325C = ((_BYTE)world_4B325C + 1) & 1; + if ( world_4B325C ) + { + v1 = v104 & 2; + v3 += v1; + v22 = v104 & 1; + v105 = v104 >> 1; + if ( v22 ) + { + ++v3; + ++v103; + v22 = v105 & 1; + v108 = v105 >> 1; + if ( v22 ) + { + _LOBYTE(v1) = *v3; + v3 += 2; + *v103 = *(_BYTE *)(v4 + v1); + v103 += 2; + } + if ( (_BYTE)v108 ) + { + do + { + v109 = *(_DWORD *)v3; + v3 += 4; + _LOBYTE(v1) = v109; + *v103 = *(_BYTE *)(v4 + v1); + _LOBYTE(v1) = BYTE2(v109); + v103 += 4; + --v108; + *(v103 - 2) = *(_BYTE *)(v4 + v1); + } + while ( v108 ); + } + } + else + { + v22 = v105 & 1; + v106 = v105 >> 1; + if ( v22 ) + { + _LOBYTE(v1) = v3[1]; + v3 += 2; + v103[1] = *(_BYTE *)(v4 + v1); + v103 += 2; + } + if ( (_BYTE)v106 ) + { + do + { + v107 = *(_DWORD *)v3; + v3 += 4; + _LOBYTE(v1) = BYTE1(v107); + v107 >>= 16; + v103[1] = *(_BYTE *)(v4 + v1); + _LOBYTE(v1) = BYTE1(v107); + v103 += 4; + --v106; + *(v103 - 1) = *(_BYTE *)(v4 + v1); + } + while ( v106 ); + } + } + } + else + { + v1 = v104 & 2; + v3 += v1; + v22 = v104 & 1; + v110 = v104 >> 1; + if ( v22 ) + { + _LOBYTE(v1) = *v3++; + *v103++ = *(_BYTE *)(v4 + v1); + v22 = v110 & 1; + v113 = v110 >> 1; + if ( v22 ) + { + _LOBYTE(v1) = v3[1]; + v3 += 2; + v103[1] = *(_BYTE *)(v4 + v1); + v103 += 2; + } + if ( (_BYTE)v113 ) + { + do + { + v114 = *(_DWORD *)v3; + v3 += 4; + _LOBYTE(v1) = BYTE1(v114); + v114 >>= 16; + v103[1] = *(_BYTE *)(v4 + v1); + _LOBYTE(v1) = BYTE1(v114); + v103 += 4; + --v113; + *(v103 - 1) = *(_BYTE *)(v4 + v1); + } + while ( v113 ); + } + } + else + { + v22 = v110 & 1; + v111 = v110 >> 1; + if ( v22 ) + { + _LOBYTE(v1) = *v3; + v3 += 2; + *v103 = *(_BYTE *)(v4 + v1); + v103 += 2; + } + if ( (_BYTE)v111 ) + { + do + { + v112 = *(_DWORD *)v3; + v3 += 4; + _LOBYTE(v1) = v112; + *v103 = *(_BYTE *)(v4 + v1); + _LOBYTE(v1) = BYTE2(v112); + v103 += 4; + --v111; + *(v103 - 2) = *(_BYTE *)(v4 + v1); + } + while ( v111 ); + } + } + } + v2 = (unsigned int)(v103 - 800); + v50 = __OFSUB__(v99, 2); + v99 -= 2; + } + while ( !((v99 < 0) ^ v50) ); + goto LABEL_210; + } + world_4B325C = 0; + v69 = 30; + if ( (unsigned int)a1 >= screen_buf_end ) + { + v70 = (unsigned int)((char *)a1 - screen_buf_end + 1023) >> 8; + if ( v70 > 45 ) + { + v2 = (unsigned int)a1 - 12288; + v3 += 288; +LABEL_154: + v84 = 2; + if ( v2 >= screen_buf_end ) + { + v85 = (v2 - screen_buf_end + 1023) >> 8; + if ( v85 > 42 ) + return; + v86 = world_4B33FD[v85]; + v3 += *(int *)((char *)world_4B3501 + v86); + v87 = 192 * v86; + v86 >>= 1; + v2 -= v87; + v84 = v86 + 2; + world_4B325C += v86 >> 1; + } + do + { + v88 = 32 - v84; + world_4B325C = ((_BYTE)world_4B325C + 1) & 1; + if ( world_4B325C ) + { + v22 = v88 & 1; + v89 = v88 >> 1; + if ( v22 ) + { + ++v3; + ++v2; + v22 = v89 & 1; + v92 = v89 >> 1; + if ( v22 ) + { + _LOBYTE(v1) = *v3; + v3 += 2; + *(_BYTE *)v2 = *(_BYTE *)(v4 + v1); + v2 += 2; + } + if ( (_BYTE)v92 ) + { + do + { + v93 = *(_DWORD *)v3; + v3 += 4; + _LOBYTE(v1) = v93; + *(_BYTE *)v2 = *(_BYTE *)(v4 + v1); + _LOBYTE(v1) = BYTE2(v93); + v2 += 4; + --v92; + *(_BYTE *)(v2 - 2) = *(_BYTE *)(v4 + v1); + } + while ( v92 ); + } + } + else + { + v22 = v89 & 1; + v90 = v89 >> 1; + if ( v22 ) + { + _LOBYTE(v1) = v3[1]; + v3 += 2; + *(_BYTE *)(v2 + 1) = *(_BYTE *)(v4 + v1); + v2 += 2; + } + if ( (_BYTE)v90 ) + { + do + { + v91 = *(_DWORD *)v3; + v3 += 4; + _LOBYTE(v1) = BYTE1(v91); + v91 >>= 16; + *(_BYTE *)(v2 + 1) = *(_BYTE *)(v4 + v1); + _LOBYTE(v1) = BYTE1(v91); + v2 += 4; + --v90; + *(_BYTE *)(v2 - 1) = *(_BYTE *)(v4 + v1); + } + while ( v90 ); + } + } + v1 = (unsigned char)v3 & 2; + v3 += v1; + } + else + { + v22 = v88 & 1; + v94 = v88 >> 1; + if ( v22 ) + { + _LOBYTE(v1) = *v3++; + *(_BYTE *)v2++ = *(_BYTE *)(v4 + v1); + v22 = v94 & 1; + v97 = v94 >> 1; + if ( v22 ) + { + _LOBYTE(v1) = v3[1]; + v3 += 2; + *(_BYTE *)(v2 + 1) = *(_BYTE *)(v4 + v1); + v2 += 2; + } + if ( (_BYTE)v97 ) + { + do + { + v98 = *(_DWORD *)v3; + v3 += 4; + _LOBYTE(v1) = BYTE1(v98); + v98 >>= 16; + *(_BYTE *)(v2 + 1) = *(_BYTE *)(v4 + v1); + _LOBYTE(v1) = BYTE1(v98); + v2 += 4; + --v97; + *(_BYTE *)(v2 - 1) = *(_BYTE *)(v4 + v1); + } + while ( v97 ); + } + } + else + { + v22 = v94 & 1; + v95 = v94 >> 1; + if ( v22 ) + { + _LOBYTE(v1) = *v3; + v3 += 2; + *(_BYTE *)v2 = *(_BYTE *)(v4 + v1); + v2 += 2; + } + if ( (_BYTE)v95 ) + { + do + { + v96 = *(_DWORD *)v3; + v3 += 4; + _LOBYTE(v1) = v96; + *(_BYTE *)v2 = *(_BYTE *)(v4 + v1); + _LOBYTE(v1) = BYTE2(v96); + v2 += 4; + --v95; + *(_BYTE *)(v2 - 2) = *(_BYTE *)(v4 + v1); + } + while ( v95 ); + } + } + v1 = (unsigned char)v3 & 2; + v3 += v1; + } + v2 = v84 + v2 - 800; + v84 += 2; + } + while ( v84 != 32 ); + return; + } + v71 = world_4B33FD[v70]; + v3 += *(int *)((char *)world_4B34BD + v71); + v72 = 192 * v71; + v71 >>= 1; + v2 -= v72; + v69 = 30 - v71; + world_4B325C += v71 >> 1; + } + do + { + v73 = 32 - v69; + world_4B325C = ((_BYTE)world_4B325C + 1) & 1; + if ( world_4B325C ) + { + v22 = v73 & 1; + v74 = v73 >> 1; + if ( v22 ) + { + ++v3; + ++v2; + v22 = v74 & 1; + v77 = v74 >> 1; + if ( v22 ) + { + _LOBYTE(v1) = *v3; + v3 += 2; + *(_BYTE *)v2 = *(_BYTE *)(v4 + v1); + v2 += 2; + } + if ( (_BYTE)v77 ) + { + do + { + v78 = *(_DWORD *)v3; + v3 += 4; + _LOBYTE(v1) = v78; + *(_BYTE *)v2 = *(_BYTE *)(v4 + v1); + _LOBYTE(v1) = BYTE2(v78); + v2 += 4; + --v77; + *(_BYTE *)(v2 - 2) = *(_BYTE *)(v4 + v1); + } + while ( v77 ); + } + } + else + { + v22 = v74 & 1; + v75 = v74 >> 1; + if ( v22 ) + { + _LOBYTE(v1) = v3[1]; + v3 += 2; + *(_BYTE *)(v2 + 1) = *(_BYTE *)(v4 + v1); + v2 += 2; + } + if ( (_BYTE)v75 ) + { + do + { + v76 = *(_DWORD *)v3; + v3 += 4; + _LOBYTE(v1) = BYTE1(v76); + v76 >>= 16; + *(_BYTE *)(v2 + 1) = *(_BYTE *)(v4 + v1); + _LOBYTE(v1) = BYTE1(v76); + v2 += 4; + --v75; + *(_BYTE *)(v2 - 1) = *(_BYTE *)(v4 + v1); + } + while ( v75 ); + } + } + v1 = (unsigned char)v3 & 2; + v3 += v1; + } + else + { + v22 = v73 & 1; + v79 = v73 >> 1; + if ( v22 ) + { + _LOBYTE(v1) = *v3++; + *(_BYTE *)v2++ = *(_BYTE *)(v4 + v1); + v22 = v79 & 1; + v82 = v79 >> 1; + if ( v22 ) + { + _LOBYTE(v1) = v3[1]; + v3 += 2; + *(_BYTE *)(v2 + 1) = *(_BYTE *)(v4 + v1); + v2 += 2; + } + if ( (_BYTE)v82 ) + { + do + { + v83 = *(_DWORD *)v3; + v3 += 4; + _LOBYTE(v1) = BYTE1(v83); + v83 >>= 16; + *(_BYTE *)(v2 + 1) = *(_BYTE *)(v4 + v1); + _LOBYTE(v1) = BYTE1(v83); + v2 += 4; + --v82; + *(_BYTE *)(v2 - 1) = *(_BYTE *)(v4 + v1); + } + while ( v82 ); + } + } + else + { + v22 = v79 & 1; + v80 = v79 >> 1; + if ( v22 ) + { + _LOBYTE(v1) = *v3; + v3 += 2; + *(_BYTE *)v2 = *(_BYTE *)(v4 + v1); + v2 += 2; + } + if ( (_BYTE)v80 ) + { + do + { + v81 = *(_DWORD *)v3; + v3 += 4; + _LOBYTE(v1) = v81; + *(_BYTE *)v2 = *(_BYTE *)(v4 + v1); + _LOBYTE(v1) = BYTE2(v81); + v2 += 4; + --v80; + *(_BYTE *)(v2 - 2) = *(_BYTE *)(v4 + v1); + } + while ( v80 ); + } + } + v1 = (unsigned char)v3 & 2; + v3 += v1; + } + v2 = v69 + v2 - 800; + v50 = __OFSUB__(v69, 2); + v69 -= 2; + } + while ( !((v69 < 0) ^ v50) ); + goto LABEL_154; + } + world_4B325C = 0; + v32 = 30; + if ( (unsigned int)a1 >= screen_buf_end ) + { + v33 = (unsigned int)((char *)a1 - screen_buf_end + 1023) >> 8; + if ( v33 > 45 ) + { + v2 = (unsigned int)a1 - 12288; + v3 += 288; +LABEL_98: + v51 = 2; + if ( v2 >= screen_buf_end ) + { + v52 = (v2 - screen_buf_end + 1023) >> 8; + if ( v52 > 42 ) + return; + v53 = world_4B33FD[v52]; + v3 += *(int *)((char *)world_4B3501 + v53); + v54 = 192 * v53; + v53 >>= 1; + v2 -= v54; + v51 = v53 + 2; + world_4B325C += v53 >> 1; + } + do + { + v55 = (_BYTE *)(v51 + v2); + v56 = 32 - v51; + world_4B325C = ((_BYTE)world_4B325C + 1) & 1; + if ( world_4B325C ) + { + v57 = v56 & 2; + v3 += v57; + v22 = v56 & 1; + v58 = v56 >> 1; + if ( v22 ) + { + ++v3; + ++v55; + v22 = v58 & 1; + v61 = v58 >> 1; + if ( v22 ) + { + _LOBYTE(v57) = *v3; + v3 += 2; + *v55 = *(_BYTE *)(v4 + v57); + v55 += 2; + } + if ( (_BYTE)v61 ) + { + do + { + v62 = *(_DWORD *)v3; + v3 += 4; + _LOBYTE(v57) = v62; + *v55 = *(_BYTE *)(v4 + v57); + _LOBYTE(v57) = BYTE2(v62); + v55 += 4; + --v61; + *(v55 - 2) = *(_BYTE *)(v4 + v57); + } + while ( v61 ); + } + } + else + { + v22 = v58 & 1; + v59 = v58 >> 1; + if ( v22 ) + { + _LOBYTE(v57) = v3[1]; + v3 += 2; + v55[1] = *(_BYTE *)(v4 + v57); + v55 += 2; + } + if ( (_BYTE)v59 ) + { + do + { + v60 = *(_DWORD *)v3; + v3 += 4; + _LOBYTE(v57) = BYTE1(v60); + v60 >>= 16; + v55[1] = *(_BYTE *)(v4 + v57); + _LOBYTE(v57) = BYTE1(v60); + v55 += 4; + --v59; + *(v55 - 1) = *(_BYTE *)(v4 + v57); + } + while ( v59 ); + } + } + } + else + { + v63 = v56 & 2; + v3 += v63; + v22 = v56 & 1; + v64 = v56 >> 1; + if ( v22 ) + { + _LOBYTE(v63) = *v3++; + *v55++ = *(_BYTE *)(v4 + v63); + v22 = v64 & 1; + v67 = v64 >> 1; + if ( v22 ) + { + _LOBYTE(v63) = v3[1]; + v3 += 2; + v55[1] = *(_BYTE *)(v4 + v63); + v55 += 2; + } + if ( (_BYTE)v67 ) + { + do + { + v68 = *(_DWORD *)v3; + v3 += 4; + _LOBYTE(v63) = BYTE1(v68); + v68 >>= 16; + v55[1] = *(_BYTE *)(v4 + v63); + _LOBYTE(v63) = BYTE1(v68); + v55 += 4; + --v67; + *(v55 - 1) = *(_BYTE *)(v4 + v63); + } + while ( v67 ); + } + } + else + { + v22 = v64 & 1; + v65 = v64 >> 1; + if ( v22 ) + { + _LOBYTE(v63) = *v3; + v3 += 2; + *v55 = *(_BYTE *)(v4 + v63); + v55 += 2; + } + if ( (_BYTE)v65 ) + { + do + { + v66 = *(_DWORD *)v3; + v3 += 4; + _LOBYTE(v63) = v66; + *v55 = *(_BYTE *)(v4 + v63); + _LOBYTE(v63) = BYTE2(v66); + v55 += 4; + --v65; + *(v55 - 2) = *(_BYTE *)(v4 + v63); + } + while ( v65 ); + } + } + } + v2 = (unsigned int)(v55 - 800); + v51 += 2; + } + while ( v51 != 32 ); + return; + } + v34 = world_4B33FD[v33]; + v3 += *(int *)((char *)world_4B34BD + v34); + v35 = 192 * v34; + v34 >>= 1; + v2 -= v35; + v32 = 30 - v34; + world_4B325C += v34 >> 1; + } + do + { + v36 = (_BYTE *)(v32 + v2); + v37 = 32 - v32; + world_4B325C = ((_BYTE)world_4B325C + 1) & 1; + if ( world_4B325C ) + { + v38 = v37 & 2; + v3 += v38; + v22 = v37 & 1; + v39 = v37 >> 1; + if ( v22 ) + { + ++v3; + ++v36; + v22 = v39 & 1; + v42 = v39 >> 1; + if ( v22 ) + { + _LOBYTE(v38) = *v3; + v3 += 2; + *v36 = *(_BYTE *)(v4 + v38); + v36 += 2; + } + if ( (_BYTE)v42 ) + { + do + { + v43 = *(_DWORD *)v3; + v3 += 4; + _LOBYTE(v38) = v43; + *v36 = *(_BYTE *)(v4 + v38); + _LOBYTE(v38) = BYTE2(v43); + v36 += 4; + --v42; + *(v36 - 2) = *(_BYTE *)(v4 + v38); + } + while ( v42 ); + } + } + else + { + v22 = v39 & 1; + v40 = v39 >> 1; + if ( v22 ) + { + _LOBYTE(v38) = v3[1]; + v3 += 2; + v36[1] = *(_BYTE *)(v4 + v38); + v36 += 2; + } + if ( (_BYTE)v40 ) + { + do + { + v41 = *(_DWORD *)v3; + v3 += 4; + _LOBYTE(v38) = BYTE1(v41); + v41 >>= 16; + v36[1] = *(_BYTE *)(v4 + v38); + _LOBYTE(v38) = BYTE1(v41); + v36 += 4; + --v40; + *(v36 - 1) = *(_BYTE *)(v4 + v38); + } + while ( v40 ); + } + } + } + else + { + v44 = v37 & 2; + v3 += v44; + v22 = v37 & 1; + v45 = v37 >> 1; + if ( v22 ) + { + _LOBYTE(v44) = *v3++; + *v36++ = *(_BYTE *)(v4 + v44); + v22 = v45 & 1; + v48 = v45 >> 1; + if ( v22 ) + { + _LOBYTE(v44) = v3[1]; + v3 += 2; + v36[1] = *(_BYTE *)(v4 + v44); + v36 += 2; + } + if ( (_BYTE)v48 ) + { + do + { + v49 = *(_DWORD *)v3; + v3 += 4; + _LOBYTE(v44) = BYTE1(v49); + v49 >>= 16; + v36[1] = *(_BYTE *)(v4 + v44); + _LOBYTE(v44) = BYTE1(v49); + v36 += 4; + --v48; + *(v36 - 1) = *(_BYTE *)(v4 + v44); + } + while ( v48 ); + } + } + else + { + v22 = v45 & 1; + v46 = v45 >> 1; + if ( v22 ) + { + _LOBYTE(v44) = *v3; + v3 += 2; + *v36 = *(_BYTE *)(v4 + v44); + v36 += 2; + } + if ( (_BYTE)v46 ) + { + do + { + v47 = *(_DWORD *)v3; + v3 += 4; + _LOBYTE(v44) = v47; + *v36 = *(_BYTE *)(v4 + v44); + _LOBYTE(v44) = BYTE2(v47); + v36 += 4; + --v46; + *(v36 - 2) = *(_BYTE *)(v4 + v44); + } + while ( v46 ); + } + } + } + v2 = (unsigned int)(v36 - 800); + v50 = __OFSUB__(v32, 2); + v32 -= 2; + } + while ( !((v32 < 0) ^ v50) ); + goto LABEL_98; + } + v6 = (char *)pSpeedCels + *(_DWORD *)(4 * (light_table_index + 16 * (level_cel_block & 0xFFF)) + world_4B3265); + v7 = (unsigned char)(BYTE1(level_cel_block) >> 4); +LABEL_11: + switch ( v7 ) + { + case 8: + v142 = 16; + do + { + if ( v2 < screen_buf_end ) + { + v143 = 8; + do + { + v144 = *(_DWORD *)v6; + v6 += 4; + v145 = (_BYTE *)(v2 + 1); + v144 = __ROR4__(v144, 8); + *v145 = v144; + v145 += 2; + *v145 = __ROR4__(v144, 16); + v2 = (unsigned int)(v145 + 1); + --v143; + } + while ( v143 ); + } + else + { + v6 += 32; + v2 += 32; + } + v146 = (_BYTE *)(v2 - 800); + if ( (unsigned int)v146 < screen_buf_end ) + { + v147 = 8; + do + { + v148 = *(_DWORD *)v6; + v6 += 4; + *v146 = v148; + v149 = v146 + 2; + *v149 = __ROR4__(v148, 16); + v146 = v149 + 2; + --v147; + } + while ( v147 ); + } + else + { + v6 += 32; + v146 += 32; + } + v2 = (unsigned int)(v146 - 800); + --v142; + } + while ( v142 ); + return; + case 9: + world_4B325C = (unsigned char)a1 & 1; + v150 = 32; + while ( 1 ) + { + v323 = v150; + v151 = 32; + do + { + while ( 1 ) + { + v152 = (unsigned char)*v6++; + if ( (v152 & 0x80u) != 0 ) + break; + v151 -= v152; + if ( v2 < screen_buf_end ) + { + if ( (v2 & 1) == world_4B325C ) + { + v153 = v152 >> 1; + if ( !(v152 & 1) ) + goto LABEL_280; + ++v6; + ++v2; + if ( v153 ) + { +LABEL_287: + v22 = v153 & 1; + v161 = v153 >> 1; + if ( !v22 || (v162 = *v6, v6 += 2, *(_BYTE *)v2 = v162, v2 += 2, v161) ) + { + do + { + v163 = *(_DWORD *)v6; + v6 += 4; + *(_BYTE *)v2 = v163; + v164 = (_BYTE *)(v2 + 2); + *v164 = __ROR4__(v163, 16); + v2 = (unsigned int)(v164 + 2); + --v161; + } + while ( v161 ); + } + goto LABEL_290; + } + } + else + { + v153 = v152 >> 1; + if ( !(v152 & 1) ) + goto LABEL_287; + v160 = *v6++; + *(_BYTE *)v2++ = v160; + if ( v153 ) + { +LABEL_280: + v22 = v153 & 1; + v154 = v153 >> 1; + if ( !v22 + || (v155 = v6 + 1, + v156 = (_BYTE *)(v2 + 1), + v157 = *v155, + v6 = v155 + 1, + *v156 = v157, + v2 = (unsigned int)(v156 + 1), + v154) ) + { + do + { + v158 = *(_DWORD *)v6; + v6 += 4; + v159 = (_BYTE *)(v2 + 1); + v158 = __ROR4__(v158, 8); + *v159 = v158; + v159 += 2; + *v159 = __ROR4__(v158, 16); + v2 = (unsigned int)(v159 + 1); + --v154; + } + while ( v154 ); + } + goto LABEL_290; + } + } + } + else + { + v6 += v152; + v2 += v152; + } +LABEL_290: + if ( !v151 ) + goto LABEL_293; + } + _LOBYTE(v152) = -(char)v152; + v2 += v152; + v151 -= v152; + } + while ( v151 ); +LABEL_293: + world_4B325C = ((_BYTE)world_4B325C + 1) & 1; + v2 -= 800; + v150 = v323 - 1; + if ( v323 == 1 ) + return; + } + case 10: + world_4B325C = 0; + v165 = 30; + if ( (unsigned int)a1 >= screen_buf_end ) + { + v166 = (unsigned int)((char *)a1 - screen_buf_end + 1023) >> 8; + if ( v166 > 45 ) + { + v2 = (unsigned int)a1 - 12288; + v6 += 288; +LABEL_308: + v180 = 2; + if ( v2 >= screen_buf_end ) + { + v181 = (v2 - screen_buf_end + 1023) >> 8; + if ( v181 > 42 ) + return; + v182 = world_4B33FD[v181]; + v6 += *(int *)((char *)world_4B3501 + v182); + v183 = 192 * v182; + v182 >>= 1; + v2 -= v183; + v180 = v182 + 2; + world_4B325C += v182 >> 1; + } + do + { + v184 = (_BYTE *)(v180 + v2); + v185 = 32 - v180; + v186 = ((_BYTE)world_4B325C + 1) & 1; + world_4B325C = ((_BYTE)world_4B325C + 1) & 1; + if ( world_4B325C ) + { + v22 = __CFSHR__(v185, 2); + v187 = v185 >> 2; + if ( !v22 + || (_LOWORD(v186) = *((_WORD *)v6 + 1), + v6 += 4, + v188 = v184 + 1, + *v188 = __ROR4__(v186, 8), + v184 = v188 + 1, + v187) ) + { + do + { + v189 = *(_DWORD *)v6; + v6 += 4; + v190 = v184 + 1; + v189 = __ROR4__(v189, 8); + *v190 = v189; + v190 += 2; + *v190 = __ROR4__(v189, 16); + v184 = v190 + 1; + --v187; + } + while ( v187 ); + } + } + else + { + v22 = __CFSHR__(v185, 2); + v191 = v185 >> 2; + if ( !v22 || (v192 = *((_WORD *)v6 + 1), v6 += 4, *v184 = v192, v184 += 2, --v191, v191) ) + { + do + { + v193 = *(_DWORD *)v6; + v6 += 4; + *v184 = v193; + v194 = v184 + 2; + *v194 = __ROR4__(v193, 16); + v184 = v194 + 2; + --v191; + } + while ( v191 ); + } + } + v2 = (unsigned int)(v184 - 800); + v180 += 2; + } + while ( v180 != 32 ); + return; + } + v167 = world_4B33FD[v166]; + v6 += *(int *)((char *)world_4B34BD + v167); + v168 = 192 * v167; + v167 >>= 1; + v2 -= v168; + v165 = 30 - v167; + world_4B325C += v167 >> 1; + } + do + { + v169 = (_BYTE *)(v165 + v2); + v170 = 32 - v165; + v171 = ((_BYTE)world_4B325C + 1) & 1; + world_4B325C = ((_BYTE)world_4B325C + 1) & 1; + if ( world_4B325C ) + { + v22 = __CFSHR__(v170, 2); + v172 = v170 >> 2; + if ( !v22 + || (_LOWORD(v171) = *((_WORD *)v6 + 1), + v6 += 4, + v173 = v169 + 1, + *v173 = __ROR4__(v171, 8), + v169 = v173 + 1, + v172) ) + { + do + { + v174 = *(_DWORD *)v6; + v6 += 4; + v175 = v169 + 1; + v174 = __ROR4__(v174, 8); + *v175 = v174; + v175 += 2; + *v175 = __ROR4__(v174, 16); + v169 = v175 + 1; + --v172; + } + while ( v172 ); + } + } + else + { + v22 = __CFSHR__(v170, 2); + v176 = v170 >> 2; + if ( !v22 || (v177 = *((_WORD *)v6 + 1), v6 += 4, *v169 = v177, v169 += 2, v176) ) + { + do + { + v178 = *(_DWORD *)v6; + v6 += 4; + *v169 = v178; + v179 = v169 + 2; + *v179 = __ROR4__(v178, 16); + v169 = v179 + 2; + --v176; + } + while ( v176 ); + } + } + v2 = (unsigned int)(v169 - 800); + v50 = __OFSUB__(v165, 2); + v165 -= 2; + } + while ( !((v165 < 0) ^ v50) ); + goto LABEL_308; + } + if ( v7 != 11 ) + { + if ( v7 != 12 ) + { + world_4B325C = 0; + v246 = 30; + if ( (unsigned int)a1 >= screen_buf_end ) + { + v247 = (unsigned int)((char *)a1 - screen_buf_end + 1023) >> 8; + if ( v247 > 45 ) + { + v2 = (unsigned int)a1 - 12288; + v6 += 288; +LABEL_389: + v260 = 8; + do + { + if ( v2 < screen_buf_end ) + { + v261 = 8; + do + { + v262 = *(_DWORD *)v6; + v6 += 4; + v263 = (_BYTE *)(v2 + 1); + v262 = __ROR4__(v262, 8); + *v263 = v262; + v263 += 2; + *v263 = __ROR4__(v262, 16); + v2 = (unsigned int)(v263 + 1); + --v261; + } + while ( v261 ); + } + else + { + v6 += 32; + v2 += 32; + } + v264 = (_BYTE *)(v2 - 800); + if ( (unsigned int)v264 < screen_buf_end ) + { + v265 = 8; + do + { + v266 = *(_DWORD *)v6; + v6 += 4; + *v264 = v266; + v267 = v264 + 2; + *v267 = __ROR4__(v266, 16); + v264 = v267 + 2; + --v265; + } + while ( v265 ); + } + else + { + v6 += 32; + v264 += 32; + } + v2 = (unsigned int)(v264 - 800); + --v260; + } + while ( v260 ); + return; + } + v248 = world_4B33FD[v247]; + v6 += *(int *)((char *)world_4B34BD + v248); + v249 = 192 * v248; + v248 >>= 1; + v2 -= v249; + v246 = 30 - v248; + world_4B325C += v248 >> 1; + } + do + { + v250 = 32 - v246; + v251 = ((_BYTE)world_4B325C + 1) & 1; + world_4B325C = ((_BYTE)world_4B325C + 1) & 1; + if ( world_4B325C ) + { + for ( m = v250 >> 2; m; --m ) + { + v253 = *(_DWORD *)v6; + v6 += 4; + v254 = (_BYTE *)(v2 + 1); + v253 = __ROR4__(v253, 8); + *v254 = v253; + v254 += 2; + v251 = __ROR4__(v253, 16); + *v254 = v251; + v2 = (unsigned int)(v254 + 1); + } + if ( (32 - (_BYTE)v246) & 2 ) + { + _LOWORD(v251) = *(_WORD *)v6; + v6 += 4; + v255 = (_BYTE *)(v2 + 1); + *v255 = __ROR4__(v251, 8); + v2 = (unsigned int)(v255 + 1); + } + } + else + { + for ( n = v250 >> 2; n; --n ) + { + v257 = *(_DWORD *)v6; + v6 += 4; + *(_BYTE *)v2 = v257; + v258 = (_BYTE *)(v2 + 2); + *v258 = __ROR4__(v257, 16); + v2 = (unsigned int)(v258 + 2); + } + if ( (32 - (_BYTE)v246) & 2 ) + { + v259 = *(_WORD *)v6; + v6 += 4; + *(_BYTE *)v2 = v259; + v2 += 2; + } + } + v2 = v246 + v2 - 800; + v50 = __OFSUB__(v246, 2); + v246 -= 2; + } + while ( !((v246 < 0) ^ v50) ); + goto LABEL_389; + } + world_4B325C = 0; + v223 = 30; + if ( (unsigned int)a1 >= screen_buf_end ) + { + v224 = (unsigned int)((char *)a1 - screen_buf_end + 1023) >> 8; + if ( v224 > 45 ) + { + v2 = (unsigned int)a1 - 12288; + v6 += 288; +LABEL_364: + v238 = 8; + do + { + if ( v2 < screen_buf_end ) + { + v239 = 8; + do + { + v240 = *(_DWORD *)v6; + v6 += 4; + v241 = (_BYTE *)(v2 + 1); + v240 = __ROR4__(v240, 8); + *v241 = v240; + v241 += 2; + *v241 = __ROR4__(v240, 16); + v2 = (unsigned int)(v241 + 1); + --v239; + } + while ( v239 ); + } + else + { + v6 += 32; + v2 += 32; + } + v242 = (_BYTE *)(v2 - 800); + if ( (unsigned int)v242 < screen_buf_end ) + { + v243 = 8; + do + { + v244 = *(_DWORD *)v6; + v6 += 4; + *v242 = v244; + v245 = v242 + 2; + *v245 = __ROR4__(v244, 16); + v242 = v245 + 2; + --v243; + } + while ( v243 ); + } + else + { + v6 += 32; + v242 += 32; + } + v2 = (unsigned int)(v242 - 800); + --v238; + } + while ( v238 ); + return; + } + v225 = world_4B33FD[v224]; + v6 += *(int *)((char *)world_4B34BD + v225); + v226 = 192 * v225; + v225 >>= 1; + v2 -= v226; + v223 = 30 - v225; + world_4B325C += v225 >> 1; + } + do + { + v227 = (_BYTE *)(v223 + v2); + v228 = 32 - v223; + v229 = ((_BYTE)world_4B325C + 1) & 1; + world_4B325C = ((_BYTE)world_4B325C + 1) & 1; + if ( world_4B325C ) + { + v22 = __CFSHR__(v228, 2); + v230 = v228 >> 2; + if ( !v22 + || (_LOWORD(v229) = *((_WORD *)v6 + 1), + v6 += 4, + v231 = v227 + 1, + *v231 = __ROR4__(v229, 8), + v227 = v231 + 1, + v230) ) + { + do + { + v232 = *(_DWORD *)v6; + v6 += 4; + v233 = v227 + 1; + v232 = __ROR4__(v232, 8); + *v233 = v232; + v233 += 2; + *v233 = __ROR4__(v232, 16); + v227 = v233 + 1; + --v230; + } + while ( v230 ); + } + } + else + { + v22 = __CFSHR__(v228, 2); + v234 = v228 >> 2; + if ( !v22 || (v235 = *((_WORD *)v6 + 1), v6 += 4, *v227 = v235, v227 += 2, v234) ) + { + do + { + v236 = *(_DWORD *)v6; + v6 += 4; + *v227 = v236; + v237 = v227 + 2; + *v237 = __ROR4__(v236, 16); + --v234; + v227 = v237 + 2; + } + while ( v234 ); + } + } + v2 = (unsigned int)(v227 - 800); + v50 = __OFSUB__(v223, 2); + v223 -= 2; + } + while ( !((v223 < 0) ^ v50) ); + goto LABEL_364; + } + world_4B325C = 0; + v195 = 30; + if ( (unsigned int)a1 < screen_buf_end ) + goto LABEL_326; + v196 = (unsigned int)((char *)a1 - screen_buf_end + 1023) >> 8; + if ( v196 <= 45 ) + { + v197 = world_4B33FD[v196]; + v6 += *(int *)((char *)world_4B34BD + v197); + v198 = 192 * v197; + v197 >>= 1; + v2 -= v198; + v195 = 30 - v197; + world_4B325C += v197 >> 1; + do + { +LABEL_326: + v199 = 32 - v195; + v200 = ((_BYTE)world_4B325C + 1) & 1; + world_4B325C = ((_BYTE)world_4B325C + 1) & 1; + if ( world_4B325C ) + { + for ( ii = v199 >> 2; ii; --ii ) + { + v202 = *(_DWORD *)v6; + v6 += 4; + v203 = (_BYTE *)(v2 + 1); + v202 = __ROR4__(v202, 8); + *v203 = v202; + v203 += 2; + v200 = __ROR4__(v202, 16); + *v203 = v200; + v2 = (unsigned int)(v203 + 1); + } + if ( (32 - (_BYTE)v195) & 2 ) + { + _LOWORD(v200) = *(_WORD *)v6; + v6 += 4; + v204 = (_BYTE *)(v2 + 1); + *v204 = __ROR4__(v200, 8); + v2 = (unsigned int)(v204 + 1); + } + } + else + { + for ( jj = v199 >> 2; jj; --jj ) + { + v206 = *(_DWORD *)v6; + v6 += 4; + *(_BYTE *)v2 = v206; + v207 = (_BYTE *)(v2 + 2); + *v207 = __ROR4__(v206, 16); + v2 = (unsigned int)(v207 + 2); + } + if ( (32 - (_BYTE)v195) & 2 ) + { + v208 = *(_WORD *)v6; + v6 += 4; + *(_BYTE *)v2 = v208; + v2 += 2; + } + } + v2 = v195 + v2 - 800; + v50 = __OFSUB__(v195, 2); + v195 -= 2; + } + while ( !((v195 < 0) ^ v50) ); + goto LABEL_336; + } + v2 = (unsigned int)a1 - 12288; + v6 += 288; +LABEL_336: + v209 = 2; + if ( v2 >= screen_buf_end ) + { + v210 = (v2 - screen_buf_end + 1023) >> 8; + if ( v210 > 42 ) + return; + v211 = world_4B33FD[v210]; + v6 += *(int *)((char *)world_4B3501 + v211); + v212 = 192 * v211; + v211 >>= 1; + v2 -= v212; + v209 = v211 + 2; + world_4B325C += v211 >> 1; + } + do + { + v213 = 32 - v209; + v214 = ((_BYTE)world_4B325C + 1) & 1; + world_4B325C = ((_BYTE)world_4B325C + 1) & 1; + if ( world_4B325C ) + { + for ( kk = v213 >> 2; kk; --kk ) + { + v216 = *(_DWORD *)v6; + v6 += 4; + v217 = (_BYTE *)(v2 + 1); + v216 = __ROR4__(v216, 8); + *v217 = v216; + v217 += 2; + v214 = __ROR4__(v216, 16); + *v217 = v214; + v2 = (unsigned int)(v217 + 1); + } + if ( (32 - (_BYTE)v209) & 2 ) + { + _LOWORD(v214) = *(_WORD *)v6; + v6 += 4; + v218 = (_BYTE *)(v2 + 1); + *v218 = __ROR4__(v214, 8); + v2 = (unsigned int)(v218 + 1); + } + } + else + { + for ( ll = v213 >> 2; ll; --ll ) + { + v220 = *(_DWORD *)v6; + v6 += 4; + *(_BYTE *)v2 = v220; + v221 = (_BYTE *)(v2 + 2); + *v221 = __ROR4__(v220, 16); + v2 = (unsigned int)(v221 + 2); + } + if ( (32 - (_BYTE)v209) & 2 ) + { + v222 = *(_WORD *)v6; + v6 += 4; + *(_BYTE *)v2 = v222; + v2 += 2; + } + } + v2 = v209 + v2 - 800; + v209 += 2; + } + while ( v209 != 32 ); +} +// 642A14: using guessed type char lightmax; +// 69BEF8: using guessed type int light_table_index; +// 69CF0C: using guessed type int screen_buf_end; +// 69CF14: using guessed type int level_cel_block; + +//----- (00467949) -------------------------------------------------------- +void __fastcall drawBottomArchesLowerScreen(void *a1, int a2) +{ + _BYTE *v2; // edi + char *v3; // esi + short v5; // ax + char *v6; // esi + short v7; // ax + unsigned int v8; // eax + char *v9; // esi + unsigned int v10; // eax + int v11; // eax + signed int v12; // ebp + int v13; // edx + signed int v14; // ecx + unsigned char v16; // cf + int v18; // ecx + signed int v19; // edx + int v20; // eax + int v21; // ecx + int v22; // edx + int v25; // edx + signed int v26; // eax + unsigned int v27; // ecx + _WORD *v28; // edi + unsigned int v29; // ecx + unsigned char v32; // of + int v33; // edx + signed int v34; // eax + unsigned int v35; // ecx + _WORD *v36; // edi + unsigned int v37; // ecx + int v40; // edx + signed int v41; // eax + unsigned int v42; // ecx + unsigned int ii; // ecx + int v46; // edx + signed int v47; // eax + unsigned int v48; // ecx + unsigned int n; // ecx + int v52; // edx + signed int v53; // eax + unsigned int v54; // ecx + _WORD *v55; // edi + unsigned int v56; // ecx + signed int v59; // edx + int v60; // edx + signed int v61; // ecx + int v64; // edx + signed int v65; // eax + unsigned int v66; // ecx + unsigned int m; // ecx + signed int v70; // edx + int v71; // edx + signed int v72; // ecx + signed int v75; // edx + int v76; // edx + signed int v77; // ecx + char v78; // al + int v79; // ecx + signed int v80; // edx + int v81; // eax + int v82; // ecx + int v83; // edx + char v84; // al + int v85; // edx + signed int v86; // eax + unsigned int v87; // ecx + _DWORD *v88; // edi + unsigned int v89; // ecx + short v90; // ax + int v91; // eax + int v92; // edx + signed int v93; // eax + unsigned int v94; // ecx + _DWORD *v95; // edi + unsigned int v96; // ecx + short v97; // ax + int v98; // eax + int v99; // edx + signed int v100; // eax + unsigned int v101; // ecx + unsigned int kk; // ecx + int v103; // eax + short v104; // ax + int v105; // edx + signed int v106; // eax + unsigned int v107; // ecx + unsigned int ll; // ecx + int v109; // eax + short v110; // ax + int v111; // edx + signed int v112; // eax + unsigned int v113; // ecx + _DWORD *v114; // edi + unsigned int v115; // ecx + short v116; // ax + int v117; // eax + signed int v118; // edx + int v119; // edx + signed int v120; // ecx + char v121; // al + int v122; // edx + signed int v123; // eax + unsigned int v124; // ecx + unsigned int jj; // ecx + int v126; // eax + short v127; // ax + signed int v128; // edx + int v129; // edx + signed int v130; // ecx + char v131; // al + signed int v132; // edx + int v133; // edx + signed int v134; // ecx + int v135; // ecx + signed int v136; // edx + int v137; // eax + int v138; // ecx + int v139; // edx + signed int i; // edx + _DWORD *v141; // edi + unsigned int v142; // ecx + signed int v143; // edx + _DWORD *v144; // edi + unsigned int v145; // ecx + signed int j; // edx + unsigned int v147; // ecx + _DWORD *v148; // edi + signed int v149; // edx + unsigned int v150; // ecx + signed int k; // edx + _DWORD *v152; // edi + unsigned int v153; // ecx + signed int v154; // edx + int v155; // edx + signed int v156; // ecx + signed int l; // edx + unsigned int v158; // ecx + _BYTE *v159; // edi + signed int v160; // edx + int v161; // edx + signed int v162; // ecx + signed int v163; // [esp-8h] [ebp-14h] + signed int v164; // [esp-8h] [ebp-14h] + signed int v165; // [esp-8h] [ebp-14h] + signed int v166; // [esp-8h] [ebp-14h] + signed int v167; // [esp-8h] [ebp-14h] + int v168; // [esp-4h] [ebp-10h] + signed int v169; // [esp-4h] [ebp-10h] + signed int v170; // [esp-4h] [ebp-10h] + int v171; // [esp-4h] [ebp-10h] + signed int v172; // [esp-4h] [ebp-10h] + signed int v173; // [esp-4h] [ebp-10h] + int v174; // [esp-4h] [ebp-10h] + signed int v175; // [esp-4h] [ebp-10h] + signed int v176; // [esp-4h] [ebp-10h] + + world_4B3265 = (int)speed_cel_frame_num_from_light_index_frame_num; + v2 = (unsigned char *)a1; + world_4B3269[0] = a2; + if ( (_BYTE)light_table_index ) + { + if ( (_BYTE)light_table_index == lightmax ) + { + if ( level_cel_block & 0x8000 ) + level_cel_block = *(_DWORD *)(((level_cel_block & 0xFFF) << 6) + world_4B3265) + + (unsigned short)(level_cel_block & 0xF000); + v9 = (char *)pDungeonCels + *((_DWORD *)pDungeonCels + (level_cel_block & 0xFFF)); + v10 = level_cel_block; + _LOBYTE(v10) = BYTE1(v10); + v11 = (v10 >> 4) & 7; + if ( v11 ) + { + switch ( (_WORD)v11 ) + { + case 1: + v135 = 32; + do + { + v174 = v135; + *(_DWORD *)world_4B3260 = *(_DWORD *)world_4B3269[0]; + v136 = 32; + do + { + while ( 1 ) + { + v137 = (unsigned char)*v9++; + if ( (v137 & 0x80u) != 0 ) + break; + v136 -= v137; + if ( (unsigned int)v2 < screen_buf_end ) + { + v138 = v137; + v9 += v137; + v167 = v136; + v139 = *(_DWORD *)world_4B3260; + do + { + v16 = __CFSHL__(v139, 1); + v139 *= 2; + if ( v16 ) + *v2 = 0; + ++v2; + --v138; + } + while ( v138 ); + *(_DWORD *)world_4B3260 = v139; + v136 = v167; + } + else + { + v9 += v137; + v2 += v137; + } + if ( !v136 ) + goto LABEL_252; + } + _LOBYTE(v137) = -(char)v137; + v2 += v137; + if ( v137 & 0x1F ) + *(_DWORD *)world_4B3260 <<= v137 & 0x1F; + v136 -= v137; + } + while ( v136 ); +LABEL_252: + v2 -= 800; + world_4B3269[0] -= 4; + v135 = v174 - 1; + } + while ( v174 != 1 ); + break; + case 2: + for ( i = 30; ; i -= 2 ) + { + if ( (unsigned int)v2 < screen_buf_end ) + { + v141 = (unsigned int *)&v2[i]; + v142 = (unsigned int)(32 - i) >> 2; + if ( !__CFSHR__(32 - i, 2) + || (*(_WORD *)v141 = 0, v141 = (_DWORD *)((char *)v141 + 2), v142) ) + { + do + { + *v141 = 0; + ++v141; + --v142; + } + while ( v142 ); + } + } + else + { + v9 = &v9[-i + 32]; + v141 = (unsigned int *)v2 + 32; + } + v2 = (unsigned char *)v141 - 200; + if ( !i ) + break; + } + v143 = 2; + do + { + if ( (unsigned int)v2 < screen_buf_end ) + { + v144 = (unsigned int *)&v2[v143]; + v145 = (unsigned int)(32 - v143) >> 2; + if ( !__CFSHR__(32 - v143, 2) + || (*(_WORD *)v144 = 0, v144 = (_DWORD *)((char *)v144 + 2), v145) ) + { + do + { + *v144 = 0; + ++v144; + --v145; + } + while ( v145 ); + } + } + else + { + v9 = &v9[-v143 + 32]; + v144 = (unsigned int *)v2 + 32; + } + v2 = (unsigned char *)v144 - 200; + v143 += 2; + } + while ( v143 != 32 ); + break; + case 3: + for ( j = 30; ; j -= 2 ) + { + if ( (unsigned int)v2 < screen_buf_end ) + { + v147 = (unsigned int)(32 - j) >> 2; + if ( !__CFSHR__(32 - j, 2) || (*(_WORD *)v2 = 0, v2 += 2, v147) ) + { + do + { + *(_DWORD *)v2 = 0; + v2 += 4; + --v147; + } + while ( v147 ); + } + } + else + { + v9 = &v9[-j + 32]; + v2 = &v2[-j + 32]; + } + v148 = (unsigned int *)v2 - 800; + if ( !j ) + break; + v2 = (unsigned char *)v148 + j; + } + v149 = 2; + do + { + if ( (unsigned int)v148 < screen_buf_end ) + { + v150 = (unsigned int)(32 - v149) >> 2; + if ( !__CFSHR__(32 - v149, 2) + || (*(_WORD *)v148 = 0, v148 = (_DWORD *)((char *)v148 + 2), v150) ) + { + do + { + *v148 = 0; + ++v148; + --v150; + } + while ( v150 ); + } + } + else + { + v9 = &v9[-v149 + 32]; + v148 = (_DWORD *)((char *)v148 - v149 + 32); + } + v148 = (_DWORD *)((char *)v148 + v149 - 800); + v149 += 2; + } + while ( v149 != 32 ); + break; + case 4: + for ( k = 30; ; k -= 2 ) + { + if ( (unsigned int)v2 < screen_buf_end ) + { + v152 = (unsigned int *)&v2[k]; + v153 = (unsigned int)(32 - k) >> 2; + if ( !__CFSHR__(32 - k, 2) + || (*(_WORD *)v152 = 0, v152 = (_DWORD *)((char *)v152 + 2), v153) ) + { + do + { + *v152 = 0; + ++v152; + --v153; + } + while ( v153 ); + } + } + else + { + v9 = &v9[-k + 32]; + v152 = (unsigned int *)v2 + 32; + } + v2 = (unsigned char *)v152 - 200; + if ( !k ) + break; + } + world_4B3269[0] -= 64; + v154 = 16; + do + { + if ( (unsigned int)v2 < screen_buf_end ) + { + v175 = v154; + v155 = *(_DWORD *)world_4B3269[0]; + v156 = 32; + do + { + v16 = __CFSHL__(v155, 1); + v155 *= 2; + if ( v16 ) + *v2 = 0; + ++v2; + --v156; + } + while ( v156 ); + v154 = v175; + } + else + { + v9 += 32; + v2 += 32; + } + v2 -= 800; + world_4B3269[0] -= 4; + --v154; + } + while ( v154 ); + break; + default: + for ( l = 30; ; l -= 2 ) + { + if ( (unsigned int)v2 < screen_buf_end ) + { + v158 = (unsigned int)(32 - l) >> 2; + if ( !__CFSHR__(32 - l, 2) || (*(_WORD *)v2 = 0, v2 += 2, v158) ) + { + do + { + *(_DWORD *)v2 = 0; + v2 += 4; + --v158; + } + while ( v158 ); + } + } + else + { + v9 = &v9[-l + 32]; + v2 = &v2[-l + 32]; + } + v159 = v2 - 800; + if ( !l ) + break; + v2 = &v159[l]; + } + world_4B3269[0] -= 64; + v160 = 16; + do + { + if ( (unsigned int)v159 < screen_buf_end ) + { + v176 = v160; + v161 = *(_DWORD *)world_4B3269[0]; + v162 = 32; + do + { + v16 = __CFSHL__(v161, 1); + v161 *= 2; + if ( v16 ) + *v159 = 0; + ++v159; + --v162; + } + while ( v162 ); + v160 = v176; + } + else + { + v9 += 32; + v159 += 32; + } + v159 -= 800; + world_4B3269[0] -= 4; + --v160; + } + while ( v160 ); + break; + } + } + else + { + v132 = 32; + do + { + if ( (unsigned int)v2 < screen_buf_end ) + { + v173 = v132; + v133 = *(_DWORD *)world_4B3269[0]; + v134 = 32; + do + { + v16 = __CFSHL__(v133, 1); + v133 *= 2; + if ( v16 ) + *v2 = 0; + ++v2; + --v134; + } + while ( v134 ); + v132 = v173; + } + else + { + v9 += 32; + v2 += 32; + } + v2 -= 800; + world_4B3269[0] -= 4; + --v132; + } + while ( v132 ); + } + return; + } + if ( !(level_cel_block & 0x8000) ) + { + v3 = (char *)pDungeonCels + *((_DWORD *)pDungeonCels + (level_cel_block & 0xFFF)); +/* _EBX = dword_646A20 + (light_table_index << 8); + v5 = (unsigned char)(BYTE1(level_cel_block) >> 4); + if ( !(BYTE1(level_cel_block) >> 4) ) + { + v12 = 32; + do + { + if ( (unsigned int)v2 < screen_buf_end ) + { + v13 = *(_DWORD *)world_4B3269[0]; + v14 = 32; + do + { + _AL = *v3++; + v16 = __CFSHL__(v13, 1); + v13 *= 2; + if ( v16 ) + { + __asm { xlat } + *v2 = _AL; + } + ++v2; + --v14; + } + while ( v14 ); + } + else + { + v3 += 32; + v2 += 32; + } + v2 -= 800; + world_4B3269[0] -= 4; + --v12; + } + while ( v12 ); + return; + } + if ( v5 == 1 ) + { + v18 = 32; + do + { + v168 = v18; + *(_DWORD *)world_4B3260 = *(_DWORD *)world_4B3269[0]; + v19 = 32; + do + { + while ( 1 ) + { + v20 = (unsigned char)*v3++; + if ( (v20 & 0x80u) != 0 ) + break; + v19 -= v20; + if ( (unsigned int)v2 < screen_buf_end ) + { + v21 = v20; + v163 = v19; + v22 = *(_DWORD *)world_4B3260; + do + { + _AL = *v3++; + v16 = __CFSHL__(v22, 1); + v22 *= 2; + if ( v16 ) + { + __asm { xlat } + *v2 = _AL; + } + ++v2; + --v21; + } + while ( v21 ); + *(_DWORD *)world_4B3260 = v22; + v19 = v163; + } + else + { + v3 += v20; + v2 += v20; + } + if ( !v19 ) + goto LABEL_52; + } + _LOBYTE(v20) = -(char)v20; + v2 += v20; + if ( v20 & 0x1F ) + *(_DWORD *)world_4B3260 <<= v20 & 0x1F; + v19 -= v20; + } + while ( v19 ); +LABEL_52: + v2 -= 800; + world_4B3269[0] -= 4; + v18 = v168 - 1; + } + while ( v168 != 1 ); + return; + } + if ( v5 != 2 ) + { + if ( v5 != 3 ) + { + if ( v5 != 4 ) + { + v64 = 30; + if ( (unsigned int)a1 >= screen_buf_end ) + { + v65 = (unsigned int)((char *)a1 - screen_buf_end + 1023) >> 8; + if ( v65 > 45 ) + { + v2 = (char *)a1 - 12288; + v3 += 288; +LABEL_117: + world_4B3269[0] -= 64; + v70 = 16; + do + { + if ( (unsigned int)v2 < screen_buf_end ) + { + v164 = v70; + v71 = *(_DWORD *)world_4B3269[0]; + v72 = 32; + do + { + _AL = *v3++; + v16 = __CFSHL__(v71, 1); + v71 *= 2; + if ( v16 ) + { + __asm { xlat } + *v2 = _AL; + } + ++v2; + --v72; + } + while ( v72 ); + v3 += (unsigned char)v3 & 2; + v70 = v164; + } + else + { + v3 += 32; + v2 += 32; + } + v2 -= 800; + world_4B3269[0] -= 4; + --v70; + } + while ( v70 ); + return; + } + v66 = world_4B33FD[v65]; + v3 += *(int *)((char *)world_4B34BD + v66); + v2 -= 192 * v66; + v64 = 30 - (v66 >> 1); + } + do + { + for ( m = (unsigned int)(32 - v64) >> 2; m; --m ) + { + _EAX = *(_DWORD *)v3; + v3 += 4; + __asm { xlat } + _EAX = __ROR4__(_EAX, 8); + __asm { xlat } + _EAX = __ROR4__(_EAX, 8); + __asm { xlat } + _EAX = __ROR4__(_EAX, 8); + __asm { xlat } + *(_DWORD *)v2 = __ROR4__(_EAX, 8); + v2 += 4; + } + if ( (32 - (_BYTE)v64) & 2 ) + { + _AX = *(_WORD *)v3; + v3 += 4; + __asm { xlat } + _AX = __ROR2__(_AX, 8); + __asm { xlat } + *(_WORD *)v2 = __ROR2__(_AX, 8); + v2 += 2; + } + v2 = &v2[v64 - 800]; + v32 = __OFSUB__(v64, 2); + v64 -= 2; + } + while ( !((v64 < 0) ^ v32) ); + goto LABEL_117; + } + v52 = 30; + if ( (unsigned int)a1 >= screen_buf_end ) + { + v53 = (unsigned int)((char *)a1 - screen_buf_end + 1023) >> 8; + if ( v53 > 45 ) + { + v2 = (char *)a1 - 12288; + v3 += 288; +LABEL_98: + world_4B3269[0] -= 64; + v59 = 16; + do + { + if ( (unsigned int)v2 < screen_buf_end ) + { + v169 = v59; + v60 = *(_DWORD *)world_4B3269[0]; + v61 = 32; + do + { + _AL = *v3++; + v16 = __CFSHL__(v60, 1); + v60 *= 2; + if ( v16 ) + { + __asm { xlat } + *v2 = _AL; + } + ++v2; + --v61; + } + while ( v61 ); + v59 = v169; + } + else + { + v3 += 32; + v2 += 32; + } + v2 -= 800; + world_4B3269[0] -= 4; + --v59; + } + while ( v59 ); + return; + } + v54 = world_4B33FD[v53]; + v3 += *(int *)((char *)world_4B34BD + v54); + v2 -= 192 * v54; + v52 = 30 - (v54 >> 1); + } + do + { + v55 = &v2[v52]; + v56 = (unsigned int)(32 - v52) >> 2; + if ( !__CFSHR__(32 - v52, 2) ) + goto LABEL_322; + _AX = *((_WORD *)v3 + 1); + v3 += 4; + __asm { xlat } + _AX = __ROR2__(_AX, 8); + __asm { xlat } + *v55 = __ROR2__(_AX, 8); + ++v55; + if ( v56 ) + { +LABEL_322: + do + { + _EAX = *(_DWORD *)v3; + v3 += 4; + __asm { xlat } + _EAX = __ROR4__(_EAX, 8); + __asm { xlat } + _EAX = __ROR4__(_EAX, 8); + __asm { xlat } + _EAX = __ROR4__(_EAX, 8); + __asm { xlat } + *(_DWORD *)v55 = __ROR4__(_EAX, 8); + v55 += 2; + --v56; + } + while ( v56 ); + } + v2 = v55 - 400; + v32 = __OFSUB__(v52, 2); + v52 -= 2; + } + while ( !((v52 < 0) ^ v32) ); + goto LABEL_98; + } + v40 = 30; + if ( (unsigned int)a1 >= screen_buf_end ) + { + v41 = (unsigned int)((char *)a1 - screen_buf_end + 1023) >> 8; + if ( v41 > 45 ) + { + v2 = (char *)a1 - 12288; + v3 += 288; +LABEL_80: + v46 = 2; + if ( (unsigned int)v2 >= screen_buf_end ) + { + v47 = (unsigned int)&v2[-screen_buf_end + 1023] >> 8; + if ( v47 > 42 ) + return; + v48 = world_4B33FD[v47]; + v3 += *(int *)((char *)world_4B3501 + v48); + v2 -= 192 * v48; + v46 = (v48 >> 1) + 2; + } + do + { + for ( n = (unsigned int)(32 - v46) >> 2; n; --n ) + { + _EAX = *(_DWORD *)v3; + v3 += 4; + __asm { xlat } + _EAX = __ROR4__(_EAX, 8); + __asm { xlat } + _EAX = __ROR4__(_EAX, 8); + __asm { xlat } + _EAX = __ROR4__(_EAX, 8); + __asm { xlat } + *(_DWORD *)v2 = __ROR4__(_EAX, 8); + v2 += 4; + } + if ( (32 - (_BYTE)v46) & 2 ) + { + _AX = *(_WORD *)v3; + v3 += 2; + __asm { xlat } + _AX = __ROR2__(_AX, 8); + __asm { xlat } + *(_WORD *)v2 = __ROR2__(_AX, 8); + v2 += 2; + } + v2 = &v2[v46 - 800]; + v46 += 2; + } + while ( v46 != 32 ); + return; + } + v42 = world_4B33FD[v41]; + v3 += *(int *)((char *)world_4B34BD + v42); + v2 -= 192 * v42; + v40 = 30 - (v42 >> 1); + } + do + { + for ( ii = (unsigned int)(32 - v40) >> 2; ii; --ii ) + { + _EAX = *(_DWORD *)v3; + v3 += 4; + __asm { xlat } + _EAX = __ROR4__(_EAX, 8); + __asm { xlat } + _EAX = __ROR4__(_EAX, 8); + __asm { xlat } + _EAX = __ROR4__(_EAX, 8); + __asm { xlat } + *(_DWORD *)v2 = __ROR4__(_EAX, 8); + v2 += 4; + } + if ( (32 - (_BYTE)v40) & 2 ) + { + _AX = *(_WORD *)v3; + v3 += 4; + __asm { xlat } + _AX = __ROR2__(_AX, 8); + __asm { xlat } + *(_WORD *)v2 = __ROR2__(_AX, 8); + v2 += 2; + } + v2 = &v2[v40 - 800]; + v32 = __OFSUB__(v40, 2); + v40 -= 2; + } + while ( !((v40 < 0) ^ v32) ); + goto LABEL_80; + } + v25 = 30; + if ( (unsigned int)a1 >= screen_buf_end ) + { + v26 = (unsigned int)((char *)a1 - screen_buf_end + 1023) >> 8; + if ( v26 > 45 ) + { + v2 = (char *)a1 - 12288; + v3 += 288; +LABEL_62: + v33 = 2; + if ( (unsigned int)v2 >= screen_buf_end ) + { + v34 = (unsigned int)&v2[-screen_buf_end + 1023] >> 8; + if ( v34 > 42 ) + return; + v35 = world_4B33FD[v34]; + v3 += *(int *)((char *)world_4B3501 + v35); + v2 -= 192 * v35; + v33 = (v35 >> 1) + 2; + } + do + { + v36 = &v2[v33]; + v37 = (unsigned int)(32 - v33) >> 2; + if ( !__CFSHR__(32 - v33, 2) ) + goto LABEL_323; + _AX = *((_WORD *)v3 + 1); + v3 += 4; + __asm { xlat } + _AX = __ROR2__(_AX, 8); + __asm { xlat } + *v36 = __ROR2__(_AX, 8); + ++v36; + if ( v37 ) + { +LABEL_323: + do + { + _EAX = *(_DWORD *)v3; + v3 += 4; + __asm { xlat } + _EAX = __ROR4__(_EAX, 8); + __asm { xlat } + _EAX = __ROR4__(_EAX, 8); + __asm { xlat } + _EAX = __ROR4__(_EAX, 8); + __asm { xlat } + *(_DWORD *)v36 = __ROR4__(_EAX, 8); + v36 += 2; + --v37; + } + while ( v37 ); + } + v2 = v36 - 400; + v33 += 2; + } + while ( v33 != 32 ); + return; + } + v27 = world_4B33FD[v26]; + v3 += *(int *)((char *)world_4B34BD + v27); + v2 -= 192 * v27; + v25 = 30 - (v27 >> 1); + } + do + { + v28 = &v2[v25]; + v29 = (unsigned int)(32 - v25) >> 2; + if ( !__CFSHR__(32 - v25, 2) ) + goto LABEL_324; + _AX = *((_WORD *)v3 + 1); + v3 += 4; + __asm { xlat } + _AX = __ROR2__(_AX, 8); + __asm { xlat } + *v28 = __ROR2__(_AX, 8); + ++v28; + if ( v29 ) + { +LABEL_324: + do + { + _EAX = *(_DWORD *)v3; + v3 += 4; + __asm { xlat } + _EAX = __ROR4__(_EAX, 8); + __asm { xlat } + _EAX = __ROR4__(_EAX, 8); + __asm { xlat } + _EAX = __ROR4__(_EAX, 8); + __asm { xlat } + *(_DWORD *)v28 = __ROR4__(_EAX, 8); + v28 += 2; + --v29; + } + while ( v29 ); + } + v2 = v28 - 400; + v32 = __OFSUB__(v25, 2); + v25 -= 2; + } + while ( !((v25 < 0) ^ v32) ); + goto LABEL_62;*/ + } + v6 = (char *)pSpeedCels + *(_DWORD *)(4 * (light_table_index + 16 * (level_cel_block & 0xFFF)) + world_4B3265); + v7 = (unsigned char)(BYTE1(level_cel_block) >> 4); + } + else + { + if ( level_cel_block & 0x8000 ) + level_cel_block = *(_DWORD *)(((level_cel_block & 0xFFF) << 6) + world_4B3265) + + (unsigned short)(level_cel_block & 0xF000); + v6 = (char *)pDungeonCels + *((_DWORD *)pDungeonCels + (level_cel_block & 0xFFF)); + v8 = level_cel_block; + _LOBYTE(v8) = BYTE1(v8); + v7 = ((v8 >> 4) & 7) + 8; + } + switch ( v7 ) + { + case 8: + v75 = 32; + do + { + if ( (unsigned int)v2 < screen_buf_end ) + { + v170 = v75; + v76 = *(_DWORD *)world_4B3269[0]; + v77 = 32; + do + { + v78 = *v6++; + v16 = __CFSHL__(v76, 1); + v76 *= 2; + if ( v16 ) + *v2 = v78; + ++v2; + --v77; + } + while ( v77 ); + v75 = v170; + } + else + { + v6 += 32; + v2 += 32; + } + v2 -= 800; + world_4B3269[0] -= 4; + --v75; + } + while ( v75 ); + return; + case 9: + v79 = 32; + do + { + v171 = v79; + *(_DWORD *)world_4B3260 = *(_DWORD *)world_4B3269[0]; + v80 = 32; + do + { + while ( 1 ) + { + v81 = (unsigned char)*v6++; + if ( (v81 & 0x80u) != 0 ) + break; + v80 -= v81; + if ( (unsigned int)v2 < screen_buf_end ) + { + v82 = v81; + v165 = v80; + v83 = *(_DWORD *)world_4B3260; + do + { + v84 = *v6++; + v16 = __CFSHL__(v83, 1); + v83 *= 2; + if ( v16 ) + *v2 = v84; + ++v2; + --v82; + } + while ( v82 ); + *(_DWORD *)world_4B3260 = v83; + v80 = v165; + } + else + { + v6 += v81; + v2 += v81; + } + if ( !v80 ) + goto LABEL_152; + } + _LOBYTE(v81) = -(char)v81; + v2 += v81; + if ( v81 & 0x1F ) + *(_DWORD *)world_4B3260 <<= v81 & 0x1F; + v80 -= v81; + } + while ( v80 ); +LABEL_152: + v2 -= 800; + world_4B3269[0] -= 4; + v79 = v171 - 1; + } + while ( v171 != 1 ); + return; + case 10: + v85 = 30; + if ( (unsigned int)a1 >= screen_buf_end ) + { + v86 = (unsigned int)((char *)a1 - screen_buf_end + 1023) >> 8; + if ( v86 > 45 ) + { + v2 = (unsigned char *)a1 - 12288; + v6 += 288; +LABEL_162: + v92 = 2; + if ( (unsigned int)v2 >= screen_buf_end ) + { + v93 = (unsigned int)&v2[-screen_buf_end + 1023] >> 8; + if ( v93 > 42 ) + return; + v94 = world_4B33FD[v93]; + v6 += *(int *)((char *)world_4B3501 + v94); + v2 -= 192 * v94; + v92 = (v94 >> 1) + 2; + } + do + { + v95 = (unsigned int *)&v2[v92]; + v96 = (unsigned int)(32 - v92) >> 2; + if ( !__CFSHR__(32 - v92, 2) + || (v97 = *((_WORD *)v6 + 1), + v6 += 4, + *(_WORD *)v95 = v97, + v95 = (_DWORD *)((char *)v95 + 2), + v96) ) + { + do + { + v98 = *(_DWORD *)v6; + v6 += 4; + *v95 = v98; + ++v95; + --v96; + } + while ( v96 ); + } + v2 = (unsigned char *)v95 - 200; + v92 += 2; + } + while ( v92 != 32 ); + return; + } + v87 = world_4B33FD[v86]; + v6 += *(int *)((char *)world_4B34BD + v87); + v2 -= 192 * v87; + v85 = 30 - (v87 >> 1); + } + do + { + v88 = (unsigned int *)&v2[v85]; + v89 = (unsigned int)(32 - v85) >> 2; + if ( !__CFSHR__(32 - v85, 2) + || (v90 = *((_WORD *)v6 + 1), v6 += 4, *(_WORD *)v88 = v90, v88 = (_DWORD *)((char *)v88 + 2), v89) ) + { + do + { + v91 = *(_DWORD *)v6; + v6 += 4; + *v88 = v91; + ++v88; + --v89; + } + while ( v89 ); + } + v2 = (unsigned char *)v88 - 200; + v32 = __OFSUB__(v85, 2); + v85 -= 2; + } + while ( !((v85 < 0) ^ v32) ); + goto LABEL_162; + } + if ( v7 != 11 ) + { + if ( v7 != 12 ) + { + v122 = 30; + if ( (unsigned int)a1 >= screen_buf_end ) + { + v123 = (unsigned int)((char *)a1 - screen_buf_end + 1023) >> 8; + if ( v123 > 45 ) + { + v2 = (unsigned char *)a1 - 12288; + v6 += 288; +LABEL_217: + world_4B3269[0] -= 64; + v128 = 16; + do + { + if ( (unsigned int)v2 < screen_buf_end ) + { + v166 = v128; + v129 = *(_DWORD *)world_4B3269[0]; + v130 = 32; + do + { + v131 = *v6++; + v16 = __CFSHL__(v129, 1); + v129 *= 2; + if ( v16 ) + *v2 = v131; + ++v2; + --v130; + } + while ( v130 ); + v6 += (unsigned char)v6 & 2; + v128 = v166; + } + else + { + v6 += 32; + v2 += 32; + } + v2 -= 800; + world_4B3269[0] -= 4; + --v128; + } + while ( v128 ); + return; + } + v124 = world_4B33FD[v123]; + v6 += *(int *)((char *)world_4B34BD + v124); + v2 -= 192 * v124; + v122 = 30 - (v124 >> 1); + } + do + { + for ( jj = (unsigned int)(32 - v122) >> 2; jj; --jj ) + { + v126 = *(_DWORD *)v6; + v6 += 4; + *(_DWORD *)v2 = v126; + v2 += 4; + } + if ( (32 - (_BYTE)v122) & 2 ) + { + v127 = *(_WORD *)v6; + v6 += 4; + *(_WORD *)v2 = v127; + v2 += 2; + } + v2 = &v2[v122 - 800]; + v32 = __OFSUB__(v122, 2); + v122 -= 2; + } + while ( !((v122 < 0) ^ v32) ); + goto LABEL_217; + } + v111 = 30; + if ( (unsigned int)a1 >= screen_buf_end ) + { + v112 = (unsigned int)((char *)a1 - screen_buf_end + 1023) >> 8; + if ( v112 > 45 ) + { + v2 = (unsigned char *)a1 - 12288; + v6 += 288; +LABEL_198: + world_4B3269[0] -= 64; + v118 = 16; + do + { + if ( (unsigned int)v2 < screen_buf_end ) + { + v172 = v118; + v119 = *(_DWORD *)world_4B3269[0]; + v120 = 32; + do + { + v121 = *v6++; + v16 = __CFSHL__(v119, 1); + v119 *= 2; + if ( v16 ) + *v2 = v121; + ++v2; + --v120; + } + while ( v120 ); + v118 = v172; + } + else + { + v6 += 32; + v2 += 32; + } + v2 -= 800; + world_4B3269[0] -= 4; + --v118; + } + while ( v118 ); + return; + } + v113 = world_4B33FD[v112]; + v6 += *(int *)((char *)world_4B34BD + v113); + v2 -= 192 * v113; + v111 = 30 - (v113 >> 1); + } + do + { + v114 = (unsigned int *)&v2[v111]; + v115 = (unsigned int)(32 - v111) >> 2; + if ( !__CFSHR__(32 - v111, 2) + || (v116 = *((_WORD *)v6 + 1), v6 += 4, *(_WORD *)v114 = v116, v114 = (_DWORD *)((char *)v114 + 2), v115) ) + { + do + { + v117 = *(_DWORD *)v6; + v6 += 4; + *v114 = v117; + ++v114; + --v115; + } + while ( v115 ); + } + v2 = (unsigned char *)v114 - 200; + v32 = __OFSUB__(v111, 2); + v111 -= 2; + } + while ( !((v111 < 0) ^ v32) ); + goto LABEL_198; + } + v99 = 30; + if ( (unsigned int)a1 < screen_buf_end ) + goto LABEL_175; + v100 = (unsigned int)((char *)a1 - screen_buf_end + 1023) >> 8; + if ( v100 <= 45 ) + { + v101 = world_4B33FD[v100]; + v6 += *(int *)((char *)world_4B34BD + v101); + v2 -= 192 * v101; + v99 = 30 - (v101 >> 1); + do + { +LABEL_175: + for ( kk = (unsigned int)(32 - v99) >> 2; kk; --kk ) + { + v103 = *(_DWORD *)v6; + v6 += 4; + *(_DWORD *)v2 = v103; + v2 += 4; + } + if ( (32 - (_BYTE)v99) & 2 ) + { + v104 = *(_WORD *)v6; + v6 += 4; + *(_WORD *)v2 = v104; + v2 += 2; + } + v2 = &v2[v99 - 800]; + v32 = __OFSUB__(v99, 2); + v99 -= 2; + } + while ( !((v99 < 0) ^ v32) ); + goto LABEL_180; + } + v2 = (unsigned char *)a1 - 12288; + v6 += 288; +LABEL_180: + v105 = 2; + if ( (unsigned int)v2 >= screen_buf_end ) + { + v106 = (unsigned int)&v2[-screen_buf_end + 1023] >> 8; + if ( v106 > 42 ) + return; + v107 = world_4B33FD[v106]; + v6 += *(int *)((char *)world_4B3501 + v107); + v2 -= 192 * v107; + v105 = (v107 >> 1) + 2; + } + do + { + for ( ll = (unsigned int)(32 - v105) >> 2; ll; --ll ) + { + v109 = *(_DWORD *)v6; + v6 += 4; + *(_DWORD *)v2 = v109; + v2 += 4; + } + if ( (32 - (_BYTE)v105) & 2 ) + { + v110 = *(_WORD *)v6; + v6 += 4; + *(_WORD *)v2 = v110; + v2 += 2; + } + v2 = &v2[v105 - 800]; + v105 += 2; + } + while ( v105 != 32 ); +} +// 642A14: using guessed type char lightmax; +// 69BEF8: using guessed type int light_table_index; +// 69CF0C: using guessed type int screen_buf_end; +// 69CF14: using guessed type int level_cel_block; + +//----- (0046886B) -------------------------------------------------------- +void __fastcall drawLowerScreen(void *a1) +{ + int v1; // edx + char v2; // al + char v3; // al + char *v4; // edi + _BYTE *v5; // esi + int v6; // ebx + short v7; // ax + unsigned char *v8; // esi + short v9; // ax + char *v10; // esi + unsigned int v11; // eax + int v12; // eax + int v13; // edx + int v14; // edx + signed int v15; // ebp + int v16; // eax + int v17; // ecx + signed int v18; // ebp + int v19; // eax + char m; // cl + int v21; // eax + char v22; // ch + char v23; // ch + char v24; // ch + int v25; // ebp + signed int v26; // eax + unsigned int v27; // ecx + char *v28; // edi + int v29; // ecx + int v30; // edx + unsigned char v31; // of + int v32; // ebp + signed int v33; // eax + unsigned int v34; // ecx + char *v35; // edi + int v36; // ecx + int v37; // edx + int v38; // ebp + signed int v39; // eax + unsigned int v40; // ecx + int v41; // ecx + int v42; // ebp + signed int v43; // eax + unsigned int v44; // ecx + int v45; // ecx + int v46; // ebp + signed int v47; // eax + unsigned int v48; // ecx + char *v49; // edi + char v50; // cl + int v51; // eax + char v52; // ch + char v53; // ch + char v54; // ch + signed int v55; // ebp + char v56; // cl + int v57; // eax + char v58; // ch + char v59; // ch + char v60; // ch + int v61; // ebp + signed int v62; // eax + unsigned int v63; // ecx + char n; // cl + int v65; // eax + char v66; // ch + char v67; // ch + char v68; // ch + signed int v69; // ebp + char v70; // cl + int v71; // eax + char v72; // ch + char v73; // ch + char v74; // ch + signed int v75; // edx + signed int v76; // ecx + int v77; // eax + int v78; // ecx + signed int v79; // edx + unsigned int v80; // eax + unsigned int v81; // ecx + unsigned char v82; // al + char v83; // cf + unsigned int v84; // ecx + short v85; // ax + int v86; // eax + int v87; // edx + signed int v88; // eax + unsigned int v89; // ecx + char *v90; // edi + unsigned int v91; // ecx + short v92; // ax + int v93; // eax + int v94; // edx + signed int v95; // eax + unsigned int v96; // ecx + char *v97; // edi + unsigned int v98; // ecx + short v99; // ax + int v100; // eax + int v101; // edx + signed int v102; // eax + unsigned int v103; // ecx + unsigned int jj; // ecx + int v105; // eax + short v106; // ax + int v107; // edx + signed int v108; // eax + unsigned int v109; // ecx + unsigned int kk; // ecx + int v111; // eax + short v112; // ax + int v113; // edi + int v114; // edx + signed int v115; // eax + unsigned int v116; // ecx + char *v117; // edi + unsigned int v118; // ecx + short v119; // ax + int v120; // eax + signed int v121; // edx + signed int v122; // ecx + int v123; // eax + int v124; // edx + signed int v125; // eax + unsigned int v126; // ecx + unsigned int ii; // ecx + int v128; // eax + short v129; // ax + signed int v130; // edx + signed int v131; // ecx + int v132; // eax + signed int v133; // edx + signed int v134; // ecx + int v135; // ecx + signed int v136; // edx + unsigned int v137; // eax + unsigned int v138; // ecx + unsigned int v139; // ecx + signed int i; // edx + char *v141; // edi + unsigned int v142; // ecx + signed int v143; // edx + char *v144; // edi + unsigned int v145; // ecx + signed int j; // edx + unsigned int v147; // ecx + char *v148; // edi + signed int v149; // edx + unsigned int v150; // ecx + signed int k; // edx + char *v152; // edi + unsigned int v153; // ecx + signed int v154; // edx + signed int v155; // ecx + signed int l; // edx + unsigned int v157; // ecx + char *v158; // edi + signed int v159; // edx + signed int v160; // ecx + int v161; // [esp-14h] [ebp-18h] + int v162; // [esp-14h] [ebp-18h] + int v163; // [esp-10h] [ebp-14h] + int v164; // [esp-10h] [ebp-14h] + + v1 = cel_transparency_active; + if ( cel_transparency_active ) + { + if ( !arch_draw_type ) + { + drawTopArchesLowerScreen(a1); + return; + } + if ( arch_draw_type == 1 ) + { + v2 = block_lvid[level_piece_id]; + if ( v2 == 1 || v2 == 3 ) + { + drawBottomArchesLowerScreen(a1, (int)&tile_draw_masks[63]); + return; + } + } + if ( arch_draw_type == 2 ) + { + v3 = block_lvid[level_piece_id]; + if ( v3 == 2 || v3 == 3 ) + { + drawBottomArchesLowerScreen(a1, (int)&tile_draw_masks[31]); + return; + } + } + } + world_4B3265 = (int)speed_cel_frame_num_from_light_index_frame_num; + v4 = (char *)a1; + if ( (_BYTE)light_table_index ) + { + if ( (_BYTE)light_table_index == lightmax ) + { + if ( level_cel_block & 0x8000 ) + level_cel_block = *(_DWORD *)(((level_cel_block & 0xFFF) << 6) + world_4B3265) + + (unsigned short)(level_cel_block & 0xF000); + v10 = (char *)pDungeonCels + *((_DWORD *)pDungeonCels + (level_cel_block & 0xFFF)); + v11 = level_cel_block; + _LOBYTE(v11) = BYTE1(v11); + v12 = (v11 >> 4) & 7; + if ( v12 ) + { + switch ( (_WORD)v12 ) + { + case 1: + v135 = 32; + do + { + v164 = v135; + v136 = 32; + do + { + while ( 1 ) + { + v137 = (unsigned char)*v10++; + if ( (v137 & 0x80u) == 0 ) + break; + _LOBYTE(v137) = -(char)v137; + v4 += v137; + v136 -= v137; + if ( !v136 ) + goto LABEL_232; + } + v136 -= v137; + if ( (unsigned int)v4 < screen_buf_end ) + { + v10 += v137; + v138 = v137 >> 1; + if ( !(v137 & 1) || (*v4 = 0, ++v4, v138) ) + { + v83 = v138 & 1; + v139 = v137 >> 2; + if ( !v83 || (*(_WORD *)v4 = 0, v4 += 2, v139) ) + { + do + { + *(_DWORD *)v4 = 0; + v4 += 4; + --v139; + } + while ( v139 ); + } + } + } + else + { + v10 += v137; + v4 += v137; + } + } + while ( v136 ); +LABEL_232: + v4 -= 800; + v135 = v164 - 1; + } + while ( v164 != 1 ); + break; + case 2: + for ( i = 30; ; i -= 2 ) + { + if ( (unsigned int)v4 < screen_buf_end ) + { + v141 = &v4[i]; + v142 = (unsigned int)(32 - i) >> 2; + if ( !__CFSHR__(32 - i, 2) || (*(_WORD *)v141 = 0, v141 += 2, v142) ) + { + do + { + *(_DWORD *)v141 = 0; + v141 += 4; + --v142; + } + while ( v142 ); + } + } + else + { + v10 = &v10[-i + 32]; + v141 = v4 + 32; + } + v4 = v141 - 800; + if ( !i ) + break; + } + v143 = 2; + do + { + if ( (unsigned int)v4 < screen_buf_end ) + { + v144 = &v4[v143]; + v145 = (unsigned int)(32 - v143) >> 2; + if ( !__CFSHR__(32 - v143, 2) || (*(_WORD *)v144 = 0, v144 += 2, v145) ) + { + do + { + *(_DWORD *)v144 = 0; + v144 += 4; + --v145; + } + while ( v145 ); + } + } + else + { + v10 = &v10[-v143 + 32]; + v144 = v4 + 32; + } + v4 = v144 - 800; + v143 += 2; + } + while ( v143 != 32 ); + break; + case 3: + for ( j = 30; ; j -= 2 ) + { + if ( (unsigned int)v4 < screen_buf_end ) + { + v147 = (unsigned int)(32 - j) >> 2; + if ( !__CFSHR__(32 - j, 2) || (*(_WORD *)v4 = 0, v4 += 2, v147) ) + { + do + { + *(_DWORD *)v4 = 0; + v4 += 4; + --v147; + } + while ( v147 ); + } + } + else + { + v10 = &v10[-j + 32]; + v4 = &v4[-j + 32]; + } + v148 = v4 - 800; + if ( !j ) + break; + v4 = &v148[j]; + } + v149 = 2; + do + { + if ( (unsigned int)v148 < screen_buf_end ) + { + v150 = (unsigned int)(32 - v149) >> 2; + if ( !__CFSHR__(32 - v149, 2) || (*(_WORD *)v148 = 0, v148 += 2, v150) ) + { + do + { + *(_DWORD *)v148 = 0; + v148 += 4; + --v150; + } + while ( v150 ); + } + } + else + { + v10 = &v10[-v149 + 32]; + v148 = &v148[-v149 + 32]; + } + v148 = &v148[v149 - 800]; + v149 += 2; + } + while ( v149 != 32 ); + break; + case 4: + for ( k = 30; ; k -= 2 ) + { + if ( (unsigned int)v4 < screen_buf_end ) + { + v152 = &v4[k]; + v153 = (unsigned int)(32 - k) >> 2; + if ( !__CFSHR__(32 - k, 2) || (*(_WORD *)v152 = 0, v152 += 2, v153) ) + { + do + { + *(_DWORD *)v152 = 0; + v152 += 4; + --v153; + } + while ( v153 ); + } + } + else + { + v10 = &v10[-k + 32]; + v152 = v4 + 32; + } + v4 = v152 - 800; + if ( !k ) + break; + } + v154 = 16; + do + { + if ( (unsigned int)v4 < screen_buf_end ) + { + v155 = 8; + do + { + *(_DWORD *)v4 = 0; + v4 += 4; + --v155; + } + while ( v155 ); + } + else + { + v10 += 32; + v4 += 32; + } + v4 -= 800; + --v154; + } + while ( v154 ); + break; + default: + for ( l = 30; ; l -= 2 ) + { + if ( (unsigned int)v4 < screen_buf_end ) + { + v157 = (unsigned int)(32 - l) >> 2; + if ( !__CFSHR__(32 - l, 2) || (*(_WORD *)v4 = 0, v4 += 2, v157) ) + { + do + { + *(_DWORD *)v4 = 0; + v4 += 4; + --v157; + } + while ( v157 ); + } + } + else + { + v10 = &v10[-l + 32]; + v4 = &v4[-l + 32]; + } + v158 = v4 - 800; + if ( !l ) + break; + v4 = &v158[l]; + } + v159 = 16; + do + { + if ( (unsigned int)v158 < screen_buf_end ) + { + v160 = 8; + do + { + *(_DWORD *)v158 = 0; + v158 += 4; + --v160; + } + while ( v160 ); + } + else + { + v10 += 32; + v158 += 32; + } + v158 -= 800; + --v159; + } + while ( v159 ); + break; + } + } + else + { + v133 = 32; + do + { + if ( (unsigned int)v4 < screen_buf_end ) + { + v134 = 8; + do + { + *(_DWORD *)v4 = 0; + v4 += 4; + --v134; + } + while ( v134 ); + } + else + { + v10 += 32; + v4 += 32; + } + v4 -= 800; + --v133; + } + while ( v133 ); + } + return; + } + if ( !(level_cel_block & 0x8000) ) + { + v5 = (unsigned char *)pDungeonCels + *((_DWORD *)pDungeonCels + (level_cel_block & 0xFFF)); + v6 = dword_646A20 + (light_table_index << 8); + v7 = (unsigned short)level_cel_block >> 12; + if ( !((unsigned short)level_cel_block >> 12) ) + { + v13 = 32; + do + { + v161 = v13; + if ( (unsigned int)v4 < screen_buf_end ) + { + v14 = 0; + v15 = 8; + do + { + v16 = *(_DWORD *)v5; + v5 += 4; + v16 = __ROR4__(v16, 16); + _LOBYTE(v14) = v16; + _LOBYTE(a1) = *(_BYTE *)(v6 + v14); + _LOBYTE(v14) = BYTE1(v16); + BYTE1(a1) = *(_BYTE *)(v6 + v14); + v16 = __ROR4__(v16, 16); + a1 = (void *)((_DWORD)a1 << 16); + _LOBYTE(v14) = v16; + _LOBYTE(a1) = *(_BYTE *)(v6 + v14); + _LOBYTE(v14) = BYTE1(v16); + BYTE1(a1) = *(_BYTE *)(v6 + v14); + *(_DWORD *)v4 = (unsigned int)a1; + v4 += 4; + --v15; + } + while ( v15 ); + } + else + { + v5 += 32; + v4 += 32; + } + v4 -= 800; + v13 = v161 - 1; + } + while ( v161 != 1 ); + return; + } + if ( v7 == 1 ) + { + v17 = 32; + do + { + v162 = v17; + v18 = 32; + do + { + v19 = (unsigned char)*v5++; + if ( (v19 & 0x80u) == 0 ) + { + v18 -= v19; + if ( (unsigned int)v4 < screen_buf_end ) + { + for ( m = v19; m >= 4; m -= 4 ) + { + v21 = *(_DWORD *)v5; + v5 += 4; + _LOBYTE(v1) = v21; + v22 = *(_BYTE *)(v6 + v1); + _LOBYTE(v1) = BYTE1(v21); + v21 = __ROR4__(v21, 16); + *v4 = v22; + v23 = *(_BYTE *)(v6 + v1); + _LOBYTE(v1) = v21; + v4[1] = v23; + v24 = *(_BYTE *)(v6 + v1); + _LOBYTE(v1) = BYTE1(v21); + v4[2] = v24; + v4[3] = *(_BYTE *)(v6 + v1); + v4 += 4; + } + if ( m >= 2 ) + { + _LOBYTE(v1) = *v5; + *v4 = *(_BYTE *)(v6 + v1); + _LOBYTE(v1) = v5[1]; + v4[1] = *(_BYTE *)(v6 + v1); + v5 += 2; + v4 += 2; + } + if ( m & 1 ) + { + _LOBYTE(v1) = *v5++; + *v4++ = *(_BYTE *)(v6 + v1); + } + } + else + { + v5 += v19; + v4 += v19; + } + } + else + { + _LOBYTE(v19) = -(char)v19; + v4 += v19; + v18 -= v19; + } + } + while ( v18 ); + v4 -= 800; + v17 = v162 - 1; + } + while ( v162 != 1 ); + return; + } + if ( v7 != 2 ) + { + if ( v7 != 3 ) + { + if ( v7 != 4 ) + { + v61 = 30; + if ( (unsigned int)a1 >= screen_buf_end ) + { + v62 = (unsigned int)((char *)a1 - screen_buf_end + 1023) >> 8; + if ( v62 > 45 ) + { + v4 = (char *)a1 - 12288; + v5 += 288; +LABEL_116: + v69 = 16; + do + { + if ( (unsigned int)v4 < screen_buf_end ) + { + v70 = 32; + do + { + v71 = *(_DWORD *)v5; + v5 += 4; + _LOBYTE(v1) = v71; + v72 = *(_BYTE *)(v6 + v1); + _LOBYTE(v1) = BYTE1(v71); + v71 = __ROR4__(v71, 16); + *v4 = v72; + v73 = *(_BYTE *)(v6 + v1); + _LOBYTE(v1) = v71; + v4[1] = v73; + v74 = *(_BYTE *)(v6 + v1); + _LOBYTE(v1) = BYTE1(v71); + v4[2] = v74; + v4[3] = *(_BYTE *)(v6 + v1); + v4 += 4; + v70 -= 4; + } + while ( v70 >= 4 ); + } + else + { + v5 += 32; + v4 += 32; + } + v4 -= 800; + --v69; + } + while ( v69 ); + return; + } + v63 = world_4B33FD[v62]; + v5 += *(int *)((char *)world_4B34BD + v63); + v4 -= 192 * v63; + v61 = 30 - (v63 >> 1); + } + do + { + for ( n = 32 - v61; n >= 4; n -= 4 ) + { + v65 = *(_DWORD *)v5; + v5 += 4; + _LOBYTE(v1) = v65; + v66 = *(_BYTE *)(v6 + v1); + _LOBYTE(v1) = BYTE1(v65); + v65 = __ROR4__(v65, 16); + *v4 = v66; + v67 = *(_BYTE *)(v6 + v1); + _LOBYTE(v1) = v65; + v4[1] = v67; + v68 = *(_BYTE *)(v6 + v1); + _LOBYTE(v1) = BYTE1(v65); + v4[2] = v68; + v4[3] = *(_BYTE *)(v6 + v1); + v4 += 4; + } + if ( n >= 2 ) + { + _LOBYTE(v1) = *v5; + *v4 = *(_BYTE *)(v6 + v1); + _LOBYTE(v1) = v5[1]; + v4[1] = *(_BYTE *)(v6 + v1); + v5 += 2; + v4 += 2; + } + v1 = (unsigned char)v5 & 2; + v5 += v1; + v4 = &v4[v61 - 800]; + v31 = __OFSUB__(v61, 2); + v61 -= 2; + } + while ( !((v61 < 0) ^ v31) ); + goto LABEL_116; + } + v46 = 30; + if ( (unsigned int)a1 >= screen_buf_end ) + { + v47 = (unsigned int)((char *)a1 - screen_buf_end + 1023) >> 8; + if ( v47 > 45 ) + { + v4 = (char *)a1 - 12288; + v5 += 288; +LABEL_100: + v55 = 16; + do + { + if ( (unsigned int)v4 < screen_buf_end ) + { + v56 = 32; + do + { + v57 = *(_DWORD *)v5; + v5 += 4; + _LOBYTE(v1) = v57; + v58 = *(_BYTE *)(v6 + v1); + _LOBYTE(v1) = BYTE1(v57); + v57 = __ROR4__(v57, 16); + *v4 = v58; + v59 = *(_BYTE *)(v6 + v1); + _LOBYTE(v1) = v57; + v4[1] = v59; + v60 = *(_BYTE *)(v6 + v1); + _LOBYTE(v1) = BYTE1(v57); + v4[2] = v60; + v4[3] = *(_BYTE *)(v6 + v1); + v4 += 4; + v56 -= 4; + } + while ( v56 >= 4 ); + } + else + { + v5 += 32; + v4 += 32; + } + v4 -= 800; + --v55; + } + while ( v55 ); + return; + } + v48 = world_4B33FD[v47]; + v5 += *(int *)((char *)world_4B34BD + v48); + v4 -= 192 * v48; + v46 = 30 - (v48 >> 1); + } + do + { + v49 = &v4[v46]; + v50 = 32 - v46; + v1 = (32 - (_BYTE)v46) & 2; + v5 += v1; + if ( (char)(32 - v46) >= 4 ) + { + do + { + v51 = *(_DWORD *)v5; + v5 += 4; + _LOBYTE(v1) = v51; + v52 = *(_BYTE *)(v6 + v1); + _LOBYTE(v1) = BYTE1(v51); + v51 = __ROR4__(v51, 16); + *v49 = v52; + v53 = *(_BYTE *)(v6 + v1); + _LOBYTE(v1) = v51; + v49[1] = v53; + v54 = *(_BYTE *)(v6 + v1); + _LOBYTE(v1) = BYTE1(v51); + v49[2] = v54; + v49[3] = *(_BYTE *)(v6 + v1); + v49 += 4; + v50 -= 4; + } + while ( v50 >= 4 ); + } + if ( v50 >= 2 ) + { + _LOBYTE(v1) = *v5; + *v49 = *(_BYTE *)(v6 + v1); + _LOBYTE(v1) = v5[1]; + v49[1] = *(_BYTE *)(v6 + v1); + v5 += 2; + v49 += 2; + } + v4 = v49 - 800; + v31 = __OFSUB__(v46, 2); + v46 -= 2; + } + while ( !((v46 < 0) ^ v31) ); + goto LABEL_100; + } + v38 = 30; + if ( (unsigned int)a1 >= screen_buf_end ) + { + v39 = (unsigned int)((char *)a1 - screen_buf_end + 1023) >> 8; + if ( v39 > 45 ) + { + v4 = (char *)a1 - 12288; + v5 += 288; +LABEL_83: + v42 = 2; + if ( (unsigned int)v4 >= screen_buf_end ) + { + v43 = (unsigned int)&v4[-screen_buf_end + 1023] >> 8; + if ( v43 > 42 ) + return; + v44 = world_4B33FD[v43]; + v5 += *(int *)((char *)world_4B3501 + v44); + v4 -= 192 * v44; + v42 = (v44 >> 1) + 2; + } + do + { + v45 = 32 - v42; + do + { + _LOBYTE(v1) = *v5++; + *v4++ = *(_BYTE *)(v6 + v1); + --v45; + } + while ( v45 ); + v1 = (unsigned char)v5 & 2; + v5 += v1; + v4 = &v4[v42 - 800]; + v42 += 2; + } + while ( v42 != 32 ); + return; + } + v40 = world_4B33FD[v39]; + v5 += *(int *)((char *)world_4B34BD + v40); + v4 -= 192 * v40; + v38 = 30 - (v40 >> 1); + } + do + { + v41 = 32 - v38; + do + { + _LOBYTE(v1) = *v5++; + *v4++ = *(_BYTE *)(v6 + v1); + --v41; + } + while ( v41 ); + v1 = (unsigned char)v5 & 2; + v5 += v1; + v4 = &v4[v38 - 800]; + v31 = __OFSUB__(v38, 2); + v38 -= 2; + } + while ( !((v38 < 0) ^ v31) ); + goto LABEL_83; + } + v25 = 30; + if ( (unsigned int)a1 >= screen_buf_end ) + { + v26 = (unsigned int)((char *)a1 - screen_buf_end + 1023) >> 8; + if ( v26 > 45 ) + { + v4 = (char *)a1 - 12288; + v5 += 288; +LABEL_68: + v32 = 2; + if ( (unsigned int)v4 >= screen_buf_end ) + { + v33 = (unsigned int)&v4[-screen_buf_end + 1023] >> 8; + if ( v33 > 42 ) + return; + v34 = world_4B33FD[v33]; + v5 += *(int *)((char *)world_4B3501 + v34); + v4 -= 192 * v34; + v32 = (v34 >> 1) + 2; + } + do + { + v35 = &v4[v32]; + v36 = 32 - v32; + v37 = (32 - (_BYTE)v32) & 2; + v5 += v37; + do + { + _LOBYTE(v37) = *v5++; + *v35++ = *(_BYTE *)(v6 + v37); + --v36; + } + while ( v36 ); + v32 += 2; + v4 = v35 - 800; + } + while ( v32 != 32 ); + return; + } + v27 = world_4B33FD[v26]; + v5 += *(int *)((char *)world_4B34BD + v27); + v4 -= 192 * v27; + v25 = 30 - (v27 >> 1); + } + do + { + v28 = &v4[v25]; + v29 = 32 - v25; + v30 = (32 - (_BYTE)v25) & 2; + v5 += v30; + do + { + _LOBYTE(v30) = *v5++; + *v28++ = *(_BYTE *)(v6 + v30); + --v29; + } + while ( v29 ); + v4 = v28 - 800; + v31 = __OFSUB__(v25, 2); + v25 -= 2; + } + while ( !((v25 < 0) ^ v31) ); + goto LABEL_68; + } + v8 = (unsigned char *)pSpeedCels + + *(_DWORD *)(4 * (light_table_index + 16 * (level_cel_block & 0xFFF)) + world_4B3265); + v9 = (unsigned short)level_cel_block >> 12; + } + else + { + if ( level_cel_block & 0x8000 ) + level_cel_block = *(_DWORD *)(((level_cel_block & 0xFFF) << 6) + world_4B3265) + + (unsigned short)(level_cel_block & 0xF000); + v8 = (unsigned char *)pDungeonCels + *((_DWORD *)pDungeonCels + (level_cel_block & 0xFFF)); + v9 = (((unsigned int)level_cel_block >> 12) & 7) + 8; + } + switch ( v9 ) + { + case 8: + v75 = 32; + do + { + if ( (unsigned int)v4 < screen_buf_end ) + { + v76 = 8; + do + { + v77 = *(_DWORD *)v8; + v8 += 4; + *(_DWORD *)v4 = v77; + v4 += 4; + --v76; + } + while ( v76 ); + } + else + { + v8 += 32; + v4 += 32; + } + v4 -= 800; + --v75; + } + while ( v75 ); + return; + case 9: + v78 = 32; + do + { + v163 = v78; + v79 = 32; + do + { + while ( 1 ) + { + v80 = *v8++; + if ( (v80 & 0x80u) == 0 ) + break; + _LOBYTE(v80) = -(char)v80; + v4 += v80; + v79 -= v80; + if ( !v79 ) + goto LABEL_143; + } + v79 -= v80; + if ( (unsigned int)v4 < screen_buf_end ) + { + v81 = v80 >> 1; + if ( !(v80 & 1) || (v82 = *v8, ++v8, *v4 = v82, ++v4, v81) ) + { + v83 = v81 & 1; + v84 = v81 >> 1; + if ( !v83 || (v85 = *(_WORD *)v8, v8 += 2, *(_WORD *)v4 = v85, v4 += 2, v84) ) + { + do + { + v86 = *(_DWORD *)v8; + v8 += 4; + *(_DWORD *)v4 = v86; + v4 += 4; + --v84; + } + while ( v84 ); + } + } + } + else + { + v8 += v80; + v4 += v80; + } + } + while ( v79 ); +LABEL_143: + v4 -= 800; + v78 = v163 - 1; + } + while ( v163 != 1 ); + return; + case 10: + v87 = 30; + if ( (unsigned int)a1 >= screen_buf_end ) + { + v88 = (unsigned int)((char *)a1 - screen_buf_end + 1023) >> 8; + if ( v88 > 45 ) + { + v4 = (char *)a1 - 12288; + v8 += 288; +LABEL_153: + v94 = 2; + if ( (unsigned int)v4 >= screen_buf_end ) + { + v95 = (unsigned int)&v4[-screen_buf_end + 1023] >> 8; + if ( v95 > 42 ) + return; + v96 = world_4B33FD[v95]; + v8 += *(int *)((char *)world_4B3501 + v96); + v4 -= 192 * v96; + v94 = (v96 >> 1) + 2; + } + do + { + v97 = &v4[v94]; + v98 = (unsigned int)(32 - v94) >> 2; + if ( !__CFSHR__(32 - v94, 2) + || (v99 = *((_WORD *)v8 + 1), v8 += 4, *(_WORD *)v97 = v99, v97 += 2, v98) ) + { + do + { + v100 = *(_DWORD *)v8; + v8 += 4; + *(_DWORD *)v97 = v100; + v97 += 4; + --v98; + } + while ( v98 ); + } + v94 += 2; + v4 = v97 - 800; + } + while ( v94 < 32 ); + return; + } + v89 = world_4B33FD[v88]; + v8 += *(int *)((char *)world_4B34BD + v89); + v4 -= 192 * v89; + v87 = 30 - (v89 >> 1); + } + do + { + v90 = &v4[v87]; + v91 = (unsigned int)(32 - v87) >> 2; + if ( !__CFSHR__(32 - v87, 2) || (v92 = *((_WORD *)v8 + 1), v8 += 4, *(_WORD *)v90 = v92, v90 += 2, v91) ) + { + do + { + v93 = *(_DWORD *)v8; + v8 += 4; + *(_DWORD *)v90 = v93; + v90 += 4; + --v91; + } + while ( v91 ); + } + v4 = v90 - 800; + v31 = __OFSUB__(v87, 2); + v87 -= 2; + } + while ( !((v87 < 0) ^ v31) ); + goto LABEL_153; + } + if ( v9 != 11 ) + { + if ( v9 != 12 ) + { + v124 = 30; + if ( (unsigned int)a1 >= screen_buf_end ) + { + v125 = (unsigned int)((char *)a1 - screen_buf_end + 1023) >> 8; + if ( v125 > 45 ) + { + v4 = (char *)a1 - 12288; + v8 += 288; +LABEL_205: + v130 = 16; + do + { + if ( (unsigned int)v4 < screen_buf_end ) + { + v131 = 8; + do + { + v132 = *(_DWORD *)v8; + v8 += 4; + *(_DWORD *)v4 = v132; + v4 += 4; + --v131; + } + while ( v131 ); + } + else + { + v8 += 32; + v4 += 32; + } + v4 -= 800; + --v130; + } + while ( v130 ); + return; + } + v126 = world_4B33FD[v125]; + v8 += *(int *)((char *)world_4B34BD + v126); + v4 -= 192 * v126; + v124 = 30 - (v126 >> 1); + } + do + { + for ( ii = (unsigned int)(32 - v124) >> 2; ii; --ii ) + { + v128 = *(_DWORD *)v8; + v8 += 4; + *(_DWORD *)v4 = v128; + v4 += 4; + } + if ( (32 - (_BYTE)v124) & 2 ) + { + v129 = *(_WORD *)v8; + v8 += 4; + *(_WORD *)v4 = v129; + v4 += 2; + } + v4 = &v4[v124 - 800]; + v31 = __OFSUB__(v124, 2); + v124 -= 2; + } + while ( !((v124 < 0) ^ v31) ); + goto LABEL_205; + } + v114 = 30; + if ( (unsigned int)a1 >= screen_buf_end ) + { + v115 = (unsigned int)((char *)a1 - screen_buf_end + 1023) >> 8; + if ( v115 > 45 ) + { + v4 = (char *)a1 - 12288; + v8 += 288; +LABEL_189: + v121 = 16; + do + { + if ( (unsigned int)v4 < screen_buf_end ) + { + v122 = 8; + do + { + v123 = *(_DWORD *)v8; + v8 += 4; + *(_DWORD *)v4 = v123; + v4 += 4; + --v122; + } + while ( v122 ); + } + else + { + v8 += 32; + v4 += 32; + } + v4 -= 800; + --v121; + } + while ( v121 ); + return; + } + v116 = world_4B33FD[v115]; + v8 += *(int *)((char *)world_4B34BD + v116); + v4 -= 192 * v116; + v114 = 30 - (v116 >> 1); + } + do + { + v117 = &v4[v114]; + v118 = (unsigned int)(32 - v114) >> 2; + if ( !__CFSHR__(32 - v114, 2) + || (v119 = *((_WORD *)v8 + 1), v8 += 4, *(_WORD *)v117 = v119, v117 += 2, v118) ) + { + do + { + v120 = *(_DWORD *)v8; + v8 += 4; + *(_DWORD *)v117 = v120; + v117 += 4; + --v118; + } + while ( v118 ); + } + v4 = v117 - 800; + v31 = __OFSUB__(v114, 2); + v114 -= 2; + } + while ( !((v114 < 0) ^ v31) ); + goto LABEL_189; + } + v101 = 30; + if ( (unsigned int)a1 < screen_buf_end ) + goto LABEL_166; + v102 = (unsigned int)((char *)a1 - screen_buf_end + 1023) >> 8; + if ( v102 <= 45 ) + { + v103 = world_4B33FD[v102]; + v8 += *(int *)((char *)world_4B34BD + v103); + v4 -= 192 * v103; + v101 = 30 - (v103 >> 1); + do + { +LABEL_166: + for ( jj = (unsigned int)(32 - v101) >> 2; jj; --jj ) + { + v105 = *(_DWORD *)v8; + v8 += 4; + *(_DWORD *)v4 = v105; + v4 += 4; + } + if ( (32 - (_BYTE)v101) & 2 ) + { + v106 = *(_WORD *)v8; + v8 += 4; + *(_WORD *)v4 = v106; + v4 += 2; + } + v4 = &v4[v101 - 800]; + v31 = __OFSUB__(v101, 2); + v101 -= 2; + } + while ( !((v101 < 0) ^ v31) ); + goto LABEL_171; + } + v4 = (char *)a1 - 12288; + v8 += 288; +LABEL_171: + v107 = 2; + if ( (unsigned int)v4 >= screen_buf_end ) + { + v108 = (unsigned int)&v4[-screen_buf_end + 1023] >> 8; + if ( v108 > 42 ) + return; + v109 = world_4B33FD[v108]; + v8 += *(int *)((char *)world_4B3501 + v109); + v4 -= 192 * v109; + v107 = (v109 >> 1) + 2; + } + do + { + for ( kk = (unsigned int)(32 - v107) >> 2; kk; --kk ) + { + v111 = *(_DWORD *)v8; + v8 += 4; + *(_DWORD *)v4 = v111; + v4 += 4; + } + if ( (32 - (_BYTE)v107) & 2 ) + { + v112 = *(_WORD *)v8; + v8 += 4; + *(_WORD *)v4 = v112; + v4 += 2; + } + v113 = (int)&v4[v107]; + v107 += 2; + v4 = (char *)(v113 - 800); + } + while ( v107 < 32 ); +} +// 642A14: using guessed type char lightmax; +// 69BEF8: using guessed type int light_table_index; +// 69CF0C: using guessed type int screen_buf_end; +// 69CF14: using guessed type int level_cel_block; +// 69CF20: using guessed type char arch_draw_type; +// 69CF94: using guessed type int cel_transparency_active; +// 69CF98: using guessed type int level_piece_id; + +//----- (004696BE) -------------------------------------------------------- +void __fastcall world_levelrelated(char *a1) +{ + char *v1; // edi + signed int v2; // edx + signed int i; // ebx + char *v4; // edi + signed int v5; // ecx + signed int v6; // edx + signed int v7; // ebx + char *v8; // edi + signed int v9; // ecx + + v1 = a1; + v2 = 30; + for ( i = 1; ; ++i ) + { + v4 = &v1[v2]; + v5 = i; + do + { + *(_DWORD *)v4 = 0; + v4 += 4; + --v5; + } + while ( v5 ); + v1 = &v4[v2 - 832]; + if ( !v2 ) + break; + v2 -= 2; + } + v6 = 2; + v7 = 15; + do + { + v8 = &v1[v6]; + v9 = v7; + do + { + *(_DWORD *)v8 = 0; + v8 += 4; + --v9; + } + while ( v9 ); + v1 = &v8[v6 - 832]; + --v7; + v6 += 2; + } + while ( v6 != 32 ); +} + +// ALL OK, 1917 function(s) have been successfully decompiled diff --git a/2018_03_14/DiabDev/_diab.h b/2018_03_14/DiabDev/_diab.h new file mode 100644 index 00000000..fd7f369c --- /dev/null +++ b/2018_03_14/DiabDev/_diab.h @@ -0,0 +1,2544 @@ + +char *__fastcall GetErr(int error_code); +void __fastcall GetDDErr(int error_code, char *error_buf, int error_buf_len); +void __fastcall GetDSErr(int error_code, char *error_buf, int error_buf_len); +char *__cdecl GetLastErr(); +void TermMsg(char *format, ...); +void __fastcall MsgBox(char *format, va_list va); +void __cdecl FreeDlg(); +void DrawDlg(char *format, ...); +void __fastcall DDErrDlg(int error_code, int log_line_nr, char *log_file_path); +void __fastcall DSErrDlg(int error_code, int log_line_nr, char *log_file_path); +void __fastcall CenterDlg(HWND hDlg); +void __fastcall TermDlg(int template_id, int error_code, char *log_file_path, int log_line_nr); +bool __stdcall FuncDlg(HWND hDlg, UINT uMsg, WPARAM wParam, char *text); +void __fastcall TextDlg(HWND hDlg, char *text); +void __fastcall ErrDlg(template_id template_id, int error_code, char *log_file_path, int log_line_nr); +void __fastcall FileErrDlg(char *error); +void __fastcall DiskFreeDlg(char *error); +bool __cdecl InsertCDDlg(); +void __fastcall DirErrDlg(char *error); +void __cdecl InitAutomapOnce(); +void __cdecl InitAutomap(); +void __cdecl StartAutomap(); +void __cdecl AutomapUp(); +void __cdecl AutomapDown(); +void __cdecl AutomapLeft(); +void __cdecl AutomapRight(); +void __cdecl AutomapZoomIn(); +void __cdecl AutomapZoomOut(); +void __cdecl DrawAutomap(); +void __fastcall DrawAutomapType(int screen_x, int screen_y, short automap_type); +void __cdecl DrawAutomapPlr(); +short __fastcall GetAutomapType(int tx, int ty, bool view); +void __cdecl DrawAutomapGame(); +void __fastcall SetAutomapView(int x, int y); +void __cdecl AutomapZoomReset(); +void __cdecl CaptureScreen(); +bool __fastcall CaptureHdr(HANDLE hFile, short width, int height); +bool __fastcall CapturePal(HANDLE hFile, PALETTEENTRY *palette); +bool __fastcall CapturePix(HANDLE hFile, short width, short height, short stride, char *pixels); +char *__fastcall CaptureEnc(char *src, void *dst, int width); +HANDLE __fastcall CaptureFile(char *dst_path); +void __fastcall CaptureRedPal(PALETTEENTRY *palette_orig); +int __fastcall codec_decode(void *src_dst, int size, char *password); +void __cdecl j_sha1_reset(); +void __fastcall codec_init_key(int unused, char *password); +int __fastcall codec_get_encoded_len(int n); +void __fastcall codec_encode(void *src_dst, int size, int size_64, char *password); +void __fastcall DrawSpellCel(int xp, int yp, char *Trans, int nCel, int w); +void __fastcall SetSpellTrans(char t); +void __cdecl DrawSpell(); +void __cdecl DrawSpellList(); +void __cdecl SetSpell(); +void __fastcall SetSpeedSpell(int slot); +void __fastcall ToggleSpell(int slot); +int __fastcall CPrintString(int No, char *pszStr, int Just); +void __fastcall AddPanelString(char *str, int just); +void __cdecl ClearPanel(); +void __fastcall DrawPanelBox(int x, int y, unsigned short a3, unsigned short a4, int sx, int sy); +void __cdecl InitPanelStr(); +void __fastcall SetFlaskHeight(char *buf, int min, int max, int c, int r); +void __fastcall DrawFlask(void *a1, int a2, int a3, void *a4, int a5, int a6); +void __cdecl DrawLifeFlask(); +void __cdecl UpdateLifeFlask(); +void __cdecl DrawManaFlask(); +void __cdecl control_update_life_mana(); +void __cdecl UpdateManaFlask(); +void __cdecl InitControlPan(); +void __cdecl ClearCtrlPan(); +void __cdecl DrawCtrlPan(); +void __cdecl DoSpeedBook(); +void __cdecl DoPanBtn(); +void __fastcall control_set_button_down(int btn_id); +void __cdecl control_check_btn_press(); +void __cdecl DoAutoMap(); +void __cdecl CheckPanelInfo(); +void __cdecl CheckBtnUp(); +void __cdecl FreeControlPan(); +int __fastcall control_WriteStringToBuffer(char *str); +void __cdecl DrawInfoBox(); +void __fastcall control_print_info_str(int y, char *str, int a3, int lines); +void __fastcall PrintGameStr(int x, int y, char *str, int color); +void __cdecl DrawChr(); +void __fastcall ADD_PlrStringXY(int x, int y, int width, char *pszStr, char col); +void __fastcall MY_PlrStringXY(int x, int y, int width, char *pszStr, char col, int base); +void __cdecl CheckLvlBtn(); +void __cdecl ReleaseLvlBtn(); +void __cdecl DrawLevelUpIcon(); +void __cdecl CheckChrBtns(); +void __cdecl ReleaseChrBtns(); +void __cdecl DrawDurIcon(); +int __fastcall DrawDurIcon4Item(ItemStruct *pItem, int x, int c); +void __cdecl RedBack(); +int __fastcall GetSBookTrans(int ii, unsigned char townok); +void __cdecl DrawSpellBook(); +void __fastcall PrintSBookStr(int x, int y, bool cjustflag, char *pszStr, int bright); +void __cdecl CheckSBook(); +char *__fastcall get_pieces_str(int nGold); +void __fastcall DrawGoldSplit(int amount); +void __fastcall control_drop_gold(int a1); +void __fastcall control_remove_gold(int pnum, int gold_index); +void __fastcall control_set_gold_curs(int pnum); +void __cdecl DrawTalkPan(); +void __fastcall control_print_talk_msg(char *msg, int x, int y, int *a4, int just); +int __cdecl control_check_talk_btn(); +void __cdecl control_release_talk_btn(); +void __cdecl control_reset_talk_msg(); +void __cdecl control_type_message(); +void __cdecl control_reset_talk(); +int __fastcall control_talk_last_key(int a1); +int __fastcall control_presskeys(int a1); +void __cdecl control_press_enter(); +void __fastcall control_up_down(char a1); +void __cdecl InitCursor(); +void __cdecl FreeCursor(); +void __fastcall SetICursor(int i); +void __fastcall SetCursor(int i); +void __fastcall NewCursor(int i); +void __cdecl InitLevelCursor(); +void __cdecl CheckTown(); +void __cdecl CheckRportal(); +void __cdecl CheckCursMove(); +void __cdecl InitDead(); +void __fastcall AddDead(int dx, int dy, char dv, direction ddir); +void __cdecl SetDead(); +void __cdecl LoadDebugGFX(); +void __cdecl FreeDebug(); +void __cdecl CheckClearDbg(); +void __cdecl diablo_cpp_init(); +void __cdecl FreeGameMem(); +int __fastcall diablo_init_menu(int a1, int bSinglePlayer); +void __fastcall run_game_loop(int interface_mode); +void __fastcall start_game(int interface_mode); +void __cdecl free_game(); +bool __cdecl diablo_get_not_running(); +int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd); +void __fastcall diablo_parse_flags(char *args); +void __cdecl diablo_init_screen(); +HWND __fastcall diablo_find_window(LPCSTR lpClassName); +void __fastcall diablo_reload_process(HMODULE hModule); +int __cdecl PressEscKey(); +LRESULT __stdcall DisableInputWndProc(HWND hWnd, int uMsg, int wParam, int lParam); +int __stdcall GM_Game(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); +void __cdecl LeftMouseDown(); +int __cdecl TryIconCurs(); +void __cdecl LeftMouseUp(); +void __cdecl RightMouseDown(); +void __fastcall j_gmenu_run_item(LPARAM lParam); +int __fastcall PressSysKey(int wParam); +void __fastcall diablo_hotkey_msg(int dwMsg); +void __fastcall ReleaseKey(int vkey); +void __fastcall PressKey(int vkey); +void __cdecl diablo_pause_game(); +void __fastcall PressChar(int vkey); +void __cdecl LoadLvlGFX(); +void __cdecl LoadAllGFX(); +void __fastcall CreateLevel(int entry); +void __fastcall LoadGameLevel(bool from_save, int entry); +void __fastcall game_loop(bool startup); +void __cdecl game_logic(); +void __fastcall timeout_cursor(bool timeout); +void __cdecl diablo_color_cyc_logic(); +int __cdecl doom_get_frame_from_time(); +void __cdecl doom_alloc_cel(); +void __cdecl doom_cleanup(); +void __cdecl doom_load_graphics(); +void __cdecl doom_init(); +void __cdecl doom_close(); +void __cdecl doom_draw(); +void __cdecl DRLG_Init_Globals(); +void __fastcall LoadL1Dungeon(char *dun_path, int view_x, int view_y); +void __cdecl DRLG_L1Floor(); +void __cdecl DRLG_L1Pass3(); +void __cdecl DRLG_InitL1Vals(); +void __fastcall LoadPreL1Dungeon(char *dun_path, int view_x, int view_y); +void __fastcall CreateL5Dungeon(int seed, int entry); +void __cdecl DRLG_LoadL1SP(); +void __cdecl DRLG_FreeL1SP(); +void __fastcall DRLG_L5(int entry); +void __fastcall DRLG_PlaceDoor(int tx, int ty); +void __cdecl DRLG_L1Shadows(); +int __fastcall DRLG_PlaceMiniSet(char *miniset, int tmin, int tmax, int cx, int cy, bool set_view, int noquad, int ldir); +void __cdecl InitL5Dungeon(); +void __cdecl L5ClearFlags(); +void __cdecl L5firstRoom(); +void __fastcall L5drawRoom(int tx, int ty, int tw, int th); +void __fastcall L5roomGen(int tx, int ty, int tw, int th, bool dir_horiz); +bool __fastcall L5checkRoom(int tx, int ty, int tw, int th); +int __cdecl L5GetArea(); +void __cdecl L5makeDungeon(); +void __cdecl L5makeDmt(); +void __cdecl L5AddWall(); +int __fastcall L5HWallOk(int tx, int ty); +int __fastcall L5VWallOk(int tx, int ty); +void __fastcall L5HorizWall(int tx, int ty, int tile_id, int tw); +void __fastcall L5VertWall(int tx, int ty, int tile_id, int th); +void __cdecl L5tileFix(); +void __cdecl DRLG_L5Subs(); +void __cdecl L5FillChambers(); +void __fastcall DRLG_L5GChamber(int tx, int ty, bool top_right, bool bottom_left, bool top_left, bool bottom_right); +void __fastcall DRLG_L5GHall(int tx_start, int ty_start, int tx_end, int ty_end); +void __fastcall DRLG_L5SetRoom(int tx, int ty); +void __cdecl DRLG_L5FloodTVal(); +void __fastcall DRLG_L5FTVR(int tx, int ty, int x, int y, int direction); +void __cdecl DRLG_L5TransFix(); +void __cdecl DRLG_L5DirtFix(); +void __cdecl DRLG_L5CornerFix(); +void __cdecl InitDungeon(); +void __cdecl L2LockoutFix(); +void __cdecl L2DoorFix(); +void __fastcall LoadL2Dungeon(char *sFileName, int vx, int vy); +void __cdecl DRLG_L2Pass3(); +void __fastcall LoadPreL2Dungeon(char *sFileName, int vx, int vy); +void __fastcall CreateL2Dungeon(int seed, int entry); +void __cdecl DRLG_LoadL2SP(); +void __cdecl DRLG_FreeL2SP(); +void __fastcall DRLG_L2(int entry); +bool __fastcall DRLG_L2PlaceMiniSet(char *miniset, int tmin, int tmax, int cx, int cy, bool set_view, int ldir); +void __fastcall DRLG_L2PlaceRndSet(char *miniset, int probability); +void __cdecl DRLG_L2Subs(); +void __cdecl DRLG_L2Shadows(); +void __fastcall DRLG_L2SetRoom(int rx1, int ry1); +void __cdecl L2TileFix(); +void __cdecl CreateDungeon(); +void __fastcall CreateRoom(int nX1, int nY1, int nX2, int nY2, int nRDest, int nHDir, int ForceHW, int nH, int nW); +void __fastcall DefineRoom(int nX1, int nY1, int nX2, int nY2, int ForceHW); +void __fastcall AddHall(int nX1, int nY1, int nX2, int nY2, int nHd); +void __fastcall GetHall(int *nX1, int *nY1, int *nX2, int *nY2, int *nHd); +void __fastcall ConnectHall(int nX1, int nY1, int nX2, int nY2, int nHd); +void __fastcall CreateDoorType(int nX, int nY); +void __fastcall PlaceHallExt(int nX, int nY); +void __fastcall DoPatternCheck(int i, int j); +void __cdecl DL2_FillVoids(); +int __fastcall DL2_Cont(unsigned char x1f, unsigned char y1f, unsigned char x2f, unsigned char y2f); +int __cdecl DL2_NumNoChar(); +void __fastcall DL2_DrawRoom(int x1, int y1, int x2, int y2); +void __fastcall DL2_KnockWalls(int x1, int y1, int x2, int y2); +void __cdecl DRLG_L2FloodTVal(); +void __fastcall DRLG_L2FTVR(int i, int j, int x, int y, int d); +void __cdecl DRLG_L2TransFix(); +void __cdecl L2DirtFix(); +void __cdecl DRLG_InitL2Vals(); +void __cdecl AddFenceDoors(); +void __cdecl FenceDoorFix(); +void __cdecl DRLG_L3Anvil(); +void __cdecl FixL3Warp(); +void __cdecl FixL3HallofHeroes(); +void __fastcall DRLG_L3LockRec(int x, int y); +void __cdecl DRLG_L3Lockout(); +void __fastcall CreateL3Dungeon(int seed, int entry); +void __fastcall DRLG_L3(int entry); +void __cdecl InitL3Dungeon(); +int __fastcall DRLG_L3FillRoom(int x1, int y1, int x2, int y2); +void __fastcall DRLG_L3CreateBlock(int x, int y, int obs, int dir); +void __fastcall DRLG_L3FloorArea(int x1, int y1, int x2, int y2); +void __cdecl DRLG_L3FillDiags(); +void __cdecl DRLG_L3FillSingles(); +void __cdecl DRLG_L3FillStraights(); +void __cdecl DRLG_L3Edges(); +void __cdecl DRLG_L3GetFloorArea(); +void __cdecl DRLG_L3MakeMegas(); +void __cdecl DRLG_L3River(); +void __cdecl DRLG_L3Pool(); +int __fastcall DRLG_L3SpawnEdge(int x, int y, int *totarea); +int __fastcall DRLG_L3Spawn(int x, int y, int *totarea); +void __cdecl DRLG_L3PoolFix(); +bool __fastcall DRLG_L3PlaceMiniSet(char *miniset, int tmin, int tmax, int cx, int cy, bool set_view, int ldir); +void __fastcall DRLG_L3PlaceRndSet(unsigned char *miniset, int rndper); +void __cdecl DRLG_L3Wood(); +int __fastcall WoodVertU(int i, int y); +int __fastcall WoodVertD(int i, int y); +int __fastcall WoodHorizL(int x, int j); +int __fastcall WoodHorizR(int x, int j); +void __cdecl DRLG_L3Pass3(); +void __fastcall LoadL3Dungeon(char *sFileName, int vx, int vy); +void __fastcall LoadPreL3Dungeon(char *sFileName, int vx, int vy); +void __cdecl DRLG_LoadL4SP(); +void __cdecl DRLG_FreeL4SP(); +void __fastcall DRLG_L4SetSPRoom(int rx1, int ry1); +void __cdecl L4SaveQuads(); +void __fastcall DRLG_L4SetRoom(unsigned char *pSetPiece, int rx1, int ry1); +void __fastcall DRLG_LoadDiabQuads(char preflag); +unsigned char __fastcall IsDURWall(char d); +unsigned char __fastcall IsDLLWall(char dd); +void __cdecl L4FixRim(); +void __cdecl DRLG_L4GeneralFix(); +void __fastcall CreateL4Dungeon(int seed, int entry); +void __fastcall DRLG_L4(int entry); +void __cdecl DRLG_L4Shadows(); +void __cdecl InitL4Dungeon(); +void __cdecl L4makeDmt(); +void __cdecl L4AddWall(); +int __fastcall L4HWallOk(int i, int j); +int __fastcall L4VWallOk(int i, int j); +void __fastcall L4HorizWall(int i, int j, int dx); +void __fastcall L4VertWall(int i, int j, int dy); +void __cdecl L4tileFix(); +void __cdecl DRLG_L4Subs(); +void __cdecl L4makeDungeon(); +void __cdecl uShape(); +int __cdecl GetArea(); +void __cdecl L4firstRoom(); +void __fastcall L4drawRoom(int x, int y, int width, int height); +void __fastcall L4roomGen(int x, int y, int w, int h, int dir); +int __fastcall L4checkRoom(int x, int y, int width, int height); +unsigned char __fastcall DRLG_L4PlaceMiniSet(unsigned char *miniset, int tmin, int tmax, int cx, int cy, int setview, int ldir); +void __cdecl DRLG_L4FloodTVal(); +void __fastcall DRLG_L4FTVR(int i, int j, int x, int y, int d); +void __cdecl DRLG_L4TransFix(); +void __cdecl DRLG_L4Corners(); +void __cdecl DRLG_L4Pass3(); +void __cdecl dthread_cpp_init_1(); +void __cdecl dthread_cpp_init_2(); +void __cdecl dthread_init_mutex(); +void __cdecl dthread_cleanup_mutex_atexit(); +void __cdecl dthread_cleanup_mutex(); +void __fastcall dthread_remove_player(int player_num); +void __fastcall dthread_send_delta(int player_num, int cmd, void *src, int len); +void __cdecl dthread_start(); +unsigned int __stdcall dthread_handler(void *a1); +void __cdecl dthread_cleanup(); +void __cdecl dx_cpp_init_1(); +void __cdecl dx_cpp_init_2(); +void __cdecl dx_init_mutex(); +void __cdecl dx_cleanup_mutex_atexit(); +void __cdecl dx_cleanup_mutex(); +void __fastcall dx_init(HWND hWnd); +void __cdecl dx_create_back_buffer(); +void __cdecl dx_create_primary_surface(); +HRESULT __fastcall dx_DirectDrawCreate(GUID *guid, IDirectDraw **DD, void *unknown); +void __cdecl j_dx_lock_mutex(); +void __cdecl dx_lock_mutex(); +void __cdecl j_dx_unlock_mutex(); +void __cdecl dx_unlock_mutex(); +void __cdecl dx_cleanup(); +void __cdecl dx_reinit(); +void __cdecl j_dx_reinit(); +void __cdecl effects_cpp_init(); +bool __fastcall effect_is_playing(int nSFX); +void __cdecl sfx_stop(); +void __fastcall InitMonsterSND(int monst); +void __cdecl FreeEffects(); +void __fastcall PlayEffect(int i, int mode); +int __fastcall calc_snd_position(int x, int y, int *plVolume, int *plPan); +void __fastcall PlaySFX(int psfx); +void __fastcall PlaySFX_priv(TSFX *pSFX, char loc, int x, int y); +void __fastcall stream_play(TSFX *pSFX, int lVolume, int lPan); +int __fastcall RndSFX(int psfx); +void __fastcall PlaySfxLoc(int psfx, int x, int y); +void __cdecl FreeMonsterSnd(); +void __cdecl sound_stop(); +void __cdecl sound_update(); +void __cdecl effects_cleanup_sfx(); +void __cdecl stream_update(); +void __fastcall priv_sound_init(int bLoadMask); +void __cdecl sound_init(); +void __stdcall effects_play_sound(char *snd_file); +void __fastcall encrypt_decrypt_block(void *block, int size, int key); +void __fastcall encrypt_encrypt_block(void *block, int size, int key); +int __fastcall encrypt_hash(char *s, int type); +void __cdecl encrypt_init_lookup_table(); +int __fastcall encrypt_compress(void *buf, int size); +int __cdecl encrypt_pkware_read(void *buf, int *size, void *param); +int __cdecl encrypt_pkware_write(void *buf, int *size, void *param); +void __fastcall encrypt_decompress(void *param, int a2, int size); +void __cdecl engine_cpp_init_1(); +void __fastcall Cel_content_into_buf(char *pDecodeTo, char *pRLEBytes, int dwRLESize, int dwRLEWdt); +void __fastcall Cel_decode(int screen_x, int screen_y, void *pCelBuff, int frame, int frame_width); +void __fastcall Cel_into_buf(char *pBuff, char *pCelBuff, int frame, int frame_width); +void __fastcall Cel_header(int screen_x, int screen_y, char *pCelBuff, int frame, int frame_width, int always_0, int direction); +void __fastcall Cel_header_into_buf(char *pBuff, char *pCelBuff, int frame, int frame_width, int always_0, int direction); +void __fastcall Cel_content_light_into_buf(char *pDecodeTo, char *pRLEBytes, int frame_content_size, int frame_width); +void __fastcall Cel_content_light_entry_into_buf(int a1, int a2); +void __fastcall Cel_content_light_trans_into_buf(char *pDecodeTo, char *pRLEBytes, int frame_content_size, int frame_width); +void __fastcall Cel_light(int screen_x, int screen_y, char *pCelBuff, int frame, int frame_width); +void __fastcall Cel_header_and_light(int screen_x, int screen_y, char *pCelBuff, int frame, int frame_width, int always_0, int direction); +void __fastcall Cel_header_light_and_trans_into_buf(char *pBuff, char *pCelBuff, int frame, int frame_width, int always_0, int direction); +void __fastcall Cel_header_and_light_not_equipable(int screen_x, int screen_y, char *pCelBuff, int frame, int frame_width, int always_0, int direction, char always_1); +void __fastcall Cel2_content_into_buf(char *pDecodeTo, char *pRLEBytes, int frame_content_size, int frame_width); +void __fastcall Cel2_header(int screen_x, int screen_y, char *pCelBuff, int frame, int frame_width, int a6, int direction); +void __fastcall Cel2_header_into_buf(char *pBuff, char *pCelBuff, int frame, int frame_width, int a5, int direction); +void __fastcall Cel2_content_light_into_buf(char *pDecodeTo, char *pRLEBytes, int frame_content_size, int frame_width); +void __fastcall Cel2_content_light_entry_into_buf(int a1, int a2); +void __fastcall Cel2_content_light_trans_into_buf(char *pDecodeTo, char *pRLEBytes, int frame_content_size, int frame_width); +void __fastcall Cel2_header_and_light(int screen_x, int screen_y, char *pCelBuff, int frame, int frame_width, int a6, int direction); +void __fastcall Cel2_header_light_and_trans_into_buf(char *dst_buf, char *pCelBuff, int frame, int frame_width, int a5, int direction); +void __fastcall Cel2_header_and_light_not_equipable(int screen_x, int screen_y, char *pCelBuff, int frame, int frame_width, int always_0, int direction, char always_1); +void __fastcall Cel_into_rect_of_buf(char *pBuff, int always_0, int dst_height, int dst_width, char *pCelBuff, int frame, int frame_width); +void __fastcall Cel_colour(char colour, int screen_x, int screen_y, char *pCelBuff, int frame, int frame_width, int a7, int direction); +void __fastcall Cel_header_and_colour_highlight(char colour, int screen_x, int screen_y, char *pCelBuff, int frame, int frame_width, int a7, int direction); +void __fastcall ENG_set_pixel(int screen_x, int screen_y, char pixel); +void __fastcall engine_417034(int x, int y); +void __fastcall engine_4170BD(int x1, int y1, int x2, int y2, char a5); +int __fastcall GetDirection(int x1, int y1, int x2, int y2); +void __fastcall SetRndSeed(int s); +int __cdecl GetRndSeed(); +int __fastcall random(int unused, int max); +void __cdecl engine_cpp_init_2(); +void __cdecl mem_init_mutex(); +void __cdecl mem_atexit_mutex(); +void __cdecl mem_free_mutex(); +void *__fastcall DiabloAllocPtr(int size); +void __fastcall mem_free_dbg(void *ptr); +unsigned char *__fastcall LoadFileInMem(char *file_path, void *size); +void __fastcall LoadFileWithMem(char *pszName, void *buf); +void __fastcall engine_cel_trn(int p, int ttbl, int a3); +void __fastcall engine_417745(int a1, int a2, void *pCelBuff, int nCel, int a5, int a6, int a7); +void __fastcall engine_4177BF(char *buffer, char *a2, int a3, int a4); +void __fastcall engine_417847(char a1, int a2, int a3, void *pCelBuff, int nCel, int a6, int a7, int a8); +void __fastcall engine_4178C5(char *buffer, char *a2, char *a3, int a4, char a5); +void __fastcall engine_417981(int a1, int a2, void *pCelBuff, int nCel, int a5, int a6, int a7, char a8); +void __fastcall engine_417A44(char *a1, char *a2, int a3, int a4, int unused_lindex); +void __fastcall engine_417AE9(int a1, int a2, void *pCelBuff, int nCel, int a5, int a6, int a7); +void __fastcall engine_417B83(int a1, int a2, void *pCelBuff, int nCel, int a5, int a6, int a7); +void __fastcall engine_417BFD(char *a1, char *a2, int a3, int a4); +void __fastcall engine_417C99(char a1, int a2, int a3, void *pCelBuff, int nCel, int a6, int a7, int a8); +void __fastcall engine_417D28(char *a1, char *a2, int a3, int a4, char a5); +void __fastcall engine_417DF8(int a1, int a2, void *pCelBuff, int nCel, int a5, int a6, int a7, char a8); +void __fastcall engine_417EBB(char *a1, char *a2, int a3, int a4, int a5); +void __fastcall engine_417F78(int a1, int a2, void *pCelBuff, int nCel, int a5, int a6, int a7); +void __fastcall PlayInGameMovie(char *pszMovie); +void __fastcall InitDiabloMsg(int error_id); +void __cdecl ClrDiabloMsg(); +void __cdecl DrawDiabloMsg(); +void __cdecl exception_cpp_init(); +int *__cdecl exception_install_filter(); +void __cdecl j_exception_init_filter(); +void __cdecl exception_init_filter(); +LONG __fastcall TopLevelExceptionFilter(struct _EXCEPTION_POINTERS *ExceptionInfo); +int __fastcall exception_hex_format(char *a1, char a2); +int __fastcall exception_unknown_module(LPCVOID lpAddress, LPSTR lpString1, int iMaxLength, int a4, int a5); +void __fastcall exception_call_stack(void *a1, LPVOID lp); +int __fastcall exception_get_error_type(DWORD dwMessageId, LPSTR lpString1, DWORD nSize); +void __fastcall exception_set_filter(); +LPTOP_LEVEL_EXCEPTION_FILTER __cdecl exception_set_filter_ptr(); +LPTOP_LEVEL_EXCEPTION_FILTER __cdecl exception_get_filter(); +void __cdecl gamemenu_previous(); +void __cdecl gamemenu_enable_single(); +void __cdecl gamemenu_enable_multi(); +void __cdecl gamemenu_off(); +void __cdecl gamemenu_handle_previous(); +void __cdecl gamemenu_new_game(); +void __cdecl gamemenu_quit_game(); +void __cdecl gamemenu_load_game(); +void __cdecl gamemenu_save_game(); +void __cdecl gamemenu_restart_town(); +void __cdecl gamemenu_options(); +void __cdecl gamemenu_get_music(); +void __fastcall gamemenu_sound_music_toggle(char **names, TMenuItem *menu_item); +void __cdecl gamemenu_get_sound(); +void __cdecl gamemenu_get_color_cycling(); +void __cdecl gamemenu_get_gamma(); +void __cdecl gamemenu_music_volume(); +int __fastcall gamemenu_slider_music_sound(TMenuItem *menu_item); +void __cdecl gamemenu_sound_volume(); +void __cdecl gamemenu_gamma(); +int __cdecl gamemenu_slider_gamma(); +void __cdecl gamemenu_color_cycling(); +void __cdecl FillSolidBlockTbls(); +void __cdecl gendung_418D91(); +void __fastcall gendung_4191BF(int frames); +void __fastcall gendung_4191FB(int a1, int a2); +int __fastcall gendung_41927A(int x, int y); +void __cdecl gendung_4192C2(); +void __cdecl SetDungeonMicros(); +void __cdecl DRLG_InitTrans(); +void __fastcall Make_RectTrans(int tx_start, int ty_start, int tx_end, int ty_end); +void __fastcall DRLG_RectTrans(int x_start, int y_start, int x_end, int y_end); +void __fastcall DRLG_CopyTrans(int src_x, int src_y, int dst_x, int dst_y); +void __fastcall DRLG_ListTrans(int num, unsigned char *List); +void __fastcall DRLG_AreaTrans(int num, unsigned char *List); +void __cdecl DRLG_InitSetPC(); +void __cdecl DRLG_SetPC(); +void __fastcall Make_SetPC(int x, int y, int w, int h); +unsigned char __fastcall DRLG_WillThemeRoomFit(int floor, int x, int y, int minSize, int maxSize, int *width, int *height); +void __fastcall DRLG_CreateThemeRoom(int themeIndex); +void __fastcall DRLG_PlaceThemeRooms(int min_size, int max_size, int floor, int frequency, int rnd_size); +void __cdecl DRLG_HoldThemeRooms(); +unsigned char __fastcall SkipThemeRoom(int x, int y); +void __cdecl InitLevels(); +void __cdecl gmenu_draw_pause(); +int __fastcall gmenu_print_text(int x, int y, char *str); +void __cdecl FreeGMenu(); +void __cdecl gmenu_init_menu(); +bool __cdecl gmenu_exception(); +void __fastcall gmenu_call_proc(int a1, void (__cdecl *gmFunc)()); +void __fastcall gmenu_up_down(int a1); +void __cdecl gmenu_draw(); +void __fastcall gmenu_spinners(int a1, int a2); +void __fastcall gmenu_clear_buffer(int x, int y, int size, int a4); +int __fastcall gmenu_get_lfont(int a1); +int __fastcall gmenu_presskeys(int a1); +void __fastcall gmenu_left_right(int a1); +int __fastcall gmenu_run_item(LPARAM lParam); +char __fastcall gmenu_valid_mouse_pos(int a1); +int __fastcall gmenu_left_mouse(int a1); +void __fastcall gmenu_enable(TMenuItem *menu_item, bool enable); +int __fastcall gmenu_slider_1(int *a1, int min, int max, int gamma); +int __fastcall gmenu_slider_get(TMenuItem *menu_item, int min, int max); +void __fastcall gmenu_slider_3(int *a1, int a2); +void __cdecl InitHelp(); +void __cdecl DrawHelp(); +void __fastcall DrawHelpLine(int always_0, int help_line_nr, char *text, text_color color); +void __cdecl DisplayHelp(); +void __cdecl HelpScrollUp(); +void __cdecl HelpScrollDown(); +void __cdecl init_cpp_init(); +void __fastcall init_cleanup(bool show_cursor); +void __cdecl init_run_office_from_start_menu(); +void __fastcall init_run_office(char *dir); +void __fastcall init_disable_screensaver(bool disable); +void __cdecl init_create_window(); +void __cdecl init_kill_mom_parent(); +HWND __cdecl init_find_mom_parent(); +void __cdecl init_await_mom_parent_exit(); +void __cdecl init_archives(); +void *__fastcall init_test_access(char *mpq_path, char *mpq_name, char *reg_loc, int flags, bool on_cd); +char *__fastcall init_strip_trailing_slash(char *path); +int __fastcall init_read_test_file(char *mpq_path, char *mpq_name, int flags, void **archive); +void __cdecl init_get_file_info(); +LRESULT __stdcall init_palette(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); +void __fastcall init_activate_window(HWND hWnd, bool activated); +LRESULT __stdcall init_redraw_window(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); +LRESULT (__stdcall *__fastcall SetWindowProc(void *func))(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); +void __cdecl interfac_cpp_init(); +void __cdecl interface_msg_pump(); +bool __cdecl IncProgress(); +void __cdecl DrawCutscene(); +void __fastcall DrawProgress(int screen_x, int screen_y, int progress_id); +void __fastcall ShowProgress(int uMsg); +void __cdecl FreeInterface(); +void __fastcall InitCutscene(int interface_mode); +void __cdecl FreeInvGFX(); +void __cdecl InitInv(); +void __fastcall InvDrawSlotBack(int X, int Y, int W, int H); +void __cdecl DrawInv(); +void __cdecl DrawInvBelt(); +int __fastcall AutoPlace(int pnum, int ii, int sx, int sy, int saveflag); +int __fastcall SpecialAutoPlace(int pnum, int ii, int sx, int sy, int saveflag); +int __fastcall GoldAutoPlace(int pnum); +int __fastcall WeaponAutoPlace(int pnum); +int __fastcall SwapItem(ItemStruct *a, ItemStruct *b); +void __fastcall CheckInvPaste(int pnum, int mx, int my); +void __fastcall CheckInvSwap(int pnum, int bLoc, int idx, int wCI, int seed, int bId); +void __fastcall CheckInvCut(int pnum, int mx, int my); +void __fastcall inv_update_rem_item(int pnum, int iv); +void __fastcall RemoveInvItem(int pnum, int iv); +void __fastcall RemoveSpdBarItem(int pnum, int iv); +void __cdecl CheckInvItem(); +void __cdecl CheckInvScrn(); +void __fastcall CheckItemStats(int pnum); +void __fastcall CheckBookLevel(int pnum); +void __fastcall CheckQuestItem(int pnum); +void __fastcall InvGetItem(int pnum, int ii); +void __fastcall AutoGetItem(int pnum, int ii); +void __fastcall FindGetItem(int indx, int ci, int iseed); +void __fastcall SyncGetItem(int x, int y, int idx, unsigned short ci, int iseed); +int __fastcall CanPut(int i, int j); +int __cdecl TryInvPut(); +void __fastcall DupeInvMsg(char *msg); +int __fastcall InvPutItem(int pnum, int x, int y); +int __fastcall SyncPutItem(int pnum, int x, int y, int idx, int icreateinfo, int iseed, int Id, int dur, int mdur, int ch, int mch, int ivalue, unsigned __int32 ibuff); +int __cdecl CheckInvHLight(); +void __fastcall RemoveScroll(int pnum); +void __cdecl UseScroll(); +void __fastcall UseStaffCharge(int pnum); +void __cdecl UseStaff(); +void __cdecl StartGoldDrop(); +int __fastcall UseInvItem(int pnum, int cii); +void __cdecl DoTelekinesis(); +int __fastcall CalculateGold(int pnum); +int __cdecl DropItemBeforeTrig(); +void __cdecl InitItemGFX(); +bool __fastcall ItemPlace(int x, int y); +void __cdecl AddInitItems(); +void __cdecl InitItems(); +void __fastcall CalcPlrItemVals(int player_num, bool load_gfx); +void __fastcall CalcPlrScrolls(int p); +void __fastcall CalcPlrStaff(int pnum); +void __fastcall CalcSelfItems(int pnum); +void __fastcall CalcPlrItemMin(int pnum); +unsigned char __fastcall ItemMinStats(PlayerStruct *p, ItemStruct *x); +void __fastcall CalcPlrBookVals(int p); +void __fastcall CalcPlrInv(int p, unsigned char Loadgfx); +void __fastcall SetPlrHandItem(ItemStruct *item, int item_id); +void __fastcall GetPlrHandSeed(ItemStruct *item); +void __fastcall GetGoldSeed(int player_num, int *item_seed); +void __fastcall SetPlrHandSeed(ItemStruct *h, int iseed); +void __fastcall SetPlrHandGoldCurs(ItemStruct *h); +void __fastcall CreatePlrItems(int player_num); +unsigned char __fastcall ItemSpaceOk(int i, int j); +unsigned char __fastcall GetItemSpace(int x, int y, char inum); +void __fastcall GetSuperItemSpace(int x, int y, char inum); +void __fastcall GetSuperItemLoc(int x, int y, int *xx, int *yy); +void __fastcall CalcItemValue(int i); +void __fastcall GetBookSpell(int i, int lvl); +void __fastcall GetStaffPower(int i, int lvl, int bs, unsigned char onlygood); +void __fastcall GetStaffSpell(int i, int lvl, unsigned char onlygood); +void __fastcall GetItemAttrs(int i, int idata, int lvl); +int __fastcall RndPL(int param1, int param2); +int __fastcall PLVal(int pv, int p1, int p2, int minv, int maxv); +void __fastcall SaveItemPower(int i, int power, int param1, int param2, int minval, int maxval, int multval); +void __fastcall GetItemPower(int i, int minlvl, int maxlvl, __int32 flgs, int onlygood); +void __fastcall GetItemBonus(int i, int idata, int minlvl, int maxlvl, int onlygood); +void __fastcall SetupItem(int i); +int __fastcall RndItem(int monster_num); +int __fastcall RndUItem(int m); +int __cdecl RndAllItems(); +int __fastcall RndTypeItems(int itype, int imid); +void __fastcall GetUniqueItem(int i, int uid); +void __fastcall SpawnUnique(int uid, int x, int y); +int __fastcall CheckUnique(int i, int lvl, int uper, unsigned char recreate); +void __fastcall ItemRndDur(int ii); +void __fastcall SetupAllItems(int ii, int idx, int iseed, int lvl, int uper, int onlygood, int recreate, int pregen); +void __fastcall SpawnItem(int m, int x, int y, unsigned char sendmsg); +void __fastcall CreateItem(int uid, int x, int y); +void __fastcall CreateRndItem(int x, int y, unsigned char onlygood, unsigned char sendmsg, int delta); +void __fastcall SetupAllUseful(int ii, int iseed, int lvl); +void __fastcall CreateRndUseful(int pnum, int x, int y, unsigned char sendmsg); +void __fastcall CreateTypeItem(int x, int y, unsigned char onlygood, int itype, int imisc, int sendmsg, int delta); +void __fastcall TempItemGeneration(int ii, int idx, int wCI, int seed, int value); +void __fastcall RecreateEar(int ii, unsigned short ic, int iseed, unsigned char Id, int dur, int mdur, int ch, int mch, int ivalue, int ibuff); +void __fastcall SpawnQuestItem(int itemid, int x, int y, int randarea, int selflag); +void __cdecl SpawnRock(); +void __fastcall RespawnItem(int i, unsigned char FlipFlag); +void __fastcall DeleteItem(int ii, int i); +void __cdecl ItemDoppel(); +void __cdecl ProcessItems(); +void __cdecl FreeItemGFX(); +void __fastcall items_get_drop_cel(int i); +void __fastcall GetItemStr(int i); +void __fastcall CheckIdentify(int pnum, int cii); +void __fastcall DoRepair(int pnum, int cii); +void __fastcall RepairItem(ItemStruct *i, int lvl); +void __fastcall DoRecharge(int pnum, int cii); +void __fastcall RechargeItem(ItemStruct *i, int r); +void __fastcall PrintItemOil(char IDidx); +void __fastcall PrintItemPower(char plidx, ItemStruct *x); +void __cdecl items_unique_info_cel(); +void __fastcall PrintUString(int x, int y, int cjustflag, char *str, int col); +void __fastcall items_unique_info_box(int y); +void __cdecl DrawUniqueInfo(); +void __fastcall PrintItemMisc(ItemStruct *x); +void __fastcall PrintItemDetails(ItemStruct *x); +void __fastcall PrintItemDur(ItemStruct *x); +void __fastcall UseItem(int p, int Mid, int spl); +bool __fastcall StoreStatOk(ItemStruct *h); +int __fastcall SmithItemOk(int i); +int __fastcall RndSmithItem(int lvl); +void __fastcall BubbleSwapItem(ItemStruct *a, ItemStruct *b); +void __cdecl SortSmith(); +void __fastcall SpawnSmith(int lvl); +int __fastcall PremiumItemOk(int i); +int __fastcall RndPremiumItem(int minlvl, int maxlvl); +void __fastcall SpawnOnePremium(int i, int plvl); +void __fastcall SpawnPremium(int lvl); +int __fastcall WitchItemOk(int i); +int __fastcall RndWitchItem(int lvl); +void __cdecl SortWitch(); +void __fastcall WitchBookLevel(int ii); +void __fastcall SpawnWitch(int lvl); +int __fastcall RndBoyItem(int lvl); +void __fastcall SpawnBoy(int lvl); +int __fastcall HealerItemOk(int i); +int __fastcall RndHealerItem(int lvl); +void __cdecl SortHealer(); +void __fastcall SpawnHealer(int lvl); +void __cdecl SpawnStoreGold(); +void __fastcall RecreateSmithItem(int ii, int idx, int plvl, int iseed); +void __fastcall RecreatePremiumItem(int ii, int idx, int lvl, int iseed); +void __fastcall RecreateBoyItem(int ii, int idx, int lvl, int iseed); +void __fastcall RecreateWitchItem(int ii, int idx, int lvl, int iseed); +void __fastcall RecreateHealerItem(int ii, int idx, int lvl, int iseed); +void __fastcall RecreateTownItem(int ii, int idx, unsigned short icreateinfo, int iseed, int ivalue); +void __cdecl RecalcStoreStats(); +void __cdecl ItemNoFlippy(); +void __fastcall CreateSpellBook(int x, int y, int ispell, unsigned char sendmsg, int delta); +void __fastcall CreateMagicItem(int x, int y, int imisc, int icurs, int sendmsg, int delta); +int __fastcall GetItemRecord(int dwSeed, int CI, int indx); +void __fastcall NextItemRecord(int a1); +void __fastcall SetItemRecord(int dwSeed, int CI, int indx); +void __fastcall PutItemRecord(int seed, int ci, int index); +void __fastcall SetLightFX(int x, int y, short s_r, short s_g, int s_b, int d_r, int d_g, int d_b); +void __fastcall DoLighting(int nXPos, int nYPos, int nRadius, int Lnum); +void __fastcall DoUnLight(int nXPos, int nYPos, int nRadius); +void __fastcall DoUnVision(int nXPos, int nYPos, int nRadius); +void __fastcall DoVision(int nXPos, int nYPos, int nRadius, unsigned char doautomap, int visible); +void __cdecl FreeLightTable(); +void __cdecl InitLightTable(); +void __cdecl MakeLightTable(); +void __cdecl InitLightMax(); +void __cdecl InitLighting(); +int __fastcall AddLight(int x, int y, int r); +void __fastcall AddUnLight(int i); +void __fastcall ChangeLightRadius(int i, int r); +void __fastcall ChangeLightXY(int i, int x, int y); +void __fastcall ChangeLightOff(int i, int x, int y); +void __fastcall ChangeLight(int i, int x, int y, int r); +void __cdecl ProcessLightList(); +void __cdecl SavePreLighting(); +void __cdecl InitVision(); +int __fastcall AddVision(int x, int y, int r, unsigned char mine); +void __fastcall ChangeVisionRadius(int id, int r); +void __fastcall ChangeVisionXY(int id, int x, int y); +void __cdecl ProcessVisionList(); +void __cdecl lighting_color_cycling(); +void __fastcall LoadGame(void *a1); +char __cdecl BLoad(); +int __cdecl ILoad(); +int __cdecl ILoad_2(); +bool __cdecl OLoad(); +void __fastcall LoadPlayer(int player_num); +void __fastcall LoadMonster(int monster_num); +void __fastcall LoadMissile(int missile_num); +void __fastcall LoadObject(int object_num); +void __fastcall LoadItem(int item_num); +void __fastcall LoadPremium(int griswold_premium_item_num); +void __fastcall LoadQuest(int i); +void __fastcall LoadLighting(int light_num); +void __fastcall LoadVision(int vision_num); +void __fastcall LoadPortal(int portal_num); +void __cdecl SaveGame(); +void __fastcall BSave(char v); +void __fastcall ISave(int v); +void __fastcall ISave_2(int v); +void __fastcall OSave(unsigned char v); +void __fastcall SavePlayer(int i); +void __fastcall SaveMonster(int i); +void __fastcall SaveMissile(int i); +void __fastcall SaveObject(int i); +void __fastcall SaveItem(int i); +void __fastcall SavePremium(int i); +void __fastcall SaveQuest(int i); +void __fastcall SaveLighting(int i); +void __fastcall SaveVision(int i); +void __fastcall SavePortal(int i); +void __cdecl SaveLevel(); +void __cdecl LoadLevel(); +void __cdecl log_cpp_init_1(); +void __cdecl log_cpp_init_2(); +void __cdecl log_init_mutex(); +void __cdecl j_log_cleanup_mutex(); +void __cdecl log_cleanup_mutex(); +void __cdecl log_flush(bool force_close); +void *__cdecl log_create(); +void __fastcall log_get_version(VS_FIXEDFILEINFO *file_info); +void log_printf(char *format, ...); +void __cdecl log_dump_computer_info(); +void __cdecl mainmenu_cpp_init(); +void __cdecl mainmenu_refresh_music(); +void __stdcall mainmenu_create_hero(char *, char *); +int __stdcall mainmenu_select_hero_dialog(int u1, int u2, int u3, int u4, int mode, char *cname, int clen, char *cdesc, int cdlen, int *multi); +void __fastcall mainmenu_action(int option); +int __cdecl mainmenu_single_player(); +int __fastcall mainmenu_init_menu(int a1); +void __cdecl mainmenu_multi_player(); +void __cdecl mainmenu_play_intro(); +void __cdecl FreeQuestText(); +void __cdecl InitQuestText(); +void __fastcall InitQTextMsg(int m); +void __cdecl DrawQTextBack(); +void __fastcall PrintQTextChr(int screen_x, int screen_y, char *cel_buf, int frame); +void __cdecl DrawQText(); +void __fastcall GetDamageAmt(int i, int *mind, int *maxd); +int __fastcall CheckBlock(int fx, int fy, int tx, int ty); +int __fastcall FindClosest(int sx, int sy, int rad); +int __fastcall GetSpellLevel(int id, int sn); +int __fastcall GetDirection8(int x1, int y1, int x2, int y2); +int __fastcall GetDirection16(int x1, int y1, int x2, int y2); +void __fastcall DeleteMissile(int mi, int i); +void __fastcall GetMissileVel(int i, int sx, int sy, int dx, int dy, int v); +void __fastcall PutMissile(int i); +void __fastcall GetMissilePos(int i); +void __fastcall MoveMissilePos(int i); +unsigned char __fastcall MonsterTrapHit(int m, int mindam, int maxdam, int dist, int t, int shift); +unsigned char __fastcall MonsterMHit(int pnum, int m, int mindam, int maxdam, int dist, int t, int shift); +unsigned char __fastcall PlayerMHit(int pnum, int m, int dist, int mind, int maxd, int mtype, int shift, int earflag); +unsigned char __fastcall Plr2PlrMHit(int pnum, int p, int mindam, int maxdam, int dist, int mtype, int shift); +void __fastcall CheckMissileCol(int i, int mindam, int maxdam, unsigned char shift, int mx, int my, int nodel, bool HurtPlr); +void __fastcall SetMissAnim(int mi, int animtype); +void __fastcall SetMissDir(int mi, int dir); +void __fastcall LoadMissileGFX(int mi); +void __cdecl InitMissileGFX(); +void __fastcall FreeMissileGFX(int mi); +void __cdecl FreeMissiles(); +void __cdecl FreeMissiles2(); +void __cdecl InitMissiles(); +void __fastcall AddLArrow(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam); +void __fastcall AddArrow(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam); +void __fastcall GetVileMissPos(int mi, int dx, int dy); +void __fastcall AddRndTeleport(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam); +void __fastcall AddFirebolt(int mi, int sx, int sy, int dx, int dy, int midir, int micaster, int id, int dam); +void __fastcall AddMagmaball(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam); +void __fastcall miss_null_33(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam); +void __fastcall AddTeleport(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam); +void __fastcall AddLightball(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam); +void __fastcall AddFirewall(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam); +void __fastcall AddFireball(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam); +void __fastcall AddLightctrl(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam); +void __fastcall AddLightning(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam); +void __fastcall AddMisexp(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam); +void __fastcall AddWeapexp(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam); +unsigned char __fastcall CheckIfTrig(int x, int y); +void __fastcall AddTown(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam); +void __fastcall AddFlash(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam); +void __fastcall AddFlash2(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam); +void __fastcall AddManashield(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam); +void __fastcall AddFiremove(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam); +void __fastcall AddGuardian(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam); +void __fastcall AddChain(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam); +void __fastcall miss_null_11(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam); +void __fastcall miss_null_12(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam); +void __fastcall miss_null_13(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam); +void __fastcall AddRhino(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam); +void __fastcall miss_null_32(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam); +void __fastcall AddFlare(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam); +void __fastcall AddAcid(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam); +void __fastcall miss_null_1D(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam); +void __fastcall AddAcidpud(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam); +void __fastcall AddStone(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam); +void __fastcall AddGolem(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam); +void __fastcall AddEtherealize(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam); +void __fastcall miss_null_1F(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam); +void __fastcall miss_null_23(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam); +void __fastcall AddBoom(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam); +void __fastcall AddHeal(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam); +void __fastcall AddHealOther(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam); +void __fastcall AddElement(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam); +void __fastcall AddIdentify(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam); +void __fastcall AddFirewallC(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam); +void __fastcall AddInfra(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam); +void __fastcall AddWave(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam); +void __fastcall AddNova(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam); +void __fastcall AddRepair(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam); +void __fastcall AddRecharge(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam); +void __fastcall AddDisarm(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam); +void __fastcall AddApoca(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam); +void __fastcall AddFlame(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam); +void __fastcall AddFlamec(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam); +void __fastcall AddCbolt(int mi, int sx, int sy, int dx, int dy, int midir, int micaster, int id, int dam); +void __fastcall AddHbolt(int mi, int sx, int sy, int dx, int dy, int midir, int micaster, int id, int dam); +void __fastcall AddResurrect(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam); +void __fastcall AddResurrectBeam(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam); +void __fastcall AddTelekinesis(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam); +void __fastcall AddBoneSpirit(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam); +void __fastcall AddRportal(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam); +void __fastcall AddDiabApoca(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam); +int __fastcall AddMissile(int sx, int sy, int v1, int v2, int midir, int mitype, int micaster, int id, int v3, int spllvl); +int __fastcall Sentfire(int i, int sx, int sy); +void __fastcall MI_Dummy(int i); +void __fastcall MI_Golem(int i); +void __fastcall MI_SetManashield(int i); +void __fastcall MI_LArrow(int i); +void __fastcall MI_Arrow(int i); +void __fastcall MI_Firebolt(int i); +void __fastcall MI_Lightball(int i); +void __fastcall mi_null_33(int i); +void __fastcall MI_Acidpud(int i); +void __fastcall MI_Firewall(int i); +void __fastcall MI_Fireball(int i); +void __fastcall MI_Lightctrl(int i); +void __fastcall MI_Lightning(int i); +void __fastcall MI_Town(int i); +void __fastcall MI_Flash(int i); +void __fastcall MI_Flash2(int i); +void __fastcall MI_Manashield(int i); +void __fastcall MI_Etherealize(int i); +void __fastcall MI_Firemove(int i); +void __fastcall MI_Guardian(int i); +void __fastcall MI_Chain(int i); +void __fastcall mi_null_11(int i); +void __fastcall MI_Weapexp(int i); +void __fastcall MI_Misexp(int i); +void __fastcall MI_Acidsplat(int i); +void __fastcall MI_Teleport(int i); +void __fastcall MI_Stone(int i); +void __fastcall MI_Boom(int i); +void __fastcall MI_Rhino(int i); +void __fastcall mi_null_32(int i); +void __fastcall MI_FirewallC(int i); +void __fastcall MI_Infra(int i); +void __fastcall MI_Apoca(int i); +void __fastcall MI_Wave(int i); +void __fastcall MI_Nova(int i); +void __fastcall MI_Blodboil(int i); +void __fastcall MI_Flame(int i); +void __fastcall MI_Flamec(int i); +void __fastcall MI_Cbolt(int i); +void __fastcall MI_Hbolt(int i); +void __fastcall MI_Element(int i); +void __fastcall MI_Bonespirit(int i); +void __fastcall MI_ResurrectBeam(int i); +void __fastcall MI_Rportal(int i); +void __cdecl ProcessMissiles(); +void __cdecl missiles_process_charge(); +void __fastcall ClearMissileSpot(int i); +void __cdecl monster_cpp_init(); +void __fastcall monster_init_special(int mon_id, int special); +void __cdecl InitLevelMonsters(); +int __fastcall AddMonsterType(int type, int placeflag); +void __cdecl GetLevelMTypes(); +void __fastcall InitMonsterGFX(int monst); +void __fastcall ClearMVars(int i); +void __fastcall InitMonster(int i, int rd, int mtype, int x, int y); +void __cdecl ClrAllMonsters(); +int __fastcall MonstPlace(int xp, int yp); +void __fastcall PlaceMonster(int i, int mtype, int x, int y); +void __fastcall PlaceUniqueMonst(int uniqindex, int miniontype, int unpackfilesize); +void __cdecl PlaceQuestMonsters(); +void __fastcall PlaceGroup(int mtype, int num, unsigned char leaderf, int leader); +void __cdecl LoadDiabMonsts(); +void __cdecl InitMonsters(); +void __cdecl PlaceUniques(); +void __fastcall SetMapMonsters(char *pMap, int startx, int starty); +void __fastcall DeleteMonster(int i); +int __fastcall AddMonster(int x, int y, int dir, int mtype, int InMap); +void __fastcall NewMonsterAnim(int i, AnimStruct *anim, int md); +int __fastcall M_Ranged(int i); +int __fastcall M_Talker(int i); +void __fastcall M_Enemy(int i); +int __fastcall M_GetDir(int i); +void __fastcall M_CheckEFlag(int i); +void __fastcall M_StartStand(int i, int md); +void __fastcall M_StartDelay(int i, int len); +void __fastcall M_StartSpStand(int i, int md); +void __fastcall M_StartWalk(int i, int xvel, int yvel, int xadd, int yadd, int EndDir); +void __fastcall M_StartWalk2(int i, int xvel, int yvel, int a4, int a5, int a6, int a7, int EndDir); +void __fastcall M_StartWalk3(int i, int xvel, int yvel, int a4, int a5, int a6, int a7, int a8, int a9, int EndDir); +void __fastcall M_StartAttack(int i); +void __fastcall M_StartRAttack(int i, int missile_type, int dam); +void __fastcall M_StartRSpAttack(int i, int missile_type, int dam); +void __fastcall M_StartSpAttack(int i); +void __fastcall M_StartEat(int i); +void __fastcall M_ClearSquares(int i); +void __fastcall M_GetKnockback(int i); +void __fastcall M_StartHit(int i, int pnum, int dam); +void __fastcall M_DiabloDeath(int i, unsigned char sendmsg); +void __fastcall M2MStartHit(int mid, int i, int dam); +void __fastcall MonstStartKill(int i, int pnum, unsigned char sendmsg); +void __fastcall M2MStartKill(int i, int mid); +void __fastcall M_StartKill(int i, int pnum); +void __fastcall M_SyncStartKill(int i, int x, int y, int pnum); +void __fastcall M_StartFadein(int i, int md, unsigned char backwards); +void __fastcall M_StartFadeout(int i, int md, unsigned char backwards); +void __fastcall M_StartHeal(int i); +void __fastcall M_ChangeLightOffset(int monst); +int __fastcall M_DoStand(int i); +int __fastcall M_DoWalk(int i); +int __fastcall M_DoWalk2(int i); +int __fastcall M_DoWalk3(int i); +void __fastcall M_TryM2MHit(int i, int mid, int hper, int mind, int maxd); +void __fastcall M_TryH2HHit(int i, int pnum, int Hit, int MinDam, int MaxDam); +int __fastcall M_DoAttack(int i); +int __fastcall M_DoRAttack(int i); +int __fastcall M_DoRSpAttack(int i); +int __fastcall M_DoSAttack(int i); +int __fastcall M_DoFadein(int i); +int __fastcall M_DoFadeout(int i); +int __fastcall M_DoHeal(int i); +int __fastcall M_DoTalk(int i); +void __fastcall M_Teleport(int i); +int __fastcall M_DoGotHit(int i); +int __fastcall M_UpdateLeader(int i); +void __cdecl DoEnding(); +void __cdecl PrepDoEnding(); +int __fastcall M_DoDeath(int i); +int __fastcall M_DoSpStand(int i); +int __fastcall M_DoDelay(int i); +int __fastcall M_DoStone(int i); +void __fastcall M_WalkDir(int i, int md); +void __fastcall GroupUnity(int i); +unsigned char __fastcall M_CallWalk(int i, int md); +int __fastcall M_PathWalk(int i); +unsigned char __fastcall M_CallWalk2(int i, int md); +unsigned char __fastcall M_DumbWalk(int i, int md); +unsigned char __fastcall M_RoundWalk(int i, int md, int *dir); +void __fastcall MAI_Zombie(int i); +void __fastcall MAI_SkelSd(int i); +void __fastcall MAI_Path(int i); +void __fastcall MAI_Snake(int i); +void __fastcall MAI_Bat(int i); +void __fastcall MAI_SkelBow(int i); +void __fastcall MAI_Fat(int i); +void __fastcall MAI_Sneak(int i); +void __fastcall MAI_Fireman(int i); +void __fastcall MAI_Fallen(int i); +void __fastcall MAI_Cleaver(int i); +void __fastcall MAI_Round(int i, unsigned char special); +void __fastcall MAI_GoatMc(int i); +void __fastcall MAI_Ranged(int i, int missile_type, unsigned char special); +void __fastcall MAI_GoatBow(int i); +void __fastcall MAI_Succ(int i); +void __fastcall MAI_AcidUniq(int i); +void __fastcall MAI_Scav(int i); +void __fastcall MAI_Garg(int i); +void __fastcall MAI_RoundRanged(int i, int missile_type, unsigned char checkdoors, int dam, int lessmissiles); +void __fastcall MAI_Magma(int i); +void __fastcall MAI_Storm(int i); +void __fastcall MAI_Acid(int i); +void __fastcall MAI_Diablo(int i); +void __fastcall MAI_RR2(int i, int mistype, int dam); +void __fastcall MAI_Mega(int i); +void __fastcall MAI_Golum(int i); +void __fastcall MAI_SkelKing(int i); +void __fastcall MAI_Rhino(int i); +void __fastcall MAI_Counselor(int i); +void __fastcall MAI_Garbud(int i); +void __fastcall MAI_Zhar(int i); +void __fastcall MAI_SnotSpil(int i); +void __fastcall MAI_Lazurus(int i); +void __fastcall MAI_Lazhelp(int i); +void __fastcall MAI_Lachdanan(int i); +void __fastcall MAI_Warlord(int i); +void __cdecl DeleteMonsterList(); +void __cdecl ProcessMonsters(); +void __cdecl FreeMonsters(); +unsigned char __fastcall DirOK(int i, int mdir); +unsigned char __fastcall PosOkMissile(int x, int y); +unsigned char __fastcall CheckNoSolid(int x, int y); +unsigned char __fastcall LineClearF(unsigned char (__cdecl *Clear)(), int x1, int y1, int x2, int y2); +unsigned char __fastcall LineClear(int x1, int y1, int x2, int y2); +unsigned char __fastcall LineClearF1(unsigned char (__cdecl *Clear)(), int monst, int x1, int y1, int x2, int y2); +int __fastcall SyncMonsterAnim(int monst); +void __fastcall M_FallenFear(int x, int y); +void __fastcall PrintMonstHistory(int mt); +void __cdecl PrintUniqueHistory(); +void __fastcall MissToMonst(int i, int x, int y); +int __fastcall PosOkMonst(int i, int x, int y); +int __fastcall PosOkMonst2(int i, int x, int y); +int __fastcall PosOkMonst3(int i, int x, int y); +BOOL __fastcall IsSkel(int mt); +BOOL __fastcall IsGoat(int mt); +int __fastcall M_SpawnSkel(int x, int y, int dir); +void __fastcall ActivateSpawn(int i, int x, int y, int dir); +int __fastcall SpawnSkeleton(int ii, int x, int y); +int __cdecl PreSpawnSkeleton(); +void __fastcall TalktoMonster(int i); +void __fastcall SpawnGolum(int i, int x, int y, int mi); +unsigned char __fastcall CanTalkToMonst(int m); +unsigned char __fastcall CheckMonsterHit(int m, unsigned char *ret); +int __cdecl encode_enemy(int m); +void __fastcall decode_enemy(int m, int enemy); +void __cdecl movie_cpp_init(); +void __fastcall play_movie(char *pszMovie, bool user_can_close); +LRESULT __stdcall MovieWndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); +void __cdecl mpqapi_cpp_init(); +bool __fastcall mpqapi_set_hidden(char *save_path, bool hidden); +void __fastcall mpqapi_store_creation_time(char *save_path, int save_num); +bool __fastcall mpqapi_reg_load_modification_time(char *dst, int size); +void __fastcall mpqapi_xor_buf(char *buf); +bool __fastcall mpqapi_reg_store_modification_time(char *src, int len); +_BLOCKENTRY *__fastcall j_mpqapi_remove_hash_entry(char *a1); +void __fastcall mpqapi_remove_hash_entry(char *path); +void __fastcall mpqapi_alloc_block(int block_offset, int block_size); +_BLOCKENTRY *__fastcall mpqapi_new_block(int *block_index); +int __fastcall mpqapi_get_hash_index_of_path(char *path); +int __fastcall mpqapi_get_hash_index(short index, int hash_a, int hash_b, int locale); +void __fastcall mpqapi_remove_hash_entries(bool (__stdcall *get_file_name)(int lvl, char *file_name)); +bool __fastcall mpqapi_write_file(char *file_name, char *buf, int len); +_BLOCKENTRY *__fastcall mpqapi_add_file(char *path, _BLOCKENTRY *block, int block_index); +bool __fastcall mpqapi_write_file_contents(char *path, char *buf, int len, _BLOCKENTRY *block); +int __fastcall mpqapi_find_free_block(int size, int *block_size); +void __fastcall mpqapi_rename(char *old_name, char *new_name); +bool __fastcall mpqapi_has_file(char *path); +bool __fastcall mpqapi_open_archive(char *save_path, bool hidden, int save_num); +bool __fastcall mpqapi_parse_archive_header(TMPQHeader *header, int *mpq_offset); +void __fastcall mpqapi_close_archive(char *save_path, bool free_tables, int save_num); +void __fastcall mpqapi_store_modified_time(char *save_path, int save_num); +void __fastcall mpqapi_flush_and_close(char *save_path, bool is_single_player, int save_num); +bool __cdecl mpqapi_write_header(); +bool __cdecl mpqapi_write_block_table(); +bool __cdecl mpqapi_write_hash_table(); +bool __cdecl mpqapi_can_seek(); +void __cdecl msg_cpp_init(); +void __fastcall msg_send_drop_pkt(int pnum, int reason); +void __fastcall msg_send_packet(int pnum, void *packet, int dwSize); +TMegaPkt *__cdecl msg_get_next_packet(); +int __cdecl msg_wait_resync(); +void __cdecl msg_free_packets(); +int __cdecl msg_wait_for_turns(); +void __cdecl msg_process_net_packets(); +void __cdecl msg_pre_packet(); +void __fastcall msg_do_sync(int pnum); +void *__fastcall msg_sync_items(void *dst, void *src); +void *__fastcall msg_sync_objects(void *dst, void *src); +void *__fastcall msg_sync_monsters(void *dst, void *src); +char *__fastcall msg_sync_portals(char *a1); +int __fastcall msg_comp_level(char *buffer, int size); +void __cdecl delta_init(); +void __fastcall delta_kill_monster(int mi, unsigned char x, unsigned char y, unsigned char bLevel); +void __fastcall delta_monster_hp(int mi, __int32 hp, unsigned char bLevel); +void __fastcall delta_sync_monster(TCmdLocParam1 *packet, char level); +void __fastcall delta_sync_golem(TCmdGolem *pG, int pnum, int bLevel); +void __fastcall delta_leave_sync(unsigned char bLevel); +bool __fastcall delta_portal_inited(int portal_num); +bool __fastcall delta_quest_inited(int quest_num); +void __fastcall DeltaAddItem(int ii); +void __cdecl DeltaSaveLevel(); +void __cdecl DeltaLoadLevel(); +void __fastcall NetSendCmd(unsigned char bHiPri, unsigned char bCmd); +void __fastcall NetSendCmdGolem(unsigned char mx, unsigned char my, unsigned char dir, unsigned char menemy, __int32 hp, int cl); +void __fastcall NetSendCmdLoc(unsigned char bHiPri, unsigned char bCmd, unsigned char x, unsigned char y); +void __fastcall NetSendCmdLocParam1(unsigned char bHiPri, unsigned char bCmd, unsigned char x, unsigned char y, int wParam1); +void __fastcall NetSendCmdLocParam2(unsigned char bHiPri, unsigned char bCmd, unsigned char x, unsigned char y, int wParam1, int wParam2); +void __fastcall NetSendCmdLocParam3(unsigned char bHiPri, unsigned char bCmd, unsigned char x, unsigned char y, int wParam1, int wParam2, int wParam3); +void __fastcall NetSendCmdParam1(unsigned char bHiPri, unsigned char bCmd, unsigned short wParam1); +void __fastcall NetSendCmdParam2(unsigned char bHiPri, unsigned char bCmd, unsigned short wParam1, unsigned short wParam2); +void __fastcall NetSendCmdParam3(unsigned char bHiPri, unsigned char bCmd, unsigned short wParam1, unsigned short wParam2, int wParam3); +void __fastcall NetSendCmdQuest(unsigned char bHiPri, unsigned char q); +void __fastcall NetSendCmdGItem(unsigned char bHiPri, unsigned char bCmd, unsigned char mast, unsigned char pnum, int ii); +void __fastcall NetSendCmdGItem2(unsigned char usonly, unsigned char bCmd, unsigned char mast, unsigned char pnum, struct TCmdGItem *p); +unsigned char __fastcall NetSendCmdReq2(unsigned char bCmd, unsigned char mast, unsigned char pnum, struct TCmdGItem *p); +void __fastcall NetSendCmdExtra(struct TCmdGItem *p); +void __fastcall NetSendCmdPItem(unsigned char bHiPri, unsigned char bCmd, unsigned char x, unsigned char y); +void __fastcall NetSendCmdChItem(unsigned char bHiPri, unsigned char bLoc); +void __fastcall NetSendCmdDelItem(unsigned char bHiPri, unsigned char bLoc); +void __fastcall NetSendCmdDItem(unsigned char bHiPri, int ii); +void __fastcall NetSendCmdDamage(unsigned char bHiPri, unsigned char bPlr, unsigned __int32 dwDam); +void __fastcall msg_init_msg(int a1, const char *pszStr); +void __fastcall RemovePlrPortal(int pnum); +int __fastcall ParseCmd(int pnum, TCmd *pCmd); +void __fastcall DoCopySync(unsigned char cmd, int recv_offset); +void *__fastcall msg_copy_items(void *src, void *dst); +void *__fastcall msg_copy_objects(void *src, void *dst); +void *__fastcall msg_copy_monsters(void *src, void *dst); +char __fastcall msg_copy_portals(int a1); +int __fastcall On_SYNCDATA(void *packet, int pnum); +int __fastcall On_WALKXY(struct TCmdLoc *pCmd, int pnum); +int __fastcall On_ADDSTR(struct TCmdParam1 *pCmd, int pnum); +int __fastcall On_ADDMAG(struct TCmdParam1 *pCmd, int pnum); +int __fastcall On_ADDDEX(struct TCmdParam1 *pCmd, int pnum); +int __fastcall On_ADDVIT(struct TCmdParam1 *pCmd, int pnum); +int __fastcall On_SBSPELL(struct TCmdParam1 *pCmd, int pnum); +void msg_errorf(char *format, ...); +int __fastcall On_GOTOGETITEM(struct TCmdLocParam1 *pCmd, int pnum); +int __fastcall On_REQUESTGITEM(struct TCmdGItem *pCmd, int pnum); +bool __fastcall i_own_level(int nReqLevel); +int __fastcall On_GETITEM(struct TCmdGItem *pCmd, int pnum); +unsigned char __fastcall delta_get_item(struct TCmdGItem *pI, unsigned char bLevel); +int __fastcall On_GOTOAGETITEM(struct TCmdLocParam1 *pCmd, int pnum); +int __fastcall On_REQUESTAGITEM(struct TCmdGItem *pCmd, int pnum); +int __fastcall On_AGETITEM(struct TCmdGItem *pCmd, int pnum); +int __fastcall On_ITEMEXTRA(struct TCmdGItem *pCmd, int pnum); +int __fastcall On_PUTITEM(struct TCmdPItem *pCmd, int pnum); +void __fastcall delta_put_item(struct TCmdPItem *pI, int x, int y, unsigned char bLevel); +void __fastcall check_update_plr(int pnum); +int __fastcall On_SYNCPUTITEM(struct TCmdPItem *pCmd, int pnum); +int __fastcall On_RESPAWNITEM(struct TCmdPItem *pCmd, int pnum); +int __fastcall On_ATTACKXY(struct TCmdLoc *pCmd, int pnum); +int __fastcall On_SATTACKXY(struct TCmdLoc *pCmd, int pnum); +int __fastcall On_RATTACKXY(struct TCmdLoc *pCmd, int pnum); +int __fastcall On_SPELLXYD(struct TCmdLocParam3 *pCmd, int pnum); +int __fastcall On_SPELLXY(struct TCmdLocParam2 *pCmd, int pnum); +int __fastcall On_TSPELLXY(struct TCmdLocParam2 *pCmd, int pnum); +int __fastcall On_OPOBJXY(struct TCmdLocParam1 *pCmd, int pnum); +int __fastcall On_DISARMXY(struct TCmdLocParam1 *pCmd, int pnum); +int __fastcall On_OPOBJT(struct TCmdParam1 *pCmd, int pnum); +int __fastcall On_ATTACKID(struct TCmdParam1 *pCmd, int pnum); +int __fastcall On_ATTACKPID(struct TCmdParam1 *pCmd, int pnum); +int __fastcall On_RATTACKID(struct TCmdParam1 *pCmd, int pnum); +int __fastcall On_RATTACKPID(struct TCmdParam1 *pCmd, int pnum); +int __fastcall On_SPELLID(struct TCmdLocParam2 *pCmd, int pnum); +int __fastcall On_SPELLPID(struct TCmdLocParam2 *pCmd, int pnum); +int __fastcall On_TSPELLID(struct TCmdLocParam2 *pCmd, int pnum); +int __fastcall On_TSPELLPID(struct TCmdLocParam2 *pCmd, int pnum); +int __fastcall On_KNOCKBACK(struct TCmdParam1 *pCmd, int pnum); +int __fastcall On_RESURRECT(struct TCmdParam1 *pCmd, int pnum); +int __fastcall On_HEALOTHER(struct TCmdParam1 *pCmd, int pnum); +int __fastcall On_TALKXY(struct TCmdLocParam1 *pCmd, int pnum); +int __fastcall On_NEWLVL(struct TCmdParam2 *pCmd, int pnum); +int __fastcall On_WARP(struct TCmdParam1 *pCmd, int pnum); +int __fastcall On_MONSTDEATH(struct TCmdLocParam1 *pCmd, int pnum); +int __fastcall On_KILLGOLEM(struct TCmdLocParam1 *pCmd, int pnum); +int __fastcall On_AWAKEGOLEM(struct TCmdGolem *pCmd, int pnum); +int __fastcall On_MONSTDAMAGE(struct TCmdLocParam1 *pCmd, int pnum); +int __fastcall On_PLRDEAD(struct TCmdParam1 *pCmd, int pnum); +int __fastcall On_PLRDAMAGE(struct TCmdDamage *pCmd, int pnum); +int __fastcall On_OPENDOOR(struct TCmdParam1 *pCmd, int pnum); +void __fastcall delta_sync_object(int oi, unsigned char bCmd, unsigned char bLevel); +int __fastcall On_CLOSEDOOR(struct TCmdParam1 *pCmd, int pnum); +int __fastcall On_OPERATEOBJ(struct TCmdParam1 *pCmd, int pnum); +int __fastcall On_PLROPOBJ(struct TCmdParam2 *pCmd, int pnum); +int __fastcall On_BREAKOBJ(struct TCmdParam2 *pCmd, int pnum); +int __fastcall On_CHANGEPLRITEMS(struct TCmdChItem *pCmd, int pnum); +int __fastcall On_DELPLRITEMS(struct TCmdDelItem *pCmd, int pnum); +int __fastcall On_PLRLEVEL(struct TCmdParam1 *pCmd, int pnum); +int __fastcall On_DROPITEM(struct TCmdPItem *pCmd, int pnum); +int __fastcall On_SEND_PLRINFO(struct TCmdPlrInfoHdr *pCmd, int pnum); +int __fastcall On_ACK_PLRINFO(struct TCmdPlrInfoHdr *pCmd, int pnum); +int __fastcall On_PLAYER_JOINLEVEL(struct TCmdLocParam1 *pCmd, int pnum); +int __fastcall On_ACTIVATEPORTAL(DJunk *pCmd, int pnum); +void __fastcall delta_open_portal(int pnum, int x, int y, int bLevel, int bLType, int bSetLvl); +int __fastcall On_DEACTIVATEPORTAL(struct TCmd *pCmd, int pnum); +int __fastcall On_RETOWN(struct TCmd *pCmd, int pnum); +int __fastcall On_SETSTR(struct TCmdParam1 *pCmd, int pnum); +int __fastcall On_SETDEX(struct TCmdParam1 *pCmd, int pnum); +int __fastcall On_SETMAG(struct TCmdParam1 *pCmd, int pnum); +int __fastcall On_SETVIT(struct TCmdParam1 *pCmd, int pnum); +int __fastcall On_STRING(struct TCmdString *pCmd, int pnum); +int __fastcall On_SYNCQUEST(struct TCmdQuest *pCmd, int pnum); +int __fastcall On_ENDSHIELD(int a1, int pnum); +int __cdecl On_DEBUG(); +int __fastcall On_NOVA(struct TCmdLoc *pCmd, int pnum); +int __fastcall On_SETSHIELD(int unused, int pnum); +int __fastcall On_REMSHIELD(int unused, int pnum); +void __cdecl msgcmd_cpp_init_1(); +void __cdecl msgcmd_cpp_init_2(); +_SNETEVENT *__cdecl msgcmd_init_event(); +int __cdecl msgcmd_init_exit_event(); +void __cdecl msgcmd_clear_all_events(); +void __cdecl msgcmd_free_pevent(); +void __cdecl msgcmd_send_chat(); +int __fastcall msgcmd_check_set_event(int a1); +int __fastcall msgcmd_set_event(const char *a1); +_SNETEVENT *__fastcall msgcmd_clear_event(_SNETEVENT *a1); +bool __fastcall msgcmd_free_event(_SNETEVENT *a1); +int __fastcall msgcmd_free_str_event(_SNETEVENT *a1); +int __fastcall msgcmd_alloc_event(int *a1, int a2, int a3, int a4); +char *__fastcall msgcmd_remove_event(_SNETEVENT *a1); +char *__fastcall msgcmd_event_type(_SNETEVENT *a1, int a2, int *a3, int a4); +void __fastcall msgcmd_wait_zero_event(_SNETEVENT *a1); +void __fastcall msgcmd_zero_event(_SNETEVENT *a1); +void __cdecl multi_cpp_init(); +void __fastcall multi_msg_add(char *a1, unsigned char a2); +void __fastcall NetSendLoPri(unsigned char *pbMsg, unsigned char bLen); +void __fastcall multi_copy_packet(void *a1, void *packet, int size); +void __fastcall multi_send_packet(void *packet, int dwSize); +void __fastcall NetRecvPlrData(TPkt *pkt); +void __fastcall NetSendHiPri(unsigned char *pbMsg, unsigned char bLen); +char *__fastcall multi_recv_packet(void *packet, char *a2, int *a3); +void __fastcall multi_send_msg_packet(int a1, char *a2, unsigned char len); +void __cdecl multi_msg_countdown(); +int __fastcall multi_start_countdown(int pnum, int a2); +void __fastcall multi_wait_delta_send(int pnum); +void __fastcall multi_player_left(int pnum, int reason); +void __cdecl multi_clear_left_tbl(); +void __fastcall multi_player_left_msg(int pnum, int left); +void __cdecl multi_net_ping(); +int __cdecl multi_handle_delta(); +int __fastcall multi_check_pkt_valid(char *a1); +void __cdecl multi_mon_seeds(); +void __cdecl multi_begin_timeout(); +void __cdecl multi_check_drop_player(); +void __cdecl multi_process_network_packets(); +void __fastcall multi_handle_all_packets(int players, TPkt *packet, int a3); +void __cdecl multi_start_packets(); +void __fastcall multi_send_zero_packet(int pnum, char a2, void *ptr, int len); +void __cdecl NetClose(); +char __fastcall multi_event_handler(int a1); +void __stdcall multi_handle_events(_SNETEVENT *event); +int __fastcall NetInit(int bSinglePlayer, int *pfExitProgram); +void __fastcall multi_clear_pkt(char *a1); +void __fastcall multi_send_pinfo(int pnum, TCmdPlrInfoHdr *cmd); +int __fastcall InitNewSeed(int newseed); +void __cdecl SetupLocalCoords(); +int __fastcall multi_init_single(_SNETPROGRAMDATA *client_info, _SNETPLAYERDATA *user_info, _SNETUIDATA *ui_info); +int __fastcall multi_init_multi(_SNETPROGRAMDATA *client_info, _SNETPLAYERDATA *user_info, _SNETUIDATA *ui_info, int *a4); +int __fastcall multi_upgrade(int *a1); +void __fastcall multi_player_joins(int pnum, TCmdPlrInfoHdr *cmd, int a3); +void __cdecl nthread_cpp_init_1(); +void __cdecl nthread_cpp_init_2(); +void __cdecl nthread_init_mutex(); +void __cdecl nthread_cleanup_mutex_atexit(); +void __cdecl nthread_cleanup_mutex(); +void __fastcall nthread_terminate_game(char *func_name); +int __fastcall nthread_send_and_recv_turn(int cur_turn, int turn_delta); +void __fastcall nthread_recv_turns(bool *recieved); +void __cdecl nthread_set_turn_upper_bit(); +void __fastcall nthread_start(bool set_turn_upper_bit); +unsigned int __stdcall nthread_handler(void *a1); +void __cdecl nthread_cleanup(); +void __fastcall nthread_ignore_mutex(bool ignore_mutex); +bool __cdecl nthread_has_500ms_passed(); +void __cdecl InitObjectGFX(); +void __cdecl FreeObjectGFX(); +int __fastcall RndLocOk(int xp, int yp); +void __fastcall InitRndLocObj(int min, int max, int objtype); +void __fastcall InitRndLocBigObj(int min, int max, int objtype); +void __fastcall InitRndLocObj5x5(int min, int max, int objtype); +void __cdecl ClrAllObjects(); +void __cdecl AddTortures(); +void __cdecl AddCandles(); +void __fastcall AddBookLever(int lx1, int ly1, int lx2, int ly2, int x1, int y1, int x2, int y2, int msg); +void __cdecl InitRndBarrels(); +void __fastcall AddL1Objs(int x1, int y1, int x2, int y2); +void __fastcall AddL2Objs(int x1, int y1, int x2, int y2); +void __fastcall AddL3Objs(int x1, int y1, int x2, int y2); +unsigned char __fastcall WallTrapLocOk(int xp, int yp); +void __cdecl AddL2Torches(); +unsigned char __fastcall TorchLocOK(int xp, int yp); +void __cdecl AddObjTraps(); +void __cdecl AddChestTraps(); +void __fastcall LoadMapObjects(unsigned char *pMap, int startx, int starty, int x1, int y1, int w, int h, int leveridx); +void __fastcall LoadMapObjs(unsigned char *pMap, int startx, int starty); +void __cdecl AddDiabObjs(); +void __cdecl AddStoryBooks(); +void __fastcall AddHookedBodies(int freq); +void __cdecl AddL4Goodies(); +void __cdecl AddLazStand(); +void __fastcall InitObjects(int a1); +void __fastcall SetMapObjects(char *pMap, int startx, int starty); +void __fastcall DeleteObject(int oi, int i); +void __fastcall SetupObject(int i, int x, int y, int ot); +void __fastcall SetObjMapRange(int i, int x1, int y1, int x2, int y2, int v); +void __fastcall SetBookMsg(int i, int msg); +void __fastcall AddL1Door(int i, int x, int y, int ot); +void __fastcall AddSCambBook(int i); +void __fastcall AddChest(int i, int t); +void __fastcall AddL2Door(int i, int x, int y, int ot); +void __fastcall AddL3Door(int i, int x, int y, int ot); +void __fastcall AddSarc(int i); +void __fastcall AddFlameTrap(int i); +void __fastcall AddFlameLvr(int i); +void __fastcall AddTrap(int i); +void __fastcall AddObjLight(int i, int r); +void __fastcall AddBarrel(int i); +void __fastcall AddShrine(int i); +void __fastcall AddBookcase(int i); +void __fastcall AddPurifyingFountain(int i); +void __fastcall AddArmorStand(int i); +void __fastcall AddDecap(int i); +void __fastcall AddVilebook(int i); +void __fastcall AddMagicCircle(int i); +void __fastcall AddBookstand(int i); +void __fastcall AddPedistal(int i); +void __fastcall AddStoryBook(int i); +void __fastcall AddWeaponRack(int i); +void __fastcall AddTorturedBody(int i); +void __fastcall GetRndObjLoc(int randarea, int *xx, int *yy); +void __cdecl AddMushPatch(); +void __cdecl AddSlainHero(); +void __fastcall AddObject(int ot, int ox, int oy); +void __fastcall Obj_Light(int i, int lr); +void __fastcall Obj_Circle(int i); +void __fastcall Obj_StopAnim(int i); +void __fastcall Obj_Door(int i); +void __fastcall Obj_Sarc(int i); +void __fastcall ActivateTrapLine(int ttype, int tid); +void __fastcall Obj_FlameTrap(int i); +void __fastcall Obj_Trap(int i); +void __fastcall Obj_BCrossDamage(int i); +void __cdecl ProcessObjects(); +void __fastcall ObjSetMicro(int dx, int dy, int pn); +void __fastcall objects_set_door_piece(int x, int y); +void __fastcall ObjSetMini(int x, int y, int v); +void __fastcall ObjL1Special(int x1, int y1, int x2, int y2); +void __fastcall ObjL2Special(int x1, int y1, int x2, int y2); +void __fastcall DoorSet(int oi, int dx, int dy); +void __cdecl RedoPlayerVision(); +void __fastcall OperateL1RDoor(int pnum, int oi, unsigned char sendflag); +void __fastcall OperateL1LDoor(int pnum, int oi, unsigned char sendflag); +void __fastcall OperateL2RDoor(int pnum, int oi, unsigned char sendflag); +void __fastcall OperateL2LDoor(int pnum, int oi, unsigned char sendflag); +void __fastcall OperateL3RDoor(int pnum, int oi, unsigned char sendflag); +void __fastcall OperateL3LDoor(int pnum, int oi, unsigned char sendflag); +void __fastcall MonstCheckDoors(int m); +void __fastcall DRLG_MRectTrans(int x1, int y1, int x2, int y2); +void __fastcall ObjChangeMapResync(int x1, int y1, int x2, int y2); +void __fastcall OperateL1Door(int pnum, int i, unsigned char sendflag); +void __fastcall OperateLever(int pnum, int i); +void __fastcall OperateBook(int pnum, int i); +void __fastcall OperateBookLever(int pnum, int i); +void __fastcall OperateSChambBk(int pnum, int i); +void __fastcall OperateChest(int pnum, int i, unsigned char sendmsg); +void __fastcall OperateMushPatch(int pnum, int i); +void __fastcall OperateInnSignChest(int pnum, int i); +void __fastcall OperateSlainHero(int pnum, int i, unsigned char sendmsg); +void __fastcall OperateTrapLvr(int i); +void __fastcall OperateSarc(int pnum, int i, unsigned char sendmsg); +void __fastcall OperateL2Door(int pnum, int i, unsigned char sendflag); +void __fastcall OperateL3Door(int pnum, int i, unsigned char sendflag); +void __fastcall OperatePedistal(int pnum, int i); +void __fastcall TryDisarm(int pnum, int i); +int __fastcall ItemMiscIdIdx(int imiscid); +void __fastcall OperateShrine(int player_num, int object_num, int sfx_id); +void __fastcall OperateSkelBook(int pnum, int i, unsigned char sendmsg); +void __fastcall OperateBookCase(int pnum, int i, unsigned char sendmsg); +void __fastcall OperateDecap(int pnum, int i, unsigned char sendmsg); +void __fastcall OperateArmorStand(int pnum, int i, unsigned char sendmsg); +void __fastcall FindValidShrine(); +void __fastcall OperateGoatShrine(int pnum, int i, int sType); +void __fastcall OperateCauldron(int pnum, int i, int sType); +unsigned char __fastcall OperateFountains(int pnum, int i); +void __fastcall OperateWeaponRack(int pnum, int i, unsigned char sendmsg); +void __fastcall OperateStoryBook(int pnum, int i); +void __fastcall OperateLazStand(int pnum, int i); +void __fastcall OperateObject(int pnum, int i, unsigned char TeleFlag); +void __fastcall SyncOpL1Door(int pnum, int cmd, int i); +void __fastcall SyncOpL2Door(int pnum, int cmd, int i); +void __fastcall SyncOpL3Door(int pnum, int cmd, int i); +void __fastcall SyncOpObject(int pnum, int cmd, int i); +void __fastcall BreakCrux(int i); +void __fastcall BreakBarrel(int pnum, int i, int dam, unsigned char forcebreak, int sendmsg); +void __fastcall BreakObject(int pnum, int oi); +void __fastcall SyncBreakObj(int pnum, int oi); +void __fastcall SyncL1Doors(int i); +void __fastcall SyncCrux(int i); +void __fastcall SyncLever(int i); +void __fastcall SyncQSTLever(int i); +void __fastcall SyncPedistal(int i); +void __fastcall SyncL2Doors(int i); +void __fastcall SyncL3Doors(int i); +void __fastcall SyncObjectAnim(int o); +void __fastcall GetObjectStr(int i); +void __cdecl pack_cpp_init(); +void __fastcall PackPlayer(PkPlayerStruct *pPack, int pnum, bool manashield); +void __fastcall PackItem(PkItemStruct *id, ItemStruct *is); +void __fastcall VerifyGoldSeeds(PlayerStruct *pPlayer); +void __fastcall UnPackPlayer(PkPlayerStruct *pPack, int pnum, bool killok); +void __fastcall UnPackItem(PkItemStruct *is, ItemStruct *id); +void __cdecl palette_cpp_init(); +void __cdecl palette_save_gamme(); +void __cdecl palette_init(); +void __cdecl palette_load_gamma(); +void __cdecl palette_load_system_palette(); +void __fastcall LoadPalette(char *pal_path); +void __fastcall LoadRndLvlPal(char dtype); +void __cdecl ResetPal(); +void __cdecl palette_inc_gamma(); +void __cdecl palette_update(); +void __fastcall palette_apply_gamma_correction(PALETTEENTRY *dst, PALETTEENTRY *src, int n); +void __cdecl palette_dec_gamma(); +int __fastcall palette_update_gamma(int gamma); +void __cdecl BlackPalette(); +void __fastcall palette_set_brightness(int brightness); +void __fastcall PaletteFadeIn(int inc); +void __fastcall PaletteFadeOut(int dec); +void __cdecl palette_update_caves(); +void __fastcall palette_update_quest_palette(int n); +bool __cdecl palette_get_colour_cycling(); +void __fastcall palette_set_color_cycling(bool enabled); +int __fastcall FindPath(int (__fastcall *PosOk)(int, int, int), int PosOkArg, int sx, int sy, int dx, int dy, char *path); +int __fastcall path_xycoord(int x, int y, int xx, int yy); +int __fastcall path_check_equal(PATHNODE *pPath, int dx, int dy); +PATHNODE *__cdecl GetNextPath(); +PATHNODE *__fastcall path_solid_pieces(PATHNODE *pPath, int dx, int dy); +int __fastcall path_get_path(int (__fastcall *PosOk)(int, int, int), int PosOkArg, PATHNODE *pPath, int x, int y); +PATHNODE *__fastcall path_parent_path(PATHNODE *pPath, int dx, int dy, int sx, int sy); +PATHNODE *__fastcall path_get_node_xy(int dx, int dy); +PATHNODE *__fastcall path_get_node_xyptr(int dx, int dy); +PATHNODE *__fastcall path_get_node2(PATHNODE *pPath); +PATHNODE *__fastcall path_set_coords(PATHNODE *pPath); +PATHNODE *__fastcall path_set_node_ptr(PATHNODE *pPath); +PATHNODE *__cdecl path_decrease_node(); +PATHNODE *__cdecl path_clear_node(); +void __cdecl pfile_cpp_init(); +void __cdecl pfile_init_save_directory(); +void __fastcall pfile_check_available_space(char *pszDir); +void __cdecl pfile_write_hero(); +int __fastcall pfile_get_save_num_from_name(char *name); +void __fastcall pfile_encode_hero(PkPlayerStruct *pPack); +bool __fastcall pfile_open_archive(bool a1, int save_num); +void __fastcall pfile_get_save_path(char *pszBuf, int dwBufSize, int save_num); +void __fastcall pfile_flush(bool is_single_player, int save_num); +bool __fastcall pfile_create_player_description(char *dst, int len); +int __fastcall pfile_create_save_file(char *name_1, char *name_2); +void __cdecl pfile_flush_W(); +void __fastcall game_2_ui_player(PlayerStruct *p, _uiheroinfo *heroinfo, bool bHasSaveFile); +char __fastcall game_2_ui_class(PlayerStruct *p); +bool __stdcall pfile_ui_set_hero_infos(void (__stdcall *ui_add_hero_info)(_uiheroinfo *)); +char *__fastcall pfile_get_archive_path(char *dst, int dst_size, int save_num); +bool __fastcall pfile_read_hero(void *archive, PkPlayerStruct *hero); +void *__fastcall pfile_open_save_archive(int *unused, int save_num); +void __fastcall pfile_SFileCloseArchive(void *hsArchive); +bool __fastcall pfile_archive_contains_game(void *hsArchive); +bool __stdcall pfile_ui_set_class_stats(int player_class_nr, _uidefaultstats *class_stats); +int __fastcall pfile_get_player_class(int player_class_nr); +bool __stdcall pfile_ui_save_create(_uiheroinfo *heroinfo); +bool __stdcall pfile_get_file_name(int lvl, char *dst); +bool __stdcall pfile_delete_save(_uiheroinfo *hero_info); +void __cdecl pfile_read_player_from_save(); +void __fastcall pfile_get_temp_level_name(char *dst); +void __fastcall pfile_get_perm_level_name(char *dst); +void __fastcall pfile_get_game_name(char *dst); +void __cdecl pfile_remove_temp_files(); +bool __stdcall pfile_get_temp_name(int a1, char *dst); +void __cdecl pfile_rename_temp_to_perm(); +bool __stdcall GetPermSaveNames(int dwIndex, char *szPerm); +void __fastcall pfile_write_save_file(char *pszName, void *pbData, int dwLen, int qwLen); +void __fastcall pfile_strcpy(char *dst, char *src); +char *__fastcall pfile_read(char *pszName, int *pdwLen); +void __fastcall pfile_update(bool force_save); +void __cdecl player_cpp_init(); +void __fastcall player_copy_frames(char *src, char *dst); +void __fastcall LoadPlrGFX(int pnum, int a2); +void __fastcall InitPlayerGFX(int pnum); +void __fastcall InitPlrGFXMem(int pnum); +int __fastcall GetPlrGFXSize(char *szCel); +void __fastcall FreePlayerGFX(int pnum); +void __fastcall NewPlrAnim(int pnum, int Peq, int numFrames, int Delay); +void __fastcall ClearPlrPVars(int pnum); +void __fastcall SetPlrAnims(int pnum); +void __fastcall ClearPlrRVars(PlayerStruct *pPlayer); +void __fastcall CreatePlayer(int pnum, char c); +int __fastcall CalcStatDiff(int pnum); +void __fastcall NextPlrLevel(int pnum); +void __fastcall AddPlrExperience(int pnum, int lvl, __int32 exp); +void __fastcall AddPlrMonstExper(int lvl, __int32 exp, char pmask); +void __fastcall InitPlayer(int pnum, bool FirstTime); +void __cdecl InitMultiView(); +int __fastcall CheckLeighSolid(int x, int y); +int __fastcall SolidLoc(int x, int y); +int __fastcall PlrDirOK(int pnum, int dir); +void __fastcall PlrClrTrans(int x, int y); +void __fastcall PlrDoTrans(int x, int y); +void __fastcall SetPlayerOld(int pnum); +void __fastcall FixPlayerLocation(int pnum, int a2); +void __fastcall StartStand(int pnum, int dir); +void __fastcall StartWalkStand(int pnum); +void __fastcall PM_ChangeLightOff(int pnum); +void __fastcall PM_ChangeOffset(int pnum); +void __fastcall StartWalk(int pnum, int xvel, int yvel, int xadd, int yadd, int EndDir, int sdir); +void __fastcall StartWalk2(int pnum, int xvel, int yvel, int xoff, int yoff, int xadd, int yadd, int EndDir, int sdir); +void __fastcall StartWalk3(int pnum, int xvel, int yvel, int xoff, int yoff, int xadd, int yadd, int mapx, int mapy, int EndDir, int sdir); +void __fastcall StartAttack(int pnum, int d); +void __fastcall StartRangeAttack(int pnum, int a2, int a3, int a4); +void __fastcall StartPlrBlock(int pnum, int dir); +void __fastcall StartSpell(int pnum, int d, int cx, int cy); +void __fastcall FixPlrWalkTags(int pnum); +void __fastcall RemovePlrFromMap(int pnum); +void __fastcall StartPlrHit(int pnum, int dam, unsigned char forcehit); +void __fastcall DestroyDupeItem(ItemStruct *pItem, int ci, int a3); +void __fastcall StartPlayerKill(int pnum, int earflag); +void __fastcall PlrDeadItem(int pnum, struct ItemStruct *itm, int xx, int yy); +void __fastcall DropHalfPlayersGold(int pnum); +void __fastcall SyncPlrKill(int pnum, int earflag); +void __fastcall j_StartPlayerKill(int pnum, int earflag); +void __fastcall RemovePlrMissiles(int pnum); +int __fastcall InitLevelChange(int pnum); +void __fastcall StartNewLvl(int pnum, int fom, int lvl); +void __fastcall RestartTownLvl(int pnum); +void __fastcall StartWarpLvl(int pnum, int pidx); +int __fastcall PM_DoNothing(int pnum); +int __fastcall PM_DoWalk(int pnum); +int __fastcall PM_DoWalk2(int pnum); +int __fastcall PM_DoWalk3(int pnum); +unsigned char __fastcall WeaponDur(int pnum, int durrnd); +unsigned char __fastcall PlrHitMonst(int pnum, int m); +unsigned char __fastcall PlrHitPlr(int pnum, char p); +unsigned char __fastcall PlrHitObj(int pnum, int mx, int my); +int __fastcall PM_DoAttack(int pnum); +int __fastcall PM_DoRangeAttack(int pnum); +void __fastcall ShieldDur(int pnum); +int __fastcall PM_DoBlock(int pnum); +int __fastcall PM_DoSpell(int pnum); +int __fastcall PM_DoGotHit(int pnum); +void __fastcall ArmorDur(int pnum); +int __fastcall PM_DoDeath(int pnum); +void __fastcall CheckNewPath(int pnum); +unsigned char __fastcall PlrDeathModeOK(int pnum); +void __cdecl ValidatePlayer(); +void __cdecl ProcessPlayers(); +void __fastcall CheckCheatStats(int pnum); +void __fastcall ClrPlrPath(int pnum); +int __fastcall PosOkPlayer(int pnum, int px, int py); +void __fastcall MakePlrPath(int pnum, int xx, int yy, unsigned char endspace); +void __fastcall CheckPlrSpell(); +void __fastcall SyncPlrAnim(int pnum); +void __fastcall SyncInitPlrPos(int pnum); +void __fastcall SyncInitPlr(int pnum); +void __fastcall CheckStats(int pnum); +void __fastcall ModifyPlrStr(int pnum, int l); +void __fastcall ModifyPlrMag(int pnum, int l); +void __fastcall ModifyPlrDex(int pnum, int l); +void __fastcall ModifyPlrVit(int pnum, int l); +void __fastcall SetPlayerHitPoints(int pnum, int newhp); +void __fastcall SetPlrStr(int pnum, int v); +void __fastcall SetPlrMag(int pnum, int v); +void __fastcall SetPlrDex(int pnum, int v); +void __fastcall SetPlrVit(int pnum, int v); +void __fastcall InitDungMsgs(int pnum); +void __cdecl PlayDungMsgs(); +void __fastcall plrmsg_delay(int a1); +char *__fastcall ErrorPlrMsg(char *a1); +size_t EventPlrMsg(char *szMsg, ...); +void __fastcall SendPlrMsg(int pnum, const char *szMsg); +void __cdecl ClearPlrMsg(); +void __cdecl InitPlrMsg(); +void __cdecl DrawPlrMsg(); +void __fastcall PrintPlrMsg(int no, int x, int y, char *str, int just); +void __cdecl InitPortals(); +void __fastcall SetPortalStats(int i, int o, int x, int y, int lvl, int lvltype); +void __fastcall AddWarpMissile(int i, int x, int y); +void __cdecl SyncPortals(); +void __fastcall AddInTownPortal(int i); +void __fastcall ActivatePortal(int i, int x, int y, int lvl, int lvltype, int sp); +void __fastcall DeactivatePortal(int i); +int __fastcall PortalOnLevel(int i); +void __fastcall RemovePortalMissile(int id); +void __fastcall SetCurrentPortal(int p); +void __cdecl GetPortalLevel(); +void __cdecl GetPortalLvlPos(); +int __fastcall portal_pos_ok(int level, int x, int y); +void __cdecl InitQuests(); +void __cdecl CheckQuests(); +int __cdecl ForceQuests(); +bool __fastcall QuestStatus(int i); +void __fastcall CheckQuestKill(int m, unsigned char sendmsg); +void __cdecl DrawButcher(); +void __fastcall DrawSkelKing(int quest_id, int xx, int yy); +void __fastcall DrawWarLord(int xx, int yy); +void __fastcall DrawSChamber(int quest_id, int xx, int yy); +void __fastcall DrawLTBanner(int xx, int yy); +void __fastcall DrawBlind(int xx, int yy); +void __fastcall DrawBlood(int xx, int yy); +void __fastcall DRLG_CheckQuests(int xx, int yy); +void __cdecl SetReturnLvlPos(); +void __cdecl GetReturnLvlPos(); +void __cdecl ResyncMPQuests(); +void __cdecl ResyncQuests(); +void __fastcall PrintQLString(int x, int y, unsigned char cjustflag, char *str, int col); +void __cdecl DrawQuestLog(); +void __cdecl StartQuestlog(); +void __cdecl QuestlogUp(); +void __cdecl QuestlogDown(); +void __cdecl QuestlogEnter(); +void __cdecl QuestlogESC(); +void __fastcall SetMultiQuest(int q, int s, unsigned char l, int v1); +bool __cdecl SystemSupported(); +bool __cdecl RestrictedTest(); +bool __cdecl ReadOnlyTest(); +void __cdecl scrollrt_cpp_init(); +void __cdecl ClearCursor(); +void __fastcall scrollrt_452994(int x, int y, int a3, int a4, int a5, int a6, int del_flag); +void __fastcall scrollrt_452B2A(int x, int y, int sx, int sy, int a5, int a6, int a7); +void __fastcall scrollrt_452CC0(int x, int y, int sx, int sy, int a5, int a6, int some_flag); +void __fastcall scrollrt_draw_player_a(int pnum, int x, int y, int px, int py, int animdata, int animframe, int animwidth, int a9, int a10); +void __fastcall scrollrt_draw_player_b(int pnum, int x, int y, int px, int py, int animdata, int animframe, int animwidth, int a9, int a10); +void __fastcall DrawView(int StartX, int StartY); +void __fastcall DrawGame(int x, int y); +void __fastcall scrollrt_levels(int x, int y, int sx, int sy, int a5, int some_flag); +void __fastcall scrollrt_dead(char *a1, int sx, int sy, int a4, int a5, int a6); +void __fastcall scrollrt_monsters(int x, int y, int a3, int a4, int mon_id, int a6, int a7); +void __fastcall scrollrt_objects(int x, int y, int a3, int a4, int pre_flag, int a6, int dir); +void __fastcall scrollrt_4540E5(char *buffer, int x, int y, int a4, int a5); +void __fastcall scrollrt_454229(int x, int y, int sx, int sy, int a5, int a6, int some_flag); +void __fastcall scrollrt_4545D2(char *buffer, int x, int y, int a4, int a5, int sx, int sy, int me_flag); +int __fastcall scrollrt_454C09(char *buffer, int x, int y, int a4, signed int a5, int sx, int sy); +void __fastcall scrollrt_454D9D(int x, int y, int sx, int sy, int a5, int a6, int some_flag); +void __fastcall scrollrt_dead2(char *buffer, int x, int y, int a4, int a5, int sx, int sy, int me_flag); +void __fastcall scrollrt_monsters2(int x, int y, int a3, int a4, int mon_id, int a6, int a7); +void __fastcall scrollrt_objects2(int x, int y, int a3, int a4, int pre_flag, int a6, int dir); +void __fastcall scrollrt_455A7D(char *buffer, int x, int y, int a4, int a5, int sx, int sy); +void __fastcall DrawZoom(int x, int y); +void __cdecl ClearScreenBuffer(); +void __fastcall scrollrt_455E65(int some_flag); +void __cdecl scrollrt_455EC7(); +void __cdecl scrollrt_455F56(); +void __fastcall scrollrt_main_stuff(int dwHgt, int some_flag, int draw_hp, int draw_mana, int draw_sbar, int draw_btn); +void __fastcall scrollrt_draw_item(int dwX, int dwY, int dwWdt, int dwHgt); +void __cdecl DrawAndBlit(); +int __fastcall ObjIndex(int x, int y); +void __cdecl AddSKingObjs(); +void __cdecl AddSChamObjs(); +void __cdecl AddVileObjs(); +void __fastcall DRLG_SetMapTrans(char *dun_path); +void __cdecl LoadSetMap(); +void __cdecl sha1_reset(); +void __fastcall sha1_final(int ctx_id, char (*dst)[20]); +void __fastcall sha1(int ctx_id, const char *data, char (*dst)[20]); +void __fastcall sha1_update(SHA1Context *ctx, const char *data, int len); +void __fastcall sha1_transform(SHA1Context *ctx); +void __fastcall sha1_init(int ctx_id); +void __cdecl sound_cpp_init(); +void __fastcall snd_update(bool bStopAll); +void __fastcall snd_stop_snd(TSnd *pSnd); +bool __fastcall snd_playing(TSnd *pSnd); +void __fastcall snd_play_snd(TSnd *pSnd, int lVolume, int lPan); +IDirectSoundBuffer *__fastcall sound_dup_channel(IDirectSoundBuffer *DSB); +bool __fastcall sound_file_reload(TSnd *sound_file, IDirectSoundBuffer *DSB); +TSnd *__fastcall sound_file_load(char *path); +void __fastcall sound_CreateSoundBuffer(TSnd *sound_file); +void __fastcall sound_file_cleanup(TSnd *sound_file); +void __fastcall snd_init(HWND hWnd); +void __fastcall sound_load_volume(char *value_name, int *value); +void __fastcall sound_create_primary_buffer(int music_track); +int __fastcall sound_DirectSoundCreate(GUID *guid, IDirectSound **DS, int always_null); +void __cdecl sound_cleanup(); +void __fastcall sound_store_volume(char *key, int value); +void __cdecl music_stop(); +void __fastcall music_start(int nTrack); +void __fastcall sound_disable_music(bool disable); +int __fastcall sound_get_or_set_music_volume(int volume); +int __fastcall sound_get_or_set_sound_volume(int volume); +int __fastcall GetManaAmount(int id, int sn); +void __fastcall UseMana(int id, int sn); +bool __fastcall CheckSpell(int player_num, int spell_id, int spell_type, bool mana_only); +void __fastcall CastSpell(int player_num, int spell_id, int x, int y, int target_x, int target_y, int target_num, int spell_lvl); +void __fastcall DoResurrect(int pnum, int rid); +void __fastcall PlacePlayer(int pnum); +void __fastcall DoHealOther(int pnum, int rid); +void __cdecl InitStores(); +void __cdecl SetupTownStores(); +void __cdecl FreeStoreMem(); +void __cdecl DrawSTextBack(); +void __fastcall PrintSString(int x, int y, unsigned char cjustflag, char *str, int col, int val); +void __fastcall DrawSLine(int y); +void __fastcall DrawSArrows(int a1, int a2); +void __cdecl DrawSTextHelp(); +void __fastcall ClearSText(int s, int e); +void __fastcall AddSLine(int y); +void __fastcall AddSTextVal(int y, int val); +void __fastcall OffsetSTextY(int y, int yo); +void __fastcall AddSText(int x, int y, unsigned char j, char *str, int clr, int sel); +unsigned char __cdecl StoreAutoPlace(); +void __cdecl S_StartSmith(); +void __fastcall S_ScrollSBuy(int idx); +void __fastcall PrintStoreItem(ItemStruct *x, int l, char iclr); +void __cdecl S_StartSBuy(); +void __fastcall S_ScrollSPBuy(int idx); +bool __cdecl S_StartSPBuy(); +bool __fastcall SmithSellOk(int inv_num); +void __fastcall S_ScrollSSell(int idx); +void __cdecl S_StartSSell(); +bool __fastcall SmithRepairOk(int i); +void __cdecl S_StartSRepair(); +void __fastcall AddStoreHoldRepair(ItemStruct *itm, int i); +void __cdecl S_StartWitch(); +void __fastcall S_ScrollWBuy(int idx); +void __cdecl S_StartWBuy(); +bool __fastcall WitchSellOk(int i); +void __cdecl S_StartWSell(); +unsigned char __fastcall WitchRechargeOk(int i); +void __fastcall AddStoreHoldRecharge(ItemStruct itm, int i); +void __cdecl S_StartWRecharge(); +void __cdecl S_StartNoMoney(); +void __cdecl S_StartNoRoom(); +void __cdecl S_StartConfirm(); +void __cdecl S_StartBoy(); +void __cdecl S_StartBBoy(); +void __cdecl S_StartHealer(); +void __fastcall S_ScrollHBuy(int idx); +void __cdecl S_StartHBuy(); +void __cdecl S_StartStory(); +bool __fastcall IdItemOk(ItemStruct *item); +void __fastcall AddStoreHoldId(ItemStruct itm, int i); +void __cdecl S_StartSIdentify(); +void __cdecl S_StartIdShow(); +void __cdecl S_StartTalk(); +void __cdecl S_StartTavern(); +void __cdecl S_StartBarMaid(); +void __cdecl S_StartDrunk(); +void __fastcall StartStore(int talk_id); +void __cdecl DrawSText(); +void __cdecl STextESC(); +void __cdecl STextUp(); +void __cdecl STextDown(); +void __cdecl STextPrior(); +void __cdecl STextNext(); +void __cdecl S_SmithEnter(); +void __fastcall SetGoldCurs(int pnum, int i); +void __fastcall SetSpdbarGoldCurs(int pnum, int i); +void __fastcall TakePlrsMoney(int cost); +void __cdecl SmithBuyItem(); +void __cdecl S_SBuyEnter(); +void __cdecl SmithBuyPItem(); +void __cdecl S_SPBuyEnter(); +unsigned char __fastcall StoreGoldFit(int idx); +void __fastcall PlaceStoreGold(int v); +void __cdecl StoreSellItem(); +void __cdecl S_SSellEnter(); +void __cdecl SmithRepairItem(); +void __cdecl S_SRepairEnter(); +void __cdecl S_WitchEnter(); +void __cdecl WitchBuyItem(); +void __cdecl S_WBuyEnter(); +void __cdecl S_WSellEnter(); +void __cdecl WitchRechargeItem(); +void __cdecl S_WRechargeEnter(); +void __cdecl S_BoyEnter(); +void __cdecl BoyBuyItem(); +void __cdecl HealerBuyItem(); +void __cdecl S_BBuyEnter(); +void __cdecl StoryIdItem(); +void __cdecl S_ConfirmEnter(); +void __cdecl S_HealerEnter(); +void __cdecl S_HBuyEnter(); +void __cdecl S_StoryEnter(); +void __cdecl S_SIDEnter(); +void __cdecl S_TalkEnter(); +void __cdecl S_TavernEnter(); +void __cdecl S_BarmaidEnter(); +void __cdecl S_DrunkEnter(); +void __cdecl STextEnter(); +void __cdecl CheckStoreBtn(); +void __cdecl ReleaseStoreBtn(); +int __fastcall sync_all_monsters(TSyncHeader *packet, int size); +void __cdecl sync_one_monster(); +int __fastcall sync_monster_active(TSyncMonster *packet); +int __fastcall sync_monster_pos(TSyncMonster *packet, int mon_id); +int __fastcall sync_monster_active2(TSyncMonster *packet); +char __fastcall SyncPlrInv(TSyncHeader *pItem); +int __fastcall SyncData(int pnum, TSyncHeader *packet); +void __fastcall sync_monster_data(int pnum, TSyncMonster *packet); +void __cdecl sync_clear_pkt(); +unsigned char __fastcall TFit_Shrine(int i); +bool __fastcall TFit_Obj5(int theme_num); +unsigned char __fastcall TFit_SkelRoom(int i); +unsigned char __fastcall TFit_GoatShrine(int i); +unsigned char __fastcall CheckThemeObj3(int xp, int yp, int t, int f); +bool __fastcall TFit_Obj3(int theme_num); +unsigned char __fastcall CheckThemeReqs(int t); +unsigned char __fastcall SpecialThemeFit(int i, int t); +unsigned char __fastcall CheckThemeRoom(int tv); +void __cdecl InitThemes(); +void __cdecl HoldThemeRooms(); +void __fastcall PlaceThemeMonsts(int t, int f); +void __fastcall Theme_Barrel(int theme_num); +void __fastcall Theme_Shrine(int theme_num); +void __fastcall Theme_MonstPit(int theme_num); +void __fastcall Theme_SkelRoom(int theme_num); +void __fastcall Theme_Treasure(int theme_num); +void __fastcall Theme_Library(int theme_num); +void __fastcall Theme_Torture(int theme_num); +void __fastcall Theme_BloodFountain(int theme_num); +void __fastcall Theme_Decap(int theme_num); +void __fastcall Theme_PurifyingFountain(int theme_num); +void __fastcall Theme_ArmorStand(int theme_num); +void __fastcall Theme_GoatShrine(int theme_num); +void __fastcall Theme_Cauldron(int theme_num); +void __fastcall Theme_MurkyFountain(int theme_num); +void __fastcall Theme_TearFountain(int theme_num); +void __fastcall Theme_BrnCross(int theme_num); +void __fastcall Theme_WeaponRack(int theme_num); +void __cdecl UpdateL4Trans(); +void __cdecl CreateThemeRooms(); +int __fastcall tmsg_get(char *data, int size); +void __fastcall tmsg_add(char *msg, char len); +void __cdecl tmsg_cleanup(); +int __fastcall town_clear_upper_buf(int a1); +void __fastcall town_clear_low_buf(int y_related); +void __fastcall town_draw_low_somepiece(void *buffer, int x, int y, int sx, int sy); +void __fastcall town_draw_low_something(void *unused, int x, int y, int sx, int sy, int some_flag); +void __fastcall town_draw_low_pieces(int x, int y, int sx, int sy, int a5, int some_flag); +void __fastcall town_draw_lower_screen(void *buffer, int x, int y, int a4, int a5, int sx, int sy); +void __fastcall town_draw_low_towners(int x, int y, int a3, int a4, int a5, int sx, int sy, int some_flag); +void __fastcall town_draw_lower(int x, int y, int sx, int sy, int a5, int a6, int some_flag); +void __fastcall town_draw_pieces(void *buffer, int x, int y, int a4, int dir, int sx, int sy); +void __fastcall town_draw_towners(void *buffer, int x, int y, int a4, int dir, int sx, int sy, int some_flag); +void __fastcall town_draw_screen(int x, int y, int sx, int sy, int a5, int a6, int some_flag); +void __fastcall T_DrawGame(int x, int y); +void __fastcall T_DrawZoom(int x, int y); +void __fastcall T_DrawView(int StartX, int StartY); +void __cdecl town_get_draw_size(); +void __fastcall T_FillSector(unsigned char *P3Tiles, unsigned char *pSector, int xi, int yi, int w, int h, int AddSec); +void __fastcall T_FillTile(unsigned char *P3Tiles, int xx, int yy, int t); +void __cdecl T_Pass3(); +void __fastcall CreateTown(int entry); +int __fastcall GetActiveTowner(int towner_id); +void __fastcall SetTownerGPtrs(void *towner_cel, void **cel_from_direction); +void __fastcall NewTownerAnim(int tnum, void *pAnim, int numFrames, int Delay); +void __fastcall InitTownerInfo(int i, int w, bool sel, int t, int x, int y, int ao, int tp); +void __fastcall InitQstSnds(int towner_num); +void __cdecl InitSmith(); +void __cdecl InitBarOwner(); +void __cdecl InitTownDead(); +void __cdecl InitWitch(); +void __cdecl InitBarmaid(); +void __cdecl InitBoy(); +void __cdecl InitHealer(); +void __cdecl InitTeller(); +void __cdecl InitDrunk(); +void __cdecl InitCows(); +void __cdecl InitTowners(); +void __cdecl FreeTownerGFX(); +void __fastcall TownCtrlMsg(int towner_num); +void __cdecl TownBlackSmith(); +void __cdecl TownBarOwner(); +void __cdecl TownDead(); +void __cdecl TownHealer(); +void __cdecl TownStory(); +void __cdecl TownDrunk(); +void __cdecl TownBoy(); +void __cdecl TownWitch(); +void __cdecl TownBarMaid(); +void __cdecl TownCow(); +void __cdecl ProcessTowners(); +ItemStruct *__fastcall PlrHasItem(int pnum, int item, int *i); +void __fastcall TownerTalk(int t); +void __fastcall TalkToTowner(int p, int t); +void __fastcall CowSFX(int pnum); +void __cdecl track_cpp_init(); +void __cdecl track_repeat_walk(); +void __fastcall track_mouse_stance(int a1); +int __cdecl track_isscrolling(); +void __cdecl InitNoTriggers(); +void __cdecl InitTownTriggers(); +void __cdecl InitL1Triggers(); +void __cdecl InitL2Triggers(); +void __cdecl InitL3Triggers(); +void __cdecl InitL4Triggers(); +void __cdecl InitSKingTriggers(); +void __cdecl InitSChambTriggers(); +void __cdecl InitPWaterTriggers(); +void __cdecl InitVPTriggers(); +unsigned char __cdecl ForceTownTrig(); +unsigned char __cdecl ForceL1Trig(); +unsigned char __cdecl ForceL2Trig(); +unsigned char __cdecl ForceL3Trig(); +unsigned char __cdecl ForceL4Trig(); +void __cdecl Freeupstairs(); +unsigned char __cdecl ForceSKingTrig(); +unsigned char __cdecl ForceSChambTrig(); +unsigned char __cdecl ForcePWaterTrig(); +void __cdecl CheckTrigForce(); +void __cdecl CheckTriggers(); +void __cdecl wave_cpp_init(); +bool __fastcall wave_close_file(void *file); +int __fastcall wave_get_file_size(int *a1, int *a2); +void __fastcall wave_get_file_archive(int a1, int *a2, char *dwInitParam); +int __fastcall wave_open_file(LPARAM dwInitParam, DIABFILE *a2, int a3); +char __fastcall wave_read_file(int a1, char *a2, int a3); +int __fastcall wave_file_pointer(int file1, int offset, int file2, int whence); +int __fastcall wave_do_buffer(int a1, TSnd *a2); +void *__fastcall wave_alloc_buffer(int a1, DIABFILE *a2, unsigned int a3); +void __fastcall wave_free_buffer(int *a1); +int __fastcall wave_read_buffer(DIABFILE *wave_file, TSnd *a2, int *a3); +int __fastcall wave_seek_section(DIABFILE *a1, void *a2, size_t a3); +char __fastcall wave_read_section(DIABFILE *a1); +int __fastcall wave_seek_position(DIABFILE *a1, unsigned int a2, int a3); +int __fastcall wave_get_section_data(DIABFILE *a1, int a2, int *a3); +int __fastcall wave_load_file(int a1, TSnd *a2, int a3); +void __fastcall j_engine_mem_free(void *ptr); +void __fastcall drawTopArchesUpperScreen(void *a1); +void __fastcall drawBottomArchesUpperScreen(void *a1, int a2); +void __fastcall drawUpperScreen(void *a1); +void __fastcall drawTopArchesLowerScreen(void *a1); +void __fastcall drawBottomArchesLowerScreen(void *a1, int a2); +void __fastcall drawLowerScreen(void *a1); +void __fastcall world_levelrelated(char *a1); + +int appfat_terminated = 0; // weak +unsigned char error_buf[256]; +int terminating; // weak +int cleanup_thread_id; // weak +char empty_string; +short automaptype[512]; +int AMdword_4B7E40; // weak +int AMdword_4B7E44; // weak +unsigned char automapflag; // idb +char AMbyte_4B7E4C[32]; +char automapview[40][40]; +int AutoMapScale; // idb +int AutoMapXOfs; // weak +int AutoMapYOfs; // weak +int CT_4B84B8; // weak +int CT_4B84BC; // weak +int CT_4B84C0; // weak +int CT_4B84C4; // weak +int CT_4B84C8; // weak +char sgbNextTalkSave; // weak +char sgbTalkSavePos; // weak +void *pDurIcons; +void *pChrButtons; +int drawhpflag; // idb +int dropGoldFlag; // weak +int panbtn[8]; +int chrbtn[4]; +void *pMultiBtns; +void *pPanelButtons; +void *pChrPanel; +int lvlbtndown; // weak +char sgszTalkSave[8][80]; +int dropGoldValue; // idb +int drawmanaflag; // idb +int chrbtnactive; // weak +char sgszTalkMsg[80]; +void *pPanelText; +int frame_4B8800; // idb +void *pLifeBuff; +void *pBtmBuff; +void *pTalkBtns; +int pstrjust[4]; +int pnumlines; // idb +int pinfoflag; // weak +int talkbtndown[3]; +int pSpell; // weak +void *pManaBuff; +int infoclr; // weak +int sgbPlrTalkTbl; // weak +void *pGBoxBuff; +void *pSBkBtnCel; +char tempstr[260]; +int sbooktab; // weak +int pSplType; // weak +int frame; // idb +int initialDropGoldIndex; // idb +int talkflag; // weak +void *pSBkIconCels; +int sbookflag; // weak +int chrflag; +int drawbtnflag; // idb +void *pSpellBkCel; +char infostr[260]; +int numpanbtns; // weak +void *pStatusPanel; +char panelstr[256]; +int panelflag; // weak +char byte_4B8B88[256]; +int initialDropGoldValue; // idb +void *pSpellCels; +int panbtndown; // weak +void *pTalkPanel; // idb +int spselflag; // weak +int cursH; // weak +int icursH28; // idb +int cursW; // idb +unsigned short pcursmonst; // idb +int icursW28; // idb +void *pCursCels; +int icursH; // weak +char pcursinvitem; // weak +int icursW; // weak +char pcursitem; // weak +char pcursobj; // weak +char pcursplr; // weak +int cursmx; +int cursmy; +int dword_4B8CCC; // weak +int pcurs; // idb +int spurtndx; // weak +DeadStruct dead[31]; +int stonendx; +void *pSquareCel; +char debug_dMonster[17][112][112]; +char debug_dflags[17][112][112]; +int diablo_cpp_init_value; // weak +HWND ghMainWnd; +int glMid1Seed[17]; +int glMid2Seed[17]; +int gnLevelTypeTbl[17]; +int MouseY; // idb +int MouseX; // idb +bool gbGameLoopStartup; // idb +int glSeedTbl[17]; +int gbRunGame; // weak +int glMid3Seed[17]; +int gbRunGameResult; // weak +int zoomflag; // weak +int gbProcessPlayers; // weak +int glEndSeed[17]; +int dword_5256E8; // weak +HINSTANCE hInstance; // idb +int DebugMonsters[10]; +char cineflag; // weak +int force_redraw; // weak +int visiondebug; // weak +int light4flag; // weak +int leveldebug; // weak +int monstdebug; // weak +int setseed; // weak +int debugmonsttypes; // weak +int PauseMode; // weak +int sgnTimeoutCurs; +char sgbMouseDown; // weak +int dword_52574C; // weak +int dword_525750; // weak +int dword_525754; // weak +void *pDoomCel; +int doomflag; // weak +int dword_525760; // idb +char L5dungeon[80][80]; +char mydflags[40][40]; +int setloadflag; // weak +int HR1; +int HR2; +int HR3; +int VR1; +int VR2; +int VR3; +void *pSetPiece; // idb +int nSx1; +int nSx2; // weak +int nSy1; +int nSy2; // weak +int nRoomCnt; +char predungeon[40][40]; +ROOMNODE RoomList[81]; +HALLNODE *pHallList; +char lavapool; // weak +int abyssx; // weak +int lockoutcnt; // weak +char lockout[40][40]; +int diabquad1x; // weak +int diabquad1y; // weak +int diabquad3x; // idb +int diabquad3y; // idb +int diabquad2x; // idb +int diabquad2y; // idb +int diabquad4x; // idb +int diabquad4y; // idb +int hallok[20]; +int l4holdx; // weak +int l4holdy; // weak +int SP4x1; // idb +int SP4x2; // weak +int SP4y1; // idb +int SP4y2; // weak +char L4dungeon[80][80]; +char dung[20][20]; +int dword_52A4DC; // weak +int dthread_cpp_init_value; // weak +struct _RTL_CRITICAL_SECTION CriticalSection; // idb +unsigned int ThreadId; // idb +int sgpInfoHead; +char byte_52A508; // weak +HANDLE sghWorkToDoEvent; // idb +void *sgpBackBuf; +int dx_cpp_init_value; // weak +IDirectDrawPalette *lpDDPPrimary; +IDirectDrawPalette *lpDDPRed; // idb +int sgdwLockCount; +Screen *gpBuffer; +IDirectDrawSurface *lpDDSBackBuf; +IDirectDrawSurface *lpDDSPrimary; +struct _RTL_CRITICAL_SECTION stru_52A530; +char gbBackBuf; // weak +char gbEmulate; // weak +HMODULE hModule; // idb +int effects_cpp_init_value; // weak +int sfxdelay; // weak +int sfxdnum; +void *sfx_stream; +TSFX *sfx_data_cur; +int encrypt_52A564[1024]; +int encrypt_52B564[257]; +int engine_cpp_init_value; // weak +char byte_52B96C; // weak +int dword_52B970; // weak +int orgseed; // weak +int dword_52B978; // weak +int sglGameSeed; // weak +struct _RTL_CRITICAL_SECTION sgMemCrit; +int SeedCount; // weak +int dword_52B99C; // weak +char msgtable[80]; +char msgdelay; // weak +char msgflag; // weak +char msgcnt; // weak +LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter; // idb +short level_frame_types[2048]; +int themeCount; +char nTransTable[2048]; +int dword_52D204; +int dMonster[112][112]; +char dungeon[40][40]; +char dObject[112][112]; +void *pSpeedCels; +int nlevel_frames; // weak +char pdungeon[40][40]; +char dDead[112][112]; +short dpiece_defs_map_1[16][112][112]; +char dTransVal2[112][112]; +char TransVal; // weak +int dword_5A5594; +char dflags[40][40]; +int dPiece[112][112]; +char dTransVal[112][112]; +int setloadflag_2; // weak +Tile tile_defs[1024]; +void *pMegaTiles; +DPiece dpiece_defs[2]; +int gnDifficulty; // idb +char block_lvid[2049]; +char byte_5B78EB; +char dung_map[112][112]; +char nTrapTable[2049]; +char leveltype; // weak +unsigned char currlevel; // idb +char TransList[256]; +char nSolidTable[2049]; +int level_frame_count[2049]; +ScrollStruct ScrollInfo; +void *pDungeonCels; +int speed_cel_frame_num_from_light_index_frame_num[16][128]; +THEME_LOC themeLoc[50]; +char dPlayer[112][112]; +int dword_5C2FF8; // weak +int dword_5C2FFC; // weak +int scr_pix_width; // weak +int scr_pix_height; // weak +char dArch[112][112]; +char nBlockTable[2049]; +void *level_special_cel; +char dFlags[112][112]; +char dItem[112][112]; +char setlvlnum; // weak +int level_frame_sizes[2048]; +char nMissileTable[2049]; +char *pSetPiece_2; +char setlvltype; // weak +char setlevel; // weak +int LvlViewY; // weak +int LvlViewX; // weak +int dmaxx; // weak +int dmaxy; // weak +int setpc_h; // weak +int setpc_w; // weak +int setpc_x; // idb +int ViewX; // idb +int ViewY; // idb +int setpc_y; // idb +char dMissile[112][112]; +int dminx; // weak +int dminy; // weak +short dpiece_defs_map_2[16][112][112]; +void *optbar_cel; +char byte_634464; // weak +void *PentSpin_cel; +void **sgpCurrItem; +void *BigTGold_cel; +int dword_634474; // weak +char byte_634478; // weak +void (__cdecl *dword_63447C)(); +int dword_634480; // idb +void *option_cel; +void *sgpLogo; +int dword_63448C; // weak +int help_select_line; // weak +int dword_634494; // weak +int helpflag; +int displayinghelp[22]; +int HelpTop; // weak +_SNETVERSIONDATA fileinfo; +int init_cpp_init_value; // weak +int window_activated; // weak +char diablo_exe_path[260]; +void *unused_mpq; +char patch_rt_mpq_path[260]; +LRESULT (__stdcall *CurrentProc)(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); +void *diabdat_mpq; +char diabdat_mpq_path[260]; +void *patch_rt_mpq; +int killed_mom_parent; // weak +bool screensaver_enabled_prev; +void *sgpBackCel; +float interfac_cpp_init_value; +int sgdwProgress; +int progress_id; // idb +int invflag; +void *pInvCels; +int drawsbarflag; // idb +int dupe_delay; +int itemactive[127]; +int uitemflag; +int itemavail[128]; +ItemStruct curruitem; +ItemGetRecordStruct itemrecords[104]; +ItemStruct item_stru_6358B8; +ItemStruct items[128]; +char itemhold[3][3]; +char byte_641234[28]; +int Item2Frm[35]; +int UniqueItemFlag[128]; +int numitems; +int gnNumGetRecords; +LightListStruct VisionList[32]; +char lightactive[32]; +LightListStruct LightList[32]; +int numlights; +char dung_map_radius[2048]; +int dovision; // weak +int numvision; +char lightmax; // weak +int dword_642A18; // weak +char dung_map_rgba[16384]; +int visionid; +int dword_646A20; +int lightflag; // weak +void *tbuff; +int dword_646A30; // weak +struct _RTL_CRITICAL_SECTION stru_646A38; +CHAR FileName[260]; // idb +char log_buffer[388]; +LPCVOID lpAddress; // idb +DWORD nNumberOfBytesToWrite; // idb +int mainmenu_cpp_init_value; // weak +char chr_name_str[16]; +int qtexty; // weak +char *qtextptr; +int qtextSpd; // weak +char qtextflag; // weak +int scrolltexty; // weak +int sgLastScroll; // weak +void *pMedTextCels; +void *pTextBoxCels; +int missileactive[125]; +int missileavail[125]; +MissileStruct missile[125]; +int nummissiles; // idb +int ManashieldFlag; +unk_missile_struct misflagstruct_unknown[125]; +int MissilePreFlag; // weak +int END_unkmis_126; // weak +int MissileFileFlag; // weak +int monster_cpp_init_value; // weak +int monstkills[200]; +int monstactive[200]; +int nummonsters; +int sgbSaveSoundOn; // weak +MonsterStruct monster[200]; +int totalmonsters; // weak +CMonster Monsters[16]; +int END_Monsters_17; // weak +int monstimgtot; // weak +int uniquetrans; +int nummtypes; +int movie_cpp_init_value; // weak +int movie_playing; // weak +int loop_movie; // weak +int mpqapi_cpp_init_value; // weak +LONG lDistanceToMove; // idb +int mpq_buf[1024]; +_BLOCKENTRY *sgpHashTbl; +int dword_65AB0C; // weak +_BLOCKENTRY *sgpBlockTbl; +char byte_65AB14; // weak +int sgdwOwnerWait; // weak +int msg_cpp_init_value; // weak +int sgdwRecvOffset; // idb +int sgnCurrMegaPlayer; // weak +DLevel sgLevels[17]; +char sbLastCmd; // weak +TMegaPkt *sgpCurrPkt; +DLevel sgTempLevel; +unsigned char sgbRecvCmd; // idb +LocalLevel sgLocals[17]; +DJunk sgJunk[4]; +TMegaPkt *sgpMegaPkt; +char sgbDeltaChanged; // weak +char sgbDeltaChunks; // weak +int deltaload; // weak +char gbBufferMsgs; // weak +int dword_676198; // weak +int msg_err_timer; // weak +int msgcmd_cpp_init_value; // weak +_SNETEVENT pEvent; +char gbSomebodyWonGameKludge; // weak +char pkdata_6761C0[4100]; +char szPlayerDescript[128]; +short sgwPackPlrOffsetTbl[4]; +PkPlayerStruct pkplr[4]; +char sgbPlayerTurnBitTbl[4]; +char sgbPlayerLeftGameTbl[4]; +int multi_cpp_init_value; // weak +int sgbSentThisCycle; // idb +int dword_678628; // weak +char gbActivePlayers; // weak +char gbGameDestroyed; // weak +char sgbSendDeltaTbl[4]; +_gamedata sgGameInitInfo; +char byte_678640; // weak +int sglTimeoutStart; // weak +int sgdwPlayerLeftReasonTbl[4]; +char pkdata_678658[4100]; +unsigned int sgdwGameLoops; // idb +char gbMaxPlayers; // weak +char sgbTimeout; // weak +char szPlayerName[128]; +char gbDeltaSender; // weak +int sgbNetInited; // weak +int player_state[4]; +int nthread_cpp_init_value; // weak +char byte_679704; // weak +int gdwMsgLenTbl[4]; +struct _RTL_CRITICAL_SECTION stru_679718; +int gdwDeltaBytesSec; // weak +char byte_679734; // weak +int gdwTurnsInTransit; // weak +int glpMsgTbl[4]; +int dword_67974C; +char sgbSyncCountdown; // weak +int dword_679754; // weak +char byte_679758; // weak +char sgbPacketCountdown; // weak +char sgbThreadIsRunning; // weak +int gdwLargestMsgSize; // weak +int gdwNormalMsgSize; // weak +int dword_679764; // weak +int trapid; // weak +int trapdir; // weak +int pObjCels[40]; +char ObjFileList[40]; +int objectactive[127]; +int nobjects; // idb +int leverid; // idb +int objectavail[127]; +ObjectStruct object[127]; +int InitObjFlag; // weak +int numobjfiles; // weak +int hero_cpp_init_value; // weak +PALETTEENTRY logical_palette[256]; +int palette_cpp_init_value; // weak +PALETTEENTRY system_palette[256]; +PALETTEENTRY orig_palette[256]; +UINT nsystem_reserve_palette_entries; +PATHNODE path_nodes[300]; +int dword_6820C8; +int pnode_vals[26]; +PATHNODE *pnode_ptr; +PATHNODE *pnode_tblptr[300]; +PATHNODE path_2_nodes[300]; +int pfile_cpp_init_value; +char hero_names[320]; +bool gbValidSaveFile; // idb +int save_prev_tc; // weak +int plr_lframe_size; // idb +int plr_wframe_size; // idb +char plr_gfx_flag; // weak +int player_cpp_init_value; // weak +int plr_aframe_size; // idb +int myplr; +PlayerStruct plr[4]; +int plr_fframe_size; // idb +int plr_qframe_size; // idb +bool deathflag; // idb +int plr_hframe_size; // idb +int plr_bframe_size; // idb +char plr_gfx_bflag; // weak +int plr_sframe_size; // idb +int deathdelay; // weak +int plr_dframe_size; // idb +int plrmsg_ticks; // weak +char plr_msg_slot; // weak +_plrmsg plr_msgs[8]; +PortalStruct portal[4]; +int portalindex; +int END_portalstruct; // weak +int qtopline; // idb +int questlog; // weak +void *pQLogCel; +QuestStruct quests[16]; +int qline; // weak +int qlist[16]; +int numqlines; // weak +int WaterDone; // idb +int ReturnLvlY; // idb +int ReturnLvlX; // idb +int ReturnLvlT; // idb +int ALLQUESTS; // idb +int ReturnLvl; // idb +int light_table_index; // weak +int screen_y_times_768[1024]; +int scrollrt_cpp_init_value; // weak +unsigned int sgdwCursWdtOld; // idb +int sgdwCursX; // idb +int sgdwCursY; // idb +int screen_buf_end; // weak +int sgdwCursHgt; +int level_cel_block; // weak +int sgdwCursXOld; // idb +int sgdwCursYOld; // idb +char arch_draw_type; // weak +DDSURFACEDESC DDS_desc; +int cel_transparency_active; // weak +int level_piece_id; // weak +int sgdwCursWdt; +int (__fastcall *draw_player)(int player_num, int x, int y, int screen_x, int screen_y, void *cl2_buf, int frame, int frame_width, int a9, int a10); +char cursor_draw_back_buffer[8192]; +int draw_monster_num; // weak +int sgdwCursHgtOld; // idb +SHA1Context sha1_contexts[3]; +float sound_cpp_init_value; +IDirectSoundBuffer *DSBs[8]; +IDirectSound *sglpDS; +char gbSndInited; +int sglMusicVolume; +int sglSoundVolume; +HMODULE hDsound_dll; // idb +void *sgpMusicTrack; +int dword_69F100; // weak +int stextup; // weak +int storenumh; // weak +int stextlhold; // weak +ItemStruct boyitem; +int stextshold; // idb +ItemStruct premiumitem[6]; +void *pSTextBoxCels; +int premiumlevel; // idb +int talker; // weak +STextStruct stext[24]; +char stextsize; // weak +int stextsmax; // weak +int InStoreFlag; // idb +ItemStruct storehold[48]; +int gossipstart; // weak +ItemStruct witchitem[20]; +int stextscrl; // weak +int numpremium; // idb +ItemStruct healitem[20]; +ItemStruct golditem; +char storehidx[48]; +void *pSTextSlidCels; +int stextvhold; // weak +int stextsel; // weak +char stextscrldbtn; // weak +int gossipend; // weak +void *pCelBuff; +int stextsval; // idb +int boylevel; // weak +ItemStruct smithitem[20]; +int stextdown; // weak +char stextscrlubtn; // weak +char stextflag; // weak +short sync_word_6AA708[200]; +int dword_6AA898; // weak +short sync_word_6AA89C[200]; +int dword_6AAA2C[2]; +int sgnSyncPInv; // weak +int numthemes; // idb +int armorFlag; // weak +int ThemeGoodIn[4]; +int weaponFlag; // weak +int treasureFlag; // weak +int mFountainFlag; // weak +int cauldronFlag; // weak +int tFountainFlag; // weak +int zharlib; // weak +int themex; // idb +int themey; // idb +int themeVar1; // idb +ThemeStruct themes[50]; +int pFountainFlag; // weak +int bFountainFlag; // weak +int bCrossFlag; // weak +TMsg sgpTimedMsgHead; +int storeflag; // weak +int sgnCowMsg; // weak +int numtowners; // idb +int sgdwCowClicks; // weak +int unused_6AAC28; // weak +int boyloadflag; // weak +void *pCowCels; // idb +TownerStruct towner[16]; +char byte_6ABAB8; // weak +int track_cpp_init_value; // weak +int dword_6ABAC0; // weak +int dword_6ABAC4; // weak +int trigflag[5]; +TriggerStruct trigs[5]; +int TWarpFrom; // weak +int wave_cpp_init_value; // weak +int dword_6ABB9C; // weak + diff --git a/2018_03_14/DiabDev/defs.h b/2018_03_14/DiabDev/defs.h new file mode 100644 index 00000000..28eb3a62 --- /dev/null +++ b/2018_03_14/DiabDev/defs.h @@ -0,0 +1,382 @@ +/* + + This file contains definitions used by the Hex-Rays decompiler output. + It has type definitions and convenience macros to make the + output more readable. + + Copyright (c) 2007-2017 Hex-Rays + +*/ + +#ifndef HEXRAYS_DEFS_H +#define HEXRAYS_DEFS_H + +#if defined(__GNUC__) + typedef long long ll; + typedef unsigned long long ull; + #define __int64 long long + #define __int32 int + #define __int16 short + #define __int8 char + #define MAKELL(num) num ## LL + #define FMT_64 "ll" +#elif defined(_MSC_VER) + typedef __int64 ll; + typedef unsigned __int64 ull; + #define MAKELL(num) num ## i64 + #define FMT_64 "I64" +#elif defined (__BORLANDC__) + typedef __int64 ll; + typedef unsigned __int64 ull; + #define MAKELL(num) num ## i64 + #define FMT_64 "L" +#else + #error "unknown compiler" +#endif +typedef unsigned int uint; +typedef unsigned char uchar; +typedef unsigned short ushort; +typedef unsigned long ulong; + +typedef char int8; +typedef signed char sint8; +typedef unsigned char uint8; +typedef short int16; +typedef signed short sint16; +typedef unsigned short uint16; +typedef int int32; +typedef signed int sint32; +typedef unsigned int uint32; +typedef ll int64; +typedef ll sint64; +typedef ull uint64; + +// Partially defined types. They are used when the decompiler does not know +// anything about the type except its size. +#define _BYTE uint8 +#define _WORD uint16 +#define _DWORD uint32 +#define _QWORD uint64 +#if !defined(_MSC_VER) +#define _LONGLONG __int128 +#endif + +// Non-standard boolean types. They are used when the decompiler can not use +// the standard "bool" type because of the size mistmatch but the possible +// values are only 0 and 1. See also 'BOOL' type below. +typedef int8 _BOOL1; +typedef int16 _BOOL2; +typedef int32 _BOOL4; + +#ifndef _WINDOWS_ +typedef int8 BYTE; +typedef int16 WORD; +typedef int32 DWORD; +typedef int32 LONG; +typedef int BOOL; // uppercase BOOL is usually 4 bytes +#endif +typedef int64 QWORD; +#ifndef __cplusplus +typedef int bool; // we want to use bool in our C programs +#endif + +#define __pure // pure function: always returns the same value, has no + // side effects + +// Non-returning function +#if defined(__GNUC__) +#define __noreturn __attribute__((noreturn)) +#else +#define __noreturn __declspec(noreturn) +#endif + + +#ifndef NULL +#define NULL 0 +#endif + +// Some convenience macros to make partial accesses nicer +#define LAST_IND(x,part_type) (sizeof(x)/sizeof(part_type) - 1) +#if defined(__BYTE_ORDER) && __BYTE_ORDER == __BIG_ENDIAN +# define LOW_IND(x,part_type) LAST_IND(x,part_type) +# define HIGH_IND(x,part_type) 0 +#else +# define HIGH_IND(x,part_type) LAST_IND(x,part_type) +# define LOW_IND(x,part_type) 0 +#endif +// first unsigned macros: +#define BYTEn(x, n) (*((_BYTE*)&(x)+n)) +#define WORDn(x, n) (*((_WORD*)&(x)+n)) +#define DWORDn(x, n) (*((_DWORD*)&(x)+n)) + +#define _LOBYTE(x) BYTEn(x,LOW_IND(x,_BYTE)) +#define _LOWORD(x) WORDn(x,LOW_IND(x,_WORD)) +#define LODWORD(x) DWORDn(x,LOW_IND(x,_DWORD)) +#define _HIBYTE(x) BYTEn(x,HIGH_IND(x,_BYTE)) +#define _HIWORD(x) WORDn(x,HIGH_IND(x,_WORD)) +#define HIDWORD(x) DWORDn(x,HIGH_IND(x,_DWORD)) +#define BYTE1(x) BYTEn(x, 1) // byte 1 (counting from 0) +#define BYTE2(x) BYTEn(x, 2) +#define BYTE3(x) BYTEn(x, 3) +#define BYTE4(x) BYTEn(x, 4) +#define BYTE5(x) BYTEn(x, 5) +#define BYTE6(x) BYTEn(x, 6) +#define BYTE7(x) BYTEn(x, 7) +#define BYTE8(x) BYTEn(x, 8) +#define BYTE9(x) BYTEn(x, 9) +#define BYTE10(x) BYTEn(x, 10) +#define BYTE11(x) BYTEn(x, 11) +#define BYTE12(x) BYTEn(x, 12) +#define BYTE13(x) BYTEn(x, 13) +#define BYTE14(x) BYTEn(x, 14) +#define BYTE15(x) BYTEn(x, 15) +#define WORD1(x) WORDn(x, 1) +#define WORD2(x) WORDn(x, 2) // third word of the object, unsigned +#define WORD3(x) WORDn(x, 3) +#define WORD4(x) WORDn(x, 4) +#define WORD5(x) WORDn(x, 5) +#define WORD6(x) WORDn(x, 6) +#define WORD7(x) WORDn(x, 7) + +// now signed macros (the same but with sign extension) +#define SBYTEn(x, n) (*((int8*)&(x)+n)) +#define SWORDn(x, n) (*((int16*)&(x)+n)) +#define SDWORDn(x, n) (*((int32*)&(x)+n)) + +#define SLOBYTE(x) SBYTEn(x,LOW_IND(x,int8)) +#define SLOWORD(x) SWORDn(x,LOW_IND(x,int16)) +#define SLODWORD(x) SDWORDn(x,LOW_IND(x,int32)) +#define SHIBYTE(x) SBYTEn(x,HIGH_IND(x,int8)) +#define SHIWORD(x) SWORDn(x,HIGH_IND(x,int16)) +#define SHIDWORD(x) SDWORDn(x,HIGH_IND(x,int32)) +#define SBYTE1(x) SBYTEn(x, 1) +#define SBYTE2(x) SBYTEn(x, 2) +#define SBYTE3(x) SBYTEn(x, 3) +#define SBYTE4(x) SBYTEn(x, 4) +#define SBYTE5(x) SBYTEn(x, 5) +#define SBYTE6(x) SBYTEn(x, 6) +#define SBYTE7(x) SBYTEn(x, 7) +#define SBYTE8(x) SBYTEn(x, 8) +#define SBYTE9(x) SBYTEn(x, 9) +#define SBYTE10(x) SBYTEn(x, 10) +#define SBYTE11(x) SBYTEn(x, 11) +#define SBYTE12(x) SBYTEn(x, 12) +#define SBYTE13(x) SBYTEn(x, 13) +#define SBYTE14(x) SBYTEn(x, 14) +#define SBYTE15(x) SBYTEn(x, 15) +#define SWORD1(x) SWORDn(x, 1) +#define SWORD2(x) SWORDn(x, 2) +#define SWORD3(x) SWORDn(x, 3) +#define SWORD4(x) SWORDn(x, 4) +#define SWORD5(x) SWORDn(x, 5) +#define SWORD6(x) SWORDn(x, 6) +#define SWORD7(x) SWORDn(x, 7) + + +// Helper functions to represent some assembly instructions. + +#ifdef __cplusplus + +// compile time assertion +#define __CASSERT_N0__(l) COMPILE_TIME_ASSERT_ ## l +#define __CASSERT_N1__(l) __CASSERT_N0__(l) +#define CASSERT(cnd) typedef char __CASSERT_N1__(__LINE__) [(cnd) ? 1 : -1] + +// check that unsigned multiplication does not overflow +template bool is_mul_ok(T count, T elsize) +{ + CASSERT((T)(-1) > 0); // make sure T is unsigned + if ( elsize == 0 || count == 0 ) + return true; + return count <= ((T)(-1)) / elsize; +} + +// multiplication that saturates (yields the biggest value) instead of overflowing +// such a construct is useful in "operator new[]" +template bool saturated_mul(T count, T elsize) +{ + return is_mul_ok(count, elsize) ? count * elsize : T(-1); +} + +#include // for size_t + +// memcpy() with determined behavoir: it always copies +// from the start to the end of the buffer +// note: it copies byte by byte, so it is not equivalent to, for example, rep movsd +inline void *qmemcpy(void *dst, const void *src, size_t cnt) +{ + char *out = (char *)dst; + const char *in = (const char *)src; + while ( cnt > 0 ) + { + *out++ = *in++; + --cnt; + } + return dst; +} + +// Generate a reference to pair of operands +template int16 __PAIR__( int8 high, T low) { return ((( int16)high) << sizeof(high)*8) | uint8(low); } +template int32 __PAIR__( int16 high, T low) { return ((( int32)high) << sizeof(high)*8) | uint16(low); } +template int64 __PAIR__( int32 high, T low) { return ((( int64)high) << sizeof(high)*8) | uint32(low); } +template uint16 __PAIR__(uint8 high, T low) { return (((uint16)high) << sizeof(high)*8) | uint8(low); } +template uint32 __PAIR__(uint16 high, T low) { return (((uint32)high) << sizeof(high)*8) | uint16(low); } +template uint64 __PAIR__(uint32 high, T low) { return (((uint64)high) << sizeof(high)*8) | uint32(low); } + +// rotate left +template T __ROL__(T value, int count) +{ + const uint nbits = sizeof(T) * 8; + + if ( count > 0 ) + { + count %= nbits; + T high = value >> (nbits - count); + if ( T(-1) < 0 ) // signed value + high &= ~((T(-1) << count)); + value <<= count; + value |= high; + } + else + { + count = -count % nbits; + T low = value << (nbits - count); + value >>= count; + value |= low; + } + return value; +} + +inline uint8 __ROL1__(uint8 value, int count) { return __ROL__((uint8)value, count); } +inline uint16 __ROL2__(uint16 value, int count) { return __ROL__((uint16)value, count); } +inline uint32 __ROL4__(uint32 value, int count) { return __ROL__((uint32)value, count); } +inline uint64 __ROL8__(uint64 value, int count) { return __ROL__((uint64)value, count); } +inline uint8 __ROR1__(uint8 value, int count) { return __ROL__((uint8)value, -count); } +inline uint16 __ROR2__(uint16 value, int count) { return __ROL__((uint16)value, -count); } +inline uint32 __ROR4__(uint32 value, int count) { return __ROL__((uint32)value, -count); } +inline uint64 __ROR8__(uint64 value, int count) { return __ROL__((uint64)value, -count); } + +// carry flag of left shift +template int8 __MKCSHL__(T value, uint count) +{ + const uint nbits = sizeof(T) * 8; + count %= nbits; + + return (value >> (nbits-count)) & 1; +} + +// carry flag of right shift +template int8 __MKCSHR__(T value, uint count) +{ + return (value >> (count-1)) & 1; +} + +// sign flag +template int8 __SETS__(T x) +{ + if ( sizeof(T) == 1 ) + return int8(x) < 0; + if ( sizeof(T) == 2 ) + return int16(x) < 0; + if ( sizeof(T) == 4 ) + return int32(x) < 0; + return int64(x) < 0; +} + +// overflow flag of subtraction (x-y) +template int8 __OFSUB__(T x, U y) +{ + if ( sizeof(T) < sizeof(U) ) + { + U x2 = x; + int8 sx = __SETS__(x2); + return (sx ^ __SETS__(y)) & (sx ^ __SETS__(x2-y)); + } + else + { + T y2 = y; + int8 sx = __SETS__(x); + return (sx ^ __SETS__(y2)) & (sx ^ __SETS__(x-y2)); + } +} + +// overflow flag of addition (x+y) +template int8 __OFADD__(T x, U y) +{ + if ( sizeof(T) < sizeof(U) ) + { + U x2 = x; + int8 sx = __SETS__(x2); + return ((1 ^ sx) ^ __SETS__(y)) & (sx ^ __SETS__(x2+y)); + } + else + { + T y2 = y; + int8 sx = __SETS__(x); + return ((1 ^ sx) ^ __SETS__(y2)) & (sx ^ __SETS__(x+y2)); + } +} + +// carry flag of subtraction (x-y) +template int8 __CFSUB__(T x, U y) +{ + int size = sizeof(T) > sizeof(U) ? sizeof(T) : sizeof(U); + if ( size == 1 ) + return uint8(x) < uint8(y); + if ( size == 2 ) + return uint16(x) < uint16(y); + if ( size == 4 ) + return uint32(x) < uint32(y); + return uint64(x) < uint64(y); +} + +// carry flag of addition (x+y) +template int8 __CFADD__(T x, U y) +{ + int size = sizeof(T) > sizeof(U) ? sizeof(T) : sizeof(U); + if ( size == 1 ) + return uint8(x) > uint8(x+y); + if ( size == 2 ) + return uint16(x) > uint16(x+y); + if ( size == 4 ) + return uint32(x) > uint32(x+y); + return uint64(x) > uint64(x+y); +} + +#else +// The following definition is not quite correct because it always returns +// uint64. The above C++ functions are good, though. +#define __PAIR__(high, low) (((uint64)(high)<>y) // Generate carry flag for (x>>y) +#define __CFADD__(x, y) invalid_operation // Generate carry flag for (x+y) +#define __CFSUB__(x, y) invalid_operation // Generate carry flag for (x-y) +#define __OFADD__(x, y) invalid_operation // Generate overflow flag for (x+y) +#define __OFSUB__(x, y) invalid_operation // Generate overflow flag for (x-y) +#endif + +#define __CFSHL__(x, y) ((x)<<(y)) // Generate carry flag for (x<>(y)) // Generate carry flag for (x>>y) +// No definition for rcl/rcr because the carry flag is unknown +#define __RCL__(x, y) invalid_operation // Rotate left thru carry +#define __RCR__(x, y) invalid_operation // Rotate right thru carry +#define __MKCRCL__(x, y) invalid_operation // Generate carry flag for a RCL +#define __MKCRCR__(x, y) invalid_operation // Generate carry flag for a RCR +#define __SETP__(x, y) invalid_operation // Generate parity flag for (x-y) + +// In the decompilation listing there are some objects declarared as _UNKNOWN +// because we could not determine their types. Since the C compiler does not +// accept void item declarations, we replace them by anything of our choice, +// for example a char: + +#define _UNKNOWN char + +#ifdef _MSC_VER +#define snprintf _snprintf +#define vsnprintf _vsnprintf +#endif + +#endif // HEXRAYS_DEFS_H diff --git a/2018_03_14/DiabDev/diablo.h b/2018_03_14/DiabDev/diablo.h new file mode 100644 index 00000000..56e89632 --- /dev/null +++ b/2018_03_14/DiabDev/diablo.h @@ -0,0 +1,6439 @@ +/* + This file has been generated by IDA. + It contains local type definitions from + the type library 'Diablo' +*/ + +struct HWND__; +struct _RTL_CRITICAL_SECTION_DEBUG; +struct tagWNDCLASSEXA; +struct HINSTANCE__; +struct HICON__; +struct HBRUSH__; +struct _iobuf; +struct _GUID; +struct ITypeInfo; +struct ITypeInfoVtbl; +struct tagTYPEATTR; +struct tagTYPEDESC; +struct ITypeComp; +struct ITypeCompVtbl; +union tagBINDPTR; +struct tagFUNCDESC; +struct tagELEMDESC; +struct tagPARAMDESCEX; +struct tagVARIANT; +struct IUnknown; +struct IUnknownVtbl; +struct IDispatch; +struct IDispatchVtbl; +struct tagDISPPARAMS; +struct tagEXCEPINFO; +struct tagSAFEARRAY; +struct tagDEC; +struct IRecordInfo; +struct IRecordInfoVtbl; +struct tagVARDESC; +struct ITypeLib; +struct ITypeLibVtbl; +struct tagTLIBATTR; +struct CMonster; +struct _DDSURFACEDESC; +struct IDirectSoundBuffer; +struct tagVS_FIXEDFILEINFO; +struct TSnd; +struct pcmwaveformat_tag; +struct IDirectDrawSurface; +struct _DDBLTFX; +struct _DDBLTBATCH; +struct IDirectDrawClipper; +struct IDirectDrawClipperVtbl; +struct _RGNDATA; +struct IDirectDraw; +struct IDirectDrawVtbl; +struct IDirectDrawPalette; +struct IDirectDrawPaletteVtbl; +struct _DDCAPS; +struct HDC__; +struct _DDOVERLAYFX; + +/* 1 */ +struct _SCOPETABLE_ENTRY +{ + int EnclosingLevel; + void *FilterFunc; + void *HandlerFunc; +}; + +/* 2 */ +typedef struct _SCOPETABLE_ENTRY *PSCOPETABLE_ENTRY; + +/* 36 */ +typedef void *PVOID; + +/* 15 */ +//typedef unsigned __int32 DWORD; + +/* 3 */ +struct _EH3_EXCEPTION_REGISTRATION +{ + struct _EH3_EXCEPTION_REGISTRATION *Next; + PVOID ExceptionHandler; + PSCOPETABLE_ENTRY ScopeTable; + DWORD TryLevel; +}; + +/* 4 */ +typedef struct _EH3_EXCEPTION_REGISTRATION EH3_EXCEPTION_REGISTRATION; + +/* 5 */ +typedef struct _EH3_EXCEPTION_REGISTRATION *PEH3_EXCEPTION_REGISTRATION; + +/* 6 */ +struct CPPEH_RECORD +{ + DWORD old_esp; + EXCEPTION_POINTERS *exc_ptr; + struct _EH3_EXCEPTION_REGISTRATION registration; +}; + +/* 8 */ +//typedef __int32 LONG; + +// /* 7 */ +// struct tagRECT +// { + // LONG left; + // LONG top; + // LONG right; + // LONG bottom; +// }; + +/* 10 */ +typedef HWND__ *HWND; + +/* 12 */ +typedef unsigned int UINT; + +/* 13 */ +typedef UINT WPARAM; + +/* 14 */ +typedef LONG LPARAM; + +/* 17 */ +/* struct tagPOINT +{ + LONG x; + LONG y; +}; */ + +/* 16 */ +typedef tagPOINT POINT; + +/* 9 */ +/* struct tagMSG +{ + HWND hwnd; + UINT message; + WPARAM wParam; + LPARAM lParam; + DWORD time; + POINT pt; +}; */ + +/* 11 */ +// struct HWND__ +// { + // int unused; +// }; + +/* 21 */ +// typedef unsigned short WORD; + +/* 20 */ +// struct _SYSTEM_INFO::$A707B71C060B6D10F73A71917EA8473F::$AA04DEB0C6383F89F13D312A174572A9 +// { + // WORD wProcessorArchitecture; + // WORD wReserved; +// }; + +/* 19 */ +/* union _SYSTEM_INFO::$A707B71C060B6D10F73A71917EA8473F +{ + DWORD dwOemId; + struct + { + WORD wProcessorArchitecture; + WORD wReserved; + }; +}; */ + +/* 22 */ +typedef void *LPVOID; + +/* 18 */ +// struct _SYSTEM_INFO +// { + // union + // { + // DWORD dwOemId; + // struct + // { + // WORD wProcessorArchitecture; + // WORD wReserved; + // }; + // }; + // DWORD dwPageSize; + // LPVOID lpMinimumApplicationAddress; + // LPVOID lpMaximumApplicationAddress; + // DWORD dwActiveProcessorMask; + // DWORD dwNumberOfProcessors; + // DWORD dwProcessorType; + // DWORD dwAllocationGranularity; + // WORD wProcessorLevel; + // WORD wProcessorRevision; +// }; + +/* 25 */ +typedef char CHAR; + +/* 24 */ +typedef CHAR *LPSTR; + +/* 27 */ +/* typedef unsigned char BYTE; + */ +/* 26 */ +typedef BYTE *LPBYTE; + +/* 28 */ +typedef void *HANDLE; + +/* 23 */ +/* struct _STARTUPINFOA +{ + DWORD cb; + LPSTR lpReserved; + LPSTR lpDesktop; + LPSTR lpTitle; + DWORD dwX; + DWORD dwY; + DWORD dwXSize; + DWORD dwYSize; + DWORD dwXCountChars; + DWORD dwYCountChars; + DWORD dwFillAttribute; + DWORD dwFlags; + WORD wShowWindow; + WORD cbReserved2; + LPBYTE lpReserved2; + HANDLE hStdInput; + HANDLE hStdOutput; + HANDLE hStdError; +}; */ + +/* 29 */ +/* struct _PROCESS_INFORMATION +{ + HANDLE hProcess; + HANDLE hThread; + DWORD dwProcessId; + DWORD dwThreadId; +}; */ + + + +/* 45 */ +typedef LONG LRESULT; + +/* 44 */ +typedef LRESULT (__stdcall *WNDPROC)(HWND, UINT, WPARAM, LPARAM); + +/* 46 */ +typedef HINSTANCE__ *HINSTANCE; + +/* 48 */ +typedef HICON__ *HICON; + +/* 50 */ +typedef HICON HCURSOR; + +/* 51 */ +typedef HBRUSH__ *HBRUSH; + +/* 53 */ +typedef const CHAR *LPCSTR; + +/* 43 */ +/* struct tagWNDCLASSEXA +{ + UINT cbSize; + UINT style; + WNDPROC lpfnWndProc; + int cbClsExtra; + int cbWndExtra; + HINSTANCE hInstance; + HICON hIcon; + HCURSOR hCursor; + HBRUSH hbrBackground; + LPCSTR lpszMenuName; + LPCSTR lpszClassName; + HICON hIconSm; +}; */ + +/* 47 */ +/* struct HINSTANCE__ +{ + int unused; +}; */ + +/* 49 */ +/* struct HICON__ +{ + int unused; +}; */ + +/* 52 */ +/* struct HBRUSH__ +{ + int unused; +}; */ + +/* 54 */ +typedef tagMSG MSG; + +/* 55 */ +/* struct _SYSTEMTIME +{ + WORD wYear; + WORD wMonth; + WORD wDayOfWeek; + WORD wDay; + WORD wHour; + WORD wMinute; + WORD wSecond; + WORD wMilliseconds; +}; */ + +/* 56 */ +/* struct tagPALETTEENTRY +{ + BYTE peRed; + BYTE peGreen; + BYTE peBlue; + BYTE peFlags; +}; */ + +/* 57 */ +/* struct _OFSTRUCT +{ + BYTE cBytes; + BYTE fFixedDisk; + WORD nErrCode; + WORD Reserved1; + WORD Reserved2; + CHAR szPathName[128]; +}; */ + +/* 58 */ +/* struct _OSVERSIONINFOA +{ + DWORD dwOSVersionInfoSize; + DWORD dwMajorVersion; + DWORD dwMinorVersion; + DWORD dwBuildNumber; + DWORD dwPlatformId; + CHAR szCSDVersion[128]; +}; */ + +/* 61 */ +/* typedef unsigned short wchar_t; + */ +/* 60 */ +typedef wchar_t WCHAR; + +/* 62 */ +typedef _SYSTEMTIME SYSTEMTIME; + +/* 59 */ +/* struct _TIME_ZONE_INFORMATION +{ + LONG Bias; + WCHAR StandardName[32]; + SYSTEMTIME StandardDate; + LONG StandardBias; + WCHAR DaylightName[32]; + SYSTEMTIME DaylightDate; + LONG DaylightBias; +}; */ + +/* 63 */ +/* struct _cpinfo +{ + UINT MaxCharSize; + BYTE DefaultChar[2]; + BYTE LeadByte[12]; +}; */ + +/* 65 */ +typedef int BOOL; + +/* 64 */ +/* struct _SECURITY_ATTRIBUTES +{ + DWORD nLength; + LPVOID lpSecurityDescriptor; + BOOL bInheritHandle; +}; */ + +/* 67 */ +/* typedef __int32 time_t; + */ +/* 68 */ +/* typedef unsigned __int32 _fsize_t; + */ +/* 66 */ +#pragma pack(push, 8) +/* struct _finddata_t +{ + unsigned int attrib; + time_t time_create; + time_t time_access; + time_t time_write; + _fsize_t size; + char name[260]; +}; */ +#pragma pack(pop) + +/* 69 */ +typedef _iobuf FILE; + +/* 70 */ +#pragma pack(push, 8) +/* struct _iobuf +{ + char *_ptr; + int _cnt; + char *_base; + int _flag; + int _file; + int _charbuf; + int _bufsiz; + char *_tmpfname; +}; */ +#pragma pack(pop) + +/* 71 */ +/* struct type_info; + */ +/* 72 */ +/* union __declspec(align(8)) __m64 +{ + unsigned __int64 m64_u64; + float m64_f32[2]; + char m64_i8[8]; + short m64_i16[4]; + __int32 m64_i32[2]; + __int64 m64_i64; + unsigned char m64_u8[8]; + unsigned short m64_u16[4]; + unsigned __int32 m64_u32[2]; +}; */ + +/* 73 */ +/* union __declspec(align(16)) __m128 +{ + float m128_f32[4]; + unsigned __int64 m128_u64[2]; + char m128_i8[16]; + short m128_i16[8]; + __int32 m128_i32[4]; + __int64 m128_i64[2]; + unsigned char m128_u8[16]; + unsigned short m128_u16[8]; + unsigned __int32 m128_u32[4]; +}; */ + +/* 74 */ +/* struct __m128d +{ + double m128d_f64[2]; +}; */ + +/* 75 */ +/* union __declspec(align(16)) __m128i +{ + char m128i_i8[16]; + short m128i_i16[8]; + __int32 m128i_i32[4]; + __int64 m128i_i64[2]; + unsigned char m128i_u8[16]; + unsigned short m128i_u16[8]; + unsigned __int32 m128i_u32[4]; + unsigned __int64 m128i_u64[2]; +}; */ + +/* 201 */ +enum unique_base_item +{ + UITYPE_NONE = 0x0, + UITYPE_SHORTBOW = 0x1, + UITYPE_LONGBOW = 0x2, + UITYPE_HUNTBOW = 0x3, + UITYPE_COMPBOW = 0x4, + UITYPE_WARBOW = 0x5, + UITYPE_BATTLEBOW = 0x6, + UITYPE_DAGGER = 0x7, + UITYPE_FALCHION = 0x8, + UITYPE_CLAYMORE = 0x9, + UITYPE_BROADSWR = 0xA, + UITYPE_SABRE = 0xB, + UITYPE_SCIMITAR = 0xC, + UITYPE_LONGSWR = 0xD, + UITYPE_BASTARDSWR = 0xE, + UITYPE_TWOHANDSWR = 0xF, + UITYPE_GREATSWR = 0x10, + UITYPE_CLEAVER = 0x11, + UITYPE_LARGEAXE = 0x12, + UITYPE_BROADAXE = 0x13, + UITYPE_SMALLAXE = 0x14, + UITYPE_BATTLEAXE = 0x15, + UITYPE_GREATAXE = 0x16, + UITYPE_MACE = 0x17, + UITYPE_MORNSTAR = 0x18, + UITYPE_SPIKCLUB = 0x19, + UITYPE_MAUL = 0x1A, + UITYPE_WARHAMMER = 0x1B, + UITYPE_FLAIL = 0x1C, + UITYPE_LONGSTAFF = 0x1D, + UITYPE_SHORTSTAFF = 0x1E, + UITYPE_COMPSTAFF = 0x1F, + UITYPE_QUARSTAFF = 0x20, + UITYPE_WARSTAFF = 0x21, + UITYPE_SKULLCAP = 0x22, + UITYPE_HELM = 0x23, + UITYPE_GREATHELM = 0x24, + UITYPE_CROWN = 0x25, + UITYPE_38 = 0x26, + UITYPE_RAGS = 0x27, + UITYPE_STUDARMOR = 0x28, + UITYPE_CLOAK = 0x29, + UITYPE_ROBE = 0x2A, + UITYPE_CHAINMAIL = 0x2B, + UITYPE_LEATHARMOR = 0x2C, + UITYPE_BREASTPLATE = 0x2D, + UITYPE_CAPE = 0x2E, + UITYPE_PLATEMAIL = 0x2F, + UITYPE_FULLPLATE = 0x30, + UITYPE_BUCKLER = 0x31, + UITYPE_SMALLSHIELD = 0x32, + UITYPE_LARGESHIELD = 0x33, + UITYPE_KITESHIELD = 0x34, + UITYPE_GOTHSHIELD = 0x35, + UITYPE_RING = 0x36, + UITYPE_55 = 0x37, + UITYPE_AMULET = 0x38, + UITYPE_SKCROWN = 0x39, + UITYPE_INFRARING = 0x3A, + UITYPE_OPTAMULET = 0x3B, + UITYPE_TRING = 0x3C, + UITYPE_HARCREST = 0x3D, + UITYPE_MAPOFDOOM = 0x3E, + UITYPE_ELIXIR = 0x3F, + UITYPE_ARMOFVAL = 0x40, + UITYPE_STEELVEIL = 0x41, + UITYPE_GRISWOLD = 0x42, + UITYPE_LGTFORGE = 0x43, + UITYPE_LAZSTAFF = 0x44, + UITYPE_INVALID = 0xFF, +}; + +/* 202 */ +enum item_effect_type +{ + IPL_TOHIT = 0x0, + IPL_TOHIT_CURSE = 0x1, + IPL_DAMP = 0x2, + IPL_DAMP_CURSE = 0x3, + IPL_TOHIT_DAMP = 0x4, + IPL_TOHIT_DAMP_CURSE = 0x5, + IPL_ACP = 0x6, + IPL_ACP_CURSE = 0x7, + IPL_FIRERES = 0x8, + IPL_LIGHTRES = 0x9, + IPL_MAGICRES = 0xA, + IPL_ALLRES = 0xB, + IPL_SPLLVLADD = 0xE, + IPL_CHARGES = 0xF, + IPL_FIREDAM = 0x10, + IPL_LIGHTDAM = 0x11, + IPL_STR = 0x13, + IPL_STR_CURSE = 0x14, + IPL_MAG = 0x15, + IPL_MAG_CURSE = 0x16, + IPL_DEX = 0x17, + IPL_DEX_CURSE = 0x18, + IPL_VIT = 0x19, + IPL_VIT_CURSE = 0x1A, + IPL_ATTRIBS = 0x1B, + IPL_ATTRIBS_CURSE = 0x1C, + IPL_GETHIT = 0x1D, + IPL_GETHIT_CURSE = 0x1E, + IPL_LIFE = 0x1F, + IPL_LIFE_CURSE = 0x20, + IPL_MANA = 0x21, + IPL_MANA_CURSE = 0x22, + IPL_DUR = 0x23, + IPL_DUR_CURSE = 0x24, + IPL_INDESTRUCTIBLE = 0x25, + IPL_LIGHT = 0x26, + IPL_LIGHT_CURSE = 0x27, + IPL_FIRE_ARROWS = 0x2A, + IPL_LIGHT_ARROWS = 0x2B, + IPL_INVCURS = 0x2C, + IPL_THORNS = 0x2D, + IPL_NOMANA = 0x2E, + IPL_NOHEALPLR = 0x2F, + IPL_ABSHALFTRAP = 0x34, + IPL_KNOCKBACK = 0x35, + IPL_NOHEALMON = 0x36, + IPL_STEALMANA = 0x37, + IPL_STEALLIFE = 0x38, + IPL_TARGAC = 0x39, + IPL_FASTATTACK = 0x3A, + IPL_FASTRECOVER = 0x3B, + IPL_FASTBLOCK = 0x3C, + IPL_DAMMOD = 0x3D, + IPL_RNDARROWVEL = 0x3E, + IPL_SETDAM = 0x3F, + IPL_SETDUR = 0x40, + IPL_NOMINSTR = 0x41, + IPL_SPELL = 0x42, + IPL_FASTSWING = 0x43, + IPL_ONEHAND = 0x44, + IPL_3XDAMVDEM = 0x45, + IPL_ALLRESZERO = 0x46, + IPL_DRAINLIFE = 0x48, + IPL_RNDSTEALLIFE = 0x49, + IPL_INFRAVISION = 0x4A, + IPL_SETAC = 0x4B, + IPL_ADDACLIFE = 0x4C, + IPL_ADDMANAAC = 0x4D, + IPL_FIRERESCLVL = 0x4E, + IPL_AC_CURSE = 0x4F, + IPL_INVALID = 0xFF, +}; + +/* 76 */ +struct UItemStruct +{ + char *UIName; + char UIItemId; + unsigned char UIMinLvl; + unsigned char UINumPL; + int UIValue; + char UIPower1; + int UIParam1; + int UIParam2; + char UIPower2; + int UIParam3; + int UIParam4; + char UIPower3; + int UIParam5; + int UIParam6; + char UIPower4; + int UIParam7; + int UIParam8; + char UIPower5; + int UIParam9; + int UIParam10; + char UIPower6; + int UIParam11; + int UIParam12; +}; + +/* 205 */ +enum affix_item_type +{ + PLT_MISC = 0x1, + PLT_BOW = 0x10, + PLT_STAFF = 0x100, + PLT_WEAP = 0x1000, + PLT_SHLD = 0x10000, + PLT_ARMO = 0x100000, +}; + +/* 79 */ +struct PLStruct +{ + const char *PLName; + char PLPower; + int PLParam1; + int PLParam2; + int PLMinLvl; + int PLIType; + int PLGOE; + int PLDouble; + int PLOk; + int PLMinVal; + int PLMaxVal; + int PLMultVal; +}; + +/* 321 */ +enum _sfx_id +{ + PS_WALK1 = 0x0, + PS_WALK2 = 0x1, + PS_WALK3 = 0x2, + PS_WALK4 = 0x3, + PS_BFIRE = 0x4, + PS_FMAG = 0x5, + PS_TMAG = 0x6, + PS_LGHIT = 0x7, + PS_LGHIT1 = 0x8, + PS_SWING = 0x9, + PS_SWING2 = 0xA, + PS_DEAD = 0xB, + IS_QUESTDN = 0xC, + IS_ARMRFKD = 0xD, + IS_BARLFIRE = 0xE, + IS_BARREL = 0xF, + IS_BHIT = 0x10, + IS_BHIT1 = 0x11, + IS_CHEST = 0x12, + IS_DOORCLOS = 0x13, + IS_DOOROPEN = 0x14, + IS_FANVL = 0x15, + IS_FAXE = 0x16, + IS_FBLST = 0x17, + IS_FBODY = 0x18, + IS_FBOOK = 0x19, + IS_FBOW = 0x1A, + IS_FCAP = 0x1B, + IS_FHARM = 0x1C, + IS_FLARM = 0x1D, + IS_FMAG = 0x1E, + IS_FMAG1 = 0x1F, + IS_FMUSH = 0x20, + IS_FPOT = 0x21, + IS_FRING = 0x22, + IS_FROCK = 0x23, + IS_FSCRL = 0x24, + IS_FSHLD = 0x25, + IS_FSIGN = 0x26, + IS_FSTAF = 0x27, + IS_FSWOR = 0x28, + IS_GOLD = 0x29, + IS_HLMTFKD = 0x2A, + IS_IANVL = 0x2B, + IS_IAXE = 0x2C, + IS_IBLST = 0x2D, + IS_IBODY = 0x2E, + IS_IBOOK = 0x2F, + IS_IBOW = 0x30, + IS_ICAP = 0x31, + IS_IGRAB = 0x32, + IS_IHARM = 0x33, + IS_ILARM = 0x34, + IS_IMUSH = 0x35, + IS_IPOT = 0x36, + IS_IRING = 0x37, + IS_IROCK = 0x38, + IS_ISCROL = 0x39, + IS_ISHIEL = 0x3A, + IS_ISIGN = 0x3B, + IS_ISTAF = 0x3C, + IS_ISWORD = 0x3D, + IS_LEVER = 0x3E, + IS_MAGIC = 0x3F, + IS_MAGIC1 = 0x40, + IS_RBOOK = 0x41, + IS_SARC = 0x42, + IS_SHLDFKD = 0x43, + IS_SWRDFKD = 0x44, + IS_TITLEMOV = 0x45, + IS_TITLSLCT = 0x46, + SFX_SILENCE = 0x47, + IS_TRAP = 0x48, + IS_CAST1 = 0x49, + IS_CAST10 = 0x4A, + IS_CAST12 = 0x4B, + IS_CAST2 = 0x4C, + IS_CAST3 = 0x4D, + IS_CAST4 = 0x4E, + IS_CAST5 = 0x4F, + IS_CAST6 = 0x50, + IS_CAST7 = 0x51, + IS_CAST8 = 0x52, + IS_CAST9 = 0x53, + LS_HEALING = 0x54, + IS_REPAIR = 0x55, + LS_ACID = 0x56, + LS_ACIDS = 0x57, + LS_APOC = 0x58, + LS_ARROWALL = 0x59, + LS_BLODBOIL = 0x5A, + LS_BLODSTAR = 0x5B, + LS_BLSIMPT = 0x5C, + LS_BONESP = 0x5D, + LS_BSIMPCT = 0x5E, + LS_CALDRON = 0x5F, + LS_CBOLT = 0x60, + LS_CHLTNING = 0x61, + LS_DSERP = 0x62, + LS_ELECIMP1 = 0x63, + LS_ELEMENTL = 0x64, + LS_ETHEREAL = 0x65, + LS_FBALL = 0x66, + LS_FBOLT1 = 0x67, + LS_FBOLT2 = 0x68, + LS_FIRIMP1 = 0x69, + LS_FIRIMP2 = 0x6A, + LS_FLAMWAVE = 0x6B, + LS_FLASH = 0x6C, + LS_FOUNTAIN = 0x6D, + LS_GOLUM = 0x6E, + LS_GOLUMDED = 0x6F, + LS_GSHRINE = 0x70, + LS_GUARD = 0x71, + LS_GUARDLAN = 0x72, + LS_HOLYBOLT = 0x73, + LS_HYPER = 0x74, + LS_INFRAVIS = 0x75, + LS_INVISIBL = 0x76, + LS_INVPOT = 0x77, + LS_LNING1 = 0x78, + LS_LTNING = 0x79, + LS_MSHIELD = 0x7A, + LS_NOVA = 0x7B, + LS_PORTAL = 0x7C, + LS_PUDDLE = 0x7D, + LS_RESUR = 0x7E, + LS_SCURSE = 0x7F, + LS_SCURIMP = 0x80, + LS_SENTINEL = 0x81, + LS_SHATTER = 0x82, + LS_SOULFIRE = 0x83, + LS_SPOUTLOP = 0x84, + LS_SPOUTSTR = 0x85, + LS_STORM = 0x86, + LS_TRAPDIS = 0x87, + LS_TELEPORT = 0x88, + LS_VTHEFT = 0x89, + LS_WALLLOOP = 0x8A, + LS_WALLSTRT = 0x8B, + TSFX_BMAID1 = 0x8C, + TSFX_BMAID2 = 0x8D, + TSFX_BMAID3 = 0x8E, + TSFX_BMAID4 = 0x8F, + TSFX_BMAID5 = 0x90, + TSFX_BMAID6 = 0x91, + TSFX_BMAID7 = 0x92, + TSFX_BMAID8 = 0x93, + TSFX_BMAID9 = 0x94, + TSFX_BMAID10 = 0x95, + TSFX_BMAID11 = 0x96, + TSFX_BMAID12 = 0x97, + TSFX_BMAID13 = 0x98, + TSFX_BMAID14 = 0x99, + TSFX_BMAID15 = 0x9A, + TSFX_BMAID16 = 0x9B, + TSFX_BMAID17 = 0x9C, + TSFX_BMAID18 = 0x9D, + TSFX_BMAID19 = 0x9E, + TSFX_BMAID20 = 0x9F, + TSFX_BMAID21 = 0xA0, + TSFX_BMAID22 = 0xA1, + TSFX_BMAID23 = 0xA2, + TSFX_BMAID24 = 0xA3, + TSFX_BMAID25 = 0xA4, + TSFX_BMAID26 = 0xA5, + TSFX_BMAID27 = 0xA6, + TSFX_BMAID28 = 0xA7, + TSFX_BMAID29 = 0xA8, + TSFX_BMAID30 = 0xA9, + TSFX_BMAID31 = 0xAA, + TSFX_BMAID32 = 0xAB, + TSFX_BMAID33 = 0xAC, + TSFX_BMAID34 = 0xAD, + TSFX_BMAID35 = 0xAE, + TSFX_BMAID36 = 0xAF, + TSFX_BMAID37 = 0xB0, + TSFX_BMAID38 = 0xB1, + TSFX_BMAID39 = 0xB2, + TSFX_BMAID40 = 0xB3, + TSFX_SMITH1 = 0xB4, + TSFX_SMITH2 = 0xB5, + TSFX_SMITH3 = 0xB6, + TSFX_SMITH4 = 0xB7, + TSFX_SMITH5 = 0xB8, + TSFX_SMITH6 = 0xB9, + TSFX_SMITH7 = 0xBA, + TSFX_SMITH8 = 0xBB, + TSFX_SMITH9 = 0xBC, + TSFX_SMITH10 = 0xBD, + TSFX_SMITH11 = 0xBE, + TSFX_SMITH12 = 0xBF, + TSFX_SMITH13 = 0xC0, + TSFX_SMITH14 = 0xC1, + TSFX_SMITH15 = 0xC2, + TSFX_SMITH16 = 0xC3, + TSFX_SMITH17 = 0xC4, + TSFX_SMITH18 = 0xC5, + TSFX_SMITH19 = 0xC6, + TSFX_SMITH20 = 0xC7, + TSFX_SMITH21 = 0xC8, + TSFX_SMITH22 = 0xC9, + TSFX_SMITH23 = 0xCA, + TSFX_SMITH24 = 0xCB, + TSFX_SMITH25 = 0xCC, + TSFX_SMITH26 = 0xCD, + TSFX_SMITH27 = 0xCE, + TSFX_SMITH28 = 0xCF, + TSFX_SMITH29 = 0xD0, + TSFX_SMITH30 = 0xD1, + TSFX_SMITH31 = 0xD2, + TSFX_SMITH32 = 0xD3, + TSFX_SMITH33 = 0xD4, + TSFX_SMITH34 = 0xD5, + TSFX_SMITH35 = 0xD6, + TSFX_SMITH36 = 0xD7, + TSFX_SMITH37 = 0xD8, + TSFX_SMITH38 = 0xD9, + TSFX_SMITH39 = 0xDA, + TSFX_SMITH40 = 0xDB, + TSFX_SMITH41 = 0xDC, + TSFX_SMITH42 = 0xDD, + TSFX_SMITH43 = 0xDE, + TSFX_SMITH44 = 0xDF, + TSFX_SMITH45 = 0xE0, + TSFX_SMITH46 = 0xE1, + TSFX_SMITH47 = 0xE2, + TSFX_SMITH48 = 0xE3, + TSFX_SMITH49 = 0xE4, + TSFX_SMITH50 = 0xE5, + TSFX_SMITH51 = 0xE6, + TSFX_SMITH52 = 0xE7, + TSFX_SMITH53 = 0xE8, + TSFX_SMITH54 = 0xE9, + TSFX_SMITH55 = 0xEA, + TSFX_SMITH56 = 0xEB, + TSFX_COW1 = 0xEC, + TSFX_COW2 = 0xED, + TSFX_DEADGUY = 0xEE, + TSFX_DRUNK1 = 0xEF, + TSFX_DRUNK2 = 0xF0, + TSFX_DRUNK3 = 0xF1, + TSFX_DRUNK4 = 0xF2, + TSFX_DRUNK5 = 0xF3, + TSFX_DRUNK6 = 0xF4, + TSFX_DRUNK7 = 0xF5, + TSFX_DRUNK8 = 0xF6, + TSFX_DRUNK9 = 0xF7, + TSFX_DRUNK10 = 0xF8, + TSFX_DRUNK11 = 0xF9, + TSFX_DRUNK12 = 0xFA, + TSFX_DRUNK13 = 0xFB, + TSFX_DRUNK14 = 0xFC, + TSFX_DRUNK15 = 0xFD, + TSFX_DRUNK16 = 0xFE, + TSFX_DRUNK17 = 0xFF, + TSFX_DRUNK18 = 0x100, + TSFX_DRUNK19 = 0x101, + TSFX_DRUNK20 = 0x102, + TSFX_DRUNK21 = 0x103, + TSFX_DRUNK22 = 0x104, + TSFX_DRUNK23 = 0x105, + TSFX_DRUNK24 = 0x106, + TSFX_DRUNK25 = 0x107, + TSFX_DRUNK26 = 0x108, + TSFX_DRUNK27 = 0x109, + TSFX_DRUNK28 = 0x10A, + TSFX_DRUNK29 = 0x10B, + TSFX_DRUNK30 = 0x10C, + TSFX_DRUNK31 = 0x10D, + TSFX_DRUNK32 = 0x10E, + TSFX_DRUNK33 = 0x10F, + TSFX_DRUNK34 = 0x110, + TSFX_DRUNK35 = 0x111, + TSFX_HEALER1 = 0x112, + TSFX_HEALER2 = 0x113, + TSFX_HEALER3 = 0x114, + TSFX_HEALER4 = 0x115, + TSFX_HEALER5 = 0x116, + TSFX_HEALER6 = 0x117, + TSFX_HEALER7 = 0x118, + TSFX_HEALER8 = 0x119, + TSFX_HEALER9 = 0x11A, + TSFX_HEALER10 = 0x11B, + TSFX_HEALER11 = 0x11C, + TSFX_HEALER12 = 0x11D, + TSFX_HEALER13 = 0x11E, + TSFX_HEALER14 = 0x11F, + TSFX_HEALER15 = 0x120, + TSFX_HEALER16 = 0x121, + TSFX_HEALER17 = 0x122, + TSFX_HEALER18 = 0x123, + TSFX_HEALER19 = 0x124, + TSFX_HEALER20 = 0x125, + TSFX_HEALER21 = 0x126, + TSFX_HEALER22 = 0x127, + TSFX_HEALER23 = 0x128, + TSFX_HEALER24 = 0x129, + TSFX_HEALER25 = 0x12A, + TSFX_HEALER26 = 0x12B, + TSFX_HEALER27 = 0x12C, + TSFX_HEALER28 = 0x12D, + TSFX_HEALER29 = 0x12E, + TSFX_HEALER30 = 0x12F, + TSFX_HEALER31 = 0x130, + TSFX_HEALER32 = 0x131, + TSFX_HEALER33 = 0x132, + TSFX_HEALER34 = 0x133, + TSFX_HEALER35 = 0x134, + TSFX_HEALER36 = 0x135, + TSFX_HEALER37 = 0x136, + TSFX_HEALER38 = 0x137, + TSFX_HEALER39 = 0x138, + TSFX_HEALER40 = 0x139, + TSFX_HEALER41 = 0x13A, + TSFX_HEALER42 = 0x13B, + TSFX_HEALER43 = 0x13C, + TSFX_HEALER44 = 0x13D, + TSFX_HEALER45 = 0x13E, + TSFX_HEALER46 = 0x13F, + TSFX_HEALER47 = 0x140, + TSFX_PEGBOY1 = 0x141, + TSFX_PEGBOY2 = 0x142, + TSFX_PEGBOY3 = 0x143, + TSFX_PEGBOY4 = 0x144, + TSFX_PEGBOY5 = 0x145, + TSFX_PEGBOY6 = 0x146, + TSFX_PEGBOY7 = 0x147, + TSFX_PEGBOY8 = 0x148, + TSFX_PEGBOY9 = 0x149, + TSFX_PEGBOY10 = 0x14A, + TSFX_PEGBOY11 = 0x14B, + TSFX_PEGBOY12 = 0x14C, + TSFX_PEGBOY13 = 0x14D, + TSFX_PEGBOY14 = 0x14E, + TSFX_PEGBOY15 = 0x14F, + TSFX_PEGBOY16 = 0x150, + TSFX_PEGBOY17 = 0x151, + TSFX_PEGBOY18 = 0x152, + TSFX_PEGBOY19 = 0x153, + TSFX_PEGBOY20 = 0x154, + TSFX_PEGBOY21 = 0x155, + TSFX_PEGBOY22 = 0x156, + TSFX_PEGBOY23 = 0x157, + TSFX_PEGBOY24 = 0x158, + TSFX_PEGBOY25 = 0x159, + TSFX_PEGBOY26 = 0x15A, + TSFX_PEGBOY27 = 0x15B, + TSFX_PEGBOY28 = 0x15C, + TSFX_PEGBOY29 = 0x15D, + TSFX_PEGBOY30 = 0x15E, + TSFX_PEGBOY31 = 0x15F, + TSFX_PEGBOY32 = 0x160, + TSFX_PEGBOY33 = 0x161, + TSFX_PEGBOY34 = 0x162, + TSFX_PEGBOY35 = 0x163, + TSFX_PEGBOY36 = 0x164, + TSFX_PEGBOY37 = 0x165, + TSFX_PEGBOY38 = 0x166, + TSFX_PEGBOY39 = 0x167, + TSFX_PEGBOY40 = 0x168, + TSFX_PEGBOY41 = 0x169, + TSFX_PEGBOY42 = 0x16A, + TSFX_PEGBOY43 = 0x16B, + TSFX_PRIEST0 = 0x16C, + TSFX_PRIEST1 = 0x16D, + TSFX_PRIEST2 = 0x16E, + TSFX_PRIEST3 = 0x16F, + TSFX_PRIEST4 = 0x170, + TSFX_PRIEST5 = 0x171, + TSFX_PRIEST6 = 0x172, + TSFX_PRIEST7 = 0x173, + TSFX_STORY0 = 0x174, + TSFX_STORY1 = 0x175, + TSFX_STORY2 = 0x176, + TSFX_STORY3 = 0x177, + TSFX_STORY4 = 0x178, + TSFX_STORY5 = 0x179, + TSFX_STORY6 = 0x17A, + TSFX_STORY7 = 0x17B, + TSFX_STORY8 = 0x17C, + TSFX_STORY9 = 0x17D, + TSFX_STORY10 = 0x17E, + TSFX_STORY11 = 0x17F, + TSFX_STORY12 = 0x180, + TSFX_STORY13 = 0x181, + TSFX_STORY14 = 0x182, + TSFX_STORY15 = 0x183, + TSFX_STORY16 = 0x184, + TSFX_STORY17 = 0x185, + TSFX_STORY18 = 0x186, + TSFX_STORY19 = 0x187, + TSFX_STORY20 = 0x188, + TSFX_STORY21 = 0x189, + TSFX_STORY22 = 0x18A, + TSFX_STORY23 = 0x18B, + TSFX_STORY24 = 0x18C, + TSFX_STORY25 = 0x18D, + TSFX_STORY26 = 0x18E, + TSFX_STORY27 = 0x18F, + TSFX_STORY28 = 0x190, + TSFX_STORY29 = 0x191, + TSFX_STORY30 = 0x192, + TSFX_STORY31 = 0x193, + TSFX_STORY32 = 0x194, + TSFX_STORY33 = 0x195, + TSFX_STORY34 = 0x196, + TSFX_STORY35 = 0x197, + TSFX_STORY36 = 0x198, + TSFX_STORY37 = 0x199, + TSFX_STORY38 = 0x19A, + TSFX_TAVERN0 = 0x19B, + TSFX_TAVERN1 = 0x19C, + TSFX_TAVERN2 = 0x19D, + TSFX_TAVERN3 = 0x19E, + TSFX_TAVERN4 = 0x19F, + TSFX_TAVERN5 = 0x1A0, + TSFX_TAVERN6 = 0x1A1, + TSFX_TAVERN7 = 0x1A2, + TSFX_TAVERN8 = 0x1A3, + TSFX_TAVERN9 = 0x1A4, + TSFX_TAVERN10 = 0x1A5, + TSFX_TAVERN11 = 0x1A6, + TSFX_TAVERN12 = 0x1A7, + TSFX_TAVERN13 = 0x1A8, + TSFX_TAVERN14 = 0x1A9, + TSFX_TAVERN15 = 0x1AA, + TSFX_TAVERN16 = 0x1AB, + TSFX_TAVERN17 = 0x1AC, + TSFX_TAVERN18 = 0x1AD, + TSFX_TAVERN19 = 0x1AE, + TSFX_TAVERN20 = 0x1AF, + TSFX_TAVERN21 = 0x1B0, + TSFX_TAVERN22 = 0x1B1, + TSFX_TAVERN23 = 0x1B2, + TSFX_TAVERN24 = 0x1B3, + TSFX_TAVERN25 = 0x1B4, + TSFX_TAVERN26 = 0x1B5, + TSFX_TAVERN27 = 0x1B6, + TSFX_TAVERN28 = 0x1B7, + TSFX_TAVERN29 = 0x1B8, + TSFX_TAVERN30 = 0x1B9, + TSFX_TAVERN31 = 0x1BA, + TSFX_TAVERN32 = 0x1BB, + TSFX_TAVERN33 = 0x1BC, + TSFX_TAVERN34 = 0x1BD, + TSFX_TAVERN35 = 0x1BE, + TSFX_TAVERN36 = 0x1BF, + TSFX_TAVERN37 = 0x1C0, + TSFX_TAVERN38 = 0x1C1, + TSFX_TAVERN39 = 0x1C2, + TSFX_TAVERN40 = 0x1C3, + TSFX_TAVERN41 = 0x1C4, + TSFX_TAVERN42 = 0x1C5, + TSFX_TAVERN43 = 0x1C6, + TSFX_TAVERN44 = 0x1C7, + TSFX_TAVERN45 = 0x1C8, + TSFX_WITCH1 = 0x1C9, + TSFX_WITCH2 = 0x1CA, + TSFX_WITCH3 = 0x1CB, + TSFX_WITCH4 = 0x1CC, + TSFX_WITCH5 = 0x1CD, + TSFX_WITCH6 = 0x1CE, + TSFX_WITCH7 = 0x1CF, + TSFX_WITCH8 = 0x1D0, + TSFX_WITCH9 = 0x1D1, + TSFX_WITCH10 = 0x1D2, + TSFX_WITCH11 = 0x1D3, + TSFX_WITCH12 = 0x1D4, + TSFX_WITCH13 = 0x1D5, + TSFX_WITCH14 = 0x1D6, + TSFX_WITCH15 = 0x1D7, + TSFX_WITCH16 = 0x1D8, + TSFX_WITCH17 = 0x1D9, + TSFX_WITCH18 = 0x1DA, + TSFX_WITCH19 = 0x1DB, + TSFX_WITCH20 = 0x1DC, + TSFX_WITCH21 = 0x1DD, + TSFX_WITCH22 = 0x1DE, + TSFX_WITCH23 = 0x1DF, + TSFX_WITCH24 = 0x1E0, + TSFX_WITCH25 = 0x1E1, + TSFX_WITCH26 = 0x1E2, + TSFX_WITCH27 = 0x1E3, + TSFX_WITCH28 = 0x1E4, + TSFX_WITCH29 = 0x1E5, + TSFX_WITCH30 = 0x1E6, + TSFX_WITCH31 = 0x1E7, + TSFX_WITCH32 = 0x1E8, + TSFX_WITCH33 = 0x1E9, + TSFX_WITCH34 = 0x1EA, + TSFX_WITCH35 = 0x1EB, + TSFX_WITCH36 = 0x1EC, + TSFX_WITCH37 = 0x1ED, + TSFX_WITCH38 = 0x1EE, + TSFX_WITCH39 = 0x1EF, + TSFX_WITCH40 = 0x1F0, + TSFX_WITCH41 = 0x1F1, + TSFX_WITCH42 = 0x1F2, + TSFX_WITCH43 = 0x1F3, + TSFX_WITCH44 = 0x1F4, + TSFX_WITCH45 = 0x1F5, + TSFX_WITCH46 = 0x1F6, + TSFX_WITCH47 = 0x1F7, + TSFX_WITCH48 = 0x1F8, + TSFX_WITCH49 = 0x1F9, + TSFX_WITCH50 = 0x1FA, + TSFX_WOUND = 0x1FB, + PS_MAGE1 = 0x1FC, + PS_MAGE2 = 0x1FD, + PS_MAGE3 = 0x1FE, + PS_MAGE4 = 0x1FF, + PS_MAGE5 = 0x200, + PS_MAGE6 = 0x201, + PS_MAGE7 = 0x202, + PS_MAGE8 = 0x203, + PS_MAGE9 = 0x204, + PS_MAGE10 = 0x205, + PS_MAGE11 = 0x206, + PS_MAGE12 = 0x207, + PS_MAGE13 = 0x208, + PS_MAGE14 = 0x209, + PS_MAGE15 = 0x20A, + PS_MAGE16 = 0x20B, + PS_MAGE17 = 0x20C, + PS_MAGE18 = 0x20D, + PS_MAGE19 = 0x20E, + PS_MAGE20 = 0x20F, + PS_MAGE21 = 0x210, + PS_MAGE22 = 0x211, + PS_MAGE23 = 0x212, + PS_MAGE24 = 0x213, + PS_MAGE25 = 0x214, + PS_MAGE26 = 0x215, + PS_MAGE27 = 0x216, + PS_MAGE28 = 0x217, + PS_MAGE29 = 0x218, + PS_MAGE30 = 0x219, + PS_MAGE31 = 0x21A, + PS_MAGE32 = 0x21B, + PS_MAGE33 = 0x21C, + PS_MAGE34 = 0x21D, + PS_MAGE35 = 0x21E, + PS_MAGE36 = 0x21F, + PS_MAGE37 = 0x220, + PS_MAGE38 = 0x221, + PS_MAGE39 = 0x222, + PS_MAGE40 = 0x223, + PS_MAGE41 = 0x224, + PS_MAGE42 = 0x225, + PS_MAGE43 = 0x226, + PS_MAGE44 = 0x227, + PS_MAGE45 = 0x228, + PS_MAGE46 = 0x229, + PS_MAGE47 = 0x22A, + PS_MAGE48 = 0x22B, + PS_MAGE49 = 0x22C, + PS_MAGE50 = 0x22D, + PS_MAGE51 = 0x22E, + PS_MAGE52 = 0x22F, + PS_MAGE53 = 0x230, + PS_MAGE54 = 0x231, + PS_MAGE55 = 0x232, + PS_MAGE56 = 0x233, + PS_MAGE57 = 0x234, + PS_MAGE58 = 0x235, + PS_MAGE59 = 0x236, + PS_MAGE60 = 0x237, + PS_MAGE61 = 0x238, + PS_MAGE62 = 0x239, + PS_MAGE63 = 0x23A, + PS_MAGE64 = 0x23B, + PS_MAGE65 = 0x23C, + PS_MAGE66 = 0x23D, + PS_MAGE67 = 0x23E, + PS_MAGE68 = 0x23F, + PS_MAGE69 = 0x240, + PS_MAGE69B = 0x241, + PS_MAGE70 = 0x242, + PS_MAGE71 = 0x243, + PS_MAGE72 = 0x244, + PS_MAGE73 = 0x245, + PS_MAGE74 = 0x246, + PS_MAGE75 = 0x247, + PS_MAGE76 = 0x248, + PS_MAGE77 = 0x249, + PS_MAGE78 = 0x24A, + PS_MAGE79 = 0x24B, + PS_MAGE80 = 0x24C, + PS_MAGE81 = 0x24D, + PS_MAGE82 = 0x24E, + PS_MAGE83 = 0x24F, + PS_MAGE84 = 0x250, + PS_MAGE85 = 0x251, + PS_MAGE86 = 0x252, + PS_MAGE87 = 0x253, + PS_MAGE88 = 0x254, + PS_MAGE89 = 0x255, + PS_MAGE90 = 0x256, + PS_MAGE91 = 0x257, + PS_MAGE92 = 0x258, + PS_MAGE93 = 0x259, + PS_MAGE94 = 0x25A, + PS_MAGE95 = 0x25B, + PS_MAGE96 = 0x25C, + PS_MAGE97 = 0x25D, + PS_MAGE98 = 0x25E, + PS_MAGE99 = 0x25F, + PS_MAGE100 = 0x260, + PS_MAGE101 = 0x261, + PS_MAGE102 = 0x262, + PS_ROGUE1 = 0x263, + PS_ROGUE2 = 0x264, + PS_ROGUE3 = 0x265, + PS_ROGUE4 = 0x266, + PS_ROGUE5 = 0x267, + PS_ROGUE6 = 0x268, + PS_ROGUE7 = 0x269, + PS_ROGUE8 = 0x26A, + PS_ROGUE9 = 0x26B, + PS_ROGUE10 = 0x26C, + PS_ROGUE11 = 0x26D, + PS_ROGUE12 = 0x26E, + PS_ROGUE13 = 0x26F, + PS_ROGUE14 = 0x270, + PS_ROGUE15 = 0x271, + PS_ROGUE16 = 0x272, + PS_ROGUE17 = 0x273, + PS_ROGUE18 = 0x274, + PS_ROGUE19 = 0x275, + PS_ROGUE20 = 0x276, + PS_ROGUE21 = 0x277, + PS_ROGUE22 = 0x278, + PS_ROGUE23 = 0x279, + PS_ROGUE24 = 0x27A, + PS_ROGUE25 = 0x27B, + PS_ROGUE26 = 0x27C, + PS_ROGUE27 = 0x27D, + PS_ROGUE28 = 0x27E, + PS_ROGUE29 = 0x27F, + PS_ROGUE30 = 0x280, + PS_ROGUE31 = 0x281, + PS_ROGUE32 = 0x282, + PS_ROGUE33 = 0x283, + PS_ROGUE34 = 0x284, + PS_ROGUE35 = 0x285, + PS_ROGUE36 = 0x286, + PS_ROGUE37 = 0x287, + PS_ROGUE38 = 0x288, + PS_ROGUE39 = 0x289, + PS_ROGUE40 = 0x28A, + PS_ROGUE41 = 0x28B, + PS_ROGUE42 = 0x28C, + PS_ROGUE43 = 0x28D, + PS_ROGUE44 = 0x28E, + PS_ROGUE45 = 0x28F, + PS_ROGUE46 = 0x290, + PS_ROGUE47 = 0x291, + PS_ROGUE48 = 0x292, + PS_ROGUE49 = 0x293, + PS_ROGUE50 = 0x294, + PS_ROGUE51 = 0x295, + PS_ROGUE52 = 0x296, + PS_ROGUE53 = 0x297, + PS_ROGUE54 = 0x298, + PS_ROGUE55 = 0x299, + PS_ROGUE56 = 0x29A, + PS_ROGUE57 = 0x29B, + PS_ROGUE58 = 0x29C, + PS_ROGUE59 = 0x29D, + PS_ROGUE60 = 0x29E, + PS_ROGUE61 = 0x29F, + PS_ROGUE62 = 0x2A0, + PS_ROGUE63 = 0x2A1, + PS_ROGUE64 = 0x2A2, + PS_ROGUE65 = 0x2A3, + PS_ROGUE66 = 0x2A4, + PS_ROGUE67 = 0x2A5, + PS_ROGUE68 = 0x2A6, + PS_ROGUE69 = 0x2A7, + PS_ROGUE69B = 0x2A8, + PS_ROGUE70 = 0x2A9, + PS_ROGUE71 = 0x2AA, + PS_ROGUE72 = 0x2AB, + PS_ROGUE73 = 0x2AC, + PS_ROGUE74 = 0x2AD, + PS_ROGUE75 = 0x2AE, + PS_ROGUE76 = 0x2AF, + PS_ROGUE77 = 0x2B0, + PS_ROGUE78 = 0x2B1, + PS_ROGUE79 = 0x2B2, + PS_ROGUE80 = 0x2B3, + PS_ROGUE81 = 0x2B4, + PS_ROGUE82 = 0x2B5, + PS_ROGUE83 = 0x2B6, + PS_ROGUE84 = 0x2B7, + PS_ROGUE85 = 0x2B8, + PS_ROGUE86 = 0x2B9, + PS_ROGUE87 = 0x2BA, + PS_ROGUE88 = 0x2BB, + PS_ROGUE89 = 0x2BC, + PS_ROGUE90 = 0x2BD, + PS_ROGUE91 = 0x2BE, + PS_ROGUE92 = 0x2BF, + PS_ROGUE93 = 0x2C0, + PS_ROGUE94 = 0x2C1, + PS_ROGUE95 = 0x2C2, + PS_ROGUE96 = 0x2C3, + PS_ROGUE97 = 0x2C4, + PS_ROGUE98 = 0x2C5, + PS_ROGUE99 = 0x2C6, + PS_ROGUE100 = 0x2C7, + PS_ROGUE101 = 0x2C8, + PS_ROGUE102 = 0x2C9, + PS_WARR1 = 0x2CA, + PS_WARR2 = 0x2CB, + PS_WARR3 = 0x2CC, + PS_WARR4 = 0x2CD, + PS_WARR5 = 0x2CE, + PS_WARR6 = 0x2CF, + PS_WARR7 = 0x2D0, + PS_WARR8 = 0x2D1, + PS_WARR9 = 0x2D2, + PS_WARR10 = 0x2D3, + PS_WARR11 = 0x2D4, + PS_WARR12 = 0x2D5, + PS_WARR13 = 0x2D6, + PS_WARR14 = 0x2D7, + PS_WARR14B = 0x2D8, + PS_WARR14C = 0x2D9, + PS_WARR15 = 0x2DA, + PS_WARR15B = 0x2DB, + PS_WARR15C = 0x2DC, + PS_WARR16 = 0x2DD, + PS_WARR16B = 0x2DE, + PS_WARR16C = 0x2DF, + PS_WARR17 = 0x2E0, + PS_WARR18 = 0x2E1, + PS_WARR19 = 0x2E2, + PS_WARR20 = 0x2E3, + PS_WARR21 = 0x2E4, + PS_WARR22 = 0x2E5, + PS_WARR23 = 0x2E6, + PS_WARR24 = 0x2E7, + PS_WARR25 = 0x2E8, + PS_WARR26 = 0x2E9, + PS_WARR27 = 0x2EA, + PS_WARR28 = 0x2EB, + PS_WARR29 = 0x2EC, + PS_WARR30 = 0x2ED, + PS_WARR31 = 0x2EE, + PS_WARR32 = 0x2EF, + PS_WARR33 = 0x2F0, + PS_WARR34 = 0x2F1, + PS_WARR35 = 0x2F2, + PS_WARR36 = 0x2F3, + PS_WARR37 = 0x2F4, + PS_WARR38 = 0x2F5, + PS_WARR39 = 0x2F6, + PS_WARR40 = 0x2F7, + PS_WARR41 = 0x2F8, + PS_WARR42 = 0x2F9, + PS_WARR43 = 0x2FA, + PS_WARR44 = 0x2FB, + PS_WARR45 = 0x2FC, + PS_WARR46 = 0x2FD, + PS_WARR47 = 0x2FE, + PS_WARR48 = 0x2FF, + PS_WARR49 = 0x300, + PS_WARR50 = 0x301, + PS_WARR51 = 0x302, + PS_WARR52 = 0x303, + PS_WARR53 = 0x304, + PS_WARR54 = 0x305, + PS_WARR55 = 0x306, + PS_WARR56 = 0x307, + PS_WARR57 = 0x308, + PS_WARR58 = 0x309, + PS_WARR59 = 0x30A, + PS_WARR60 = 0x30B, + PS_WARR61 = 0x30C, + PS_WARR62 = 0x30D, + PS_WARR63 = 0x30E, + PS_WARR64 = 0x30F, + PS_WARR65 = 0x310, + PS_WARR66 = 0x311, + PS_WARR67 = 0x312, + PS_WARR68 = 0x313, + PS_WARR69 = 0x314, + PS_WARR69B = 0x315, + PS_WARR70 = 0x316, + PS_WARR71 = 0x317, + PS_WARR72 = 0x318, + PS_WARR73 = 0x319, + PS_WARR74 = 0x31A, + PS_WARR75 = 0x31B, + PS_WARR76 = 0x31C, + PS_WARR77 = 0x31D, + PS_WARR78 = 0x31E, + PS_WARR79 = 0x31F, + PS_WARR80 = 0x320, + PS_WARR81 = 0x321, + PS_WARR82 = 0x322, + PS_WARR83 = 0x323, + PS_WARR84 = 0x324, + PS_WARR85 = 0x325, + PS_WARR86 = 0x326, + PS_WARR87 = 0x327, + PS_WARR88 = 0x328, + PS_WARR89 = 0x329, + PS_WARR90 = 0x32A, + PS_WARR91 = 0x32B, + PS_WARR92 = 0x32C, + PS_WARR93 = 0x32D, + PS_WARR94 = 0x32E, + PS_WARR95 = 0x32F, + PS_WARR95B = 0x330, + PS_WARR95C = 0x331, + PS_WARR95D = 0x332, + PS_WARR95E = 0x333, + PS_WARR95F = 0x334, + PS_WARR96B = 0x335, + PS_WARR97 = 0x336, + PS_WARR98 = 0x337, + PS_WARR99 = 0x338, + PS_WARR100 = 0x339, + PS_WARR101 = 0x33A, + PS_WARR102 = 0x33B, + PS_NAR1 = 0x33C, + PS_NAR2 = 0x33D, + PS_NAR3 = 0x33E, + PS_NAR4 = 0x33F, + PS_NAR5 = 0x340, + PS_NAR6 = 0x341, + PS_NAR7 = 0x342, + PS_NAR8 = 0x343, + PS_NAR9 = 0x344, + PS_DIABLVLINT = 0x345, + USFX_CLEAVER = 0x346, + USFX_GARBUD1 = 0x347, + USFX_GARBUD2 = 0x348, + USFX_GARBUD3 = 0x349, + USFX_GARBUD4 = 0x34A, + USFX_IZUAL1 = 0x34B, + USFX_LACH1 = 0x34C, + USFX_LACH2 = 0x34D, + USFX_LACH3 = 0x34E, + USFX_LAZ1 = 0x34F, + USFX_LAZ2 = 0x350, + USFX_SKING1 = 0x351, + USFX_SNOT1 = 0x352, + USFX_SNOT2 = 0x353, + USFX_SNOT3 = 0x354, + USFX_WARLRD1 = 0x355, + USFX_WLOCK1 = 0x356, + USFX_ZHAR1 = 0x357, + USFX_ZHAR2 = 0x358, + USFX_DIABLOD = 0x359, +}; + +/* 85 */ +struct TextDataStruct +{ + char *txtstr; + int scrlltxt; + int txtspd; + int sfxnr; +}; + +/* 87 */ +struct RECT32 +{ + int x; + int y; + int w; + int h; +}; + +/* 88 */ +struct TSFX +{ + unsigned char bFlags; + char *pszName; + int Channel; +}; + +/* 94 */ +typedef LONG HRESULT; + +/* 92 */ +typedef _GUID GUID; + +/* 91 */ +typedef GUID IID; + +/* 95 */ +//typedef unsigned __int32 ULONG; + +/* 96 */ +typedef DWORD LCID; + +/* 188 */ +typedef WCHAR *LPWSTR; + +/* 102 */ +typedef LONG DISPID; + +/* 151 */ +typedef tagDISPPARAMS DISPPARAMS; + +/* 132 */ +typedef tagVARIANT VARIANT; + +/* 153 */ +typedef tagEXCEPINFO EXCEPINFO; + +/* 104 */ +typedef WCHAR OLECHAR; + +/* 146 */ +typedef OLECHAR *BSTR; + +/* 189 */ +typedef BSTR *PBSTR; + +/* 190 */ +typedef BOOL *PBOOL; + +/* 90 */ +/* struct MenuItemVtbl +{ + HRESULT (__stdcall *QueryInterface)(#89 *This, const IID *const riid, void **ppvObject); + ULONG (__stdcall *AddRef)(#89 *This); + ULONG (__stdcall *Release)(#89 *This); + HRESULT (__stdcall *GetTypeInfoCount)(#89 *This, UINT *pctinfo); + HRESULT (__stdcall *GetTypeInfo)(#89 *This, UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo); + HRESULT (__stdcall *GetIDsOfNames)(#89 *This, const IID *const riid, LPWSTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId); + HRESULT (__stdcall *Invoke)(#89 *This, DISPID dispIdMember, const IID *const riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr); + HRESULT (__stdcall *get_DisplayName)(#89 *This, PBSTR DisplayName); + HRESULT (__stdcall *get_LanguageIndependentName)(#89 *This, PBSTR LanguageIndependentName); + HRESULT (__stdcall *get_Path)(#89 *This, PBSTR Path); + HRESULT (__stdcall *get_LanguageIndependentPath)(#89 *This, PBSTR LanguageIndependentPath); + HRESULT (__stdcall *Execute)(#89 *This); + HRESULT (__stdcall *get_Enabled)(#89 *This, PBOOL Enabled); +}; */ + +/* 93 */ +/* struct _GUID +{ + DWORD Data1; + WORD Data2; + WORD Data3; + BYTE Data4[8]; +}; */ + +/* 97 */ +#pragma pack(push, 8) +/* struct ITypeInfo +{ + ITypeInfoVtbl *lpVtbl; +}; */ +#pragma pack(pop) + +/* 131 */ +/* typedef VARIANT VARIANTARG; + */ +/* 152 */ +#pragma pack(push, 8) +/* struct tagDISPPARAMS +{ + VARIANTARG *rgvarg; + DISPID *rgdispidNamedArgs; + UINT cArgs; + UINT cNamedArgs; +}; */ +#pragma pack(pop) + +/* 111 */ +/* typedef unsigned short VARTYPE; + */ +/* 137 */ +/* typedef short SHORT; + */ +/* 138 */ +typedef float FLOAT; + +/* 139 */ +typedef double DOUBLE; + +/* 140 */ +/* typedef short VARIANT_BOOL; + */ +/* 123 */ +typedef LONG SCODE; + +/* 143 */ +#pragma pack(push, 8) +/* struct tagCY::$4ADA6AE34E722E24764E0C4FBCDA3E73 +{ + unsigned __int32 Lo; + __int32 Hi; +}; */ +#pragma pack(pop) + +/* 144 */ +typedef __int64 LONGLONG; + +/* 142 */ +#pragma pack(push, 8) +/* union tagCY +{ + #pragma pack(push, 8) + struct + { + unsigned __int32 Lo; + __int32 Hi; + }; + #pragma pack(pop) + LONGLONG int64; +}; */ +#pragma pack(pop) + +/* 141 */ +/* typedef tagCY CY; + */ +/* 145 */ +typedef double DATE; + +/* 155 */ +typedef tagSAFEARRAY SAFEARRAY; + +/* 114 */ +/* typedef unsigned short USHORT; + */ +/* 159 */ +typedef int INT; + +/* 160 */ +typedef tagDEC DECIMAL; + +/* 167 */ +#pragma pack(push, 8) +/* struct tagVARIANT::$::$::$E3ADF3533BFFE4E09553D0C58E41D45E::$0FDBD249F1AECD6A49409B6B82281578 +{ + PVOID pvRecord; + IRecordInfo *pRecInfo; +}; */ +#pragma pack(pop) + +/* 136 */ +#pragma pack(push, 8) +/* union tagVARIANT::$::$2E851DBA257FA738680F86C475CAC6EB::$E3ADF3533BFFE4E09553D0C58E41D45E +{ + LONG lVal; + BYTE bVal; + SHORT iVal; + FLOAT fltVal; + DOUBLE dblVal; + VARIANT_BOOL boolVal; + SCODE scode; + CY cyVal; + DATE date; + BSTR bstrVal; + IUnknown *punkVal; + IDispatch *pdispVal; + SAFEARRAY *parray; + BYTE *pbVal; + SHORT *piVal; + LONG *plVal; + FLOAT *pfltVal; + DOUBLE *pdblVal; + VARIANT_BOOL *pboolVal; + SCODE *pscode; + CY *pcyVal; + DATE *pdate; + BSTR *pbstrVal; + IUnknown **ppunkVal; + IDispatch **ppdispVal; + SAFEARRAY **pparray; + VARIANT *pvarVal; + PVOID byref; + CHAR cVal; + USHORT uiVal; + ULONG ulVal; + INT intVal; + UINT uintVal; + DECIMAL *pdecVal; + CHAR *pcVal; + USHORT *puiVal; + ULONG *pulVal; + INT *pintVal; + UINT *puintVal; + #pragma pack(push, 8) + struct + { + PVOID pvRecord; + IRecordInfo *pRecInfo; + }; + #pragma pack(pop) +}; */ +#pragma pack(pop) + +/* 135 */ +#pragma pack(push, 8) +/* struct tagVARIANT::$CFEED276C078973BD7512520F6B5AF6E::$2E851DBA257FA738680F86C475CAC6EB +{ + VARTYPE vt; + WORD wReserved1; + WORD wReserved2; + WORD wReserved3; + #pragma pack(push, 8) + union + { + LONG lVal; + BYTE bVal; + SHORT iVal; + FLOAT fltVal; + DOUBLE dblVal; + VARIANT_BOOL boolVal; + SCODE scode; + CY cyVal; + DATE date; + BSTR bstrVal; + IUnknown *punkVal; + IDispatch *pdispVal; + SAFEARRAY *parray; + BYTE *pbVal; + SHORT *piVal; + LONG *plVal; + FLOAT *pfltVal; + DOUBLE *pdblVal; + VARIANT_BOOL *pboolVal; + SCODE *pscode; + CY *pcyVal; + DATE *pdate; + BSTR *pbstrVal; + IUnknown **ppunkVal; + IDispatch **ppdispVal; + SAFEARRAY **pparray; + VARIANT *pvarVal; + PVOID byref; + CHAR cVal; + USHORT uiVal; + ULONG ulVal; + INT intVal; + UINT uintVal; + DECIMAL *pdecVal; + CHAR *pcVal; + USHORT *puiVal; + ULONG *pulVal; + INT *pintVal; + UINT *puintVal; + #pragma pack(push, 8) + struct + { + PVOID pvRecord; + IRecordInfo *pRecInfo; + }; + #pragma pack(pop) + }; + #pragma pack(pop) +}; */ +#pragma pack(pop) + +/* 163 */ +#pragma pack(push, 8) +/* struct tagDEC::$64EC678C49E7BE49873AFBFB7A849D34::$7F8459940C2B08BD5D82B0F27239141B +{ + BYTE scale; + BYTE sign; +}; */ +#pragma pack(pop) + +/* 162 */ +#pragma pack(push, 8) +/* union tagDEC::$64EC678C49E7BE49873AFBFB7A849D34 +{ + #pragma pack(push, 8) + struct + { + BYTE scale; + BYTE sign; + }; + #pragma pack(pop) + USHORT signscale; +}; */ +#pragma pack(pop) + +/* 165 */ +#pragma pack(push, 8) +/* struct tagDEC::$D28E26DEC3EC762C06C2AA9D0F7AC301::$674876891A86A76F12C10005982BCA56 +{ + ULONG Lo32; + ULONG Mid32; +}; */ +#pragma pack(pop) + +/* 166 */ +typedef unsigned __int64 ULONGLONG; + +/* 164 */ +#pragma pack(push, 8) +/* union tagDEC::$D28E26DEC3EC762C06C2AA9D0F7AC301 +{ + #pragma pack(push, 8) + struct + { + ULONG Lo32; + ULONG Mid32; + }; + #pragma pack(pop) + ULONGLONG Lo64; +}; */ +#pragma pack(pop) + +/* 161 */ +#pragma pack(push, 8) +/* struct tagDEC +{ + USHORT wReserved; + #pragma pack(push, 8) + union + { + #pragma pack(push, 8) + struct + { + BYTE scale; + BYTE sign; + }; + #pragma pack(pop) + USHORT signscale; + }; + #pragma pack(pop) + ULONG Hi32; + #pragma pack(push, 8) + union + { + #pragma pack(push, 8) + struct + { + ULONG Lo32; + ULONG Mid32; + }; + #pragma pack(pop) + ULONGLONG Lo64; + }; + #pragma pack(pop) +}; */ +#pragma pack(pop) + +/* 134 */ +#pragma pack(push, 8) +/* union tagVARIANT::$CFEED276C078973BD7512520F6B5AF6E +{ + #pragma pack(push, 8) + struct + { + VARTYPE vt; + WORD wReserved1; + WORD wReserved2; + WORD wReserved3; + #pragma pack(push, 8) + union + { + LONG lVal; + BYTE bVal; + SHORT iVal; + FLOAT fltVal; + DOUBLE dblVal; + VARIANT_BOOL boolVal; + SCODE scode; + CY cyVal; + DATE date; + BSTR bstrVal; + IUnknown *punkVal; + IDispatch *pdispVal; + SAFEARRAY *parray; + BYTE *pbVal; + SHORT *piVal; + LONG *plVal; + FLOAT *pfltVal; + DOUBLE *pdblVal; + VARIANT_BOOL *pboolVal; + SCODE *pscode; + CY *pcyVal; + DATE *pdate; + BSTR *pbstrVal; + IUnknown **ppunkVal; + IDispatch **ppdispVal; + SAFEARRAY **pparray; + VARIANT *pvarVal; + PVOID byref; + CHAR cVal; + USHORT uiVal; + ULONG ulVal; + INT intVal; + UINT uintVal; + DECIMAL *pdecVal; + CHAR *pcVal; + USHORT *puiVal; + ULONG *pulVal; + INT *pintVal; + UINT *puintVal; + #pragma pack(push, 8) + struct + { + PVOID pvRecord; + IRecordInfo *pRecInfo; + }; + #pragma pack(pop) + }; + #pragma pack(pop) + }; + #pragma pack(pop) + DECIMAL decVal; +}; */ +#pragma pack(pop) + +/* 133 */ +#pragma pack(push, 8) +/* struct tagVARIANT +{ + #pragma pack(push, 8) + union + { + #pragma pack(push, 8) + struct + { + VARTYPE vt; + WORD wReserved1; + WORD wReserved2; + WORD wReserved3; + #pragma pack(push, 8) + union + { + LONG lVal; + BYTE bVal; + SHORT iVal; + FLOAT fltVal; + DOUBLE dblVal; + VARIANT_BOOL boolVal; + SCODE scode; + CY cyVal; + DATE date; + BSTR bstrVal; + IUnknown *punkVal; + IDispatch *pdispVal; + SAFEARRAY *parray; + BYTE *pbVal; + SHORT *piVal; + LONG *plVal; + FLOAT *pfltVal; + DOUBLE *pdblVal; + VARIANT_BOOL *pboolVal; + SCODE *pscode; + CY *pcyVal; + DATE *pdate; + BSTR *pbstrVal; + IUnknown **ppunkVal; + IDispatch **ppdispVal; + SAFEARRAY **pparray; + VARIANT *pvarVal; + PVOID byref; + CHAR cVal; + USHORT uiVal; + ULONG ulVal; + INT intVal; + UINT uintVal; + DECIMAL *pdecVal; + CHAR *pcVal; + USHORT *puiVal; + ULONG *pulVal; + INT *pintVal; + UINT *puintVal; + #pragma pack(push, 8) + struct + { + PVOID pvRecord; + IRecordInfo *pRecInfo; + }; + #pragma pack(pop) + }; + #pragma pack(pop) + }; + #pragma pack(pop) + DECIMAL decVal; + }; + #pragma pack(pop) +}; */ +#pragma pack(pop) + +/* 154 */ +#pragma pack(push, 8) +/* struct tagEXCEPINFO +{ + WORD wCode; + WORD wReserved; + BSTR bstrSource; + BSTR bstrDescription; + BSTR bstrHelpFile; + DWORD dwHelpContext; + PVOID pvReserved; + HRESULT (__stdcall *pfnDeferredFillIn)(tagEXCEPINFO *); + SCODE scode; +}; */ +#pragma pack(pop) + +/* 99 */ +typedef tagTYPEATTR TYPEATTR; + +/* 121 */ +typedef tagFUNCDESC FUNCDESC; + +/* 177 */ +typedef tagVARDESC VARDESC; + +/* 101 */ +typedef DISPID MEMBERID; + +/* 110 */ +typedef DWORD HREFTYPE; + +/* 103 */ +typedef OLECHAR *LPOLESTR; + +/* 174 */ +/* enum tagINVOKEKIND +{ + INVOKE_FUNC = 0x1, + INVOKE_PROPERTYGET = 0x2, + INVOKE_PROPERTYPUT = 0x4, + INVOKE_PROPERTYPUTREF = 0x8, +}; */ + +/* 173 */ +typedef tagINVOKEKIND INVOKEKIND; + +/* 98 */ +#pragma pack(push, 8) +struct ITypeInfoVtbl +{ + HRESULT (__stdcall *QueryInterface)(ITypeInfo *This, const IID *const riid, void **ppvObject); + ULONG (__stdcall *AddRef)(ITypeInfo *This); + ULONG (__stdcall *Release)(ITypeInfo *This); + HRESULT (__stdcall *GetTypeAttr)(ITypeInfo *This, TYPEATTR **ppTypeAttr); + HRESULT (__stdcall *GetTypeComp)(ITypeInfo *This, ITypeComp **ppTComp); + HRESULT (__stdcall *GetFuncDesc)(ITypeInfo *This, UINT index, FUNCDESC **ppFuncDesc); + HRESULT (__stdcall *GetVarDesc)(ITypeInfo *This, UINT index, VARDESC **ppVarDesc); + HRESULT (__stdcall *GetNames)(ITypeInfo *This, MEMBERID memid, BSTR *rgBstrNames, UINT cMaxNames, UINT *pcNames); + HRESULT (__stdcall *GetRefTypeOfImplType)(ITypeInfo *This, UINT index, HREFTYPE *pRefType); + HRESULT (__stdcall *GetImplTypeFlags)(ITypeInfo *This, UINT index, INT *pImplTypeFlags); + HRESULT (__stdcall *GetIDsOfNames)(ITypeInfo *This, LPOLESTR *rgszNames, UINT cNames, MEMBERID *pMemId); + HRESULT (__stdcall *Invoke)(ITypeInfo *This, PVOID pvInstance, MEMBERID memid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr); + HRESULT (__stdcall *GetDocumentation)(ITypeInfo *This, MEMBERID memid, BSTR *pBstrName, BSTR *pBstrDocString, DWORD *pdwHelpContext, BSTR *pBstrHelpFile); + HRESULT (__stdcall *GetDllEntry)(ITypeInfo *This, MEMBERID memid, INVOKEKIND invKind, BSTR *pBstrDllName, BSTR *pBstrName, WORD *pwOrdinal); + HRESULT (__stdcall *GetRefTypeInfo)(ITypeInfo *This, HREFTYPE hRefType, ITypeInfo **ppTInfo); + HRESULT (__stdcall *AddressOfMember)(ITypeInfo *This, MEMBERID memid, INVOKEKIND invKind, PVOID *ppv); + HRESULT (__stdcall *CreateInstance)(ITypeInfo *This, IUnknown *pUnkOuter, const IID *const riid, PVOID *ppvObj); + HRESULT (__stdcall *GetMops)(ITypeInfo *This, MEMBERID memid, BSTR *pBstrMops); + HRESULT (__stdcall *GetContainingTypeLib)(ITypeInfo *This, ITypeLib **ppTLib, UINT *pIndex); + void (__stdcall *ReleaseTypeAttr)(ITypeInfo *This, TYPEATTR *pTypeAttr); + void (__stdcall *ReleaseFuncDesc)(ITypeInfo *This, FUNCDESC *pFuncDesc); + void (__stdcall *ReleaseVarDesc)(ITypeInfo *This, VARDESC *pVarDesc); +}; +#pragma pack(pop) + +/* 147 */ +#pragma pack(push, 8) +/* struct IUnknown +{ + IUnknownVtbl *lpVtbl; +}; */ +#pragma pack(pop) + +/* 149 */ +#pragma pack(push, 8) +/* struct IDispatch +{ + IDispatchVtbl *lpVtbl; +}; */ +#pragma pack(pop) + +/* 158 */ +#pragma pack(push, 8) +/* struct tagSAFEARRAYBOUND +{ + ULONG cElements; + LONG lLbound; +}; */ +#pragma pack(pop) + +/* 157 */ +typedef tagSAFEARRAYBOUND SAFEARRAYBOUND; + +/* 156 */ +#pragma pack(push, 8) +/* struct tagSAFEARRAY +{ + USHORT cDims; + USHORT fFeatures; + ULONG cbElements; + ULONG cLocks; + PVOID pvData; + SAFEARRAYBOUND rgsabound[1]; +}; */ +#pragma pack(pop) + +/* 168 */ +#pragma pack(push, 8) +/* struct IRecordInfo +{ + IRecordInfoVtbl *lpVtbl; +}; */ +#pragma pack(pop) + +/* 106 */ +/* enum tagTYPEKIND +{ + TKIND_ENUM = 0x0, + TKIND_RECORD = 0x1, + TKIND_MODULE = 0x2, + TKIND_INTERFACE = 0x3, + TKIND_DISPATCH = 0x4, + TKIND_COCLASS = 0x5, + TKIND_ALIAS = 0x6, + TKIND_UNION = 0x7, + TKIND_MAX = 0x8, +}; */ + +/* 105 */ +typedef tagTYPEKIND TYPEKIND; + +/* 109 */ +#pragma pack(push, 8) +/* union tagTYPEDESC::$B05FCE5490B0CB857F8E7C0862C02AF4 +{ + tagTYPEDESC *lptdesc; + struct tagTYPEDESC::$B05FCE5490B0CB857F8E7C0862C02AF4::tagARRAYDESC *lpadesc; + HREFTYPE hreftype; +}; */ +#pragma pack(pop) + +/* 108 */ +#pragma pack(push, 8) +/* struct tagTYPEDESC +{ + #pragma pack(push, 8) + union + { + tagTYPEDESC *lptdesc; + struct tagTYPEDESC::$B05FCE5490B0CB857F8E7C0862C02AF4::tagARRAYDESC *lpadesc; + HREFTYPE hreftype; + }; + #pragma pack(pop) + VARTYPE vt; +}; */ +#pragma pack(pop) + +/* 107 */ +typedef tagTYPEDESC TYPEDESC; + +/* 113 */ +#pragma pack(push, 8) +/* struct tagIDLDESC +{ + ULONG dwReserved; + USHORT wIDLFlags; +}; */ +#pragma pack(pop) + +/* 112 */ +typedef tagIDLDESC IDLDESC; + +/* 100 */ +#pragma pack(push, 8) +/* struct tagTYPEATTR +{ + GUID guid; + LCID lcid; + DWORD dwReserved; + MEMBERID memidConstructor; + MEMBERID memidDestructor; + LPOLESTR lpstrSchema; + ULONG cbSizeInstance; + TYPEKIND typekind; + WORD cFuncs; + WORD cVars; + WORD cImplTypes; + WORD cbSizeVft; + WORD cbAlignment; + WORD wTypeFlags; + WORD wMajorVerNum; + WORD wMinorVerNum; + TYPEDESC tdescAlias; + IDLDESC idldescType; +}; */ +#pragma pack(pop) + +/* 115 */ +#pragma pack(push, 8) +/* struct ITypeComp +{ + ITypeCompVtbl *lpVtbl; +}; */ +#pragma pack(pop) + +/* 124 */ +typedef tagELEMDESC ELEMDESC; + +/* 172 */ +/* enum tagFUNCKIND +{ + FUNC_VIRTUAL = 0x0, + FUNC_PUREVIRTUAL = 0x1, + FUNC_NONVIRTUAL = 0x2, + FUNC_STATIC = 0x3, + FUNC_DISPATCH = 0x4, +}; */ + +/* 171 */ +typedef tagFUNCKIND FUNCKIND; + +/* 176 */ +/* enum tagCALLCONV +{ + CC_FASTCALL = 0x0, + CC_CDECL = 0x1, + CC_MSCPASCAL = 0x2, + CC_PASCAL = 0x2, + CC_MACPASCAL = 0x3, + CC_STDCALL = 0x4, + CC_FPFASTCALL = 0x5, + CC_SYSCALL = 0x6, + CC_MPWCDECL = 0x7, + CC_MPWPASCAL = 0x8, + CC_MAX = 0x9, +}; */ + +/* 175 */ +typedef tagCALLCONV CALLCONV; + +/* 129 */ +typedef tagPARAMDESCEX *LPPARAMDESCEX; + +/* 128 */ +#pragma pack(push, 8) +/* struct tagPARAMDESC +{ + LPPARAMDESCEX pparamdescex; + USHORT wParamFlags; +}; */ +#pragma pack(pop) + +/* 127 */ +typedef tagPARAMDESC PARAMDESC; + +/* 126 */ +#pragma pack(push, 8) +/* union tagELEMDESC::$7C8F4CED1424251743D09680A1A0B07D +{ + IDLDESC idldesc; + PARAMDESC paramdesc; +}; */ +#pragma pack(pop) + +/* 125 */ +#pragma pack(push, 8) +/* struct tagELEMDESC +{ + TYPEDESC tdesc; + #pragma pack(push, 8) + union + { + IDLDESC idldesc; + PARAMDESC paramdesc; + }; + #pragma pack(pop) +}; */ +#pragma pack(pop) + +/* 122 */ +#pragma pack(push, 8) +/* struct tagFUNCDESC +{ + MEMBERID memid; + SCODE *lprgscode; + ELEMDESC *lprgelemdescParam; + FUNCKIND funckind; + INVOKEKIND invkind; + CALLCONV callconv; + SHORT cParams; + SHORT cParamsOpt; + SHORT oVft; + SHORT cScodes; + ELEMDESC elemdescFunc; + WORD wFuncFlags; +}; */ +#pragma pack(pop) + +/* 179 */ +#pragma pack(push, 8) +/* union tagVARDESC::$E6274BD6A7149C9CC2413444FF769F0B +{ + ULONG oInst; + VARIANT *lpvarValue; +}; */ +#pragma pack(pop) + +/* 181 */ +/* enum tagVARKIND +{ + VAR_PERINSTANCE = 0x0, + VAR_STATIC = 0x1, + VAR_CONST = 0x2, + VAR_DISPATCH = 0x3, +}; */ + +/* 180 */ +typedef tagVARKIND VARKIND; + +/* 178 */ +#pragma pack(push, 8) +/* struct tagVARDESC +{ + MEMBERID memid; + LPOLESTR lpstrSchema; + #pragma pack(push, 8) + union + { + ULONG oInst; + VARIANT *lpvarValue; + }; + #pragma pack(pop) + ELEMDESC elemdescVar; + WORD wVarFlags; + VARKIND varkind; +}; */ +#pragma pack(pop) + +/* 182 */ +#pragma pack(push, 8) +/* struct ITypeLib +{ + ITypeLibVtbl *lpVtbl; +}; */ +#pragma pack(pop) + +/* 148 */ +#pragma pack(push, 8) +struct IUnknownVtbl +{ + HRESULT (__stdcall *QueryInterface)(IUnknown *This, const IID *const riid, void **ppvObject); + ULONG (__stdcall *AddRef)(IUnknown *This); + ULONG (__stdcall *Release)(IUnknown *This); +}; +#pragma pack(pop) + +/* 150 */ +#pragma pack(push, 8) +struct IDispatchVtbl +{ + HRESULT (__stdcall *QueryInterface)(IDispatch *This, const IID *const riid, void **ppvObject); + ULONG (__stdcall *AddRef)(IDispatch *This); + ULONG (__stdcall *Release)(IDispatch *This); + HRESULT (__stdcall *GetTypeInfoCount)(IDispatch *This, UINT *pctinfo); + HRESULT (__stdcall *GetTypeInfo)(IDispatch *This, UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo); + HRESULT (__stdcall *GetIDsOfNames)(IDispatch *This, const IID *const riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId); + HRESULT (__stdcall *Invoke)(IDispatch *This, DISPID dispIdMember, const IID *const riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr); +}; +#pragma pack(pop) + +/* 170 */ +typedef const OLECHAR *LPCOLESTR; + +/* 169 */ +#pragma pack(push, 8) +struct IRecordInfoVtbl +{ + HRESULT (__stdcall *QueryInterface)(IRecordInfo *This, const IID *const riid, void **ppvObject); + ULONG (__stdcall *AddRef)(IRecordInfo *This); + ULONG (__stdcall *Release)(IRecordInfo *This); + HRESULT (__stdcall *RecordInit)(IRecordInfo *This, PVOID pvNew); + HRESULT (__stdcall *RecordClear)(IRecordInfo *This, PVOID pvExisting); + HRESULT (__stdcall *RecordCopy)(IRecordInfo *This, PVOID pvExisting, PVOID pvNew); + HRESULT (__stdcall *GetGuid)(IRecordInfo *This, GUID *pguid); + HRESULT (__stdcall *GetName)(IRecordInfo *This, BSTR *pbstrName); + HRESULT (__stdcall *GetSize)(IRecordInfo *This, ULONG *pcbSize); + HRESULT (__stdcall *GetTypeInfo)(IRecordInfo *This, ITypeInfo **ppTypeInfo); + HRESULT (__stdcall *GetField)(IRecordInfo *This, PVOID pvData, LPCOLESTR szFieldName, VARIANT *pvarField); + HRESULT (__stdcall *GetFieldNoCopy)(IRecordInfo *This, PVOID pvData, LPCOLESTR szFieldName, VARIANT *pvarField, PVOID *ppvDataCArray); + HRESULT (__stdcall *PutField)(IRecordInfo *This, ULONG wFlags, PVOID pvData, LPCOLESTR szFieldName, VARIANT *pvarField); + HRESULT (__stdcall *PutFieldNoCopy)(IRecordInfo *This, ULONG wFlags, PVOID pvData, LPCOLESTR szFieldName, VARIANT *pvarField); + HRESULT (__stdcall *GetFieldNames)(IRecordInfo *This, ULONG *pcNames, BSTR *rgBstrNames); + BOOL (__stdcall *IsMatchingType)(IRecordInfo *This, IRecordInfo *pRecordInfo); + PVOID (__stdcall *RecordCreate)(IRecordInfo *This); + HRESULT (__stdcall *RecordCreateCopy)(IRecordInfo *This, PVOID pvSource, PVOID *ppvDest); + HRESULT (__stdcall *RecordDestroy)(IRecordInfo *This, PVOID pvRecord); +}; +#pragma pack(pop) + +/* 118 */ +/* enum tagDESCKIND +{ + DESCKIND_NONE = 0x0, + DESCKIND_FUNCDESC = 0x1, + DESCKIND_VARDESC = 0x2, + DESCKIND_TYPECOMP = 0x3, + DESCKIND_IMPLICITAPPOBJ = 0x4, + DESCKIND_MAX = 0x5, +}; */ + +/* 117 */ +typedef tagDESCKIND DESCKIND; + +/* 119 */ +typedef tagBINDPTR BINDPTR; + +/* 116 */ +#pragma pack(push, 8) +struct ITypeCompVtbl +{ + HRESULT (__stdcall *QueryInterface)(ITypeComp *This, const IID *const riid, void **ppvObject); + ULONG (__stdcall *AddRef)(ITypeComp *This); + ULONG (__stdcall *Release)(ITypeComp *This); + HRESULT (__stdcall *Bind)(ITypeComp *This, LPOLESTR szName, ULONG lHashVal, WORD wFlags, ITypeInfo **ppTInfo, DESCKIND *pDescKind, BINDPTR *pBindPtr); + HRESULT (__stdcall *BindType)(ITypeComp *This, LPOLESTR szName, ULONG lHashVal, ITypeInfo **ppTInfo, ITypeComp **ppTComp); +}; +#pragma pack(pop) + +/* 130 */ +#pragma pack(push, 8) +/* struct tagPARAMDESCEX +{ + ULONG cBytes; + VARIANTARG varDefaultValue; +}; */ +#pragma pack(pop) + +/* 184 */ +typedef tagTLIBATTR TLIBATTR; + +/* 183 */ +#pragma pack(push, 8) +struct ITypeLibVtbl +{ + HRESULT (__stdcall *QueryInterface)(ITypeLib *This, const IID *const riid, void **ppvObject); + ULONG (__stdcall *AddRef)(ITypeLib *This); + ULONG (__stdcall *Release)(ITypeLib *This); + UINT (__stdcall *GetTypeInfoCount)(ITypeLib *This); + HRESULT (__stdcall *GetTypeInfo)(ITypeLib *This, UINT index, ITypeInfo **ppTInfo); + HRESULT (__stdcall *GetTypeInfoType)(ITypeLib *This, UINT index, TYPEKIND *pTKind); + HRESULT (__stdcall *GetTypeInfoOfGuid)(ITypeLib *This, const GUID *const guid, ITypeInfo **ppTinfo); + HRESULT (__stdcall *GetLibAttr)(ITypeLib *This, TLIBATTR **ppTLibAttr); + HRESULT (__stdcall *GetTypeComp)(ITypeLib *This, ITypeComp **ppTComp); + HRESULT (__stdcall *GetDocumentation)(ITypeLib *This, INT index, BSTR *pBstrName, BSTR *pBstrDocString, DWORD *pdwHelpContext, BSTR *pBstrHelpFile); + HRESULT (__stdcall *IsName)(ITypeLib *This, LPOLESTR szNameBuf, ULONG lHashVal, BOOL *pfName); + HRESULT (__stdcall *FindName)(ITypeLib *This, LPOLESTR szNameBuf, ULONG lHashVal, ITypeInfo **ppTInfo, MEMBERID *rgMemId, USHORT *pcFound); + void (__stdcall *ReleaseTLibAttr)(ITypeLib *This, TLIBATTR *pTLibAttr); +}; +#pragma pack(pop) + +/* 120 */ +#pragma pack(push, 8) +/* union tagBINDPTR +{ + FUNCDESC *lpfuncdesc; + VARDESC *lpvardesc; + ITypeComp *lptcomp; +}; */ +#pragma pack(pop) + +/* 187 */ +/* enum tagSYSKIND +{ + SYS_WIN16 = 0x0, + SYS_WIN32 = 0x1, + SYS_MAC = 0x2, +}; */ + +/* 186 */ +typedef tagSYSKIND SYSKIND; + +/* 185 */ +#pragma pack(push, 8) +/* struct tagTLIBATTR +{ + GUID guid; + LCID lcid; + SYSKIND syskind; + WORD wMajorVerNum; + WORD wMinorVerNum; + WORD wLibFlags; +}; */ +#pragma pack(pop) + +/* 191 */ +struct TMenuItem +{ + int dwFlags; + char *pszStr; + void (__cdecl *fnMenu)(); +}; + +/* 203 */ +enum item_equip_type +{ + ILOC_NONE = 0x0, + ILOC_ONEHAND = 0x1, + ILOC_TWOHAND = 0x2, + ILOC_ARMOR = 0x3, + ILOC_HELM = 0x4, + ILOC_RING = 0x5, + ILOC_AMULET = 0x6, + ILOC_UNEQUIPABLE = 0x7, + ILOC_BELT = 0x8, + ILOC_INVALID = 0xFF, +}; + +/* 192 */ +struct ItemDataStruct +{ + int iRnd; + unsigned char iClass; + char iLoc; + int iCurs; + unsigned char itype; + char iItemId; + char *iName; + char *iSName; + int iMinMLvl; + int iDurability; + int iMinDam; + int iMaxDam; + int iMinAC; + int iMaxAC; + unsigned char iMinStr; + unsigned char iMinMag; + unsigned char iMinDex; + int iFlags; + int iMiscId; + int iSpell; + int iUsable; + int iValue; + int iMaxValue; +}; + +/* 319 */ +enum missile_id +{ + MIS_ARROW = 0x0, + MIS_FIREBOLT = 0x1, + MIS_GUARDIAN = 0x2, + MIS_RNDTELEPORT = 0x3, + MIS_LIGHTBALL = 0x4, + MIS_FIREWALL = 0x5, + MIS_FIREBALL = 0x6, + MIS_LIGHTCTRL = 0x7, + MIS_LIGHTNING = 0x8, + MIS_MISEXP = 0x9, + MIS_TOWN = 0xA, + MIS_FLASH = 0xB, + MIS_FLASH2 = 0xC, + MIS_MANASHIELD = 0xD, + MIS_FIREMOVE = 0xE, + MIS_CHAIN = 0xF, + MIS_NULL_10 = 0x10, + MIS_NULL_11 = 0x11, + MIS_NULL_12 = 0x12, + MIS_NULL_13 = 0x13, + MIS_RHINO = 0x14, + MIS_MAGMABALL = 0x15, + MIS_LIGHTCTRL2 = 0x16, + MIS_LIGHTNING2 = 0x17, + MIS_FLARE = 0x18, + MIS_MISEXP2 = 0x19, + MIS_TELEPORT = 0x1A, + MIS_LARROW = 0x1B, + MIS_DOOMSERP = 0x1C, + MIS_NULL_1D = 0x1D, + MIS_STONE = 0x1E, + MIS_NULL_1F = 0x1F, + MIS_INVISIBL = 0x20, + MIS_GOLEM = 0x21, + MIS_ETHEREALIZE = 0x22, + MIS_NULL_23 = 0x23, + MIS_BOOM = 0x24, + MIS_HEAL = 0x25, + MIS_FIREWALLC = 0x26, + MIS_INFRA = 0x27, + MIS_IDENTIFY = 0x28, + MIS_WAVE = 0x29, + MIS_NOVA = 0x2A, + MIS_BLODBOIL = 0x2B, + MIS_APOCA = 0x2C, + MIS_REPAIR = 0x2D, + MIS_RECHARGE = 0x2E, + MIS_DISARM = 0x2F, + MIS_FLAME = 0x30, + MIS_FLAMEC = 0x31, + MIS_NULL_32 = 0x32, + MIS_NULL_33 = 0x33, + MIS_CBOLT = 0x34, + MIS_HBOLT = 0x35, + MIS_RESURRECT = 0x36, + MIS_TELEKINESIS = 0x37, + MIS_LARROW2 = 0x38, + MIS_ACID = 0x39, + MIS_MISEXP3 = 0x3A, + MIS_ACIDPUD = 0x3B, + MIS_HEALOTHER = 0x3C, + MIS_ELEMENT = 0x3D, + MIS_RESURRECTBEAM = 0x3E, + MIS_BONESPIRIT = 0x3F, + MIS_WEAPEXP = 0x40, + MIS_RPORTAL = 0x41, + MIS_BOOM2 = 0x42, + MIS_DIABAPOCA = 0x43, +}; + +/* 200 */ +enum missile_graphic_id +{ + MFILE_ARROWS = 0x0, + MFILE_FIREBA = 0x1, + MFILE_GUARD = 0x2, + MFILE_LGHNING = 0x3, + MFILE_FIREWAL = 0x4, + MFILE_MAGBLOS = 0x5, + MFILE_PORTAL = 0x6, + MFILE_BLUEXFR = 0x7, + MFILE_BLUEXBK = 0x8, + MFILE_MANASHLD = 0x9, + MFILE_BLOOD = 0xA, + MFILE_BONE = 0xB, + MFILE_METLHIT = 0xC, + MFILE_FARROW = 0xD, + MFILE_DOOM = 0xE, + MFILE_0F = 0xF, + MFILE_BLODBUR = 0x10, + MFILE_NEWEXP = 0x11, + MFILE_SHATTER1 = 0x12, + MFILE_BIGEXP = 0x13, + MFILE_INFERNO = 0x14, + MFILE_THINLGHT = 0x15, + MFILE_FLARE = 0x16, + MFILE_FLAREEXP = 0x17, + MFILE_MAGBALL = 0x18, + MFILE_KRULL = 0x19, + MFILE_MINILTNG = 0x1A, + MFILE_HOLY = 0x1B, + MFILE_HOLYEXPL = 0x1C, + MFILE_LARROW = 0x1D, + MFILE_FIRARWEX = 0x1E, + MFILE_ACIDBF = 0x1F, + MFILE_ACIDSPLA = 0x20, + MFILE_ACIDPUD = 0x21, + MFILE_ETHRSHLD = 0x22, + MFILE_FIRERUN = 0x23, + MFILE_RESSUR1 = 0x24, + MFILE_SKLBALL = 0x25, + MFILE_RPORTAL = 0x26, + MFILE_FIREPLAR = 0x27, + MFILE_SCUBMISB = 0x28, + MFILE_SCBSEXPB = 0x29, + MFILE_SCUBMISC = 0x2A, + MFILE_SCBSEXPC = 0x2B, + MFILE_SCUBMISD = 0x2C, + MFILE_SCBSEXPD = 0x2D, + MFILE_NULL = 0x2E, + MFILE_INVALID = 0x2F, + MFILE_NONE = 0xFF, +}; + +/* 193 */ +struct MissileData +{ + char mName; + void (__fastcall *mAddProc)(int, int, int, int, int, int, int, int, int); + void (__fastcall *mProc)(int); + int mDraw; + unsigned char mType; + unsigned char mResist; + char mFileNum; + int mlSFX; + int miSFX; +}; + +/* 194 */ +struct MisFileData +{ + char mAnimName; + unsigned char mAnimFAmt; + char *mName; + int mFlags; + int mAnimCel[16]; + unsigned char mAnimDelay[16]; + unsigned char mAnimLen[16]; + int mAnimWidth[16]; + int mAnimWidth2[16]; +}; + +/* 323 */ +enum _mai_id +{ + MG_ZOMBIE = 0, + MG_FAT = 1, + MG_SKELSD = 2, + MG_SKELBOW = 3, + MG_SCAV = 4, + MG_RHINO = 5, + MG_GOATMC = 6, + MG_GOATBOW = 7, + MG_FALLEN = 8, + MG_MAGMA = 9, + MG_SKELKING = 10, + MG_BAT = 11, + MG_GARG = 12, + MG_CLEAVER = 13, + MG_SUCC = 14, + MG_SNEAK = 15, + MG_STORM = 16, + MG_FIREMAN = 17, + MG_GARBUD = 18, + MG_ACID = 19, + MG_ACIDUNIQ = 20, + MG_GOLUM = 21, + MG_ZHAR = 22, + MG_SNOTSPIL = 23, + MG_SNAKE = 24, + MG_COUNSELOR = 25, + MG_MEGA = 26, + MG_DIABLO = 27, + MG_LAZURUS = 28, + MG_LAZHELP = 29, + MG_LACHDANAN = 30, + MG_WARLORD = 31, +}; + +/* 324 */ +enum _mc_id +{ + MC_UNDEAD = 0, + MC_DEMON = 1, + MC_ANIMAL = 2, +}; + +/* 195 */ +struct MonsterData +{ + int flags; + int mType; + char *GraphicType; + int has_special; + char *sndfile; + int snd_special; + int has_trans; + char *TransFile; + int Frames[6]; + int Rate[6]; + char *mName; + unsigned char mMinDLvl; + unsigned char mMaxDLvl; + unsigned char mLevel; + int mMinHP; + int mMaxHP; + char mAi; + int mFlags; + unsigned char mInt; + unsigned char mHit; + unsigned char mAFNum; + unsigned char mMinDamage; + unsigned char mMaxDamage; + unsigned char mHit2; + unsigned char mAFNum2; + unsigned char mMinDamage2; + unsigned char mMaxDamage2; + unsigned char mArmorClass; + char mMonstClass; + short mMagicRes; + short mMagicRes2; + short mTreasure; + unsigned char mSelFlag; + int mExp; +}; + +/* 325 */ +enum _monster_id +{ + MON_ZOMBIEA = 0x0, + MON_ZOMBIEB = 0x1, + MON_ZOMBIEC = 0x2, + MON_ZOMBIED = 0x3, + MON_FALSPEARA = 0x4, + MON_FALSPEARB = 0x5, + MON_FALSPEARC = 0x6, + MON_FALSPEARD = 0x7, + MON_SKELAXEA = 0x8, + MON_SKELAXEB = 0x9, + MON_SKELAXEC = 0xA, + MON_SKELAXED = 0xB, + MON_FALSWORDA = 0xC, + MON_FALSWORDB = 0xD, + MON_FALSWORDC = 0xE, + MON_FALSWORDD = 0xF, + MON_SCAVA = 0x10, + MON_SCAVB = 0x11, + MON_SCAVC = 0x12, + MON_SCAVD = 0x13, + MON_SKELBOWA = 0x14, + MON_SKELBOWB = 0x15, + MON_SKELBOWC = 0x16, + MON_SKELBOWD = 0x17, + MON_SKELSDA = 0x18, + MON_SKELSDB = 0x19, + MON_SKELSDC = 0x1A, + MON_SKELSDD = 0x1B, + MON_TSNEAK = 0x1C, + MON_SNEAKA = 0x1D, + MON_SNEAKB = 0x1E, + MON_SNEAKC = 0x1F, + MON_SNEAKD = 0x20, + MON_GOATLORD = 0x21, + MON_GOATMACEA = 0x22, + MON_GOATMACEB = 0x23, + MON_GOATMACEC = 0x24, + MON_GOATMACED = 0x25, + MON_BATA = 0x26, + MON_BATB = 0x27, + MON_BATC = 0x28, + MON_BATD = 0x29, + MON_GOATBOWA = 0x2A, + MON_GOATBOWB = 0x2B, + MON_GOATBOWC = 0x2C, + MON_GOATBOWD = 0x2D, + MON_ACIDA = 0x2E, + MON_ACIDB = 0x2F, + MON_ACIDC = 0x30, + MON_ACIDD = 0x31, + MON_SKING = 0x32, + MON_BUTCH = 0x33, + MON_FATA = 0x34, + MON_FATB = 0x35, + MON_FATC = 0x36, + MON_FATD = 0x37, + MON_WORMA = 0x38, + MON_WORMB = 0x39, + MON_WORMC = 0x3A, + MON_WORMD = 0x3B, + MON_MAGMAA = 0x3C, + MON_MAGMAB = 0x3D, + MON_MAGMAC = 0x3E, + MON_MAGMAD = 0x3F, + MON_RHINOA = 0x40, + MON_RHINOB = 0x41, + MON_RHINOC = 0x42, + MON_RHINOD = 0x43, + MON_DEMSKEL = 0x44, + MON_THINE = 0x45, + MON_THINF = 0x46, + MON_THING = 0x47, + MON_FIREMANA = 0x48, + MON_FIREMANB = 0x49, + MON_FIREMANC = 0x4A, + MON_FIREMAND = 0x4B, + MON_THINA = 0x4C, + MON_THINB = 0x4D, + MON_THINC = 0x4E, + MON_THIND = 0x4F, + MON_BIGFALL = 0x50, + MON_GARGOYLEA = 0x51, + MON_GARGOYLEB = 0x52, + MON_GARGOYLEC = 0x53, + MON_GARGOYLED = 0x54, + MON_MEGAA = 0x55, + MON_MEGAB = 0x56, + MON_MEGAC = 0x57, + MON_MEGAD = 0x58, + MON_SNAKEA = 0x59, + MON_SNAKEB = 0x5A, + MON_SNAKEC = 0x5B, + MON_SNAKED = 0x5C, + MON_BLACKA = 0x5D, + MON_BLACKB = 0x5E, + MON_BLACKC = 0x5F, + MON_BLACKD = 0x60, + MON_UNRAVA = 0x61, + MON_UNRAVB = 0x62, + MON_UNRAVC = 0x63, + MON_UNRAVD = 0x64, + MON_SUCCA = 0x65, + MON_SUCCB = 0x66, + MON_SUCCC = 0x67, + MON_SUCCD = 0x68, + MON_MAGEA = 0x69, + MON_MAGEB = 0x6A, + MON_MAGEC = 0x6B, + MON_MAGED = 0x6C, + MON_GOLEM = 0x6D, + MON_DIABLO = 0x6E, + MON_DARKMAGE = 0x6F, + MON_NONE = 0xFF, +}; + +/* 326 */ +enum _speech_id +{ + TEXT_STORY1 = 0x0, + TEXT_TAVERN21 = 0x1, + TEXT_TAVERN22 = 0x2, + TEXT_TAVERN23 = 0x3, + TEXT_HEALER1 = 0x4, + TEXT_BMAID1 = 0x5, + TEXT_SMITH1 = 0x6, + TEXT_DRUNK1 = 0x7, + TEXT_WITCH1 = 0x8, + TEXT_PEGBOY1 = 0x9, + TEXT_SKING1 = 0xA, + TEXT_STORY2 = 0xB, + TEXT_TAVERN24 = 0xC, + TEXT_TAVERN25 = 0xD, + TEXT_HEALER2 = 0xE, + TEXT_BMAID2 = 0xF, + TEXT_SMITH2 = 0x10, + TEXT_DRUNK2 = 0x11, + TEXT_WITCH2 = 0x12, + TEXT_PEGBOY2 = 0x13, + TEXT_SNOT1 = 0x14, + TEXT_SNOT2 = 0x15, + TEXT_SNOT3 = 0x16, + TEXT_STORY36 = 0x17, + TEXT_STORY37 = 0x18, + TEXT_STORY38_1 = 0x19, + TEXT_TAVERN1 = 0x1A, + TEXT_STORY38_2 = 0x1B, + TEXT_STORY38_3 = 0x1C, + TEXT_HEALER3 = 0x1D, + TEXT_BMAID3 = 0x1E, + TEXT_SMITH3 = 0x1F, + TEXT_DRUNK3 = 0x20, + TEXT_WITCH3 = 0x21, + TEXT_PEGBOY3 = 0x22, + TEXT_LAZ1_1 = 0x23, + TEXT_LAZ1_2 = 0x24, + TEXT_STORY4 = 0x25, + TEXT_TAVERN2 = 0x26, + TEXT_HEALER20 = 0x27, + TEXT_HEALER21 = 0x28, + TEXT_HEALER22 = 0x29, + TEXT_BMAID4 = 0x2A, + TEXT_SMITH4 = 0x2B, + TEXT_DRUNK4 = 0x2C, + TEXT_WITCH4 = 0x2D, + TEXT_PEGBOY4 = 0x2E, + TEXT_STORY7 = 0x2F, + TEXT_TAVERN5 = 0x30, + TEXT_HEALER5 = 0x31, + TEXT_BMAID6 = 0x32, + TEXT_SMITH7 = 0x33, + TEXT_DRUNK7 = 0x34, + TEXT_WITCH7 = 0x35, + TEXT_PEGBOY7 = 0x36, + TEXT_STORY10 = 0x37, + TEXT_TAVERN8 = 0x38, + TEXT_HEALER8 = 0x39, + TEXT_BMAID8 = 0x3A, + TEXT_SMITH10 = 0x3B, + TEXT_DRUNK10 = 0x3C, + TEXT_WITCH10 = 0x3D, + TEXT_PEGBOY10 = 0x3E, + TEXT_WOUND = 0x3F, + TEXT_CLEAVER = 0x40, + TEXT_STORY12 = 0x41, + TEXT_TAVERN10 = 0x42, + TEXT_HEALER10 = 0x43, + TEXT_BMAID10 = 0x44, + TEXT_SMITH12 = 0x45, + TEXT_DRUNK12 = 0x46, + TEXT_WITCH12 = 0x47, + TEXT_PEGBOY11 = 0x48, + TEXT_STORY13 = 0x49, + TEXT_TAVERN11 = 0x4A, + TEXT_HEALER11 = 0x4B, + TEXT_BMAID11 = 0x4C, + TEXT_SMITH13 = 0x4D, + TEXT_DRUNK13 = 0x4E, + TEXT_WITCH13 = 0x4F, + TEXT_PEGBOY12 = 0x50, + TEXT_LACH1 = 0x51, + TEXT_LACH2 = 0x52, + TEXT_LACH3 = 0x53, + TEXT_STORY14 = 0x54, + TEXT_TAVERN12 = 0x55, + TEXT_HEALER12 = 0x56, + TEXT_BMAID12 = 0x57, + TEXT_SMITH21 = 0x58, + TEXT_SMITH22 = 0x59, + TEXT_SMITH23 = 0x5A, + TEXT_DRUNK14 = 0x5B, + TEXT_WITCH14 = 0x5C, + TEXT_PEGBOY13 = 0x5D, + TEXT_STORY15 = 0x5E, + TEXT_TAVERN13 = 0x5F, + TEXT_HEALER13 = 0x60, + TEXT_BMAID13 = 0x61, + TEXT_SMITH14 = 0x62, + TEXT_DRUNK15 = 0x63, + TEXT_WITCH15 = 0x64, + TEXT_PEGBOY14 = 0x65, + TEXT_STORY18 = 0x66, + TEXT_TAVERN16 = 0x67, + TEXT_HEALER16 = 0x68, + TEXT_BMAID16 = 0x69, + TEXT_SMITH17 = 0x6A, + TEXT_DRUNK17 = 0x6B, + TEXT_WITCH18 = 0x6C, + TEXT_PEGBOY17 = 0x6D, + TEXT_WARLRD1 = 0x6E, + TEXT_STORY20 = 0x6F, + TEXT_TAVERN18 = 0x70, + TEXT_HEALER18 = 0x71, + TEXT_BMAID18 = 0x72, + TEXT_SMITH24 = 0x73, + TEXT_SMITH25 = 0x74, + TEXT_SMITH26 = 0x75, + TEXT_DRUNK19 = 0x76, + TEXT_WITCH20 = 0x77, + TEXT_PEGBOY18 = 0x78, + TEXT_STORY21 = 0x79, + TEXT_TAVERN19 = 0x7A, + TEXT_HEALER26 = 0x7B, + TEXT_HEALER27 = 0x7C, + TEXT_BMAID19 = 0x7D, + TEXT_SMITH19 = 0x7E, + TEXT_DRUNK20 = 0x7F, + TEXT_WITCH22 = 0x80, + TEXT_WITCH23 = 0x81, + TEXT_WITCH24 = 0x82, + TEXT_WITCH25 = 0x83, + TEXT_WITCH26 = 0x84, + TEXT_PEGBOY19 = 0x85, + TEXT_STORY22 = 0x86, + TEXT_STORY23 = 0x87, + TEXT_STORY24 = 0x88, + TEXT_TAVERN20 = 0x89, + TEXT_HEALER19 = 0x8A, + TEXT_BMAID20 = 0x8B, + TEXT_SMITH20 = 0x8C, + TEXT_DRUNK21 = 0x8D, + TEXT_WITCH21 = 0x8E, + TEXT_PEGBOY20 = 0x8F, + TEXT_GARBUD1 = 0x90, + TEXT_GARBUD2 = 0x91, + TEXT_GARBUD3 = 0x92, + TEXT_GARBUD4 = 0x93, + TEXT_ZHAR1 = 0x94, + TEXT_ZHAR2 = 0x95, + TEXT_STORY25 = 0x96, + TEXT_STORY26 = 0x97, + TEXT_STORY27 = 0x98, + TEXT_STORY28 = 0x99, + TEXT_STORY29 = 0x9A, + TEXT_STORY30 = 0x9B, + TEXT_STORY31 = 0x9C, + TEXT_STORY33 = 0x9D, + TEXT_STORY34 = 0x9E, + TEXT_STORY35 = 0x9F, + TEXT_TAVERN36 = 0xA0, + TEXT_TAVERN37 = 0xA1, + TEXT_TAVERN38 = 0xA2, + TEXT_TAVERN39 = 0xA3, + TEXT_TAVERN40 = 0xA4, + TEXT_TAVERN41 = 0xA5, + TEXT_TAVERN43 = 0xA6, + TEXT_TAVERN44 = 0xA7, + TEXT_TAVERN45 = 0xA8, + TEXT_HEALER37 = 0xA9, + TEXT_HEALER38 = 0xAA, + TEXT_HEALER39 = 0xAB, + TEXT_HEALER40 = 0xAC, + TEXT_HEALER41 = 0xAD, + TEXT_HEALER42 = 0xAE, + TEXT_HEALER43 = 0xAF, + TEXT_HEALER45 = 0xB0, + TEXT_HEALER46 = 0xB1, + TEXT_HEALER47 = 0xB2, + TEXT_BMAID31 = 0xB3, + TEXT_BMAID32 = 0xB4, + TEXT_BMAID33 = 0xB5, + TEXT_BMAID34 = 0xB6, + TEXT_BMAID35 = 0xB7, + TEXT_BMAID36 = 0xB8, + TEXT_BMAID37 = 0xB9, + TEXT_BMAID39 = 0xBA, + TEXT_BMAID40 = 0xBB, + TEXT_SMITH44 = 0xBC, + TEXT_SMITH45 = 0xBD, + TEXT_SMITH46 = 0xBE, + TEXT_SMITH47 = 0xBF, + TEXT_SMITH48 = 0xC0, + TEXT_SMITH49 = 0xC1, + TEXT_SMITH50 = 0xC2, + TEXT_SMITH51 = 0xC3, + TEXT_SMITH52 = 0xC4, + TEXT_SMITH53 = 0xC5, + TEXT_SMITH55 = 0xC6, + TEXT_SMITH56 = 0xC7, + TEXT_DRUNK27 = 0xC8, + TEXT_DRUNK28 = 0xC9, + TEXT_DRUNK29 = 0xCA, + TEXT_DRUNK30 = 0xCB, + TEXT_DRUNK31 = 0xCC, + TEXT_DRUNK32 = 0xCD, + TEXT_DRUNK34 = 0xCE, + TEXT_DRUNK35 = 0xCF, + TEXT_DRUNK23 = 0xD0, + TEXT_DRUNK24 = 0xD1, + TEXT_DRUNK25 = 0xD2, + TEXT_DRUNK26 = 0xD3, + TEXT_WITCH38 = 0xD4, + TEXT_WITCH39 = 0xD5, + TEXT_WITCH40 = 0xD6, + TEXT_WITCH41 = 0xD7, + TEXT_WITCH42 = 0xD8, + TEXT_WITCH43 = 0xD9, + TEXT_WITCH44 = 0xDA, + TEXT_WITCH45 = 0xDB, + TEXT_WITCH46 = 0xDC, + TEXT_WITCH47 = 0xDD, + TEXT_WITCH49 = 0xDE, + TEXT_WITCH50 = 0xDF, + TEXT_PEGBOY32 = 0xE0, + TEXT_PEGBOY33 = 0xE1, + TEXT_PEGBOY34 = 0xE2, + TEXT_PEGBOY35 = 0xE3, + TEXT_PEGBOY36 = 0xE4, + TEXT_PEGBOY37 = 0xE5, + TEXT_PEGBOY38 = 0xE6, + TEXT_PEGBOY39 = 0xE7, + TEXT_PEGBOY40 = 0xE8, + TEXT_PEGBOY42 = 0xE9, + TEXT_PEGBOY43 = 0xEA, + TEXT_WARR1 = 0xEB, + TEXT_WARR10 = 0xEC, + TEXT_WARR11 = 0xED, + TEXT_WARR12 = 0xEE, + TEXT_MAGE1 = 0xEF, + TEXT_MAGE10 = 0xF0, + TEXT_MAGE11 = 0xF1, + TEXT_MAGE12 = 0xF2, + TEXT_ROGUE1 = 0xF3, + TEXT_ROGUE10 = 0xF4, + TEXT_ROGUE11 = 0xF5, + TEXT_ROGUE12 = 0xF6, + TEXT_COW1 = 0xF7, + TEXT_COW2 = 0xF8, + TEXT_NAR1 = 0xF9, + TEXT_NAR2 = 0xFA, + TEXT_NAR3 = 0xFB, + TEXT_NAR4 = 0xFC, + TEXT_NAR5 = 0xFD, + TEXT_NAR6 = 0xFE, + TEXT_NAR7 = 0xFF, + TEXT_NAR8 = 0x100, + TEXT_NAR9 = 0x101, + TEXT_TAVERN0 = 0x102, + TEXT_INVALID = 0xFFFFFFFF, +}; + +/* 196 */ +struct UniqMonstStruct +{ + char mtype; + char *mName; + char *mMode; + unsigned char mlevel; + unsigned short mmaxhp; + char mAi; + unsigned char mint; + unsigned char mMinDamage; + unsigned char mMaxDamage; + short mMagicRes; + short mUnqAttr; + unsigned char mUnqVar1; + unsigned char mUnqVar2; + int mtalkmsg; +}; + +/* 362 */ +enum object_graphic_id +{ + OFILE_L1BRAZ = 0x0, + OFILE_L1DOORS = 0x1, + OFILE_LEVER = 0x2, + OFILE_CHEST1 = 0x3, + OFILE_CHEST2 = 0x4, + OFILE_BANNER = 0x5, + OFILE_SKULPILE = 0x6, + OFILE_SKULFIRE = 0x7, + OFILE_SKULSTIK = 0x8, + OFILE_CRUXSK1 = 0x9, + OFILE_CRUXSK2 = 0xA, + OFILE_CRUXSK3 = 0xB, + OFILE_BOOK1 = 0xC, + OFILE_BOOK2 = 0xD, + OFILE_ROCKSTAN = 0xE, + OFILE_ANGEL = 0xF, + OFILE_CHEST3 = 0x10, + OFILE_BURNCROS = 0x11, + OFILE_CANDLE2 = 0x12, + OFILE_NUDE2 = 0x13, + OFILE_SWITCH4 = 0x14, + OFILE_TNUDEM = 0x15, + OFILE_TNUDEW = 0x16, + OFILE_TSOUL = 0x17, + OFILE_L2DOORS = 0x18, + OFILE_WTORCH4 = 0x19, + OFILE_WTORCH3 = 0x1A, + OFILE_SARC = 0x1B, + OFILE_FLAME1 = 0x1C, + OFILE_PRSRPLT1 = 0x1D, + OFILE_TRAPHOLE = 0x1E, + OFILE_MINIWATR = 0x1F, + OFILE_WTORCH2 = 0x20, + OFILE_WTORCH1 = 0x21, + OFILE_BCASE = 0x22, + OFILE_BSHELF = 0x23, + OFILE_WEAPSTND = 0x24, + OFILE_BARREL = 0x25, + OFILE_BARRELEX = 0x26, + OFILE_LSHRINEG = 0x27, + OFILE_RSHRINEG = 0x28, + OFILE_BLOODFNT = 0x29, + OFILE_DECAP = 0x2A, + OFILE_PEDISTL = 0x2B, + OFILE_L3DOORS = 0x2C, + OFILE_PFOUNTN = 0x2D, + OFILE_ARMSTAND = 0x2E, + OFILE_GOATSHRN = 0x2F, + OFILE_CAULDREN = 0x30, + OFILE_MFOUNTN = 0x31, + OFILE_TFOUNTN = 0x32, + OFILE_ALTBOY = 0x33, + OFILE_MCIRL = 0x34, + OFILE_BKSLBRNT = 0x35, + OFILE_MUSHPTCH = 0x36, + OFILE_LZSTAND = 0x37, +}; + +/* 197 */ +struct ObjDataStruct +{ + unsigned char oload; + char ofindex; + unsigned char ominlvl; + unsigned char omaxlvl; + unsigned char olvltype; + unsigned char otheme; + unsigned char oquest; + int oAnimFlag; + int oAnimDelay; + int oAnimLen; + int oAnimWidth; + int oSolidFlag; + int oMissFlag; + int oLightFlag; + unsigned char oBreak; + unsigned char oSelFlag; + int oTrapFlag; +}; + +/* 204 */ +enum dungeon_type +{ + DTYPE_TOWN = 0x0, + DTYPE_CATHEDRAL = 0x1, + DTYPE_CATACOMBS = 0x2, + DTYPE_CAVES = 0x3, + DTYPE_HELL = 0x4, + DTYPE_NONE = 0xFF, +}; + +/* 198 */ +struct QuestData +{ + unsigned char _qdlvl; + unsigned char _qdmultlvl; + char _qlvlt; + unsigned char _qdtype; + unsigned char _qdrnd; + unsigned char _qslvl; + unsigned char _qflags; //__declspec(align(4)) + int _qdmsg; + char *_qlstr; +}; + +/* 364 */ +enum spell_id_small +{ + REM4X_SPL_NULL = 0x0, + REM4X_SPL_FIREBOLT = 0x1, + REM4X_SPL_HEAL = 0x2, + REM4X_SPL_LIGHTNING = 0x3, + REM4X_SPL_FLASH = 0x4, + REM4X_SPL_IDENTIFY = 0x5, + REM4X_SPL_FIREWALL = 0x6, + REM4X_SPL_TOWN = 0x7, + REM4X_SPL_STONE = 0x8, + REM4X_SPL_INFRA = 0x9, + REM4X_SPL_RNDTELEPORT = 0xA, + REM4X_SPL_MANASHIELD = 0xB, + REM4X_SPL_FIREBALL = 0xC, + REM4X_SPL_GUARDIAN = 0xD, + REM4X_SPL_CHAIN = 0xE, + REM4X_SPL_WAVE = 0xF, + REM4X_SPL_DOOMSERP = 0x10, + REM4X_SPL_BLODRIT = 0x11, + REM4X_SPL_NOVA = 0x12, + REM4X_SPL_INVISIBIL = 0x13, + REM4X_SPL_FLAME = 0x14, + REM4X_SPL_GOLEM = 0x15, + REM4X_SPL_BLODBOIL = 0x16, + REM4X_SPL_TELEPORT = 0x17, + REM4X_SPL_APOCA = 0x18, + REM4X_SPL_ETHEREALIZE = 0x19, + REM4X_SPL_REPAIR = 0x1A, + REM4X_SPL_RECHARGE = 0x1B, + REM4X_SPL_DISARM = 0x1C, + REM4X_SPL_ELEMENT = 0x1D, + REM4X_SPL_CBOLT = 0x1E, + REM4X_SPL_HBOLT = 0x1F, + REM4X_SPL_RESURRECT = 0x20, + REM4X_SPL_TELEKINESIS = 0x21, + REM4X_SPL_HEALOTHER = 0x22, + REM4X_SPL_FLARE = 0x23, + REM4X_SPL_BONESPIRIT = 0x24, + REM4X_SPL_INVALID = 0xFF, +}; + +/* 357 */ +enum magic_type +{ + STYPE_FIRE = 0x0, + STYPE_LIGHTNING = 0x1, + STYPE_MAGIC = 0x2, +}; + +/* 361 */ +enum _spell_sfx +{ + REM4X_IS_CAST1 = 0x49, + REM4X_IS_CAST10 = 0x4A, + REM4X_IS_CAST12 = 0x4B, + REM4X_IS_CAST2 = 0x4C, + REM4X_IS_CAST3 = 0x4D, + REM4X_IS_CAST4 = 0x4E, + REM4X_IS_CAST5 = 0x4F, + REM4X_IS_CAST6 = 0x50, + REM4X_IS_CAST7 = 0x51, + REM4X_IS_CAST8 = 0x52, + REM4X_IS_CAST9 = 0x53, +}; + +/* 199 */ +struct SpellData +{ + char sName; + unsigned char sManaCost; + char sType; + char *sNameText; + char *sSkillText; + int sBookLvl; + int sStaffLvl; + int sTargeted; + unsigned char sTownSpell; + int sMinInt; + char sSFX; + char sMissiles[3]; + unsigned char sManaAdj; + unsigned char sMinMana; + int sStaffMin; + int sStaffMax; + int sBookCost; + int sStaffCost; +}; + +/* 206 */ +struct ActionFrame +{ + unsigned char NFrame; + unsigned char AFrame; + unsigned char WFrame; + unsigned char BFrame; + unsigned char DFrame; + unsigned char SFrame; + unsigned char HFrame; + unsigned char TNFrame; + unsigned char TWFrame; + unsigned char A2Frame; + unsigned char A3Frame; +}; + +/* 314 */ +struct Coord +{ + unsigned char x; + unsigned char y; +}; + +/* 208 */ +struct RECT8 +{ + Coord x; + Coord y; +}; + +/* 209 */ +enum theme_id +{ + THEME_BARREL = 0x0, + THEME_SHRINE = 0x1, + THEME_MONSTPIT = 0x2, + THEME_SKELROOM = 0x3, + THEME_TREASURE = 0x4, + THEME_LIBRARY = 0x5, + THEME_TORTURE = 0x6, + THEME_BLOODFOUNTAIN = 0x7, + THEME_DECAPITATED = 0x8, + THEME_PURIFYINGFOUNTAIN = 0x9, + THEME_ARMORSTAND = 0xA, + THEME_GOATSHRINE = 0xB, + THEME_CAULDRON = 0xC, + THEME_MURKYFOUNTAIN = 0xD, + THEME_TEARFOUNTAIN = 0xE, + THEME_BRNCROSS = 0xF, + THEME_WEAPONRACK = 0x10, + THEME_NONE = 0xFF, +}; + +/* 210 */ +struct QuestTalkData +{ + int _qinfra; + int _qblkm; + int _qgarb; + int _qzhar; + int _qveil; + int _qmod; + int _qbutch; + int _qbol; + int _qblind; + int _qblood; + int _qanvil; + int _qwarlrd; + int _qking; + int _qpw; + int _qbone; + int _qvb; +}; + +/* 211 */ +struct ShadowStruct +{ + unsigned char strig; + unsigned char s1; + unsigned char s2; + unsigned char s3; + unsigned char nv1; + unsigned char nv2; + unsigned char nv3; +}; + +/* 213 */ +struct POINT32 +{ + int x; + int y; +}; + +/* 214 */ +enum event_type +{ + EVENT_TYPE_PLAYER_CREATE_GAME = 1, + EVENT_TYPE_2 = 2, + EVENT_TYPE_PLAYER_LEAVE_GAME = 3, + EVENT_TYPE_PLAYER_MESSAGE = 4, + EVENT_TYPE_5 = 5, + EVENT_TYPE_6 = 6, + EVENT_TYPE_7 = 7, + EVENT_TYPE_8 = 8, + EVENT_TYPE_9 = 9, + EVENT_TYPE_10 = 10, + EVENT_TYPE_11 = 11, + EVENT_TYPE_12 = 12, + EVENT_TYPE_13 = 13, + EVENT_TYPE_14 = 14, + EVENT_TYPE_15 = 15, +}; + +/* 215 */ +enum text_color +{ + COL_WHITE = 0x0, + COL_BLUE = 0x1, + COL_RED = 0x2, + COL_GOLD = 0x3, +}; + +/* 218 */ +enum _difficulty +{ + DIFF_NORMAL = 0x0, + DIFF_NIGHTMARE = 0x1, + DIFF_HELL = 0x2, + NUM_DIFFICULTIES = 0x3, +}; + +/* 219 */ +struct ItemStruct +{ + int _iSeed; + short _iCreateInfo; + int _itype; + int _ix; + int _iy; + int _iAnimFlag; + int ItemFrame; + int _iAnimLen; + int _iAnimFrame; + int _iAnimWidth; + int _iAnimXOff; + int inactive_2C; + char _iSelFlag; + int _iPostDraw; + int _iIdentified; + char _iMagical; + char _iName[64]; + char _iIName[64]; + char _iLoc; + unsigned char _iClass; + int _iCurs; + int _ivalue; + int _iIvalue; + int _iMinDam; + int _iMaxDam; + int _iAC; + int _iFlags; + int _iMiscId; + int _iSpell; + int _iCharges; + int _iMaxCharges; + int _iDurability; + int _iMaxDur; + int _iPLDam; + int _iPLToHit; + int _iPLAC; + int _iPLStr; + int _iPLMag; + int _iPLDex; + int _iPLVit; + int _iPLFR; + int _iPLLR; + int _iPLMR; + int _iPLMana; + int _iPLHP; + int _iPLDamMod; + int _iPLGetHit; + int _iPLLight; + char _iSplLvlAdd; + char _iRequest; + int _iUid; + int _iFMinDam; + int _iFMaxDam; + int _iLMinDam; + int _iLMaxDam; + int _iPLEnAc; + char _iPrePower; + char _iSufPower; + int _iVAdd1; + int _iVMult1; + int _iVAdd2; + int _iVMult2; + char _iMinStr; + char _iMinMag; + char _iMinDex; + int _iStatFlag; + int IDidx; + int inactive_16C; +}; + +/* 220 */ +struct DeadStruct +{ + int _deadAnim[8]; + int _deadFrame; + int field_24; + int field_28; + int _deadtrans; +}; + +/* 221 */ +struct ScreenRow +{ + char col_unused_1[64]; + char pixels[640]; + char col_unused_2[64]; +}; + +/* 222 */ +struct Screen +{ + ScreenRow row_unused_1[160]; + ScreenRow row[480]; + ScreenRow row_unused_2[16]; +}; + +/* 223 */ +struct Tile +{ + short top; + short right; + short left; + short bottom; +}; + +/* 224 */ +struct DPiece +{ + short blocks; +}; + +/* 225 */ +struct _SNETVERSIONDATA +{ + int size; + char *versionstring; + char *executablefile; + char *originalarchivefile; + char *patcharchivefile; +}; + +/* 226 */ +struct LightListStruct +{ + int _lx; + int _ly; + int _lradius; + int _lid; + int _ldel; + int _lunflag; + int field_18; + int _lunx; + int _luny; + int _lunr; + int _xoff; + int _yoff; + int _lflags; +}; + +/* 227 */ +struct MissileStruct +{ + int _mitype; + int _mix; + int _miy; + int _mixoff; + int _miyoff; + int _mixvel; + int _miyvel; + int _misx; + int _misy; + int _mitxoff; + int _mityoff; + int _mimfnum; + int _mispllvl; + int _miDelFlag; + int _miAnimType; + int _miAnimFlags; + int _miAnimCel; + int _miAnimDelay; + int _miAnimLen; + int _miAnimWidth; + int _miAnimWidth2; + int _miAnimCnt; + int _miAnimAdd; + int _miAnimFrame; + int _miDrawFlag; + int _miLightFlag; + int _miPreFlag; + int _miUniqTrans; + int _mirange; + int _misource; + int _micaster; + int _midam; + int _miHitFlag; + int _midist; + int _mlid; + int _mirnd; + int _miVar1; + int _miVar2; + int _miVar3; + int _miVar4; + int _miVar5; + int _miVar6; + int _miVar7; + int _miVar8; +}; + +/* 347 */ +enum MON_MODE +{ + MM_STAND = 0, + MM_WALK = 1, + MM_WALK2 = 2, + MM_WALK3 = 3, + MM_ATTACK = 4, + MM_GOTHIT = 5, + MM_DEATH = 6, + MM_SATTACK = 7, + MM_FADEIN = 8, + MM_FADEOUT = 9, + MM_RATTACK = 10, + MM_SPSTAND = 11, + MM_RSPATTACK = 12, + MM_DELAY = 13, + MM_CHARGE = 14, + MM_STONE = 15, + MM_HEAL = 16, + MM_TALK = 17, +}; + +/* 228 */ +struct MonsterStruct +{ + int _mMTidx; + int _mmode; + int _mgoal; + int _mgoalvar1; + int _mgoalvar2; + int _mgoalvar3; + int field_18; + int _pathcount; + int _mx; + int _my; + int _mfutx; + int _mfuty; + int _moldx; + int _moldy; + int _mxoff; + int _myoff; + int _mxvel; + int _myvel; + int _mdir; + int _menemy; + char _menemyx; + char _menemyy; + short falign_52; + int _mAFNum; + int _mAnimDelay; + int _mAnimCnt; + int _mAnimLen; + int _mAnimFrame; + int _meflag; + int _mDelFlag; + int _mVar1; + int _mVar2; + int _mVar3; + int _mVar4; + int _mVar5; + int _mVar6; + int _mVar7; + int _mVar8; + int _mmaxhp; + int _mhitpoints; + char _mAi; + char _mint; + short falign_9A; + int _mFlags; + int _msquelch; + int falign_A4; + int _lastx; + int _lasty; + int _mRndSeed; + int _mAISeed; + int falign_B8; + char _uniqtype; + char _uniqtrans; + char _udeadval; + char mWhoHit; + short mLevel; + short mExp; + char mHit; + char mMinDamage; + char mMaxDamage; + char mHit2; + char mMinDamage2; + char mMaxDamage2; + char mArmorClass; + char falign_CB; + int mMagicRes; + int mtalkmsg; + char leader; + char leaderflag; + char unpackfilesize; + char mlid; + char *mName; + CMonster *MType; + MonsterData *MData; +}; + +/* 268 */ +struct AnimStruct +{ + int Frames[9]; + int Rate; + int Delay; +}; + +/* 229 */ +struct CMonster +{ + char mtype; + char mPlaceFlags; + AnimStruct Anims[6]; + TSnd *Snds[8]; + int flags_1; + int flags_2; + char mMinHP; + char mMaxHP; + int has_special; + char mAFNum; + char mdeadval; + MonsterData *MData; + void *trans_file; +}; + +/* 285 */ +#pragma pack(push, 1) +/* struct tWAVEFORMATEX +{ + WORD wFormatTag; + WORD nChannels; + DWORD nSamplesPerSec; + DWORD nAvgBytesPerSec; + WORD nBlockAlign; + WORD wBitsPerSample; + WORD cbSize; +}; */ +#pragma pack(pop) + +/* 284 */ +typedef tWAVEFORMATEX WAVEFORMATEX; + +/* 283 */ +struct TSnd +{ + WAVEFORMATEX fmt; + short field_12; + int len; + int offset; + int sound_path; + IDirectSoundBuffer *DSB; + int start_tc; +}; + +/* 259 */ +/* struct IDirectSoundBuffer +{ + struct IDirectSoundBuffer::IDirectSoundBufferVtbl *lpVtbl; +}; */ + +/* 232 */ +struct DObjectStr +{ + char bCmd; +}; + +/* 233 __declspec(align(1))*/ +struct DMonsterStr +{ + char _mx; + char _my; + char _mdir; + char _menemy; + char _mactive; + int _mhitpoints; +}; + +/* 302 __declspec(align(2))*/ +struct TCmdPItem +{ + char bCmd; + char x; + char y; + short wIndx; + short wCI; + int dwSeed; + char bId; + char bDur; + char bMDur; + char bCh; + char bMCh; + short wValue; + int dwBuff; +}; + +/* 234 __declspec(align(1))*/ +struct DLevel +{ + TCmdPItem item[127]; + DObjectStr object[127]; + DMonsterStr monster[200]; +}; + +/* 316 */ +struct DPortal +{ + char x; + char y; + char level; + char ltype; + char setlvl; +}; + +/* 317 */ +struct MultiQuests +{ + char qstate; + char qlog; + char qvar1; +}; + +/* 235 */ +struct DJunk +{ + DPortal portal[4]; + MultiQuests quests[4]; +}; + +/* 236 __declspec(align(1)) */ +struct PkItemStruct +{ + int iSeed; + short iCreateInfo; + short idx; + char bId; + char bDur; + char bMDur; + char bCh; + char bMCh; + short wValue; + int dwBuff; +}; + +/* 237 __declspec(align(2)) */ +struct PkPlayerStruct +{ + FILETIME archiveTime; + char destAction; + char destParam1; + char destParam2; + char plrlevel; + char px; + char py; + char targx; + char targy; + char pName[32]; + char pClass; + char pBaseStr; + char pBaseMag; + char pBaseDex; + char pBaseVit; + char pLevel; + char pStatPts; + int pExperience; + int pGold; + int pHPBase; + int pMaxHPBase; + int pManaBase; + int pMaxManaBase; + char pSplLvl[37]; + int pMemSpells; + int pMemSpells2; + PkItemStruct InvBody[7]; + PkItemStruct InvList[40]; + char InvGrid[40]; + char _pNumInv; + PkItemStruct SpdList[8]; + char pTownWarps; + char pDungMsgs; + char pLvlLoad; + char pBattleNet; + char pManaShield; + char bReserved[3]; + short wReserved[8]; + int pDiabloKillLevel; + int dwReserved[7]; +}; + +/* 238 */ +struct ObjectStruct +{ + int _otype; + int _ox; + int _oy; + int _oLight; + int _oAnimFlag; + int _oAnimCel; + int _oAnimDelay; + int _oAnimCnt; + int _oAnimLen; + int _oAnimFrame; + int _oAnimWidth; + int _oAnimWidth2; + int _oDelFlag; + int _oBreak; + int _oSolidFlag; + int _oMissFlag; + int _oSelFlag; + int _oPreFlag; + int _oTrapFlag; + int _oDoorFlag; + int _olid; + int _oRndSeed; + int _oVar1; + int _oVar2; + int _oVar3; + int _oVar4; + int _oVar5; + int _oVar6; + int _oVar7; + int _oVar8; +}; + +/* 239 */ +typedef tagPALETTEENTRY PALETTEENTRY; + +/* 240 */ +struct PATHNODE +{ + char f; + char h; + short g; + int x; + int y; + struct PATHNODE *Parent; + struct PATHNODE *Child[8]; + struct PATHNODE *NextNode; +}; + +/* 346 */ +enum PLR_MODE +{ + PM_STAND = 0, + PM_WALK = 1, + PM_WALK2 = 2, + PM_WALK3 = 3, + PM_ATTACK = 4, + PM_RATTACK = 5, + PM_BLOCK = 6, + PM_GOTHIT = 7, + PM_DEATH = 8, + PM_SPELL = 9, + PM_NEWLVL = 10, + PM_QUIT = 11, +}; + +/* 241 */ +struct PlayerStruct +{ + int _pmode; + char walkpath[25]; + char plractive[3]; + int destAction; + int destParam1; + int destParam2; + int destParam3; + int destParam4; + int plrlevel; + int WorldX; + int WorldY; + int _px; + int _py; + int _ptargx; + int _ptargy; + int _pownerx; + int _pownery; + int _poldx; + int _poldy; + int _pxoff; + int _pyoff; + int _pxvel; + int _pyvel; + int _pdir; + int _nextdir; + int _pgfxnum; + int _pAnimData; + int _pAnimDelay; + int _pAnimCnt; + int _pAnimLen; + int _pAnimFrame; + int _pAnimWidth; + int _pAnimWidth2; + int _peflag; + int _plid; + int _pvid; + int _pSpell; + char _pSplType; + char _pSplFrom; + int _pTSpell; + int _pTSplType; + int _pRSpell; + int _pRSplType; + int _pSBkSpell; + char _pSBkSplType; + char _pSplLvl[64]; + int _pMemSpells[2]; // __declspec(align(8)) + int _pAblSpells[2]; + int _pScrlSpells[2]; + int _pSpellFlags; + int _pSplHotKey[4]; + char _pSplTHotKey[4]; + int _pwtype; + char _pBlockFlag; + char _pInvincible; + char _pLightRad; + char _pLvlChanging; + char _pName[32]; + int _pClass; + int _pStrength; + int _pBaseStr; + int _pMagic; + int _pBaseMag; + int _pDexterity; + int _pBaseDex; + int _pVitality; + int _pBaseVit; + int _pStatPts; + int _pDamageMod; + int _pBaseToBlk; + int _pHPBase; + int _pMaxHPBase; + int _pHitPoints; + int _pMaxHP; + int _pHPPer; + int _pManaBase; + int _pMaxManaBase; + int _pMana; + int _pMaxMana; + int _pManaPer; + char _pLevel; + char _pMaxLvl; + int _pExperience; + int _pMaxExp; + int _pNextExper; + char _pArmorClass; + char _pMagResist; + char _pFireResist; + char _pLghtResist; + int _pGold; + int _pInfraFlag; + int _pVar1; + int _pVar2; + int _pVar3; + int _pVar4; + int _pVar5; + int _pVar6; + int _pVar7; + int _pVar8; + char _pLvlVisited[17]; + char _pSLvlVisited[10]; + char gap20F[9]; + int _pGFXLoad; + int _peqN[8]; + int _pNFrames; + int _pNFNum; + int _peqW[8]; + int _pWFrames; + int _pWFNum; + int _peqA[8]; + int _pAFrames; + int frame_9_unk; + int _pAFNum; + int _peqS2_LM[8]; + int _peqS1_FM[8]; + int _peqS3_QM[8]; + int _pSFrames; + int frame_A_unk; + int _pSFNum; + int _peqH[8]; + int _pHFrames; + int _pHFNum; + int _peqD[8]; + int _pDFrames; + int _pDFNum; + int _peqB[8]; + int _pBFrames; + int _pBFNum; + ItemStruct InvBody[7]; + ItemStruct InvList[40]; + int _pNumInv; + char InvGrid[40]; + ItemStruct SpdList[8]; + ItemStruct HoldItem; + int _pIMinDam; + int _pIMaxDam; + int _pIAC; + int _pIBonusDam; + int _pIBonusToHit; + int _pIBonusAC; + int _pIBonusDamMod; + int _pISpells[2]; //__declspec(align(8)) + int _pIFlags; + int _pIGetHit; + char _pISplLvlAdd; + char _pISplCost; + int _pISplDur; + int _pIEnAc; + int _pIFMinDam; + int _pIFMaxDam; + int _pILMinDam; + int _pILMaxDam; + int _pOilType; + char pTownWarps; + char pDungMsgs; + char pLvlLoad; + char pBattleNet; + char pManaShield; + char bReserved[3]; + short wReserved[8]; + int pDiabloKillLevel; + int dwReserved[7]; + void *pSFrame; + void *pWFrame; + void *pAFrame; + void *pLFrame; + void *pFFrame; + void *pQFrame; + void *pHFrame; + void *pDFrame; + void *pBFrame; + int unused_54D4; +}; + +/* 242 */ +struct QuestStruct +{ + char _qlevel; + char _qtype; + char _qactive; + char _qlvltype; + int _qtx; + int _qty; + char _qslvl; + char _qidx; + char _qmsg; + char _qvar1; + char _qvar2; + int _qlog; +}; + +/* 243 */ +typedef _DDSURFACEDESC DDSURFACEDESC; + +/* 245 */ +/* union _DDSURFACEDESC::$091DBF7D405BE25E65B16620C008128B +{ + LONG lPitch; + DWORD dwLinearSize; +}; */ + +/* 246 */ +/* union _DDSURFACEDESC::$9AB659F8D6A45F8C7834A76B9C40973B +{ + DWORD dwMipMapCount; + DWORD dwZBufferBitDepth; + DWORD dwRefreshRate; +}; */ + +/* 248 */ +/* struct _DDCOLORKEY +{ + DWORD dwColorSpaceLowValue; + DWORD dwColorSpaceHighValue; +}; */ + +/* 247 */ +/* typedef _DDCOLORKEY DDCOLORKEY; + */ +/* 251 */ + + +/* 250 */ +/* struct _DDPIXELFORMAT +{ + DWORD dwSize; + DWORD dwFlags; + DWORD dwFourCC; + union + { + DWORD dwRGBBitCount; + DWORD dwYUVBitCount; + DWORD dwZBufferBitDepth; + DWORD dwAlphaBitDepth; + }; + union + { + DWORD dwRBitMask; + DWORD dwYBitMask; + }; + union + { + DWORD dwGBitMask; + DWORD dwUBitMask; + }; + union + { + DWORD dwBBitMask; + DWORD dwVBitMask; + }; + union + { + DWORD dwRGBAlphaBitMask; + DWORD dwYUVAlphaBitMask; + DWORD dwRGBZBitMask; + DWORD dwYUVZBitMask; + }; +}; */ + +/* 249 */ +typedef _DDPIXELFORMAT DDPIXELFORMAT; + +/* 257 */ +/* struct _DDSCAPS +{ + DWORD dwCaps; +}; */ + +/* 256 */ +/* typedef _DDSCAPS DDSCAPS; + */ +/* 244 */ +/* struct _DDSURFACEDESC +{ + DWORD dwSize; + DWORD dwFlags; + DWORD dwHeight; + DWORD dwWidth; + union + { + LONG lPitch; + DWORD dwLinearSize; + }; + DWORD dwBackBufferCount; + union + { + DWORD dwMipMapCount; + DWORD dwZBufferBitDepth; + DWORD dwRefreshRate; + }; + DWORD dwAlphaBitDepth; + DWORD dwReserved; + LPVOID lpSurface; + DDCOLORKEY ddckCKDestOverlay; + DDCOLORKEY ddckCKDestBlt; + DDCOLORKEY ddckCKSrcOverlay; + DDCOLORKEY ddckCKSrcBlt; + DDPIXELFORMAT ddpfPixelFormat; + DDSCAPS ddsCaps; +}; */ + +/* 258 */ +struct SHA1Context +{ + int state[5]; + int count[2]; + char buffer[64]; +}; + +/* 260 */ +/* struct IDirectSound +{ + struct IDirectSound::IDirectSoundVtbl *lpVtbl; +}; + */ +/* 261 */ +struct ThemeStruct +{ + int ttype; + int ttval; +}; + +/* 262 */ +struct TMsgHeader +{ + char next; + char start_tc; + char len; +}; + +/* 263 */ +struct TMsg +{ + TMsgHeader hdr; + char data; +}; + +/* 265 */ +struct TNQ +{ + char _qsttype; + char _qstmsg; + char _qstmsgact; +}; + +/* 264 */ +struct TownerStruct +{ + int _tmode; + int _ttype; + int _tx; + int _ty; + int _txoff; + int _tyoff; + int _txvel; + int _tyvel; + int _tdir; + void *_tAnimCel; + int _tAnimDelay; + int _tAnimCnt; + int _tAnimLen; + int _tAnimFrame; + int _tAnimFrameCnt; + int _tAnimOrder; + int _tAnimWidth; + int _tAnimWidth2; + int _tTenPer; + int _teflag; + int _tbtcnt; + int _tSelFlag; + int _tMsgSaid; + TNQ qsts[16]; + int _tSeed; + int _tVar1; + int _tVar2; + int _tVar3; + int _tVar4; + char _tName[32]; + int _tNAnim[8]; + int _tNFrames; + char *_tNData; +}; + +/* 266 */ +struct _SNETUIDATA +{ + int size; + int uiflags; + HWND parentwindow; + void (__cdecl *artcallback)(); + void (__cdecl *authcallback)(); + void (__cdecl *createcallback)(); + void (__cdecl *drawdesccallback)(); + void (__cdecl *selectedcallback)(); + void (__cdecl *messageboxcallback)(); + void (__cdecl *soundcallback)(); + void (__cdecl *statuscallback)(); + void (__cdecl *getdatacallback)(); + void (__cdecl *categorycallback)(); + void (__cdecl *field_34)(); + void (__cdecl *field_38)(); + void (__cdecl *profilecallback)(); + void (__cdecl *profilegetstring)(); + void (__cdecl *profiledraw)(); + void (__cdecl *selecthero)(); + void (__cdecl *createhero)(); +}; + +/* 267 */ +struct _SNETPROGRAMDATA +{ + int size; + char *programname; + char *programdescription; + int programid; + int versionid; + int reserved1; + int maxplayers; + int multi_seed; + void *initdata; + int initdatabytes; + void *reserved2; + int optcategorybits; + int reserved3; + int reserved4; + int languageid; +}; + +/* 269 */ +struct _uiheroinfo +{ + _uiheroinfo *next; + char name[16]; + short level; + char heroclass; + char herorank; + short strength; + short magic; + short dexterity; + short vitality; + int gold; + int hassaved; + int spawned; +}; + +/* 270 */ +enum template_id +{ + TEMPLATE_ERR_DX = 0x68, + TEMPLATE_ERR_NOMEMORY = 0x69, + TEMPLATE_ERR_NOFILE = 0x6A, + TEMPLATE_ERR_DDRAW = 0x6B, + TEMPLATE_ERR_DSOUND = 0x6C, + TEMPLATE_ERR_DISKSPACE = 0x6E, + TEMPLATE_ERR_VIDEOMODE = 0x6F, + TEMPLATE_ERR_INSERTCD = 0x70, + TEMPLATE_ERR_RESTRICTED = 0x71, + TEMPLATE_ERR_READONLY = 0x72, +}; + +/* 271 */ +enum spell_type +{ + RSPLTYPE_SKILL = 0x0, + RSPLTYPE_SPELL = 0x1, + RSPLTYPE_SCROLL = 0x2, + RSPLTYPE_CHARGES = 0x3, + RSPLTYPE_INVALID = 0x4, +}; + +/* 272 */ +enum cursor_id +{ + CURSOR_NONE = 0x0, + CURSOR_HAND = 0x1, + CURSOR_IDENTIFY = 0x2, + CURSOR_REPAIR = 0x3, + CURSOR_RECHARGE = 0x4, + CURSOR_DISARM = 0x5, + CURSOR_OIL = 0x6, + CURSOR_TELEKINESIS = 0x7, + CURSOR_RESURRECT = 0x8, + CURSOR_TELEPORT = 0x9, + CURSOR_HEALOTHER = 0xA, + CURSOR_HOURGLASS = 0xB, + CURSOR_FIRSTITEM = 0xC, +}; + +/* 273 */ +enum direction +{ + DIR_S = 0x0, + DIR_SW = 0x1, + DIR_W = 0x2, + DIR_NW = 0x3, + DIR_N = 0x4, + DIR_NE = 0x5, + DIR_E = 0x6, + DIR_SE = 0x7, + DIR_OMNI = 0x8, +}; + +/* 274 */ +enum interface_mode +{ + WM_DIABNEXTLVL = 0x402, + WM_DIABPREVLVL = 0x403, + WM_DIABRTNLVL = 0x404, + WM_DIABSETLVL = 0x405, + WM_DIABWARPLVL = 0x406, + WM_DIABTOWNWARP = 0x407, + WM_DIABTWARPUP = 0x408, + WM_DIABRETOWN = 0x409, + WM_DIABNEWGAME = 0x40A, + WM_DIABLOADGAME = 0x40B, + WM_LEIGHSKIP = 0x40C, + WM_DIAVNEWLVL = 0x40D, +}; + +/* 275 */ +/* struct MenuItem +{ + MenuItemVtbl *lpVtbl; +}; */ + +/* 276 */ +typedef tagVS_FIXEDFILEINFO VS_FIXEDFILEINFO; + +/* 277 */ +/* struct tagVS_FIXEDFILEINFO +{ + DWORD dwSignature; + DWORD dwStrucVersion; + DWORD dwFileVersionMS; + DWORD dwFileVersionLS; + DWORD dwProductVersionMS; + DWORD dwProductVersionLS; + DWORD dwFileFlagsMask; + DWORD dwFileFlags; + DWORD dwFileOS; + DWORD dwFileType; + DWORD dwFileSubtype; + DWORD dwFileDateMS; + DWORD dwFileDateLS; +}; */ + +/* 278 */ +struct _BLOCKENTRY +{ + int offset; + int sizealloc; + int sizefile; + int flags; +}; + +/* 279 __declspec(align(2)) */ +struct TCmdGItem +{ + char bCmd; + char bMaster; + char bPnum; + char bCursitem; + char bLevel; + char x; + char y; + short wIndx; + short wCI; + int dwSeed; + char bId; + char bDur; + char bMDur; + char bCh; + char bMCh; + short wValue; + int dwBuff; + int dwTime; +}; + +/* 280 */ +struct TCmdLoc +{ + char bCmd; + char x; + char y; +}; + +/* 281 __declspec(align(1)) */ +struct TCmdParam1 +{ + char bCmd; + short wParam1; +}; + +/* 282 __declspec(align(1)) */ +struct TCmdLocParam1 +{ + char bCmd; + char x; + char y; + short wParam1; +}; + +/* 286 __declspec(align(1)) */ +struct TPktHdr +{ + char px; + char py; + char targx; + char targy; + int php; + int pmhp; + char bstr; + char bmag; + char bdex; + short wCheck; + short wLen; +}; + +/* 287 */ +struct _SNETEVENT +{ + int eventid; + int playerid; + void *data; + int databytes; +}; + +/* 288 */ +enum game_info +{ + GAME_INFO_NAME = 1, + GAME_INFO_PASS = 2, +}; + +/* 289 */ +struct _SNETPLAYERDATA +{ + int size; + char *playername; + char *playerdescription; + int field_C; +}; + +/* 290 */ +struct _SNETCAPS +{ + int size; + int flags; + int maxmessagesize; + int maxqueuesize; + int maxplayers; + int bytessec; + int latencyms; + int defaultturnssec; + int defaultturnsintransit; +}; + +/* 293 */ +struct TMPQHeader +{ + int dwID; + int dwHeaderSize; + int dwArchiveSize; + short wFormatVersion; + short wSectorSize; + int dwHashTablePos; + int dwBlockTablePos; + int dwHashTableSize; + int dwBlockTableSize; + char field_20[72]; +}; + +/* 294 */ +struct _uidefaultstats +{ + short strength; + short magic; + short dexterity; + short vitality; +}; + +/* 295 __declspec(align(1)) */ +struct TCmdLocParam2 +{ + char bCmd; + char x; + char y; + short wParam1; + short wParam2; +}; + +/* 296 __declspec(align(1)) */ +struct TCmdLocParam3 +{ + char bCmd; + char x; + char y; + short wParam1; + short wParam2; + short wParam3; +}; + +/* 297 __declspec(align(1)) */ +struct TCmdParam2 +{ + char bCmd; + short wParam1; + short wParam2; +}; + +/* 298 __declspec(align(1)) */ +struct TCmdParam3 +{ + char bCmd; + short wParam1; + short wParam2; + short wParam3; +}; + +/* 299 */ +struct TCmd +{ + char bCmd; +}; + +/* 300 __declspec(align(2)) */ +struct TCmdGolem +{ + char bCmd; + char _mx; + char _my; + char _mdir; + char _menemy; + int _mhitpoints; + char _currlevel; +}; + +/* 301 */ +struct TCmdQuest +{ + char bCmd; + char q; + char qstate; + char qlog; + char qvar1; +}; + +/* 303 __declspec(align(1)) */ +struct TCmdChItem +{ + char bCmd; + char bLoc; + short wIndx; + short wCI; + int dwSeed; + char bId; +}; + +/* 304 */ +struct TCmdDelItem +{ + char bCmd; + char bLoc; +}; + +/* 305 __declspec(align(2)) */ +struct TCmdDamage +{ + char bCmd; + char bPlr; + int dwDam; +}; + +/* 306 */ +struct TFakeCmdPlr +{ + char bCmd; + char bPlr; +}; + +/* 307 __declspec(align(2)) */ +struct TFakeDropPlr +{ + char bCmd; + char bPlr; + int dwReason; +}; + +/* 308 */ +struct TCmdString +{ + char bCmd; + char str[80]; +}; + +/* 309 __declspec(align(1)) */ +struct TCmdPlrInfoHdr +{ + char bCmd; + short wOffset; + short wBytes; +}; + +/* 310 */ +struct PortalStruct +{ + int open; + int x; + int y; + int level; + int ltype; + int setlvl; +}; + +/* 313 */ +struct CircleCoord +{ + unsigned char n_1; + Coord delta_1[1]; + unsigned char n_4; + Coord delta_4[4]; + unsigned char n_16; + Coord delta_16[16]; + unsigned char n_24; + Coord delta_24[24]; + unsigned char n_32; + Coord delta_32[32]; + unsigned char n_40; + Coord delta_40[40]; + unsigned char n_48; + Coord delta_48[48]; + unsigned char n_56; + Coord delta_56[56]; + unsigned char n_64; + Coord delta_64[64]; + unsigned char n_72; + Coord delta_72[72]; + unsigned char n_80; + Coord delta_80[80]; + unsigned char n_88; + Coord delta_88[88]; + unsigned char n_96; + Coord delta_96[96]; + unsigned char n_104; + Coord delta_104[104]; + unsigned char n_112; + Coord delta_112[112]; + unsigned char n_120; + Coord delta_120[120]; + unsigned char n_128; + Coord delta_128[128]; + unsigned char n_136; + Coord delta_136[136]; + unsigned char n_144; + Coord delta_144[144]; +}; + +/* 315 */ +struct TriggerStruct +{ + int _tx; + int _ty; + int _tmsg; + int _tlvl; +}; + +/* 318 */ +struct THEME_LOC +{ + int x; + int y; + int ttval; + int width; + int height; +}; + +/* 320 */ +enum spell_id +{ + SPL_NULL = 0x0, + SPL_FIREBOLT = 0x1, + SPL_HEAL = 0x2, + SPL_LIGHTNING = 0x3, + SPL_FLASH = 0x4, + SPL_IDENTIFY = 0x5, + SPL_FIREWALL = 0x6, + SPL_TOWN = 0x7, + SPL_STONE = 0x8, + SPL_INFRA = 0x9, + SPL_RNDTELEPORT = 0xA, + SPL_MANASHIELD = 0xB, + SPL_FIREBALL = 0xC, + SPL_GUARDIAN = 0xD, + SPL_CHAIN = 0xE, + SPL_WAVE = 0xF, + SPL_DOOMSERP = 0x10, + SPL_BLODRIT = 0x11, + SPL_NOVA = 0x12, + SPL_INVISIBIL = 0x13, + SPL_FLAME = 0x14, + SPL_GOLEM = 0x15, + SPL_BLODBOIL = 0x16, + SPL_TELEPORT = 0x17, + SPL_APOCA = 0x18, + SPL_ETHEREALIZE = 0x19, + SPL_REPAIR = 0x1A, + SPL_RECHARGE = 0x1B, + SPL_DISARM = 0x1C, + SPL_ELEMENT = 0x1D, + SPL_CBOLT = 0x1E, + SPL_HBOLT = 0x1F, + SPL_RESURRECT = 0x20, + SPL_TELEKINESIS = 0x21, + SPL_HEALOTHER = 0x22, + SPL_FLARE = 0x23, + SPL_BONESPIRIT = 0x24, + SPL_INVALID = 0xFFFFFFFF, +}; + +/* 322 */ +enum _cmd_id +{ + CMD_STAND = 0, + CMD_WALKXY = 1, + CMD_ACK_PLRINFO = 2, + CMD_ADDSTR = 3, + CMD_ADDMAG = 4, + CMD_ADDDEX = 5, + CMD_ADDVIT = 6, + CMD_SBSPELL = 7, + CMD_GETITEM = 8, + CMD_AGETITEM = 9, + CMD_PUTITEM = 10, + CMD_RESPAWNITEM = 11, + CMD_ATTACKXY = 12, + CMD_RATTACKXY = 13, + CMD_SPELLXY = 14, + CMD_TSPELLXY = 15, + CMD_OPOBJXY = 16, + CMD_DISARMXY = 17, + CMD_ATTACKID = 18, + CMD_ATTACKPID = 19, + CMD_RATTACKID = 20, + CMD_RATTACKPID = 21, + CMD_SPELLID = 22, + CMD_SPELLPID = 23, + CMD_TSPELLID = 24, + CMD_TSPELLPID = 25, + CMD_RESURRECT = 26, + CMD_OPOBJT = 27, + CMD_KNOCKBACK = 28, + CMD_TALKXY = 29, + CMD_NEWLVL = 30, + CMD_WARP = 31, + CMD_CHEAT_EXPERIENCE = 32, + CMD_CHEAT_SPELL_LEVEL = 33, + CMD_DEBUG = 34, + CMD_SYNCDATA = 35, + CMD_MONSTDEATH = 36, + CMD_MONSTDAMAGE = 37, + CMD_PLRDEAD = 38, + CMD_REQUESTGITEM = 39, + CMD_REQUESTAGITEM = 40, + CMD_GOTOGETITEM = 41, + CMD_GOTOAGETITEM = 42, + CMD_OPENDOOR = 43, + CMD_CLOSEDOOR = 44, + CMD_OPERATEOBJ = 45, + CMD_PLROPOBJ = 46, + CMD_BREAKOBJ = 47, + CMD_CHANGEPLRITEMS = 48, + CMD_DELPLRITEMS = 49, + CMD_PLRDAMAGE = 50, + CMD_PLRLEVEL = 51, + CMD_DROPITEM = 52, + CMD_PLAYER_JOINLEVEL = 53, + CMD_SEND_PLRINFO = 54, + CMD_SATTACKXY = 55, + CMD_ACTIVATEPORTAL = 56, + CMD_DEACTIVATEPORTAL = 57, + CMD_DLEVEL_0 = 58, + CMD_DLEVEL_1 = 59, + CMD_DLEVEL_2 = 60, + CMD_DLEVEL_3 = 61, + CMD_DLEVEL_4 = 62, + CMD_DLEVEL_5 = 63, + CMD_DLEVEL_6 = 64, + CMD_DLEVEL_7 = 65, + CMD_DLEVEL_8 = 66, + CMD_DLEVEL_9 = 67, + CMD_DLEVEL_10 = 68, + CMD_DLEVEL_11 = 69, + CMD_DLEVEL_12 = 70, + CMD_DLEVEL_13 = 71, + CMD_DLEVEL_14 = 72, + CMD_DLEVEL_15 = 73, + CMD_DLEVEL_16 = 74, + CMD_DLEVEL_JUNK = 75, + CMD_DLEVEL_END = 76, + CMD_HEALOTHER = 77, + CMD_STRING = 78, + CMD_SETSTR = 79, + CMD_SETMAG = 80, + CMD_SETDEX = 81, + CMD_SETVIT = 82, + CMD_RETOWN = 83, + CMD_SPELLXYD = 84, + CMD_ITEMEXTRA = 85, + CMD_SYNCPUTITEM = 86, + CMD_KILLGOLEM = 87, + CMD_SYNCQUEST = 88, + CMD_ENDSHIELD = 89, + CMD_AWAKEGOLEM = 90, + CMD_NOVA = 91, + CMD_SETSHIELD = 92, + CMD_REMSHIELD = 93, + FAKE_CMD_SETID = 94, + FAKE_CMD_DROPID = 95, + NUM_CMDS = 96, +}; + +/* 327 */ +struct STextStruct +{ + int _sx; + int _syoff; + char _sstr[128]; + int _sjust; + int _sclr; + int _sline; + int _ssel; + int _sval; +}; + +/* 328 */ +enum _talker_id +{ + TOWN_SMITH = 0x0, + TOWN_HEALER = 0x1, + TOWN_DEADGUY = 0x2, + TOWN_TAVERN = 0x3, + TOWN_STORY = 0x4, + TOWN_DRUNK = 0x5, + TOWN_WITCH = 0x6, + TOWN_BMAID = 0x7, + TOWN_PEGBOY = 0x8, + TOWN_COW = 0x9, + TOWN_PRIEST = 0xA, +}; + +/* 329 */ +struct HALLNODE +{ + int nHallx1; + int nHally1; + int nHallx2; + int nHally2; + int nHalldir; + HALLNODE *pNext; +}; + +/* 330 */ +struct ROOMNODE +{ + int nRoomx1; + int nRoomy1; + int nRoomx2; + int nRoomy2; + int nRoomDest; +}; + +/* 331 */ +struct LocalLevel +{ + char automapsv[40][40]; +}; + +/* 332 */ +struct TMegaPkt +{ + TMegaPkt *pNext; + int dwSpaceLeft; + char data[32000]; +}; + +/* 333 */ +struct ScrollStruct +{ + int _sxoff; + int _syoff; + int _sdx; + int _sdy; + int _sdir; +}; + +/* 334 */ +struct _gamedata +{ + int dwSeed; + int bDiff; +}; + +/* 335 */ +struct TPkt +{ + TPktHdr hdr; + char body[493]; +}; + +/* 336 */ +enum _music_id +{ + TMUSIC_TOWN = 0, + TMUSIC_L1 = 1, + TMUSIC_L2 = 2, + TMUSIC_L3 = 3, + TMUSIC_L4 = 4, + TMUSIC_INTRO = 5, + NUM_MUSIC = 6, +}; + +/* 337 */ +struct DIABFILE +{ + int _cnt; + char *_ptr; + char *_base; + int _bufsiz; + int _flag; + int _file; + char *_name_to_remove; +}; + +/* 338 */ +typedef pcmwaveformat_tag PCMWAVEFORMAT; + +/* 341 */ +#pragma pack(push, 1) +/* struct waveformat_tag +{ + WORD wFormatTag; + WORD nChannels; + DWORD nSamplesPerSec; + DWORD nAvgBytesPerSec; + WORD nBlockAlign; +}; */ +#pragma pack(pop) + +/* 340 */ +typedef waveformat_tag WAVEFORMAT; + +/* 339 */ +#pragma pack(push, 1) +/* struct pcmwaveformat_tag +{ + WAVEFORMAT wf; + WORD wBitsPerSample; +}; */ +#pragma pack(pop) + +/* 342 */ +struct _plrmsg +{ + int time; + char player; + char msg[144]; + char falign_95[3]; +}; + +/* 343 */ +enum _copyprot_results +{ + COPYPROT_OK = 1, + COPYPROT_CANCEL = 2, +}; + +/* 344 */ +enum _mainmenu_selections +{ + MAINMENU_SINGLE_PLAYER = 1, + MAINMENU_MULTIPLAYER = 2, + MAINMENU_REPLAY_INTRO = 3, + MAINMENU_SHOW_CREDITS = 4, + MAINMENU_EXIT_DIABLO = 5, + MAINMENU_ATTRACT_MODE = 6, +}; + +/* 345 */ +struct ItemGetRecordStruct +{ + int nSeed; + short wCI; + int nIndex; + int dwTimestamp; +}; + +/* 348 */ +enum panel_button_id +{ + PANBTN_CHARINFO = 0, + PANBTN_QLOG = 1, + PANBTN_AUTOMAP = 2, + PANBTN_MAINMENU = 3, + PANBTN_INVENTORY = 4, + PANBTN_SPELLBOOK = 5, + PANBTN_SENDMSG = 6, + PANBTN_FRIENDLY = 7, +}; + +/* 349 */ +enum attribute_id +{ + ATTRIB_STR = 0, + ATTRIB_MAG = 1, + ATTRIB_DEX = 2, + ATTRIB_VIT = 3, +}; + +/* 350 */ +/* enum _virtual_keys +{ + VK_LBUTTON = 0x1, + VK_RBUTTON = 0x2, + VK_CANCEL = 0x3, + VK_MBUTTON = 0x4, + VK_BACK = 0x8, + VK_TAB = 0x9, + VK_CLEAR = 0xC, + VK_RETURN = 0xD, + VK_SHIFT = 0x10, + VK_CONTROL = 0x11, + VK_MENU = 0x12, + VK_PAUSE = 0x13, + VK_CAPITAL = 0x14, + VK_KANA = 0x15, + VK_JUNJA = 0x17, + VK_FINAL = 0x18, + VK_KANJI = 0x19, + VK_ESCAPE = 0x1B, + VK_CONVERT = 0x1C, + VK_NONCONVERT = 0x1D, + VK_ACCEPT = 0x1E, + VK_MODECHANGE = 0x1F, + VK_SPACE = 0x20, + VK_PRIOR = 0x21, + VK_NEXT = 0x22, + VK_END = 0x23, + VK_HOME = 0x24, + VK_LEFT = 0x25, + VK_UP = 0x26, + VK_RIGHT = 0x27, + VK_DOWN = 0x28, + VK_SELECT = 0x29, + VK_PRINT = 0x2A, + VK_EXECUTE = 0x2B, + VK_SNAPSHOT = 0x2C, + VK_INSERT = 0x2D, + VK_DELETE = 0x2E, + VK_HELP = 0x2F, + VK_LWIN = 0x5B, + VK_RWIN = 0x5C, + VK_APPS = 0x5D, + VK_NUMPAD0 = 0x60, + VK_NUMPAD1 = 0x61, + VK_NUMPAD2 = 0x62, + VK_NUMPAD3 = 0x63, + VK_NUMPAD4 = 0x64, + VK_NUMPAD5 = 0x65, + VK_NUMPAD6 = 0x66, + VK_NUMPAD7 = 0x67, + VK_NUMPAD8 = 0x68, + VK_NUMPAD9 = 0x69, + VK_MULTIPLY = 0x6A, + VK_ADD = 0x6B, + VK_SEPARATOR = 0x6C, + VK_SUBTRACT = 0x6D, + VK_DECIMAL = 0x6E, + VK_DIVIDE = 0x6F, + VK_F1 = 0x70, + VK_F2 = 0x71, + VK_F3 = 0x72, + VK_F4 = 0x73, + VK_F5 = 0x74, + VK_F6 = 0x75, + VK_F7 = 0x76, + VK_F8 = 0x77, + VK_F9 = 0x78, + VK_F10 = 0x79, + VK_F11 = 0x7A, + VK_F12 = 0x7B, + VK_F13 = 0x7C, + VK_F14 = 0x7D, + VK_F15 = 0x7E, + VK_F16 = 0x7F, + VK_F17 = 0x80, + VK_F18 = 0x81, + VK_F19 = 0x82, + VK_F20 = 0x83, + VK_F21 = 0x84, + VK_F22 = 0x85, + VK_F23 = 0x86, + VK_F24 = 0x87, + VK_NUMLOCK = 0x90, + VK_SCROLL = 0x91, + VK_LSHIFT = 0xA0, + VK_RSHIFT = 0xA1, + VK_LCONTROL = 0xA2, + VK_RCONTROL = 0xA3, + VK_LMENU = 0xA4, + VK_RMENU = 0xA5, + VK_PROCESSKEY = 0xE5, + VK_ATTN = 0xF6, + VK_CRSEL = 0xF7, + VK_EXSEL = 0xF8, + VK_EREOF = 0xF9, + VK_PLAY = 0xFA, + VK_ZOOM = 0xFB, + VK_NONAME = 0xFC, + VK_PA1 = 0xFD, + VK_OEM_CLEAR = 0xFE, +}; */ + +/* 351 */ +/* enum _window_messages +{ + WM_NULL = 0x0, + WM_CREATE = 0x1, + WM_DESTROY = 0x2, + WM_MOVE = 0x3, + WM_SIZE = 0x5, + WM_ACTIVATE = 0x6, + WM_SETFOCUS = 0x7, + WM_KILLFOCUS = 0x8, + WM_ENABLE = 0xA, + WM_SETREDRAW = 0xB, + WM_SETTEXT = 0xC, + WM_GETTEXT = 0xD, + WM_GETTEXTLENGTH = 0xE, + WM_PAINT = 0xF, + WM_CLOSE = 0x10, + WM_QUERYENDSESSION = 0x11, + WM_QUIT = 0x12, + WM_QUERYOPEN = 0x13, + WM_ERASEBKGND = 0x14, + WM_SYSCOLORCHANGE = 0x15, + WM_ENDSESSION = 0x16, + WM_SHOWWINDOW = 0x18, + WM_WININICHANGE = 0x1A, + WM_DEVMODECHANGE = 0x1B, + WM_ACTIVATEAPP = 0x1C, + WM_FONTCHANGE = 0x1D, + WM_TIMECHANGE = 0x1E, + WM_CANCELMODE = 0x1F, + WM_SETCURSOR = 0x20, + WM_MOUSEACTIVATE = 0x21, + WM_CHILDACTIVATE = 0x22, + WM_QUEUESYNC = 0x23, + WM_GETMINMAXINFO = 0x24, + WM_PAINTICON = 0x26, + WM_ICONERASEBKGND = 0x27, + WM_NEXTDLGCTL = 0x28, + WM_SPOOLERSTATUS = 0x2A, + WM_DRAWITEM = 0x2B, + WM_MEASUREITEM = 0x2C, + WM_DELETEITEM = 0x2D, + WM_VKEYTOITEM = 0x2E, + WM_CHARTOITEM = 0x2F, + WM_SETFONT = 0x30, + WM_GETFONT = 0x31, + WM_SETHOTKEY = 0x32, + WM_GETHOTKEY = 0x33, + WM_QUERYDRAGICON = 0x37, + WM_COMPAREITEM = 0x39, + WM_GETOBJECT = 0x3D, + WM_COMPACTING = 0x41, + WM_COMMNOTIFY = 0x44, + WM_WINDOWPOSCHANGING = 0x46, + WM_WINDOWPOSCHANGED = 0x47, + WM_POWER = 0x48, + WM_COPYDATA = 0x4A, + WM_CANCELJOURNAL = 0x4B, + WM_NOTIFY = 0x4E, + WM_INPUTLANGCHANGEREQUEST = 0x50, + WM_INPUTLANGCHANGE = 0x51, + WM_TCARD = 0x52, + WM_HELP = 0x53, + WM_USERCHANGED = 0x54, + WM_NOTIFYFORMAT = 0x55, + WM_CONTEXTMENU = 0x7B, + WM_STYLECHANGING = 0x7C, + WM_STYLECHANGED = 0x7D, + WM_DISPLAYCHANGE = 0x7E, + WM_GETICON = 0x7F, + WM_SETICON = 0x80, + WM_NCCREATE = 0x81, + WM_NCDESTROY = 0x82, + WM_NCCALCSIZE = 0x83, + WM_NCHITTEST = 0x84, + WM_NCPAINT = 0x85, + WM_NCACTIVATE = 0x86, + WM_GETDLGCODE = 0x87, + WM_SYNCPAINT = 0x88, + WM_NCMOUSEMOVE = 0xA0, + WM_NCLBUTTONDOWN = 0xA1, + WM_NCLBUTTONUP = 0xA2, + WM_NCLBUTTONDBLCLK = 0xA3, + WM_NCRBUTTONDOWN = 0xA4, + WM_NCRBUTTONUP = 0xA5, + WM_NCRBUTTONDBLCLK = 0xA6, + WM_NCMBUTTONDOWN = 0xA7, + WM_NCMBUTTONUP = 0xA8, + WM_NCMBUTTONDBLCLK = 0xA9, + WM_KEYFIRST = 0x100, + WM_KEYDOWN = 0x100, + WM_KEYUP = 0x101, + WM_CHAR = 0x102, + WM_DEADCHAR = 0x103, + WM_SYSKEYDOWN = 0x104, + WM_SYSKEYUP = 0x105, + WM_SYSCHAR = 0x106, + WM_SYSDEADCHAR = 0x107, + WM_KEYLAST = 0x108, + WM_IME_STARTCOMPOSITION = 0x10D, + WM_IME_ENDCOMPOSITION = 0x10E, + WM_IME_COMPOSITION = 0x10F, + WM_IME_KEYLAST = 0x10F, + WM_INITDIALOG = 0x110, + WM_COMMAND = 0x111, + WM_SYSCOMMAND = 0x112, + WM_TIMER = 0x113, + WM_HSCROLL = 0x114, + WM_VSCROLL = 0x115, + WM_INITMENU = 0x116, + WM_INITMENUPOPUP = 0x117, + WM_MENUSELECT = 0x11F, + WM_MENUCHAR = 0x120, + WM_ENTERIDLE = 0x121, + WM_MENURBUTTONUP = 0x122, + WM_MENUDRAG = 0x123, + WM_MENUGETOBJECT = 0x124, + WM_UNINITMENUPOPUP = 0x125, + WM_MENUCOMMAND = 0x126, + WM_CTLCOLORMSGBOX = 0x132, + WM_CTLCOLOREDIT = 0x133, + WM_CTLCOLORLISTBOX = 0x134, + WM_CTLCOLORBTN = 0x135, + WM_CTLCOLORDLG = 0x136, + WM_CTLCOLORSCROLLBAR = 0x137, + WM_CTLCOLORSTATIC = 0x138, + WM_MOUSEFIRST = 0x200, + WM_MOUSEMOVE = 0x200, + WM_LBUTTONDOWN = 0x201, + WM_LBUTTONUP = 0x202, + WM_LBUTTONDBLCLK = 0x203, + WM_RBUTTONDOWN = 0x204, + WM_RBUTTONUP = 0x205, + WM_RBUTTONDBLCLK = 0x206, + WM_MBUTTONDOWN = 0x207, + WM_MBUTTONUP = 0x208, + WM_MBUTTONDBLCLK = 0x209, + WM_MOUSEWHEEL = 0x20A, + WM_MOUSELAST = 0x20A, + WM_PARENTNOTIFY = 0x210, + WM_ENTERMENULOOP = 0x211, + WM_EXITMENULOOP = 0x212, + WM_NEXTMENU = 0x213, + WM_SIZING = 0x214, + WM_CAPTURECHANGED = 0x215, + WM_MOVING = 0x216, + WM_POWERBROADCAST = 0x218, + WM_DEVICECHANGE = 0x219, + WM_MDICREATE = 0x220, + WM_MDIDESTROY = 0x221, + WM_MDIACTIVATE = 0x222, + WM_MDIRESTORE = 0x223, + WM_MDINEXT = 0x224, + WM_MDIMAXIMIZE = 0x225, + WM_MDITILE = 0x226, + WM_MDICASCADE = 0x227, + WM_MDIICONARRANGE = 0x228, + WM_MDIGETACTIVE = 0x229, + WM_MDISETMENU = 0x230, + WM_ENTERSIZEMOVE = 0x231, + WM_EXITSIZEMOVE = 0x232, + WM_DROPFILES = 0x233, + WM_MDIREFRESHMENU = 0x234, + WM_IME_SETCONTEXT = 0x281, + WM_IME_NOTIFY = 0x282, + WM_IME_CONTROL = 0x283, + WM_IME_COMPOSITIONFULL = 0x284, + WM_IME_SELECT = 0x285, + WM_IME_CHAR = 0x286, + WM_IME_REQUEST = 0x288, + WM_IME_KEYDOWN = 0x290, + WM_IME_KEYUP = 0x291, + WM_MOUSEHOVER = 0x2A1, + WM_MOUSELEAVE = 0x2A3, + WM_CUT = 0x300, + WM_COPY = 0x301, + WM_PASTE = 0x302, + WM_CLEAR = 0x303, + WM_UNDO = 0x304, + WM_RENDERFORMAT = 0x305, + WM_RENDERALLFORMATS = 0x306, + WM_DESTROYCLIPBOARD = 0x307, + WM_DRAWCLIPBOARD = 0x308, + WM_PAINTCLIPBOARD = 0x309, + WM_VSCROLLCLIPBOARD = 0x30A, + WM_SIZECLIPBOARD = 0x30B, + WM_ASKCBFORMATNAME = 0x30C, + WM_CHANGECBCHAIN = 0x30D, + WM_HSCROLLCLIPBOARD = 0x30E, + WM_QUERYNEWPALETTE = 0x30F, + WM_PALETTEISCHANGING = 0x310, + WM_PALETTECHANGED = 0x311, + WM_HOTKEY = 0x312, + WM_PRINT = 0x317, + WM_PRINTCLIENT = 0x318, + WM_HANDHELDFIRST = 0x358, + WM_HANDHELDLAST = 0x35F, + WM_AFXFIRST = 0x360, + WM_AFXLAST = 0x37F, + WM_PENWINFIRST = 0x380, + WM_PENWINLAST = 0x38F, +}; */ + +/* 352 */ +enum _object_id +{ + OBJ_L1LIGHT = 0x0, + OBJ_L1LDOOR = 0x1, + OBJ_L1RDOOR = 0x2, + OBJ_SKFIRE = 0x3, + OBJ_LEVER = 0x4, + OBJ_CHEST1 = 0x5, + OBJ_CHEST2 = 0x6, + OBJ_CHEST3 = 0x7, + OBJ_CANDLE1 = 0x8, + OBJ_CANDLE2 = 0x9, + OBJ_CANDLEO = 0xA, + OBJ_BANNERL = 0xB, + OBJ_BANNERM = 0xC, + OBJ_BANNERR = 0xD, + OBJ_SKPILE = 0xE, + OBJ_SKSTICK1 = 0xF, + OBJ_SKSTICK2 = 0x10, + OBJ_SKSTICK3 = 0x11, + OBJ_SKSTICK4 = 0x12, + OBJ_SKSTICK5 = 0x13, + OBJ_CRUX1 = 0x14, + OBJ_CRUX2 = 0x15, + OBJ_CRUX3 = 0x16, + OBJ_STAND = 0x17, + OBJ_ANGEL = 0x18, + OBJ_BOOK2L = 0x19, + OBJ_BCROSS = 0x1A, + OBJ_NUDEW2R = 0x1B, + OBJ_SWITCHSKL = 0x1C, + OBJ_TNUDEM1 = 0x1D, + OBJ_TNUDEM2 = 0x1E, + OBJ_TNUDEM3 = 0x1F, + OBJ_TNUDEM4 = 0x20, + OBJ_TNUDEW1 = 0x21, + OBJ_TNUDEW2 = 0x22, + OBJ_TNUDEW3 = 0x23, + OBJ_TORTURE1 = 0x24, + OBJ_TORTURE2 = 0x25, + OBJ_TORTURE3 = 0x26, + OBJ_TORTURE4 = 0x27, + OBJ_TORTURE5 = 0x28, + OBJ_BOOK2R = 0x29, + OBJ_L2LDOOR = 0x2A, + OBJ_L2RDOOR = 0x2B, + OBJ_TORCHL = 0x2C, + OBJ_TORCHR = 0x2D, + OBJ_TORCHL2 = 0x2E, + OBJ_TORCHR2 = 0x2F, + OBJ_SARC = 0x30, + OBJ_FLAMEHOLE = 0x31, + OBJ_FLAMELVR = 0x32, + OBJ_WATER = 0x33, + OBJ_BOOKLVR = 0x34, + OBJ_TRAPL = 0x35, + OBJ_TRAPR = 0x36, + OBJ_BOOKSHELF = 0x37, + OBJ_WEAPRACK = 0x38, + OBJ_BARREL = 0x39, + OBJ_BARRELEX = 0x3A, + OBJ_SHRINEL = 0x3B, + OBJ_SHRINER = 0x3C, + OBJ_SKELBOOK = 0x3D, + OBJ_BOOKCASEL = 0x3E, + OBJ_BOOKCASER = 0x3F, + OBJ_BOOKSTAND = 0x40, + OBJ_BOOKCANDLE = 0x41, + OBJ_BLOODFTN = 0x42, + OBJ_DECAP = 0x43, + OBJ_TCHEST1 = 0x44, + OBJ_TCHEST2 = 0x45, + OBJ_TCHEST3 = 0x46, + OBJ_BLINDBOOK = 0x47, + OBJ_BLOODBOOK = 0x48, + OBJ_PEDISTAL = 0x49, + OBJ_L3LDOOR = 0x4A, + OBJ_L3RDOOR = 0x4B, + OBJ_PURIFYINGFTN = 0x4C, + OBJ_ARMORSTAND = 0x4D, + OBJ_ARMORSTANDN = 0x4E, + OBJ_GOATSHRINE = 0x4F, + OBJ_CAULDRON = 0x50, + OBJ_MURKYFTN = 0x51, + OBJ_TEARFTN = 0x52, + OBJ_ALTBOY = 0x53, + OBJ_MCIRCLE1 = 0x54, + OBJ_MCIRCLE2 = 0x55, + OBJ_STORYBOOK = 0x56, + OBJ_STORYCANDLE = 0x57, + OBJ_STEELTOME = 0x58, + OBJ_WARARMOR = 0x59, + OBJ_WARWEAP = 0x5A, + OBJ_TBCROSS = 0x5B, + OBJ_WEAPONRACK = 0x5C, + OBJ_WEAPONRACKN = 0x5D, + OBJ_MUSHPATCH = 0x5E, + OBJ_LAZSTAND = 0x5F, + OBJ_SLAINHERO = 0x60, + OBJ_SIGNCHEST = 0x61, + OBJ_NULL_98 = 0x62, +}; + +/* 353 */ +enum item_misc_id +{ + IMISC_NONE = 0x0, + IMISC_USEFIRST = 0x1, + IMISC_FULLHEAL = 0x2, + IMISC_HEAL = 0x3, + IMISC_OLDHEAL = 0x4, + IMISC_DEADHEAL = 0x5, + IMISC_MANA = 0x6, + IMISC_FULLMANA = 0x7, + IMISC_08 = 0x8, + IMISC_09 = 0x9, + IMISC_ELIXSTR = 0xA, + IMISC_ELIXMAG = 0xB, + IMISC_ELIXDEX = 0xC, + IMISC_ELIXVIT = 0xD, + IMISC_ELIXWEAK = 0xE, + IMISC_ELIXDIS = 0xF, + IMISC_ELIXCLUM = 0x10, + IMISC_ELIXSICK = 0x11, + IMISC_REJUV = 0x12, + IMISC_FULLREJUV = 0x13, + IMISC_USELAST = 0x14, + IMISC_SCROLL = 0x15, + IMISC_SCROLLT = 0x16, + IMISC_STAFF = 0x17, + IMISC_BOOK = 0x18, + IMISC_RING = 0x19, + IMISC_AMULET = 0x1A, + IMISC_UNIQUE = 0x1B, + IMISC_HEAL_1C = 0x1C, + IMISC_1D = 0x1D, + IMISC_1E = 0x1E, + IMISC_1F = 0x1F, + IMISC_20 = 0x20, + IMISC_21 = 0x21, + IMISC_22 = 0x22, + IMISC_23 = 0x23, + IMISC_24 = 0x24, + IMISC_25 = 0x25, + IMISC_26 = 0x26, + IMISC_27 = 0x27, + IMISC_28 = 0x28, + IMISC_29 = 0x29, + IMISC_MAPOFDOOM = 0x2A, + IMISC_EAR = 0x2B, + IMISC_SPECELIX = 0x2C, + IMISC_INVALID = 0xFFFFFFFF, +}; + +/* 354 */ +enum item_type +{ + ITYPE_MISC = 0x0, + ITYPE_SWORD = 0x1, + ITYPE_AXE = 0x2, + ITYPE_BOW = 0x3, + ITYPE_MACE = 0x4, + ITYPE_SHIELD = 0x5, + ITYPE_LARMOR = 0x6, + ITYPE_HELM = 0x7, + ITYPE_MARMOR = 0x8, + ITYPE_HARMOR = 0x9, + ITYPE_STAFF = 0xA, + ITYPE_GOLD = 0xB, + ITYPE_RING = 0xC, + ITYPE_AMULET = 0xD, + ITYPE_0E = 0xE, + ITYPE_NONE = 0xFFFFFFFF, +}; + +/* 355 */ +enum _item_indexes +{ + IDI_GOLD = 0x0, + IDI_WARRIOR = 0x1, + IDI_WARRSHLD = 0x2, + IDI_WARRCLUB = 0x3, + IDI_ROGUE = 0x4, + IDI_SORCEROR = 0x5, + IDI_CLEAVER = 0x6, + IDI_FIRSTQUEST = 0x6, + IDI_SKCROWN = 0x7, + IDI_INFRARING = 0x8, + IDI_ROCK = 0x9, + IDI_OPTAMULET = 0xA, + IDI_TRING = 0xB, + IDI_BANNER = 0xC, + IDI_HARCREST = 0xD, + IDI_STEELVEIL = 0xE, + IDI_GLDNELIX = 0xF, + IDI_ANVIL = 0x10, + IDI_MUSHROOM = 0x11, + IDI_BRAIN = 0x12, + IDI_FUNGALTM = 0x13, + IDI_SPECELIX = 0x14, + IDI_BLDSTONE = 0x15, + IDI_LASTQUEST = 0x16, + IDI_MAPOFDOOM = 0x16, + IDI_EAR = 0x17, + IDI_HEAL = 0x18, + IDI_MANA = 0x19, + IDI_IDENTIFY = 0x1A, + IDI_PORTAL = 0x1B, + IDI_ARMOFVAL = 0x1C, + IDI_FULLHEAL = 0x1D, + IDI_FULLMANA = 0x1E, + IDI_GRISWOLD = 0x1F, + IDI_LGTFORGE = 0x20, + IDI_LAZSTAFF = 0x21, + IDI_RESURRECT = 0x22, +}; + +/* 356 */ +enum _setlevels +{ + SL_SKELKING = 0x1, + SL_BONECHAMB = 0x2, + SL_MAZE = 0x3, + SL_POISONWATER = 0x4, + SL_VILEBETRAYER = 0x5, +}; + +/* 358 */ +enum quest_id +{ + QTYPE_INFRA = 0x0, + QTYPE_BLKM = 0x1, + QTYPE_GARB = 0x2, + QTYPE_ZHAR = 0x3, + QTYPE_VEIL = 0x4, + QTYPE_MOD = 0x5, + QTYPE_BUTCH = 0x6, + QTYPE_BOL = 0x7, + QTYPE_BLIND = 0x8, + QTYPE_BLOOD = 0x9, + QTYPE_ANVIL = 0xA, + QTYPE_WARLRD = 0xB, + QTYPE_KING = 0xC, + QTYPE_PW = 0xD, + QTYPE_BONE = 0xE, + QTYPE_VB = 0xF, + QTYPE_INVALID = 0xFFFFFFFF, +}; + +/* 359 */ +enum talk_id +{ + STORE_NONE = 0x0, + STORE_SMITH = 0x1, + STORE_SBUY = 0x2, + STORE_SSELL = 0x3, + STORE_SREPAIR = 0x4, + STORE_WITCH = 0x5, + STORE_WBUY = 0x6, + STORE_WSELL = 0x7, + STORE_WRECHARGE = 0x8, + STORE_NOMONEY = 0x9, + STORE_NOROOM = 0xA, + STORE_CONFIRM = 0xB, + STORE_BOY = 0xC, + STORE_BBOY = 0xD, + STORE_HEALER = 0xE, + STORE_STORY = 0xF, + STORE_HBUY = 0x10, + STORE_SIDENTIFY = 0x11, + STORE_SPBUY = 0x12, + STORE_GOSSIP = 0x13, + STORE_IDSHOW = 0x14, + STORE_TAVERN = 0x15, + STORE_DRUNK = 0x16, + STORE_BARMAID = 0x17, +}; + +/* 360 */ +/* enum _exception_id +{ + EXCEPTION_GUARD_PAGE = 0x80000001, + EXCEPTION_DATATYPE_MISALIGNMENT = 0x80000002, + EXCEPTION_BREAKPOINT = 0x80000003, + EXCEPTION_SINGLE_STEP = 0x80000004, + EXCEPTION_ACCESS_VIOLATION = 0xC0000005, + EXCEPTION_IN_PAGE_ERROR = 0xC0000006, + EXCEPTION_INVALID_HANDLE = 0xC0000008, + EXCEPTION_ILLEGAL_INSTRUCTION = 0xC000001D, + EXCEPTION_NONCONTINUABLE_EXCEPTION = 0xC0000025, + EXCEPTION_INVALID_DISPOSITION = 0xC0000026, + EXCEPTION_ARRAY_BOUNDS_EXCEEDED = 0xC000008C, + EXCEPTION_FLT_DENORMAL_OPERAND = 0xC000008D, + EXCEPTION_FLT_DIVIDE_BY_ZERO = 0xC000008E, + EXCEPTION_FLT_INEXACT_RESULT = 0xC000008F, + EXCEPTION_FLT_INVALID_OPERATION = 0xC0000090, + EXCEPTION_FLT_OVERFLOW = 0xC0000091, + EXCEPTION_FLT_STACK_CHECK = 0xC0000092, + EXCEPTION_FLT_UNDERFLOW = 0xC0000093, + EXCEPTION_INT_DIVIDE_BY_ZERO = 0xC0000094, + EXCEPTION_INT_OVERFLOW = 0xC0000095, + EXCEPTION_PRIV_INSTRUCTION = 0xC0000096, + EXCEPTION_STACK_OVERFLOW = 0xC00000FD, +}; */ + +/* 363 */ +struct unk_missile_struct +{ + int field_0; + int field_4; + int field_8; +}; + +/* 365 */ +struct TSyncMonster +{ + char _mndx; + char _mx; + char _my; + char _menemy; + char _mdelta; +}; + +/* 366 */ +struct TSyncHeader +{ + unsigned char bCmd; + unsigned char bLevel; + unsigned short wLen; + unsigned char bObjId; + unsigned char bObjCmd; + unsigned char bItemI; + unsigned char bItemX; + unsigned char bItemY; + unsigned short wItemIndx; + unsigned short wItemCI; + int dwItemSeed; + unsigned char bItemId; + unsigned char bItemDur; + unsigned char bItemMDur; + unsigned char bItemCh; + unsigned char bItemMCh; + unsigned short wItemVal; + unsigned int dwItemBuff; + unsigned char bPInvLoc; + unsigned short wPInvIndx; + unsigned short wPInvCI; + int dwPInvSeed; + unsigned char bPInvId; +}; + +/* 367 */ +/* enum sys_commands +{ + SC_SIZE = 0xF000, + SC_SEPARATOR = 0xF00F, + SC_MOVE = 0xF010, + SC_MINIMIZE = 0xF020, + SC_MAXIMIZE = 0xF030, + SC_NEXTWINDOW = 0xF040, + SC_PREVWINDOW = 0xF050, + SC_CLOSE = 0xF060, + SC_VSCROLL = 0xF070, + SC_HSCROLL = 0xF080, + SC_MOUSEMENU = 0xF090, + SC_KEYMENU = 0xF100, + SC_ARRANGE = 0xF110, + SC_RESTORE = 0xF120, + SC_TASKLIST = 0xF130, + SC_SCREENSAVE = 0xF140, + SC_HOTKEY = 0xF150, + SC_DEFAULT = 0xF160, + SC_MONITORPOWER = 0xF170, + SC_CONTEXTHELP = 0xF180, +}; */ + +/* 370 */ +typedef IDirectDrawSurface *LPDIRECTDRAWSURFACE; + +/* 371 */ +typedef tagRECT *LPRECT; + +/* 373 */ +typedef _DDBLTFX DDBLTFX; + +/* 372 */ +typedef DDBLTFX *LPDDBLTFX; + +/* 381 */ +typedef _DDBLTBATCH DDBLTBATCH; + +/* 380 */ +typedef DDBLTBATCH *LPDDBLTBATCH; + +/* 384 */ +typedef _DDSURFACEDESC *LPDDSURFACEDESC; + +/* 383 */ +typedef HRESULT (__stdcall *LPDDENUMSURFACESCALLBACK)(LPDIRECTDRAWSURFACE, LPDDSURFACEDESC, LPVOID); + +/* 385 */ +typedef DDSCAPS *LPDDSCAPS; + +/* 386 */ +typedef IDirectDrawClipper *LPDIRECTDRAWCLIPPER; + +/* 406 */ +typedef DDCOLORKEY *LPDDCOLORKEY; + +/* 407 */ +typedef HDC__ *HDC; + +/* 409 */ +/* typedef int *LPLONG; + */ +/* 398 */ +typedef IDirectDrawPalette *LPDIRECTDRAWPALETTE; + +/* 410 */ +typedef DDPIXELFORMAT *LPDDPIXELFORMAT; + +/* 394 */ +typedef IDirectDraw *LPDIRECTDRAW; + +/* 412 */ +typedef _DDOVERLAYFX DDOVERLAYFX; + +/* 411 */ +typedef DDOVERLAYFX *LPDDOVERLAYFX; + +/* 368 */ +struct IDirectDrawSurfaceVtbl +{ + HRESULT (__stdcall *QueryInterface)(IDirectDrawSurface *This, const IID *const riid, LPVOID *ppvObj); + ULONG (__stdcall *AddRef)(IDirectDrawSurface *This); + ULONG (__stdcall *Release)(IDirectDrawSurface *This); + HRESULT (__stdcall *AddAttachedSurface)(IDirectDrawSurface *This, LPDIRECTDRAWSURFACE); + HRESULT (__stdcall *AddOverlayDirtyRect)(IDirectDrawSurface *This, LPRECT); + HRESULT (__stdcall *Blt)(IDirectDrawSurface *This, LPRECT, LPDIRECTDRAWSURFACE, LPRECT, DWORD, LPDDBLTFX); + HRESULT (__stdcall *BltBatch)(IDirectDrawSurface *This, LPDDBLTBATCH, DWORD, DWORD); + HRESULT (__stdcall *BltFast)(IDirectDrawSurface *This, DWORD, DWORD, LPDIRECTDRAWSURFACE, LPRECT, DWORD); + HRESULT (__stdcall *DeleteAttachedSurface)(IDirectDrawSurface *This, DWORD, LPDIRECTDRAWSURFACE); + HRESULT (__stdcall *EnumAttachedSurfaces)(IDirectDrawSurface *This, LPVOID, LPDDENUMSURFACESCALLBACK); + HRESULT (__stdcall *EnumOverlayZOrders)(IDirectDrawSurface *This, DWORD, LPVOID, LPDDENUMSURFACESCALLBACK); + HRESULT (__stdcall *Flip)(IDirectDrawSurface *This, LPDIRECTDRAWSURFACE, DWORD); + HRESULT (__stdcall *GetAttachedSurface)(IDirectDrawSurface *This, LPDDSCAPS, LPDIRECTDRAWSURFACE *); + HRESULT (__stdcall *GetBltStatus)(IDirectDrawSurface *This, DWORD); + HRESULT (__stdcall *GetCaps)(IDirectDrawSurface *This, LPDDSCAPS); + HRESULT (__stdcall *GetClipper)(IDirectDrawSurface *This, LPDIRECTDRAWCLIPPER *); + HRESULT (__stdcall *GetColorKey)(IDirectDrawSurface *This, DWORD, LPDDCOLORKEY); + HRESULT (__stdcall *GetDC)(IDirectDrawSurface *This, HDC *); + HRESULT (__stdcall *GetFlipStatus)(IDirectDrawSurface *This, DWORD); + HRESULT (__stdcall *GetOverlayPosition)(IDirectDrawSurface *This, LPLONG, LPLONG); + HRESULT (__stdcall *GetPalette)(IDirectDrawSurface *This, LPDIRECTDRAWPALETTE *); + HRESULT (__stdcall *GetPixelFormat)(IDirectDrawSurface *This, LPDDPIXELFORMAT); + HRESULT (__stdcall *GetSurfaceDesc)(IDirectDrawSurface *This, LPDDSURFACEDESC); + HRESULT (__stdcall *Initialize)(IDirectDrawSurface *This, LPDIRECTDRAW, LPDDSURFACEDESC); + HRESULT (__stdcall *IsLost)(IDirectDrawSurface *This); + HRESULT (__stdcall *Lock)(IDirectDrawSurface *This, LPRECT, LPDDSURFACEDESC, DWORD, HANDLE); + HRESULT (__stdcall *ReleaseDC)(IDirectDrawSurface *This, HDC); + HRESULT (__stdcall *Restore)(IDirectDrawSurface *This); + HRESULT (__stdcall *SetClipper)(IDirectDrawSurface *This, LPDIRECTDRAWCLIPPER); + HRESULT (__stdcall *SetColorKey)(IDirectDrawSurface *This, DWORD, LPDDCOLORKEY); + HRESULT (__stdcall *SetOverlayPosition)(IDirectDrawSurface *This, LONG, LONG); + HRESULT (__stdcall *SetPalette)(IDirectDrawSurface *This, LPDIRECTDRAWPALETTE); + HRESULT (__stdcall *Unlock)(IDirectDrawSurface *This, LPVOID); + HRESULT (__stdcall *UpdateOverlay)(IDirectDrawSurface *This, LPRECT, LPDIRECTDRAWSURFACE, LPRECT, DWORD, LPDDOVERLAYFX); + HRESULT (__stdcall *UpdateOverlayDisplay)(IDirectDrawSurface *This, DWORD); + HRESULT (__stdcall *UpdateOverlayZOrder)(IDirectDrawSurface *This, DWORD, LPDIRECTDRAWSURFACE); +}; + +/* 369 */ +/* struct IDirectDrawSurface +{ + IDirectDrawSurfaceVtbl *lpVtbl; +}; */ + +/* 375 */ + +/* 374 */ + + +/* 387 */ +/* struct IDirectDrawClipper +{ + IDirectDrawClipperVtbl *lpVtbl; +}; */ + +/* 408 */ +/* struct HDC__ +{ + int unused; +}; */ + +/* 399 */ +/* struct IDirectDrawPalette +{ + IDirectDrawPaletteVtbl *lpVtbl; +}; */ + +/* 395 */ +/* struct IDirectDraw +{ + IDirectDrawVtbl *lpVtbl; +}; */ + +/* 414 */ + + +/* 413 */ +/* struct _DDOVERLAYFX +{ + DWORD dwSize; + DWORD dwAlphaEdgeBlendBitDepth; + DWORD dwAlphaEdgeBlend; + DWORD dwReserved; + DWORD dwAlphaDestConstBitDepth; + union + { + DWORD dwAlphaDestConst; + LPDIRECTDRAWSURFACE lpDDSAlphaDest; + }; + DWORD dwAlphaSrcConstBitDepth; + union + { + DWORD dwAlphaSrcConst; + LPDIRECTDRAWSURFACE lpDDSAlphaSrc; + }; + DDCOLORKEY dckDestColorkey; + DDCOLORKEY dckSrcColorkey; + DWORD dwDDFX; + DWORD dwFlags; +}; */ + +/* 389 */ +typedef _RGNDATA *LPRGNDATA; + +/* 393 */ +typedef DWORD *LPDWORD; + +/* 388 */ +struct IDirectDrawClipperVtbl +{ + HRESULT (__stdcall *QueryInterface)(IDirectDrawClipper *This, const IID *const riid, LPVOID *ppvObj); + ULONG (__stdcall *AddRef)(IDirectDrawClipper *This); + ULONG (__stdcall *Release)(IDirectDrawClipper *This); + HRESULT (__stdcall *GetClipList)(IDirectDrawClipper *This, LPRECT, LPRGNDATA, LPDWORD); + HRESULT (__stdcall *GetHWnd)(IDirectDrawClipper *This, HWND *); + HRESULT (__stdcall *Initialize)(IDirectDrawClipper *This, LPDIRECTDRAW, DWORD); + HRESULT (__stdcall *IsClipListChanged)(IDirectDrawClipper *This, BOOL *); + HRESULT (__stdcall *SetClipList)(IDirectDrawClipper *This, LPRGNDATA, DWORD); + HRESULT (__stdcall *SetHWnd)(IDirectDrawClipper *This, DWORD, HWND); +}; + +/* 397 */ +typedef tagPALETTEENTRY *LPPALETTEENTRY; + +/* 400 */ +struct IDirectDrawPaletteVtbl +{ + HRESULT (__stdcall *QueryInterface)(IDirectDrawPalette *This, const IID *const riid, LPVOID *ppvObj); + ULONG (__stdcall *AddRef)(IDirectDrawPalette *This); + ULONG (__stdcall *Release)(IDirectDrawPalette *This); + HRESULT (__stdcall *GetCaps)(IDirectDrawPalette *This, LPDWORD); + HRESULT (__stdcall *GetEntries)(IDirectDrawPalette *This, DWORD, DWORD, DWORD, LPPALETTEENTRY); + HRESULT (__stdcall *Initialize)(IDirectDrawPalette *This, LPDIRECTDRAW, DWORD, LPPALETTEENTRY); + HRESULT (__stdcall *SetEntries)(IDirectDrawPalette *This, DWORD, DWORD, DWORD, LPPALETTEENTRY); +}; + +/* 401 */ +typedef HRESULT (__stdcall *LPDDENUMMODESCALLBACK)(LPDDSURFACEDESC, LPVOID); + +/* 403 */ +typedef _DDCAPS DDCAPS; + +/* 402 */ +typedef DDCAPS *LPDDCAPS; + +/* 405 */ +typedef BOOL *LPBOOL; + +/* 396 */ +struct IDirectDrawVtbl +{ + HRESULT (__stdcall *QueryInterface)(IDirectDraw *This, const IID *const riid, LPVOID *ppvObj); + ULONG (__stdcall *AddRef)(IDirectDraw *This); + ULONG (__stdcall *Release)(IDirectDraw *This); + HRESULT (__stdcall *Compact)(IDirectDraw *This); + HRESULT (__stdcall *CreateClipper)(IDirectDraw *This, DWORD, LPDIRECTDRAWCLIPPER *, IUnknown *); + HRESULT (__stdcall *CreatePalette)(IDirectDraw *This, DWORD, LPPALETTEENTRY, LPDIRECTDRAWPALETTE *, IUnknown *); + HRESULT (__stdcall *CreateSurface)(IDirectDraw *This, LPDDSURFACEDESC, LPDIRECTDRAWSURFACE *, IUnknown *); + HRESULT (__stdcall *DuplicateSurface)(IDirectDraw *This, LPDIRECTDRAWSURFACE, LPDIRECTDRAWSURFACE *); + HRESULT (__stdcall *EnumDisplayModes)(IDirectDraw *This, DWORD, LPDDSURFACEDESC, LPVOID, LPDDENUMMODESCALLBACK); + HRESULT (__stdcall *EnumSurfaces)(IDirectDraw *This, DWORD, LPDDSURFACEDESC, LPVOID, LPDDENUMSURFACESCALLBACK); + HRESULT (__stdcall *FlipToGDISurface)(IDirectDraw *This); + HRESULT (__stdcall *GetCaps)(IDirectDraw *This, LPDDCAPS, LPDDCAPS); + HRESULT (__stdcall *GetDisplayMode)(IDirectDraw *This, LPDDSURFACEDESC); + HRESULT (__stdcall *GetFourCCCodes)(IDirectDraw *This, LPDWORD, LPDWORD); + HRESULT (__stdcall *GetGDISurface)(IDirectDraw *This, LPDIRECTDRAWSURFACE *); + HRESULT (__stdcall *GetMonitorFrequency)(IDirectDraw *This, LPDWORD); + HRESULT (__stdcall *GetScanLine)(IDirectDraw *This, LPDWORD); + HRESULT (__stdcall *GetVerticalBlankStatus)(IDirectDraw *This, LPBOOL); + HRESULT (__stdcall *Initialize)(IDirectDraw *This, GUID *); + HRESULT (__stdcall *RestoreDisplayMode)(IDirectDraw *This); + HRESULT (__stdcall *SetCooperativeLevel)(IDirectDraw *This, HWND, DWORD); + HRESULT (__stdcall *SetDisplayMode)(IDirectDraw *This, DWORD, DWORD, DWORD); + HRESULT (__stdcall *WaitForVerticalBlank)(IDirectDraw *This, DWORD, HANDLE); +}; + +/* 392 */ +/* struct _RGNDATAHEADER +{ + DWORD dwSize; + DWORD iType; + DWORD nCount; + DWORD nRgnSize; + RECT rcBound; +}; */ + +/* 391 */ +typedef _RGNDATAHEADER RGNDATAHEADER; + +/* 390 */ +/* struct _RGNDATA +{ + RGNDATAHEADER rdh; + char Buffer[1]; +}; */ + +/* 404 */ + +/* 416 */ +enum _unique_items +{ + UITEM_CLEAVER = 0x0, + UITEM_SKCROWN = 0x1, + UITEM_INFRARING = 0x2, + UITEM_OPTAMULET = 0x3, + UITEM_TRING = 0x4, + UITEM_HARCREST = 0x5, + UITEM_STEELVEIL = 0x6, + UITEM_ARMOFVAL = 0x7, + UITEM_GRISWOLD = 0x8, + UITEM_LGTFORGE = 0x9, + UITEM_RIFTBOW = 0xA, + UITEM_NEEDLER = 0xB, + UITEM_CELESTBOW = 0xC, + UITEM_DEADLYHUNT = 0xD, + UITEM_BOWOFDEAD = 0xE, + UITEM_BLKOAKBOW = 0xF, + UITEM_FLAMEDART = 0x10, + UITEM_FLESHSTING = 0x11, + UITEM_WINDFORCE = 0x12, + UITEM_EAGLEHORN = 0x13, + UITEM_GONNAGALDIRK = 0x14, + UITEM_DEFENDER = 0x15, + UITEM_GRYPHONCLAW = 0x16, + UITEM_BLACKRAZOR = 0x17, + UITEM_GIBBOUSMOON = 0x18, + UITEM_ICESHANK = 0x19, + UITEM_EXECUTIONER = 0x1A, + UITEM_BONESAW = 0x1B, + UITEM_SHADHAWK = 0x1C, + UITEM_WIZSPIKE = 0x1D, + UITEM_LGTSABRE = 0x1E, + UITEM_FALCONTALON = 0x1F, + UITEM_INFERNO = 0x20, + UITEM_DOOMBRINGER = 0x21, + UITEM_GRIZZLY = 0x22, + UITEM_GRANDFATHER = 0x23, + UITEM_MANGLER = 0x24, + UITEM_SHARPBEAK = 0x25, + UITEM_BLOODLSLAYER = 0x26, + UITEM_CELESTAXE = 0x27, + UITEM_WICKEDAXE = 0x28, + UITEM_STONECLEAV = 0x29, + UITEM_AGUHATCHET = 0x2A, + UITEM_HELLSLAYER = 0x2B, + UITEM_MESSERREAVER = 0x2C, + UITEM_CRACKRUST = 0x2D, + UITEM_JHOLMHAMM = 0x2E, + UITEM_CIVERBS = 0x2F, + UITEM_CELESTSTAR = 0x30, + UITEM_BARANSTAR = 0x31, + UITEM_GNARLROOT = 0x32, + UITEM_CRANBASH = 0x33, + UITEM_SCHAEFHAMM = 0x34, + UITEM_DREAMFLANGE = 0x35, + UITEM_STAFFOFSHAD = 0x36, + UITEM_IMMOLATOR = 0x37, + UITEM_STORMSPIRE = 0x38, + UITEM_GLEAMSONG = 0x39, + UITEM_THUNDERCALL = 0x3A, + UITEM_PROTECTOR = 0x3B, + UITEM_NAJPUZZLE = 0x3C, + UITEM_MINDCRY = 0x3D, + UITEM_RODOFONAN = 0x3E, + UITEM_SPIRITSHELM = 0x3F, + UITEM_THINKINGCAP = 0x40, + UITEM_OVERLORDHELM = 0x41, + UITEM_FOOLSCREST = 0x42, + UITEM_GOTTERDAM = 0x43, + UITEM_ROYCIRCLET = 0x44, + UITEM_TORNFLESH = 0x45, + UITEM_GLADBANE = 0x46, + UITEM_RAINCLOAK = 0x47, + UITEM_LEATHAUT = 0x48, + UITEM_WISDWRAP = 0x49, + UITEM_SPARKMAIL = 0x4A, + UITEM_SCAVCARAP = 0x4B, + UITEM_NIGHTSCAPE = 0x4C, + UITEM_NAJPLATE = 0x4D, + UITEM_DEMONSPIKE = 0x4E, + UITEM_DEFLECTOR = 0x4F, + UITEM_SKULLSHLD = 0x50, + UITEM_DRAGONBRCH = 0x51, + UITEM_BLKOAKSHLD = 0x52, + UITEM_HOLYDEF = 0x53, + UITEM_STORMSHLD = 0x54, + UITEM_BRAMBLE = 0x55, + UITEM_REGHA = 0x56, + UITEM_BLEEDER = 0x57, + UITEM_CONSTRICT = 0x58, + UITEM_ENGAGE = 0x59, + UITEM_INVALID = 0x5A, +}; + +/* 417 */ +enum _ui_classes +{ + UI_WARRIOR = 0x0, + UI_ROGUE = 0x1, + UI_SORCERER = 0x2, + UI_NUM_CLASSES = 0x3, +}; + +/* 418 */ +/* enum _win_error +{ + ERROR_FILE_NOT_FOUND = 0x2, + ERROR_ALREADY_EXISTS = 0xB7, +}; */ + +/* 419 */ +enum _walk_path +{ + WALK_NONE = 0x0, + WALK_NE = 0x1, + WALK_NW = 0x2, + WALK_SE = 0x3, + WALK_SW = 0x4, + WALK_N = 0x5, + WALK_E = 0x6, + WALK_S = 0x7, + WALK_W = 0x8, +}; + diff --git a/2018_03_14/DiabDev/pklib/crc32.c b/2018_03_14/DiabDev/pklib/crc32.c new file mode 100644 index 00000000..cd47b1d4 --- /dev/null +++ b/2018_03_14/DiabDev/pklib/crc32.c @@ -0,0 +1,66 @@ +/*****************************************************************************/ +/* crc32.c Copyright (c) Ladislav Zezula 2003 */ +/*---------------------------------------------------------------------------*/ +/* Pkware Data Compression Library Version 1.11 */ +/* Dissassembled method crc32 - cdecl version */ +/*---------------------------------------------------------------------------*/ +/* Date Ver Who Comment */ +/* -------- ---- --- ------- */ +/* 09.04.03 1.00 Lad The first version of crc32.c */ +/* 02.05.03 1.00 Lad Stress test done */ +/*****************************************************************************/ + +#include "pklib.h" + +static unsigned long crc_table[] = +{ + 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, + 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, + 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, + 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, + 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, + 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, + 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, + 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, + 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, + 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, + 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, + 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, + 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, + 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, + 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, + 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, + 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, + 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, + 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, + 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, + 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, + 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, + 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, + 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, + 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, + 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, + 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, + 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, + 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, + 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, + 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, + 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D +}; + + +unsigned long PKEXPORT crc32_pklib(char * buffer, unsigned int * psize, unsigned long * old_crc) +{ + unsigned int size = *psize; + unsigned long ch; + unsigned long crc_value = *old_crc; + + while(size-- != 0) + { + ch = *buffer++ ^ (char)crc_value; + crc_value >>= 8; + + crc_value = crc_table[ch & 0x0FF] ^ crc_value; + } + return crc_value; +} diff --git a/2018_03_14/DiabDev/pklib/explode.c b/2018_03_14/DiabDev/pklib/explode.c new file mode 100644 index 00000000..97961739 --- /dev/null +++ b/2018_03_14/DiabDev/pklib/explode.c @@ -0,0 +1,522 @@ +/*****************************************************************************/ +/* explode.c Copyright (c) Ladislav Zezula 2003 */ +/*---------------------------------------------------------------------------*/ +/* Implode function of PKWARE Data Compression library */ +/*---------------------------------------------------------------------------*/ +/* Date Ver Who Comment */ +/* -------- ---- --- ------- */ +/* 11.03.03 1.00 Lad Splitted from Pkware.cpp */ +/* 08.04.03 1.01 Lad Renamed to explode.c to be compatible with pklib */ +/* 02.05.03 1.01 Lad Stress test done */ +/* 22.04.10 1.01 Lad Documented */ +/*****************************************************************************/ + +#include +#include + +#include "pklib.h" + +#define PKDCL_OK 0 +#define PKDCL_STREAM_END 1 // All data from the input stream is read +#define PKDCL_NEED_DICT 2 // Need more data (dictionary) +#define PKDCL_CONTINUE 10 // Internal flag, not returned to user +#define PKDCL_GET_INPUT 11 // Internal flag, not returned to user + +char CopyrightPkware[] = "PKWARE Data Compression Library for Win32\r\n" + "Copyright 1989-1995 PKWARE Inc. All Rights Reserved\r\n" + "Patent No. 5,051,745\r\n" + "PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off.\r\n" + "Version 1.11\r\n"; + +//----------------------------------------------------------------------------- +// Tables + +static unsigned char DistBits[] = +{ + 0x02, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08 +}; + +static unsigned char DistCode[] = +{ + 0x03, 0x0D, 0x05, 0x19, 0x09, 0x11, 0x01, 0x3E, 0x1E, 0x2E, 0x0E, 0x36, 0x16, 0x26, 0x06, 0x3A, + 0x1A, 0x2A, 0x0A, 0x32, 0x12, 0x22, 0x42, 0x02, 0x7C, 0x3C, 0x5C, 0x1C, 0x6C, 0x2C, 0x4C, 0x0C, + 0x74, 0x34, 0x54, 0x14, 0x64, 0x24, 0x44, 0x04, 0x78, 0x38, 0x58, 0x18, 0x68, 0x28, 0x48, 0x08, + 0xF0, 0x70, 0xB0, 0x30, 0xD0, 0x50, 0x90, 0x10, 0xE0, 0x60, 0xA0, 0x20, 0xC0, 0x40, 0x80, 0x00 +}; + +static unsigned char ExLenBits[] = +{ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 +}; + +static unsigned short LenBase[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x000A, 0x000E, 0x0016, 0x0026, 0x0046, 0x0086, 0x0106 +}; + +static unsigned char LenBits[] = +{ + 0x03, 0x02, 0x03, 0x03, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x07, 0x07 +}; + +static unsigned char LenCode[] = +{ + 0x05, 0x03, 0x01, 0x06, 0x0A, 0x02, 0x0C, 0x14, 0x04, 0x18, 0x08, 0x30, 0x10, 0x20, 0x40, 0x00 +}; + +static unsigned char ChBitsAsc[] = +{ + 0x0B, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x08, 0x07, 0x0C, 0x0C, 0x07, 0x0C, 0x0C, + 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0D, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, + 0x04, 0x0A, 0x08, 0x0C, 0x0A, 0x0C, 0x0A, 0x08, 0x07, 0x07, 0x08, 0x09, 0x07, 0x06, 0x07, 0x08, + 0x07, 0x06, 0x07, 0x07, 0x07, 0x07, 0x08, 0x07, 0x07, 0x08, 0x08, 0x0C, 0x0B, 0x07, 0x09, 0x0B, + 0x0C, 0x06, 0x07, 0x06, 0x06, 0x05, 0x07, 0x08, 0x08, 0x06, 0x0B, 0x09, 0x06, 0x07, 0x06, 0x06, + 0x07, 0x0B, 0x06, 0x06, 0x06, 0x07, 0x09, 0x08, 0x09, 0x09, 0x0B, 0x08, 0x0B, 0x09, 0x0C, 0x08, + 0x0C, 0x05, 0x06, 0x06, 0x06, 0x05, 0x06, 0x06, 0x06, 0x05, 0x0B, 0x07, 0x05, 0x06, 0x05, 0x05, + 0x06, 0x0A, 0x05, 0x05, 0x05, 0x05, 0x08, 0x07, 0x08, 0x08, 0x0A, 0x0B, 0x0B, 0x0C, 0x0C, 0x0C, + 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, + 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, + 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, + 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, + 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, + 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, + 0x0D, 0x0C, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D, + 0x0D, 0x0D, 0x0C, 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D +}; + +static unsigned short ChCodeAsc[] = +{ + 0x0490, 0x0FE0, 0x07E0, 0x0BE0, 0x03E0, 0x0DE0, 0x05E0, 0x09E0, + 0x01E0, 0x00B8, 0x0062, 0x0EE0, 0x06E0, 0x0022, 0x0AE0, 0x02E0, + 0x0CE0, 0x04E0, 0x08E0, 0x00E0, 0x0F60, 0x0760, 0x0B60, 0x0360, + 0x0D60, 0x0560, 0x1240, 0x0960, 0x0160, 0x0E60, 0x0660, 0x0A60, + 0x000F, 0x0250, 0x0038, 0x0260, 0x0050, 0x0C60, 0x0390, 0x00D8, + 0x0042, 0x0002, 0x0058, 0x01B0, 0x007C, 0x0029, 0x003C, 0x0098, + 0x005C, 0x0009, 0x001C, 0x006C, 0x002C, 0x004C, 0x0018, 0x000C, + 0x0074, 0x00E8, 0x0068, 0x0460, 0x0090, 0x0034, 0x00B0, 0x0710, + 0x0860, 0x0031, 0x0054, 0x0011, 0x0021, 0x0017, 0x0014, 0x00A8, + 0x0028, 0x0001, 0x0310, 0x0130, 0x003E, 0x0064, 0x001E, 0x002E, + 0x0024, 0x0510, 0x000E, 0x0036, 0x0016, 0x0044, 0x0030, 0x00C8, + 0x01D0, 0x00D0, 0x0110, 0x0048, 0x0610, 0x0150, 0x0060, 0x0088, + 0x0FA0, 0x0007, 0x0026, 0x0006, 0x003A, 0x001B, 0x001A, 0x002A, + 0x000A, 0x000B, 0x0210, 0x0004, 0x0013, 0x0032, 0x0003, 0x001D, + 0x0012, 0x0190, 0x000D, 0x0015, 0x0005, 0x0019, 0x0008, 0x0078, + 0x00F0, 0x0070, 0x0290, 0x0410, 0x0010, 0x07A0, 0x0BA0, 0x03A0, + 0x0240, 0x1C40, 0x0C40, 0x1440, 0x0440, 0x1840, 0x0840, 0x1040, + 0x0040, 0x1F80, 0x0F80, 0x1780, 0x0780, 0x1B80, 0x0B80, 0x1380, + 0x0380, 0x1D80, 0x0D80, 0x1580, 0x0580, 0x1980, 0x0980, 0x1180, + 0x0180, 0x1E80, 0x0E80, 0x1680, 0x0680, 0x1A80, 0x0A80, 0x1280, + 0x0280, 0x1C80, 0x0C80, 0x1480, 0x0480, 0x1880, 0x0880, 0x1080, + 0x0080, 0x1F00, 0x0F00, 0x1700, 0x0700, 0x1B00, 0x0B00, 0x1300, + 0x0DA0, 0x05A0, 0x09A0, 0x01A0, 0x0EA0, 0x06A0, 0x0AA0, 0x02A0, + 0x0CA0, 0x04A0, 0x08A0, 0x00A0, 0x0F20, 0x0720, 0x0B20, 0x0320, + 0x0D20, 0x0520, 0x0920, 0x0120, 0x0E20, 0x0620, 0x0A20, 0x0220, + 0x0C20, 0x0420, 0x0820, 0x0020, 0x0FC0, 0x07C0, 0x0BC0, 0x03C0, + 0x0DC0, 0x05C0, 0x09C0, 0x01C0, 0x0EC0, 0x06C0, 0x0AC0, 0x02C0, + 0x0CC0, 0x04C0, 0x08C0, 0x00C0, 0x0F40, 0x0740, 0x0B40, 0x0340, + 0x0300, 0x0D40, 0x1D00, 0x0D00, 0x1500, 0x0540, 0x0500, 0x1900, + 0x0900, 0x0940, 0x1100, 0x0100, 0x1E00, 0x0E00, 0x0140, 0x1600, + 0x0600, 0x1A00, 0x0E40, 0x0640, 0x0A40, 0x0A00, 0x1200, 0x0200, + 0x1C00, 0x0C00, 0x1400, 0x0400, 0x1800, 0x0800, 0x1000, 0x0000 +}; + +//----------------------------------------------------------------------------- +// Local functions + +static void GenDecodeTabs( + unsigned char * positions, // [out] Table of positions + unsigned char * start_indexes, // [in] Table of start indexes + unsigned char * length_bits, // [in] Table of lengths. Each length is stored as number of bits + size_t elements) // [in] Number of elements in start_indexes and length_bits +{ + unsigned int index; + unsigned int length; + size_t i; + + for(i = 0; i < elements; i++) + { + length = 1 << length_bits[i]; // Get the length in bytes + + for(index = start_indexes[i]; index < 0x100; index += length) + { + positions[index] = (unsigned char)i; + } + } +} + +static void GenAscTabs(TDcmpStruct * pWork) +{ + unsigned short * pChCodeAsc = &ChCodeAsc[0xFF]; + unsigned int acc, add; + unsigned short count; + + for(count = 0x00FF; pChCodeAsc >= ChCodeAsc; pChCodeAsc--, count--) + { + unsigned char * pChBitsAsc = pWork->ChBitsAsc + count; + unsigned char bits_asc = *pChBitsAsc; + + if(bits_asc <= 8) + { + add = (1 << bits_asc); + acc = *pChCodeAsc; + + do + { + pWork->offs2C34[acc] = (unsigned char)count; + acc += add; + } + while(acc < 0x100); + } + else if((acc = (*pChCodeAsc & 0xFF)) != 0) + { + pWork->offs2C34[acc] = 0xFF; + + if(*pChCodeAsc & 0x3F) + { + bits_asc -= 4; + *pChBitsAsc = bits_asc; + + add = (1 << bits_asc); + acc = *pChCodeAsc >> 4; + do + { + pWork->offs2D34[acc] = (unsigned char)count; + acc += add; + } + while(acc < 0x100); + } + else + { + bits_asc -= 6; + *pChBitsAsc = bits_asc; + + add = (1 << bits_asc); + acc = *pChCodeAsc >> 6; + do + { + pWork->offs2E34[acc] = (unsigned char)count; + acc += add; + } + while(acc < 0x80); + } + } + else + { + bits_asc -= 8; + *pChBitsAsc = bits_asc; + + add = (1 << bits_asc); + acc = *pChCodeAsc >> 8; + do + { + pWork->offs2EB4[acc] = (unsigned char)count; + acc += add; + } + while(acc < 0x100); + } + } +} + +//----------------------------------------------------------------------------- +// Removes given number of bits in the bit buffer. New bits are reloaded from +// the input buffer, if needed. +// Returns: PKDCL_OK: Operation was successful +// PKDCL_STREAM_END: There are no more bits in the input buffer + +static int WasteBits(TDcmpStruct * pWork, unsigned int nBits) +{ + // If number of bits required is less than number of (bits in the buffer) ? + if(nBits <= pWork->extra_bits) + { + pWork->extra_bits -= nBits; + pWork->bit_buff >>= nBits; + return PKDCL_OK; + } + + // Load input buffer if necessary + pWork->bit_buff >>= pWork->extra_bits; + if(pWork->in_pos == pWork->in_bytes) + { + pWork->in_pos = sizeof(pWork->in_buff); + if((pWork->in_bytes = pWork->read_buf((char *)pWork->in_buff, &pWork->in_pos, pWork->param)) == 0) + return PKDCL_STREAM_END; + pWork->in_pos = 0; + } + + // Update bit buffer + pWork->bit_buff |= (pWork->in_buff[pWork->in_pos++] << 8); + pWork->bit_buff >>= (nBits - pWork->extra_bits); + pWork->extra_bits = (pWork->extra_bits - nBits) + 8; + return PKDCL_OK; +} + +//----------------------------------------------------------------------------- +// Decodes next literal from the input (compressed) data. +// Returns : 0x000: One byte 0x00 +// 0x001: One byte 0x01 +// ... +// 0x0FF: One byte 0xFF +// 0x100: Repetition, length of 0x02 bytes +// 0x101: Repetition, length of 0x03 bytes +// ... +// 0x304: Repetition, length of 0x206 bytes +// 0x305: End of stream +// 0x306: Error + +static unsigned int DecodeLit(TDcmpStruct * pWork) +{ + unsigned int extra_length_bits; // Number of bits of extra literal length + unsigned int length_code; // Length code + unsigned int value; + + // Test the current bit in byte buffer. If is not set, simply return the next 8 bits. + if(pWork->bit_buff & 1) + { + // Remove one bit from the input data + if(WasteBits(pWork, 1)) + return 0x306; + + // The next 8 bits hold the index to the length code table + length_code = pWork->LengthCodes[pWork->bit_buff & 0xFF]; + + // Remove the apropriate number of bits + if(WasteBits(pWork, pWork->LenBits[length_code])) + return 0x306; + + // Are there some extra bits for the obtained length code ? + if((extra_length_bits = pWork->ExLenBits[length_code]) != 0) + { + unsigned int extra_length = pWork->bit_buff & ((1 << extra_length_bits) - 1); + + if(WasteBits(pWork, extra_length_bits)) + { + if((length_code + extra_length) != 0x10E) + return 0x306; + } + length_code = pWork->LenBase[length_code] + extra_length; + } + + // In order to distinguish uncompressed byte from repetition length, + // we have to add 0x100 to the length. + return length_code + 0x100; + } + + // Remove one bit from the input data + if(WasteBits(pWork, 1)) + return 0x306; + + // If the binary compression type, read 8 bits and return them as one byte. + if(pWork->ctype == CMP_BINARY) + { + unsigned int uncompressed_byte = pWork->bit_buff & 0xFF; + + if(WasteBits(pWork, 8)) + return 0x306; + return uncompressed_byte; + } + + // When ASCII compression ... + if(pWork->bit_buff & 0xFF) + { + value = pWork->offs2C34[pWork->bit_buff & 0xFF]; + + if(value == 0xFF) + { + if(pWork->bit_buff & 0x3F) + { + if(WasteBits(pWork, 4)) + return 0x306; + + value = pWork->offs2D34[pWork->bit_buff & 0xFF]; + } + else + { + if(WasteBits(pWork, 6)) + return 0x306; + + value = pWork->offs2E34[pWork->bit_buff & 0x7F]; + } + } + } + else + { + if(WasteBits(pWork, 8)) + return 0x306; + + value = pWork->offs2EB4[pWork->bit_buff & 0xFF]; + } + + return WasteBits(pWork, pWork->ChBitsAsc[value]) ? 0x306 : value; +} + +//----------------------------------------------------------------------------- +// Decodes the distance of the repetition, backwards relative to the +// current output buffer position + +static unsigned int DecodeDist(TDcmpStruct * pWork, unsigned int rep_length) +{ + unsigned int dist_pos_code; // Distance position code + unsigned int dist_pos_bits; // Number of bits of distance position + unsigned int distance; // Distance position + + // Next 2-8 bits in the input buffer is the distance position code + dist_pos_code = pWork->DistPosCodes[pWork->bit_buff & 0xFF]; + dist_pos_bits = pWork->DistBits[dist_pos_code]; + if(WasteBits(pWork, dist_pos_bits)) + return 0; + + if(rep_length == 2) + { + // If the repetition is only 2 bytes length, + // then take 2 bits from the stream in order to get the distance + distance = (dist_pos_code << 2) | (pWork->bit_buff & 0x03); + if(WasteBits(pWork, 2)) + return 0; + } + else + { + // If the repetition is more than 2 bytes length, + // then take "dsize_bits" bits in order to get the distance + distance = (dist_pos_code << pWork->dsize_bits) | (pWork->bit_buff & pWork->dsize_mask); + if(WasteBits(pWork, pWork->dsize_bits)) + return 0; + } + return distance + 1; +} + +static unsigned int Expand(TDcmpStruct * pWork) +{ + unsigned int next_literal; // Literal decoded from the compressed data + unsigned int result; // Value to be returned + unsigned int copyBytes; // Number of bytes to copy to the output buffer + + pWork->outputPos = 0x1000; // Initialize output buffer position + + // Decode the next literal from the input data. + // The returned literal can either be an uncompressed byte (next_literal < 0x100) + // or an encoded length of the repeating byte sequence that + // is to be copied to the current buffer position + while((result = next_literal = DecodeLit(pWork)) < 0x305) + { + // If the literal is greater than 0x100, it holds length + // of repeating byte sequence + // literal of 0x100 means repeating sequence of 0x2 bytes + // literal of 0x101 means repeating sequence of 0x3 bytes + // ... + // literal of 0x305 means repeating sequence of 0x207 bytes + if(next_literal >= 0x100) + { + unsigned char * source; + unsigned char * target; + unsigned int rep_length; // Length of the repetition, in bytes + unsigned int minus_dist; // Backward distance to the repetition, relative to the current buffer position + + // Get the length of the repeating sequence. + // Note that the repeating block may overlap the current output position, + // for example if there was a sequence of equal bytes + rep_length = next_literal - 0xFE; + + // Get backward distance to the repetition + if((minus_dist = DecodeDist(pWork, rep_length)) == 0) + { + result = 0x306; + break; + } + + // Target and source pointer + target = &pWork->out_buff[pWork->outputPos]; + source = target - minus_dist; + + // Update buffer output position + pWork->outputPos += rep_length; + + // Copy the repeating sequence + while(rep_length-- > 0) + *target++ = *source++; + } + else + { + pWork->out_buff[pWork->outputPos++] = (unsigned char)next_literal; + } + + // Flush the output buffer, if number of extracted bytes has reached the end + if(pWork->outputPos >= 0x2000) + { + // Copy decompressed data into user buffer + copyBytes = 0x1000; + pWork->write_buf((char *)&pWork->out_buff[0x1000], ©Bytes, pWork->param); + + // Now copy the decompressed data to the first half of the buffer. + // This is needed because the decompression might reuse them as repetitions. + // Note that if the output buffer overflowed previously, the extra decompressed bytes + // are stored in "out_buff_overflow", and they will now be + // within decompressed part of the output buffer. + memmove(pWork->out_buff, &pWork->out_buff[0x1000], pWork->outputPos - 0x1000); + pWork->outputPos -= 0x1000; + } + } + + // Flush any remaining decompressed bytes + copyBytes = pWork->outputPos - 0x1000; + pWork->write_buf((char *)&pWork->out_buff[0x1000], ©Bytes, pWork->param); + return result; +} + + +//----------------------------------------------------------------------------- +// Main exploding function. + +unsigned int explode( + unsigned int (*read_buf)(char *buf, unsigned int *size, void *param), + void (*write_buf)(char *buf, unsigned int *size, void *param), + char *work_buf, + void *param) +{ + TDcmpStruct * pWork = (TDcmpStruct *)work_buf; + + // Initialize work struct and load compressed data + // Note: The caller must zero the "work_buff" before passing it to explode + pWork->read_buf = read_buf; + pWork->write_buf = write_buf; + pWork->param = param; + pWork->in_pos = sizeof(pWork->in_buff); + pWork->in_bytes = pWork->read_buf((char *)pWork->in_buff, &pWork->in_pos, pWork->param); + if(pWork->in_bytes <= 4) + return CMP_BAD_DATA; + + pWork->ctype = pWork->in_buff[0]; // Get the compression type (CMP_BINARY or CMP_ASCII) + pWork->dsize_bits = pWork->in_buff[1]; // Get the dictionary size + pWork->bit_buff = pWork->in_buff[2]; // Initialize 16-bit bit buffer + pWork->extra_bits = 0; // Extra (over 8) bits + pWork->in_pos = 3; // Position in input buffer + + // Test for the valid dictionary size + if(4 > pWork->dsize_bits || pWork->dsize_bits > 6) + return CMP_INVALID_DICTSIZE; + + pWork->dsize_mask = 0xFFFF >> (0x10 - pWork->dsize_bits); // Shifted by 'sar' instruction + + if(pWork->ctype != CMP_BINARY) + { + if(pWork->ctype != CMP_ASCII) + return CMP_INVALID_MODE; + + memcpy(pWork->ChBitsAsc, ChBitsAsc, sizeof(pWork->ChBitsAsc)); + GenAscTabs(pWork); + } + + memcpy(pWork->LenBits, LenBits, sizeof(pWork->LenBits)); + GenDecodeTabs(pWork->LengthCodes, LenCode, pWork->LenBits, sizeof(pWork->LenBits)); + memcpy(pWork->ExLenBits, ExLenBits, sizeof(pWork->ExLenBits)); + memcpy(pWork->LenBase, LenBase, sizeof(pWork->LenBase)); + memcpy(pWork->DistBits, DistBits, sizeof(pWork->DistBits)); + GenDecodeTabs(pWork->DistPosCodes, DistCode, pWork->DistBits, sizeof(pWork->DistBits)); + if(Expand(pWork) != 0x306) + return CMP_NO_ERROR; + + return CMP_ABORT; +} diff --git a/2018_03_14/DiabDev/pklib/implode.c b/2018_03_14/DiabDev/pklib/implode.c new file mode 100644 index 00000000..b0c4ea96 --- /dev/null +++ b/2018_03_14/DiabDev/pklib/implode.c @@ -0,0 +1,769 @@ +/*****************************************************************************/ +/* implode.c Copyright (c) Ladislav Zezula 2003 */ +/*---------------------------------------------------------------------------*/ +/* Implode function of PKWARE Data Compression library */ +/*---------------------------------------------------------------------------*/ +/* Date Ver Who Comment */ +/* -------- ---- --- ------- */ +/* 11.04.03 1.00 Lad First version of implode.c */ +/* 02.05.03 1.00 Lad Stress test done */ +/* 22.04.10 1.01 Lad Documented */ +/*****************************************************************************/ + +#include +#include + +#include "pklib.h" + +#if ((1200 < _MSC_VER) && (_MSC_VER < 1400)) +#pragma optimize("", off) // Fucking Microsoft VS.NET 2003 compiler !!! (_MSC_VER=1310) +#endif + +//----------------------------------------------------------------------------- +// Defines + +#define MAX_REP_LENGTH 0x204 // The longest allowed repetition + +//----------------------------------------------------------------------------- +// Tables +/* +static unsigned char DistBits[] = +{ + 0x02, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08 +}; + +static unsigned char DistCode[] = +{ + 0x03, 0x0D, 0x05, 0x19, 0x09, 0x11, 0x01, 0x3E, 0x1E, 0x2E, 0x0E, 0x36, 0x16, 0x26, 0x06, 0x3A, + 0x1A, 0x2A, 0x0A, 0x32, 0x12, 0x22, 0x42, 0x02, 0x7C, 0x3C, 0x5C, 0x1C, 0x6C, 0x2C, 0x4C, 0x0C, + 0x74, 0x34, 0x54, 0x14, 0x64, 0x24, 0x44, 0x04, 0x78, 0x38, 0x58, 0x18, 0x68, 0x28, 0x48, 0x08, + 0xF0, 0x70, 0xB0, 0x30, 0xD0, 0x50, 0x90, 0x10, 0xE0, 0x60, 0xA0, 0x20, 0xC0, 0x40, 0x80, 0x00 +}; + +static unsigned char ExLenBits[] = +{ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 +}; + +static unsigned char LenBits[] = +{ + 0x03, 0x02, 0x03, 0x03, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x07, 0x07 +}; + +static unsigned char LenCode[] = +{ + 0x05, 0x03, 0x01, 0x06, 0x0A, 0x02, 0x0C, 0x14, 0x04, 0x18, 0x08, 0x30, 0x10, 0x20, 0x40, 0x00 +}; + +static unsigned char ChBitsAsc[] = +{ + 0x0B, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x08, 0x07, 0x0C, 0x0C, 0x07, 0x0C, 0x0C, + 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0D, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, + 0x04, 0x0A, 0x08, 0x0C, 0x0A, 0x0C, 0x0A, 0x08, 0x07, 0x07, 0x08, 0x09, 0x07, 0x06, 0x07, 0x08, + 0x07, 0x06, 0x07, 0x07, 0x07, 0x07, 0x08, 0x07, 0x07, 0x08, 0x08, 0x0C, 0x0B, 0x07, 0x09, 0x0B, + 0x0C, 0x06, 0x07, 0x06, 0x06, 0x05, 0x07, 0x08, 0x08, 0x06, 0x0B, 0x09, 0x06, 0x07, 0x06, 0x06, + 0x07, 0x0B, 0x06, 0x06, 0x06, 0x07, 0x09, 0x08, 0x09, 0x09, 0x0B, 0x08, 0x0B, 0x09, 0x0C, 0x08, + 0x0C, 0x05, 0x06, 0x06, 0x06, 0x05, 0x06, 0x06, 0x06, 0x05, 0x0B, 0x07, 0x05, 0x06, 0x05, 0x05, + 0x06, 0x0A, 0x05, 0x05, 0x05, 0x05, 0x08, 0x07, 0x08, 0x08, 0x0A, 0x0B, 0x0B, 0x0C, 0x0C, 0x0C, + 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, + 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, + 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, + 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, + 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, + 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, + 0x0D, 0x0C, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D, + 0x0D, 0x0D, 0x0C, 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D +}; + +static unsigned short ChCodeAsc[] = +{ + 0x0490, 0x0FE0, 0x07E0, 0x0BE0, 0x03E0, 0x0DE0, 0x05E0, 0x09E0, + 0x01E0, 0x00B8, 0x0062, 0x0EE0, 0x06E0, 0x0022, 0x0AE0, 0x02E0, + 0x0CE0, 0x04E0, 0x08E0, 0x00E0, 0x0F60, 0x0760, 0x0B60, 0x0360, + 0x0D60, 0x0560, 0x1240, 0x0960, 0x0160, 0x0E60, 0x0660, 0x0A60, + 0x000F, 0x0250, 0x0038, 0x0260, 0x0050, 0x0C60, 0x0390, 0x00D8, + 0x0042, 0x0002, 0x0058, 0x01B0, 0x007C, 0x0029, 0x003C, 0x0098, + 0x005C, 0x0009, 0x001C, 0x006C, 0x002C, 0x004C, 0x0018, 0x000C, + 0x0074, 0x00E8, 0x0068, 0x0460, 0x0090, 0x0034, 0x00B0, 0x0710, + 0x0860, 0x0031, 0x0054, 0x0011, 0x0021, 0x0017, 0x0014, 0x00A8, + 0x0028, 0x0001, 0x0310, 0x0130, 0x003E, 0x0064, 0x001E, 0x002E, + 0x0024, 0x0510, 0x000E, 0x0036, 0x0016, 0x0044, 0x0030, 0x00C8, + 0x01D0, 0x00D0, 0x0110, 0x0048, 0x0610, 0x0150, 0x0060, 0x0088, + 0x0FA0, 0x0007, 0x0026, 0x0006, 0x003A, 0x001B, 0x001A, 0x002A, + 0x000A, 0x000B, 0x0210, 0x0004, 0x0013, 0x0032, 0x0003, 0x001D, + 0x0012, 0x0190, 0x000D, 0x0015, 0x0005, 0x0019, 0x0008, 0x0078, + 0x00F0, 0x0070, 0x0290, 0x0410, 0x0010, 0x07A0, 0x0BA0, 0x03A0, + 0x0240, 0x1C40, 0x0C40, 0x1440, 0x0440, 0x1840, 0x0840, 0x1040, + 0x0040, 0x1F80, 0x0F80, 0x1780, 0x0780, 0x1B80, 0x0B80, 0x1380, + 0x0380, 0x1D80, 0x0D80, 0x1580, 0x0580, 0x1980, 0x0980, 0x1180, + 0x0180, 0x1E80, 0x0E80, 0x1680, 0x0680, 0x1A80, 0x0A80, 0x1280, + 0x0280, 0x1C80, 0x0C80, 0x1480, 0x0480, 0x1880, 0x0880, 0x1080, + 0x0080, 0x1F00, 0x0F00, 0x1700, 0x0700, 0x1B00, 0x0B00, 0x1300, + 0x0DA0, 0x05A0, 0x09A0, 0x01A0, 0x0EA0, 0x06A0, 0x0AA0, 0x02A0, + 0x0CA0, 0x04A0, 0x08A0, 0x00A0, 0x0F20, 0x0720, 0x0B20, 0x0320, + 0x0D20, 0x0520, 0x0920, 0x0120, 0x0E20, 0x0620, 0x0A20, 0x0220, + 0x0C20, 0x0420, 0x0820, 0x0020, 0x0FC0, 0x07C0, 0x0BC0, 0x03C0, + 0x0DC0, 0x05C0, 0x09C0, 0x01C0, 0x0EC0, 0x06C0, 0x0AC0, 0x02C0, + 0x0CC0, 0x04C0, 0x08C0, 0x00C0, 0x0F40, 0x0740, 0x0B40, 0x0340, + 0x0300, 0x0D40, 0x1D00, 0x0D00, 0x1500, 0x0540, 0x0500, 0x1900, + 0x0900, 0x0940, 0x1100, 0x0100, 0x1E00, 0x0E00, 0x0140, 0x1600, + 0x0600, 0x1A00, 0x0E40, 0x0640, 0x0A40, 0x0A00, 0x1200, 0x0200, + 0x1C00, 0x0C00, 0x1400, 0x0400, 0x1800, 0x0800, 0x1000, 0x0000 +}; +*/ +//----------------------------------------------------------------------------- +// Macros + +// Macro for calculating hash of the current byte pair. +// Note that most exact byte pair hash would be buffer[0] + buffer[1] << 0x08, +// but even this way gives nice indication of equal byte pairs, with significantly +// smaller size of the array that holds numbers of those hashes +#define BYTE_PAIR_HASH(buffer) ((buffer[0] * 4) + (buffer[1] * 5)) + +//----------------------------------------------------------------------------- +// Local functions + +// Builds the "hash_to_index" table and "pair_hash_offsets" table. +// Every element of "hash_to_index" will contain lowest index to the +// "pair_hash_offsets" table, effectively giving offset of the first +// occurence of the given PAIR_HASH in the input data. +static void SortBuffer(TCmpStruct * pWork, unsigned char * buffer_begin, unsigned char * buffer_end) +{ + unsigned short * phash_to_index; + unsigned char * buffer_ptr; + unsigned short total_sum = 0; + unsigned long byte_pair_hash; // Hash value of the byte pair + unsigned short byte_pair_offs; // Offset of the byte pair, relative to "work_buff" + + // Zero the entire "phash_to_index" table + memset(pWork->phash_to_index, 0, sizeof(pWork->phash_to_index)); + + // Step 1: Count amount of each PAIR_HASH in the input buffer + // The table will look like this: + // offs 0x000: Number of occurences of PAIR_HASH 0 + // offs 0x001: Number of occurences of PAIR_HASH 1 + // ... + // offs 0x8F7: Number of occurences of PAIR_HASH 0x8F7 (the highest hash value) + for(buffer_ptr = buffer_begin; buffer_ptr < buffer_end; buffer_ptr++) + pWork->phash_to_index[BYTE_PAIR_HASH(buffer_ptr)]++; + + // Step 2: Convert the table to the array of PAIR_HASH amounts. + // Each element contains count of PAIR_HASHes that is less or equal + // to element index + // The table will look like this: + // offs 0x000: Number of occurences of PAIR_HASH 0 or lower + // offs 0x001: Number of occurences of PAIR_HASH 1 or lower + // ... + // offs 0x8F7: Number of occurences of PAIR_HASH 0x8F7 or lower + for(phash_to_index = pWork->phash_to_index; phash_to_index < &pWork->phash_to_index_end; phash_to_index++) + { + total_sum = total_sum + phash_to_index[0]; + phash_to_index[0] = total_sum; + } + + // Step 3: Convert the table to the array of indexes. + // Now, each element contains index to the first occurence of given PAIR_HASH + for(buffer_end--; buffer_end >= buffer_begin; buffer_end--) + { + byte_pair_hash = BYTE_PAIR_HASH(buffer_end); + byte_pair_offs = (unsigned short)(buffer_end - pWork->work_buff); + + pWork->phash_to_index[byte_pair_hash]--; + pWork->phash_offs[pWork->phash_to_index[byte_pair_hash]] = byte_pair_offs; + } +} + +static void FlushBuf(TCmpStruct * pWork) +{ + unsigned char save_ch1; + unsigned char save_ch2; + unsigned int size = 0x800; + + pWork->write_buf(pWork->out_buff, &size, pWork->param); + + save_ch1 = pWork->out_buff[0x800]; + save_ch2 = pWork->out_buff[pWork->out_bytes]; + pWork->out_bytes -= 0x800; + + memset(pWork->out_buff, 0, sizeof(pWork->out_buff)); + + if(pWork->out_bytes != 0) + pWork->out_buff[0] = save_ch1; + if(pWork->out_bits != 0) + pWork->out_buff[pWork->out_bytes] = save_ch2; +} + +static void OutputBits(TCmpStruct * pWork, unsigned int nbits, unsigned long bit_buff) +{ + unsigned int out_bits; + + // If more than 8 bits to output, do recursion + if(nbits > 8) + { + OutputBits(pWork, 8, bit_buff); + bit_buff >>= 8; + nbits -= 8; + } + + // Add bits to the last out byte in out_buff; + out_bits = pWork->out_bits; + pWork->out_buff[pWork->out_bytes] |= (unsigned char)(bit_buff << out_bits); + pWork->out_bits += nbits; + + // If 8 or more bits, increment number of bytes + if(pWork->out_bits > 8) + { + pWork->out_bytes++; + bit_buff >>= (8 - out_bits); + + pWork->out_buff[pWork->out_bytes] = (unsigned char)bit_buff; + pWork->out_bits &= 7; + } + else + { + pWork->out_bits &= 7; + if(pWork->out_bits == 0) + pWork->out_bytes++; + } + + // If there is enough compressed bytes, flush them + if(pWork->out_bytes >= 0x800) + FlushBuf(pWork); +} + +// This function searches for a repetition +// (a previous occurence of the current byte sequence) +// Returns length of the repetition, and stores the backward distance +// to pWork structure. +static unsigned int FindRep(TCmpStruct * pWork, unsigned char * input_data) +{ + unsigned short * phash_to_index; // Pointer into pWork->phash_to_index table + unsigned short * phash_offs; // Pointer to the table containing offsets of each PAIR_HASH + unsigned char * repetition_limit; // An eventual repetition must be at position below this pointer + unsigned char * prev_repetition; // Pointer to the previous occurence of the current PAIR_HASH + unsigned char * prev_rep_end; // End of the previous repetition + unsigned char * input_data_ptr; + unsigned short phash_offs_index; // Index to the table with PAIR_HASH positions + unsigned short min_phash_offs; // The lowest allowed hash offset + unsigned short offs_in_rep; // Offset within found repetition + unsigned int equal_byte_count; // Number of bytes that are equal to the previous occurence + unsigned int rep_length = 1; // Length of the found repetition + unsigned int rep_length2; // Secondary repetition + unsigned char pre_last_byte; // Last but one byte from a repetion + unsigned short di_val; + + // Calculate the previous position of the PAIR_HASH + phash_to_index = pWork->phash_to_index + BYTE_PAIR_HASH(input_data); + min_phash_offs = (unsigned short)((input_data - pWork->work_buff) - pWork->dsize_bytes + 1); + phash_offs_index = phash_to_index[0]; + + // If the PAIR_HASH offset is below the limit, find a next one + phash_offs = pWork->phash_offs + phash_offs_index; + if(*phash_offs < min_phash_offs) + { + while(*phash_offs < min_phash_offs) + { + phash_offs_index++; + phash_offs++; + } + *phash_to_index = phash_offs_index; + } + + // Get the first location of the PAIR_HASH, + // and thus the first eventual location of byte repetition + phash_offs = pWork->phash_offs + phash_offs_index; + prev_repetition = pWork->work_buff + phash_offs[0]; + repetition_limit = input_data - 1; + + // If the current PAIR_HASH was not encountered before, + // we haven't found a repetition. + if(prev_repetition >= repetition_limit) + return 0; + + // We have found a match of a PAIR_HASH. Now we have to make sure + // that it is also a byte match, because PAIR_HASH is not unique. + // We compare the bytes and count the length of the repetition + input_data_ptr = input_data; + for(;;) + { + // If the first byte of the repetition and the so-far-last byte + // of the repetition are equal, we will compare the blocks. + if(*input_data_ptr == *prev_repetition && input_data_ptr[rep_length-1] == prev_repetition[rep_length-1]) + { + // Skip the current byte + prev_repetition++; + input_data_ptr++; + equal_byte_count = 2; + + // Now count how many more bytes are equal + while(equal_byte_count < MAX_REP_LENGTH) + { + prev_repetition++; + input_data_ptr++; + + // Are the bytes different ? + if(*prev_repetition != *input_data_ptr) + break; + + equal_byte_count++; + } + + // If we found a repetition of at least the same length, take it. + // If there are multiple repetitions in the input buffer, this will + // make sure that we find the most recent one, which in turn allows + // us to store backward length in less amount of bits + input_data_ptr = input_data; + if(equal_byte_count >= rep_length) + { + // Calculate the backward distance of the repetition. + // Note that the distance is stored as decremented by 1 + pWork->distance = (unsigned int)(input_data - prev_repetition + equal_byte_count - 1); + + // Repetitions longer than 10 bytes will be stored in more bits, + // so they need a bit different handling + if((rep_length = equal_byte_count) > 10) + break; + } + } + + // Move forward in the table of PAIR_HASH repetitions. + // There might be a more recent occurence of the same repetition. + phash_offs_index++; + phash_offs++; + prev_repetition = pWork->work_buff + phash_offs[0]; + + // If the next repetition is beyond the minimum allowed repetition, we are done. + if(prev_repetition >= repetition_limit) + { + // A repetition must have at least 2 bytes, otherwise it's not worth it + return (rep_length >= 2) ? rep_length : 0; + } + } + + // If the repetition has max length of 0x204 bytes, we can't go any fuhrter + if(equal_byte_count == MAX_REP_LENGTH) + { + pWork->distance--; + return equal_byte_count; + } + + // Check for possibility of a repetition that occurs at more recent position + phash_offs = pWork->phash_offs + phash_offs_index; + if(pWork->work_buff + phash_offs[1] >= repetition_limit) + return rep_length; + + // + // The following part checks if there isn't a longer repetition at + // a latter offset, that would lead to better compression. + // + // Example of data that can trigger this optimization: + // + // "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEQQQQQQQQQQQQ" + // "XYZ" + // "EEEEEEEEEEEEEEEEQQQQQQQQQQQQ"; + // + // Description of data in this buffer + // [0x00] Single byte "E" + // [0x01] Single byte "E" + // [0x02] Repeat 0x1E bytes from [0x00] + // [0x20] Single byte "X" + // [0x21] Single byte "Y" + // [0x22] Single byte "Z" + // [0x23] 17 possible previous repetitions of length at least 0x10 bytes: + // - Repetition of 0x10 bytes from [0x00] "EEEEEEEEEEEEEEEE" + // - Repetition of 0x10 bytes from [0x01] "EEEEEEEEEEEEEEEE" + // - Repetition of 0x10 bytes from [0x02] "EEEEEEEEEEEEEEEE" + // ... + // - Repetition of 0x10 bytes from [0x0F] "EEEEEEEEEEEEEEEE" + // - Repetition of 0x1C bytes from [0x10] "EEEEEEEEEEEEEEEEQQQQQQQQQQQQ" + // The last repetition is the best one. + // + + pWork->offs09BC[0] = 0xFFFF; + pWork->offs09BC[1] = 0x0000; + di_val = 0; + + // Note: I failed to figure out what does the table "offs09BC" mean. + // If anyone has an idea, let me know to zezula_at_volny_dot_cz + for(offs_in_rep = 1; offs_in_rep < rep_length; ) + { + if(input_data[offs_in_rep] != input_data[di_val]) + { + di_val = pWork->offs09BC[di_val]; + if(di_val != 0xFFFF) + continue; + } + pWork->offs09BC[++offs_in_rep] = ++di_val; + } + + // + // Now go through all the repetitions from the first found one + // to the current input data, and check if any of them migh be + // a start of a greater sequence match. + // + + prev_repetition = pWork->work_buff + phash_offs[0]; + prev_rep_end = prev_repetition + rep_length; + rep_length2 = rep_length; + + for(;;) + { + rep_length2 = pWork->offs09BC[rep_length2]; + if(rep_length2 == 0xFFFF) + rep_length2 = 0; + + // Get the pointer to the previous repetition + phash_offs = pWork->phash_offs + phash_offs_index; + + // Skip those repetitions that don't reach the end + // of the first found repetition + do + { + phash_offs++; + phash_offs_index++; + prev_repetition = pWork->work_buff + *phash_offs; + if(prev_repetition >= repetition_limit) + return rep_length; + } + while(prev_repetition + rep_length2 < prev_rep_end); + + // Verify if the last but one byte from the repetition matches + // the last but one byte from the input data. + // If not, find a next repetition + pre_last_byte = input_data[rep_length - 2]; + if(pre_last_byte == prev_repetition[rep_length - 2]) + { + // If the new repetition reaches beyond the end + // of previously found repetition, reset the repetition length to zero. + if(prev_repetition + rep_length2 != prev_rep_end) + { + prev_rep_end = prev_repetition; + rep_length2 = 0; + } + } + else + { + phash_offs = pWork->phash_offs + phash_offs_index; + do + { + phash_offs++; + phash_offs_index++; + prev_repetition = pWork->work_buff + *phash_offs; + if(prev_repetition >= repetition_limit) + return rep_length; + } + while(prev_repetition[rep_length - 2] != pre_last_byte || prev_repetition[0] != input_data[0]); + + // Reset the length of the repetition to 2 bytes only + prev_rep_end = prev_repetition + 2; + rep_length2 = 2; + } + + // Find out how many more characters are equal to the first repetition. + while(*prev_rep_end == input_data[rep_length2]) + { + if(++rep_length2 >= 0x204) + break; + prev_rep_end++; + } + + // Is the newly found repetion at least as long as the previous one ? + if(rep_length2 >= rep_length) + { + // Calculate the distance of the new repetition + pWork->distance = (unsigned int)(input_data - prev_repetition - 1); + if((rep_length = rep_length2) == 0x204) + return rep_length; + + // Update the additional elements in the "offs09BC" table + // to reflect new rep length + while(offs_in_rep < rep_length2) + { + if(input_data[offs_in_rep] != input_data[di_val]) + { + di_val = pWork->offs09BC[di_val]; + if(di_val != 0xFFFF) + continue; + } + pWork->offs09BC[++offs_in_rep] = ++di_val; + } + } + } +} + +static void WriteCmpData(TCmpStruct * pWork) +{ + unsigned char * input_data_end; // Pointer to the end of the input data + unsigned char * input_data = pWork->work_buff + pWork->dsize_bytes + 0x204; + unsigned int input_data_ended = 0; // If 1, then all data from the input stream have been already loaded + unsigned int save_rep_length; // Saved length of current repetition + unsigned int save_distance = 0; // Saved distance of current repetition + unsigned int rep_length; // Length of the found repetition + unsigned int phase = 0; // + + // Store the compression type and dictionary size + pWork->out_buff[0] = (char)pWork->ctype; + pWork->out_buff[1] = (char)pWork->dsize_bits; + pWork->out_bytes = 2; + + // Reset output buffer to zero + memset(&pWork->out_buff[2], 0, sizeof(pWork->out_buff) - 2); + pWork->out_bits = 0; + + while(input_data_ended == 0) + { + unsigned int bytes_to_load = 0x1000; + int total_loaded = 0; + int bytes_loaded; + + // Load the bytes from the input stream, up to 0x1000 bytes + while(bytes_to_load != 0) + { + bytes_loaded = pWork->read_buf((char *)pWork->work_buff + pWork->dsize_bytes + 0x204 + total_loaded, + &bytes_to_load, + pWork->param); + if(bytes_loaded == 0) + { + if(total_loaded == 0 && phase == 0) + goto __Exit; + input_data_ended = 1; + break; + } + else + { + bytes_to_load -= bytes_loaded; + total_loaded += bytes_loaded; + } + } + + input_data_end = pWork->work_buff + pWork->dsize_bytes + total_loaded; + if(input_data_ended) + input_data_end += 0x204; + + // + // Warning: The end of the buffer passed to "SortBuffer" is actually 2 bytes beyond + // valid data. It is questionable if this is actually a bug or not, + // but it might cause the compressed data output to be dependent on random bytes + // that are in the buffer. + // To prevent that, the calling application must always zero the compression + // buffer before passing it to "implode" + // + + // Search the PAIR_HASHes of the loaded blocks. Also, include + // previously compressed data, if any. + switch(phase) + { + case 0: + SortBuffer(pWork, input_data, input_data_end + 1); + phase++; + if(pWork->dsize_bytes != 0x1000) + phase++; + break; + + case 1: + SortBuffer(pWork, input_data - pWork->dsize_bytes + 0x204, input_data_end + 1); + phase++; + break; + + default: + SortBuffer(pWork, input_data - pWork->dsize_bytes, input_data_end + 1); + break; + } + + // Perform the compression of the current block + while(input_data < input_data_end) + { + // Find if the current byte sequence wasn't there before. + rep_length = FindRep(pWork, input_data); + while(rep_length != 0) + { + // If we found repetition of 2 bytes, that is 0x100 or fuhrter back, + // don't bother. Storing the distance of 0x100 bytes would actually + // take more space than storing the 2 bytes as-is. + if(rep_length == 2 && pWork->distance >= 0x100) + break; + + // When we are at the end of the input data, we cannot allow + // the repetition to go past the end of the input data. + if(input_data_ended && input_data + rep_length > input_data_end) + { + // Shorten the repetition length so that it only covers valid data + rep_length = (unsigned long)(input_data_end - input_data); + if(rep_length < 2) + break; + + // If we got repetition of 2 bytes, that is 0x100 or more backward, don't bother + if(rep_length == 2 && pWork->distance >= 0x100) + break; + goto __FlushRepetition; + } + + if(rep_length >= 8 || input_data + 1 >= input_data_end) + goto __FlushRepetition; + + // Try to find better repetition 1 byte later. + // Example: "ARROCKFORT" "AROCKFORT" + // When "input_data" points to the second string, FindRep + // returns the occurence of "AR". But there is longer repetition "ROCKFORT", + // beginning 1 byte after. + save_rep_length = rep_length; + save_distance = pWork->distance; + rep_length = FindRep(pWork, input_data + 1); + + // Only use the new repetition if it's length is greater than the previous one + if(rep_length > save_rep_length) + { + // If the new repetition if only 1 byte better + // and the previous distance is less than 0x80 bytes, use the previous repetition + if(rep_length > save_rep_length + 1 || save_distance > 0x80) + { + // Flush one byte, so that input_data will point to the secondary repetition + OutputBits(pWork, pWork->nChBits[*input_data], pWork->nChCodes[*input_data]); + input_data++; + continue; + } + } + + // Revert to the previous repetition + rep_length = save_rep_length; + pWork->distance = save_distance; + + __FlushRepetition: + + OutputBits(pWork, pWork->nChBits[rep_length + 0xFE], pWork->nChCodes[rep_length + 0xFE]); + if(rep_length == 2) + { + OutputBits(pWork, pWork->dist_bits[pWork->distance >> 2], + pWork->dist_codes[pWork->distance >> 2]); + OutputBits(pWork, 2, pWork->distance & 3); + } + else + { + OutputBits(pWork, pWork->dist_bits[pWork->distance >> pWork->dsize_bits], + pWork->dist_codes[pWork->distance >> pWork->dsize_bits]); + OutputBits(pWork, pWork->dsize_bits, pWork->dsize_mask & pWork->distance); + } + + // Move the begin of the input data by the length of the repetition + input_data += rep_length; + goto _00402252; + } + + // If there was no previous repetition for the current position in the input data, + // just output the 9-bit literal for the one character + OutputBits(pWork, pWork->nChBits[*input_data], pWork->nChCodes[*input_data]); + input_data++; +_00402252:; + } + + if(input_data_ended == 0) + { + input_data -= 0x1000; + memmove(pWork->work_buff, pWork->work_buff + 0x1000, pWork->dsize_bytes + 0x204); + } + } + +__Exit: + + // Write the termination literal + OutputBits(pWork, pWork->nChBits[0x305], pWork->nChCodes[0x305]); + if(pWork->out_bits != 0) + pWork->out_bytes++; + pWork->write_buf(pWork->out_buff, &pWork->out_bytes, pWork->param); + return; +} + +//----------------------------------------------------------------------------- +// Main imploding function + +unsigned int PKEXPORT implode( + unsigned int (*read_buf)(char *buf, unsigned int *size, void *param), + void (*write_buf)(char *buf, unsigned int *size, void *param), + char *work_buf, + void *param, + unsigned int *type, + unsigned int *dsize) +{ + TCmpStruct * pWork = (TCmpStruct *)work_buf; + unsigned int nChCode; + unsigned int nCount; + unsigned int i; + int nCount2; + + // Fill the work buffer information + // Note: The caller must zero the "work_buff" before passing it to implode + pWork->read_buf = read_buf; + pWork->write_buf = write_buf; + pWork->dsize_bytes = *dsize; + pWork->ctype = *type; + pWork->param = param; + pWork->dsize_bits = 4; + pWork->dsize_mask = 0x0F; + + // Test dictionary size + switch(*dsize) + { + case CMP_IMPLODE_DICT_SIZE3: // 0x1000 bytes + pWork->dsize_bits++; + pWork->dsize_mask |= 0x20; + // No break here !!! + + case CMP_IMPLODE_DICT_SIZE2: // 0x800 bytes + pWork->dsize_bits++; + pWork->dsize_mask |= 0x10; + // No break here !!! + + case CMP_IMPLODE_DICT_SIZE1: // 0x400 + break; + + default: + return CMP_INVALID_DICTSIZE; + } + + // Test the compression type + switch(*type) + { + case CMP_BINARY: // We will compress data with binary compression type + for(nChCode = 0, nCount = 0; nCount < 0x100; nCount++) + { + pWork->nChBits[nCount] = 9; + pWork->nChCodes[nCount] = (unsigned short)nChCode; + nChCode = (nChCode & 0x0000FFFF) + 2; + } + break; + + + case CMP_ASCII: // We will compress data with ASCII compression type + for(nCount = 0; nCount < 0x100; nCount++) + { + pWork->nChBits[nCount] = (unsigned char )(ChBitsAsc[nCount] + 1); + pWork->nChCodes[nCount] = (unsigned short)(ChCodeAsc[nCount] * 2); + } + break; + + default: + return CMP_INVALID_MODE; + } + + for(i = 0; i < 0x10; i++) + { + if(1 << ExLenBits[i]) + { + for(nCount2 = 0; nCount2 < (1 << ExLenBits[i]); nCount2++) + { + pWork->nChBits[nCount] = (unsigned char)(ExLenBits[i] + LenBits[i] + 1); + pWork->nChCodes[nCount] = (unsigned short)((nCount2 << (LenBits[i] + 1)) | ((LenCode[i] & 0xFFFF00FF) * 2) | 1); + nCount++; + } + } + } + + // Copy the distance codes and distance bits and perform the compression + memcpy(&pWork->dist_codes, DistCode, sizeof(DistCode)); + memcpy(&pWork->dist_bits, DistBits, sizeof(DistBits)); + WriteCmpData(pWork); + return CMP_NO_ERROR; +} diff --git a/2018_03_14/DiabDev/pklib/pklib.h b/2018_03_14/DiabDev/pklib/pklib.h new file mode 100644 index 00000000..9eb2915b --- /dev/null +++ b/2018_03_14/DiabDev/pklib/pklib.h @@ -0,0 +1,146 @@ +/*****************************************************************************/ +/* pklib.h Copyright (c) Ladislav Zezula 2003 */ +/*---------------------------------------------------------------------------*/ +/* Header file for PKWARE Data Compression Library */ +/*---------------------------------------------------------------------------*/ +/* Date Ver Who Comment */ +/* -------- ---- --- ------- */ +/* 31.03.03 1.00 Lad The first version of pkware.h */ +/*****************************************************************************/ + +#ifndef __PKLIB_H__ +#define __PKLIB_H__ + +//----------------------------------------------------------------------------- +// Defines + +#define CMP_BINARY 0 // Binary compression +#define CMP_ASCII 1 // Ascii compression + +#define CMP_NO_ERROR 0 +#define CMP_INVALID_DICTSIZE 1 +#define CMP_INVALID_MODE 2 +#define CMP_BAD_DATA 3 +#define CMP_ABORT 4 + +#define CMP_IMPLODE_DICT_SIZE1 1024 // Dictionary size of 1024 +#define CMP_IMPLODE_DICT_SIZE2 2048 // Dictionary size of 2048 +#define CMP_IMPLODE_DICT_SIZE3 4096 // Dictionary size of 4096 + +//----------------------------------------------------------------------------- +// Define calling convention + +#ifndef PKEXPORT +#ifdef WIN32 +#define PKEXPORT __cdecl // Use for normal __cdecl calling +#else +#define PKEXPORT +#endif +#endif + +//----------------------------------------------------------------------------- +// Internal structures + +// Compression structure +typedef struct +{ + unsigned int distance; // 0000: Backward distance of the currently found repetition, decreased by 1 + unsigned int out_bytes; // 0004: # bytes available in out_buff + unsigned int out_bits; // 0008: # of bits available in the last out byte + unsigned int dsize_bits; // 000C: Number of bits needed for dictionary size. 4 = 0x400, 5 = 0x800, 6 = 0x1000 + unsigned int dsize_mask; // 0010: Bit mask for dictionary. 0x0F = 0x400, 0x1F = 0x800, 0x3F = 0x1000 + unsigned int ctype; // 0014: Compression type (CMP_ASCII or CMP_BINARY) + unsigned int dsize_bytes; // 0018: Dictionary size in bytes + unsigned char dist_bits[0x40]; // 001C: Distance bits + unsigned char dist_codes[0x40]; // 005C: Distance codes + unsigned char nChBits[0x306]; // 009C: Table of literal bit lengths to be put to the output stream + unsigned short nChCodes[0x306]; // 03A2: Table of literal codes to be put to the output stream + unsigned short offs09AE; // 09AE: + + void * param; // 09B0: User parameter + unsigned int (*read_buf)(char *buf, unsigned int *size, void *param); // 9B4 + void (*write_buf)(char *buf, unsigned int *size, void *param); // 9B8 + + unsigned short offs09BC[0x204]; // 09BC: + unsigned long offs0DC4; // 0DC4: + unsigned short phash_to_index[0x900]; // 0DC8: Array of indexes (one for each PAIR_HASH) to the "pair_hash_offsets" table + unsigned short phash_to_index_end; // 1FC8: End marker for "phash_to_index" table + char out_buff[0x802]; // 1FCA: Compressed data + unsigned char work_buff[0x2204]; // 27CC: Work buffer + // + DICT_OFFSET => Dictionary + // + UNCMP_OFFSET => Uncompressed data + unsigned short phash_offs[0x2204]; // 49D0: Table of offsets for each PAIR_HASH +} TCmpStruct; + +#define CMP_BUFFER_SIZE sizeof(TCmpStruct) // Size of compression structure. + // Defined as 36312 in pkware header file + + +// Decompression structure +typedef struct +{ + unsigned long offs0000; // 0000 + unsigned long ctype; // 0004: Compression type (CMP_BINARY or CMP_ASCII) + unsigned long outputPos; // 0008: Position in output buffer + unsigned long dsize_bits; // 000C: Dict size (4, 5, 6 for 0x400, 0x800, 0x1000) + unsigned long dsize_mask; // 0010: Dict size bitmask (0x0F, 0x1F, 0x3F for 0x400, 0x800, 0x1000) + unsigned long bit_buff; // 0014: 16-bit buffer for processing input data + unsigned long extra_bits; // 0018: Number of extra (above 8) bits in bit buffer + unsigned int in_pos; // 001C: Position in in_buff + unsigned long in_bytes; // 0020: Number of bytes in input buffer + void * param; // 0024: Custom parameter + unsigned int (*read_buf)(char *buf, unsigned int *size, void *param); // Pointer to function that reads data from the input stream + void (*write_buf)(char *buf, unsigned int *size, void *param);// Pointer to function that writes data to the output stream + + unsigned char out_buff[0x2204]; // 0030: Output circle buffer. + // 0x0000 - 0x0FFF: Previous uncompressed data, kept for repetitions + // 0x1000 - 0x1FFF: Currently decompressed data + // 0x2000 - 0x2203: Reserve space for the longest possible repetition + unsigned char in_buff[0x800]; // 2234: Buffer for data to be decompressed + unsigned char DistPosCodes[0x100]; // 2A34: Table of distance position codes + unsigned char LengthCodes[0x100]; // 2B34: Table of length codes + unsigned char offs2C34[0x100]; // 2C34: Buffer for + unsigned char offs2D34[0x100]; // 2D34: Buffer for + unsigned char offs2E34[0x80]; // 2EB4: Buffer for + unsigned char offs2EB4[0x100]; // 2EB4: Buffer for + unsigned char ChBitsAsc[0x100]; // 2FB4: Buffer for + unsigned char DistBits[0x40]; // 30B4: Numbers of bytes to skip copied block length + unsigned char LenBits[0x10]; // 30F4: Numbers of bits for skip copied block length + unsigned char ExLenBits[0x10]; // 3104: Number of valid bits for copied block + unsigned short LenBase[0x10]; // 3114: Buffer for +} TDcmpStruct; + +#define EXP_BUFFER_SIZE sizeof(TDcmpStruct) // Size of decompression structure + // Defined as 12596 in pkware headers + +//----------------------------------------------------------------------------- +// Public functions + +#ifdef __cplusplus + extern "C" { +#endif + +unsigned int PKEXPORT implode( + unsigned int (*read_buf)(char *buf, unsigned int *size, void *param), + void (*write_buf)(char *buf, unsigned int *size, void *param), + char *work_buf, + void *param, + unsigned int *type, + unsigned int *dsize); + + +unsigned int PKEXPORT explode( + unsigned int (*read_buf)(char *buf, unsigned int *size, void *param), + void (*write_buf)(char *buf, unsigned int *size, void *param), + char *work_buf, + void *param); + +// The original name "crc32" was changed to "crc32pk" due +// to compatibility with zlib +unsigned long PKEXPORT crc32_pklib(char *buffer, unsigned int *size, unsigned long *old_crc); + +#ifdef __cplusplus + } // End of 'extern "C"' declaration +#endif + +#endif // __PKLIB_H__ diff --git a/2018_03_14/DiabDev/resource.h b/2018_03_14/DiabDev/resource.h new file mode 100644 index 00000000..3040bdf7 --- /dev/null +++ b/2018_03_14/DiabDev/resource.h @@ -0,0 +1,27 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by DIABDEV.RC +// +#define IDR_MAINFRAME 128 +#define IDD_DIABDEV_DIALOG 102 +#define IDD_ABOUTBOX 103 +#define IDS_APP_TITLE 103 +#define IDM_ABOUT 104 +#define IDM_EXIT 105 +#define IDS_HELLO 106 +#define IDI_DIABDEV 107 +#define IDI_SMALL 108 +#define IDC_DIABDEV 109 +#define IDC_MYICON 2 +#define IDC_STATIC -1 +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS + +#define _APS_NEXT_RESOURCE_VALUE 129 +#define _APS_NEXT_COMMAND_VALUE 32771 +#define _APS_NEXT_CONTROL_VALUE 1000 +#define _APS_NEXT_SYMED_VALUE 110 +#endif +#endif diff --git a/2018_03_14/DiabDev/storm.h b/2018_03_14/DiabDev/storm.h new file mode 100644 index 00000000..b5fd9e2b --- /dev/null +++ b/2018_03_14/DiabDev/storm.h @@ -0,0 +1,1298 @@ +#pragma once + +#ifndef __BLIZZARD_STORM_HEADER +#define __BLIZZARD_STORM_HEADER + +#include +#include +#include +#include + +// Note to self: Linker error => forgot a return value in cpp + +// Storm API definition +#ifndef STORMAPI +#define STORMAPI __stdcall +#endif + +#ifndef __STORM_SMAX +#define __STORM_SMAX(x,y) (x < y ? y : x) +#endif + +#ifndef __STORM_SSIZEMAX +#define __STORM_SSIZEMAX(x,y) (__STORM_SMAX(sizeof(x),sizeof(y))) +#endif + +#ifndef __STORM_SMIN +#define __STORM_SMIN(x,y) (x < y ? x : y) +#endif + +#ifndef __STORM_SSIZEMIN +#define __STORM_SSIZEMIN(x,y) (__STORM_SMIN(sizeof(x),sizeof(y))) +#endif + +typedef struct _WRECT +{ + WORD left; + WORD top; + WORD right; + WORD bottom; +} WRECT, *PWRECT; + +typedef struct _WPOINT +{ + WORD x; + WORD y; +} WPOINT, *PWPOINT; + +typedef struct _WSIZE +{ + WORD cx; + WORD cy; +} WSIZE, *PWSIZE; + + + +// Game states +#define GAMESTATE_PRIVATE 0x01 +#define GAMESTATE_FULL 0x02 +#define GAMESTATE_ACTIVE 0x04 +#define GAMESTATE_STARTED 0x08 +#define GAMESTATE_REPLAY 0x80 + + +BOOL STORMAPI SNetCreateGame(const char *pszGameName, const char *pszGamePassword, const char *pszGameStatString, DWORD dwGameType, char *GameTemplateData, int GameTemplateSize, int playerCount, char *creatorName, char *a11, int *playerID); +BOOL STORMAPI SNetDestroy(); +BOOL STORMAPI SNetEnumProviders(int (STORMAPI *callback)(DWORD, DWORD, DWORD, DWORD), int mincaps); + +BOOL STORMAPI SNetEnumGames(int (STORMAPI *callback)(DWORD, DWORD, DWORD), int *hintnextcall); + +/* SNetDropPlayer @ 106 + * + * Drops a player from the current game. + * + * playerid: The player ID for the player to be dropped. + * flags: + * + * Returns TRUE if the function was called successfully and FALSE otherwise. + */ +BOOL +STORMAPI +SNetDropPlayer( + int playerid, + DWORD flags); + +/* SNetGetGameInfo @ 107 + * + * Retrieves specific game information from Storm, such as name, password, + * stats, mode, game template, and players. + * + * type: The type of data to retrieve. See GAMEINFO_ flags. + * dst: The destination buffer for the data. + * length: The maximum size of the destination buffer. + * byteswritten: The number of bytes written to the destination buffer. + * + * Returns TRUE if the function was called successfully and FALSE otherwise. + */ +BOOL +STORMAPI +SNetGetGameInfo( + int type, + void *dst, + size_t length, + size_t *byteswritten = NULL); + + +#define SNGetGameInfo(typ,dst) SNetGetGameInfo(typ, &dst, sizeof(dst)) + + + +// Game info fields +#define GAMEINFO_NAME 1 +#define GAMEINFO_PASSWORD 2 +#define GAMEINFO_STATS 3 +#define GAMEINFO_MODEFLAG 4 +#define GAMEINFO_GAMETEMPLATE 5 +#define GAMEINFO_PLAYERS 6 + + +BOOL STORMAPI SNetGetNumPlayers(int *firstplayerid, int *lastplayerid, int *activeplayers); + + +typedef struct _CAPS +{ + DWORD dwSize; // Size of this structure // sizeof(CAPS) + DWORD dwUnk_0x04; // Some flags? + DWORD maxmessagesize; // Size of the packet buffer, must be beteen 128 and 512 + DWORD dwUnk_0x0C; // Unknown + DWORD dwDisplayedPlayerCount; // Displayed player count in the mode selection list + DWORD dwUnk_0x14; // some kind of timeout or timer related + DWORD dwPlayerLatency; // ... latency? + DWORD dwPlayerCount; // the number of players that can participate, must be between 1 and 20 + DWORD dwCallDelay; // the number of calls before data is sent over the network // between 2 and 8; single player is set to 1 +} CAPS, *PCAPS; + + +BOOL STORMAPI SNetGetPlayerCaps(char playerid, PCAPS playerCaps); + +/* SNetGetPlayerName @ 113 + * + * Retrieves the name of a player given their player ID. + * + * playerid: The player's ID. + * buffer: The buffer that will receive the name. + * buffersize: The maximum size of buffer. + * + * Returns TRUE if the function was called successfully and FALSE otherwise. + */ +BOOL +STORMAPI +SNetGetPlayerName( + int playerid, + char *buffer, + size_t buffersize); + +/* SNetGetProviderCaps @ 114 + * + * Retrieves network provider capacity information. + * + * providerCaps: A pointer to a CAPS structure that will receive the information. + * + * Returns TRUE if the function was called successfully and FALSE otherwise. + */ +BOOL +STORMAPI +SNetGetProviderCaps( + _SNETCAPS *providerCaps); + +/* SNetGetTurnsInTransit @ 115 + * + * Retrieves the number of turns (buffers) that have been queued + * before sending them over the network. + * + * turns: A pointer to an integer that will receive the value. + * + * Returns TRUE if the function was called successfully and FALSE otherwise. + */ +BOOL +STORMAPI +SNetGetTurnsInTransit( + int *turns); + + +BOOL STORMAPI SNetInitializeDevice(int a1, int a2, int a3, int a4, int *a5); + +// Network provider structures +typedef struct _client_info +{ + DWORD dwSize; // 60 + char *pszName; + char *pszVersion; + DWORD dwProduct; + DWORD dwVerbyte; + DWORD dwUnk5; + DWORD dwMaxPlayers; + DWORD dwUnk7; + DWORD dwUnk8; + DWORD dwUnk9; + DWORD dwUnk10; // 0xFF + char *pszCdKey; + char *pszCdOwner; + DWORD dwIsShareware; + DWORD dwLangId; +} client_info; + +typedef struct _user_info +{ + DWORD dwSize; // 16 + char *pszPlayerName; + char *pszUnknown; + DWORD dwUnknown; +} user_info; + +typedef struct _battle_info +{ + DWORD dwSize; // 92 + DWORD dwUnkType; + HWND hFrameWnd; + void *pfnBattleGetResource; + void *pfnBattleGetErrorString; + void *pfnBattleMakeCreateGameDialog; + void *pfnBattleUpdateIcons; + DWORD dwUnk_07; + void *pfnBattleErrorDialog; + void *pfnBattlePlaySound; + DWORD dwUnk_10; + void *pfnBattleGetCursorLink; + DWORD dwUnk_12; + void *pfnUnk_13; + DWORD dwUnk_14; + void *pfnBattleMakeProfileDialog; + char *pszProfileStrings; + void *pfnBattleDrawProfileInfo; + void *pfnUnk_18; + DWORD dwUnk_19; + void *pfnUnk_20; + void *pfnUnk_21; + void *pfnBattleSetLeagueName; +} battle_info; + +typedef struct _module_info +{ + DWORD dwSize; // 20 + char *pszVersionString; + char *pszModuleName; + char *pszMainArchive; + char *pszPatchArchive; +} module_info; + +typedef struct _game +{ + DWORD dwIndex; + DWORD dwGameState; + DWORD dwUnk_08; + SOCKADDR saHost; + DWORD dwUnk_1C; + DWORD dwTimer; + DWORD dwUnk_24; + char szGameName[128]; + char szGameStatString[128]; + _game *pNext; + void *pExtra; + DWORD dwExtraBytes; + DWORD dwProduct; + DWORD dwVersion; +} game; + +typedef struct _storm_head +{ + WORD wChecksum; + WORD wLength; + WORD wSent; + WORD wReceived; + BYTE bCommandClass; + BYTE bCommandType; + BYTE bPlayerId; + BYTE bFlags; +} storm_head; + + +// Traffic flags +#define STRAFFIC_NORMAL 0 +#define STRAFFIC_VERIFY 1 +#define STRAFFIC_RESEND 2 +#define STRAFFIC_REPLY 4 + + +/* SNetInitializeProvider @ 117 + * + * Initializes a provider by storing the provider callbacks, and calling + * spiInitialize() using the parameters passed to this function. + * Note: The use of the parameters is determined by the network + * module. + * + * providerName: The provider's identifier. Example: 'TENB' (BNET). + * gameClientInfo: A pointer to a clientInfo structure containing + * information about the game client. + * userData: A pointer to a userInfo structure containing information + * about the player. + * bnCallbacks: A pointer to a battleInfo structure containing callbacks + * and other information that is specific to Battle.net. + * moduleData: A pointer to a moduleInfo structure containing the + * executable information and paths to MPQ archives. + * + * Returns TRUE if the function was called successfully and FALSE otherwise. + */ +BOOL +STORMAPI +SNetInitializeProvider( + DWORD providerName, + _SNETPROGRAMDATA *gameClientInfo, + _SNETPLAYERDATA *userData, + _SNETUIDATA *bnCallbacks, + _SNETVERSIONDATA *moduleData); + + +BOOL STORMAPI SNetJoinGame(int id, char *gameName, char *gamePassword, char *playerName, char *userStats, int *playerid); + +/* SNetLeaveGame @ 119 + * + * Notifies Storm that the player has left the game. Storm will + * notify all connected peers through the network provider. + * + * type: The leave type. It doesn't appear to be important, no documentation available. + * + * Returns TRUE if the function was called successfully and FALSE otherwise. + */ +BOOL +STORMAPI +SNetLeaveGame( + int type); + +BOOL STORMAPI SNetPerformUpgrade(DWORD *upgradestatus); +BOOL STORMAPI SNetReceiveMessage(int *senderplayerid, char **data, int *databytes); +BOOL STORMAPI SNetReceiveTurns(int a1, int arraysize, char **arraydata, unsigned int *arraydatabytes, DWORD *arrayplayerstatus); + +// Values for arrayplayerstatus +#define SNET_PS_OK 0 +#define SNET_PS_WAITING 2 +#define SNET_PS_NOTRESPONDING 3 +#define SNET_PS_UNKNOWN default + + +// Event structure +typedef struct _s_evt +{ + DWORD dwFlags; + int dwPlayerId; + void *pData; + DWORD dwSize; +} S_EVT, *PS_EVT; + + +// @TODO: "type" is unknown. +HANDLE STORMAPI SNetRegisterEventHandler(int type, void (STORMAPI *sEvent)(_SNETEVENT *)); +HANDLE STORMAPI SNetUnregisterEventHandler(int type, void (STORMAPI *sEvent)(_SNETEVENT *)); + +int STORMAPI SNetSelectGame(int a1, int a2, int a3, int a4, int a5, int *playerid); + +/* SNetSendMessage @ 127 + * + * Sends a message to a player given their player ID. Network message + * is sent using class 01 and is retrieved by the other client using + * SNetReceiveMessage(). + * + * playerID: The player index of the player to receive the data. + * Conversely, this field can be one of the following constants: + * SNPLAYER_ALL | Sends the message to all players, including oneself. + * SNPLAYER_OTHERS | Sends the message to all players, except for oneself. + * data: A pointer to the data. + * databytes: The amount of bytes that the data pointer contains. + * + * Returns TRUE if the function was called successfully and FALSE otherwise. + */ +BOOL +STORMAPI +SNetSendMessage( + int playerID, + void *data, + size_t databytes); + + +// Macro values to target specific players +#define SNPLAYER_ALL -1 +#define SNPLAYER_OTHERS -2 + + +/* SNetSendTurn @ 128 + * + * Sends a turn (data packet) to all players in the game. Network data + * is sent using class 02 and is retrieved by the other client using + * SNetReceiveTurns(). + * + * data: A pointer to the data. + * databytes: The amount of bytes that the data pointer contains. + * + * Returns TRUE if the function was called successfully and FALSE otherwise. + */ +BOOL +STORMAPI +SNetSendTurn( + char *data, + size_t databytes); + +/* SNetSetGameMode @ 130 + * + * Set's the game's mode flags, notifying the network + * provider that the state of the game has changed. + * For example: notifies Battle.net when the game is + * full. + * + * You should first call SNetGetGameInfo to retrieve + * the existing mode flags. + * + * modeFlags: The new flags for the game mode. + * GAMESTATE_PRIVATE | The game is passworded. + * GAMESTATE_FULL | The game is full. + * GAMESTATE_ACTIVE | The game is available. + * GAMESTATE_STARTED | The game is in progress. + * GAMESTATE_REPLAY | The game is a replay. + * makePublic: Used to make the game a public game, removing the GAMESTATE_PRIVATE flag. + * + * Returns TRUE if the function was called successfully and FALSE otherwise. + */ +BOOL +STORMAPI +SNetSetGameMode( + DWORD modeFlags, + bool makePublic = false); + +#define SNMakeGamePublic() SNetSetGameMode( (DWORD mode, SNetGetGameInfo(GAMEINFO_MODEFLAGS, &mode, 4), mode), true) + +BOOL STORMAPI SNetEnumGamesEx(int a1, int a2, int (__fastcall *callback)(DWORD, DWORD, DWORD), int *hintnextcall); +BOOL STORMAPI SNetSendServerChatCommand(const char *command); + +BOOL STORMAPI SNetDisconnectAll(DWORD flags); +BOOL STORMAPI SNetCreateLadderGame(const char *pszGameName, const char *pszGamePassword, const char *pszGameStatString, DWORD dwGameType, DWORD dwGameLadderType, DWORD dwGameModeFlags, char *GameTemplateData, int GameTemplateSize, int playerCount, char *creatorName, char *a11, int *playerID); + +#define SNET_GAME_RESULT_WIN 1 +#define SNET_GAME_RESULT_LOSS 2 +#define SNET_GAME_RESULT_DRAW 3 +#define SNET_GAME_RESULT_DISCONNECT 4 + +BOOL STORMAPI SNetReportGameResult(unsigned a1, int size, int *results, const char* headerInfo, const char* detailInfo); + +int STORMAPI SNetSendLeagueCommand(char *cmd, char *callback); +int STORMAPI SNetSendReplayPath(int a1, int a2, char *replayPath); +int STORMAPI SNetGetLeagueName(int leagueID); +BOOL STORMAPI SNetGetPlayerNames(char **names); +int STORMAPI SNetLeagueLogout(char *bnetName); +int STORMAPI SNetGetLeaguePlayerName(char *curPlayerLeageName, size_t nameSize); + +HGDIOBJ STORMAPI SDlgDefDialogProc(HWND hDlg, signed int DlgType, HDC textLabel, HWND hWnd); + +HANDLE STORMAPI SDlgDialogBoxIndirectParam(HMODULE hModule, LPCSTR lpName, HWND hWndParent, LPVOID lpParam, LPARAM lParam); + +BOOL STORMAPI SDlgEndDialog(HWND hDlg, HANDLE nResult); + +BOOL STORMAPI SDlgSetControlBitmaps(HWND parentwindow, int *id, int a3, char *buffer2, char *buffer, int flags, int mask); + +/* +// lpCursorName can only be IDC_ARROW +BOOL STORMAPI SDlgSetSystemCursor(void *lpSrcBuffer, void *p_a2, LPSIZE lpSize, LPCSTR lpCursorName); +*/ + +BOOL STORMAPI SDlgBltToWindowE(HWND hWnd, HRGN a2, char *a3, int a4, void *buffer, RECT *rct, SIZE *size, int a8, int a9, DWORD rop); +BOOL STORMAPI SDlgSetBitmapE(HWND hWnd, int a2, char *src, int mask1, int flags, int a6, int a7, int width, int a9, int mask2); + +int STORMAPI Ordinal224(int a1); + +BOOL STORMAPI SFileCloseArchive(HANDLE hArchive); +BOOL STORMAPI SFileCloseFile(HANDLE hFile); + +BOOL STORMAPI SFileDdaBeginEx(HANDLE directsound, DWORD flags, DWORD mask, unsigned __int32 lDistanceToMove, signed __int32 volume, signed int a6, int a7); +BOOL STORMAPI SFileDdaDestroy(); +BOOL STORMAPI SFileDdaEnd(HANDLE directsound); +BOOL STORMAPI SFileDdaGetPos(HANDLE directsound, int a2, int a3); + +BOOL STORMAPI SFileDdaInitialize(HANDLE directsound); +BOOL STORMAPI SFileDdaSetVolume(HANDLE directsound, signed int bigvolume, signed int volume); +BOOL STORMAPI SFileDestroy(); + +BOOL STORMAPI SFileGetFileArchive(HANDLE hFile, HANDLE archive); +LONG STORMAPI SFileGetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh); +BOOL STORMAPI SFileOpenArchive(const char *szMpqName, DWORD dwPriority, DWORD dwFlags, HANDLE *phMpq); + +// values for dwFlags +enum MPQFlags +{ + MPQ_NO_LISTFILE = 0x0010, + MPQ_NO_ATTRIBUTES = 0x0020, + MPQ_FORCE_V1 = 0x0040, + MPQ_CHECK_SECTOR_CRC = 0x0080 +}; + + +BOOL STORMAPI SFileOpenFile(const char *filename, HANDLE *phFile); +BOOL STORMAPI SFileOpenFileEx(HANDLE hMpq, const char *szFileName, DWORD dwSearchScope, HANDLE *phFile); + +// values for dwSearchScope +enum SFileFlags +{ + SFILE_FROM_MPQ = 0x00000000, + SFILE_FROM_ABSOLUTE = 0x00000001, + SFILE_FROM_RELATIVE = 0x00000002, + SFILE_FROM_DISK = 0x00000004 +}; + +BOOL STORMAPI SFileReadFile(HANDLE hFile, void *buffer, DWORD nNumberOfBytesToRead, DWORD *read, LONG lpDistanceToMoveHigh); + +void STORMAPI SFileSetLocale(LCID lcLocale); + +// mode: 0 - Silent (callback is NULL) +// 1 - Application Defined +// 2 - Handled by storm (callback is NULL) +// BOOL STORMAPI callback(const char *pszFilename, DWORD dwErrCode, DWORD dwErrCount) +BOOL STORMAPI SFileSetIoErrorMode(DWORD mode, BOOL (STORMAPI *callback)(const char*,DWORD,DWORD) ); + +BOOL STORMAPI SFileGetArchiveName(HANDLE hArchive, char *name, int length); +BOOL STORMAPI SFileGetFileName(HANDLE hFile, char *buffer, int length); + +BOOL STORMAPI SFileLoadFile(char *filename, void *buffer, int buffersize, int a4, int a5); +BOOL STORMAPI SFileUnloadFile(HANDLE hFile); +BOOL STORMAPI SFileLoadFileEx(void *hArchive, char *filename, int a3, int a4, int a5, DWORD searchScope, struct _OVERLAPPED *lpOverlapped); + +// Options are DWORD except for #6 +// 1: [TRUE|FALSE] - If true, reports resource leaks (SErrReportResourceLeak/SErrReportNamedResourceLeak) to the attached debugger instead of a message box. +// 2: This option is unused. +// 3: [TRUE|FALSE] - If true, reports general memory leaks to the attached debugger instead of a message box. +// 4: This option is unused. +// 5: [TRUE|FALSE] - If true, reports log messages and log dumps to the attached debugger. +// 6: { DWORD blocks_allocated; DWORD blocks_freed; } Used to determine the amount of memory/heap blocks that have been allocated and freed by storm. +// Can also be used for custom allocations outside of storm. +// +//BOOL STORMAPI StormGetOption(int type, void *pValue, size_t *pSize); +//BOOL STORMAPI StormSetOption(int type, void *pValue, size_t size); + +BOOL STORMAPI SBltROP3(void *lpDstBuffer, void *lpSrcBuffer, int srcDrawWidth, int srcDrawHeight, int dstWidth, int srcWidth, int a7, DWORD rop); +BOOL STORMAPI SBltROP3Clipped(void *lpDstBuffer, RECT *lpDstRect, POINT *lpDstPt, int a4, void *lpSrcBuffer, RECT *lpSrcRect, POINT *lpSrcPt, int a8, int a9, DWORD rop); + +#define SBMP_DEFAULT 0 +#define SBMP_BMP 1 +#define SBMP_PCX 2 +#define SBMP_TGA 3 + + +/* SBmpDecodeImage @ 321 + * + * Decodes an image that has already been loaded into a buffer. + * + * dwImgType: Optional, the image type. See SBMP_ macros. + * pSrcBuffer: A pointer to the source buffer. + * dwSrcBuffersize: The size of the data in the source buffer. + * pPalette: An optional buffer that receives the image palette. + * pDstBuffer: A buffer that receives the image data. + * dwDstBuffersize: The size of the specified image buffer. If the size of the + * destination buffer is 0, then the destination buffer is not used. + * pdwWidth: An optional variable that receives the image width. + * pdwHeight: An optional variable that receives the image height. + * pdwBpp: An optional variable that receives the image bits per pixel. + * + * Returns TRUE if the image was supported and decoded correctly, FALSE otherwise. + */ +BOOL +STORMAPI +SBmpDecodeImage( + DWORD dwImgType, + void *pSrcBuffer, + DWORD dwSrcBuffersize, + PALETTEENTRY *pPalette = NULL, + void *pDstBuffer = NULL, + DWORD dwDstBuffersize = 0, + DWORD *pdwWidth = NULL, + DWORD *pdwHeight = NULL, + DWORD *pdwBpp = NULL); + + +/* SBmpLoadImage @ 323 + * + * Load an image from an available archive into a buffer. + * + * pszFileName: The name of the graphic in an active archive. + * pPalette: An optional buffer that receives the image palette. + * pBuffer: A buffer that receives the image data. + * dwBuffersize: The size of the specified image buffer. + * pdwWidth: An optional variable that receives the image width. + * pdwHeight: An optional variable that receives the image height. + * pdwBpp: An optional variable that receives the image bits per pixel. + * + * Returns TRUE if the image was supported and loaded correctly, FALSE otherwise. + */ +BOOL +STORMAPI +SBmpLoadImage( + const char *pszFileName, + PALETTEENTRY *pPalette = NULL, + void *pBuffer = NULL, + DWORD dwBuffersize = 0, + DWORD *pdwWidth = NULL, + DWORD *pdwHeight = NULL, + DWORD *pdwBpp = NULL); + +/* SBmpSaveImage @ 324 + * + * Save an image from a buffer to a file. The image format is determined + * from the filename and is either .gif, .pcx, .tga, or .bmp being the default. + * + * pszFileName: The name of the file to create. + * pPalette: A pointer to a palette array containing 256 entries. + * pBuffer: A buffer containing the image data. + * pdwWidth: The width of the image. + * pdwHeight: The height of the image. + * pdwBpp: The bits per pixel. + * + * Returns TRUE if the image was saved correctly, FALSE otherwise. + */ +BOOL +STORMAPI +SBmpSaveImage( + const char *pszFileName, + PALETTEENTRY *pPalette, + void *pBuffer, + DWORD dwWidth, + DWORD dwHeight, + DWORD dwBpp = 8); + + +HANDLE STORMAPI SBmpAllocLoadImage(const char *fileName, PALETTEENTRY *palette, void **buffer, int *width, int *height, int unused6, int unused7, void *(STORMAPI *allocFunction)(DWORD)); + +BOOL STORMAPI SCodeCompile(char *directives1, char *directives2, char *loopstring, unsigned int maxiterations, unsigned int flags, HANDLE handle); +BOOL STORMAPI SCodeDelete(HANDLE handle); + +int STORMAPI SCodeExecute(HANDLE handle, int a2); + +BOOL STORMAPI SDrawAutoInitialize(HINSTANCE hInst, LPCSTR lpClassName, LPCSTR lpWindowName, WNDPROC pfnWndProc, int nMode, int nWidth, int nHeight, int nBits); + + +/* SDrawCaptureScreen @ 342 + * + * Saves a screenshot from the primary surface being handled by Storm. + * + * pszOutput: The name of the output file. The save format is automatically set by the extension. + * The extensions supported are .gif, .pcx, .tga, and .bmp. It will write a bitmap by default. + * + * Returns TRUE if successful and FALSE otherwise. + */ +BOOL +STORMAPI +SDrawCaptureScreen( + const char *pszOutput); + + +/* SDrawGetFrameWindow @ 346 + * + * Retrieves the window handle that was specified in + * SDrawManualInitialize or created in SDrawAutoInitialize. + * + * sdraw_framewindow: Optional variable that receives the returned handle. + * + * Returns the handle of the window. + */ +HWND +STORMAPI +SDrawGetFrameWindow( + HWND *sdraw_framewindow = NULL); + + +/* SDrawGetObjects @ 347 + * + * Retrieves the object information that was initialized using + * SDrawManualInitialize or SDrawAutoInitialize. + * + * ddInterface: The DirectDraw interface. + * primarySurface: The primary DirectDraw surface. + * surface2: A second unknown surface. + * surface3: A third unknown surface. + * backSurface: The back DirectDraw surface. + * ddPalette: The DirectDraw palette. + * hPalette: The palette handle. + * + * Returns FALSE if the direct draw interface has not been initialized. + */ +BOOL +STORMAPI +SDrawGetObjects( + LPDIRECTDRAW *ddInterface = NULL, + LPDIRECTDRAWSURFACE *primarySurface = NULL, + LPDIRECTDRAWSURFACE *surface2 = NULL, + LPDIRECTDRAWSURFACE *surface3 = NULL, + LPDIRECTDRAWSURFACE *backSurface = NULL, + LPDIRECTDRAWPALETTE *ddPalette = NULL, + HPALETTE *hPalette = NULL); + + +/* SDrawGetScreenSize @ 348 + * + * Obtains information for the current screen resolution. + * + * pdwWidth: Optional variable that receives the screen width. + * pdwHeight: Optional variable that receives the screen height. + * pdwBpp: Optional variable that receives the bits per pixel. + * + * Returns FALSE if no variables were specified. + */ +BOOL +STORMAPI +SDrawGetScreenSize( + DWORD *pdwWidth, + DWORD *pdwHeight, + DWORD *pdwBpp); + + +// undefined +BOOL STORMAPI SDrawLockSurface(int surfacenumber, RECT *lpDestRect, void **lplpSurface, int *lpPitch, int arg_unused); + + +/* SDrawManualInitialize @ 351 + * + * Sets the DirectDraw variables to be referenced in Storm. + * + * hWnd: The handle of the DirectDraw window. + * ddInterface: The DirectDraw interface. + * primarySurface: The first and primary surface. + * surface2: A second surface. Behaviour not completely known. + * surface3: A third surface. Behaviour not completely known. + * backSurface: The fourth and final surface. The back surface. + * ddPalette: The DirectDraw palette if the application requires it. + * hPalette: The palette handle that belongs to the window. + * If this is NULL and ddPalette is specified, then it + * will be created automatically. A palette can be created + * using the CreatePalette WinAPI function. + * + * Returns FALSE if no variables were specified. + */ +BOOL +STORMAPI +SDrawManualInitialize( + HWND hWnd = NULL, + LPDIRECTDRAW ddInterface = NULL, + LPDIRECTDRAWSURFACE primarySurface = NULL, + LPDIRECTDRAWSURFACE surface2 = NULL, + LPDIRECTDRAWSURFACE surface3 = NULL, + LPDIRECTDRAWSURFACE backSurface = NULL, + LPDIRECTDRAWPALETTE ddPalette = NULL, + HPALETTE hPalette = NULL); + + +/* SDrawPostClose @ 353 + * + * Posts a WM_QUIT message to the active drawing window specified + * in SDrawManualInitialize or created in SDrawAutoInitialize. + * + * Returns TRUE if successful and FALSE otherwise. + */ +BOOL +STORMAPI +SDrawPostClose(); + + +// undefined +//BOOL STORMAPI SDrawRealizePalette(); + +BOOL STORMAPI SDrawUnlockSurface(int surfacenumber, void *lpSurface, int a3, RECT *lpRect); +BOOL STORMAPI SDrawUpdatePalette(unsigned int firstentry, unsigned int numentries, PALETTEENTRY *pPalEntries, int a4); + +BOOL STORMAPI SEvtDispatch(DWORD dwMessageID, DWORD dwFlags, int type, PS_EVT pEvent); + +BOOL STORMAPI SGdiDeleteObject(HANDLE handle); + +BOOL STORMAPI SGdiExtTextOut(int a1, int a2, int a3, int a4, unsigned int a8, signed int a6, signed int a7, const char *pszString, unsigned int arg20); +BOOL STORMAPI SGdiImportFont(HGDIOBJ handle, int windowsfont); + +BOOL STORMAPI SGdiSelectObject(int handle); +BOOL STORMAPI SGdiSetPitch(int pitch); + +BOOL STORMAPI Ordinal393(char *pszString, int, int); + + +/* SMemAlloc @ 401 + * + * Allocates a block of memory. This block is different + * from the standard malloc by including a header containing + * information about the block. + * + * amount: The amount of memory to allocate, in bytes. + * logfilename: The name of the file or object that this call belongs to. + * logline: The line in the file or one of the SLOG_ macros. + * defaultValue: The default value of a byte in the allocated memory. + * + * Returns a pointer to the allocated memory. This pointer does NOT include + * the additional storm header. + */ +void* +STORMAPI +SMemAlloc( + size_t amount, + char *logfilename, + int logline, + char defaultValue = 0); + +#define SMAlloc(amount) SMemAlloc((amount), __FILE__, __LINE__) + + +/* SMemFree @ 403 + * + * Frees a block of memory that was created using SMemAlloc, + * includes the log file and line for debugging purposes. + * + * location: The memory location to be freed. + * logfilename: The name of the file or object that this call belongs to. + * logline: The line in the file or one of the SLOG_ macros. + * defaultValue: + * + * Returns TRUE if the call was successful and FALSE otherwise. + */ +BOOL +STORMAPI +SMemFree( + void *location, + char *logfilename, + int logline, + char defaultValue = 0); + +#define SMFree(loc) SMemFree((loc), __FILE__, __LINE__) + + +/* SMemReAlloc @ 405 + * + * Reallocates a block of memory that was created using SMemAlloc, + * includes the log file and line for debugging purposes. + * + * location: The memory location to be re-allocated. If this parameter + * is NULL, then SMemAlloc is called with the remaining parameters. + * amount: The amount of memory to re-allocate. + * logfilename: The name of the file or object that this call belongs to. + * logline: The line in the file or one of the SLOG_ macros. + * defaultValue: + * + * Returns a pointer to the re-allocated memory. This pointer does NOT include + * the additional storm header. + */ +void* +STORMAPI +SMemReAlloc( + void *location, + size_t amount, + char *logfilename, + int logline, + char defaultValue = 0); + +#define SMReAlloc(loc,s) SMemReAlloc((loc),(s), __FILE__, __LINE__) + +// Can be provided instead of logline/__LINE__ parameter to indicate different errors. +#define SLOG_EXPRESSION 0 +#define SLOG_FUNCTION -1 +#define SLOG_OBJECT -2 +#define SLOG_HANDLE -3 +#define SLOG_FILE -4 +#define SLOG_EXCEPTION -5 + + +BOOL STORMAPI SRegLoadData(const char *keyname, const char *valuename, int size, LPBYTE lpData, BYTE flags, LPDWORD lpcbData); +BOOL STORMAPI SRegLoadString(const char *keyname, const char *valuename, BYTE flags, char *buffer, size_t buffersize); +BOOL STORMAPI SRegLoadValue(const char *keyname, const char *valuename, BYTE flags, int *value); +BOOL STORMAPI SRegSaveData(const char *keyname, const char *valuename, int size, BYTE *lpData, DWORD cbData); +BOOL STORMAPI SRegSaveString(const char *keyname, const char *valuename, BYTE flags, char *string); +BOOL STORMAPI SRegSaveValue(const char *keyname, const char *valuename, BYTE flags, DWORD result); + +BOOL STORMAPI SRegDeleteValue(const char *keyname, const char *valuename, BYTE flags); + +// Flags for SReg functions + +// Default behaviour checks both HKEY_LOCAL_MACHINE and HKEY_CURRENT_USER +// relative to the "Software\\Blizzard Entertainment\\" key in both hives. +#define SREG_NONE 0x00000000 +#define SREG_EXCLUDE_LOCAL_MACHINE 0x00000001 // excludes checking the HKEY_LOCAL_MACHINE hive +#define SREG_BATTLE_NET 0x00000002 // sets the relative key to "Software\\Battle.net\\" instead +#define SREG_EXCLUDE_CURRENT_USER 0x00000004 // excludes checking the HKEY_CURRENT_USER hive +#define SREG_ABSOLUTE 0x00000010 // specifies that the key is not a relative key + +BOOL STORMAPI STransBlt(void *lpSurface, int x, int y, int width, HANDLE hTrans); +BOOL STORMAPI STransBltUsingMask(void *lpDest, void *lpSource, int pitch, int width, HANDLE hTrans); + +BOOL STORMAPI STransDelete(HANDLE hTrans); + +BOOL STORMAPI STransDuplicate(HANDLE hTransSource, HANDLE hTransDest); +BOOL STORMAPI STransIntersectDirtyArray(HANDLE hTrans, char * dirtyarraymask, unsigned flags, HANDLE * phTransResult); +BOOL STORMAPI STransInvertMask(HANDLE hTrans, HANDLE * phTransResult); + +BOOL STORMAPI STransSetDirtyArrayInfo(int width, int height, int depth, int bits); + +BOOL STORMAPI STransPointInMask(HANDLE hTrans, int x, int y); // Name is a pure guess +BOOL STORMAPI STransCombineMasks(HANDLE hTransA, HANDLE hTransB, int left, int top, int flags, HANDLE * phTransResult); + +BOOL STORMAPI STransCreateE(void *pBuffer, int width, int height, int bpp, int a5, int bufferSize, HANDLE *phTransOut); + +BOOL STORMAPI SVidDestroy(); +BOOL STORMAPI SVidGetSize(HANDLE video, int width, int height, int zero); +BOOL STORMAPI SVidInitialize(HANDLE video); +BOOL STORMAPI SVidPlayBegin(char *filename, int arg4, int a3, int a4, int a5, int a6, HANDLE* video); + +BOOL STORMAPI SVidPlayContinueSingle(HANDLE video, int a2, int a3); +BOOL STORMAPI SVidPlayEnd(HANDLE video); + +/* SErrDisplayError @ 461 + * + * Displays a formatted error message. The message is detailed and flexible for many applications. + * The message will be different if there is a debugger attached. Will typically terminate the application + * unless the option to continue is given. + * + * dwErrMessage: The error code. See SErrGetLastError and GetLastError. + * logfilename: The name of the file or object that this call belongs to. + * logline: The line in the file or one of the SLOG_ macros. + * message: A message or expression with additional information. + * allowOption: If TRUE, allows the user the option to continue execution, otherwise the program will terminate. + * exitCode: The exit code used for program termination. + * + * Returns TRUE if the user chose to continue execution, FALSE otherwise. + */ +BOOL +STORMAPI +SErrDisplayError( + DWORD dwErrMsg, + const char *logfilename, + int logline, + const char *message = NULL, + BOOL allowOption = FALSE, + int exitCode = 1); + +#define SAssert(x) { if ( !(x) ) SErrDisplayError(STORM_ERROR_ASSERTION, __FILE__, __LINE__, #x) } + +#define SEDisplayError(err) SErrDisplayError(e, __FILE__, __LINE__) + +/* SErrGetErrorStr @ 462 + * + * Retrieves a string that describes the specified error code for + * the system, Storm, DirectDraw, or DirectSound. + * + * dwErrCode: The error code to look up. + * buffer: The destination buffer to receive the string. + * bufferchars: The size of the destination buffer. + * + * Returns TRUE if the call was successful and FALSE otherwise. + */ +BOOL +STORMAPI +SErrGetErrorStr( + DWORD dwErrCode, + char *buffer, + size_t bufferchars); + +#define SEGetErrorStr(e,b) SErrGetErrorStr(e,b,sizeof(b)) + + +/* SErrGetLastError @ 463 + * + * Retrieves the last error that was specifically + * set for the Storm library. + * + * Returns the last error set within the Storm library. + */ +DWORD +STORMAPI +SErrGetLastError(); + + +// Registers a module as a message source for SErrGetErrorStr, always returns TRUE +// groupID is a group in a MessageTable entry for example in STORM_ERROR_BAD_ARGUMENT 0x85100065, 0x510 is the group. +// BOOL STORMAPI SErrRegisterMessageSource(WORD groupID, HMODULE hSourceModule, int a3) + + +/* SErrSetLastError @ 465 + * + * Sets the last error for the Storm library and the Kernel32 library. + * + * dwErrCode: The error code that will be set. + */ +void +STORMAPI +SErrSetLastError( + DWORD dwErrCode = NO_ERROR); + +// +// void STORMAPI SErrReportNamedResourceLeak(const char *pszMsg, const char *pszSubMsg = nullptr) +// void STORMAPI SErrReportResourceLeak(const char *pszMsg) + +void STORMAPI SErrSuppressErrors(BOOL suppressErrors); + +// Values for dwErrCode +#define STORM_ERROR_ASSERTION 0x85100000 +#define STORM_ERROR_BAD_ARGUMENT 0x85100065 +#define STORM_ERROR_GAME_ALREADY_STARTED 0x85100066 +#define STORM_ERROR_GAME_FULL 0x85100067 +#define STORM_ERROR_GAME_NOT_FOUND 0x85100068 +#define STORM_ERROR_GAME_TERMINATED 0x85100069 +#define STORM_ERROR_INVALID_PLAYER 0x8510006a +#define STORM_ERROR_NO_MESSAGES_WAITING 0x8510006b +#define STORM_ERROR_NOT_ARCHIVE 0x8510006c +#define STORM_ERROR_NOT_ENOUGH_ARGUMENTS 0x8510006d +#define STORM_ERROR_NOT_IMPLEMENTED 0x8510006e +#define STORM_ERROR_NOT_IN_ARCHIVE 0x8510006f +#define STORM_ERROR_NOT_IN_GAME 0x85100070 +#define STORM_ERROR_NOT_INITIALIZED 0x85100071 +#define STORM_ERROR_NOT_PLAYING 0x85100072 +#define STORM_ERROR_NOT_REGISTERED 0x85100073 +#define STORM_ERROR_REQUIRES_CODEC1 0x85100074 +#define STORM_ERROR_REQUIRES_CODEC2 0x85100075 +#define STORM_ERROR_REQUIRES_CODEC3 0x85100076 +#define STORM_ERROR_REQUIRES_UPGRADE 0x85100077 +#define STORM_ERROR_STILL_ACTIVE 0x85100078 +#define STORM_ERROR_VERSION_MISMATCH 0x85100079 +#define STORM_ERROR_MEM_NOT_ALLOCATED 0x8510007a +#define STORM_ERROR_MEM_CORRUPTED 0x8510007b +#define STORM_ERROR_MEM_INVALID 0x8510007c +#define STORM_ERROR_MEM_MANAGER_NOT_INITIALIZED 0x8510007d +#define STORM_ERROR_MEM_NOT_FREED 0x8510007e +#define STORM_ERROR_RESOURCES_NOT_RELEASED 0x8510007f +#define STORM_ERROR_OUT_OF_BOUNDS 0x85100080 +#define STORM_ERROR_NULL_POINTER 0x85100081 +#define STORM_ERROR_CDKEY_MISMATCH 0x85100082 +#define STORM_ERROR_FILE_CORRUPTED 0x85100083 +#define STORM_ERROR_FATAL 0x85100084 +#define STORM_ERROR_GAMETYPE_UNAVAILABLE 0x85100085 + + +/* SMemCopy @ 491 + * + * Copies a block of memory from source to destination. + * This function immediately calls memcpy. See online documentation + * of memcpy for more details. + * + * dest: The destination buffer. + * source: The source buffer. + * size: The number of bytes to copy. + */ +void +STORMAPI +SMemCopy( + void *dest, + const void *source, + size_t size); + +#define SMCopy(d,s) ( SMemCopy(d, s, __STORM_SSIZEMIN(s,d)) ) + +/* SMemFill @ 492 + * + * Fills a block of memory with the specified character. + * This function immediately calls memset. See online documentation + * of memset for more details. + * + * dest: The destination buffer. + * source: The size of the destination buffer. + * size: The format to use. + */ +void +STORMAPI +SMemFill( + void *location, + size_t length, + char fillWith = 0); + +#define SMFill(l,f) (SMemFill(l, sizeof(l), f)) + +/* SMemZero @ 494 + * + * Fills a block of memory with the integer 0x00 (Zero). + * + * location: The location to write at. + * length: The amount of bytes to write. + */ +void +STORMAPI +SMemZero( + void *location, + size_t length); + +#define SMZero(l) (SMemZero(l, sizeof(l))) + + +int STORMAPI SMemCmp(void *location1, void *location2, DWORD size); + +#define SMCmp(l,x) ( SMemCmp(l, x, __STORM_SSIZEMIN(x,l)) ) + +/* SStrCopy @ 501 + * + * Copies a string from src to dest (including NULL terminator) + * until the max_length is reached. + * + * dest: The destination array. + * src: The source array. + * max_length: The maximum length of dest. + * + * Returns the number of characters copied. + */ +int +STORMAPI +SStrCopy( + char *dest, + const char *src, + int max_length = 0x7FFFFFFF); + +#define SSCopy(d,s) (SStrCopy(d, s, sizeof(d))) + +#define STORM_HASH_ABSOLUTE 1 + +/* SStrHash @ 502 + * + * Creates a simple hash for the string. This function + * should NOT be used for sensitive information. + * + * string: The input string. + * flags: If STORM_HASH_ABSOLUTE is set then this + function uses the absolute string, otherwise + it will convert backslashes to forward + slashes and some other processing. + * seed: The hash seed. If this value is 0 then the + * default value 0x7FED7FED will be used. + * + * Returns the 32-bit hash of the string. + */ +DWORD +STORMAPI +SStrHash( + const char *string, + DWORD flags = 0, + DWORD Seed = 0); + +int STORMAPI SStrNCat(char *dest, const char *src, DWORD max_length); + +/* SStrLen @ 506 + * + * Retrieves the length of a string. + * + * string: The input string of which to obtain a + * length for. + * + * Returns the length of the string. + */ +int +STORMAPI +SStrLen( + const char *string); + +/* SStrCmp @ 508 + * + * Compares two strings case sensitive. + * + * string1: The first string. + * string2: The second string. + * size: The maximum amount of characters to compare. + * + * Returns 0 if strings are equal. See strcmp documentation for more details. + */ +int +STORMAPI +SStrCmp( + const char *string1, + const char *string2, + size_t size); + +#define SSCmp(s,x) ( SStrCmp(s,x,__STORM_SSIZEMIN(s,x)) ) + +/* SStrCmpI @ 509 + * + * Compares two strings case insensitive. + * + * string1: The first string. + * string2: The second string. + * size: The maximum amount of characters to compare. + * + * Returns 0 if strings are equal. See strcmpi documentation for more details. + */ +int +STORMAPI +SStrCmpI( + const char *string1, + const char *string2, + size_t size); + +#define SSCmpI(s,x) ( SStrCmpI(s,x,__STORM_SSIZEMIN(s,x)) ) + +/* SStrUpper @ 510 + * + * Converts all lower-case alpha characters of a string to upper-case. + * + * string: The string to convert. + * + * Returns the same pointer given in the input. + */ +char* +STORMAPI +SStrUpper( + char* string); + +void STORMAPI SRgn523(HANDLE hRgn, RECT *pRect, int a3, int a4); +void STORMAPI SRgnCreateRegion(HANDLE *hRgn, int a2); +void STORMAPI SRgnDeleteRegion(HANDLE hRgn); + +void STORMAPI SRgn529i(int handle, int a2, int a3); + + +/* SErrDisplayErrorFmt @ 562 + * + * Displays a formatted error message. The message is detailed and flexible for many applications. + * The message will be different if there is a debugger attached. Will typically terminate the application + * unless the option to continue is given. + * + * dwErrMessage: The error code. See SErrGetLastError and GetLastError. + * logfilename: The name of the file or object that this call belongs to. + * logline: The line in the file or one of the SLOG_ macros. + * allowOption: If TRUE, allows the user the option to continue execution, otherwise the program will terminate. + * exitCode: The exit code used for program termination. + * format: Additional message formatting. See printf. + * + * Returns TRUE if the user chose to continue execution, FALSE otherwise. + */ +BOOL +SErrDisplayErrorFmt( + DWORD dwErrMsg, + const char *logfilename, + int logline, + BOOL allowOption, + int exitCode, + const char *format, + ...); + +//#define SEDisplayErrorFmt(err,...) SErrDisplayErrorFmt(err, __FILE__, __LINE__, FALSE, 1, __VA_ARGS__) + +/* SErrCatchUnhandledExceptions @ 567 + * + * Registers a top-level exception filter managed entirely by Storm. + * The registered filter will display formatted exception information by calling SErrDisplayError. + */ +void +STORMAPI +SErrCatchUnhandledExceptions(); + + +/* SStrChr @ 571 + * + * Searches a string for the given character. See + * strchr documentation for more details. + * + * string: The string to search. + * c: The character to search for. + * + * Returns a pointer to the first occurance of the character. + */ +char* +STORMAPI +SStrChr( + const char *string, + char c); + + +char *STORMAPI SStrChrR(const char *string, char c); + + +/* SStrVPrintf @ 578 + * + * Prints a formatted string to a destination buffer. + * This function calls vsnprintf with some extra error handling. + * See online documentation of vsnprintf for more details. + * + * dest: The destination buffer. + * size: The size of the destination buffer. + * format: The format to use. + * + * Returns the number of characters written. + */ +size_t +SStrVPrintf( + char *dest, + size_t size, + const char *format, ...); + + +int STORMAPI SBigDel(void *buffer); + +int STORMAPI SBigFromBinary(void *buffer, const void *str, size_t size); + +int STORMAPI SBigNew(void **buffer); + +int STORMAPI SBigPowMod(void *buffer1, void *buffer2, int a3, int a4); + +int STORMAPI SBigToBinaryBuffer(void *buffer, int length, int a3, int a4); + + +bool StormDestroy(); +void SDrawDestroy(); +bool __stdcall SFileSetBasePath(char *base_dir); +void SDrawRealizePalette(); +bool SVidPlayContinue(); +bool __stdcall SNetGetOwnerTurnsWaiting(int *turns); +bool __stdcall SNetSetBasePlayer(int base_player_num); +int __stdcall SFileSetFilePointer(int file1, int offset, int file2, int whence); + +void __stdcall SDrawMessageBox(char *text, char *caption, int type); +#endif diff --git a/2018_03_14/DiabDev/storm.lib b/2018_03_14/DiabDev/storm.lib new file mode 100644 index 00000000..0ff1de84 Binary files /dev/null and b/2018_03_14/DiabDev/storm.lib differ diff --git a/2018_03_14/DiabloUI/DiabloUI.cpp b/2018_03_14/DiabloUI/DiabloUI.cpp new file mode 100644 index 00000000..ac5c8375 --- /dev/null +++ b/2018_03_14/DiabloUI/DiabloUI.cpp @@ -0,0 +1,80 @@ +// DiabloUI.cpp : Defines the entry point for the DLL application. +// + +#include "stdafx.h" +#include "DiabloUI.h" + +BOOL APIENTRY DllMain( HANDLE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved + ) +{ + switch (ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + break; + } + return TRUE; +} + + +// This is an example of an exported variable +DIABLOUI_API int nDiabloUI=0; + +// This is an example of an exported function. +DIABLOUI_API int fnDiabloUI(void) +{ + return 42; +} + +// This is the constructor of a class that has been exported. +// see DiabloUI.h for the class definition +CDiabloUI::CDiabloUI() +{ + return; +} + +struct _SNETPROGRAMDATA { + int a1; +}; +struct _SNETPLAYERDATA { + int a1; +}; +struct _SNETUIDATA { + int a1; +}; +struct _SNETVERSIONDATA { + int a1; +}; +struct _uiheroinfo { + int a1; +}; +void __cdecl UiDestroy() { return; } +void __cdecl UiTitleDialog(int a1) { return; } +void __cdecl UiInitialize() { return; } +void __stdcall UiCopyProtError(int a1) { return; } +void __stdcall UiAppActivate(int a1) { return; } +int __stdcall UiValidPlayerName(char *a1) { return 0; } +int __stdcall UiSelHeroMultDialog(void *fninfo, void *fncreate, void *fnremove, void *fnstats, int *a5, int *a6, char *name) { return 0; } +int __stdcall UiSelHeroSingDialog(void *fninfo, void *fncreate, void *fnremove, void *fnstats, int *a5, char *name, int *difficulty) { return 0; } +void __stdcall UiCreditsDialog(int a1) { return; } +int __stdcall UiMainMenuDialog(char *name, int *a2, void *fnSound, int a4) { return 0; } +int __stdcall UiProgressDialog(HWND window, char *msg, int a3, void *fnfunc, int a5) { return 0; } +void __cdecl UiProfileGetString() { return; } +void __cdecl UiProfileCallback() { return; } +void __cdecl UiProfileDraw() { return; } +void __cdecl UiCategoryCallback() { return; } +void __cdecl UiGetDataCallback() { return; } +void __cdecl UiAuthCallback() { return; } +void __cdecl UiSoundCallback() { return; } +void __cdecl UiMessageBoxCallback() { return; } +void __cdecl UiDrawDescCallback() { return; } +void __cdecl UiCreateGameCallback() { return; } +void __cdecl UiArtCallback() { return; } +int __stdcall UiSelectGame(int a1, _SNETPROGRAMDATA *client_info, _SNETPLAYERDATA *user_info, _SNETUIDATA *ui_info, _SNETVERSIONDATA *file_info, int *a6) { return 0; } +int __stdcall UiSelectProvider(int a1, _SNETPROGRAMDATA *client_info, _SNETPLAYERDATA *user_info, _SNETUIDATA *ui_info, _SNETVERSIONDATA *file_info, int *type) { return 0; } +int __stdcall UiCreatePlayerDescription(_uiheroinfo *info, int mode, char *desc) { return 0; } +int __stdcall UiSetupPlayerInfo(char *str, _uiheroinfo *info, int mode) { return 0; } diff --git a/2018_03_14/DiabloUI/DiabloUI.dsp b/2018_03_14/DiabloUI/DiabloUI.dsp new file mode 100644 index 00000000..d37a08f4 --- /dev/null +++ b/2018_03_14/DiabloUI/DiabloUI.dsp @@ -0,0 +1,124 @@ +# Microsoft Developer Studio Project File - Name="DiabloUI" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=DiabloUI - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "DiabloUI.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "DiabloUI.mak" CFG="DiabloUI - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "DiabloUI - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "DiabloUI - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "DiabloUI - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "DIABLOUI_EXPORTS" /Yu"stdafx.h" /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "DIABLOUI_EXPORTS" /Yu"stdafx.h" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 + +!ELSEIF "$(CFG)" == "DiabloUI - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "DIABLOUI_EXPORTS" /Yu"stdafx.h" /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "DIABLOUI_EXPORTS" /Yu"stdafx.h" /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /def:"diabloui.def" /pdbtype:sept +# SUBTRACT LINK32 /pdb:none + +!ENDIF + +# Begin Target + +# Name "DiabloUI - Win32 Release" +# Name "DiabloUI - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\DiabloUI.cpp +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.cpp +# ADD CPP /Yc"stdafx.h" +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\DiabloUI.h +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# Begin Source File + +SOURCE=.\ReadMe.txt +# End Source File +# End Target +# End Project diff --git a/2018_03_14/DiabloUI/DiabloUI.dsw b/2018_03_14/DiabloUI/DiabloUI.dsw new file mode 100644 index 00000000..abf01add --- /dev/null +++ b/2018_03_14/DiabloUI/DiabloUI.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "DiabloUI"=.\DiabloUI.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/2018_03_14/DiabloUI/DiabloUI.h b/2018_03_14/DiabloUI/DiabloUI.h new file mode 100644 index 00000000..62050705 --- /dev/null +++ b/2018_03_14/DiabloUI/DiabloUI.h @@ -0,0 +1,24 @@ + +// The following ifdef block is the standard way of creating macros which make exporting +// from a DLL simpler. All files within this DLL are compiled with the DIABLOUI_EXPORTS +// symbol defined on the command line. this symbol should not be defined on any project +// that uses this DLL. This way any other project whose source files include this file see +// DIABLOUI_API functions as being imported from a DLL, wheras this DLL sees symbols +// defined with this macro as being exported. +#ifdef DIABLOUI_EXPORTS +#define DIABLOUI_API __declspec(dllexport) +#else +#define DIABLOUI_API __declspec(dllimport) +#endif + +// This class is exported from the DiabloUI.dll +class DIABLOUI_API CDiabloUI { +public: + CDiabloUI(void); + // TODO: add your methods here. +}; + +extern DIABLOUI_API int nDiabloUI; + +DIABLOUI_API int fnDiabloUI(void); + diff --git a/2018_03_14/DiabloUI/ReadMe.txt b/2018_03_14/DiabloUI/ReadMe.txt new file mode 100644 index 00000000..85e02870 --- /dev/null +++ b/2018_03_14/DiabloUI/ReadMe.txt @@ -0,0 +1,37 @@ +======================================================================== + DYNAMIC LINK LIBRARY : DiabloUI +======================================================================== + + +AppWizard has created this DiabloUI DLL for you. + +This file contains a summary of what you will find in each of the files that +make up your DiabloUI application. + +DiabloUI.dsp + This file (the project file) contains information at the project level and + is used to build a single project or subproject. Other users can share the + project (.dsp) file, but they should export the makefiles locally. + +DiabloUI.cpp + This is the main DLL source file. + +DiabloUI.h + This file contains your DLL exports. + +///////////////////////////////////////////////////////////////////////////// +Other standard files: + +StdAfx.h, StdAfx.cpp + These files are used to build a precompiled header (PCH) file + named DiabloUI.pch and a precompiled types file named StdAfx.obj. + + +///////////////////////////////////////////////////////////////////////////// +Other notes: + +AppWizard uses "TODO:" to indicate parts of the source code you +should add to or customize. + + +///////////////////////////////////////////////////////////////////////////// diff --git a/2018_03_14/DiabloUI/StdAfx.cpp b/2018_03_14/DiabloUI/StdAfx.cpp new file mode 100644 index 00000000..219dbfe3 --- /dev/null +++ b/2018_03_14/DiabloUI/StdAfx.cpp @@ -0,0 +1,8 @@ +// stdafx.cpp : source file that includes just the standard includes +// DiabloUI.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + +// TODO: reference any additional headers you need in STDAFX.H +// and not in this file diff --git a/2018_03_14/DiabloUI/StdAfx.h b/2018_03_14/DiabloUI/StdAfx.h new file mode 100644 index 00000000..f63f043a --- /dev/null +++ b/2018_03_14/DiabloUI/StdAfx.h @@ -0,0 +1,24 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#if !defined(AFX_STDAFX_H__00D95503_7CAF_44D4_9FCA_8D0EC8F2FF23__INCLUDED_) +#define AFX_STDAFX_H__00D95503_7CAF_44D4_9FCA_8D0EC8F2FF23__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + + +// Insert your headers here +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers + +#include + +// TODO: reference additional headers your program requires here + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_STDAFX_H__00D95503_7CAF_44D4_9FCA_8D0EC8F2FF23__INCLUDED_) diff --git a/2018_03_14/DiabloUI/diabloui.def b/2018_03_14/DiabloUI/diabloui.def new file mode 100644 index 00000000..1bd12cfe --- /dev/null +++ b/2018_03_14/DiabloUI/diabloui.def @@ -0,0 +1,29 @@ +LIBRARY "DiabloUI" + +EXPORTS + UiDestroy + UiTitleDialog + UiInitialize + UiCopyProtError + UiAppActivate + UiValidPlayerName + UiSelHeroMultDialog + UiSelHeroSingDialog + UiCreditsDialog + UiMainMenuDialog + UiProgressDialog + UiProfileGetString + UiProfileCallback + UiProfileDraw + UiCategoryCallback + UiGetDataCallback + UiAuthCallback + UiSoundCallback + UiMessageBoxCallback + UiDrawDescCallback + UiCreateGameCallback + UiArtCallback + UiSelectGame + UiSelectProvider + UiCreatePlayerDescription + UiSetupPlayerInfo diff --git a/2018_03_14/storm/ReadMe.txt b/2018_03_14/storm/ReadMe.txt new file mode 100644 index 00000000..028b8e25 --- /dev/null +++ b/2018_03_14/storm/ReadMe.txt @@ -0,0 +1,41 @@ +======================================================================== + DYNAMIC LINK LIBRARY : storm +======================================================================== + + +AppWizard has created this storm DLL for you. + +This file contains a summary of what you will find in each of the files that +make up your storm application. + +storm.dsp + This file (the project file) contains information at the project level and + is used to build a single project or subproject. Other users can share the + project (.dsp) file, but they should export the makefiles locally. + +storm.cpp + This is the main DLL source file. + + When created, this DLL does not export any symbols. As a result, it + will not produce a .lib file when it is built. If you wish this project + to be a project dependency of some other project, you will either need to + add code to export some symbols from the DLL so that an export library + will be produced, or you can check the "doesn't produce lib" checkbox in + the Linker settings page for this project. + +///////////////////////////////////////////////////////////////////////////// +Other standard files: + +StdAfx.h, StdAfx.cpp + These files are used to build a precompiled header (PCH) file + named storm.pch and a precompiled types file named StdAfx.obj. + + +///////////////////////////////////////////////////////////////////////////// +Other notes: + +AppWizard uses "TODO:" to indicate parts of the source code you +should add to or customize. + + +///////////////////////////////////////////////////////////////////////////// diff --git a/2018_03_14/storm/StdAfx.cpp b/2018_03_14/storm/StdAfx.cpp new file mode 100644 index 00000000..9a7784ce --- /dev/null +++ b/2018_03_14/storm/StdAfx.cpp @@ -0,0 +1,8 @@ +// stdafx.cpp : source file that includes just the standard includes +// storm.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + +// TODO: reference any additional headers you need in STDAFX.H +// and not in this file diff --git a/2018_03_14/storm/StdAfx.h b/2018_03_14/storm/StdAfx.h new file mode 100644 index 00000000..4b8adeb5 --- /dev/null +++ b/2018_03_14/storm/StdAfx.h @@ -0,0 +1,24 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#if !defined(AFX_STDAFX_H__2197EABE_2E6C_4E93_90B8_DA67E0A2C425__INCLUDED_) +#define AFX_STDAFX_H__2197EABE_2E6C_4E93_90B8_DA67E0A2C425__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + + +// Insert your headers here +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers + +#include + +// TODO: reference additional headers your program requires here + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_STDAFX_H__2197EABE_2E6C_4E93_90B8_DA67E0A2C425__INCLUDED_) diff --git a/2018_03_14/storm/Storm.vcproj b/2018_03_14/storm/Storm.vcproj new file mode 100644 index 00000000..223067ec --- /dev/null +++ b/2018_03_14/storm/Storm.vcproj @@ -0,0 +1,139 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/2018_03_14/storm/storm.cpp b/2018_03_14/storm/storm.cpp new file mode 100644 index 00000000..8aae3d4d --- /dev/null +++ b/2018_03_14/storm/storm.cpp @@ -0,0 +1,238 @@ +#include "storm.h" + +#define rBool { return TRUE; } +#define rPVoid { return NULL; } +#define rVoid { return; } +#define rInt { return 0; } + +BOOL STORMAPI SNetCreateGame(const char *pszGameName, const char *pszGamePassword, const char *pszGameStatString, DWORD dwGameType, char *GameTemplateData, int GameTemplateSize, int playerCount, char *creatorName, char *a11, int *playerID) rBool; +BOOL STORMAPI SNetDestroy() rBool; +BOOL STORMAPI SNetEnumProviders(int (STORMAPI *callback)(DWORD, DWORD, DWORD, DWORD), int mincaps) rBool; + +BOOL STORMAPI SNetEnumGames(int (STORMAPI *callback)(DWORD, DWORD, DWORD), int *hintnextcall) rBool; +BOOL STORMAPI SNetDropPlayer(int playerid, DWORD flags) rBool; +BOOL STORMAPI SNetGetGameInfo(int type, void *dst, size_t length, size_t *byteswritten) rBool; + +BOOL STORMAPI SNetGetNumPlayers(int *firstplayerid, int *lastplayerid, int *activeplayers) rBool; + +BOOL STORMAPI SNetGetPlayerCaps(char playerid, PCAPS playerCaps) rBool; +BOOL STORMAPI SNetGetPlayerName(int playerid, char *buffer, size_t buffersize) rBool; +//BOOL STORMAPI SNetGetProviderCaps(PCAPS providerCaps) rBool; +BOOL STORMAPI SNetGetTurnsInTransit(int *turns) rBool; +BOOL STORMAPI SNetInitializeDevice(int a1, int a2, int a3, int a4, int *a5) rBool; +//BOOL STORMAPI SNetInitializeProvider(DWORD providerName, client_info *gameClientInfo, user_info *userData, battle_info *bnCallbacks, module_info *moduleData) rBool; +BOOL STORMAPI SNetJoinGame(int id, char *gameName, char *gamePassword, char *playerName, char *userStats, int *playerid) rBool; +BOOL STORMAPI SNetLeaveGame(int type) rBool; +BOOL STORMAPI SNetPerformUpgrade(DWORD *upgradestatus) rBool; +BOOL STORMAPI SNetReceiveMessage(int *senderplayerid, char **data, int *databytes) rBool; +BOOL STORMAPI SNetReceiveTurns(int a1, int arraysize, char **arraydata, unsigned int *arraydatabytes, DWORD *arrayplayerstatus) rBool; +//HANDLE STORMAPI SNetRegisterEventHandler(int type, void (STORMAPI *sEvent)(PS_EVT)) rPVoid; + +int STORMAPI SNetSelectGame(int a1, int a2, int a3, int a4, int a5, int *playerid) rInt; + +BOOL STORMAPI SNetSendMessage(int playerID, void *data, size_t databytes) rBool; +BOOL STORMAPI SNetSendTurn(char *data, size_t databytes) rBool; + +BOOL STORMAPI SNetSetGameMode(DWORD modeFlags, bool makePublic) rBool; + +BOOL STORMAPI SNetEnumGamesEx(int a1, int a2, int (__fastcall *callback)(DWORD, DWORD, DWORD), int *hintnextcall) rBool; +BOOL STORMAPI SNetSendServerChatCommand(const char *command) rBool; + +BOOL STORMAPI SNetDisconnectAll(DWORD flags) rBool; +BOOL STORMAPI SNetCreateLadderGame(const char *pszGameName, const char *pszGamePassword, const char *pszGameStatString, DWORD dwGameType, DWORD dwGameLadderType, DWORD dwGameModeFlags, char *GameTemplateData, int GameTemplateSize, int playerCount, char *creatorName, char *a11, int *playerID) rBool; +BOOL STORMAPI SNetReportGameResult(unsigned a1, int size, int *results, const char* headerInfo, const char* detailInfo) rBool; + +int STORMAPI SNetSendLeagueCommand(char *cmd, char *callback) rInt; +int STORMAPI SNetSendReplayPath(int a1, int a2, char *replayPath) rInt; +int STORMAPI SNetGetLeagueName(int leagueID) rInt; +BOOL STORMAPI SNetGetPlayerNames(char **names) rBool; +int STORMAPI SNetLeagueLogout(char *bnetName) rInt; +int STORMAPI SNetGetLeaguePlayerName(char *curPlayerLeageName, size_t nameSize) rInt; + +HGDIOBJ STORMAPI SDlgDefDialogProc(HWND hDlg, signed int DlgType, HDC textLabel, HWND hWnd) rPVoid; + +HANDLE STORMAPI SDlgDialogBoxIndirectParam(HMODULE hModule, LPCSTR lpName, HWND hWndParent, LPVOID lpParam, LPARAM lParam) rPVoid; + +BOOL STORMAPI SDlgEndDialog(HWND hDlg, HANDLE nResult) rBool; + +BOOL STORMAPI SDlgSetControlBitmaps(HWND parentwindow, int *id, int a3, char *buffer2, char *buffer, int flags, int mask) rBool; + +BOOL STORMAPI SDlgBltToWindowE(HWND hWnd, HRGN a2, char *a3, int a4, void *buffer, RECT *rct, SIZE *size, int a8, int a9, DWORD rop) rBool; +BOOL STORMAPI SDlgSetBitmapE(HWND hWnd, int a2, char *src, int mask1, int flags, int a6, int a7, int width, int a9, int mask2) rBool; + +int STORMAPI Ordinal224(int a1) rInt; + +BOOL STORMAPI SFileCloseArchive(HANDLE hArchive) rBool; +BOOL STORMAPI SFileCloseFile(HANDLE hFile) rBool; + +BOOL STORMAPI SFileDdaBeginEx(HANDLE directsound, DWORD flags, DWORD mask, unsigned __int32 lDistanceToMove, signed __int32 volume, signed int a6, int a7) rBool; +BOOL STORMAPI SFileDdaDestroy() rBool; +BOOL STORMAPI SFileDdaEnd(HANDLE directsound) rBool; +BOOL STORMAPI SFileDdaGetPos(HANDLE directsound, int a2, int a3) rBool; + +BOOL STORMAPI SFileDdaInitialize(HANDLE directsound) rBool; +BOOL STORMAPI SFileDdaSetVolume(HANDLE directsound, signed int bigvolume, signed int volume) rBool; +BOOL STORMAPI SFileDestroy() rBool; + +BOOL STORMAPI SFileGetFileArchive(HANDLE hFile, HANDLE archive) rBool; +LONG STORMAPI SFileGetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh) rInt; +BOOL STORMAPI SFileOpenArchive(const char *szMpqName, DWORD dwPriority, DWORD dwFlags, HANDLE *phMpq) rBool; +BOOL STORMAPI SFileOpenFile(const char *filename, HANDLE *phFile) rBool; +BOOL STORMAPI SFileOpenFileEx(HANDLE hMpq, const char *szFileName, DWORD dwSearchScope, HANDLE *phFile) rBool; +BOOL STORMAPI SFileReadFile(HANDLE hFile, void *buffer, DWORD nNumberOfBytesToRead, DWORD *read, LONG lpDistanceToMoveHigh) rBool; + +void STORMAPI SFileSetLocale(LCID lcLocale) rVoid; + +BOOL STORMAPI SFileSetIoErrorMode(int mode, BOOL (STORMAPI *callback)(char*,int,int) ) rBool; +BOOL STORMAPI SFileGetArchiveName(HANDLE hArchive, char *name, int length) rBool; +BOOL STORMAPI SFileGetFileName(HANDLE hFile, char *buffer, int length) rBool; + +BOOL STORMAPI SFileLoadFile(char *filename, void *buffer, int buffersize, int a4, int a5) rBool; +BOOL STORMAPI SFileUnloadFile(HANDLE hFile) rBool; +BOOL STORMAPI SFileLoadFileEx(void *hArchive, char *filename, int a3, int a4, int a5, DWORD searchScope, struct _OVERLAPPED *lpOverlapped) rBool; + +BOOL STORMAPI SBltROP3(void *lpDstBuffer, void *lpSrcBuffer, int width, int height, int a5, int a6, int a7, DWORD rop) rBool; +BOOL STORMAPI SBltROP3Clipped(void *lpDstBuffer, RECT *lpDstRect, POINT *lpDstPt, int a4, void *lpSrcBuffer, RECT *lpSrcRect, POINT *lpSrcPt, int a8, int a9, DWORD rop) rBool; + +BOOL STORMAPI SBmpDecodeImage(DWORD dwImgType, void *pSrcBuffer, DWORD dwSrcBuffersize, PALETTEENTRY *pPalette, void *pDstBuffer, DWORD dwDstBuffersize, DWORD *pdwWidth, DWORD *pdwHeight, DWORD *pdwBpp) rBool; + +BOOL STORMAPI SBmpLoadImage(const char *pszFileName, PALETTEENTRY *pPalette, void *pBuffer, DWORD dwBuffersize, DWORD *pdwWidth, DWORD *dwHeight, DWORD *pdwBpp) rBool; + +BOOL STORMAPI SBmpSaveImage(const char*, PALETTEENTRY*, void*, DWORD, DWORD, DWORD) rBool; +HANDLE STORMAPI SBmpAllocLoadImage(const char *fileName, PALETTEENTRY *palette, void **buffer, int *width, int *height, int unused6, int unused7, void *(STORMAPI *allocFunction)(DWORD)) rPVoid; + +BOOL STORMAPI SCodeCompile(char *directives1, char *directives2, char *loopstring, unsigned int maxiterations, unsigned int flags, HANDLE handle) rBool; +BOOL STORMAPI SCodeDelete(HANDLE handle) rBool; + +int STORMAPI SCodeExecute(HANDLE handle, int a2) rInt; + +BOOL STORMAPI SDrawAutoInitialize(HINSTANCE hInst, LPCSTR lpClassName, LPCSTR lpWindowName, WNDPROC pfnWndProc, int nMode, int nWidth, int nHeight, int nBits) rBool; +BOOL STORMAPI SDrawCaptureScreen(const char *source) rBool; + +HWND STORMAPI SDrawGetFrameWindow(HWND *sdraw_framewindow) rPVoid; +BOOL STORMAPI SDrawGetObjects(LPDIRECTDRAW *ddInterface, LPDIRECTDRAWSURFACE *primarySurface, LPDIRECTDRAWSURFACE *surface2, LPDIRECTDRAWSURFACE *surface3, LPDIRECTDRAWSURFACE *backSurface, LPDIRECTDRAWPALETTE *ddPalette, HPALETTE *hPalette) rBool; +BOOL STORMAPI SDrawGetScreenSize(DWORD *pdwWidth, DWORD *pdwHeight, DWORD *pdwBpp) rBool; + +BOOL STORMAPI SDrawLockSurface(int surfacenumber, RECT *lpDestRect, void **lplpSurface, int *lpPitch, int arg_unused) rBool; +BOOL STORMAPI SDrawManualInitialize(HWND hWnd, LPDIRECTDRAW ddInterface, LPDIRECTDRAWSURFACE primarySurface, LPDIRECTDRAWSURFACE surface2, LPDIRECTDRAWSURFACE surface3, LPDIRECTDRAWSURFACE backSurface, LPDIRECTDRAWPALETTE ddPalette, HPALETTE hPalette) rBool; + +BOOL STORMAPI SDrawPostClose() rBool; +//BOOL STORMAPI SDrawRealizePalette() rBool; + +BOOL STORMAPI SDrawUnlockSurface(int surfacenumber, void *lpSurface, int a3, RECT *lpRect) rBool; +BOOL STORMAPI SDrawUpdatePalette(unsigned int firstentry, unsigned int numentries, PALETTEENTRY *pPalEntries, int a4) rBool; + +BOOL STORMAPI SEvtDispatch(DWORD dwMessageID, DWORD dwFlags, int type, PS_EVT pEvent) rBool; + +BOOL STORMAPI SGdiDeleteObject(HANDLE handle) rBool; + +BOOL STORMAPI SGdiExtTextOut(int a1, int a2, int a3, int a4, unsigned int a8, signed int a6, signed int a7, const char *string, unsigned int arg20) rBool; +BOOL STORMAPI SGdiImportFont(HGDIOBJ handle, int windowsfont) rBool; + +BOOL STORMAPI SGdiSelectObject(int handle) rBool; +BOOL STORMAPI SGdiSetPitch(int pitch) rBool; + +BOOL STORMAPI Ordinal393(char *string, int, int) rBool; + +void* STORMAPI SMemAlloc(size_t amount, char *logfilename, int logline, char defaultValue) rPVoid; + +BOOL STORMAPI SMemFree(void *location, char *logfilename, int logline, char defaultValue) rBool; + +void* STORMAPI SMemReAlloc(void *location, size_t amount, char *logfilename, int logline, char defaultValue) rPVoid; + +BOOL STORMAPI SRegLoadData(const char *keyname, const char *valuename, int size, LPBYTE lpData, BYTE flags, LPDWORD lpcbData) rBool; +BOOL STORMAPI SRegLoadString(const char *keyname, const char *valuename, BYTE flags, char *buffer, size_t buffersize) rBool; +BOOL STORMAPI SRegLoadValue(const char *keyname, const char *valuename, BYTE flags, int *value) rBool; +BOOL STORMAPI SRegSaveData(const char *keyname, const char *valuename, int size, BYTE *lpData, DWORD cbData) rBool; +BOOL STORMAPI SRegSaveString(const char *keyname, const char *valuename, BYTE flags, char *string) rBool; +BOOL STORMAPI SRegSaveValue(const char *keyname, const char *valuename, BYTE flags, DWORD result) rBool; + +BOOL STORMAPI SRegDeleteValue(const char *keyname, const char *valuename, BYTE flags) rBool; + +BOOL STORMAPI STransBlt(void *lpSurface, int x, int y, int width, HANDLE hTrans) rBool; +BOOL STORMAPI STransBltUsingMask(void *lpSurface, void *lpSource, int pitch, int width, HANDLE hTrans) rBool; + +BOOL STORMAPI STransDelete(HANDLE hTrans) rBool; + +BOOL STORMAPI STransDuplicate(HANDLE hTransSource, HANDLE hTransDest) rBool; +BOOL STORMAPI STransIntersectDirtyArray(HANDLE hTrans, char * dirtyarraymask, unsigned flags, HANDLE * phTransResult) rBool; +BOOL STORMAPI STransInvertMask(HANDLE hTrans, HANDLE * phTransResult) rBool; + +BOOL STORMAPI STransSetDirtyArrayInfo(int width, int height, int depth, int bits) rBool; + +BOOL STORMAPI STransPointInMask(HANDLE hTrans, int x, int y) rBool; +BOOL STORMAPI STransCombineMasks(HANDLE hTransA, HANDLE hTransB, int left, int top, int flags, HANDLE * phTransResult) rBool; + +BOOL STORMAPI STransCreateE(void *pBuffer, int width, int height, int bpp, int a5, int bufferSize, HANDLE *phTransOut) rBool; + +BOOL STORMAPI SVidDestroy() rBool; +BOOL STORMAPI SVidGetSize(HANDLE video, int width, int height, int zero) rBool; +BOOL STORMAPI SVidInitialize(HANDLE video) rBool; +BOOL STORMAPI SVidPlayBegin(char *filename, int arg4, int a3, int a4, int a5, int a6, HANDLE* video) rBool; + +BOOL STORMAPI SVidPlayContinueSingle(HANDLE video, int a2, int a3) rBool; +BOOL STORMAPI SVidPlayEnd(HANDLE video) rBool; + +BOOL STORMAPI SErrDisplayError(DWORD dwErrMsg, const char *logfilename, int logline, const char *message, BOOL allowOption, int exitCode) rBool; +BOOL STORMAPI SErrGetErrorStr(DWORD dwErrCode, char *buffer, size_t bufferchars) rBool; +DWORD STORMAPI SErrGetLastError() rInt; + +void STORMAPI SErrSetLastError(DWORD dwErrCode) rVoid; + +void STORMAPI SErrSuppressErrors(BOOL suppressErrors) rVoid; + +void STORMAPI SMemCopy(void *dest, const void *source, size_t size) rVoid; +void STORMAPI SMemFill(void *location, size_t length, char fillWith) rVoid; + +void STORMAPI SMemZero(void *location, DWORD length) rVoid; +int STORMAPI SMemCmp(void *location1, void *location2, DWORD size) rInt; + +int STORMAPI SStrCopy(char *dest, const char *src, int max_length) rInt; +DWORD STORMAPI SStrHash(const char *string, DWORD flags, DWORD Seed) rInt; +int STORMAPI SStrNCat(char *dest, const char *src, DWORD max_length) rInt; + +int STORMAPI SStrLen(const char* string) rInt; + +int STORMAPI SStrCmp(const char *string1, const char *string2, size_t size) rInt; +int STORMAPI SStrCmpI(const char *string1, const char *string2, size_t size) rInt; +char* STORMAPI SStrUpper(char* string) rPVoid; + +void STORMAPI SRgn523(HANDLE hRgn, RECT *pRect, int a3, int a4) rVoid; +void STORMAPI SRgnCreateRegion(HANDLE *hRgn, int a2) rVoid; +void STORMAPI SRgnDeleteRegion(HANDLE hRgn) rVoid; + +void STORMAPI SRgn529i(int handle, int a2, int a3) rVoid; + +BOOL SErrDisplayErrorFmt(DWORD dwErrMsg, const char *logfilename, int logline, BOOL allowOption, int exitCode, const char *format, ...) rBool; + +void STORMAPI SErrCatchUnhandledExceptions() rVoid; + +char* STORMAPI SStrChr(const char *string, char c) rPVoid; +char* STORMAPI SStrChrR(const char *string, char c) rPVoid; + +size_t SStrVPrintf(char *dest, size_t size, const char *format, ...) rInt; + +int STORMAPI SBigDel(void *buffer) rInt; + +int STORMAPI SBigFromBinary(void *buffer, const void *str, size_t size) rInt; + +int STORMAPI SBigNew(void **buffer) rInt; + +int STORMAPI SBigPowMod(void *buffer1, void *buffer2, int a3, int a4) rInt; + +int STORMAPI SBigToBinaryBuffer(void *buffer, int length, int a3, int a4) rInt; +// + +void __stdcall SDrawMessageBox(char *,char *,int) rVoid; +void __cdecl SDrawDestroy(void) rVoid; +bool __cdecl StormDestroy(void) rBool; +bool __stdcall SFileSetBasePath(char *) rBool; +void __cdecl SDrawRealizePalette(void) rVoid; +bool __cdecl SVidPlayContinue(void) rBool; +bool __stdcall SNetGetOwnerTurnsWaiting(int *) rBool; +void * __stdcall SNetUnregisterEventHandler(int,void (__stdcall*)(struct _SNETEVENT *)) rPVoid; +void * __stdcall SNetRegisterEventHandler(int,void (__stdcall*)(struct _SNETEVENT *)) rPVoid; +bool __stdcall SNetSetBasePlayer(int) rBool; +int __stdcall SNetInitializeProvider(unsigned long,struct _SNETPROGRAMDATA *,struct _SNETPLAYERDATA *,struct _SNETUIDATA *,struct _SNETVERSIONDATA *) rInt; +int __stdcall SNetGetProviderCaps(struct _SNETCAPS *) rInt; +int __stdcall SFileSetFilePointer(int,int,int,int) rInt; \ No newline at end of file diff --git a/2018_03_14/storm/storm.def b/2018_03_14/storm/storm.def new file mode 100644 index 00000000..989059cd --- /dev/null +++ b/2018_03_14/storm/storm.def @@ -0,0 +1,441 @@ +LIBRARY "Storm" + +EXPORTS + SNetCreateGame @101 NONAME + SNetDestroy @102 NONAME + SNetEnumProviders @103 NONAME + ;SNetEnumDevices @104 NONAME + SNetEnumGames @105 NONAME + SNetDropPlayer @106 NONAME + SNetGetGameInfo @107 NONAME + ;SNetGetNetworkLatency @108 NONAME + SNetGetNumPlayers @109 NONAME + SNetGetOwnerTurnsWaiting @110 NONAME + ;SNetGetPerformanceData @111 NONAME + SNetGetPlayerCaps @112 NONAME + SNetGetPlayerName @113 NONAME + SNetGetProviderCaps @114 NONAME + SNetGetTurnsInTransit @115 NONAME + SNetInitializeDevice @116 NONAME + SNetInitializeProvider @117 NONAME + SNetJoinGame @118 NONAME + SNetLeaveGame @119 NONAME + SNetPerformUpgrade @120 NONAME + SNetReceiveMessage @121 NONAME + SNetReceiveTurns @122 NONAME + SNetRegisterEventHandler @123 NONAME + ;SNetResetLatencyMeasurements @124 NONAME + SNetSelectGame @125 NONAME + ;SNetSelectProvider @126 NONAME + SNetSendMessage @127 NONAME + SNetSendTurn @128 NONAME + SNetSetBasePlayer @129 NONAME + SNetSetGameMode @130 NONAME + SNetUnregisterEventHandler @131 NONAME + + SNetEnumGamesEx @133 NONAME + SNetSendServerChatCommand @134 NONAME + ;SNetSendDatagram @135 NONAME + ;SNetReceiveDatagram @136 NONAME + SNetDisconnectAll @137 NONAME + SNetCreateLadderGame @138 NONAME + SNetReportGameResult @139 NONAME + ;SNetCheckDataFile @140 NONAME + SNetSendLeagueCommand @141 NONAME + SNetSendReplayPath @142 NONAME + SNetGetLeagueName @143 NONAME + SNetGetPlayerNames @144 NONAME + SNetLeagueLogout @145 NONAME + SNetGetLeaguePlayerName @146 NONAME + + ;Ordinal150 @150 NONAME + ;Ordinal151 @151 NONAME + + ;SDlgBeginPaint @201 NONAME + ;SDlgBltToWindowI @202 NONAME + ;SDlgCheckTimers @203 NONAME + ;SDlgCreateDialogIndirectParam @204 NONAME + ;SDlgCreateDialogParam @205 NONAME + SDlgDefDialogProc @206 NONAME + + SDlgDialogBoxIndirectParam @208 NONAME + ;SDlgDialogBoxParam @209 NONAME + ;SDlgDrawBitmap @210 NONAME + SDlgEndDialog @211 NONAME + ;SDlgEndPaint @212 NONAME + ;SDlgKillTimer @213 NONAME + ;SDlgSetBaseFont @214 NONAME + ;SDlgSetBitmapI @215 NONAME + SDlgSetControlBitmaps @216 NONAME + ;SDlgSetCursor @217 NONAME + ;SDlgSetSystemCursor @218 NONAME + ;SDlgSetTimer @219 NONAME + ;SDlgUpdateCursor @220 NONAME + SDlgBltToWindowE @221 NONAME + SDlgSetBitmapE @222 NONAME + ;SDlgSetLocale @223 NONAME + Ordinal224 @224 NONAME + + ;SFileAuthenticateArchive @251 NONAME + SFileCloseArchive @252 NONAME + SFileCloseFile @253 NONAME + ;SFileDdaBegin @254 NONAME + SFileDdaBeginEx @255 NONAME + SFileDdaDestroy @256 NONAME + SFileDdaEnd @257 NONAME + SFileDdaGetPos @258 NONAME + ;SFileDdaGetVolume @259 NONAME + SFileDdaInitialize @260 NONAME + SFileDdaSetVolume @261 NONAME + SFileDestroy @262 NONAME + ;SFileEnableDirectAccess @263 NONAME + SFileGetFileArchive @264 NONAME + SFileGetFileSize @265 NONAME + SFileOpenArchive @266 NONAME + SFileOpenFile @267 NONAME + SFileOpenFileEx @268 NONAME + SFileReadFile @269 NONAME + SFileSetBasePath @270 NONAME + SFileSetFilePointer @271 NONAME + SFileSetLocale @272 NONAME + ;SFileGetBasePath @273 NONAME + SFileSetIoErrorMode @274 NONAME + SFileGetArchiveName @275 NONAME + SFileGetFileName @276 NONAME + ;SFileGetArchiveInfo @277 NONAME + ;SFileSetPlatform @278 NONAME + SFileLoadFile @279 NONAME + SFileUnloadFile @280 NONAME + SFileLoadFileEx @281 NONAME + ;SFilePrioritizeRequest @282 NONAME + ;SFileCancelRequest @283 NONAME + ;SFileSetAsyncBudget @284 NONAME + ;SFileSetDataChunkSize @285 NONAME + ;SFileEnableSeekOptimization @286 NONAME + ;SFileReadFileEx @287 NONAME + ;SFileFileExists @288 NONAME + ;SFileFileExistsEx @289 NONAME + ;SFileReadFileEx2 @290 NONAME + ;SFileReadFile2 @291 NONAME + ;SFileLoadFile2 @292 NONAME + ;SFileOpenFileAsArchive @293 NONAME + ;SFileGetLocale @294 NONAME + ;SFileRegisterLoadNotifyProc @295 NONAME + ;SFileGetFileCompressedSize @296 NONAME + ;Ordinal297 @297 NONAME + ;Ordinal298 @298 NONAME + ;SFileAuthenticateArchiveEx @299 NONAME + ;SFileOpenPathAsArchive @300 NONAME + StormDestroy @301 NONAME + ;StormGetInstance @302 NONAME + ;StormGetOption @303 NONAME + ;StormSetOption @304 NONAME + + ;SBltGetSCode @312 NONAME + SBltROP3 @313 NONAME + SBltROP3Clipped @314 NONAME + ;SBltROP3Tiled @315 NONAME + + SBmpDecodeImage @321 NONAME + + SBmpLoadImage @323 NONAME + SBmpSaveImage @324 NONAME + SBmpAllocLoadImage @325 NONAME + ;SBmpSaveImageEx @326 NONAME + + SCodeCompile @331 NONAME + SCodeDelete @332 NONAME + + SCodeExecute @334 NONAME + ;SCodeGetPseudocode @335 NONAME + + SDrawAutoInitialize @341 NONAME + SDrawCaptureScreen @342 NONAME + ;SDrawClearSurface @343 NONAME + SDrawDestroy @344 NONAME + ;SDrawFlipPage @345 NONAME + SDrawGetFrameWindow @346 NONAME + SDrawGetObjects @347 NONAME + SDrawGetScreenSize @348 NONAME + ;SDrawGetServiceLevel @349 NONAME + SDrawLockSurface @350 NONAME + SDrawManualInitialize @351 NONAME + SDrawMessageBox @352 NONAME + SDrawPostClose @353 NONAME + SDrawRealizePalette @354 NONAME + ;SDrawSelectGdiSurface @355 NONAME + SDrawUnlockSurface @356 NONAME + SDrawUpdatePalette @357 NONAME + ;SDrawUpdateScreen @358 NONAME + ;SDrawWaitForVerticalBlank @359 NONAME + + SEvtDispatch @372 NONAME + ;SEvtRegisterHandler @373 NONAME + ;SEvtUnregisterHandler @374 NONAME + ;SEvtUnregisterType @375 NONAME + ;SEvtPopState @376 NONAME + ;SEvtPushState @377 NONAME + ;SEvtBreakHandlerChain @378 NONAME + + ;SGdiBitBlt @381 NONAME + ;SGdiCreateFont @382 NONAME + SGdiDeleteObject @383 NONAME + ;SGdiDestroy @384 NONAME + SGdiExtTextOut @385 NONAME + SGdiImportFont @386 NONAME + ;SGdiLoadFont @387 NONAME + ;SGdiRectangle @388 NONAME + SGdiSelectObject @389 NONAME + SGdiSetPitch @390 NONAME + ;SGdiTextOut @391 NONAME + ;SGdi392 @392 NONAME + Ordinal393 @393 NONAME + + ;SMem399 @399 NONAME + + SMemAlloc @401 NONAME + ;SMemDestroy @402 NONAME + SMemFree @403 NONAME + ;SMemGetSize @404 NONAME + SMemReAlloc @405 NONAME + ;Storm406 @406 NONAME + + ;SMsgDispatchMessage @412 NONAME + ;SMsgDoMessageLoop @413 NONAME + ;SMsgRegisterCommand @414 NONAME + ;SMsgRegisterKeyDown @415 NONAME + ;SMsgRegisterKeyUp @416 NONAME + ;SMsgRegisterMessage @417 NONAME + ;SMsgPopRegisterState @418 NONAME + ;SMsgPushRegisterState @419 NONAME + ;SMsg420 @420 NONAME + SRegLoadData @421 NONAME + SRegLoadString @422 NONAME + SRegLoadValue @423 NONAME + SRegSaveData @424 NONAME + SRegSaveString @425 NONAME + SRegSaveValue @426 NONAME + ;SRegGetBaseKey @427 NONAME + SRegDeleteValue @428 NONAME + ;SReg429 @429 NONAME + ;SReg430 @430 NONAME + STransBlt @431 NONAME + STransBltUsingMask @432 NONAME + ;STransCreateI @433 NONAME + STransDelete @434 NONAME + + STransDuplicate @436 NONAME + STransIntersectDirtyArray @437 NONAME + STransInvertMask @438 NONAME + ;STransLoadI @439 NONAME + STransSetDirtyArrayInfo @440 NONAME + ;STransUpdateDirtyArray @441 NONAME + STransPointInMask @442 NONAME + STransCombineMasks @443 NONAME + ;STransCreateI @444 NONAME + STransCreateE @445 NONAME + ;STrans446 @446 NONAME + ;STransLoadE @447 NONAME + + SVidDestroy @451 NONAME + SVidGetSize @452 NONAME + SVidInitialize @453 NONAME + SVidPlayBegin @454 NONAME + ;SVidPlayBeginFromMemory @455 NONAME + SVidPlayContinue @456 NONAME + SVidPlayContinueSingle @457 NONAME + SVidPlayEnd @458 NONAME + ;SVidSetVolume @459 NONAME + ;Storm460 @460 NONAME + SErrDisplayError @461 NONAME + SErrGetErrorStr @462 NONAME + SErrGetLastError @463 NONAME + ;SErrRegisterMessageSource @464 NONAME + SErrSetLastError @465 NONAME + ;SErrReportNamedResourceLeak @466 NONAME + ;SErrReportResourceLeak @467 NONAME + SErrSuppressErrors @468 NONAME + ;SErrRegisterHandler @469 NONAME + ;SErrUnregisterHandler @470 NONAME + ;Storm471 @471 NONAME + ;SCmdGetBool @472 NONAME + ;SCmdGetNum @473 NONAME + ;SCmdGetString @474 NONAME + ;SCmdProcess @475 NONAME + ;SCmdRegisterArgList @476 NONAME + ;SCmdRegisterArgument @477 NONAME + ;SCmdStringExists @478 NONAME + ;SCmdProcessCommandLine @479 NONAME + ;Ordinal480 @480 NONAME + ;SMemFindNextBlock @481 NONAME + ;SMemFindNextHeap @482 NONAME + ;SMemGetHeapByCaller @483 NONAME + ;SMemGetHeapByPtr @484 NONAME + ;SMemHeapAlloc @485 NONAME + ;SMemHeapCreate @486 NONAME + ;SMemHeapDestroy @487 NONAME + ;SMemHeapFree @488 NONAME + ;SMemHeapRealloc @489 NONAME + ;SMemHeapSize @490 NONAME + SMemCopy @491 NONAME + SMemFill @492 NONAME + ;SMemMove @493 NONAME + SMemZero @494 NONAME + SMemCmp @495 NONAME + ;SMem496 @496 NONAME + ;SMemDumpState @497 NONAME + ;Ordinal498 @498 NONAME + + SStrCopy @501 NONAME + SStrHash @502 NONAME + SStrNCat @503 NONAME + ;SStrTokenize @504 NONAME + ;SStrPack @505 NONAME + SStrLen @506 NONAME + ;SStrDup @507 NONAME + SStrCmp @508 NONAME + SStrCmpI @509 NONAME + SStrUpper @510 NONAME + ;SMsgBreakHandlerChain @511 NONAME + ;SMsgUnregisterCommand @512 NONAME + ;SMsgUnregisterKeyDown @513 NONAME + ;SMsgUnregisterKeyUp @514 NONAME + ;SMsgUnregisterMessage @515 NONAME + ;SMsgGetDispatcher @516 NONAME + ;SMsgSetDefaultWindow @517 NONAME + ;SMsgGetDefaultWindow @518 NONAME + ;SMsg519 @519 NONAME + + ;SRgn521 @521 NONAME + + SRgn523 @523 NONAME + SRgnCreateRegion @524 NONAME + SRgnDeleteRegion @525 NONAME + + ;SRgn527 @527 NONAME + ;SRgn528i @528 NONAME + SRgn529i @529 NONAME + ;SRgn530i @530 NONAME + ;SRgn531i @531 NONAME + ;SRgn532i @532 NONAME + ;SRgn533i @533 NONAME + ;SRgn534 @534 NONAME + ;SRgn535f @535 NONAME + ;SRgn536f @536 NONAME + ;SRgn537f @537 NONAME + ;SRgn538f @538 NONAME + ;SRgn539f @539 NONAME + ;SRgn540f @540 NONAME + ;SLogClose @541 NONAME + ;SLogCreate @542 NONAME + ;SLog543 @543 NONAME + ;SLogDump @544 NONAME + ;SLogFlush @545 NONAME + ;SLogFlushAll @546 NONAME + ;SLogPend @547 NONAME + ;SLogWrite @548 NONAME + ;SLog549 @549 NONAME + ;SLogCriticalLog @550 NONAME + ;SCompCompress @551 NONAME + ;SCompDecompress @552 NONAME + ;SLogVWrite @553 NONAME + ;Ordinal554 @554 NONAME + ;Ordinal555 @555 NONAME + ;Ordinal556 @556 NONAME + ;Ordinal557 @557 NONAME + ;Ordinal558 @558 NONAME + ;Ordinal559 @559 NONAME + ;Ordinal560 @560 NONAME + ;SErrCheckDebugSymbolLibrary @561 NONAME + SErrDisplayErrorFmt @562 NONAME + ;SErrIsDisplayingError @563 NONAME + ;SErrPrepareAppFatal @564 NONAME + ;SErrSetLogTitleString @565 NONAME + ;SErrDisplayAppFatal @566 NONAME + SErrCatchUnhandledExceptions @567 NONAME + ;Storm568 @568 NONAME + ;SStrChr @569 NONAME + ;SStrChrR @570 NONAME + SStrChr @571 NONAME + SStrChrR @572 NONAME + ;SStrToDouble @573 NONAME + ;SStrToFloat @574 NONAME + ;SStrToInt @575 NONAME + ;SStrToUnsigned @576 NONAME + ;SStrToInt64 @577 NONAME + SStrVPrintf @578 NONAME + ;SStrLower @579 NONAME + ;SStrHash64 @580 NONAME + ;SStrPrintf @581 NONAME + ;SDrawSetClientRect @582 NONAME + ;SDrawGetClientRect @583 NONAME + ;SStrStrI @584 NONAME + ;SStrStrI @585 NONAME + ;SStrStr @586 NONAME + ;SStrStr @587 NONAME + ;SNet588 @588 NONAME + + ;SBigAdd @601 NONAME + ;SBigAnd @602 NONAME + ;SBigCompare @603 NONAME + ;SBigCopy @604 NONAME + ;SBigDec @605 NONAME + SBigDel @606 NONAME + ;SBigDiv @607 NONAME + ;SBigFindPrime @608 NONAME + SBigFromBinary @609 NONAME + ;SBigFromStr @610 NONAME + ;SBigFromStream @611 NONAME + ;SBigFromUnsigned @612 NONAME + ;SBigGcd @613 NONAME + ;SBigInc @614 NONAME + ;SBigInvMod @615 NONAME + ;SBigIsEven @616 NONAME + ;SBigIsOdd @617 NONAME + ;SBigIsOne @618 NONAME + ;SBigIsPrime @619 NONAME + ;SBigIsZero @620 NONAME + ;SBigMod @621 NONAME + ;SBigMul @622 NONAME + ;SBigMulMod @623 NONAME + SBigNew @624 NONAME + ;SBigNot @625 NONAME + ;SBigOr @626 NONAME + ;SBigPow @627 NONAME + SBigPowMod @628 NONAME + ;SBigRand @629 NONAME + ;SBigSet2Exp @630 NONAME + ;SBigSetOne @631 NONAME + ;SBigSetZero @632 NONAME + ;SBigShl @633 NONAME + ;SBigShr @634 NONAME + ;SBigSquare @635 NONAME + ;SBigSub @636 NONAME + ;SBigToBinaryArray @637 NONAME + SBigToBinaryBuffer @638 NONAME + ;SBigToBinaryPtr @639 NONAME + ;SBigToStrArray @640 NONAME + ;SBigToStrBuffer @641 NONAME + ;SBigToStrPtr @642 NONAME + ;SBigToStreamArray @643 NONAME + ;SBigToStreamBuffer @644 NONAME + ;SBigToStreamPtr @645 NONAME + ;SBigToUnsigned @646 NONAME + ;SBigXor @647 NONAME + + ;SUniConvertUTF16to8Len @901 NONAME + ;SUniConvertUTF16to8 @902 NONAME + ;SUniConvertUTF8to16Len @903 NONAME + ;SUniConvertUTF8to16 @904 NONAME + ;SUniS905 @905 NONAME + ;SUniS906 @906 NONAME + ;SUniFindAfterUTF8Chr @907 NONAME + ;SUniFindUTF8ChrStart @908 NONAME + ;SUniConvertUTF16To909 @909 NONAME + ;SUniConvertUTF16To910 @910 NONAME + ;SUniConvertUTF16To911 @911 NONAME + ;SUniConvert912 @912 NONAME + ;SUniConvert913 @913 NONAME + ;SUniConvert914 @914 NONAME + ;SUniConvertUTF8ToWin @915 NONAME +; END diff --git a/2018_03_14/storm/storm.dsp b/2018_03_14/storm/storm.dsp new file mode 100644 index 00000000..c7d60d17 --- /dev/null +++ b/2018_03_14/storm/storm.dsp @@ -0,0 +1,126 @@ +# Microsoft Developer Studio Project File - Name="storm" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=storm - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "storm.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "storm.mak" CFG="storm - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "storm - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "storm - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "storm - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "STORM_EXPORTS" /Yu"stdafx.h" /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "STORM_EXPORTS" /FD /c +# SUBTRACT CPP /YX /Yc /Yu +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /def:"Storm.def" +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "storm - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "STORM_EXPORTS" /Yu"stdafx.h" /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "STORM_EXPORTS" /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /def:"Storm.def" /pdbtype:sept +# SUBTRACT LINK32 /pdb:none + +!ENDIF + +# Begin Target + +# Name "storm - Win32 Release" +# Name "storm - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\StdAfx.cpp +# ADD CPP /Yc"stdafx.h" +# End Source File +# Begin Source File + +SOURCE=.\storm.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\StdAfx.h +# End Source File +# Begin Source File + +SOURCE=.\storm.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# Begin Source File + +SOURCE=.\ReadMe.txt +# End Source File +# End Target +# End Project diff --git a/2018_03_14/storm/storm.dsw b/2018_03_14/storm/storm.dsw new file mode 100644 index 00000000..2a874e7a --- /dev/null +++ b/2018_03_14/storm/storm.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "storm"=.\storm.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/2018_03_14/storm/storm.h b/2018_03_14/storm/storm.h new file mode 100644 index 00000000..88bd8bae --- /dev/null +++ b/2018_03_14/storm/storm.h @@ -0,0 +1,1299 @@ +#pragma once + +#ifndef __BLIZZARD_STORM_HEADER +#define __BLIZZARD_STORM_HEADER + +#include +#include +#include +#include + +// Note to self: Linker error => forgot a return value in cpp + +// Storm API definition +#ifndef STORMAPI +#define STORMAPI __stdcall +#endif + +#ifndef __STORM_SMAX +#define __STORM_SMAX(x,y) (x < y ? y : x) +#endif + +#ifndef __STORM_SSIZEMAX +#define __STORM_SSIZEMAX(x,y) (__STORM_SMAX(sizeof(x),sizeof(y))) +#endif + +#ifndef __STORM_SMIN +#define __STORM_SMIN(x,y) (x < y ? x : y) +#endif + +#ifndef __STORM_SSIZEMIN +#define __STORM_SSIZEMIN(x,y) (__STORM_SMIN(sizeof(x),sizeof(y))) +#endif + +typedef struct _WRECT +{ + WORD left; + WORD top; + WORD right; + WORD bottom; +} WRECT, *PWRECT; + +typedef struct _WPOINT +{ + WORD x; + WORD y; +} WPOINT, *PWPOINT; + +typedef struct _WSIZE +{ + WORD cx; + WORD cy; +} WSIZE, *PWSIZE; + + + +// Game states +#define GAMESTATE_PRIVATE 0x01 +#define GAMESTATE_FULL 0x02 +#define GAMESTATE_ACTIVE 0x04 +#define GAMESTATE_STARTED 0x08 +#define GAMESTATE_REPLAY 0x80 + + +BOOL STORMAPI SNetCreateGame(const char *pszGameName, const char *pszGamePassword, const char *pszGameStatString, DWORD dwGameType, char *GameTemplateData, int GameTemplateSize, int playerCount, char *creatorName, char *a11, int *playerID); +BOOL STORMAPI SNetDestroy(); +BOOL STORMAPI SNetEnumProviders(int (STORMAPI *callback)(DWORD, DWORD, DWORD, DWORD), int mincaps); + +BOOL STORMAPI SNetEnumGames(int (STORMAPI *callback)(DWORD, DWORD, DWORD), int *hintnextcall); + +/* SNetDropPlayer @ 106 + * + * Drops a player from the current game. + * + * playerid: The player ID for the player to be dropped. + * flags: + * + * Returns TRUE if the function was called successfully and FALSE otherwise. + */ +BOOL +STORMAPI +SNetDropPlayer( + int playerid, + DWORD flags); + +/* SNetGetGameInfo @ 107 + * + * Retrieves specific game information from Storm, such as name, password, + * stats, mode, game template, and players. + * + * type: The type of data to retrieve. See GAMEINFO_ flags. + * dst: The destination buffer for the data. + * length: The maximum size of the destination buffer. + * byteswritten: The number of bytes written to the destination buffer. + * + * Returns TRUE if the function was called successfully and FALSE otherwise. + */ +BOOL +STORMAPI +SNetGetGameInfo( + int type, + void *dst, + size_t length, + size_t *byteswritten = NULL); + + +#define SNGetGameInfo(typ,dst) SNetGetGameInfo(typ, &dst, sizeof(dst)) + + + +// Game info fields +#define GAMEINFO_NAME 1 +#define GAMEINFO_PASSWORD 2 +#define GAMEINFO_STATS 3 +#define GAMEINFO_MODEFLAG 4 +#define GAMEINFO_GAMETEMPLATE 5 +#define GAMEINFO_PLAYERS 6 + + +BOOL STORMAPI SNetGetNumPlayers(int *firstplayerid, int *lastplayerid, int *activeplayers); + + +typedef struct _CAPS +{ + DWORD dwSize; // Size of this structure // sizeof(CAPS) + DWORD dwUnk_0x04; // Some flags? + DWORD maxmessagesize; // Size of the packet buffer, must be beteen 128 and 512 + DWORD dwUnk_0x0C; // Unknown + DWORD dwDisplayedPlayerCount; // Displayed player count in the mode selection list + DWORD dwUnk_0x14; // some kind of timeout or timer related + DWORD dwPlayerLatency; // ... latency? + DWORD dwPlayerCount; // the number of players that can participate, must be between 1 and 20 + DWORD dwCallDelay; // the number of calls before data is sent over the network // between 2 and 8; single player is set to 1 +} CAPS, *PCAPS; + + +BOOL STORMAPI SNetGetPlayerCaps(char playerid, PCAPS playerCaps); + +/* SNetGetPlayerName @ 113 + * + * Retrieves the name of a player given their player ID. + * + * playerid: The player's ID. + * buffer: The buffer that will receive the name. + * buffersize: The maximum size of buffer. + * + * Returns TRUE if the function was called successfully and FALSE otherwise. + */ +BOOL +STORMAPI +SNetGetPlayerName( + int playerid, + char *buffer, + size_t buffersize); + +/* SNetGetProviderCaps @ 114 + * + * Retrieves network provider capacity information. + * + * providerCaps: A pointer to a CAPS structure that will receive the information. + * + * Returns TRUE if the function was called successfully and FALSE otherwise. + */ +BOOL +STORMAPI +SNetGetProviderCaps( + PCAPS providerCaps); + +/* SNetGetTurnsInTransit @ 115 + * + * Retrieves the number of turns (buffers) that have been queued + * before sending them over the network. + * + * turns: A pointer to an integer that will receive the value. + * + * Returns TRUE if the function was called successfully and FALSE otherwise. + */ +BOOL +STORMAPI +SNetGetTurnsInTransit( + int *turns); + + +BOOL STORMAPI SNetInitializeDevice(int a1, int a2, int a3, int a4, int *a5); + +// Network provider structures +typedef struct _client_info +{ + DWORD dwSize; // 60 + char *pszName; + char *pszVersion; + DWORD dwProduct; + DWORD dwVerbyte; + DWORD dwUnk5; + DWORD dwMaxPlayers; + DWORD dwUnk7; + DWORD dwUnk8; + DWORD dwUnk9; + DWORD dwUnk10; // 0xFF + char *pszCdKey; + char *pszCdOwner; + DWORD dwIsShareware; + DWORD dwLangId; +} client_info; + +typedef struct _user_info +{ + DWORD dwSize; // 16 + char *pszPlayerName; + char *pszUnknown; + DWORD dwUnknown; +} user_info; + +typedef struct _battle_info +{ + DWORD dwSize; // 92 + DWORD dwUnkType; + HWND hFrameWnd; + void *pfnBattleGetResource; + void *pfnBattleGetErrorString; + void *pfnBattleMakeCreateGameDialog; + void *pfnBattleUpdateIcons; + DWORD dwUnk_07; + void *pfnBattleErrorDialog; + void *pfnBattlePlaySound; + DWORD dwUnk_10; + void *pfnBattleGetCursorLink; + DWORD dwUnk_12; + void *pfnUnk_13; + DWORD dwUnk_14; + void *pfnBattleMakeProfileDialog; + char *pszProfileStrings; + void *pfnBattleDrawProfileInfo; + void *pfnUnk_18; + DWORD dwUnk_19; + void *pfnUnk_20; + void *pfnUnk_21; + void *pfnBattleSetLeagueName; +} battle_info; + +typedef struct _module_info +{ + DWORD dwSize; // 20 + char *pszVersionString; + char *pszModuleName; + char *pszMainArchive; + char *pszPatchArchive; +} module_info; + +typedef struct _game +{ + DWORD dwIndex; + DWORD dwGameState; + DWORD dwUnk_08; + SOCKADDR saHost; + DWORD dwUnk_1C; + DWORD dwTimer; + DWORD dwUnk_24; + char szGameName[128]; + char szGameStatString[128]; + _game *pNext; + void *pExtra; + DWORD dwExtraBytes; + DWORD dwProduct; + DWORD dwVersion; +} game; + +typedef struct _storm_head +{ + WORD wChecksum; + WORD wLength; + WORD wSent; + WORD wReceived; + BYTE bCommandClass; + BYTE bCommandType; + BYTE bPlayerId; + BYTE bFlags; +} storm_head; + + +// Traffic flags +#define STRAFFIC_NORMAL 0 +#define STRAFFIC_VERIFY 1 +#define STRAFFIC_RESEND 2 +#define STRAFFIC_REPLY 4 + + +/* SNetInitializeProvider @ 117 + * + * Initializes a provider by storing the provider callbacks, and calling + * spiInitialize() using the parameters passed to this function. + * Note: The use of the parameters is determined by the network + * module. + * + * providerName: The provider's identifier. Example: 'TENB' (BNET). + * gameClientInfo: A pointer to a clientInfo structure containing + * information about the game client. + * userData: A pointer to a userInfo structure containing information + * about the player. + * bnCallbacks: A pointer to a battleInfo structure containing callbacks + * and other information that is specific to Battle.net. + * moduleData: A pointer to a moduleInfo structure containing the + * executable information and paths to MPQ archives. + * + * Returns TRUE if the function was called successfully and FALSE otherwise. + */ +BOOL +STORMAPI +SNetInitializeProvider( + DWORD providerName, + client_info *gameClientInfo, + user_info *userData, + battle_info *bnCallbacks, + module_info *moduleData); + + +BOOL STORMAPI SNetJoinGame(int id, char *gameName, char *gamePassword, char *playerName, char *userStats, int *playerid); + +/* SNetLeaveGame @ 119 + * + * Notifies Storm that the player has left the game. Storm will + * notify all connected peers through the network provider. + * + * type: The leave type. It doesn't appear to be important, no documentation available. + * + * Returns TRUE if the function was called successfully and FALSE otherwise. + */ +BOOL +STORMAPI +SNetLeaveGame( + int type); + +BOOL STORMAPI SNetPerformUpgrade(DWORD *upgradestatus); +BOOL STORMAPI SNetReceiveMessage(int *senderplayerid, char **data, int *databytes); +BOOL STORMAPI SNetReceiveTurns(int a1, int arraysize, char **arraydata, unsigned int *arraydatabytes, DWORD *arrayplayerstatus); + +// Values for arrayplayerstatus +#define SNET_PS_OK 0 +#define SNET_PS_WAITING 2 +#define SNET_PS_NOTRESPONDING 3 +#define SNET_PS_UNKNOWN default + + +// Event structure +typedef struct _s_evt +{ + DWORD dwFlags; + int dwPlayerId; + void *pData; + DWORD dwSize; +} S_EVT, *PS_EVT; + + +// @TODO: "type" is unknown. +HANDLE STORMAPI SNetRegisterEventHandler(int type, void (STORMAPI *sEvent)(PS_EVT)); + +int STORMAPI SNetSelectGame(int a1, int a2, int a3, int a4, int a5, int *playerid); + +/* SNetSendMessage @ 127 + * + * Sends a message to a player given their player ID. Network message + * is sent using class 01 and is retrieved by the other client using + * SNetReceiveMessage(). + * + * playerID: The player index of the player to receive the data. + * Conversely, this field can be one of the following constants: + * SNPLAYER_ALL | Sends the message to all players, including oneself. + * SNPLAYER_OTHERS | Sends the message to all players, except for oneself. + * data: A pointer to the data. + * databytes: The amount of bytes that the data pointer contains. + * + * Returns TRUE if the function was called successfully and FALSE otherwise. + */ +BOOL +STORMAPI +SNetSendMessage( + int playerID, + void *data, + size_t databytes); + + +// Macro values to target specific players +#define SNPLAYER_ALL -1 +#define SNPLAYER_OTHERS -2 + + +/* SNetSendTurn @ 128 + * + * Sends a turn (data packet) to all players in the game. Network data + * is sent using class 02 and is retrieved by the other client using + * SNetReceiveTurns(). + * + * data: A pointer to the data. + * databytes: The amount of bytes that the data pointer contains. + * + * Returns TRUE if the function was called successfully and FALSE otherwise. + */ +BOOL +STORMAPI +SNetSendTurn( + char *data, + size_t databytes); + +/* SNetSetGameMode @ 130 + * + * Set's the game's mode flags, notifying the network + * provider that the state of the game has changed. + * For example: notifies Battle.net when the game is + * full. + * + * You should first call SNetGetGameInfo to retrieve + * the existing mode flags. + * + * modeFlags: The new flags for the game mode. + * GAMESTATE_PRIVATE | The game is passworded. + * GAMESTATE_FULL | The game is full. + * GAMESTATE_ACTIVE | The game is available. + * GAMESTATE_STARTED | The game is in progress. + * GAMESTATE_REPLAY | The game is a replay. + * makePublic: Used to make the game a public game, removing the GAMESTATE_PRIVATE flag. + * + * Returns TRUE if the function was called successfully and FALSE otherwise. + */ +BOOL +STORMAPI +SNetSetGameMode( + DWORD modeFlags, + bool makePublic = false); + +#define SNMakeGamePublic() SNetSetGameMode( (DWORD mode, SNetGetGameInfo(GAMEINFO_MODEFLAGS, &mode, 4), mode), true) + +BOOL STORMAPI SNetEnumGamesEx(int a1, int a2, int (__fastcall *callback)(DWORD, DWORD, DWORD), int *hintnextcall); +BOOL STORMAPI SNetSendServerChatCommand(const char *command); + +BOOL STORMAPI SNetDisconnectAll(DWORD flags); +BOOL STORMAPI SNetCreateLadderGame(const char *pszGameName, const char *pszGamePassword, const char *pszGameStatString, DWORD dwGameType, DWORD dwGameLadderType, DWORD dwGameModeFlags, char *GameTemplateData, int GameTemplateSize, int playerCount, char *creatorName, char *a11, int *playerID); + +#define SNET_GAME_RESULT_WIN 1 +#define SNET_GAME_RESULT_LOSS 2 +#define SNET_GAME_RESULT_DRAW 3 +#define SNET_GAME_RESULT_DISCONNECT 4 + +BOOL STORMAPI SNetReportGameResult(unsigned a1, int size, int *results, const char* headerInfo, const char* detailInfo); + +int STORMAPI SNetSendLeagueCommand(char *cmd, char *callback); +int STORMAPI SNetSendReplayPath(int a1, int a2, char *replayPath); +int STORMAPI SNetGetLeagueName(int leagueID); +BOOL STORMAPI SNetGetPlayerNames(char **names); +int STORMAPI SNetLeagueLogout(char *bnetName); +int STORMAPI SNetGetLeaguePlayerName(char *curPlayerLeageName, size_t nameSize); + +HGDIOBJ STORMAPI SDlgDefDialogProc(HWND hDlg, signed int DlgType, HDC textLabel, HWND hWnd); + +HANDLE STORMAPI SDlgDialogBoxIndirectParam(HMODULE hModule, LPCSTR lpName, HWND hWndParent, LPVOID lpParam, LPARAM lParam); + +BOOL STORMAPI SDlgEndDialog(HWND hDlg, HANDLE nResult); + +BOOL STORMAPI SDlgSetControlBitmaps(HWND parentwindow, int *id, int a3, char *buffer2, char *buffer, int flags, int mask); + +/* +// lpCursorName can only be IDC_ARROW +BOOL STORMAPI SDlgSetSystemCursor(void *lpSrcBuffer, void *p_a2, LPSIZE lpSize, LPCSTR lpCursorName); +*/ + +BOOL STORMAPI SDlgBltToWindowE(HWND hWnd, HRGN a2, char *a3, int a4, void *buffer, RECT *rct, SIZE *size, int a8, int a9, DWORD rop); +BOOL STORMAPI SDlgSetBitmapE(HWND hWnd, int a2, char *src, int mask1, int flags, int a6, int a7, int width, int a9, int mask2); + +int STORMAPI Ordinal224(int a1); + +BOOL STORMAPI SFileCloseArchive(HANDLE hArchive); +BOOL STORMAPI SFileCloseFile(HANDLE hFile); + +BOOL STORMAPI SFileDdaBeginEx(HANDLE directsound, DWORD flags, DWORD mask, unsigned __int32 lDistanceToMove, signed __int32 volume, signed int a6, int a7); +BOOL STORMAPI SFileDdaDestroy(); +BOOL STORMAPI SFileDdaEnd(HANDLE directsound); +BOOL STORMAPI SFileDdaGetPos(HANDLE directsound, int a2, int a3); + +BOOL STORMAPI SFileDdaInitialize(HANDLE directsound); +BOOL STORMAPI SFileDdaSetVolume(HANDLE directsound, signed int bigvolume, signed int volume); +BOOL STORMAPI SFileDestroy(); + +BOOL STORMAPI SFileGetFileArchive(HANDLE hFile, HANDLE archive); +LONG STORMAPI SFileGetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh); +BOOL STORMAPI SFileOpenArchive(const char *szMpqName, DWORD dwPriority, DWORD dwFlags, HANDLE *phMpq); + +// values for dwFlags +enum MPQFlags +{ + MPQ_NO_LISTFILE = 0x0010, + MPQ_NO_ATTRIBUTES = 0x0020, + MPQ_FORCE_V1 = 0x0040, + MPQ_CHECK_SECTOR_CRC = 0x0080 +}; + + +BOOL STORMAPI SFileOpenFile(const char *filename, HANDLE *phFile); +BOOL STORMAPI SFileOpenFileEx(HANDLE hMpq, const char *szFileName, DWORD dwSearchScope, HANDLE *phFile); + +// values for dwSearchScope +enum SFileFlags +{ + SFILE_FROM_MPQ = 0x00000000, + SFILE_FROM_ABSOLUTE = 0x00000001, + SFILE_FROM_RELATIVE = 0x00000002, + SFILE_FROM_DISK = 0x00000004 +}; + +BOOL STORMAPI SFileReadFile(HANDLE hFile, void *buffer, DWORD nNumberOfBytesToRead, DWORD *read, LONG lpDistanceToMoveHigh); + +void STORMAPI SFileSetLocale(LCID lcLocale); + +// mode: 0 - Silent (callback is NULL) +// 1 - Application Defined +// 2 - Handled by storm (callback is NULL) +// BOOL STORMAPI callback(const char *pszFilename, DWORD dwErrCode, DWORD dwErrCount) +BOOL STORMAPI SFileSetIoErrorMode(DWORD mode, BOOL (STORMAPI *callback)(const char*,DWORD,DWORD) ); + +BOOL STORMAPI SFileGetArchiveName(HANDLE hArchive, char *name, int length); +BOOL STORMAPI SFileGetFileName(HANDLE hFile, char *buffer, int length); + +BOOL STORMAPI SFileLoadFile(char *filename, void *buffer, int buffersize, int a4, int a5); +BOOL STORMAPI SFileUnloadFile(HANDLE hFile); +BOOL STORMAPI SFileLoadFileEx(void *hArchive, char *filename, int a3, int a4, int a5, DWORD searchScope, struct _OVERLAPPED *lpOverlapped); + +// Options are DWORD except for #6 +// 1: [TRUE|FALSE] - If true, reports resource leaks (SErrReportResourceLeak/SErrReportNamedResourceLeak) to the attached debugger instead of a message box. +// 2: This option is unused. +// 3: [TRUE|FALSE] - If true, reports general memory leaks to the attached debugger instead of a message box. +// 4: This option is unused. +// 5: [TRUE|FALSE] - If true, reports log messages and log dumps to the attached debugger. +// 6: { DWORD blocks_allocated; DWORD blocks_freed; } Used to determine the amount of memory/heap blocks that have been allocated and freed by storm. +// Can also be used for custom allocations outside of storm. +// +//BOOL STORMAPI StormGetOption(int type, void *pValue, size_t *pSize); +//BOOL STORMAPI StormSetOption(int type, void *pValue, size_t size); + +BOOL STORMAPI SBltROP3(void *lpDstBuffer, void *lpSrcBuffer, int srcDrawWidth, int srcDrawHeight, int dstWidth, int srcWidth, int a7, DWORD rop); +BOOL STORMAPI SBltROP3Clipped(void *lpDstBuffer, RECT *lpDstRect, POINT *lpDstPt, int a4, void *lpSrcBuffer, RECT *lpSrcRect, POINT *lpSrcPt, int a8, int a9, DWORD rop); + +#define SBMP_DEFAULT 0 +#define SBMP_BMP 1 +#define SBMP_PCX 2 +#define SBMP_TGA 3 + + +/* SBmpDecodeImage @ 321 + * + * Decodes an image that has already been loaded into a buffer. + * + * dwImgType: Optional, the image type. See SBMP_ macros. + * pSrcBuffer: A pointer to the source buffer. + * dwSrcBuffersize: The size of the data in the source buffer. + * pPalette: An optional buffer that receives the image palette. + * pDstBuffer: A buffer that receives the image data. + * dwDstBuffersize: The size of the specified image buffer. If the size of the + * destination buffer is 0, then the destination buffer is not used. + * pdwWidth: An optional variable that receives the image width. + * pdwHeight: An optional variable that receives the image height. + * pdwBpp: An optional variable that receives the image bits per pixel. + * + * Returns TRUE if the image was supported and decoded correctly, FALSE otherwise. + */ +BOOL +STORMAPI +SBmpDecodeImage( + DWORD dwImgType, + void *pSrcBuffer, + DWORD dwSrcBuffersize, + PALETTEENTRY *pPalette = NULL, + void *pDstBuffer = NULL, + DWORD dwDstBuffersize = 0, + DWORD *pdwWidth = NULL, + DWORD *pdwHeight = NULL, + DWORD *pdwBpp = NULL); + + +/* SBmpLoadImage @ 323 + * + * Load an image from an available archive into a buffer. + * + * pszFileName: The name of the graphic in an active archive. + * pPalette: An optional buffer that receives the image palette. + * pBuffer: A buffer that receives the image data. + * dwBuffersize: The size of the specified image buffer. + * pdwWidth: An optional variable that receives the image width. + * pdwHeight: An optional variable that receives the image height. + * pdwBpp: An optional variable that receives the image bits per pixel. + * + * Returns TRUE if the image was supported and loaded correctly, FALSE otherwise. + */ +BOOL +STORMAPI +SBmpLoadImage( + const char *pszFileName, + PALETTEENTRY *pPalette = NULL, + void *pBuffer = NULL, + DWORD dwBuffersize = 0, + DWORD *pdwWidth = NULL, + DWORD *pdwHeight = NULL, + DWORD *pdwBpp = NULL); + +/* SBmpSaveImage @ 324 + * + * Save an image from a buffer to a file. The image format is determined + * from the filename and is either .gif, .pcx, .tga, or .bmp being the default. + * + * pszFileName: The name of the file to create. + * pPalette: A pointer to a palette array containing 256 entries. + * pBuffer: A buffer containing the image data. + * pdwWidth: The width of the image. + * pdwHeight: The height of the image. + * pdwBpp: The bits per pixel. + * + * Returns TRUE if the image was saved correctly, FALSE otherwise. + */ +BOOL +STORMAPI +SBmpSaveImage( + const char *pszFileName, + PALETTEENTRY *pPalette, + void *pBuffer, + DWORD dwWidth, + DWORD dwHeight, + DWORD dwBpp = 8); + + +HANDLE STORMAPI SBmpAllocLoadImage(const char *fileName, PALETTEENTRY *palette, void **buffer, int *width, int *height, int unused6, int unused7, void *(STORMAPI *allocFunction)(DWORD)); + +BOOL STORMAPI SCodeCompile(char *directives1, char *directives2, char *loopstring, unsigned int maxiterations, unsigned int flags, HANDLE handle); +BOOL STORMAPI SCodeDelete(HANDLE handle); + +int STORMAPI SCodeExecute(HANDLE handle, int a2); + +BOOL STORMAPI SDrawAutoInitialize(HINSTANCE hInst, LPCSTR lpClassName, LPCSTR lpWindowName, WNDPROC pfnWndProc, int nMode, int nWidth, int nHeight, int nBits); + + +/* SDrawCaptureScreen @ 342 + * + * Saves a screenshot from the primary surface being handled by Storm. + * + * pszOutput: The name of the output file. The save format is automatically set by the extension. + * The extensions supported are .gif, .pcx, .tga, and .bmp. It will write a bitmap by default. + * + * Returns TRUE if successful and FALSE otherwise. + */ +BOOL +STORMAPI +SDrawCaptureScreen( + const char *pszOutput); + + +/* SDrawGetFrameWindow @ 346 + * + * Retrieves the window handle that was specified in + * SDrawManualInitialize or created in SDrawAutoInitialize. + * + * sdraw_framewindow: Optional variable that receives the returned handle. + * + * Returns the handle of the window. + */ +HWND +STORMAPI +SDrawGetFrameWindow( + HWND *sdraw_framewindow = NULL); + + +/* SDrawGetObjects @ 347 + * + * Retrieves the object information that was initialized using + * SDrawManualInitialize or SDrawAutoInitialize. + * + * ddInterface: The DirectDraw interface. + * primarySurface: The primary DirectDraw surface. + * surface2: A second unknown surface. + * surface3: A third unknown surface. + * backSurface: The back DirectDraw surface. + * ddPalette: The DirectDraw palette. + * hPalette: The palette handle. + * + * Returns FALSE if the direct draw interface has not been initialized. + */ +BOOL +STORMAPI +SDrawGetObjects( + LPDIRECTDRAW *ddInterface = NULL, + LPDIRECTDRAWSURFACE *primarySurface = NULL, + LPDIRECTDRAWSURFACE *surface2 = NULL, + LPDIRECTDRAWSURFACE *surface3 = NULL, + LPDIRECTDRAWSURFACE *backSurface = NULL, + LPDIRECTDRAWPALETTE *ddPalette = NULL, + HPALETTE *hPalette = NULL); + + +/* SDrawGetScreenSize @ 348 + * + * Obtains information for the current screen resolution. + * + * pdwWidth: Optional variable that receives the screen width. + * pdwHeight: Optional variable that receives the screen height. + * pdwBpp: Optional variable that receives the bits per pixel. + * + * Returns FALSE if no variables were specified. + */ +BOOL +STORMAPI +SDrawGetScreenSize( + DWORD *pdwWidth, + DWORD *pdwHeight, + DWORD *pdwBpp); + + +// undefined +BOOL STORMAPI SDrawLockSurface(int surfacenumber, RECT *lpDestRect, void **lplpSurface, int *lpPitch, int arg_unused); + + +/* SDrawManualInitialize @ 351 + * + * Sets the DirectDraw variables to be referenced in Storm. + * + * hWnd: The handle of the DirectDraw window. + * ddInterface: The DirectDraw interface. + * primarySurface: The first and primary surface. + * surface2: A second surface. Behaviour not completely known. + * surface3: A third surface. Behaviour not completely known. + * backSurface: The fourth and final surface. The back surface. + * ddPalette: The DirectDraw palette if the application requires it. + * hPalette: The palette handle that belongs to the window. + * If this is NULL and ddPalette is specified, then it + * will be created automatically. A palette can be created + * using the CreatePalette WinAPI function. + * + * Returns FALSE if no variables were specified. + */ +BOOL +STORMAPI +SDrawManualInitialize( + HWND hWnd = NULL, + LPDIRECTDRAW ddInterface = NULL, + LPDIRECTDRAWSURFACE primarySurface = NULL, + LPDIRECTDRAWSURFACE surface2 = NULL, + LPDIRECTDRAWSURFACE surface3 = NULL, + LPDIRECTDRAWSURFACE backSurface = NULL, + LPDIRECTDRAWPALETTE ddPalette = NULL, + HPALETTE hPalette = NULL); + + +/* SDrawPostClose @ 353 + * + * Posts a WM_QUIT message to the active drawing window specified + * in SDrawManualInitialize or created in SDrawAutoInitialize. + * + * Returns TRUE if successful and FALSE otherwise. + */ +BOOL +STORMAPI +SDrawPostClose(); + + +// undefined +//BOOL STORMAPI SDrawRealizePalette(); + +BOOL STORMAPI SDrawUnlockSurface(int surfacenumber, void *lpSurface, int a3, RECT *lpRect); +BOOL STORMAPI SDrawUpdatePalette(unsigned int firstentry, unsigned int numentries, PALETTEENTRY *pPalEntries, int a4); + +BOOL STORMAPI SEvtDispatch(DWORD dwMessageID, DWORD dwFlags, int type, PS_EVT pEvent); + +BOOL STORMAPI SGdiDeleteObject(HANDLE handle); + +BOOL STORMAPI SGdiExtTextOut(int a1, int a2, int a3, int a4, unsigned int a8, signed int a6, signed int a7, const char *pszString, unsigned int arg20); +BOOL STORMAPI SGdiImportFont(HGDIOBJ handle, int windowsfont); + +BOOL STORMAPI SGdiSelectObject(int handle); +BOOL STORMAPI SGdiSetPitch(int pitch); + +BOOL STORMAPI Ordinal393(char *pszString, int, int); + + +/* SMemAlloc @ 401 + * + * Allocates a block of memory. This block is different + * from the standard malloc by including a header containing + * information about the block. + * + * amount: The amount of memory to allocate, in bytes. + * logfilename: The name of the file or object that this call belongs to. + * logline: The line in the file or one of the SLOG_ macros. + * defaultValue: The default value of a byte in the allocated memory. + * + * Returns a pointer to the allocated memory. This pointer does NOT include + * the additional storm header. + */ +void* +STORMAPI +SMemAlloc( + size_t amount, + char *logfilename, + int logline, + char defaultValue = 0); + +#define SMAlloc(amount) SMemAlloc((amount), __FILE__, __LINE__) + + +/* SMemFree @ 403 + * + * Frees a block of memory that was created using SMemAlloc, + * includes the log file and line for debugging purposes. + * + * location: The memory location to be freed. + * logfilename: The name of the file or object that this call belongs to. + * logline: The line in the file or one of the SLOG_ macros. + * defaultValue: + * + * Returns TRUE if the call was successful and FALSE otherwise. + */ +BOOL +STORMAPI +SMemFree( + void *location, + char *logfilename, + int logline, + char defaultValue = 0); + +#define SMFree(loc) SMemFree((loc), __FILE__, __LINE__) + + +/* SMemReAlloc @ 405 + * + * Reallocates a block of memory that was created using SMemAlloc, + * includes the log file and line for debugging purposes. + * + * location: The memory location to be re-allocated. If this parameter + * is NULL, then SMemAlloc is called with the remaining parameters. + * amount: The amount of memory to re-allocate. + * logfilename: The name of the file or object that this call belongs to. + * logline: The line in the file or one of the SLOG_ macros. + * defaultValue: + * + * Returns a pointer to the re-allocated memory. This pointer does NOT include + * the additional storm header. + */ +void* +STORMAPI +SMemReAlloc( + void *location, + size_t amount, + char *logfilename, + int logline, + char defaultValue = 0); + +#define SMReAlloc(loc,s) SMemReAlloc((loc),(s), __FILE__, __LINE__) + +// Can be provided instead of logline/__LINE__ parameter to indicate different errors. +#define SLOG_EXPRESSION 0 +#define SLOG_FUNCTION -1 +#define SLOG_OBJECT -2 +#define SLOG_HANDLE -3 +#define SLOG_FILE -4 +#define SLOG_EXCEPTION -5 + + +BOOL STORMAPI SRegLoadData(const char *keyname, const char *valuename, int size, LPBYTE lpData, BYTE flags, LPDWORD lpcbData); +BOOL STORMAPI SRegLoadString(const char *keyname, const char *valuename, BYTE flags, char *buffer, size_t buffersize); +BOOL STORMAPI SRegLoadValue(const char *keyname, const char *valuename, BYTE flags, int *value); +BOOL STORMAPI SRegSaveData(const char *keyname, const char *valuename, int size, BYTE *lpData, DWORD cbData); +BOOL STORMAPI SRegSaveString(const char *keyname, const char *valuename, BYTE flags, char *string); +BOOL STORMAPI SRegSaveValue(const char *keyname, const char *valuename, BYTE flags, DWORD result); + +BOOL STORMAPI SRegDeleteValue(const char *keyname, const char *valuename, BYTE flags); + +// Flags for SReg functions + +// Default behaviour checks both HKEY_LOCAL_MACHINE and HKEY_CURRENT_USER +// relative to the "Software\\Blizzard Entertainment\\" key in both hives. +#define SREG_NONE 0x00000000 +#define SREG_EXCLUDE_LOCAL_MACHINE 0x00000001 // excludes checking the HKEY_LOCAL_MACHINE hive +#define SREG_BATTLE_NET 0x00000002 // sets the relative key to "Software\\Battle.net\\" instead +#define SREG_EXCLUDE_CURRENT_USER 0x00000004 // excludes checking the HKEY_CURRENT_USER hive +#define SREG_ABSOLUTE 0x00000010 // specifies that the key is not a relative key + +BOOL STORMAPI STransBlt(void *lpSurface, int x, int y, int width, HANDLE hTrans); +BOOL STORMAPI STransBltUsingMask(void *lpDest, void *lpSource, int pitch, int width, HANDLE hTrans); + +BOOL STORMAPI STransDelete(HANDLE hTrans); + +BOOL STORMAPI STransDuplicate(HANDLE hTransSource, HANDLE hTransDest); +BOOL STORMAPI STransIntersectDirtyArray(HANDLE hTrans, char * dirtyarraymask, unsigned flags, HANDLE * phTransResult); +BOOL STORMAPI STransInvertMask(HANDLE hTrans, HANDLE * phTransResult); + +BOOL STORMAPI STransSetDirtyArrayInfo(int width, int height, int depth, int bits); + +BOOL STORMAPI STransPointInMask(HANDLE hTrans, int x, int y); // Name is a pure guess +BOOL STORMAPI STransCombineMasks(HANDLE hTransA, HANDLE hTransB, int left, int top, int flags, HANDLE * phTransResult); + +BOOL STORMAPI STransCreateE(void *pBuffer, int width, int height, int bpp, int a5, int bufferSize, HANDLE *phTransOut); + +BOOL STORMAPI SVidDestroy(); +BOOL STORMAPI SVidGetSize(HANDLE video, int width, int height, int zero); +BOOL STORMAPI SVidInitialize(HANDLE video); +BOOL STORMAPI SVidPlayBegin(char *filename, int arg4, int a3, int a4, int a5, int a6, HANDLE* video); + +BOOL STORMAPI SVidPlayContinueSingle(HANDLE video, int a2, int a3); +BOOL STORMAPI SVidPlayEnd(HANDLE video); + +/* SErrDisplayError @ 461 + * + * Displays a formatted error message. The message is detailed and flexible for many applications. + * The message will be different if there is a debugger attached. Will typically terminate the application + * unless the option to continue is given. + * + * dwErrMessage: The error code. See SErrGetLastError and GetLastError. + * logfilename: The name of the file or object that this call belongs to. + * logline: The line in the file or one of the SLOG_ macros. + * message: A message or expression with additional information. + * allowOption: If TRUE, allows the user the option to continue execution, otherwise the program will terminate. + * exitCode: The exit code used for program termination. + * + * Returns TRUE if the user chose to continue execution, FALSE otherwise. + */ +BOOL +STORMAPI +SErrDisplayError( + DWORD dwErrMsg, + const char *logfilename, + int logline, + const char *message = NULL, + BOOL allowOption = FALSE, + int exitCode = 1); + +#define SAssert(x) { if ( !(x) ) SErrDisplayError(STORM_ERROR_ASSERTION, __FILE__, __LINE__, #x) } + +#define SEDisplayError(err) SErrDisplayError(e, __FILE__, __LINE__) + +/* SErrGetErrorStr @ 462 + * + * Retrieves a string that describes the specified error code for + * the system, Storm, DirectDraw, or DirectSound. + * + * dwErrCode: The error code to look up. + * buffer: The destination buffer to receive the string. + * bufferchars: The size of the destination buffer. + * + * Returns TRUE if the call was successful and FALSE otherwise. + */ +BOOL +STORMAPI +SErrGetErrorStr( + DWORD dwErrCode, + char *buffer, + size_t bufferchars); + +#define SEGetErrorStr(e,b) SErrGetErrorStr(e,b,sizeof(b)) + + +/* SErrGetLastError @ 463 + * + * Retrieves the last error that was specifically + * set for the Storm library. + * + * Returns the last error set within the Storm library. + */ +DWORD +STORMAPI +SErrGetLastError(); + + +// Registers a module as a message source for SErrGetErrorStr, always returns TRUE +// groupID is a group in a MessageTable entry for example in STORM_ERROR_BAD_ARGUMENT 0x85100065, 0x510 is the group. +// BOOL STORMAPI SErrRegisterMessageSource(WORD groupID, HMODULE hSourceModule, int a3) + + +/* SErrSetLastError @ 465 + * + * Sets the last error for the Storm library and the Kernel32 library. + * + * dwErrCode: The error code that will be set. + */ +void +STORMAPI +SErrSetLastError( + DWORD dwErrCode = NO_ERROR); + +// +// void STORMAPI SErrReportNamedResourceLeak(const char *pszMsg, const char *pszSubMsg = nullptr) +// void STORMAPI SErrReportResourceLeak(const char *pszMsg) + +void STORMAPI SErrSuppressErrors(BOOL suppressErrors); + +// Values for dwErrCode +#define STORM_ERROR_ASSERTION 0x85100000 +#define STORM_ERROR_BAD_ARGUMENT 0x85100065 +#define STORM_ERROR_GAME_ALREADY_STARTED 0x85100066 +#define STORM_ERROR_GAME_FULL 0x85100067 +#define STORM_ERROR_GAME_NOT_FOUND 0x85100068 +#define STORM_ERROR_GAME_TERMINATED 0x85100069 +#define STORM_ERROR_INVALID_PLAYER 0x8510006a +#define STORM_ERROR_NO_MESSAGES_WAITING 0x8510006b +#define STORM_ERROR_NOT_ARCHIVE 0x8510006c +#define STORM_ERROR_NOT_ENOUGH_ARGUMENTS 0x8510006d +#define STORM_ERROR_NOT_IMPLEMENTED 0x8510006e +#define STORM_ERROR_NOT_IN_ARCHIVE 0x8510006f +#define STORM_ERROR_NOT_IN_GAME 0x85100070 +#define STORM_ERROR_NOT_INITIALIZED 0x85100071 +#define STORM_ERROR_NOT_PLAYING 0x85100072 +#define STORM_ERROR_NOT_REGISTERED 0x85100073 +#define STORM_ERROR_REQUIRES_CODEC1 0x85100074 +#define STORM_ERROR_REQUIRES_CODEC2 0x85100075 +#define STORM_ERROR_REQUIRES_CODEC3 0x85100076 +#define STORM_ERROR_REQUIRES_UPGRADE 0x85100077 +#define STORM_ERROR_STILL_ACTIVE 0x85100078 +#define STORM_ERROR_VERSION_MISMATCH 0x85100079 +#define STORM_ERROR_MEM_NOT_ALLOCATED 0x8510007a +#define STORM_ERROR_MEM_CORRUPTED 0x8510007b +#define STORM_ERROR_MEM_INVALID 0x8510007c +#define STORM_ERROR_MEM_MANAGER_NOT_INITIALIZED 0x8510007d +#define STORM_ERROR_MEM_NOT_FREED 0x8510007e +#define STORM_ERROR_RESOURCES_NOT_RELEASED 0x8510007f +#define STORM_ERROR_OUT_OF_BOUNDS 0x85100080 +#define STORM_ERROR_NULL_POINTER 0x85100081 +#define STORM_ERROR_CDKEY_MISMATCH 0x85100082 +#define STORM_ERROR_FILE_CORRUPTED 0x85100083 +#define STORM_ERROR_FATAL 0x85100084 +#define STORM_ERROR_GAMETYPE_UNAVAILABLE 0x85100085 + + +/* SMemCopy @ 491 + * + * Copies a block of memory from source to destination. + * This function immediately calls memcpy. See online documentation + * of memcpy for more details. + * + * dest: The destination buffer. + * source: The source buffer. + * size: The number of bytes to copy. + */ +void +STORMAPI +SMemCopy( + void *dest, + const void *source, + size_t size); + +#define SMCopy(d,s) ( SMemCopy(d, s, __STORM_SSIZEMIN(s,d)) ) + +/* SMemFill @ 492 + * + * Fills a block of memory with the specified character. + * This function immediately calls memset. See online documentation + * of memset for more details. + * + * dest: The destination buffer. + * source: The size of the destination buffer. + * size: The format to use. + */ +void +STORMAPI +SMemFill( + void *location, + size_t length, + char fillWith = 0); + +#define SMFill(l,f) (SMemFill(l, sizeof(l), f)) + +/* SMemZero @ 494 + * + * Fills a block of memory with the integer 0x00 (Zero). + * + * location: The location to write at. + * length: The amount of bytes to write. + */ +void +STORMAPI +SMemZero( + void *location, + size_t length); + +#define SMZero(l) (SMemZero(l, sizeof(l))) + + +int STORMAPI SMemCmp(void *location1, void *location2, DWORD size); + +#define SMCmp(l,x) ( SMemCmp(l, x, __STORM_SSIZEMIN(x,l)) ) + +/* SStrCopy @ 501 + * + * Copies a string from src to dest (including NULL terminator) + * until the max_length is reached. + * + * dest: The destination array. + * src: The source array. + * max_length: The maximum length of dest. + * + * Returns the number of characters copied. + */ +int +STORMAPI +SStrCopy( + char *dest, + const char *src, + int max_length = 0x7FFFFFFF); + +#define SSCopy(d,s) (SStrCopy(d, s, sizeof(d))) + +#define STORM_HASH_ABSOLUTE 1 + +/* SStrHash @ 502 + * + * Creates a simple hash for the string. This function + * should NOT be used for sensitive information. + * + * string: The input string. + * flags: If STORM_HASH_ABSOLUTE is set then this + function uses the absolute string, otherwise + it will convert backslashes to forward + slashes and some other processing. + * seed: The hash seed. If this value is 0 then the + * default value 0x7FED7FED will be used. + * + * Returns the 32-bit hash of the string. + */ +DWORD +STORMAPI +SStrHash( + const char *string, + DWORD flags = 0, + DWORD Seed = 0); + +int STORMAPI SStrNCat(char *dest, const char *src, DWORD max_length); + +/* SStrLen @ 506 + * + * Retrieves the length of a string. + * + * string: The input string of which to obtain a + * length for. + * + * Returns the length of the string. + */ +int +STORMAPI +SStrLen( + const char *string); + +/* SStrCmp @ 508 + * + * Compares two strings case sensitive. + * + * string1: The first string. + * string2: The second string. + * size: The maximum amount of characters to compare. + * + * Returns 0 if strings are equal. See strcmp documentation for more details. + */ +int +STORMAPI +SStrCmp( + const char *string1, + const char *string2, + size_t size); + +#define SSCmp(s,x) ( SStrCmp(s,x,__STORM_SSIZEMIN(s,x)) ) + +/* SStrCmpI @ 509 + * + * Compares two strings case insensitive. + * + * string1: The first string. + * string2: The second string. + * size: The maximum amount of characters to compare. + * + * Returns 0 if strings are equal. See strcmpi documentation for more details. + */ +int +STORMAPI +SStrCmpI( + const char *string1, + const char *string2, + size_t size); + +#define SSCmpI(s,x) ( SStrCmpI(s,x,__STORM_SSIZEMIN(s,x)) ) + +/* SStrUpper @ 510 + * + * Converts all lower-case alpha characters of a string to upper-case. + * + * string: The string to convert. + * + * Returns the same pointer given in the input. + */ +char* +STORMAPI +SStrUpper( + char* string); + +void STORMAPI SRgn523(HANDLE hRgn, RECT *pRect, int a3, int a4); +void STORMAPI SRgnCreateRegion(HANDLE *hRgn, int a2); +void STORMAPI SRgnDeleteRegion(HANDLE hRgn); + +void STORMAPI SRgn529i(int handle, int a2, int a3); + + +/* SErrDisplayErrorFmt @ 562 + * + * Displays a formatted error message. The message is detailed and flexible for many applications. + * The message will be different if there is a debugger attached. Will typically terminate the application + * unless the option to continue is given. + * + * dwErrMessage: The error code. See SErrGetLastError and GetLastError. + * logfilename: The name of the file or object that this call belongs to. + * logline: The line in the file or one of the SLOG_ macros. + * allowOption: If TRUE, allows the user the option to continue execution, otherwise the program will terminate. + * exitCode: The exit code used for program termination. + * format: Additional message formatting. See printf. + * + * Returns TRUE if the user chose to continue execution, FALSE otherwise. + */ +BOOL +SErrDisplayErrorFmt( + DWORD dwErrMsg, + const char *logfilename, + int logline, + BOOL allowOption, + int exitCode, + const char *format, + ...); + +//#define SEDisplayErrorFmt(err,...) SErrDisplayErrorFmt(err, __FILE__, __LINE__, FALSE, 1, __VA_ARGS__) + +/* SErrCatchUnhandledExceptions @ 567 + * + * Registers a top-level exception filter managed entirely by Storm. + * The registered filter will display formatted exception information by calling SErrDisplayError. + */ +void +STORMAPI +SErrCatchUnhandledExceptions(); + + +/* SStrChr @ 571 + * + * Searches a string for the given character. See + * strchr documentation for more details. + * + * string: The string to search. + * c: The character to search for. + * + * Returns a pointer to the first occurance of the character. + */ +char* +STORMAPI +SStrChr( + const char *string, + char c); + + +char *STORMAPI SStrChrR(const char *string, char c); + + +/* SStrVPrintf @ 578 + * + * Prints a formatted string to a destination buffer. + * This function calls vsnprintf with some extra error handling. + * See online documentation of vsnprintf for more details. + * + * dest: The destination buffer. + * size: The size of the destination buffer. + * format: The format to use. + * + * Returns the number of characters written. + */ +size_t +SStrVPrintf( + char *dest, + size_t size, + const char *format, ...); + + +int STORMAPI SBigDel(void *buffer); + +int STORMAPI SBigFromBinary(void *buffer, const void *str, size_t size); + +int STORMAPI SBigNew(void **buffer); + +int STORMAPI SBigPowMod(void *buffer1, void *buffer2, int a3, int a4); + +int STORMAPI SBigToBinaryBuffer(void *buffer, int length, int a3, int a4); + +void __stdcall SDrawMessageBox(char *,char *,int); +void __cdecl SDrawDestroy(void); +bool __cdecl StormDestroy(void); +bool __stdcall SFileSetBasePath(char *); +void __cdecl SDrawRealizePalette(void); +bool __cdecl SVidPlayContinue(void); +bool __stdcall SNetGetOwnerTurnsWaiting(int *); +void * __stdcall SNetUnregisterEventHandler(int,void (__stdcall*)(struct _SNETEVENT *)); +void * __stdcall SNetRegisterEventHandler(int,void (__stdcall*)(struct _SNETEVENT *)); +bool __stdcall SNetSetBasePlayer(int); +int __stdcall SNetInitializeProvider(unsigned long,struct _SNETPROGRAMDATA *,struct _SNETPLAYERDATA *,struct _SNETUIDATA *,struct _SNETVERSIONDATA *); +int __stdcall SNetGetProviderCaps(struct _SNETCAPS *); +int __stdcall SFileSetFilePointer(int,int,int,int); +#endif diff --git a/2018_03_14/storm/stormapi.txt b/2018_03_14/storm/stormapi.txt new file mode 100644 index 00000000..fa522018 --- /dev/null +++ b/2018_03_14/storm/stormapi.txt @@ -0,0 +1,577 @@ +Retrieved from: http://vgce.googlecode.com/svn/trunk/docs/Blizzard/Starcraft/ + +#summary Storm.dll Functions and their Ordinals +Note: Some name assignments may not be accurate, or may be out-dated. This is for the Starcraft: Broodwar version of storm.dll. If there are any corrections to be made, please post a comment. + +{{{ +100 SNetInit() // guess +101 BOOL __stdcall SNetCreateGame(char *Source, char *a2, char *a3, int a4, int a5, int a6, char *a7, char *a8, int *playerid) +102 BOOL __cdecl SNetDestroy() +103 BOOL __stdcall SNetEnumDevices(int (__stdcall *callback)(DWORD, DWORD, DWORD, DWORD), int mincaps) +104 BOOL __stdcall SNetEnumGames(int (__stdcall *callback)(DWORD, DWORD, DWORD), int *hintnextcall) +105 BOOL __stdcall SNetEnumProviders(int (__stdcall *callback)(DWORD, DWORD, DWORD)) +106 BOOL __stdcall SNetDropPlayer(int playerid, DWORD flags) +107 BOOL __stdcall SNetGetGameInfo(int type, char *src, unsigned int length, int *byteswritten) +108 BOOL __stdcall SNetGetNetworkLatency(int measurementtype, int *result) +109 BOOL __stdcall SNetGetNumPlayers(int *firstplayerid, int *lastplayerid, int *activeplayers) +110 BOOL __stdcall SNetGetOwnerTurnsWaiting(int *turns) +111 BOOL __stdcall SNetGetPerformanceData(int counterid, int *countervalue, int *countertype, int *counterscale, LPFILETIME *measurementtime, int *measurementfreq) +112 BOOL __stdcall SNetGetPlayerCaps(char playerid, int *caps) +113 BOOL __stdcall SNetGetPlayerName(int playerid, char *buffer, size_t buffersize) +114 BOOL __stdcall SNetGetProviderCaps(char *caps) +115 BOOL __stdcall SNetGetTurnsInTransit(int *turns) +116 BOOL __stdcall SNetInitializeDevice(int a1, int a2, int a3, int a4, int *a5) +117 BOOL __stdcall SNetInitializeProvider(DWORD providerName, int *providerData, int *userData, int *a4, int *a5) // contains verbyte in providerData +118 BOOL __stdcall SNetJoinGame(unsigned int a1, char *gameName, char *gamePassword, char *playerName, char *userStats, int *playerid) +119 BOOL __stdcall SNetLeaveGame(int type) +120 BOOL __stdcall SNetPerformUpgrade(DWORD *upgradestatus) +121 BOOL __stdcall SNetReceiveMessage(int *senderplayerid, BYTE **data, int *databytes) +122 BOOL __stdcall SNetReceiveTurns(int a1, int arraysize, char **arraydata, unsigned int *arraydatabytes, DWORD *arrayplayerstatus) // arraysize = player count +123 HANDLE __stdcall SNetRegisterEventHandler(int type, int event) +124 BOOL __cdecl SNetResetLatencyMeasurements() +125 int __stdcall SNetSelectGame(int a1, int a2, int a3, int a4, int a5, int *playerid) // a2 is a buffer containing the verbyte +126 BOOL __stdcall SNetSelectProvider(LPARAM lparam, int a2, int a3, int a4, int a5, int *providerid) +127 BOOL __stdcall SNetSendMessage(unsigned int playerID, char *data, unsigned int databytes) +128 BOOL __stdcall SNetSendTurn(char *data, unsigned int databytes) +129 BOOL __stdcall SNetSetBasePlayer(unsigned int a1) +130 BOOL __stdcall SNetSetGameMode(DWORD modeFlags, char a2) +131 BOOL __stdcall SNetUnregisterEventHandler(unsigned int a1, char *callback) + +133 BOOL __stdcall SNetEnumGamesEx(int a1, int a2, int (__fastcall *callback)(DWORD, DWORD, DWORD), int *hintnextcall) +134 int __stdcall SNetSendServerChatCommand(const char *command) +135 BOOL __stdcall SNetSend135(signed int playerID, const char *buffer, unsigned int length) // special case for playerID -1 and -2 +136 BOOL __stdcall SNetReceive136(int a1, int a2, int a3) +137 BOOL __stdcall SNet137(DWORD flags) // this can't be SNetGetPlayerNames +138 BOOL __stdcall SNetCreateLadderGame(char *gameName, char *gamePassword, char *gameDataString, DWORD gameType, int a5, int a6, char *GameTemplateData, int GameTemplateSize, int playerCount, char *playerName, char *a11, int *playerID) +139 BOOL __stdcall SNetReportGameResult(unsigned int a1, int size, int a3, int a4, int a5) +140 BOOL __stdcall SNetCheckDataFile(int a1, int a2, int a3, int a4) +141 int __stdcall SNetSendLeagueCommand(char *cmd, char *callback) +142 int __stdcall SNetSendReplayPath(int a1, int a2, char *replayPath) +143 int __stdcall SNetGetLeagueName(int leagueID) // not official name +144 BOOL __stdcall SNet144(char *buffer) +145 int __stdcall SNetLeagueLogout(char *bnetName) +146 int __stdcall SNetGetLeaguePlayerName(int *curPlayerID, size_t nameSize) // not official name + +150 void __cdecl Ordinal150() +151 BOOL __stdcall Ordinal151(int a1, int a2) // WC3 + +200 SDlgInit() +201 HDC __stdcall SDlgBeginPaint(HWND window, LPPAINTSTRUCT ps) +202 BOOL __stdcall SDlgBltToWindowI(HWND window, HRGN hrgnSrc2, int a3, int a4, int a5, int a6, int a7, int a8, int a9, int a10) +203 BOOL __cdecl SDlgCheckTimers() +204 HWND __stdcall SDlgCreateDialogIndirectParam(HMODULE hModule, LPCSTR lpName, HWND hWndParent, LPVOID lpParam) +205 HWND __stdcall SDlgCreateDialogParam(HMODULE hModule, LPCSTR lpName, HWND hWndParent, LPVOID lpParam) +206 HGDIOBJ __stdcall SDlgDefDialogProc(HWND hDlg, signed int DlgType, HDC textLabel, HWND hWnd) +207 SDlgDestroy() +208 HANDLE __stdcall SDlgDialogBoxIndirectParam(HMODULE hModule, LPCSTR lpName, HWND hWndParent, LPVOID lpParam, LPARAM lParam) +209 HANDLE __stdcall SDlgDialogBoxParam(HMODULE hModule, LPCSTR lpName, HWND hWndParent, LPVOID lpParam, LPARAM lParam) +210 BOOL __stdcall SDlgDrawBitmap(HWND window, HGDIOBJ a2, HRGN hrgnSrc2, int a4, int a5, int a6, char a7) +211 BOOL __stdcall SDlgEndDialog(HWND hDlg, HANDLE nResult) +212 BOOL __stdcall SDlgEndPaint(HWND hWnd, PAINTSTRUCT *lpPaint) +213 BOOL __stdcall SDlgKillTimer(HWND hDlg, int state) +214 BOOL __stdcall SDlgSetBaseFont(int a1, int a2, int a3, int a4, char *Source) +215 BOOL __stdcall SDlgSetBitmapI(HWND hWnd, int a2, char *Str2, int mask1, int flags, int a6, int a7, int a8, int a9, int mask2) +216 BOOL __stdcall SDlgSetControlBitmaps(HWND parentwindow, int *id, int a3, char *buffer2, char *buffer, int flags, int mask) +217 BOOL __stdcall SDlgSetCursor(HWND hWnd, LONG dwNewLong, int a3, int a4) +218 BOOL __stdcall SDlgSetSystemCursor(int a1, int a2, int a3, signed int a4) +219 int __stdcall SDlgSetTimer(HWND hDlg, int state, int time, int a4) +220 BOOL __cdecl SDlgUpdateCursor() +221 BOOL __stdcall SDlgBltToWindowE(HWND hWnd, HRGN a2, char *a3, int a4, int a5, int a6, int a7, int a8, int a9, int a10) +222 BOOL __stdcall SDlgSetBitmapE(HWND hWnd, int a2, char *src, int mask1, int flags, int a6, int a7, int width, int a9, int mask2) +223 char* __stdcall SDlgSetLocale(int category, const char *locale) +224 int __stdcall Ordinal224(int a1) // BNET/League related + +250 SFileInit() +251 BOOL __stdcall SFileAuthenticateArchive(HANDLE hArchive, DWORD *dwResult) // (signature) file in archive +252 BOOL __stdcall SFileCloseArchive(HANDLE hArchive) +253 BOOL __stdcall SFileCloseFile(HANDLE hFile) +254 BOOL __stdcall SFileDdaBegin(HANDLE directsound, int a2, int a3) +255 BOOL __stdcall SFileDdaBeginEx(HANDLE directsound, DWORD flags, DWORD mask, unsigned __int32 lDistanceToMove, signed __int32 volume, signed int a6, int a7) +256 BOOL __cdecl SFileDdaDestroy() +257 BOOL __stdcall SFileDdaEnd(HANDLE directsound) +258 BOOL __stdcall SFileDdaGetPos(HANDLE directsound, int a2, int a3) +259 BOOL __stdcall SFileDdaGetVolume(HANDLE directsound, int a2, int a3) +260 BOOL __stdcall SFileDdaInitialize(HANDLE directsound) +261 BOOL __stdcall SFileDdaSetVolume(HANDLE directsound, signed int bigvolume, signed int volume) +262 BOOL __cdecl SFileDestroy() +263 BOOL __stdcall SFileEnableDirectAccess(BOOL access) +264 BOOL __stdcall SFileGetFileArchive(HANDLE hFile, HANDLE archive) +265 LONG __stdcall SFileGetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh) +266 BOOL __stdcall SFileOpenArchive(char *archivename, DWORD dwPriority, DWORD dwFlags, HANDLE handle) +267 BOOL __stdcall SFileOpenFile(char *filename, HANDLE handle) +268 BOOL __stdcall SFileOpenFileEx(HANDLE hMpq, const char *szFileName, DWORD dwSearchScope, HANDLE *phFile) +269 BOOL __stdcall SFileReadFile(HANDLE hFile, void *buffer, DWORD nNumberOfBytesToRead, int *read, LONG lpDistanceToMoveHigh) +270 BOOL __stdcall SFileSetBasePath(char *path) +271 LONG __stdcall SFileSetFilePointer(HANDLE hFile, LONG filePos, LONG *filePosHigh, DWORD dwMethod) +272 void __stdcall SFileSetLocale(LCID lcLocale) +273 BOOL __stdcall SFileGetBasePath(char *result, int maxSize) +274 BOOL __stdcall SFileSetIoErrorMode(int mode, void *callback) +275 BOOL __stdcall SFileGetArchiveName(HANDLE hArchive, char *name, int length) +276 BOOL __stdcall SFileGetFileName(HANDLE hFile, char *buffer, int length) +277 BOOL __stdcall SFileGetArchiveInfo(int a1, int a2, int a3) +278 char __stdcall SFileSetPlatform(char a1) +279 BOOL __stdcall SFileLoadFile(char *filename, void *buffer, int buffersize, int a4, int a5) +280 BOOL __stdcall SFileUnloadFile(HANDLE hFile) +281 BOOL __stdcall SFileLoadFileEx(void *hArchive, char *filename, int a3, int a4, int a5, DWORD searchScope, struct _OVERLAPPED *lpOverlapped) +282 void __stdcall SFilePrioritizeRequest(int a1, int a2) +283 void __stdcall SFileCancelRequest(int a1) +284 int __stdcall SFileSetAsyncBudget(DWORD dwBudget) +285 void __stdcall SFileSetDataChunkSize(DWORD dwSize) +286 int __stdcall SFileEnableSeekOptimization(int a1) +287 BOOL __stdcall SFileReadFileEx(int a1, int a2, int a3, int a4, PLONG lpDistanceToMoveHigh, int a6) +288 DWORD __stdcall SFileFileExists(HANDLE hFile) +289 DWORD __stdcall SFileFileExistsEx(HANDLE hFile, void *buffer, DWORD nNumberOfBytesToRead, int *read, LONG lpDistanceToMoveHigh, int a6, int a7); +290 BOOL __stdcall SFileReadFileEx2(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8) +291 BOOL __stdcall SFileReadFile2(int a1, void *a2, size_t a3, int a4, int a5, int a6, int a7) +292 BOOL __stdcall SFileLoadFile2(int a1, int a2, int a3, int a4, size_t a5, int a6, int a7, int a8) +293 BOOL __stdcall SFileOpenFileAsArchive(int a1, char *a2, int a3, int a4, int a5) +294 LCID __cdecl SFileGetLocale() +295 int __stdcall SFileRegisterLoadNotifyProc(int a1, int a2) +296 int __stdcall SFileGetFileCompressedSize(int a1, int a2) +297 BOOL __stdcall Ordinal297(int a1, int a2, int a3) +298 void __cdecl Ordinal298() +299 BOOL __stdcall SFileAuthenticateArchiveEx(int a1, int a2, int a3, int a4, int a5, DWORD NumberOfBytesRead) +300 BOOL __stdcall SFileOpenPathAsArchive(int a1, int a2, int a3, int a4, int a5) +301 BOOL __cdecl StormDestroy() +302 HMODULE __cdecl StormGetInstance() +303 BOOL __stdcall StormGetOption(int type, int optval, size_t optlen) +304 BOOL __stdcall StormSetOption(int type, int optval, size_t optlen) + +311 SBltDestroy() +312 BOOL __stdcall SBltGetSCode(unsigned int maxiterations, char *buffer, size_t buffersize, char *loopstring) +313 BOOL __stdcall SBltROP3(int maxiterations, int lpSurface, int width, int height, int width2, int pitch, int a7, DWORD rop) +314 BOOL __stdcall SBltROP3Clipped(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9, int a10) +315 BOOL __stdcall SBltROP3Tiled(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9, int a10) + +320 SBmpInit() +321 BOOL __stdcall SBmpDecodeImage(int type, signed int *srcbuffer, unsigned int a3, int a4, void *dstbuffer, int size, int a7, int a8, int a9) +322 SBmpDestroy() +323 BOOL __stdcall SBmpLoadImage(const char *fileName, int size, void *buffer, int buffersize, int width, int height, int depth) +324 BOOL __stdcall SBmpSaveImage(const char *fileName, int paletteentries, int bitdepth, unsigned __int16 width, unsigned __int16 height, int bitmapbits) +325 HANDLE __stdcall SBmpAllocLoadImage(const char *fileName, int *palette, void **buffer, int *width, int *height, int unused6, int unused7, void *(__stdcall *allocFunction)(DWORD)) +326 BOOL __stdcall SBmpSaveImageEx(const char *fileName, int paletteentries, int bitdepth, unsigned __int16 width, unsigned __int16 height, int bitmapbits, int reserved) + +330 SCodeInit() +331 BOOL __stdcall SCodeCompile(char *directives1, char *directives2, char *loopstring, unsigned int maxiterations, unsigned int flags, HANDLE handle) +332 BOOL __stdcall SCodeDelete(HANDLE handle) +333 SCodeDestroy() +334 int __cdecl SCodeExecute(HANDLE handle, int a2) +335 BOOL __stdcall SCodeGetPseudocode(int scodestring, int buffer, size_t buffersize) + +340 SDrawInit() +341 BOOL __stdcall SDrawAutoInitialize(HINSTANCE hInst, LPCSTR lpClassName, LPCSTR lpWindowName, LRESULT (WINAPI *pfnWndProc)(HWND, UINT, WPARAM, LPARAM), int nMode, int nWidth, int nHeight, int nBits) +342 BOOL __stdcall SDrawCaptureScreen(char *source) +343 BOOL __stdcall SDrawClearSurface(int surfacenumber) +344 BOOL __cdecl SDrawDestroy() +345 BOOL __cdecl SDrawFlipPage() +346 HWND __stdcall SDrawGetFrameWindow(HWND sdraw_framewindow) +347 BOOL __stdcall SDrawGetObjects(LPDIRECTDRAW ddInterface, LPDIRECTDRAWSURFACE primarySurface, LPDIRECTDRAWSURFACE surface2, LPDIRECTDRAWSURFACE surface3, LPDIRECTDRAWSURFACE backSurface, LPDIRECTDRAWPALETTE ddPalette, HPALETTE hPalette); +348 BOOL __stdcall SDrawGetScreenSize(int width, int height, int depth) +349 BOOL __stdcall SDrawGetServiceLevel(int a1) +350 BOOL __stdcall SDrawLockSurface(int surfacenumber, RECT *lpDestRect, void **lplpSurface, int *lpPitch, int arg_unused) +351 BOOL __stdcall SDrawManualInitialize(HWND hWnd, IDirectDraw *ddInterface, IDirectDrawSurface *primarySurface, int a4, int a5, IDirectDrawSurface *backSurface, IDirectDrawPalette *palette, int a8) +352 DWORD __stdcall SDrawMessageBox(LPCSTR lpText, LPCSTR lpCaption, UINT uType) +353 BOOL __cdecl SDrawPostClose() +354 BOOL __cdecl SDrawRealizePalette() +355 BOOL __stdcall SDrawSelectGdiSurface(unsigned int a1, int a2) +356 BOOL __stdcall SDrawUnlockSurface(int surfacenumber, void *lpSurface, int a3, RECT *lpRect) +357 BOOL __stdcall SDrawUpdatePalette(unsigned int firstentry, unsigned int numentries, PALETTEENTRY *pPalEntries, int a4) +358 BOOL __stdcall SDrawUpdateScreen(BOOL bErase) +359 int __cdecl SDrawWaitForVerticalBlank() + +372 BOOL __stdcall SEvtDispatch(DWORD dwMessageID, DWORD dwFlags, int type, s_evt *event) +373 BOOL __stdcall SEvtRegisterHandler(DWORD messageID, DWORD type, int command, int class, void *callback) +374 BOOL __stdcall SEvtUnregisterHandler(DWORD messageID, int a2, int a3, int a4) +375 BOOL __stdcall SEvtUnregisterType(DWORD messageID, int type) +376 BOOL __stdcall SEvtPopState(DWORD messageID, int type) +377 BOOL __stdcall SEvtPushState(DWORD messageID, int type) +378 BOOL __stdcall SEvtBreakHandlerChain(int a1) + +380 SGdiInit() +381 BOOL __stdcall SGdiBitBlt(int a1, int a2, int a3, int a4, unsigned int a5, int a6, int a7, unsigned int a8, signed int a9) +382 BOOL __stdcall SGdiCreateFont(HANDLE handle, int bits, int width, int height, int filecharwidth, int filecharheight, const void *charsizetable, int windowsfont) +383 BOOL __stdcall SGdiDeleteObject(HANDLE handle) +384 BOOL __cdecl SGdiDestroy() +385 BOOL __stdcall SGdiExtTextOut(int a1, int a2, int a3, int a4, unsigned int a8, signed int a6, signed int a7, const char *string, unsigned int arg20) +386 BOOL __stdcall SGdiImportFont(HGDIOBJ handle, int windowsfont) +387 BOOL __stdcall SGdiLoadFont(char *Str, int filecharwidth, int filecharheight, int argC, int a7, int a8) +388 BOOL __stdcall SGdiRectangle(int lpSurface, int a2, int a3, int width, int height, int a6) +389 BOOL __stdcall SGdiSelectObject(int handle) +390 BOOL __stdcall SGdiSetPitch(int pitch) +391 BOOL __stdcall SGdiTextOut(int a1, int a2, int a3, unsigned int a8, const char *string, unsigned int arg20) +392 BOOL __stdcall SGdi392(int width, int height, int depth, int width2) // SGdiGetTextExtent? +393 BOOL __stdcall Ordinal393(char *string, int, int) + +399 BOOL __stdcall SMem399(int a1, int a2, int a3, void *a4, unsigned int a5) // calls to SMemDumpStateEx and SMemMarkAllHeapsEx +400 SMemInit() +401 void* __stdcall SMemAlloc(int amount, char *logfilename, int logline, int defaultValue) +402 BOOL __cdecl SMemDestroy() +403 BOOL __stdcall SMemFree(void *location, char *logfilename, int logline, char defaultValue) +404 int __stdcall SMemGetSize(void *location, char *logfilename, int logline) +405 void* __stdcall SMemReAlloc(void *location, int amount, char *logfilename, int logline, int defaultValue) +406 int __stdcall Storm406(int a1, int a2, int a3) // WC3 + +412 BOOL __stdcall SMsgDispatchMessage(HWND hWnd, DWORD messageID, WPARAM wParam, LPARAM lParam, int a5, int a6) +413 WPARAM __stdcall SMsgDoMessageLoop(void *callback, int followWithStormDestroy) +414 BOOL __stdcall SMsgRegisterCommand(int a1, int event, int a3) // SMSH +415 BOOL __stdcall SMsgRegisterKeyDown(int a1, int event, int a3) // SMSJ +416 BOOL __stdcall SMsgRegisterKeyUp(int a1, int event, int a3) // SMSK +417 BOOL __stdcall SMsgRegisterMessage(int a1, int event, int a3) // SMSG +418 BOOL __stdcall SMsgPopRegisterState(int type) +419 BOOL __stdcall SMsgPushRegisterState(int type) +420 BOOL __stdcall SMsg420(int a1, int a2, int a3) // Register SMSI +421 BOOL __stdcall SRegLoadData(char *keyname, char *valuename, BYTE flags, LPBYTE lpData, int size, LPDWORD lpcbData) +422 BOOL __stdcall SRegLoadString(char *keyname, char *valuename, BYTE flags, char *buffer, size_t buffersize) +423 BOOL __stdcall SRegLoadValue(char *keyname, char *valuename, BYTE flags, int *value) +424 BOOL __stdcall SRegSaveData(char *keyname, char *valuename, int size, BYTE *lpData, DWORD cbData) +425 BOOL __stdcall SRegSaveString(char *keyname, char *valuename, BYTE flags, char *string) +426 BOOL __stdcall SRegSaveValue(char *keyname, char *valuename, BYTE flags, DWORD result) +427 BOOL __stdcall SRegGetBaseKey(BYTE flags, char *buffer, size_t bufferchars) +428 BOOL __stdcall SRegDeleteValue(char *keyname, char *valuename, BYTE flags) +429 BOOL __stdcall SReg429(char *keyname, DWORD dwflags, DWORD dwIndex, char *, size_t) +430 BOOL __stdcall SReg430(char *keyname, int a2, DWORD cSubKeys) +431 BOOL __stdcall STransBlt(int handle, int a2, int a3, int a4, int a5) +432 BOOL __stdcall STransBltUsingMask(int lpSurface, int a2, int pitch, int width, int handle) +433 BOOL __stdcall STransCreateI(int handle, int a2, int a3, signed int a4, int a5, int a6, int a7) +434 BOOL __stdcall STransDelete(int handle) +435 STransDestroy() +436 BOOL __stdcall STransDuplicate(int handle, int source) +437 BOOL __stdcall STransIntersectDirtyArray(int handle, int dirtyarraymask, unsigned __int8 dirtyarray, int sourcemask) +438 BOOL __stdcall STransInvertMask(int handle, int sourcemask) +439 BOOL __stdcall STransLoadI(char *filename, int a2, int a3, int handle) +440 BOOL __stdcall STransSetDirtyArrayInfo(int width, int height, int depth, int bits) +441 BOOL __stdcall STransUpdateDirtyArray(int a1, char a2, int a3, int a4, int a5, int a6) // dirtyarray, dirtyvalue, transparency +442 BOOL __stdcall STrans442(int a1, int a2, int a3, char *a4, size_t a5) // STransIsPixelInMask? STransGetBoundingRect? +443 BOOL __stdcall STransCombineMasks(int handle, int a2, int a3, int a4, int depth, int a6) +444 BOOL __stdcall STransCreateI(int a1, int a2, int a3, int a4, int a5, int a6, int a7) +445 BOOL __stdcall STransCreateE(int a1, int a2, int a3, int bpp, int a5, int bufferSize, int a7) +446 BOOL __stdcall STrans446(int a1, int a2, int a3, int a4, int a5, int a6, int a7) // STransIsPixelInMask? STransGetBoundingRect? +447 BOOL __stdcall STransLoadE(char *filename, int a2, int a3, int handle) + +450 SVidInit() +451 BOOL __cdecl SVidDestroy() +452 BOOL __stdcall SVidGetSize(HANDLE video, int width, int height, int zero) +453 BOOL __stdcall SVidInitialize(HANDLE video) +454 BOOL __stdcall SVidPlayBegin(char *filename, int arg4, int a3, int a4, int a5, int a6, HANDLE video) +455 BOOL __stdcall SVidPlayBeginFromMemory(void *destbuffer, int destsize, int arg4, int a3, int a4, int a6, int sourcebytes, int sourceptr) // flags, paletteuse +456 BOOL __cdecl SVidPlayContinue() +457 BOOL __stdcall SVidPlayContinueSingle(HANDLE video, int a2, int a3) +458 BOOL __stdcall SVidPlayEnd(HANDLE video) +459 BOOL __stdcall SVidSetVolume(HANDLE video, int a2, int a3, int type) +460 int __stdcall Storm460(int a1) // WC3 +461 BOOL __stdcall SErrDisplayError(DWORD dwErrCode, char *logfile, int logline, int location, int exitCode, UINT uExitCode) +462 BOOL __stdcall SErrGetErrorStr(DWORD dwErrCode, char *buffer, size_t bufferchars) +463 DWORD __cdecl SErrGetLastError() +464 BOOL __stdcall SErrRegisterMessageSource(__int16 a1, int a2, int a3) +465 void __stdcall SErrSetLastError(DWORD dwErrCode) +466 void __stdcall SErrReportNamedResourceLeak(char *resourceName, int a2) +467 void __stdcall SErrReportResourceLeak(char *resourceName) +468 void __stdcall SErrSuppressErrors(bool suppressErrors) +469 void __stdcall SErrRegisterHandler(int a1) +470 void __stdcall SErrUnregisterHandler(int a1) +471 unsigned int __stdcall Storm471(void *a1, unsigned int a2, int a3) // WC3 +472 BOOL __stdcall SCmdGetBool(int argnum) +473 int __stdcall SCmdGetNum(int argnum) +474 BOOL __stdcall SCmdGetString(int argnum, char* dest, size_t size) +475 BOOL __stdcall SCmdProcess(const char **string, int a2, int a3, int a4) +476 BOOL __stdcall SCmdRegisterArgList(void *argstruct, int count) +477 BOOL __stdcall SCmdRegisterArgument(int a1, int a2, char *str, int a4, int a5, int a6, int a7, int a8) +478 int __stdcall SCmdStringExists(int argnum) +479 BOOL __stdcall SCmdProcessCommandLine(int count, void *function) +480 BOOL __stdcall SCmd480(int a1, int a2) // WC3 +481 BOOL __stdcall SMemFindNextBlock(int a1, int a2, int a3, int a4) +482 BOOL __stdcall SMemFindNextHeap(int prevheap, int details, int nextheap) +483 int __stdcall SMemGetHeapByCaller(int a1, int a2) +484 int __stdcall SMemGetHeapByPtr(int a1) +485 int __stdcall SMemHeapAlloc(int a1, int a2, int a3) +486 int __stdcall SMemHeapCreate(int a1, int a2, int a3, char a4, DWORD ExitCode) +487 BOOL __stdcall SMemHeapDestroy(int a1) +488 BOOL __stdcall SMemHeapFree(int a1, int a2, void *a3) +489 int __stdcall SMemHeapRealloc(int a1, int a2, void *a3, int a4) +490 int __stdcall SMemHeapSize(int a1, int a2, void *a3) +491 void __stdcall SMemCopy(void *dest, const void *source, size_t size) +492 int __stdcall SMemFill(void *location, size_t length, char fillWith) +493 int __stdcall SMemMove(void *dest, void *source, size_t size) +494 int __stdcall SMemZero(void *location, size_t length) +495 int __stdcall SMemCmp(void *location1, void *location2, size_t size) +496 int __stdcall SMem496(unsigned int a1, char a2) // either SMemGetAllocated or SMemSetDebugFlags +497 BOOL __stdcall SMemDumpState(int (__stdcall *a1)(_DWORD, _DWORD), int a2) +498 void __cdecl Ordinal498() + +500 SStrInit() +501 int __stdcall SStrCopy(char *dest, const char *source, size_t size) +502 DWORD __stdcall SStrHash(const char *string, DWORD flags, DWORD Seed) +503 int __stdcall SStrNCat(char *base, char *new, int max_length) +504 void __stdcall SStrTokenize(const char **string, char *(*string), char *buffer, const char *whitespace, size_t size) +505 char* __stdcall SStrPack(const char *string, char c, int type) +506 int __stdcall SStrLen(const char* string) +507 char* __stdcall SStrDup(const char* string) +508 int __stdcall SStrCmp(const char *string1, const char *string2, size_t size) +509 int __stdcall SStrCmpI(const char *string1, const char *string2, size_t size) +510 char* __stdcall SStrUpper(char* string) +511 BOOL __stdcall SMsgBreakHandlerChain(int a1) +512 BOOL __stdcall SMsgUnregisterCommand(int a1, int a2, int a3) // SMSH +513 BOOL __stdcall SMsgUnregisterKeyDown(int a1, int a2, int a3) // SMSJ +514 BOOL __stdcall SMsgUnregisterKeyUp(int a1, int a2, int a3) // SMSK +515 BOOL __stdcall SMsgUnregisterMessage(int a1, int a2, int a3) // SMSG +516 int __stdcall SMsg516(int a1) // calls 412.. WC3 does weird stuff here +517 BOOL __stdcall SMsgSetDefaultWindow(HWND window) +518 HWND __cdecl SMsgGetDefaultWindow() +519 BOOL __stdcall SMsg519(int a1, int a2, int a3) // Unregister SMSI + +521 void __stdcall Ordinal521(int a1) + +523 void __stdcall SRgn523(int handle, RECT *rect, int reserved, int a4) +524 void __stdcall SRgnCreate(int handle, int reserved) +525 void __stdcall SRgnDelete(int handle) + +527 void __stdcall SRgn527(int handle, int a2, int a3) +528 void __stdcall SRgn528i(int handle, int a2, int a3, int a4) // 534 +529 void __stdcall SRgn529i(int handle, int a2, int a3) // 536 +530 void __stdcall SRgn530i(int handle, int a2) // 537 +531 BOOL __stdcall SRgn531i(int handle, int a2, int a3) //538 +532 BOOL __stdcall SRgn532i(int handle, int a2) // 539 +533 void __stdcall SRgn533i(int handle, int a2, int a3) // 540 +534 void __stdcall SRgn534(int handle, int a2, int a3, int a4) +535 void __stdcall SRgn535f(int handle, float a2, float a3, float a4) +536 void __stdcall SRgn536f(int handle, float a2, float a3) +537 void __stdcall SRgn537f(int handle, float a2) +538 BOOL __stdcall SRgn538f(int handle, float a2, float a3) +539 BOOL __stdcall SRgn539f(int handle, float a2) +540 void __stdcall SRgn540f(int handle, float a2, float a3) +541 void __stdcall SLogClose(DWORD NumberOfBytesWritten) +542 HANDLE __stdcall SLogCreate(char *filename, int a2, int a3) +543 void __stdcall SLog543(int a1, int a2) +544 void __stdcall SLogDump(int a1, int a2, DWORD NumberOfBytesWritten) +545 void __stdcall SLogFlush(DWORD NumberOfBytesWritten) +546 void __cdecl SLogFlushAll() +547 void __cdecl SLogPend(int a1, char *a2, char a3) +548 void __cdecl SLogWrite(HANDLE handle, char *format, ...) +549 void __stdcall SLog549(int a1, int a2) +550 void __stdcall SLogCriticalLog(HANDLE handle, int a2) // unofficial name +551 BOOL __stdcall SCompCompress(void *a1, int a2, unsigned int a3, signed int amount, int a5, char a6, int a7) +552 BOOL __stdcall SCompDecompress(void *a1, int *a2, const void *a3, unsigned int a4) +553 void __cdecl SLogVWrite(HANDLE handle, char *format, ...) +554 void __stdcall Ordinal554(int a1, int a2) +555 void __stdcall Ordinal555(int a1, int a2) +556 void __stdcall Ordinal556(int a1, int a2) +557 void __stdcall Ordinal557(int a1, int a2, int a3, int a4, int a5) +558 void __stdcall Ordinal558(int a1, int a2) +559 void __cdecl Ordinal559() +560 void __cdecl Ordinal560() +561 void __cdecl SErrCheckDebugSymbolLibrary(char *, char) +562 BOOL __cdecl SErrDisplayErrorFmt(DWORD dwMessageId, char *logfile, int logline, int unk, UINT uExitCode, char *format, ...) +563 int __cdecl SErrIsDisplayingError() +564 void __stdcall SErrPrepareAppFatal(int a1, int a2) +565 void __cdecl SErrSetLogTitleString(char* title) +566 BOOL __stdcall SErrDisplayAppFatal(int a1) +567 LPTOP_LEVEL_EXCEPTION_FILTER __cdecl SErrCatchUnhandledExceptions() +568 void __cdecl Storm568(struct _RTL_CRITICAL_SECTION *a1) // WC3 +569 char * __stdcall SStrChr(char *string, char c) +570 char * __stdcall SStrChrR(char *string, char c) +571 char * __stdcall SStrChr(const char *string, char c) +572 char * __stdcall SStrChrR(const char *string, char c) +573 double __stdcall SStrToDouble(const char *string) +574 float __stdcall SStrToFloat(const char *string) +575 signed int __stdcall SStrToInt(const char *string) +576 unsigned int __stdcall SStrToUnsigned(const char *string) +577 __int64 __stdcall SStrToInt64(const char *string) +578 size_t __cdecl SStrVPrintf(char *dest, size_t size, const char *format, ...) +579 char* __stdcall SStrLower(char* string) +580 int __stdcall SStrHash64(int a1, int a2, int a3, int a4) // or SStrHashHT?? +581 int __cdecl SStrPrintf(char *dest, size_t size, const char *format, ...) +582 void __stdcall SStr582(int a1) +583 BOOL __stdcall Ordinal583(LPRECT lpRect) +584 int __stdcall SStrStrI(char *string, const char *search) +585 int __stdcall SStrStrI(const char *string, const char *search) +586 int __stdcall SStrStr(char *string, const char *search) +587 int __stdcall SStrStr(const char *string, const char *search) +588 int __stdcall SNet588(char *a1, char *a2) // league related? +589 +590 +595 +596 +597 + +600 SBigInit() +601 int __stdcall SBigAdd(void *buffer, const void *buffer2, const void *buffer3) +602 int __stdcall SBigAnd(void *buffer, const void *buffer2, const void *buffer3) +603 int __stdcall SBigCompare(void *buffer, void *buffer2) +604 int __stdcall SBigCopy(void *buffer, void *buffer2) +605 int __stdcall SBigDec(void *buffer, const void *buffer2) +606 int __stdcall SBigDel(void *buffer) +607 int __stdcall SBigDiv(int a1, const void *buffer1, const void *buffer2) +608 int __stdcall SBigFindPrime(int a1, void *a2, unsigned int a3, const void *a4) +609 int __stdcall SBigFromBinary(void *buffer, const void *str, size_t size) +610 int __stdcall SBigFromStr(void *buffer, int a2) +611 int __stdcall SBigFromStream(void *buffer, int a2, int a3, int a4) +612 int __stdcall SBigFromUnsigned(void *buffer, unsigned int value) +613 int __stdcall SBigGcd(void *buffer, int a2, int a3) +614 int __stdcall SBigInc(void *buffer, int a2) +615 int __stdcall SBigInvMod(void *buffer, int a2, int a3) +616 int __stdcall SBigIsEven(void *buffer) +617 int __stdcall SBigIsOdd(void *buffer) +618 int __stdcall SBigIsOne(void *buffer) +619 int __stdcall SBigIsPrime(void *buffer) +620 int __stdcall SBigIsZero(void *buffer) +621 int __stdcall SBigMod(void *buffer, int a2, int a3) +622 int __stdcall SBigMul(void *buffer, int a2, int a3) +623 int __stdcall SBigMulMod(void *buffer, int a2, int a3, int a4) +624 int __stdcall SBigNew(void **buffer) +625 int __stdcall SBigNot(void *buffer, int a2) +626 int __stdcall SBigOr(void *buffer, int a2, int a3) +627 int __stdcall SBigPow(void *buffer, int a2, int a3) +628 int __stdcall SBigPowMod(void *buffer1, void *buffer2, int a3, int a4) +629 int __stdcall SBigRand(void *buffer, int a2, int a3) +630 int __stdcall SBigSet2Exp(void *buffer, int a2) +631 int __stdcall SBigSetOne(void *buffer) +632 int __stdcall SBigSetZero(void *buffer) +633 int __stdcall SBigShl(void *buffer, int a2, int a3) +634 int __stdcall SBigShr(void *buffer, int a2, int a3) +635 int __stdcall SBigSquare(void *buffer, int a2) +636 int __stdcall SBigSub(void *buffer, int a2, int a3) +637 int __stdcall SBigToBinaryArray(void *buffer, int length, int a3) +638 int __stdcall SBigToBinaryBuffer(void *buffer, int length, int a3, int a4) +639 int __stdcall SBigToBinaryPtr(void *buffer, int a2, int a3) +640 int __stdcall SBigToStrArray(void *buffer, int a2, int a3) +641 int __stdcall SBigToStrBuffer(void *buffer, char *dst, int count) +642 int __stdcall SBigToStrPtr(void *buffer, int a2) +643 int __stdcall SBigToStreamArray(void *buffer, int a2, int a3) +644 int __stdcall SBigToStreamBuffer(void *buffer, int a2, int a3, int a4) +645 int __stdcall SBigToStreamPtr(void *buffer, int a2, int a3) +646 int __stdcall SBigToUnsigned(void *buffer, int a2) +647 int __stdcall SBigXor(void *buffer, int a2, int a3) +648 SSignatureVerify(int a1, int a2, int a3, int a4) +649 SSignatureVerifyStream_Begin(int a1) +650 SSignatureVerifyStream_ProvideData(int a1) +651 SSignatureVerifyStream_Finish(int a1) +652 SSignatureGenerate(int a1, int a2, int a3, int a4, int a5, int a6) +653 SSignatureVerifyStream_GetSignatureLength() + +900 SUniInit() +901 int __stdcall SUniConvertUTF16to8Len(int a1, int a2, int a3) +902 int __stdcall SUniConvertUTF16to8(int a1, int mask1, int a3, int mask2, int a5, int a6) +903 int __stdcall SUniConvertUTF8to16Len(int a1, int a2, int a3) +904 int __stdcall SUniConvertUTF8to16(int a1, int a2, int a3, int a4, int a5, int a6) +905 int __stdcall SUniS905(int a1, int a2) // SUniSPutUTF8 or SUniSGetUTF8 +906 int __stdcall SUniS906(int a1, int a2) // SUniSPutUTF8 or SUniSGetUTF8 +907 int __stdcall SUniFindAfterUTF8Chr(int a1, int a2) +908 int __stdcall SUniFindUTF8ChrStart(int a1, int a2) +909 int __stdcall SUniConvertUTF16To909(unsigned __int32 a1, char *a2, unsigned __int16 *a3) // SUniConvertUTF16ToDos, SUniConvertUTF16ToMac, or SUniConvertUTF16ToWin +910 int __stdcall SUniConvertUTF16To910(unsigned __int32 a1, char *a2, unsigned __int16 *a3) // SUniConvertUTF16ToDos, SUniConvertUTF16ToMac, or SUniConvertUTF16ToWin +911 int __stdcall SUniConvertUTF16To911(unsigned __int32 a1, char *a2, unsigned __int16 *a3) // SUniConvertUTF16ToDos, SUniConvertUTF16ToMac, or SUniConvertUTF16ToWin +912 int __stdcall SUniConvert912(int a1, int a2, int a3) // SUniConvertDosToUTF16, SUniConvertMacToUTF16, or SUniConvertWinToUTF16 +913 int __stdcall SUniConvert913(int a1, int a2, int a3) // SUniConvertDosToUTF16, SUniConvertMacToUTF16, or SUniConvertWinToUTF16 +914 int __stdcall SUniConvert914(int a1, int a2, int a3) // SUniConvertDosToUTF16, SUniConvertMacToUTF16, or SUniConvertWinToUTF16 +915 int __stdcall SUniConvertUTF8ToWin(unsigned __int32 a1, char *a2, unsigned __int16 *a3) +}}} + +Values for the logline parameter: +{{{ +0 = Expression +-1 = Function +-2 = Object +-3 = Handle +-4 = File + +Else it's a project File + line number pair. +}}} + +Values for SNetLeaveGame: +{{{ +1 = Fail to join game +2 = Fail to create game +3 = Leave, Disconnect, Destroy +}}} + +Values for Registry Flags: +{{{ +0 = "Software\\Battle.net\\" +2 = "Software\\Blizzard Entertainment\\" +}}} + +Values for SNet player flags +{{{ +40000006 = Drop +}}} + +values for modeFlags of SNetSetGameMode +{{{ +0x00000001 = Game is private +0x00000002 = Game is full +0x00000004 = Game is active +0x00000008 = Game has started +0x00000080 = Game is replay +}}} + +values for SNetGetGameInfo type +{{{ +1 = Game Name +2 = Game Password +3 = Full Game Stat String (see http://www.bnetdocs.org/?op=doc&did=13) +4 = Game Mode +}}} + +player Struct +{{{ +struct playerStruct +{ + playerStruct *prev; // +0x00 + playerStruct *next; // +0x04 + char playerName[128]; // +0x08 + char statString[128]; // +0x88 + WORD addr_family; // +0x108 + WORD port; // +0x10A + DWORD ipAddress; // +0x10C + u32 ping; // +0x110 + void *newMessagePointer; // +0x114 + DWORD dwFlags; // +0x118 // 0x04 = unknown, 0x08 = dropped + u32 unknown_0x11C; // +0x11C + u32 tickCount; // +0x120 + u32 playerBuffer; // +0x124 + int Ping; // +0x128 + BYTE unknown_0x12C[12]; // +0x12C + u32 unknown_0x138; // +0x138 + BYTE unknown_0x13C[68]; // +0x13C + u32 unknown_0x180; // +0x180 + BYTE unknown_0x184[68]; // +0x184 + u32 unknown_0x1C8; // +0x1C8 + WORD sentMessageNumber[3];// +0x1CC + WORD unknown_0x1D2[3];// +0x1D2 + u32 unknown_0x1D8; // +0x1D8 // ref'd by SNetDropPlayer + WORD unknown7; // +0x1DC + WORD recvMessageNumber[3]; // +0x1DE + BYTE unknown[40]; // +0x1E4 + u16 dropReason; // +0x20C // Just a guess + u16 droppedBy; // +0x210 // Just a guess + BYTE PlayerID; // +0x212 + // +0x213 + // +0x214 +} + +}}} + +caps +{{{ +struct caps +{ + u32 size; + u32 unk4; + u32 unk8; + u32 unkC; + u32 unk10; + u32 unk14; + u32 ping; + u32 unk1C; + u32 latencyCalls; +} + +}}} + +struct argstruct +{ + DWORD flags; + int index; + char* name; + (bool (__stdcall*)(int,int)) function; +} \ No newline at end of file diff --git a/2020_03_31/.gitignore b/2020_03_31/.gitignore new file mode 100644 index 00000000..e96b083e --- /dev/null +++ b/2020_03_31/.gitignore @@ -0,0 +1,358 @@ +# ELF object file. +*.o + +# PE shared library and associated files. +*.lib +*.exp +*.dll + +# PE executable. +*.exe + +# GCC dependency file. +*.d + +# Resource file. +*.res + +# Created by https://www.gitignore.io/api/visualstudio + +### VisualStudio ### +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore + +# User-specific files +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ +WinDebug/ +WinRel/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUNIT +*.VisualState.xml +TestResult.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_i.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# JustCode is a .NET coding add-in +.JustCode + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# JetBrains Rider +.idea/ +*.sln.iml + +# CodeRush +.cr/ + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +### VisualStudio Patch ### +# By default, sensitive information, such as encrypted password +# should be stored in the .pubxml.user file. +*.pubxml.user + +# End of https://www.gitignore.io/api/visualstudio diff --git a/2020_03_31/.travis.yml b/2020_03_31/.travis.yml new file mode 100644 index 00000000..aa961c0f --- /dev/null +++ b/2020_03_31/.travis.yml @@ -0,0 +1,34 @@ +language: cpp + +os: + - linux + - osx + +notifications: + email: + on_failure: change # default: always + +addons: + # Packages for Linux + apt: + packages: + - mingw-w64 + +env: + - MAKE_BUILD=make + - MAKE_BUILD=debug + +before_install: + # Packages for OSX + - if [ $TRAVIS_OS_NAME = osx ]; then brew install mingw-w64; fi + +before_script: + - touch storm.dll + - touch diabloui.dll + +script: + - if [ $MAKE_BUILD = make ]; then make; fi + - if [ $MAKE_BUILD = debug ]; then make debug; fi + +after_script: + - make clean diff --git a/2020_03_31/3rdParty/Pkware/Source/Makefile b/2020_03_31/3rdParty/Pkware/Source/Makefile new file mode 100644 index 00000000..8e4ab80c --- /dev/null +++ b/2020_03_31/3rdParty/Pkware/Source/Makefile @@ -0,0 +1,35 @@ +# Implode Library make file for Win32 + +CFLAGS = /nologo /W3 /O2 /D "_X86_" /D "NDEBUG" /ML + +BCCFLAGS = -vi -WC -c + +all: implode.lib implodei.lib + +CRC32.OBJ: crc32.C + cl $(CFLAGS) /c CRC32.C + cl $(CFLAGS) /c crc32.c /Gr /Focrcfast.obj + cl $(CFLAGS) /c crc32.c /Gz /Focrcstd.obj + Bcc32 $(BCCFLAGS) -ocrcborl.obj crc32.c + +EXPLODE.OBJ: EXPLODE.C tables.inc implode.h + cl $(CFLAGS) /c EXPLODE.C + cl $(CFLAGS) /c explode.c /Gr /Foexpfast.obj + cl $(CFLAGS) /c explode.c /Gz /Foexpstd.obj + Bcc32 $(BCCFLAGS) -oexpborl.obj explode.c + +IMPLODE.OBJ:IMPLODE.C tables.inc implode.h + cl $(CFLAGS) /c IMPLODE.C + cl $(CFLAGS) /c implode.c /Gr /Foimpfast.obj + cl $(CFLAGS) /c implode.c /Gz /Foimpstd.obj + Bcc32 $(BCCFLAGS) -oimpborl.obj implode.c + +implode.LIB: CRC32.OBJ EXPLODE.OBJ IMPLODE.OBJ + link -lib implode.obj impfast.obj impstd.obj crc32.obj crcfast.obj crcstd.obj explode.obj expfast.obj expstd.obj + tlib impborl.lib -+crcborl.obj -+expborl.obj -+impborl.obj + +implodei.lib: implode.obj explode.obj crc32.obj + link -dll -implib:implodei.lib -DEF:implode.def -OUT:implode.dll implode.obj explode.obj crc32.obj + tlink32 -Tpd crcborl.obj expborl.obj impborl.obj, impborl.dll,,,impborl.def + implib impborli.lib impborl.dll + diff --git a/2020_03_31/3rdParty/Pkware/Source/crc32.c b/2020_03_31/3rdParty/Pkware/Source/crc32.c new file mode 100644 index 00000000..71da3302 --- /dev/null +++ b/2020_03_31/3rdParty/Pkware/Source/crc32.c @@ -0,0 +1,73 @@ +/* the crc table */ + +static char CopyRight[] = { \ + "PKWARE Data Compression Library for Win32\r\n" \ + "Copyright 1989-1995 PKWARE Inc. All Rights Reserved\r\n" \ + "Patent No. 5,051,745\r\n" \ + "PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off.\r\n" \ + "Version 1.11" }; + +static unsigned crc_table[]={ +0x00000000,0x77073096,0xEE0E612C,0x990951BA,0x076DC419,0x706AF48F, +0xE963A535,0x9E6495A3,0x0EDB8832,0x79DCB8A4,0xE0D5E91E,0x97D2D988, +0x09B64C2B,0x7EB17CBD,0xE7B82D07,0x90BF1D91,0x1DB71064,0x6AB020F2, +0xF3B97148,0x84BE41DE,0x1ADAD47D,0x6DDDE4EB,0xF4D4B551,0x83D385C7, +0x136C9856,0x646BA8C0,0xFD62F97A,0x8A65C9EC,0x14015C4F,0x63066CD9, +0xFA0F3D63,0x8D080DF5,0x3B6E20C8,0x4C69105E,0xD56041E4,0xA2677172, +0x3C03E4D1,0x4B04D447,0xD20D85FD,0xA50AB56B,0x35B5A8FA,0x42B2986C, +0xDBBBC9D6,0xACBCF940,0x32D86CE3,0x45DF5C75,0xDCD60DCF,0xABD13D59, +0x26D930AC,0x51DE003A,0xC8D75180,0xBFD06116,0x21B4F4B5,0x56B3C423, +0xCFBA9599,0xB8BDA50F,0x2802B89E,0x5F058808,0xC60CD9B2,0xB10BE924, +0x2F6F7C87,0x58684C11,0xC1611DAB,0xB6662D3D,0x76DC4190,0x01DB7106, +0x98D220BC,0xEFD5102A,0x71B18589,0x06B6B51F,0x9FBFE4A5,0xE8B8D433, +0x7807C9A2,0x0F00F934,0x9609A88E,0xE10E9818,0x7F6A0DBB,0x086D3D2D, +0x91646C97,0xE6635C01,0x6B6B51F4,0x1C6C6162,0x856530D8,0xF262004E, +0x6C0695ED,0x1B01A57B,0x8208F4C1,0xF50FC457,0x65B0D9C6,0x12B7E950, +0x8BBEB8EA,0xFCB9887C,0x62DD1DDF,0x15DA2D49,0x8CD37CF3,0xFBD44C65, +0x4DB26158,0x3AB551CE,0xA3BC0074,0xD4BB30E2,0x4ADFA541,0x3DD895D7, +0xA4D1C46D,0xD3D6F4FB,0x4369E96A,0x346ED9FC,0xAD678846,0xDA60B8D0, +0x44042D73,0x33031DE5,0xAA0A4C5F,0xDD0D7CC9,0x5005713C,0x270241AA, +0xBE0B1010,0xC90C2086,0x5768B525,0x206F85B3,0xB966D409,0xCE61E49F, +0x5EDEF90E,0x29D9C998,0xB0D09822,0xC7D7A8B4,0x59B33D17,0x2EB40D81, +0xB7BD5C3B,0xC0BA6CAD,0xEDB88320,0x9ABFB3B6,0x03B6E20C,0x74B1D29A, +0xEAD54739,0x9DD277AF,0x04DB2615,0x73DC1683,0xE3630B12,0x94643B84, +0x0D6D6A3E,0x7A6A5AA8,0xE40ECF0B,0x9309FF9D,0x0A00AE27,0x7D079EB1, +0xF00F9344,0x8708A3D2,0x1E01F268,0x6906C2FE,0xF762575D,0x806567CB, +0x196C3671,0x6E6B06E7,0xFED41B76,0x89D32BE0,0x10DA7A5A,0x67DD4ACC, +0xF9B9DF6F,0x8EBEEFF9,0x17B7BE43,0x60B08ED5,0xD6D6A3E8,0xA1D1937E, +0x38D8C2C4,0x4FDFF252,0xD1BB67F1,0xA6BC5767,0x3FB506DD,0x48B2364B, +0xD80D2BDA,0xAF0A1B4C,0x36034AF6,0x41047A60,0xDF60EFC3,0xA867DF55, +0x316E8EEF,0x4669BE79,0xCB61B38C,0xBC66831A,0x256FD2A0,0x5268E236, +0xCC0C7795,0xBB0B4703,0x220216B9,0x5505262F,0xC5BA3BBE,0xB2BD0B28, +0x2BB45A92,0x5CB36A04,0xC2D7FFA7,0xB5D0CF31,0x2CD99E8B,0x5BDEAE1D, +0x9B64C2B0,0xEC63F226,0x756AA39C,0x026D930A,0x9C0906A9,0xEB0E363F, +0x72076785,0x05005713,0x95BF4A82,0xE2B87A14,0x7BB12BAE,0x0CB61B38, +0x92D28E9B,0xE5D5BE0D,0x7CDCEFB7,0x0BDBDF21,0x86D3D2D4,0xF1D4E242, +0x68DDB3F8,0x1FDA836E,0x81BE16CD,0xF6B9265B,0x6FB077E1,0x18B74777, +0x88085AE6,0xFF0F6A70,0x66063BCA,0x11010B5C,0x8F659EFF,0xF862AE69, +0x616BFFD3,0x166CCF45,0xA00AE278,0xD70DD2EE,0x4E048354,0x3903B3C2, +0xA7672661,0xD06016F7,0x4969474D,0x3E6E77DB,0xAED16A4A,0xD9D65ADC, +0x40DF0B66,0x37D83BF0,0xA9BCAE53,0xDEBB9EC5,0x47B2CF7F,0x30B5FFE9, +0xBDBDF21C,0xCABAC28A,0x53B39330,0x24B4A3A6,0xBAD03605,0xCDD70693, +0x54DE5729,0x23D967BF,0xB3667A2E,0xC4614AB8,0x5D681B02,0x2A6F2B94, +0xB40BBE37,0xC30C8EA1,0x5A05DF1B,0x2D02EF8D +}; + +#ifdef SYSLINK +unsigned int _System crc32_sys(unsigned char *ptr, unsigned int *len, + unsigned int *oldcrc) +#else +unsigned int crc32(unsigned char *ptr, unsigned int *len, + unsigned int *oldcrc) +#endif +{ +unsigned int crc=*oldcrc; +unsigned int count=*len; + +while (count--) +{ + crc = crc_table[(crc ^ *ptr++) & 0xff] ^ (crc >> 8); +} + +return(crc); +} diff --git a/2020_03_31/3rdParty/Pkware/Source/explode.c b/2020_03_31/3rdParty/Pkware/Source/explode.c new file mode 100644 index 00000000..ae9a78c0 --- /dev/null +++ b/2020_03_31/3rdParty/Pkware/Source/explode.c @@ -0,0 +1,460 @@ + +#define EXPLODE +#include "tables.inc" + +#include "implode.h" + +#ifndef FALSE + #define FALSE 0 +#endif + +#ifndef TRUE + #define TRUE 1 +#endif + +#ifndef NULL + #define NULL ((void *)0) +#endif + +//#define DEBUG_COPY +//#define DEBUG_LIT +//#include + +static char Copyright[] = { \ + "PKWARE Data Compression Library for Win32\r\n" \ + "Copyright 1989-1995 PKWARE Inc. All Rights Reserved.\r\n" \ + "Patent No. 5,051,745\r\n" \ + "PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off.\r\n" \ + "Version 1.11" }; + +#define VOID void +#define CHAR char /* 8 bits, signed */ +#define UCHAR unsigned char /* 8 bits, unsigned */ +#define SHORT signed short /* 16 bits, signed */ +#define USHORT unsigned short /* 16 bits, unsigned */ +#define UINT unsigned int +#define INT int +#define LONG signed long /* 32 bits, signed */ +#define ULONG unsigned long /* 32 bits, unsigned */ + +#define MAX_DICT_SIZE 4096 +#define EXP_BUFSIZE 4096 +#define OUT_SIZE 2048 +#define FOO_SIZE 2304 +#define MINREP 2 +#define SIZE_DIST 64 +#define SIZE_LEN 16 +#define MAXREP (MINREP+(8*1)+2+4+8+16+32+64+128+256-4) +#define SIZE_LIT (256+MAXREP+2) +#define EOF_CODE (SIZE_LIT-1) +#define ABORT_CODE (EOF_CODE+1) + +typedef struct EXP_DATA +{ + UINT Distance; + UINT Mode; + UINT OutPtr; + UINT ExtDistBits; + UINT ExtDistMask; + UINT LookAhead; + UINT LookBits; + UINT InPtr; + UINT InBufCnt; + VOID *Param; + #ifdef SYSLINK + UINT (* _System GetBuf)(CHAR *buffer, UINT *size, VOID *Param); + VOID (* _System PutBuf)(CHAR *buffer, UINT *size, VOID *Param); + #else + UINT (*GetBuf)(CHAR *buffer, UINT *size, VOID *Param); + VOID (*PutBuf)(CHAR *buffer, UINT *size, VOID *Param); + #endif + UCHAR OutBuf[(EXP_BUFSIZE*2)+MAXREP]; + UCHAR InBuf[OUT_SIZE]; + UCHAR DistDecode[256]; + UCHAR LenDecode[256]; + UCHAR ChLow[256]; + UCHAR ChMid1[256]; + UCHAR ChMid2[128]; + UCHAR ChHi[256]; + UCHAR ChBits[256]; + UCHAR DistBits[SIZE_DIST]; + UCHAR LenBits[SIZE_LEN]; + UCHAR ExLenBits[SIZE_LEN]; + USHORT LenBase[SIZE_LEN]; +}; + +/**************************************************** + Function Declarations +****************************************************/ + +static UINT Expand(struct EXP_DATA *Exp); +static UINT DecodeLit(struct EXP_DATA *Exp); +static UINT DecodeDist(struct EXP_DATA *Exp, UINT Len); +static UINT WasteBits(struct EXP_DATA *Exp, UINT Bits); +static VOID GenDecodeTabs(UINT Len, UCHAR *Bits, UCHAR *Code, UCHAR *Decode); +static VOID GenAscTabs(struct EXP_DATA *Exp); +static VOID lmemcpy(VOID *Dest, VOID *Source, UINT Size); + +/************************************************* + Function: explode +************************************************** +*/ +#ifdef SYSLINK +UINT _System explode_sys( + UINT (* _System ReadBuf )(CHAR *Buf, UINT *Size, VOID *Param), + VOID (* _System WriteBuf)(CHAR *Buf, UINT *Size, VOID *Param), +#else +UINT explode( + UINT (*ReadBuf )(CHAR *Buf, UINT *Size, VOID *Param), + VOID (*WriteBuf)(CHAR *Buf, UINT *Size, VOID *Param), +#endif + CHAR *WorkBuf, VOID *Param) +{ + struct EXP_DATA *Exp = (struct EXP_DATA *)WorkBuf; + + Exp->GetBuf = ReadBuf; + Exp->PutBuf = WriteBuf; + Exp->Param = Param; + + Exp->InPtr = OUT_SIZE; + if ((Exp->InBufCnt = (*Exp->GetBuf)((VOID *)(Exp->InBuf), &Exp->InPtr, + Exp->Param)) <= 4) + return CMP_BAD_DATA; + + Exp->Mode = Exp->InBuf[0]; + Exp->ExtDistBits = Exp->InBuf[1]; + Exp->LookAhead = Exp->InBuf[2]; + Exp->LookBits = 0; + Exp->InPtr = 3; + + if (Exp->ExtDistBits < 4 || Exp->ExtDistBits > 6) + return CMP_INVALID_DICTSIZE; + Exp->ExtDistMask = 0xFFFF >> (16 - Exp->ExtDistBits); + + switch (Exp->Mode) + { + case CMP_ASCII: + lmemcpy(Exp->ChBits,ChBitsAsc,sizeof(ChBitsAsc)); + GenAscTabs(Exp); + break; + case CMP_BINARY: + break; + default: + return CMP_INVALID_MODE; + } + + lmemcpy(Exp->LenBits,LenBits,sizeof(LenBits)); + GenDecodeTabs(SIZE_LEN, Exp->LenBits, LenCode, Exp->LenDecode); + lmemcpy(Exp->ExLenBits,ExLenBits,sizeof(ExLenBits)); + lmemcpy(Exp->LenBase,LenBase,sizeof(LenBase)); + + lmemcpy(Exp->DistBits,DistBits,sizeof(DistBits)); + GenDecodeTabs(SIZE_DIST, Exp->DistBits, DistCode, Exp->DistDecode); + + if (Expand(Exp) == ABORT_CODE) + return CMP_ABORT; + + return CMP_NO_ERROR; +} + +/************************************************** + Function: Expand +*************************************************** +*/ +static UINT Expand(struct EXP_DATA *Exp) +{ + UINT Len, Dist, i; + CHAR *Src, *Dest; + + Exp->OutPtr = EXP_BUFSIZE; + while ((Len = DecodeLit(Exp)) < EOF_CODE) + { + if (Len < 256) + { + #ifdef DEBUG_LIT + printf("Ch=%02x\n",Len); + #endif + Exp->OutBuf[Exp->OutPtr++] = (UCHAR)Len; + } + else + { + Len -= (256 - MINREP); + if ((Dist = DecodeDist(Exp, Len)) == 0) + { + Len = ABORT_CODE; + break; + } + #ifdef DEBUG_COPY + printf("Copy-%d %d\n",Len,Dist); + #endif + Dest = &Exp->OutBuf[Exp->OutPtr]; + Src = Dest - Dist; + Exp->OutPtr += Len; + do { + *Dest++ = *Src++; + } while (--Len); + } + + if (Exp->OutPtr >= EXP_BUFSIZE*2) + { + Len = EXP_BUFSIZE; + (* Exp->PutBuf)(&Exp->OutBuf[EXP_BUFSIZE], &Len, Exp->Param); + lmemcpy(Exp->OutBuf, &Exp->OutBuf[EXP_BUFSIZE], + Exp->OutPtr-EXP_BUFSIZE); + Exp->OutPtr -= EXP_BUFSIZE; + } + } + + i = Exp->OutPtr - EXP_BUFSIZE; + (* Exp->PutBuf)(&Exp->OutBuf[EXP_BUFSIZE], &i, Exp->Param); + + return Len; +} + +/************************************************** + Function: DecodeLit +*************************************************** +*/ +static UINT DecodeLit(struct EXP_DATA *Exp) +{ + UINT LitChar, i; + + if (Exp->LookAhead & 1) /* Length found */ + { + if (WasteBits(Exp, 1)) + return ABORT_CODE; + LitChar = Exp->LenDecode[Exp->LookAhead & 0xFF]; + if (WasteBits(Exp, Exp->LenBits[LitChar])) + return ABORT_CODE; + if (Exp->ExLenBits[LitChar]) + { + i = Exp->LookAhead & ((1 << Exp->ExLenBits[LitChar]) - 1); + if (WasteBits(Exp, Exp->ExLenBits[LitChar])) + { + if (LitChar + i != 15 + 255) /* If not EOF */ + return ABORT_CODE; + } + LitChar = Exp->LenBase[LitChar] + i; + } + LitChar += 256; + } + else /* Character found */ + { + if (WasteBits(Exp, 1)) + return ABORT_CODE; + if (Exp->Mode == CMP_BINARY) + { + LitChar = Exp->LookAhead & 0xFF; + if (WasteBits(Exp, 8)) + return ABORT_CODE; + } + else + { + if (Exp->LookAhead & 0xFF) /* Low/Mid tab */ + { + if ((LitChar = Exp->ChLow[Exp->LookAhead & 0xFF]) == 0xFF) + { + if (Exp->LookAhead & 0x3F) /* Mid tab 1 */ + { + if (WasteBits(Exp, 4)) + return ABORT_CODE; + LitChar = Exp->ChMid1[Exp->LookAhead & 0xFF]; + } + else /* Mid tab 2 */ + { + if (WasteBits(Exp, 6)) + return ABORT_CODE; + LitChar = Exp->ChMid2[Exp->LookAhead & 0x7F]; + } + } + } + else /* High tab */ + { + if (WasteBits(Exp, 8)) + return ABORT_CODE; + LitChar = Exp->ChHi[Exp->LookAhead & 0xFF]; + } + if (WasteBits(Exp, Exp->ChBits[LitChar])) + return ABORT_CODE; + } + } + return LitChar; +} + +/************************************************** + Function: DecodeDist +*************************************************** +*/ +static UINT DecodeDist(struct EXP_DATA *Exp, UINT Len) +{ + UINT Dist; + + Dist = Exp->DistDecode[Exp->LookAhead & 0xFF]; + if (WasteBits(Exp, Exp->DistBits[Dist])) + return 0; + + if (Len == MINREP) + { + Dist <<= 2; + Dist |= Exp->LookAhead & 3; + if (WasteBits(Exp, 2)) + return 0; + } + else + { + Dist <<= Exp->ExtDistBits; + Dist |= Exp->LookAhead & Exp->ExtDistMask; + if (WasteBits(Exp, Exp->ExtDistBits)) + return 0; + } + + return Dist+1; +} + +/************************************************** + Function: WasteBits +*************************************************** +*/ +static UINT WasteBits(struct EXP_DATA *Exp, UINT Bits) +{ + if (Bits <= Exp->LookBits) + { + Exp->LookAhead >>= Bits; + Exp->LookBits -= Bits; + return 0; + } + + Exp->LookAhead >>= Exp->LookBits; + + if (Exp->InPtr == Exp->InBufCnt) + { + Exp->InPtr = OUT_SIZE; + if ((Exp->InBufCnt = (*Exp->GetBuf)((VOID *)(Exp->InBuf), &Exp->InPtr, + Exp->Param)) == 0) + return 1; + Exp->InPtr = 0; + } + + Exp->LookAhead |= (Exp->InBuf[Exp->InPtr])<<8; + ++Exp->InPtr; + Exp->LookAhead >>= (Bits - Exp->LookBits); + Exp->LookBits = 8-(Bits-Exp->LookBits); + return 0; +} + +/************************************************* + Function: GenDecodeTabs +************************************************** +*/ +static VOID GenDecodeTabs(UINT Len, UCHAR *Bits, UCHAR *Code, UCHAR *Decode) +{ + UINT j, Incr; + INT i; + + for (i=Len-1; i>=0; i--) + { + Incr = 1 << Bits[i]; + j = Code[i]; + do + { + Decode[j] = (UCHAR)i; + j += Incr; + } while (j<256); + } +} + +/*#pragma optimize("z",off)*/ + +/************************************************** + Function: GenAscTabs +*************************************************** +*/ +static VOID GenAscTabs(struct EXP_DATA *Exp) +{ + UINT j, Incr; + INT i; + + for (i=255; i>=0; i--) + { + if (Exp->ChBits[i] <= 8) + { + Incr = 1 << Exp->ChBits[i]; + j = ChCodeAsc[i]; + do + { + Exp->ChLow[j] = (UCHAR)i; + j += Incr; + } while (j < 256); + } + else if (ChCodeAsc[i] & 0xFF) + { + Exp->ChLow[ChCodeAsc[i] & 0xFF] = 0xFF; + if (ChCodeAsc[i] & 0x3F) + { + Exp->ChBits[i] -= 4; + Incr= 1 << Exp->ChBits[i]; + j = ChCodeAsc[i] >> 4; + do + { + Exp->ChMid1[j] = (UCHAR)i; + j += Incr; + } while (j < 256); + } + else + { + Exp->ChBits[i] -= 6; + Incr = 1 << Exp->ChBits[i]; + j = ChCodeAsc[i] >> 6; + do + { + Exp->ChMid2[j] = (UCHAR)i; + j += Incr; + } while (j<128); + } + } + else + { + Exp->ChBits[i] -= 8; + Incr = 1 << Exp->ChBits[i]; + j = ChCodeAsc[i] >> 8; + do + { + Exp->ChHi[j] = (UCHAR)i; + j += Incr; + } while (j < 256); + } + } +} + + +/*************************************************** + Function: lmemcpy +**************************************************** +*/ + +static VOID lmemcpy(VOID *Dest, VOID *Source, UINT Size) +{ + UCHAR *s=(UCHAR *)Source, *t=(UCHAR *)Dest; +#ifndef _ALPHA + UINT count=Size/4; + + if (count) + { do + { *(ULONG *)t = *(ULONG *)s; + s+=4; + t+=4; + } + while (--count); + } + + if (Size %= 4) +#endif + do { + *t++=*s++; + } while (--Size); +} + + + + + diff --git a/2020_03_31/3rdParty/Pkware/Source/impborl.def b/2020_03_31/3rdParty/Pkware/Source/impborl.def new file mode 100644 index 00000000..a515acc9 --- /dev/null +++ b/2020_03_31/3rdParty/Pkware/Source/impborl.def @@ -0,0 +1,6 @@ +NAME IMPLODEI + +EXPORTS + _implode + _explode + _crc32 diff --git a/2020_03_31/3rdParty/Pkware/Source/implode.c b/2020_03_31/3rdParty/Pkware/Source/implode.c new file mode 100644 index 00000000..c27c4a97 --- /dev/null +++ b/2020_03_31/3rdParty/Pkware/Source/implode.c @@ -0,0 +1,588 @@ + +#include "tables.inc" + +#include "implode.h" + +#ifndef FALSE + #define FALSE 0 +#endif + +#ifndef TRUE + #define TRUE 1 +#endif + +#ifndef NULL + #define NULL ((void *)0) +#endif + +//#define DEBUG_COPY +//#define DEBUG_LIT +//#include + +static char Copyright[] = { \ + "PKWARE Data Compression Library for Win32\r\n" \ + "Copyright 1989-1995 PKWARE Inc. All Rights Reserved\r\n" \ + "Patent No. 5,051,745\r\n" \ + "PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off.\r\n" \ + "Version 1.11" }; + +#define VOID void +#define CHAR char /* 8 bits, signed */ +#define UCHAR unsigned char /* 8 bits, unsigned */ +#define SHORT signed short /* 16 bits, signed */ +#define USHORT unsigned short /* 16 bits, unsigned */ +#define UINT unsigned int +#define INT int +#define LONG signed long /* 32 bits, signed */ +#define ULONG unsigned long /* 32 bits, unsigned */ + +#define MAX_DICT_SIZE 4096 +#define EXP_BUFSIZE 4096 +#define OUT_SIZE 2048 +#define FOO_SIZE 2304 +#define MINREP 2 +#define SIZE_DIST 64 +#define SIZE_LEN 16 +#define MAXREP (MINREP+(8*1)+2+4+8+16+32+64+128+256-4) +#define SIZE_LIT (256+MAXREP+2) +#define EOF_CODE (SIZE_LIT-1) +#define ABORT_CODE (EOF_CODE+1) + +typedef struct CMP_DATA +{ + UINT Distance; + UINT OutPtr; + UINT OutPos; + UINT ExtDistBits; + UINT ExtDistMask; + UINT Mode; + UINT DictSize; + UCHAR DistBits[SIZE_DIST]; + UCHAR DistCode[SIZE_DIST]; + UCHAR LitBits[SIZE_LIT]; + USHORT LitCode[SIZE_LIT]; + VOID *Param; + #ifdef SYSLINK + UINT (* _System GetBuf)(UCHAR *buffer, UINT *size, VOID *Param); + VOID (* _System PutBuf)(UCHAR *buffer, UINT *size, VOID *Param); + #else + UINT (*GetBuf)(UCHAR *buffer, UINT *size, VOID *Param); + VOID (*PutBuf)(UCHAR *buffer, UINT *size, VOID *Param); + #endif + SHORT Next[MAXREP+2]; + USHORT Index[FOO_SIZE+1]; + UCHAR OutBuf[OUT_SIZE+2]; + UCHAR Buffer[(MAX_DICT_SIZE*2)+MAXREP]; + USHORT SortBuf[(MAX_DICT_SIZE*2)+MAXREP]; +}; + +#define FOO(x) (4*(x)[0] + 5*(x)[1]) + +/**************************************************** + Function Declarations +****************************************************/ + +static VOID WriteCmpData(struct CMP_DATA *Cmp); +static VOID SortBuffer(struct CMP_DATA *Cmp, UCHAR *low, UCHAR *hi); +static UINT FindRep(struct CMP_DATA *Cmp, UCHAR *Start); +static VOID OutputBits(struct CMP_DATA *Cmp, UINT Cnt, UINT Code); +static VOID lmemcpy(VOID *Dest, VOID *Source, UINT Size); +static VOID lmemset(VOID *Buf, UCHAR ch, UINT Size); +static VOID FlushBuf(struct CMP_DATA *Cmp); + + +/******************************************* + Function: Implode +******************************************** +*/ + +#ifdef SYSLINK +UINT _System implode_sys( + UINT (* _System ReadBuf)(UCHAR *buffer, UINT *size, VOID *Param), + VOID (* _System WriteBuf)(UCHAR *buffer,UINT *size, VOID *Param), +#else +UINT implode( + UINT (*ReadBuf)(CHAR *buffer, UINT *size, VOID *Param), + VOID (*WriteBuf)(CHAR *buffer,UINT *size, VOID *Param), +#endif + CHAR *WorkBuf, VOID *Param, UINT *Mode, UINT *DictSize) +{ + UINT i, j, k; + struct CMP_DATA *Cmp = (struct CMP_DATA *)WorkBuf; + + Cmp->GetBuf = ReadBuf; + Cmp->PutBuf = WriteBuf; + Cmp->DictSize = *DictSize; + Cmp->Mode = *Mode; + Cmp->Param = Param; + + Cmp->ExtDistBits = 4; + Cmp->ExtDistMask = 0xF; + switch (*DictSize) + { + case 4096: + Cmp->ExtDistBits++; + Cmp->ExtDistMask |= 0x20; + case 2048: + Cmp->ExtDistBits++; + Cmp->ExtDistMask |= 0x10; + case 1024: + break; + default: + return CMP_INVALID_DICTSIZE; + } + + switch (*Mode) + { + case CMP_ASCII: + for (k=0; k<256; k++) + { + Cmp->LitBits[k] = (UCHAR)(ChBitsAsc[k] + 1); + Cmp->LitCode[k] = (USHORT)(ChCodeAsc[k] << 1); + } + break; + case CMP_BINARY: + for (k=0; k<256; k++) + { + Cmp->LitBits[k] = 9; + Cmp->LitCode[k] = (USHORT)(k << 1); + } + break; + default: + return CMP_INVALID_MODE; + } + + + for (i=0; i<16; i++) + { + for (j=0; j < ( 1U<LitBits[k] = (UCHAR)(LenBits[i] + ExLenBits[i] + 1); + Cmp->LitCode[k] = (USHORT)((j<<(LenBits[i]+1)) | (LenCode[i]<<1) | 1); + } + } + + lmemcpy(Cmp->DistCode,DistCode,sizeof(DistCode)); + lmemcpy(Cmp->DistBits,DistBits,sizeof(DistBits)); + + WriteCmpData(Cmp); + + return CMP_NO_ERROR; +} + +/************************************************* + Function: WriteCmpData +************************************************** +*/ +static VOID WriteCmpData(struct CMP_DATA *Cmp) +{ + UINT Len, Pass=0, InCnt, CmpEnd = FALSE, i; + UINT Request, PassReq; + UCHAR *Cur, *Lim; + + Cur = (UCHAR *)&Cmp->Buffer[Cmp->DictSize+MAXREP]; + + Cmp->OutBuf[0] = (UCHAR)Cmp->Mode; + Cmp->OutBuf[1] = (UCHAR)Cmp->ExtDistBits; + Cmp->OutPtr = 2; + lmemset(Cmp->OutBuf+2,0,OUT_SIZE); + Cmp->OutPos = 0; + + do + { + Request = MAX_DICT_SIZE; + InCnt = 0; + do + { + PassReq = Request; + if ((i = (*Cmp->GetBuf)((VOID *)(Cmp->Buffer+Cmp->DictSize+MAXREP+InCnt), + &PassReq, Cmp->Param)) == 0) + { + if (InCnt == 0 && Pass == 0) + { + OutputBits(Cmp, Cmp->LitBits[EOF_CODE], Cmp->LitCode[EOF_CODE]); + if (Cmp->OutPos != 0) + ++Cmp->OutPtr; + (*Cmp->PutBuf)(Cmp->OutBuf, &Cmp->OutPtr, Cmp->Param); + return; + } + CmpEnd = TRUE; + break; + } + InCnt += i; + Request -= i; + } while (Request); + + Lim = (UCHAR *)&Cmp->Buffer[Cmp->DictSize+InCnt]; + if (CmpEnd) + Lim += MAXREP; + + switch (Pass) + { + case 0: + SortBuffer(Cmp, Cur,Lim+1); + ++Pass; + if (Cmp->DictSize != 4096) // Added: 12-14-94 + ++Pass; + break; + case 1: + SortBuffer(Cmp, Cur-Cmp->DictSize+MAXREP,Lim+1); ++Pass; break; + default: + SortBuffer(Cmp, Cur-Cmp->DictSize, Lim+1); break; + } + + while (Cur < Lim) + { + Len = FindRep(Cmp, Cur); + + SkipFindRep: + if (Len == 0 || (Len == MINREP && Cmp->Distance >= 256)) + { + #ifdef DEBUG_LIT + printf("Ch=%02x\n",*Cur); + #endif + OutputBits(Cmp, Cmp->LitBits[*Cur],Cmp->LitCode[*Cur]); + Cur++; + continue; + } + + if (CmpEnd && Cur+Len > Lim) + { + Len = (unsigned)(Lim - Cur); + if (Len < MINREP || (Len == MINREP && Cmp->Distance >= 256)) + { + #ifdef DEBUG_LIT + printf("Ch=%02x\n",*Cur); + #endif + OutputBits(Cmp, Cmp->LitBits[*Cur],Cmp->LitCode[*Cur]); + Cur++; + continue; + } + } + else if (Len < 8 && Cur+1 < Lim) + { + unsigned savd,savl; + + savd=Cmp->Distance; + savl=Len; + Len=FindRep(Cmp, Cur + 1); + if (Len > savl && (Len > savl+1 || savd > 128)) + { + #ifdef DEBUG_LIT + printf("Ch=%02x\n",*Cur); + #endif + OutputBits(Cmp, Cmp->LitBits[*Cur], Cmp->LitCode[*Cur]); + ++Cur; + goto SkipFindRep; + } + Len=savl; + Cmp->Distance=savd; + } + + #ifdef DEBUG_COPY + printf("Copy-%d %d\n",Len,Cmp->Distance+1); + #endif + OutputBits(Cmp, Cmp->LitBits[Len - MINREP + 256], + Cmp->LitCode[Len - MINREP + 256]); + + if (Len == MINREP) + { + OutputBits(Cmp, Cmp->DistBits[Cmp->Distance>>2], + Cmp->DistCode[Cmp->Distance>>2]); + OutputBits(Cmp, 2, Cmp->Distance & 3); + } + else + { + OutputBits(Cmp, Cmp->DistBits[Cmp->Distance>>Cmp->ExtDistBits], + Cmp->DistCode[Cmp->Distance>>Cmp->ExtDistBits]); + OutputBits(Cmp, Cmp->ExtDistBits, Cmp->Distance & Cmp->ExtDistMask); + } + Cur+=Len; + } + + if (CmpEnd == FALSE) + { + lmemcpy(Cmp->Buffer, Cmp->Buffer+MAX_DICT_SIZE, + Cmp->DictSize+MAXREP); + Cur -= MAX_DICT_SIZE; + } + } while (CmpEnd == FALSE); + + OutputBits(Cmp, Cmp->LitBits[EOF_CODE], Cmp->LitCode[EOF_CODE]); + + if (Cmp->OutPos != 0) + ++Cmp->OutPtr; + (* Cmp->PutBuf)(Cmp->OutBuf, &Cmp->OutPtr, Cmp->Param); +} + +/************************************************** + Function: FindRep +*************************************************** +*/ +#define KMP_THRESHOLD 10 + +static UINT FindRep(struct CMP_DATA *Cmp, UCHAR *Start) +{ + INT CurLen=1; + register INT Len; + UCHAR *Pat; + register UCHAR *Ptr; + UINT ind; + UCHAR *Lim; + UINT HashVal; + UINT MinIndex; + + ind=Cmp->Index[HashVal=FOO(Start)]; + MinIndex = (UINT)(Start - Cmp->DictSize + 1 - Cmp->Buffer); + + if (MinIndex > Cmp->SortBuf[ind]) + { + do { + ++ind; + } while (MinIndex > Cmp->SortBuf[ind]); /* enddo */ + Cmp->Index[HashVal] = (USHORT)ind; + } + + Lim=Start-1; + + if ((Ptr = &Cmp->Buffer[Cmp->SortBuf[ind]]) >= Lim) + return 0; + + Pat=Start; + + do + { + if (*(Ptr+CurLen-1) == *(Pat+CurLen-1) && *Ptr == *Pat) + { + ++Ptr; ++Pat; Len=2; + while (*++Ptr==*++Pat && ++Len= CurLen) + { + Cmp->Distance = (unsigned)(Pat-Ptr+Len-1); + if ((CurLen=Len) > KMP_THRESHOLD) + { + if (Len == MAXREP) + { + --(Cmp->Distance); + return Len; + } + goto DoKMP; + } + } + } + } + while ((Ptr = &Cmp->Buffer[Cmp->SortBuf[++ind]]) < Lim); + return CurLen >= MINREP ? CurLen : 0; +{ +SHORT i1, j1; +UCHAR *BasePtr; + +DoKMP: +if (&Cmp->Buffer[Cmp->SortBuf[ind+1]] >= Lim) + return CurLen; + +j1 = Cmp->Next[1] = 0; +Cmp->Next[0] = -1; +i1 = 1; +do + { if (Pat[i1] == Pat[j1] || (j1 = Cmp->Next[j1]) == -1) + Cmp->Next[++i1] = ++j1; + } +while (i1 < CurLen); + +Len = CurLen; +Ptr = &Cmp->Buffer[Cmp->SortBuf[ind]+CurLen]; + +while (TRUE) + { if ((Len = Cmp->Next[Len]) == -1) + Len = 0; + + do + { if ((BasePtr=&Cmp->Buffer[Cmp->SortBuf[++ind]]) >= Lim) + return CurLen; + } while (BasePtr+Len < Ptr); + + if (*(BasePtr+CurLen-2) != *(Pat+CurLen-2)) + { + do { + if ((BasePtr=&Cmp->Buffer[Cmp->SortBuf[++ind]]) >= Lim) + return CurLen; + } while (*(BasePtr+CurLen-2) != *(Pat+CurLen-2) || *BasePtr != *Pat); + Len = 2; + Ptr = BasePtr+Len; + } + else if (BasePtr+Len != Ptr) + { Len = 0; + Ptr = BasePtr; + } + + while (*Ptr == Pat[Len] && ++Len < MAXREP) + Ptr++; + + if (Len >= CurLen) + { Cmp->Distance = (UINT)(Start-BasePtr-1); + if (Len > CurLen) + { if (Len == MAXREP) + return Len; + CurLen = Len; + do + { if (Pat[i1] == Pat[j1] || (j1 = Cmp->Next[j1]) == -1) + Cmp->Next[++i1] = ++j1; + } + while (i1 < CurLen); + } + } + } +} + +} + +/*************************************************** + Function: OutputBits +**************************************************** +*/ +static VOID OutputBits(struct CMP_DATA *Cmp, UINT Cnt, UINT Code) +{ + unsigned p; + + if (Cnt > 8) + { + OutputBits(Cmp, 8,Code); + Cnt -= 8; + Code >>= 8; + } + + *(Cmp->OutBuf+Cmp->OutPtr) |= Code << (p = Cmp->OutPos); + + if ((Cmp->OutPos = p + Cnt) > 8) + { + ++Cmp->OutPtr; + *(Cmp->OutBuf+Cmp->OutPtr) = (UCHAR)(Code >> (8 - p)); + Cmp->OutPos &= 7; + } + else if ((Cmp->OutPos &= 7) == 0) + ++Cmp->OutPtr; + + if (Cmp->OutPtr >= OUT_SIZE) + FlushBuf(Cmp); +} + + +/*************************************************** + Function: lmemcpy +**************************************************** +*/ + +static VOID lmemcpy(VOID *Dest, VOID *Source, UINT Size) +{ + UCHAR *s=(UCHAR *)Source, *t=(UCHAR *)Dest; +#ifndef _ALPHA + UINT count=Size/4; + + if (count) + { do + { *(ULONG *)t = *(ULONG *)s; + s+=4; + t+=4; + } + while (--count); + } + + if (Size %= 4) +#endif + do + { + *t++=*s++; + } while (--Size); +} + + +/************************************************** + Function: lmemset +*************************************************** +*/ +static VOID lmemset(VOID *Buf, UCHAR ch, UINT Size) +{ + UCHAR *s=(UCHAR *)Buf; +#ifndef _ALPHA + UINT count=Size/4; + ULONG Ch2=ch; + ULONG LongCh = (((((Ch2 << 8) | Ch2) << 8) | Ch2) << 8) | Ch2; + + if (count) + { do + { *(ULONG *)s = LongCh; + s+=4; + } + while (--count); + } + + if (Size %= 4) +#endif + do { + *s++=(UCHAR)ch; + } while (--Size); +} + + +/************************************************** + Function: FlushBuf +*************************************************** +*/ +static VOID FlushBuf(struct CMP_DATA *Cmp) +{ + UCHAR s1, s2; + UINT i = OUT_SIZE; + + (* Cmp->PutBuf)(Cmp->OutBuf, &i, Cmp->Param); + + s1 = Cmp->OutBuf[Cmp->OutPtr]; + s2 = Cmp->OutBuf[OUT_SIZE]; + Cmp->OutPtr -= OUT_SIZE; + lmemset(Cmp->OutBuf,0,OUT_SIZE+2); + if (Cmp->OutPtr > 0) + Cmp->OutBuf[0] = s2; + if (Cmp->OutPos != 0) + Cmp->OutBuf[Cmp->OutPtr] = s1; +} + +/**************************************************** + Function: SortBuffer +***************************************************** + Do a distribution sort on a 3 character hash value of the passed buffer. +*/ + +static VOID SortBuffer(struct CMP_DATA *Cmp, UCHAR *low, UCHAR *hi) +{ + UINT *Ptr; + USHORT Accum = 0, *IndexPtr; + UCHAR *p; + + Ptr = (UINT *)Cmp->Index; + do { /* Zero all index values */ + *Ptr = 0; + } while (++Ptr < (UINT *)&Cmp->Index[FOO_SIZE]); + + p = low; /* Get hash counts */ + do + { + ++(Cmp->Index[FOO(p)]); + } while (++p < hi); + + IndexPtr = Cmp->Index; + do /* Accumulate counts */ + { + Accum += *IndexPtr; + *IndexPtr = Accum; + } while (++IndexPtr < &Cmp->Index[FOO_SIZE]); + + p = hi - 1; /* Complete sort buffer */ + do { + IndexPtr = &Cmp->Index[FOO(p)]; + --(*IndexPtr); + Cmp->SortBuf[*IndexPtr] = (USHORT)(p - Cmp->Buffer); + } while (--p >= low); +} + + diff --git a/2020_03_31/3rdParty/Pkware/Source/implode.def b/2020_03_31/3rdParty/Pkware/Source/implode.def new file mode 100644 index 00000000..9ceef206 --- /dev/null +++ b/2020_03_31/3rdParty/Pkware/Source/implode.def @@ -0,0 +1,6 @@ +NAME IMPLODE.DLL + +EXPORTS + implode + explode + crc32 diff --git a/2020_03_31/3rdParty/Pkware/Source/implode.h b/2020_03_31/3rdParty/Pkware/Source/implode.h new file mode 100644 index 00000000..ce97a5ef --- /dev/null +++ b/2020_03_31/3rdParty/Pkware/Source/implode.h @@ -0,0 +1,43 @@ +/* +PKWARE Data Compression Library (R) for Win32 +Copyright 1994-95 PKWARE Inc. All Rights Reserved. +*/ + +#ifdef __cplusplus + extern "C" { +#endif + +unsigned int implode( + unsigned int (*read_buf)(char *buf, unsigned int *size, void *param), + void (*write_buf)(char *buf, unsigned int *size, void *param), + char *work_buf, + void *param, + unsigned int *type, + unsigned int *dsize); + + +unsigned int explode( + unsigned int (*read_buf)(char *buf, unsigned int *size, void *param), + void (*write_buf)(char *buf, unsigned int *size, void *param), + char *work_buf, + void *param); + +unsigned long crc32(char *buffer, unsigned int *size, unsigned long *old_crc); + +#ifdef __cplusplus + } // End of 'extern "C"' declaration +#endif + + +#define CMP_BUFFER_SIZE 36312 +#define EXP_BUFFER_SIZE 12596 + +#define CMP_BINARY 0 +#define CMP_ASCII 1 + +#define CMP_NO_ERROR 0 +#define CMP_INVALID_DICTSIZE 1 +#define CMP_INVALID_MODE 2 +#define CMP_BAD_DATA 3 +#define CMP_ABORT 4 + diff --git a/2020_03_31/3rdParty/Pkware/Source/tables.inc b/2020_03_31/3rdParty/Pkware/Source/tables.inc new file mode 100644 index 00000000..ed386ab3 --- /dev/null +++ b/2020_03_31/3rdParty/Pkware/Source/tables.inc @@ -0,0 +1,88 @@ + +static unsigned char DistBits[]= + { 2, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 + }; + +static unsigned char DistCode[] = { +0x003,0x00d,0x005,0x019,0x009,0x011,0x001,0x03e, +0x01e,0x02e,0x00e,0x036,0x016,0x026,0x006,0x03a, +0x01a,0x02a,0x00a,0x032,0x012,0x022,0x042,0x002, +0x07c,0x03c,0x05c,0x01c,0x06c,0x02c,0x04c,0x00c, + +0x074,0x034,0x054,0x014,0x064,0x024,0x044,0x004, +0x078,0x038,0x058,0x018,0x068,0x028,0x048,0x008, +0x0f0,0x070,0x0b0,0x030,0x0d0,0x050,0x090,0x010, +0x0e0,0x060,0x0a0,0x020,0x0c0,0x040,0x080,0x000 +}; + +static unsigned char ExLenBits[] = + { 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8 }; + +#ifdef EXPLODE +static unsigned short int LenBase[] = + { 0, 1, 2, 3, 4, 5, 6, 7, 8,10,14,22,38,70,134,262 }; +#endif + +static unsigned char LenBits[] = + { 3, 2, 3, 3, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 7, 7 }; + +static unsigned char LenCode[]= + { 0x05, 0x03, 0x01, 0x06, 0x0A, 0x02, 0x0C, 0x14, + 0x04, 0x18, 0x08, 0x30, 0x10, 0x20, 0x40, 0x00 }; + +static unsigned char ChBitsAsc[] = { +11, 12, 12, 12, 12, 12, 12, 12, 12, 8, 7, 12, 12, 7, 12, 12, +12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 12, 12, 12, 12, 12, + 4, 10, 8, 12, 10, 12, 10, 8, 7, 7, 8, 9, 7, 6, 7, 8, + 7, 6, 7, 7, 7, 7, 8, 7, 7, 8, 8, 12, 11, 7, 9, 11, +12, 6, 7, 6, 6, 5, 7, 8, 8, 6, 11, 9, 6, 7, 6, 6, + 7, 11, 6, 6, 6, 7, 9, 8, 9, 9, 11, 8, 11, 9, 12, 8, +12, 5, 6, 6, 6, 5, 6, 6, 6, 5, 11, 7, 5, 6, 5, 5, + 6, 10, 5, 5, 5, 5, 8, 7, 8, 8, 10, 11, 11, 12, 12, 12, +13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, +13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, +13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, +12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +13, 12, 13, 13, 13, 12, 13, 13, 13, 12, 13, 13, 13, 13, 12, 13, +13, 13, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13 +}; + +static unsigned short int ChCodeAsc[]={ +0x490 , 0xfe0 , 0x7e0 , 0xbe0 , 0x3e0 , 0xde0 , 0x5e0 , 0x9e0 , +0x1e0 , 0xb8 , 0x62 , 0xee0 , 0x6e0 , 0x22 , 0xae0 , 0x2e0 , +0xce0 , 0x4e0 , 0x8e0 , 0xe0 , 0xf60 , 0x760 , 0xb60 , 0x360 , +0xd60 , 0x560 , 0x1240, 0x960 , 0x160 , 0xe60 , 0x660 , 0xa60 , +0xf , 0x250 , 0x38 , 0x260 , 0x50 , 0xc60 , 0x390 , 0xd8 , +0x42 , 0x2 , 0x58 , 0x1b0 , 0x7c , 0x29 , 0x3c , 0x98 , +0x5c , 0x9 , 0x1c , 0x6c , 0x2c , 0x4c , 0x18 , 0xc , +0x74 , 0xe8 , 0x68 , 0x460 , 0x90 , 0x34 , 0xb0 , 0x710 , +0x860 , 0x31 , 0x54 , 0x11 , 0x21 , 0x17 , 0x14 , 0xa8 , +0x28 , 0x1 , 0x310 , 0x130 , 0x3e , 0x64 , 0x1e , 0x2e , +0x24 , 0x510 , 0xe , 0x36 , 0x16 , 0x44 , 0x30 , 0xc8 , +0x1d0 , 0xd0 , 0x110 , 0x48 , 0x610 , 0x150 , 0x60 , 0x88 , +0xfa0 , 0x7 , 0x26 , 0x6 , 0x3a , 0x1b , 0x1a , 0x2a , +0xa , 0xb , 0x210 , 0x4 , 0x13 , 0x32 , 0x3 , 0x1d , +0x12 , 0x190 , 0xd , 0x15 , 0x5 , 0x19 , 0x8 , 0x78 , +0xf0 , 0x70 , 0x290 , 0x410 , 0x10 , 0x7a0 , 0xba0 , 0x3a0 , +0x240 , 0x1c40, 0xc40 , 0x1440, 0x440 , 0x1840, 0x840 , 0x1040, +0x40 , 0x1f80, 0xf80 , 0x1780, 0x780 , 0x1b80, 0xb80 , 0x1380, +0x380 , 0x1d80, 0xd80 , 0x1580, 0x580 , 0x1980, 0x980 , 0x1180, +0x180 , 0x1e80, 0xe80 , 0x1680, 0x680 , 0x1a80, 0xa80 , 0x1280, +0x280 , 0x1c80, 0xc80 , 0x1480, 0x480 , 0x1880, 0x880 , 0x1080, +0x80 , 0x1f00, 0xf00 , 0x1700, 0x700 , 0x1b00, 0xb00 , 0x1300, +0xda0 , 0x5a0 , 0x9a0 , 0x1a0 , 0xea0 , 0x6a0 , 0xaa0 , 0x2a0 , +0xca0 , 0x4a0 , 0x8a0 , 0xa0 , 0xf20 , 0x720 , 0xb20 , 0x320 , +0xd20 , 0x520 , 0x920 , 0x120 , 0xe20 , 0x620 , 0xa20 , 0x220 , +0xc20 , 0x420 , 0x820 , 0x20 , 0xfc0 , 0x7c0 , 0xbc0 , 0x3c0 , +0xdc0 , 0x5c0 , 0x9c0 , 0x1c0 , 0xec0 , 0x6c0 , 0xac0 , 0x2c0 , +0xcc0 , 0x4c0 , 0x8c0 , 0xc0 , 0xf40 , 0x740 , 0xb40 , 0x340 , +0x300 , 0xd40 , 0x1d00, 0xd00 , 0x1500, 0x540 , 0x500 , 0x1900, +0x900 , 0x940 , 0x1100, 0x100 , 0x1e00, 0xe00 , 0x140 , 0x1600, +0x600 , 0x1a00, 0xe40 , 0x640 , 0xa40 , 0xa00 , 0x1200, 0x200 , +0x1c00, 0xc00 , 0x1400, 0x400 , 0x1800, 0x800 , 0x1000, 0x0 +}; diff --git a/2020_03_31/3rdParty/Pkware/implode.h b/2020_03_31/3rdParty/Pkware/implode.h new file mode 100644 index 00000000..c65ccc1a --- /dev/null +++ b/2020_03_31/3rdParty/Pkware/implode.h @@ -0,0 +1,44 @@ +/*************************************************************** + PKWARE Data Compression Library (R) for Win32 + Copyright 1991,1992,1994,1995 PKWARE Inc. All Rights Reserved. + PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. +***************************************************************/ + +#ifdef __cplusplus + extern "C" { +#endif + +unsigned int __cdecl implode( + unsigned int (__cdecl *read_buf)(char *buf, unsigned int *size, void *param), + void (__cdecl *write_buf)(char *buf, unsigned int *size, void *param), + char *work_buf, + void *param, + unsigned int *type, + unsigned int *dsize); + + +unsigned int __cdecl explode( + unsigned int (__cdecl *read_buf)(char *buf, unsigned int *size, void *param), + void (__cdecl *write_buf)(char *buf, unsigned int *size, void *param), + char *work_buf, + void *param); + +unsigned long __cdecl crc32(char *buffer, unsigned int *size, unsigned long *old_crc); + +#ifdef __cplusplus + } // End of 'extern "C"' declaration +#endif + + +#define CMP_BUFFER_SIZE 36312 +#define EXP_BUFFER_SIZE 12596 + +#define CMP_BINARY 0 +#define CMP_ASCII 1 + +#define CMP_NO_ERROR 0 +#define CMP_INVALID_DICTSIZE 1 +#define CMP_INVALID_MODE 2 +#define CMP_BAD_DATA 3 +#define CMP_ABORT 4 + diff --git a/2020_03_31/3rdParty/Storm/Source/Storm.dsp b/2020_03_31/3rdParty/Storm/Source/Storm.dsp new file mode 100644 index 00000000..e0b9dda1 --- /dev/null +++ b/2020_03_31/3rdParty/Storm/Source/Storm.dsp @@ -0,0 +1,93 @@ +# Microsoft Developer Studio Project File - Name="Storm" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=Storm - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "Storm.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "Storm.mak" CFG="Storm - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "Storm - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "Storm - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "Storm - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "WinRel" +# PROP BASE Intermediate_Dir "WinRel" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "WinRel" +# PROP Intermediate_Dir "WinRel" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 /def:"storm.def" + +!ELSEIF "$(CFG)" == "Storm - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "WinDebug" +# PROP BASE Intermediate_Dir "WinDebug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "WinDebug" +# PROP Intermediate_Dir "WinDebug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /O1 /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /def:"storm.def" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "Storm - Win32 Release" +# Name "Storm - Win32 Debug" +# Begin Source File + +SOURCE=.\storm.cpp +# End Source File +# End Target +# End Project diff --git a/2020_03_31/3rdParty/Storm/Source/Storm.vcxproj b/2020_03_31/3rdParty/Storm/Source/Storm.vcxproj new file mode 100644 index 00000000..986799d9 --- /dev/null +++ b/2020_03_31/3rdParty/Storm/Source/Storm.vcxproj @@ -0,0 +1,146 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + + + {B28F69CE-15A1-424D-BBB5-2727258D675B} + + + + DynamicLibrary + v141 + false + + + DynamicLibrary + v141 + false + + + + + + + + + + + + + + + .\WinRel\ + .\WinRel\ + false + + + .\WinDebug\ + .\WinDebug\ + true + + + + MultiThreaded + Default + true + true + MaxSpeed + true + Level3 + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + .\WinRel\ + .\WinRel\Storm.pch + .\WinRel\ + .\WinRel\ + + + true + NDEBUG;%(PreprocessorDefinitions) + .\WinRel\Storm.tlb + true + NUL + Win32 + + + 0x0409 + NDEBUG;%(PreprocessorDefinitions) + + + true + .\WinRel\Storm.bsc + + + true + true + Windows + storm.def + .\WinRel\Storm.dll + .\WinRel\Storm.lib + odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + MultiThreadedDebug + Default + Disabled + true + Level3 + true + EditAndContinue + WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + .\WinDebug\ + .\WinDebug\Storm.pch + .\WinDebug\ + .\WinDebug\ + + + true + _DEBUG;%(PreprocessorDefinitions) + .\WinDebug\Storm.tlb + true + NUL + Win32 + + + 0x0409 + _DEBUG;%(PreprocessorDefinitions) + + + true + .\WinDebug\Storm.bsc + + + true + true + true + Windows + storm.def + .\WinDebug\Storm.dll + .\WinDebug\Storm.lib + odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/2020_03_31/3rdParty/Storm/Source/storm.cpp b/2020_03_31/3rdParty/Storm/Source/storm.cpp new file mode 100644 index 00000000..511a538b --- /dev/null +++ b/2020_03_31/3rdParty/Storm/Source/storm.cpp @@ -0,0 +1,253 @@ +#include "storm.h" + +#define rBool { return TRUE; } +#define rPVoid { return NULL; } +#define rVoid { return; } +#define rInt { return 0; } + +BOOL STORMAPI SNetCreateGame(const char *pszGameName, const char *pszGamePassword, const char *pszGameStatString, DWORD dwGameType, void *GameTemplateData, int GameTemplateSize, int playerCount, char *creatorName, char *a11, DWORD *playerID) rBool; +BOOL STORMAPI SNetDestroy() rBool; +BOOL STORMAPI SNetEnumProviders(int (STORMAPI *callback)(DWORD, DWORD, DWORD, DWORD), int mincaps) rBool; + +BOOL STORMAPI SNetEnumGames(int (STORMAPI *callback)(DWORD, DWORD, DWORD), int *hintnextcall) rBool; +BOOL STORMAPI SNetDropPlayer(int playerid, DWORD flags) rBool; +BOOL STORMAPI SNetGetGameInfo(int type, void *dst, size_t length, DWORD *byteswritten) rBool; + +BOOL STORMAPI SNetGetNumPlayers(int *firstplayerid, int *lastplayerid, int *activeplayers) rBool; + +BOOL STORMAPI SNetGetPlayerCaps(char playerid, PCAPS playerCaps) rBool; +BOOL STORMAPI SNetGetPlayerName(int playerid, char *buffer, size_t buffersize) rBool; +//BOOL STORMAPI SNetGetProviderCaps(PCAPS providerCaps) rBool; +BOOL STORMAPI SNetGetTurnsInTransit(DWORD *turns) rBool; +BOOL STORMAPI SNetInitializeDevice(int a1, int a2, int a3, int a4, int *a5) rBool; +//BOOL STORMAPI SNetInitializeProvider(DWORD providerName, client_info *gameClientInfo, user_info *userData, battle_info *bnCallbacks, module_info *moduleData) rBool; +BOOL STORMAPI SNetJoinGame(int id, char *gameName, char *gamePassword, char *playerName, char *userStats, int *playerid) rBool; +BOOL STORMAPI SNetLeaveGame(int type) rBool; +BOOL STORMAPI SNetPerformUpgrade(DWORD *upgradestatus) rBool; +BOOL STORMAPI SNetReceiveMessage(DWORD *senderplayerid, char **data, DWORD *databytes) rBool; +BOOL STORMAPI SNetReceiveTurns(int a1, int arraysize, void *arraydata, void *arraydatabytes, void *arrayplayerstatus) rBool; +//HANDLE STORMAPI SNetRegisterEventHandler(int type, void (STORMAPI *sEvent)(PS_EVT)) rPVoid; + +int STORMAPI SNetSelectGame(int a1, int a2, int a3, int a4, int a5, int *playerid) rInt; + +BOOL STORMAPI SNetSendMessage(int playerID, void *data, size_t databytes) rBool; +BOOL STORMAPI SNetSendTurn(void *data, size_t databytes) rBool; + +BOOL STORMAPI SNetSetGameMode(DWORD modeFlags, _bool makePublic) rBool; + +BOOL STORMAPI SNetEnumGamesEx(int a1, int a2, int (__fastcall *callback)(DWORD, DWORD, DWORD), int *hintnextcall) rBool; +BOOL STORMAPI SNetSendServerChatCommand(const char *command) rBool; + +BOOL STORMAPI SNetDisconnectAll(DWORD flags) rBool; +BOOL STORMAPI SNetCreateLadderGame(const char *pszGameName, const char *pszGamePassword, const char *pszGameStatString, DWORD dwGameType, DWORD dwGameLadderType, DWORD dwGameModeFlags, char *GameTemplateData, int GameTemplateSize, int playerCount, char *creatorName, char *a11, int *playerID) rBool; +BOOL STORMAPI SNetReportGameResult(unsigned a1, int size, int *results, const char* headerInfo, const char* detailInfo) rBool; + +int STORMAPI SNetSendLeagueCommand(char *cmd, char *callback) rInt; +int STORMAPI SNetSendReplayPath(int a1, int a2, char *replayPath) rInt; +int STORMAPI SNetGetLeagueName(int leagueID) rInt; +BOOL STORMAPI SNetGetPlayerNames(char **names) rBool; +int STORMAPI SNetLeagueLogout(char *bnetName) rInt; +int STORMAPI SNetGetLeaguePlayerName(char *curPlayerLeageName, size_t nameSize) rInt; + +HGDIOBJ STORMAPI SDlgDefDialogProc(HWND hDlg, signed int DlgType, HDC textLabel, HWND hWnd) rPVoid; + +HANDLE STORMAPI SDlgDialogBoxIndirectParam(HMODULE hModule, LPCSTR lpName, HWND hWndParent, LPVOID lpParam, LPARAM lParam) rPVoid; + +BOOL STORMAPI SDlgEndDialog(HWND hDlg, HANDLE nResult) rBool; + +BOOL STORMAPI SDlgSetControlBitmaps(HWND parentwindow, int *id, int a3, char *buffer2, char *buffer, int flags, int mask) rBool; + +BOOL STORMAPI SDlgBltToWindowI(HWND hWnd, HRGN a2, char *a3, int a4, void *buffer, RECT *rct, SIZE *size, int a8, int a9, DWORD rop) rBool; +BOOL STORMAPI SDlgBltToWindowE(HWND hWnd, HRGN a2, char *a3, int a4, void *buffer, RECT *rct, SIZE *size, int a8, int a9, DWORD rop) rBool; +BOOL STORMAPI SDlgSetBitmapE(HWND hWnd, int a2, char *src, int mask1, int flags, int a6, int a7, int width, int a9, int mask2) rBool; + +int STORMAPI Ordinal224(int a1) rInt; + +BOOL STORMAPI SFileCloseArchive(HANDLE hArchive) rBool; +BOOL STORMAPI SFileCloseFile(HANDLE hFile) rBool; + +BOOL STORMAPI SFileDdaBeginEx(HANDLE directsound, DWORD flags, DWORD mask, unsigned __int32 lDistanceToMove, signed __int32 volume, signed int a6, int a7) rBool; +BOOL STORMAPI SFileDdaDestroy() rBool; +BOOL STORMAPI SFileDdaEnd(HANDLE directsound) rBool; +BOOL STORMAPI SFileDdaGetPos(HANDLE directsound, DWORD *a2, DWORD *a3) rBool; + +BOOL STORMAPI SFileDdaInitialize(HANDLE directsound) rBool; +BOOL STORMAPI SFileDdaSetVolume(HANDLE directsound, signed int bigvolume, signed int volume) rBool; +BOOL STORMAPI SFileDestroy() rBool; + +BOOL STORMAPI SFileGetFileArchive(HANDLE hFile, HANDLE archive) rBool; +LONG STORMAPI SFileGetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh) rInt; +BOOL STORMAPI SFileOpenArchive(const char *szMpqName, DWORD dwPriority, DWORD dwFlags, HANDLE *phMpq) rBool; +BOOL STORMAPI SFileOpenFile(const char *filename, HANDLE *phFile) rBool; +BOOL STORMAPI SFileOpenFileEx(HANDLE hMpq, const char *szFileName, DWORD dwSearchScope, HANDLE *phFile) rBool; +BOOL STORMAPI SFileReadFile(HANDLE hFile, void *buffer, DWORD nNumberOfBytesToRead, DWORD *read, LONG lpDistanceToMoveHigh) rBool; + +void STORMAPI SFileSetLocale(LCID lcLocale) rVoid; + +BOOL STORMAPI SFileSetIoErrorMode(int mode, BOOL (STORMAPI *callback)(char*,int,int) ) rBool; +BOOL STORMAPI SFileGetArchiveName(HANDLE hArchive, char *name, int length) rBool; +BOOL STORMAPI SFileGetFileName(HANDLE hFile, char *buffer, int length) rBool; + +BOOL STORMAPI SFileLoadFile(char *filename, void *buffer, int buffersize, int a4, int a5) rBool; +BOOL STORMAPI SFileUnloadFile(HANDLE hFile) rBool; +BOOL STORMAPI SFileLoadFileEx(void *hArchive, char *filename, int a3, int a4, int a5, DWORD searchScope, struct _OVERLAPPED *lpOverlapped) rBool; + +BOOL STORMAPI SBltROP3(void *lpDstBuffer, void *lpSrcBuffer, int width, int height, int a5, int a6, int a7, DWORD rop) rBool; +BOOL STORMAPI SBltROP3Clipped(void *lpDstBuffer, RECT *lpDstRect, POINT *lpDstPt, int a4, void *lpSrcBuffer, RECT *lpSrcRect, POINT *lpSrcPt, int a8, int a9, DWORD rop) rBool; +BOOL STORMAPI SBltROP3Tiled(void *lpDstBuffer, RECT *lpDstRect, POINT *lpDstPt, int a4, void *lpSrcBuffer, RECT *lpSrcRect, POINT *lpSrcPt, int a8, int a9, DWORD rop) rBool; + +BOOL STORMAPI SBmpDecodeImage(DWORD dwImgType, void *pSrcBuffer, DWORD dwSrcBuffersize, PALETTEENTRY *pPalette, void *pDstBuffer, DWORD dwDstBuffersize, DWORD *pdwWidth, DWORD *pdwHeight, DWORD *pdwBpp) rBool; + +BOOL STORMAPI SBmpLoadImage(const char *pszFileName, PALETTEENTRY *pPalette, void *pBuffer, DWORD dwBuffersize, DWORD *pdwWidth, DWORD *dwHeight, DWORD *pdwBpp) rBool; + +BOOL STORMAPI SBmpSaveImage(const char*, PALETTEENTRY*, void*, DWORD, DWORD, DWORD) rBool; +HANDLE STORMAPI SBmpAllocLoadImage(const char *fileName, PALETTEENTRY *palette, void **buffer, int *width, int *height, int unused6, int unused7, void *(STORMAPI *allocFunction)(DWORD)) rPVoid; + +BOOL STORMAPI SCodeCompile(char *directives1, char *directives2, char *loopstring, unsigned int maxiterations, unsigned int flags, HANDLE handle) rBool; +BOOL STORMAPI SCodeDelete(HANDLE handle) rBool; + +int STORMAPI SCodeExecute(HANDLE handle, int a2) rInt; + +BOOL STORMAPI SDrawAutoInitialize(HINSTANCE hInst, LPCSTR lpClassName, LPCSTR lpWindowName, WNDPROC pfnWndProc, int nMode, int nWidth, int nHeight, int nBits) rBool; +BOOL STORMAPI SDrawCaptureScreen(const char *source) rBool; + +HWND STORMAPI SDrawGetFrameWindow(HWND *sdraw_framewindow) rPVoid; +BOOL STORMAPI SDrawGetObjects(LPDIRECTDRAW *ddInterface, LPDIRECTDRAWSURFACE *primarySurface, LPDIRECTDRAWSURFACE *surface2, LPDIRECTDRAWSURFACE *surface3, LPDIRECTDRAWSURFACE *backSurface, LPDIRECTDRAWPALETTE *ddPalette, HPALETTE *hPalette) rBool; +BOOL STORMAPI SDrawGetScreenSize(DWORD *pdwWidth, DWORD *pdwHeight, DWORD *pdwBpp) rBool; + +BOOL STORMAPI SDrawLockSurface(int surfacenumber, RECT *lpDestRect, void **lplpSurface, int *lpPitch, int arg_unused) rBool; +BOOL STORMAPI SDrawManualInitialize(HWND hWnd, LPDIRECTDRAW ddInterface, LPDIRECTDRAWSURFACE primarySurface, LPDIRECTDRAWSURFACE surface2, LPDIRECTDRAWSURFACE surface3, LPDIRECTDRAWSURFACE backSurface, LPDIRECTDRAWPALETTE ddPalette, HPALETTE hPalette) rBool; + +BOOL STORMAPI SDrawPostClose() rBool; +//BOOL STORMAPI SDrawRealizePalette() rBool; + +BOOL STORMAPI SDrawUnlockSurface(int surfacenumber, void *lpSurface, int a3, RECT *lpRect) rBool; +BOOL STORMAPI SDrawUpdatePalette(unsigned int firstentry, unsigned int numentries, PALETTEENTRY *pPalEntries, int a4) rBool; + +BOOL STORMAPI SEvtDispatch(DWORD dwMessageID, DWORD dwFlags, int type, PS_EVT pEvent) rBool; + +BOOL STORMAPI SGdiDeleteObject(HANDLE handle) rBool; + +BOOL STORMAPI SGdiExtTextOut(int a1, int a2, int a3, int a4, unsigned int a8, signed int a6, signed int a7, const char *string, unsigned int arg20) rBool; +BOOL STORMAPI SGdiImportFont(HGDIOBJ handle, int windowsfont) rBool; + +BOOL STORMAPI SGdiSelectObject(int handle) rBool; +BOOL STORMAPI SGdiSetPitch(int pitch) rBool; + +BOOL STORMAPI Ordinal393(char *string, int, int) rBool; + +void* STORMAPI SMemAlloc(size_t amount, char *logfilename, int logline, char defaultValue) rPVoid; + +BOOL STORMAPI SMemFree(void *location, char *logfilename, int logline, char defaultValue) rBool; + +void* STORMAPI SMemReAlloc(void *location, size_t amount, char *logfilename, int logline, char defaultValue) rPVoid; + +BOOL STORMAPI SRegLoadData(const char *keyname, const char *valuename, int size, LPBYTE lpData, BYTE flags, LPDWORD lpcbData) rBool; +BOOL STORMAPI SRegLoadString(const char *keyname, const char *valuename, BYTE flags, char *buffer, size_t buffersize) rBool; +BOOL STORMAPI SRegLoadValue(const char *keyname, const char *valuename, BYTE flags, DWORD *value) rBool; +BOOL STORMAPI SRegSaveData(const char *keyname, const char *valuename, int size, BYTE *lpData, DWORD cbData) rBool; +BOOL STORMAPI SRegSaveString(const char *keyname, const char *valuename, BYTE flags, char *string) rBool; +BOOL STORMAPI SRegSaveValue(const char *keyname, const char *valuename, BYTE flags, DWORD result) rBool; + +BOOL STORMAPI SRegDeleteValue(const char *keyname, const char *valuename, BYTE flags) rBool; + +BOOL STORMAPI STransBlt(void *lpSurface, int x, int y, int width, HANDLE hTrans) rBool; +BOOL STORMAPI STransBltUsingMask(void *lpSurface, void *lpSource, int pitch, int width, HANDLE hTrans) rBool; + +BOOL STORMAPI STransDelete(HANDLE hTrans) rBool; + +BOOL STORMAPI STransDuplicate(HANDLE hTransSource, HANDLE hTransDest) rBool; +BOOL STORMAPI STransIntersectDirtyArray(HANDLE hTrans, char * dirtyarraymask, unsigned flags, HANDLE * phTransResult) rBool; +BOOL STORMAPI STransInvertMask(HANDLE hTrans, HANDLE * phTransResult) rBool; + +BOOL STORMAPI STransSetDirtyArrayInfo(int width, int height, int depth, int bits) rBool; + +BOOL STORMAPI STransPointInMask(HANDLE hTrans, int x, int y) rBool; +BOOL STORMAPI STransCombineMasks(HANDLE hTransA, HANDLE hTransB, int left, int top, int flags, HANDLE * phTransResult) rBool; + +BOOL STORMAPI STransCreateE(void *pBuffer, int width, int height, int bpp, int a5, int bufferSize, HANDLE *phTransOut) rBool; +BOOL STORMAPI STransCreateI(void *pBuffer, int width, int height, int bpp, int a5, int bufferSize, HANDLE *phTransOut) rBool; + +BOOL STORMAPI SVidDestroy() rBool; +BOOL STORMAPI SVidGetSize(HANDLE video, int width, int height, int zero) rBool; +BOOL STORMAPI SVidInitialize(HANDLE video) rBool; +BOOL STORMAPI SVidPlayBegin(const char *filename, int arg4, int a3, int a4, int a5, int a6, HANDLE* video) rBool; + +BOOL STORMAPI SVidPlayContinueSingle(HANDLE video, int a2, int a3) rBool; +BOOL STORMAPI SVidPlayEnd(HANDLE video) rBool; + +BOOL STORMAPI SErrDisplayError(DWORD dwErrMsg, const char *logfilename, int logline, const char *message, BOOL allowOption, int exitCode) rBool; +BOOL STORMAPI SErrGetErrorStr(DWORD dwErrCode, char *buffer, size_t bufferchars) rBool; +DWORD STORMAPI SErrGetLastError() rInt; + +void STORMAPI SErrSetLastError(DWORD dwErrCode) rVoid; + +void STORMAPI SErrSuppressErrors(BOOL suppressErrors) rVoid; + +void STORMAPI SMemCopy(void *dest, const void *source, size_t size) rVoid; +void STORMAPI SMemFill(void *location, size_t length, char fillWith) rVoid; + +void STORMAPI SMemZero(void *location, DWORD length) rVoid; +int STORMAPI SMemCmp(void *location1, void *location2, DWORD size) rInt; + +int STORMAPI SStrCopy(char *dest, const char *src, int max_length) rInt; +DWORD STORMAPI SStrHash(const char *string, DWORD flags, DWORD Seed) rInt; +int STORMAPI SStrPack(char *dest, const char *src, DWORD max_length) rInt; + +int STORMAPI SStrLen(const char* string) rInt; + +int STORMAPI SStrCmp(const char *string1, const char *string2, size_t size) rInt; +int STORMAPI SStrCmpI(const char *string1, const char *string2, size_t size) rInt; +char* STORMAPI SStrUpper(char* string) rPVoid; + +void STORMAPI SRgn523(HANDLE hRgn, RECT *pRect, int a3, int a4) rVoid; +void STORMAPI SRgnCreateRegion(HANDLE *hRgn, int a2) rVoid; +void STORMAPI SRgnDeleteRegion(HANDLE hRgn) rVoid; + +void STORMAPI SRgn529i(int handle, int a2, int a3) rVoid; + +BOOL __cdecl SErrDisplayErrorFmt(DWORD dwErrMsg, const char *logfilename, int logline, BOOL allowOption, int exitCode, const char *format, ...) rBool; + +void STORMAPI SErrCatchUnhandledExceptions() rVoid; + +char* STORMAPI SStrChr(const char *string, char c) rPVoid; +char* STORMAPI SStrChrR(const char *string, char c) rPVoid; + +size_t __cdecl SStrVPrintf(char *dest, size_t size, const char *format, ...) rInt; + +int STORMAPI SBigDel(void *buffer) rInt; + +int STORMAPI SBigFromBinary(void *buffer, const void *str, size_t size) rInt; + +int STORMAPI SBigNew(void **buffer) rInt; + +int STORMAPI SBigPowMod(void *buffer1, void *buffer2, int a3, int a4) rInt; + +int STORMAPI SBigToBinaryBuffer(void *buffer, int length, int a3, int a4) rInt; +// + +void __stdcall SDrawMessageBox(char *,char *,int) rVoid; +void __cdecl SDrawDestroy(void) rVoid; +_bool __cdecl StormDestroy(void) rBool; +_bool __stdcall SFileSetBasePath(char *) rBool; +void __cdecl SDrawRealizePalette(void) rVoid; +BOOL __stdcall SVidPlayContinue(void) rBool; +BOOL __stdcall SNetGetOwnerTurnsWaiting(DWORD *) rBool; +BOOL __stdcall SNetUnregisterEventHandler(int,void (__stdcall*)(struct _SNETEVENT *)) rBool; +BOOL __stdcall SNetRegisterEventHandler(int,void (__stdcall*)(struct _SNETEVENT *)) rBool; +_bool __stdcall SNetSetBasePlayer(int) rBool; +int __stdcall SNetInitializeProvider(unsigned long,struct _SNETPROGRAMDATA *,struct _SNETPLAYERDATA *,struct _SNETUIDATA *,struct _SNETVERSIONDATA *) rInt; +int __stdcall SNetGetProviderCaps(struct _SNETCAPS *) rInt; +int __stdcall SFileSetFilePointer(HANDLE,int,HANDLE,int) rInt; +void __stdcall SDrawClearSurface(int a1) rVoid; +BOOL __stdcall SDlgSetBitmapI(HWND hWnd, int a2, char *src, int mask1, int flags, void *pBuff, int a7, int width, int height, int mask2) rBool; +void __stdcall SDlgBeginPaint(HWND hWnd, char *a2) rVoid; +void __stdcall SDlgEndPaint(HWND hWnd, char *a2) rVoid; +void __stdcall SDlgSetSystemCursor(BYTE *a1, BYTE *a2, int *a3, int a4) rVoid; +void __stdcall SDlgSetCursor(HWND hWnd, HCURSOR a2, int a3, int *a4) rVoid; +BOOL __stdcall SDlgSetTimer(int a1, int a2, int a3, void (__stdcall *a4)(int, int, int, int)) rBool; +BOOL __stdcall SDlgKillTimer(int a1, int a2) rBool; +BOOL __stdcall SDlgDrawBitmap(HWND hWnd, int a2, int a3, int a4, int a5, int a6, int a7) rBool; +BOOL __stdcall SDlgDialogBoxParam(HINSTANCE hInst, char *szDialog, int a3, WNDPROC func, int a5) rBool; +BOOL __stdcall SGdiTextOut(void *pBuffer, int x, int y, int mask, char *str, int len) rBool; +BOOL __stdcall SFileEnableDirectAccess(BOOL enable) rBool; diff --git a/2020_03_31/3rdParty/Storm/Source/storm.def b/2020_03_31/3rdParty/Storm/Source/storm.def new file mode 100644 index 00000000..fd1d260d --- /dev/null +++ b/2020_03_31/3rdParty/Storm/Source/storm.def @@ -0,0 +1,441 @@ +LIBRARY "Storm" + +EXPORTS + SNetCreateGame @101 NONAME + SNetDestroy @102 NONAME + SNetEnumProviders @103 NONAME + ;SNetEnumDevices @104 NONAME + SNetEnumGames @105 NONAME + SNetDropPlayer @106 NONAME + SNetGetGameInfo @107 NONAME + ;SNetGetNetworkLatency @108 NONAME + SNetGetNumPlayers @109 NONAME + SNetGetOwnerTurnsWaiting @110 NONAME + ;SNetGetPerformanceData @111 NONAME + SNetGetPlayerCaps @112 NONAME + SNetGetPlayerName @113 NONAME + SNetGetProviderCaps @114 NONAME + SNetGetTurnsInTransit @115 NONAME + SNetInitializeDevice @116 NONAME + SNetInitializeProvider @117 NONAME + SNetJoinGame @118 NONAME + SNetLeaveGame @119 NONAME + SNetPerformUpgrade @120 NONAME + SNetReceiveMessage @121 NONAME + SNetReceiveTurns @122 NONAME + SNetRegisterEventHandler @123 NONAME + ;SNetResetLatencyMeasurements @124 NONAME + SNetSelectGame @125 NONAME + ;SNetSelectProvider @126 NONAME + SNetSendMessage @127 NONAME + SNetSendTurn @128 NONAME + SNetSetBasePlayer @129 NONAME + SNetSetGameMode @130 NONAME + SNetUnregisterEventHandler @131 NONAME + + SNetEnumGamesEx @133 NONAME + SNetSendServerChatCommand @134 NONAME + ;SNetSendDatagram @135 NONAME + ;SNetReceiveDatagram @136 NONAME + SNetDisconnectAll @137 NONAME + SNetCreateLadderGame @138 NONAME + SNetReportGameResult @139 NONAME + ;SNetCheckDataFile @140 NONAME + SNetSendLeagueCommand @141 NONAME + SNetSendReplayPath @142 NONAME + SNetGetLeagueName @143 NONAME + SNetGetPlayerNames @144 NONAME + SNetLeagueLogout @145 NONAME + SNetGetLeaguePlayerName @146 NONAME + + ;Ordinal150 @150 NONAME + ;Ordinal151 @151 NONAME + + SDlgBeginPaint @201 NONAME + SDlgBltToWindowI @202 NONAME + ;SDlgCheckTimers @203 NONAME + ;SDlgCreateDialogIndirectParam @204 NONAME + ;SDlgCreateDialogParam @205 NONAME + SDlgDefDialogProc @206 NONAME + + SDlgDialogBoxIndirectParam @208 NONAME + SDlgDialogBoxParam @209 NONAME + SDlgDrawBitmap @210 NONAME + SDlgEndDialog @211 NONAME + SDlgEndPaint @212 NONAME + SDlgKillTimer @213 NONAME + ;SDlgSetBaseFont @214 NONAME + SDlgSetBitmapI @215 NONAME + SDlgSetControlBitmaps @216 NONAME + SDlgSetCursor @217 NONAME + SDlgSetSystemCursor @218 NONAME + SDlgSetTimer @219 NONAME + ;SDlgUpdateCursor @220 NONAME + SDlgBltToWindowE @221 NONAME + SDlgSetBitmapE @222 NONAME + ;SDlgSetLocale @223 NONAME + Ordinal224 @224 NONAME + + ;SFileAuthenticateArchive @251 NONAME + SFileCloseArchive @252 NONAME + SFileCloseFile @253 NONAME + ;SFileDdaBegin @254 NONAME + SFileDdaBeginEx @255 NONAME + SFileDdaDestroy @256 NONAME + SFileDdaEnd @257 NONAME + SFileDdaGetPos @258 NONAME + ;SFileDdaGetVolume @259 NONAME + SFileDdaInitialize @260 NONAME + SFileDdaSetVolume @261 NONAME + SFileDestroy @262 NONAME + SFileEnableDirectAccess @263 NONAME + SFileGetFileArchive @264 NONAME + SFileGetFileSize @265 NONAME + SFileOpenArchive @266 NONAME + SFileOpenFile @267 NONAME + SFileOpenFileEx @268 NONAME + SFileReadFile @269 NONAME + SFileSetBasePath @270 NONAME + SFileSetFilePointer @271 NONAME + SFileSetLocale @272 NONAME + ;SFileGetBasePath @273 NONAME + SFileSetIoErrorMode @274 NONAME + SFileGetArchiveName @275 NONAME + SFileGetFileName @276 NONAME + ;SFileGetArchiveInfo @277 NONAME + ;SFileSetPlatform @278 NONAME + SFileLoadFile @279 NONAME + SFileUnloadFile @280 NONAME + SFileLoadFileEx @281 NONAME + ;SFilePrioritizeRequest @282 NONAME + ;SFileCancelRequest @283 NONAME + ;SFileSetAsyncBudget @284 NONAME + ;SFileSetDataChunkSize @285 NONAME + ;SFileEnableSeekOptimization @286 NONAME + ;SFileReadFileEx @287 NONAME + ;SFileFileExists @288 NONAME + ;SFileFileExistsEx @289 NONAME + ;SFileReadFileEx2 @290 NONAME + ;SFileReadFile2 @291 NONAME + ;SFileLoadFile2 @292 NONAME + ;SFileOpenFileAsArchive @293 NONAME + ;SFileGetLocale @294 NONAME + ;SFileRegisterLoadNotifyProc @295 NONAME + ;SFileGetFileCompressedSize @296 NONAME + ;Ordinal297 @297 NONAME + ;Ordinal298 @298 NONAME + ;SFileAuthenticateArchiveEx @299 NONAME + ;SFileOpenPathAsArchive @300 NONAME + StormDestroy @301 NONAME + ;StormGetInstance @302 NONAME + ;StormGetOption @303 NONAME + ;StormSetOption @304 NONAME + + ;SBltGetSCode @312 NONAME + SBltROP3 @313 NONAME + SBltROP3Clipped @314 NONAME + SBltROP3Tiled @315 NONAME + + SBmpDecodeImage @321 NONAME + + SBmpLoadImage @323 NONAME + SBmpSaveImage @324 NONAME + SBmpAllocLoadImage @325 NONAME + ;SBmpSaveImageEx @326 NONAME + + SCodeCompile @331 NONAME + SCodeDelete @332 NONAME + + SCodeExecute @334 NONAME + ;SCodeGetPseudocode @335 NONAME + + SDrawAutoInitialize @341 NONAME + SDrawCaptureScreen @342 NONAME + SDrawClearSurface @343 NONAME + SDrawDestroy @344 NONAME + ;SDrawFlipPage @345 NONAME + SDrawGetFrameWindow @346 NONAME + SDrawGetObjects @347 NONAME + SDrawGetScreenSize @348 NONAME + ;SDrawGetServiceLevel @349 NONAME + SDrawLockSurface @350 NONAME + SDrawManualInitialize @351 NONAME + SDrawMessageBox @352 NONAME + SDrawPostClose @353 NONAME + SDrawRealizePalette @354 NONAME + ;SDrawSelectGdiSurface @355 NONAME + SDrawUnlockSurface @356 NONAME + SDrawUpdatePalette @357 NONAME + ;SDrawUpdateScreen @358 NONAME + ;SDrawWaitForVerticalBlank @359 NONAME + + SEvtDispatch @372 NONAME + ;SEvtRegisterHandler @373 NONAME + ;SEvtUnregisterHandler @374 NONAME + ;SEvtUnregisterType @375 NONAME + ;SEvtPopState @376 NONAME + ;SEvtPushState @377 NONAME + ;SEvtBreakHandlerChain @378 NONAME + + ;SGdiBitBlt @381 NONAME + ;SGdiCreateFont @382 NONAME + SGdiDeleteObject @383 NONAME + ;SGdiDestroy @384 NONAME + SGdiExtTextOut @385 NONAME + SGdiImportFont @386 NONAME + ;SGdiLoadFont @387 NONAME + ;SGdiRectangle @388 NONAME + SGdiSelectObject @389 NONAME + SGdiSetPitch @390 NONAME + SGdiTextOut @391 NONAME + ;SGdi392 @392 NONAME + Ordinal393 @393 NONAME + + ;SMem399 @399 NONAME + + SMemAlloc @401 NONAME + ;SMemDestroy @402 NONAME + SMemFree @403 NONAME + ;SMemGetSize @404 NONAME + SMemReAlloc @405 NONAME + ;Storm406 @406 NONAME + + ;SMsgDispatchMessage @412 NONAME + ;SMsgDoMessageLoop @413 NONAME + ;SMsgRegisterCommand @414 NONAME + ;SMsgRegisterKeyDown @415 NONAME + ;SMsgRegisterKeyUp @416 NONAME + ;SMsgRegisterMessage @417 NONAME + ;SMsgPopRegisterState @418 NONAME + ;SMsgPushRegisterState @419 NONAME + ;SMsg420 @420 NONAME + SRegLoadData @421 NONAME + SRegLoadString @422 NONAME + SRegLoadValue @423 NONAME + SRegSaveData @424 NONAME + SRegSaveString @425 NONAME + SRegSaveValue @426 NONAME + ;SRegGetBaseKey @427 NONAME + SRegDeleteValue @428 NONAME + ;SReg429 @429 NONAME + ;SReg430 @430 NONAME + STransBlt @431 NONAME + STransBltUsingMask @432 NONAME + STransCreateI @433 NONAME + STransDelete @434 NONAME + + STransDuplicate @436 NONAME + STransIntersectDirtyArray @437 NONAME + STransInvertMask @438 NONAME + ;STransLoadI @439 NONAME + STransSetDirtyArrayInfo @440 NONAME + ;STransUpdateDirtyArray @441 NONAME + STransPointInMask @442 NONAME + STransCombineMasks @443 NONAME + ;STransCreateI @444 NONAME + STransCreateE @445 NONAME + ;STrans446 @446 NONAME + ;STransLoadE @447 NONAME + + SVidDestroy @451 NONAME + SVidGetSize @452 NONAME + SVidInitialize @453 NONAME + SVidPlayBegin @454 NONAME + ;SVidPlayBeginFromMemory @455 NONAME + SVidPlayContinue @456 NONAME + SVidPlayContinueSingle @457 NONAME + SVidPlayEnd @458 NONAME + ;SVidSetVolume @459 NONAME + ;Storm460 @460 NONAME + SErrDisplayError @461 NONAME + SErrGetErrorStr @462 NONAME + SErrGetLastError @463 NONAME + ;SErrRegisterMessageSource @464 NONAME + SErrSetLastError @465 NONAME + ;SErrReportNamedResourceLeak @466 NONAME + ;SErrReportResourceLeak @467 NONAME + SErrSuppressErrors @468 NONAME + ;SErrRegisterHandler @469 NONAME + ;SErrUnregisterHandler @470 NONAME + ;Storm471 @471 NONAME + ;SCmdGetBool @472 NONAME + ;SCmdGetNum @473 NONAME + ;SCmdGetString @474 NONAME + ;SCmdProcess @475 NONAME + ;SCmdRegisterArgList @476 NONAME + ;SCmdRegisterArgument @477 NONAME + ;SCmdStringExists @478 NONAME + ;SCmdProcessCommandLine @479 NONAME + ;Ordinal480 @480 NONAME + ;SMemFindNextBlock @481 NONAME + ;SMemFindNextHeap @482 NONAME + ;SMemGetHeapByCaller @483 NONAME + ;SMemGetHeapByPtr @484 NONAME + ;SMemHeapAlloc @485 NONAME + ;SMemHeapCreate @486 NONAME + ;SMemHeapDestroy @487 NONAME + ;SMemHeapFree @488 NONAME + ;SMemHeapRealloc @489 NONAME + ;SMemHeapSize @490 NONAME + SMemCopy @491 NONAME + SMemFill @492 NONAME + ;SMemMove @493 NONAME + SMemZero @494 NONAME + SMemCmp @495 NONAME + ;SMem496 @496 NONAME + ;SMemDumpState @497 NONAME + ;Ordinal498 @498 NONAME + + SStrCopy @501 NONAME + SStrHash @502 NONAME + SStrPack @503 NONAME + ;SStrTokenize @504 NONAME + ;SStrPack @505 NONAME + SStrLen @506 NONAME + ;SStrDup @507 NONAME + SStrCmp @508 NONAME + SStrCmpI @509 NONAME + SStrUpper @510 NONAME + ;SMsgBreakHandlerChain @511 NONAME + ;SMsgUnregisterCommand @512 NONAME + ;SMsgUnregisterKeyDown @513 NONAME + ;SMsgUnregisterKeyUp @514 NONAME + ;SMsgUnregisterMessage @515 NONAME + ;SMsgGetDispatcher @516 NONAME + ;SMsgSetDefaultWindow @517 NONAME + ;SMsgGetDefaultWindow @518 NONAME + ;SMsg519 @519 NONAME + + ;SRgn521 @521 NONAME + + SRgn523 @523 NONAME + SRgnCreateRegion @524 NONAME + SRgnDeleteRegion @525 NONAME + + ;SRgn527 @527 NONAME + ;SRgn528i @528 NONAME + SRgn529i @529 NONAME + ;SRgn530i @530 NONAME + ;SRgn531i @531 NONAME + ;SRgn532i @532 NONAME + ;SRgn533i @533 NONAME + ;SRgn534 @534 NONAME + ;SRgn535f @535 NONAME + ;SRgn536f @536 NONAME + ;SRgn537f @537 NONAME + ;SRgn538f @538 NONAME + ;SRgn539f @539 NONAME + ;SRgn540f @540 NONAME + ;SLogClose @541 NONAME + ;SLogCreate @542 NONAME + ;SLog543 @543 NONAME + ;SLogDump @544 NONAME + ;SLogFlush @545 NONAME + ;SLogFlushAll @546 NONAME + ;SLogPend @547 NONAME + ;SLogWrite @548 NONAME + ;SLog549 @549 NONAME + ;SLogCriticalLog @550 NONAME + ;SCompCompress @551 NONAME + ;SCompDecompress @552 NONAME + ;SLogVWrite @553 NONAME + ;Ordinal554 @554 NONAME + ;Ordinal555 @555 NONAME + ;Ordinal556 @556 NONAME + ;Ordinal557 @557 NONAME + ;Ordinal558 @558 NONAME + ;Ordinal559 @559 NONAME + ;Ordinal560 @560 NONAME + ;SErrCheckDebugSymbolLibrary @561 NONAME + SErrDisplayErrorFmt @562 NONAME + ;SErrIsDisplayingError @563 NONAME + ;SErrPrepareAppFatal @564 NONAME + ;SErrSetLogTitleString @565 NONAME + ;SErrDisplayAppFatal @566 NONAME + SErrCatchUnhandledExceptions @567 NONAME + ;Storm568 @568 NONAME + ;SStrChr @569 NONAME + ;SStrChrR @570 NONAME + SStrChr @571 NONAME + SStrChrR @572 NONAME + ;SStrToDouble @573 NONAME + ;SStrToFloat @574 NONAME + ;SStrToInt @575 NONAME + ;SStrToUnsigned @576 NONAME + ;SStrToInt64 @577 NONAME + SStrVPrintf @578 NONAME + ;SStrLower @579 NONAME + ;SStrHash64 @580 NONAME + ;SStrPrintf @581 NONAME + ;SDrawSetClientRect @582 NONAME + ;SDrawGetClientRect @583 NONAME + ;SStrStrI @584 NONAME + ;SStrStrI @585 NONAME + ;SStrStr @586 NONAME + ;SStrStr @587 NONAME + ;SNet588 @588 NONAME + + ;SBigAdd @601 NONAME + ;SBigAnd @602 NONAME + ;SBigCompare @603 NONAME + ;SBigCopy @604 NONAME + ;SBigDec @605 NONAME + SBigDel @606 NONAME + ;SBigDiv @607 NONAME + ;SBigFindPrime @608 NONAME + SBigFromBinary @609 NONAME + ;SBigFromStr @610 NONAME + ;SBigFromStream @611 NONAME + ;SBigFromUnsigned @612 NONAME + ;SBigGcd @613 NONAME + ;SBigInc @614 NONAME + ;SBigInvMod @615 NONAME + ;SBigIsEven @616 NONAME + ;SBigIsOdd @617 NONAME + ;SBigIsOne @618 NONAME + ;SBigIsPrime @619 NONAME + ;SBigIsZero @620 NONAME + ;SBigMod @621 NONAME + ;SBigMul @622 NONAME + ;SBigMulMod @623 NONAME + SBigNew @624 NONAME + ;SBigNot @625 NONAME + ;SBigOr @626 NONAME + ;SBigPow @627 NONAME + SBigPowMod @628 NONAME + ;SBigRand @629 NONAME + ;SBigSet2Exp @630 NONAME + ;SBigSetOne @631 NONAME + ;SBigSetZero @632 NONAME + ;SBigShl @633 NONAME + ;SBigShr @634 NONAME + ;SBigSquare @635 NONAME + ;SBigSub @636 NONAME + ;SBigToBinaryArray @637 NONAME + SBigToBinaryBuffer @638 NONAME + ;SBigToBinaryPtr @639 NONAME + ;SBigToStrArray @640 NONAME + ;SBigToStrBuffer @641 NONAME + ;SBigToStrPtr @642 NONAME + ;SBigToStreamArray @643 NONAME + ;SBigToStreamBuffer @644 NONAME + ;SBigToStreamPtr @645 NONAME + ;SBigToUnsigned @646 NONAME + ;SBigXor @647 NONAME + + ;SUniConvertUTF16to8Len @901 NONAME + ;SUniConvertUTF16to8 @902 NONAME + ;SUniConvertUTF8to16Len @903 NONAME + ;SUniConvertUTF8to16 @904 NONAME + ;SUniS905 @905 NONAME + ;SUniS906 @906 NONAME + ;SUniFindAfterUTF8Chr @907 NONAME + ;SUniFindUTF8ChrStart @908 NONAME + ;SUniConvertUTF16To909 @909 NONAME + ;SUniConvertUTF16To910 @910 NONAME + ;SUniConvertUTF16To911 @911 NONAME + ;SUniConvert912 @912 NONAME + ;SUniConvert913 @913 NONAME + ;SUniConvert914 @914 NONAME + ;SUniConvertUTF8ToWin @915 NONAME +; END diff --git a/2020_03_31/3rdParty/Storm/Source/storm.h b/2020_03_31/3rdParty/Storm/Source/storm.h new file mode 100644 index 00000000..86f7f92d --- /dev/null +++ b/2020_03_31/3rdParty/Storm/Source/storm.h @@ -0,0 +1,1345 @@ +#pragma once + +#ifndef __BLIZZARD_STORM_HEADER +#define __BLIZZARD_STORM_HEADER + +#include +#include +#include +#include + +// Note to self: Linker error => forgot a return value in cpp + +typedef unsigned char _bool; + +// Storm API definition +#ifndef STORMAPI +#define STORMAPI __stdcall +#endif + +#ifndef __STORM_SMAX +#define __STORM_SMAX(x,y) (x < y ? y : x) +#endif + +#ifndef __STORM_SSIZEMAX +#define __STORM_SSIZEMAX(x,y) (__STORM_SMAX(sizeof(x),sizeof(y))) +#endif + +#ifndef __STORM_SMIN +#define __STORM_SMIN(x,y) (x < y ? x : y) +#endif + +#ifndef __STORM_SSIZEMIN +#define __STORM_SSIZEMIN(x,y) (__STORM_SMIN(sizeof(x),sizeof(y))) +#endif + +typedef struct _WRECT +{ + WORD left; + WORD top; + WORD right; + WORD bottom; +} WRECT, *PWRECT; + +typedef struct _WPOINT +{ + WORD x; + WORD y; +} WPOINT, *PWPOINT; + +typedef struct _WSIZE +{ + WORD cx; + WORD cy; +} WSIZE, *PWSIZE; + +struct CCritSect { + CRITICAL_SECTION m_critsect; + + CCritSect() + { + InitializeCriticalSection(&m_critsect); + } + ~CCritSect() + { + DeleteCriticalSection(&m_critsect); + } + void Enter() + { + EnterCriticalSection(&m_critsect); + } + void Leave() + { + LeaveCriticalSection(&m_critsect); + } +}; + + + +// Game states +#define GAMESTATE_PRIVATE 0x01 +#define GAMESTATE_FULL 0x02 +#define GAMESTATE_ACTIVE 0x04 +#define GAMESTATE_STARTED 0x08 +#define GAMESTATE_REPLAY 0x80 + +#ifdef __GNUC__ +extern "C" { +#endif + +BOOL STORMAPI SNetCreateGame(const char *pszGameName, const char *pszGamePassword, const char *pszGameStatString, DWORD dwGameType, void *GameTemplateData, int GameTemplateSize, int playerCount, char *creatorName, char *a11, DWORD *playerID); +BOOL STORMAPI SNetDestroy(); +BOOL STORMAPI SNetEnumProviders(int (STORMAPI *callback)(DWORD, DWORD, DWORD, DWORD), int mincaps); + +BOOL STORMAPI SNetEnumGames(int (STORMAPI *callback)(DWORD, DWORD, DWORD), int *hintnextcall); + +/* SNetDropPlayer @ 106 + * + * Drops a player from the current game. + * + * playerid: The player ID for the player to be dropped. + * flags: + * + * Returns TRUE if the function was called successfully and FALSE otherwise. + */ +BOOL +STORMAPI +SNetDropPlayer( + int playerid, + DWORD flags); + +/* SNetGetGameInfo @ 107 + * + * Retrieves specific game information from Storm, such as name, password, + * stats, mode, game template, and players. + * + * type: The type of data to retrieve. See GAMEINFO_ flags. + * dst: The destination buffer for the data. + * length: The maximum size of the destination buffer. + * byteswritten: The number of bytes written to the destination buffer. + * + * Returns TRUE if the function was called successfully and FALSE otherwise. + */ +BOOL +STORMAPI +SNetGetGameInfo( + int type, + void *dst, + size_t length, + DWORD *byteswritten); + + +#define SNGetGameInfo(typ,dst) SNetGetGameInfo(typ, &dst, sizeof(dst)) + + + +// Game info fields +#define GAMEINFO_NAME 1 +#define GAMEINFO_PASSWORD 2 +#define GAMEINFO_STATS 3 +#define GAMEINFO_MODEFLAG 4 +#define GAMEINFO_GAMETEMPLATE 5 +#define GAMEINFO_PLAYERS 6 + + +BOOL STORMAPI SNetGetNumPlayers(int *firstplayerid, int *lastplayerid, int *activeplayers); + + +typedef struct _CAPS +{ + DWORD dwSize; // Size of this structure // sizeof(CAPS) + DWORD dwUnk_0x04; // Some flags? + DWORD maxmessagesize; // Size of the packet buffer, must be beteen 128 and 512 + DWORD dwUnk_0x0C; // Unknown + DWORD dwDisplayedPlayerCount; // Displayed player count in the mode selection list + DWORD dwUnk_0x14; // some kind of timeout or timer related + DWORD dwPlayerLatency; // ... latency? + DWORD dwPlayerCount; // the number of players that can participate, must be between 1 and 20 + DWORD dwCallDelay; // the number of calls before data is sent over the network // between 2 and 8; single player is set to 1 +} CAPS, *PCAPS; + + +BOOL STORMAPI SNetGetPlayerCaps(char playerid, PCAPS playerCaps); + +/* SNetGetPlayerName @ 113 + * + * Retrieves the name of a player given their player ID. + * + * playerid: The player's ID. + * buffer: The buffer that will receive the name. + * buffersize: The maximum size of buffer. + * + * Returns TRUE if the function was called successfully and FALSE otherwise. + */ +BOOL +STORMAPI +SNetGetPlayerName( + int playerid, + char *buffer, + size_t buffersize); + +/* SNetGetProviderCaps @ 114 + * + * Retrieves network provider capacity information. + * + * providerCaps: A pointer to a CAPS structure that will receive the information. + * + * Returns TRUE if the function was called successfully and FALSE otherwise. + */ +//BOOL +//STORMAPI +//SNetGetProviderCaps( +// PCAPS providerCaps); + +/* SNetGetTurnsInTransit @ 115 + * + * Retrieves the number of turns (buffers) that have been queued + * before sending them over the network. + * + * turns: A pointer to an integer that will receive the value. + * + * Returns TRUE if the function was called successfully and FALSE otherwise. + */ +BOOL +STORMAPI +SNetGetTurnsInTransit( + DWORD *turns); + + +BOOL STORMAPI SNetInitializeDevice(int a1, int a2, int a3, int a4, int *a5); + +// Network provider structures +typedef struct _client_info +{ + DWORD dwSize; // 60 + char *pszName; + char *pszVersion; + DWORD dwProduct; + DWORD dwVerbyte; + DWORD dwUnk5; + DWORD dwMaxPlayers; + DWORD dwUnk7; + DWORD dwUnk8; + DWORD dwUnk9; + DWORD dwUnk10; // 0xFF + char *pszCdKey; + char *pszCdOwner; + DWORD dwIsShareware; + DWORD dwLangId; +} client_info; + +typedef struct _user_info +{ + DWORD dwSize; // 16 + char *pszPlayerName; + char *pszUnknown; + DWORD dwUnknown; +} user_info; + +typedef struct _battle_info +{ + DWORD dwSize; // 92 + DWORD dwUnkType; + HWND hFrameWnd; + void *pfnBattleGetResource; + void *pfnBattleGetErrorString; + void *pfnBattleMakeCreateGameDialog; + void *pfnBattleUpdateIcons; + DWORD dwUnk_07; + void *pfnBattleErrorDialog; + void *pfnBattlePlaySound; + DWORD dwUnk_10; + void *pfnBattleGetCursorLink; + DWORD dwUnk_12; + void *pfnUnk_13; + DWORD dwUnk_14; + void *pfnBattleMakeProfileDialog; + char *pszProfileStrings; + void *pfnBattleDrawProfileInfo; + void *pfnUnk_18; + DWORD dwUnk_19; + void *pfnUnk_20; + void *pfnUnk_21; + void *pfnBattleSetLeagueName; +} battle_info; + +typedef struct _module_info +{ + DWORD dwSize; // 20 + char *pszVersionString; + char *pszModuleName; + char *pszMainArchive; + char *pszPatchArchive; +} module_info; + +typedef struct _game +{ + DWORD dwIndex; + DWORD dwGameState; + DWORD dwUnk_08; + SOCKADDR saHost; + DWORD dwUnk_1C; + DWORD dwTimer; + DWORD dwUnk_24; + char szGameName[128]; + char szGameStatString[128]; + struct _game *pNext; + void *pExtra; + DWORD dwExtraBytes; + DWORD dwProduct; + DWORD dwVersion; +} game; + +typedef struct _storm_head +{ + WORD wChecksum; + WORD wLength; + WORD wSent; + WORD wReceived; + BYTE bCommandClass; + BYTE bCommandType; + BYTE bPlayerId; + BYTE bFlags; +} storm_head; + + +// Traffic flags +#define STRAFFIC_NORMAL 0 +#define STRAFFIC_VERIFY 1 +#define STRAFFIC_RESEND 2 +#define STRAFFIC_REPLY 4 + + +/* SNetInitializeProvider @ 117 + * + * Initializes a provider by storing the provider callbacks, and calling + * spiInitialize() using the parameters passed to this function. + * Note: The use of the parameters is determined by the network + * module. + * + * providerName: The provider's identifier. Example: 'TENB' (BNET). + * gameClientInfo: A pointer to a clientInfo structure containing + * information about the game client. + * userData: A pointer to a userInfo structure containing information + * about the player. + * bnCallbacks: A pointer to a battleInfo structure containing callbacks + * and other information that is specific to Battle.net. + * moduleData: A pointer to a moduleInfo structure containing the + * executable information and paths to MPQ archives. + * + * Returns TRUE if the function was called successfully and FALSE otherwise. + */ +//BOOL +//STORMAPI +//SNetInitializeProvider( +// DWORD providerName, +// client_info *gameClientInfo, +// user_info *userData, +// battle_info *bnCallbacks, +// module_info *moduleData); + + +BOOL STORMAPI SNetJoinGame(int id, char *gameName, char *gamePassword, char *playerName, char *userStats, int *playerid); + +/* SNetLeaveGame @ 119 + * + * Notifies Storm that the player has left the game. Storm will + * notify all connected peers through the network provider. + * + * type: The leave type. It doesn't appear to be important, no documentation available. + * + * Returns TRUE if the function was called successfully and FALSE otherwise. + */ +BOOL +STORMAPI +SNetLeaveGame( + int type); + +BOOL STORMAPI SNetPerformUpgrade(DWORD *upgradestatus); +BOOL STORMAPI SNetReceiveMessage(DWORD *senderplayerid, char **data, DWORD *databytes); +BOOL STORMAPI SNetReceiveTurns(int a1, int arraysize, void *arraydata, void *arraydatabytes, void *arrayplayerstatus); + +// Values for arrayplayerstatus +#define SNET_PS_OK 0 +#define SNET_PS_WAITING 2 +#define SNET_PS_NOTRESPONDING 3 +#define SNET_PS_UNKNOWN default + + +// Event structure +typedef struct _s_evt +{ + DWORD dwFlags; + int dwPlayerId; + void *pData; + DWORD dwSize; +} S_EVT, *PS_EVT; + + +// @TODO: "type" is unknown. +//HANDLE STORMAPI SNetRegisterEventHandler(int type, void (STORMAPI *sEvent)(PS_EVT)); + +int STORMAPI SNetSelectGame(int a1, int a2, int a3, int a4, int a5, int *playerid); + +/* SNetSendMessage @ 127 + * + * Sends a message to a player given their player ID. Network message + * is sent using class 01 and is retrieved by the other client using + * SNetReceiveMessage(). + * + * playerID: The player index of the player to receive the data. + * Conversely, this field can be one of the following constants: + * SNPLAYER_ALL | Sends the message to all players, including oneself. + * SNPLAYER_OTHERS | Sends the message to all players, except for oneself. + * data: A pointer to the data. + * databytes: The amount of bytes that the data pointer contains. + * + * Returns TRUE if the function was called successfully and FALSE otherwise. + */ +BOOL +STORMAPI +SNetSendMessage( + int playerID, + void *data, + size_t databytes); + + +// Macro values to target specific players +#define SNPLAYER_ALL -1 +#define SNPLAYER_OTHERS -2 + + +/* SNetSendTurn @ 128 + * + * Sends a turn (data packet) to all players in the game. Network data + * is sent using class 02 and is retrieved by the other client using + * SNetReceiveTurns(). + * + * data: A pointer to the data. + * databytes: The amount of bytes that the data pointer contains. + * + * Returns TRUE if the function was called successfully and FALSE otherwise. + */ +BOOL +STORMAPI +SNetSendTurn( + void *data, + size_t databytes); + +/* SNetSetGameMode @ 130 + * + * Set's the game's mode flags, notifying the network + * provider that the state of the game has changed. + * For example: notifies Battle.net when the game is + * full. + * + * You should first call SNetGetGameInfo to retrieve + * the existing mode flags. + * + * modeFlags: The new flags for the game mode. + * GAMESTATE_PRIVATE | The game is passworded. + * GAMESTATE_FULL | The game is full. + * GAMESTATE_ACTIVE | The game is available. + * GAMESTATE_STARTED | The game is in progress. + * GAMESTATE_REPLAY | The game is a replay. + * makePublic: Used to make the game a public game, removing the GAMESTATE_PRIVATE flag. + * + * Returns TRUE if the function was called successfully and FALSE otherwise. + */ +BOOL +STORMAPI +SNetSetGameMode( + DWORD modeFlags, + _bool makePublic); + +#define SNMakeGamePublic() SNetSetGameMode( (DWORD mode, SNetGetGameInfo(GAMEINFO_MODEFLAGS, &mode, 4), mode), true) + +BOOL STORMAPI SNetEnumGamesEx(int a1, int a2, int (__fastcall *callback)(DWORD, DWORD, DWORD), int *hintnextcall); +BOOL STORMAPI SNetSendServerChatCommand(const char *command); + +BOOL STORMAPI SNetDisconnectAll(DWORD flags); +BOOL STORMAPI SNetCreateLadderGame(const char *pszGameName, const char *pszGamePassword, const char *pszGameStatString, DWORD dwGameType, DWORD dwGameLadderType, DWORD dwGameModeFlags, char *GameTemplateData, int GameTemplateSize, int playerCount, char *creatorName, char *a11, int *playerID); + +#define SNET_GAME_RESULT_WIN 1 +#define SNET_GAME_RESULT_LOSS 2 +#define SNET_GAME_RESULT_DRAW 3 +#define SNET_GAME_RESULT_DISCONNECT 4 + +BOOL STORMAPI SNetReportGameResult(unsigned a1, int size, int *results, const char* headerInfo, const char* detailInfo); + +int STORMAPI SNetSendLeagueCommand(char *cmd, char *callback); +int STORMAPI SNetSendReplayPath(int a1, int a2, char *replayPath); +int STORMAPI SNetGetLeagueName(int leagueID); +BOOL STORMAPI SNetGetPlayerNames(char **names); +int STORMAPI SNetLeagueLogout(char *bnetName); +int STORMAPI SNetGetLeaguePlayerName(char *curPlayerLeageName, size_t nameSize); + +HGDIOBJ STORMAPI SDlgDefDialogProc(HWND hDlg, signed int DlgType, HDC textLabel, HWND hWnd); + +HANDLE STORMAPI SDlgDialogBoxIndirectParam(HMODULE hModule, LPCSTR lpName, HWND hWndParent, LPVOID lpParam, LPARAM lParam); + +BOOL STORMAPI SDlgEndDialog(HWND hDlg, HANDLE nResult); + +BOOL STORMAPI SDlgSetControlBitmaps(HWND parentwindow, int *id, int a3, char *buffer2, char *buffer, int flags, int mask); + +/* +// lpCursorName can only be IDC_ARROW +BOOL STORMAPI SDlgSetSystemCursor(void *lpSrcBuffer, void *p_a2, LPSIZE lpSize, LPCSTR lpCursorName); +*/ + +BOOL STORMAPI SDlgBltToWindowI(HWND hWnd, HRGN a2, char *a3, int a4, void *buffer, RECT *rct, SIZE *size, int a8, int a9, DWORD rop); +BOOL STORMAPI SDlgBltToWindowE(HWND hWnd, HRGN a2, char *a3, int a4, void *buffer, RECT *rct, SIZE *size, int a8, int a9, DWORD rop); +BOOL STORMAPI SDlgSetBitmapE(HWND hWnd, int a2, char *src, int mask1, int flags, int a6, int a7, int width, int a9, int mask2); + +int STORMAPI Ordinal224(int a1); + +BOOL STORMAPI SFileCloseArchive(HANDLE hArchive); +BOOL STORMAPI SFileCloseFile(HANDLE hFile); + +BOOL STORMAPI SFileDdaBeginEx(HANDLE directsound, DWORD flags, DWORD mask, unsigned __int32 lDistanceToMove, signed __int32 volume, signed int a6, int a7); +BOOL STORMAPI SFileDdaDestroy(); +BOOL STORMAPI SFileDdaEnd(HANDLE directsound); +BOOL STORMAPI SFileDdaGetPos(HANDLE directsound, DWORD *a2, DWORD *a3); + +BOOL STORMAPI SFileDdaInitialize(HANDLE directsound); +BOOL STORMAPI SFileDdaSetVolume(HANDLE directsound, signed int bigvolume, signed int volume); +BOOL STORMAPI SFileDestroy(); + +BOOL STORMAPI SFileGetFileArchive(HANDLE hFile, HANDLE archive); +LONG STORMAPI SFileGetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh); +BOOL STORMAPI SFileOpenArchive(const char *szMpqName, DWORD dwPriority, DWORD dwFlags, HANDLE *phMpq); + +// values for dwFlags +enum MPQFlags +{ + MPQ_NO_LISTFILE = 0x0010, + MPQ_NO_ATTRIBUTES = 0x0020, + MPQ_FORCE_V1 = 0x0040, + MPQ_CHECK_SECTOR_CRC = 0x0080 +}; + + +BOOL STORMAPI SFileOpenFile(const char *filename, HANDLE *phFile); +BOOL STORMAPI SFileOpenFileEx(HANDLE hMpq, const char *szFileName, DWORD dwSearchScope, HANDLE *phFile); + +// values for dwSearchScope +enum SFileFlags +{ + SFILE_FROM_MPQ = 0x00000000, + SFILE_FROM_ABSOLUTE = 0x00000001, + SFILE_FROM_RELATIVE = 0x00000002, + SFILE_FROM_DISK = 0x00000004 +}; + +BOOL STORMAPI SFileReadFile(HANDLE hFile, void *buffer, DWORD nNumberOfBytesToRead, DWORD *read, LONG lpDistanceToMoveHigh); + +void STORMAPI SFileSetLocale(LCID lcLocale); + +// mode: 0 - Silent (callback is NULL) +// 1 - Application Defined +// 2 - Handled by storm (callback is NULL) +// BOOL STORMAPI callback(const char *pszFilename, DWORD dwErrCode, DWORD dwErrCount) +BOOL STORMAPI SFileSetIoErrorMode(DWORD mode, BOOL (STORMAPI *callback)(const char*,DWORD,DWORD) ); + +BOOL STORMAPI SFileGetArchiveName(HANDLE hArchive, char *name, int length); +BOOL STORMAPI SFileGetFileName(HANDLE hFile, char *buffer, int length); + +BOOL STORMAPI SFileLoadFile(char *filename, void *buffer, int buffersize, int a4, int a5); +BOOL STORMAPI SFileUnloadFile(HANDLE hFile); +BOOL STORMAPI SFileLoadFileEx(void *hArchive, char *filename, int a3, int a4, int a5, DWORD searchScope, struct _OVERLAPPED *lpOverlapped); + +// Options are DWORD except for #6 +// 1: [TRUE|FALSE] - If true, reports resource leaks (SErrReportResourceLeak/SErrReportNamedResourceLeak) to the attached debugger instead of a message box. +// 2: This option is unused. +// 3: [TRUE|FALSE] - If true, reports general memory leaks to the attached debugger instead of a message box. +// 4: This option is unused. +// 5: [TRUE|FALSE] - If true, reports log messages and log dumps to the attached debugger. +// 6: { DWORD blocks_allocated; DWORD blocks_freed; } Used to determine the amount of memory/heap blocks that have been allocated and freed by storm. +// Can also be used for custom allocations outside of storm. +// +//BOOL STORMAPI StormGetOption(int type, void *pValue, size_t *pSize); +//BOOL STORMAPI StormSetOption(int type, void *pValue, size_t size); + +BOOL STORMAPI SBltROP3(void *lpDstBuffer, void *lpSrcBuffer, int srcDrawWidth, int srcDrawHeight, int dstWidth, int srcWidth, int a7, DWORD rop); +BOOL STORMAPI SBltROP3Clipped(void *lpDstBuffer, RECT *lpDstRect, POINT *lpDstPt, int a4, void *lpSrcBuffer, RECT *lpSrcRect, POINT *lpSrcPt, int a8, int a9, DWORD rop); +BOOL STORMAPI SBltROP3Tiled(void *lpDstBuffer, RECT *lpDstRect, POINT *lpDstPt, int a4, void *lpSrcBuffer, RECT *lpSrcRect, POINT *lpSrcPt, int a8, int a9, DWORD rop); + +#define SBMP_DEFAULT 0 +#define SBMP_BMP 1 +#define SBMP_PCX 2 +#define SBMP_TGA 3 + + +/* SBmpDecodeImage @ 321 + * + * Decodes an image that has already been loaded into a buffer. + * + * dwImgType: Optional, the image type. See SBMP_ macros. + * pSrcBuffer: A pointer to the source buffer. + * dwSrcBuffersize: The size of the data in the source buffer. + * pPalette: An optional buffer that receives the image palette. + * pDstBuffer: A buffer that receives the image data. + * dwDstBuffersize: The size of the specified image buffer. If the size of the + * destination buffer is 0, then the destination buffer is not used. + * pdwWidth: An optional variable that receives the image width. + * pdwHeight: An optional variable that receives the image height. + * pdwBpp: An optional variable that receives the image bits per pixel. + * + * Returns TRUE if the image was supported and decoded correctly, FALSE otherwise. + */ +BOOL +STORMAPI +SBmpDecodeImage( + DWORD dwImgType, + void *pSrcBuffer, + DWORD dwSrcBuffersize, + PALETTEENTRY *pPalette, + void *pDstBuffer, + DWORD dwDstBuffersize, + DWORD *pdwWidth, + DWORD *pdwHeight, + DWORD *pdwBpp); + + +/* SBmpLoadImage @ 323 + * + * Load an image from an available archive into a buffer. + * + * pszFileName: The name of the graphic in an active archive. + * pPalette: An optional buffer that receives the image palette. + * pBuffer: A buffer that receives the image data. + * dwBuffersize: The size of the specified image buffer. + * pdwWidth: An optional variable that receives the image width. + * pdwHeight: An optional variable that receives the image height. + * pdwBpp: An optional variable that receives the image bits per pixel. + * + * Returns TRUE if the image was supported and loaded correctly, FALSE otherwise. + */ +BOOL +STORMAPI +SBmpLoadImage( + const char *pszFileName, + PALETTEENTRY *pPalette, + void *pBuffer, + DWORD dwBuffersize, + DWORD *pdwWidth, + DWORD *pdwHeight, + DWORD *pdwBpp); + +/* SBmpSaveImage @ 324 + * + * Save an image from a buffer to a file. The image format is determined + * from the filename and is either .gif, .pcx, .tga, or .bmp being the default. + * + * pszFileName: The name of the file to create. + * pPalette: A pointer to a palette array containing 256 entries. + * pBuffer: A buffer containing the image data. + * pdwWidth: The width of the image. + * pdwHeight: The height of the image. + * pdwBpp: The bits per pixel. + * + * Returns TRUE if the image was saved correctly, FALSE otherwise. + */ +BOOL +STORMAPI +SBmpSaveImage( + const char *pszFileName, + PALETTEENTRY *pPalette, + void *pBuffer, + DWORD dwWidth, + DWORD dwHeight, + DWORD dwBpp); + + +HANDLE STORMAPI SBmpAllocLoadImage(const char *fileName, PALETTEENTRY *palette, void **buffer, int *width, int *height, int unused6, int unused7, void *(STORMAPI *allocFunction)(DWORD)); + +BOOL STORMAPI SCodeCompile(char *directives1, char *directives2, char *loopstring, unsigned int maxiterations, unsigned int flags, HANDLE handle); +BOOL STORMAPI SCodeDelete(HANDLE handle); + +int STORMAPI SCodeExecute(HANDLE handle, int a2); + +BOOL STORMAPI SDrawAutoInitialize(HINSTANCE hInst, LPCSTR lpClassName, LPCSTR lpWindowName, WNDPROC pfnWndProc, int nMode, int nWidth, int nHeight, int nBits); + + +/* SDrawCaptureScreen @ 342 + * + * Saves a screenshot from the primary surface being handled by Storm. + * + * pszOutput: The name of the output file. The save format is automatically set by the extension. + * The extensions supported are .gif, .pcx, .tga, and .bmp. It will write a bitmap by default. + * + * Returns TRUE if successful and FALSE otherwise. + */ +BOOL +STORMAPI +SDrawCaptureScreen( + const char *pszOutput); + + +/* SDrawGetFrameWindow @ 346 + * + * Retrieves the window handle that was specified in + * SDrawManualInitialize or created in SDrawAutoInitialize. + * + * sdraw_framewindow: Optional variable that receives the returned handle. + * + * Returns the handle of the window. + */ +HWND +STORMAPI +SDrawGetFrameWindow( + HWND *sdraw_framewindow); + + +/* SDrawGetObjects @ 347 + * + * Retrieves the object information that was initialized using + * SDrawManualInitialize or SDrawAutoInitialize. + * + * ddInterface: The DirectDraw interface. + * primarySurface: The primary DirectDraw surface. + * surface2: A second unknown surface. + * surface3: A third unknown surface. + * backSurface: The back DirectDraw surface. + * ddPalette: The DirectDraw palette. + * hPalette: The palette handle. + * + * Returns FALSE if the direct draw interface has not been initialized. + */ +BOOL +STORMAPI +SDrawGetObjects( + LPDIRECTDRAW *ddInterface, + LPDIRECTDRAWSURFACE *primarySurface, + LPDIRECTDRAWSURFACE *surface2, + LPDIRECTDRAWSURFACE *surface3, + LPDIRECTDRAWSURFACE *backSurface, + LPDIRECTDRAWPALETTE *ddPalette, + HPALETTE *hPalette); + + +/* SDrawGetScreenSize @ 348 + * + * Obtains information for the current screen resolution. + * + * pdwWidth: Optional variable that receives the screen width. + * pdwHeight: Optional variable that receives the screen height. + * pdwBpp: Optional variable that receives the bits per pixel. + * + * Returns FALSE if no variables were specified. + */ +BOOL +STORMAPI +SDrawGetScreenSize( + DWORD *pdwWidth, + DWORD *pdwHeight, + DWORD *pdwBpp); + + +// undefined +BOOL STORMAPI SDrawLockSurface(int surfacenumber, RECT *lpDestRect, void **lplpSurface, int *lpPitch, int arg_unused); + + +/* SDrawManualInitialize @ 351 + * + * Sets the DirectDraw variables to be referenced in Storm. + * + * hWnd: The handle of the DirectDraw window. + * ddInterface: The DirectDraw interface. + * primarySurface: The first and primary surface. + * surface2: A second surface. Behaviour not completely known. + * surface3: A third surface. Behaviour not completely known. + * backSurface: The fourth and final surface. The back surface. + * ddPalette: The DirectDraw palette if the application requires it. + * hPalette: The palette handle that belongs to the window. + * If this is NULL and ddPalette is specified, then it + * will be created automatically. A palette can be created + * using the CreatePalette WinAPI function. + * + * Returns FALSE if no variables were specified. + */ +BOOL +STORMAPI +SDrawManualInitialize( + HWND hWnd, + LPDIRECTDRAW ddInterface, + LPDIRECTDRAWSURFACE primarySurface, + LPDIRECTDRAWSURFACE surface2, + LPDIRECTDRAWSURFACE surface3, + LPDIRECTDRAWSURFACE backSurface, + LPDIRECTDRAWPALETTE ddPalette, + HPALETTE hPalette); + + +/* SDrawPostClose @ 353 + * + * Posts a WM_QUIT message to the active drawing window specified + * in SDrawManualInitialize or created in SDrawAutoInitialize. + * + * Returns TRUE if successful and FALSE otherwise. + */ +BOOL +STORMAPI +SDrawPostClose(); + + +// undefined +//BOOL STORMAPI SDrawRealizePalette(); + +BOOL STORMAPI SDrawUnlockSurface(int surfacenumber, void *lpSurface, int a3, RECT *lpRect); +BOOL STORMAPI SDrawUpdatePalette(unsigned int firstentry, unsigned int numentries, PALETTEENTRY *pPalEntries, int a4); + +BOOL STORMAPI SEvtDispatch(DWORD dwMessageID, DWORD dwFlags, int type, PS_EVT pEvent); + +BOOL STORMAPI SGdiDeleteObject(HANDLE handle); + +BOOL STORMAPI SGdiExtTextOut(int a1, int a2, int a3, int a4, unsigned int a8, signed int a6, signed int a7, const char *pszString, unsigned int arg20); +BOOL STORMAPI SGdiImportFont(HGDIOBJ handle, int windowsfont); + +BOOL STORMAPI SGdiSelectObject(int handle); +BOOL STORMAPI SGdiSetPitch(int pitch); + +BOOL STORMAPI Ordinal393(char *pszString, int, int); + + +/* SMemAlloc @ 401 + * + * Allocates a block of memory. This block is different + * from the standard malloc by including a header containing + * information about the block. + * + * amount: The amount of memory to allocate, in bytes. + * logfilename: The name of the file or object that this call belongs to. + * logline: The line in the file or one of the SLOG_ macros. + * defaultValue: The default value of a byte in the allocated memory. + * + * Returns a pointer to the allocated memory. This pointer does NOT include + * the additional storm header. + */ +void* +STORMAPI +SMemAlloc( + size_t amount, + char *logfilename, + int logline, + char defaultValue); + +#define SMAlloc(amount) SMemAlloc((amount), __FILE__, __LINE__) + + +/* SMemFree @ 403 + * + * Frees a block of memory that was created using SMemAlloc, + * includes the log file and line for debugging purposes. + * + * location: The memory location to be freed. + * logfilename: The name of the file or object that this call belongs to. + * logline: The line in the file or one of the SLOG_ macros. + * defaultValue: + * + * Returns TRUE if the call was successful and FALSE otherwise. + */ +BOOL +STORMAPI +SMemFree( + void *location, + char *logfilename, + int logline, + char defaultValue); + +#define SMFree(loc) SMemFree((loc), __FILE__, __LINE__) + + +/* SMemReAlloc @ 405 + * + * Reallocates a block of memory that was created using SMemAlloc, + * includes the log file and line for debugging purposes. + * + * location: The memory location to be re-allocated. If this parameter + * is NULL, then SMemAlloc is called with the remaining parameters. + * amount: The amount of memory to re-allocate. + * logfilename: The name of the file or object that this call belongs to. + * logline: The line in the file or one of the SLOG_ macros. + * defaultValue: + * + * Returns a pointer to the re-allocated memory. This pointer does NOT include + * the additional storm header. + */ +void* +STORMAPI +SMemReAlloc( + void *location, + size_t amount, + char *logfilename, + int logline, + char defaultValue); + +#define SMReAlloc(loc,s) SMemReAlloc((loc),(s), __FILE__, __LINE__) + +// Can be provided instead of logline/__LINE__ parameter to indicate different errors. +#define SLOG_EXPRESSION 0 +#define SLOG_FUNCTION -1 +#define SLOG_OBJECT -2 +#define SLOG_HANDLE -3 +#define SLOG_FILE -4 +#define SLOG_EXCEPTION -5 + + +BOOL STORMAPI SRegLoadData(const char *keyname, const char *valuename, int size, LPBYTE lpData, BYTE flags, LPDWORD lpcbData); +BOOL STORMAPI SRegLoadString(const char *keyname, const char *valuename, BYTE flags, char *buffer, size_t buffersize); +BOOL STORMAPI SRegLoadValue(const char *keyname, const char *valuename, BYTE flags, DWORD *value); +BOOL STORMAPI SRegSaveData(const char *keyname, const char *valuename, int size, BYTE *lpData, DWORD cbData); +BOOL STORMAPI SRegSaveString(const char *keyname, const char *valuename, BYTE flags, char *string); +BOOL STORMAPI SRegSaveValue(const char *keyname, const char *valuename, BYTE flags, DWORD result); + +BOOL STORMAPI SRegDeleteValue(const char *keyname, const char *valuename, BYTE flags); + +// Flags for SReg functions + +// Default behaviour checks both HKEY_LOCAL_MACHINE and HKEY_CURRENT_USER +// relative to the "Software\\Blizzard Entertainment\\" key in both hives. +#define SREG_NONE 0x00000000 +#define SREG_EXCLUDE_LOCAL_MACHINE 0x00000001 // excludes checking the HKEY_LOCAL_MACHINE hive +#define SREG_BATTLE_NET 0x00000002 // sets the relative key to "Software\\Battle.net\\" instead +#define SREG_EXCLUDE_CURRENT_USER 0x00000004 // excludes checking the HKEY_CURRENT_USER hive +#define SREG_ABSOLUTE 0x00000010 // specifies that the key is not a relative key + +BOOL STORMAPI STransBlt(void *lpSurface, int x, int y, int width, HANDLE hTrans); +BOOL STORMAPI STransBltUsingMask(void *lpDest, void *lpSource, int pitch, int width, HANDLE hTrans); + +BOOL STORMAPI STransDelete(HANDLE hTrans); + +BOOL STORMAPI STransDuplicate(HANDLE hTransSource, HANDLE hTransDest); +BOOL STORMAPI STransIntersectDirtyArray(HANDLE hTrans, char * dirtyarraymask, unsigned flags, HANDLE * phTransResult); +BOOL STORMAPI STransInvertMask(HANDLE hTrans, HANDLE * phTransResult); + +BOOL STORMAPI STransSetDirtyArrayInfo(int width, int height, int depth, int bits); + +BOOL STORMAPI STransPointInMask(HANDLE hTrans, int x, int y); // Name is a pure guess +BOOL STORMAPI STransCombineMasks(HANDLE hTransA, HANDLE hTransB, int left, int top, int flags, HANDLE * phTransResult); + +BOOL STORMAPI STransCreateE(void *pBuffer, int width, int height, int bpp, int a5, int bufferSize, HANDLE *phTransOut); +BOOL STORMAPI STransCreateI(void *pBuffer, int width, int height, int bpp, int a5, int bufferSize, HANDLE *phTransOut); + +BOOL STORMAPI SVidDestroy(); +BOOL STORMAPI SVidGetSize(HANDLE video, int width, int height, int zero); +BOOL STORMAPI SVidInitialize(HANDLE video); +BOOL STORMAPI SVidPlayBegin(const char *filename, int arg4, int a3, int a4, int a5, int a6, HANDLE* video); + +BOOL STORMAPI SVidPlayContinueSingle(HANDLE video, int a2, int a3); +BOOL STORMAPI SVidPlayEnd(HANDLE video); + +/* SErrDisplayError @ 461 + * + * Displays a formatted error message. The message is detailed and flexible for many applications. + * The message will be different if there is a debugger attached. Will typically terminate the application + * unless the option to continue is given. + * + * dwErrMessage: The error code. See SErrGetLastError and GetLastError. + * logfilename: The name of the file or object that this call belongs to. + * logline: The line in the file or one of the SLOG_ macros. + * message: A message or expression with additional information. + * allowOption: If TRUE, allows the user the option to continue execution, otherwise the program will terminate. + * exitCode: The exit code used for program termination. + * + * Returns TRUE if the user chose to continue execution, FALSE otherwise. + */ +BOOL +STORMAPI +SErrDisplayError( + DWORD dwErrMsg, + const char *logfilename, + int logline, + const char *message, + BOOL allowOption, + int exitCode); + +#define SAssert(x) { if ( !(x) ) SErrDisplayError(STORM_ERROR_ASSERTION, __FILE__, __LINE__, #x) } + +#define SEDisplayError(err) SErrDisplayError(e, __FILE__, __LINE__) + +/* SErrGetErrorStr @ 462 + * + * Retrieves a string that describes the specified error code for + * the system, Storm, DirectDraw, or DirectSound. + * + * dwErrCode: The error code to look up. + * buffer: The destination buffer to receive the string. + * bufferchars: The size of the destination buffer. + * + * Returns TRUE if the call was successful and FALSE otherwise. + */ +BOOL +STORMAPI +SErrGetErrorStr( + DWORD dwErrCode, + char *buffer, + size_t bufferchars); + +#define SEGetErrorStr(e,b) SErrGetErrorStr(e,b,sizeof(b)) + + +/* SErrGetLastError @ 463 + * + * Retrieves the last error that was specifically + * set for the Storm library. + * + * Returns the last error set within the Storm library. + */ +DWORD +STORMAPI +SErrGetLastError(); + + +// Registers a module as a message source for SErrGetErrorStr, always returns TRUE +// groupID is a group in a MessageTable entry for example in STORM_ERROR_BAD_ARGUMENT 0x85100065, 0x510 is the group. +// BOOL STORMAPI SErrRegisterMessageSource(WORD groupID, HMODULE hSourceModule, int a3) + + +/* SErrSetLastError @ 465 + * + * Sets the last error for the Storm library and the Kernel32 library. + * + * dwErrCode: The error code that will be set. + */ +void +STORMAPI +SErrSetLastError( + DWORD dwErrCode); + +// +// void STORMAPI SErrReportNamedResourceLeak(const char *pszMsg, const char *pszSubMsg) +// void STORMAPI SErrReportResourceLeak(const char *pszMsg) + +void STORMAPI SErrSuppressErrors(BOOL suppressErrors); + +// Values for dwErrCode +#define STORM_ERROR_ASSERTION 0x85100000 +#define STORM_ERROR_BAD_ARGUMENT 0x85100065 +#define STORM_ERROR_GAME_ALREADY_STARTED 0x85100066 +#define STORM_ERROR_GAME_FULL 0x85100067 +#define STORM_ERROR_GAME_NOT_FOUND 0x85100068 +#define STORM_ERROR_GAME_TERMINATED 0x85100069 +#define STORM_ERROR_INVALID_PLAYER 0x8510006a +#define STORM_ERROR_NO_MESSAGES_WAITING 0x8510006b +#define STORM_ERROR_NOT_ARCHIVE 0x8510006c +#define STORM_ERROR_NOT_ENOUGH_ARGUMENTS 0x8510006d +#define STORM_ERROR_NOT_IMPLEMENTED 0x8510006e +#define STORM_ERROR_NOT_IN_ARCHIVE 0x8510006f +#define STORM_ERROR_NOT_IN_GAME 0x85100070 +#define STORM_ERROR_NOT_INITIALIZED 0x85100071 +#define STORM_ERROR_NOT_PLAYING 0x85100072 +#define STORM_ERROR_NOT_REGISTERED 0x85100073 +#define STORM_ERROR_REQUIRES_CODEC1 0x85100074 +#define STORM_ERROR_REQUIRES_CODEC2 0x85100075 +#define STORM_ERROR_REQUIRES_CODEC3 0x85100076 +#define STORM_ERROR_REQUIRES_UPGRADE 0x85100077 +#define STORM_ERROR_STILL_ACTIVE 0x85100078 +#define STORM_ERROR_VERSION_MISMATCH 0x85100079 +#define STORM_ERROR_MEM_NOT_ALLOCATED 0x8510007a +#define STORM_ERROR_MEM_CORRUPTED 0x8510007b +#define STORM_ERROR_MEM_INVALID 0x8510007c +#define STORM_ERROR_MEM_MANAGER_NOT_INITIALIZED 0x8510007d +#define STORM_ERROR_MEM_NOT_FREED 0x8510007e +#define STORM_ERROR_RESOURCES_NOT_RELEASED 0x8510007f +#define STORM_ERROR_OUT_OF_BOUNDS 0x85100080 +#define STORM_ERROR_NULL_POINTER 0x85100081 +#define STORM_ERROR_CDKEY_MISMATCH 0x85100082 +#define STORM_ERROR_FILE_CORRUPTED 0x85100083 +#define STORM_ERROR_FATAL 0x85100084 +#define STORM_ERROR_GAMETYPE_UNAVAILABLE 0x85100085 + + +/* SMemCopy @ 491 + * + * Copies a block of memory from source to destination. + * This function immediately calls memcpy. See online documentation + * of memcpy for more details. + * + * dest: The destination buffer. + * source: The source buffer. + * size: The number of bytes to copy. + */ +void +STORMAPI +SMemCopy( + void *dest, + const void *source, + size_t size); + +#define SMCopy(d,s) ( SMemCopy(d, s, __STORM_SSIZEMIN(s,d)) ) + +/* SMemFill @ 492 + * + * Fills a block of memory with the specified character. + * This function immediately calls memset. See online documentation + * of memset for more details. + * + * dest: The destination buffer. + * source: The size of the destination buffer. + * size: The format to use. + */ +void +STORMAPI +SMemFill( + void *location, + size_t length, + char fillWith); + +#define SMFill(l,f) (SMemFill(l, sizeof(l), f)) + +/* SMemZero @ 494 + * + * Fills a block of memory with the integer 0x00 (Zero). + * + * location: The location to write at. + * length: The amount of bytes to write. + */ +void +STORMAPI +SMemZero( + void *location, + size_t length); + +#define SMZero(l) (SMemZero(l, sizeof(l))) + + +int STORMAPI SMemCmp(void *location1, void *location2, DWORD size); + +#define SMCmp(l,x) ( SMemCmp(l, x, __STORM_SSIZEMIN(x,l)) ) + +/* SStrCopy @ 501 + * + * Copies a string from src to dest (including NULL terminator) + * until the max_length is reached. + * + * dest: The destination array. + * src: The source array. + * max_length: The maximum length of dest. + * + * Returns the number of characters copied. + */ +int +STORMAPI +SStrCopy( + char *dest, + const char *src, + int max_length); + +#define SSCopy(d,s) (SStrCopy(d, s, sizeof(d))) + +#define STORM_HASH_ABSOLUTE 1 + +/* SStrHash @ 502 + * + * Creates a simple hash for the string. This function + * should NOT be used for sensitive information. + * + * string: The input string. + * flags: If STORM_HASH_ABSOLUTE is set then this + function uses the absolute string, otherwise + it will convert backslashes to forward + slashes and some other processing. + * seed: The hash seed. If this value is 0 then the + * default value 0x7FED7FED will be used. + * + * Returns the 32-bit hash of the string. + */ +DWORD +STORMAPI +SStrHash( + const char *string, + DWORD flags, + DWORD Seed); + +int STORMAPI SStrPack(char *dest, const char *src, DWORD max_length); + +/* SStrLen @ 506 + * + * Retrieves the length of a string. + * + * string: The input string of which to obtain a + * length for. + * + * Returns the length of the string. + */ +int +STORMAPI +SStrLen( + const char *string); + +/* SStrCmp @ 508 + * + * Compares two strings case sensitive. + * + * string1: The first string. + * string2: The second string. + * size: The maximum amount of characters to compare. + * + * Returns 0 if strings are equal. See strcmp documentation for more details. + */ +int +STORMAPI +SStrCmp( + const char *string1, + const char *string2, + size_t size); + +#define SSCmp(s,x) ( SStrCmp(s,x,__STORM_SSIZEMIN(s,x)) ) + +/* SStrCmpI @ 509 + * + * Compares two strings case insensitive. + * + * string1: The first string. + * string2: The second string. + * size: The maximum amount of characters to compare. + * + * Returns 0 if strings are equal. See strcmpi documentation for more details. + */ +int +STORMAPI +SStrCmpI( + const char *string1, + const char *string2, + size_t size); + +#define SSCmpI(s,x) ( SStrCmpI(s,x,__STORM_SSIZEMIN(s,x)) ) + +/* SStrUpper @ 510 + * + * Converts all lower-case alpha characters of a string to upper-case. + * + * string: The string to convert. + * + * Returns the same pointer given in the input. + */ +char* +STORMAPI +SStrUpper( + char* string); + +void STORMAPI SRgn523(HANDLE hRgn, RECT *pRect, int a3, int a4); +void STORMAPI SRgnCreateRegion(HANDLE *hRgn, int a2); +void STORMAPI SRgnDeleteRegion(HANDLE hRgn); + +void STORMAPI SRgn529i(int handle, int a2, int a3); + + +/* SErrDisplayErrorFmt @ 562 + * + * Displays a formatted error message. The message is detailed and flexible for many applications. + * The message will be different if there is a debugger attached. Will typically terminate the application + * unless the option to continue is given. + * + * dwErrMessage: The error code. See SErrGetLastError and GetLastError. + * logfilename: The name of the file or object that this call belongs to. + * logline: The line in the file or one of the SLOG_ macros. + * allowOption: If TRUE, allows the user the option to continue execution, otherwise the program will terminate. + * exitCode: The exit code used for program termination. + * format: Additional message formatting. See printf. + * + * Returns TRUE if the user chose to continue execution, FALSE otherwise. + */ +BOOL __cdecl +SErrDisplayErrorFmt( + DWORD dwErrMsg, + const char *logfilename, + int logline, + BOOL allowOption, + int exitCode, + const char *format, + ...); + +//#define SEDisplayErrorFmt(err,...) SErrDisplayErrorFmt(err, __FILE__, __LINE__, FALSE, 1, __VA_ARGS__) + +/* SErrCatchUnhandledExceptions @ 567 + * + * Registers a top-level exception filter managed entirely by Storm. + * The registered filter will display formatted exception information by calling SErrDisplayError. + */ +void +STORMAPI +SErrCatchUnhandledExceptions(); + + +/* SStrChr @ 571 + * + * Searches a string for the given character. See + * strchr documentation for more details. + * + * string: The string to search. + * c: The character to search for. + * + * Returns a pointer to the first occurance of the character. + */ +char* +STORMAPI +SStrChr( + const char *string, + char c); + + +char *STORMAPI SStrChrR(const char *string, char c); + + +/* SStrVPrintf @ 578 + * + * Prints a formatted string to a destination buffer. + * This function calls vsnprintf with some extra error handling. + * See online documentation of vsnprintf for more details. + * + * dest: The destination buffer. + * size: The size of the destination buffer. + * format: The format to use. + * + * Returns the number of characters written. + */ +size_t __cdecl +SStrVPrintf( + char *dest, + size_t size, + const char *format, ...); + + +int STORMAPI SBigDel(void *buffer); + +int STORMAPI SBigFromBinary(void *buffer, const void *str, size_t size); + +int STORMAPI SBigNew(void **buffer); + +int STORMAPI SBigPowMod(void *buffer1, void *buffer2, int a3, int a4); + +int STORMAPI SBigToBinaryBuffer(void *buffer, int length, int a3, int a4); + +void __stdcall SDrawMessageBox(char *,char *,int); +void __cdecl SDrawDestroy(void); +_bool __cdecl StormDestroy(void); +_bool __stdcall SFileSetBasePath(char *); +void __cdecl SDrawRealizePalette(void); +BOOL __stdcall SVidPlayContinue(void); +BOOL __stdcall SNetGetOwnerTurnsWaiting(DWORD *); +BOOL __stdcall SNetUnregisterEventHandler(int,void (__stdcall*)(struct _SNETEVENT *)); +BOOL __stdcall SNetRegisterEventHandler(int,void (__stdcall*)(struct _SNETEVENT *)); +_bool __stdcall SNetSetBasePlayer(int); +int __stdcall SNetInitializeProvider(unsigned long,struct _SNETPROGRAMDATA *,struct _SNETPLAYERDATA *,struct _SNETUIDATA *,struct _SNETVERSIONDATA *); +int __stdcall SNetGetProviderCaps(struct _SNETCAPS *); +int __stdcall SFileSetFilePointer(HANDLE,int,HANDLE,int); +void __stdcall SDrawClearSurface(int a1); +BOOL __stdcall SDlgSetBitmapI(HWND hWnd, int a2, char *src, int mask1, int flags, void *pBuff, int a7, int width, int height, int mask2); +void __stdcall SDlgBeginPaint(HWND hWnd, char *a2); +void __stdcall SDlgEndPaint(HWND hWnd, char *a2); +void __stdcall SDlgSetSystemCursor(BYTE *a1, BYTE *a2, int *a3, int a4); +void __stdcall SDlgSetCursor(HWND hWnd, HCURSOR a2, int a3, int *a4); +BOOL __stdcall SDlgSetTimer(int a1, int a2, int a3, void (__stdcall *a4)(int, int, int, int)); +BOOL __stdcall SDlgKillTimer(int a1, int a2); +BOOL __stdcall SDlgDrawBitmap(HWND hWnd, int a2, int a3, int a4, int a5, int a6, int a7); +BOOL __stdcall SDlgDialogBoxParam(HINSTANCE hInst, char *szDialog, int a3, WNDPROC func, int a5); +BOOL __stdcall SGdiTextOut(void *pBuffer, int x, int y, int mask, char *str, int len); +BOOL __stdcall SFileEnableDirectAccess(BOOL enable); + +#ifdef __GNUC__ +} +#endif + +#endif diff --git a/2020_03_31/3rdParty/Storm/Source/storm_gcc.def b/2020_03_31/3rdParty/Storm/Source/storm_gcc.def new file mode 100644 index 00000000..c01ddbdc --- /dev/null +++ b/2020_03_31/3rdParty/Storm/Source/storm_gcc.def @@ -0,0 +1,522 @@ +LIBRARY "Storm" + +EXPORTS + SNetCreateGame @101 NONAME + SNetCreateGame@40 @101 NONAME + SNetDestroy @102 NONAME + SNetDestroy@0 @102 NONAME + SNetEnumProviders @103 NONAME + ;SNetEnumDevices @104 NONAME + SNetEnumGames @105 NONAME + SNetDropPlayer @106 NONAME + SNetDropPlayer@8 @106 NONAME + SNetGetGameInfo @107 NONAME + SNetGetGameInfo@16 @107 NONAME + ;SNetGetNetworkLatency @108 NONAME + SNetGetNumPlayers @109 NONAME + SNetGetOwnerTurnsWaiting @110 NONAME + SNetGetOwnerTurnsWaiting@4 @110 NONAME + ;SNetGetPerformanceData @111 NONAME + SNetGetPlayerCaps @112 NONAME + SNetGetPlayerName @113 NONAME + SNetGetProviderCaps @114 NONAME + SNetGetProviderCaps@4 @114 NONAME + SNetGetTurnsInTransit @115 NONAME + SNetGetTurnsInTransit@4 @115 NONAME + SNetInitializeDevice @116 NONAME + SNetInitializeProvider @117 NONAME + SNetInitializeProvider@20 @117 NONAME + SNetJoinGame @118 NONAME + SNetLeaveGame @119 NONAME + SNetLeaveGame@4 @119 NONAME + SNetPerformUpgrade @120 NONAME + SNetPerformUpgrade@4 @120 NONAME + SNetReceiveMessage @121 NONAME + SNetReceiveMessage@12 @121 NONAME + SNetReceiveTurns @122 NONAME + SNetReceiveTurns@20 @122 NONAME + SNetRegisterEventHandler @123 NONAME + SNetRegisterEventHandler@8 @123 NONAME + ;SNetResetLatencyMeasurements @124 NONAME + SNetSelectGame @125 NONAME + ;SNetSelectProvider @126 NONAME + SNetSendMessage @127 NONAME + SNetSendMessage@12 @127 NONAME + SNetSendTurn @128 NONAME + SNetSendTurn@8 @128 NONAME + SNetSetBasePlayer @129 NONAME + SNetSetBasePlayer@4 @129 NONAME + SNetSetGameMode @130 NONAME + SNetUnregisterEventHandler @131 NONAME + SNetUnregisterEventHandler@8 @131 NONAME + + SNetEnumGamesEx @133 NONAME + SNetSendServerChatCommand @134 NONAME + SNetSendServerChatCommand@4 @134 NONAME + ;SNetSendDatagram @135 NONAME + ;SNetReceiveDatagram @136 NONAME + SNetDisconnectAll @137 NONAME + SNetCreateLadderGame @138 NONAME + SNetReportGameResult @139 NONAME + ;SNetCheckDataFile @140 NONAME + SNetSendLeagueCommand @141 NONAME + SNetSendReplayPath @142 NONAME + SNetGetLeagueName @143 NONAME + SNetGetPlayerNames @144 NONAME + SNetLeagueLogout @145 NONAME + SNetGetLeaguePlayerName @146 NONAME + + ;Ordinal150 @150 NONAME + ;Ordinal151 @151 NONAME + + SDlgBeginPaint @201 NONAME + SDlgBeginPaint@8 @201 NONAME + SDlgBltToWindowI @202 NONAME + SDlgBltToWindowI@40 @202 NONAME + ;SDlgCheckTimers @203 NONAME + ;SDlgCreateDialogIndirectParam @204 NONAME + ;SDlgCreateDialogParam @205 NONAME + SDlgDefDialogProc @206 NONAME + SDlgDefDialogProc@16 @206 NONAME + + SDlgDialogBoxIndirectParam @208 NONAME + SDlgDialogBoxParam @209 NONAME + SDlgDialogBoxParam@20 @209 NONAME + SDlgDrawBitmap @210 NONAME + SDlgDrawBitmap@28 @210 NONAME + SDlgEndDialog @211 NONAME + SDlgEndDialog@8 @211 NONAME + SDlgEndPaint @212 NONAME + SDlgEndPaint@8 @212 NONAME + SDlgKillTimer @213 NONAME + SDlgKillTimer@8 @213 NONAME + ;SDlgSetBaseFont @214 NONAME + SDlgSetBitmapI @215 NONAME + SDlgSetBitmapI@40 @215 NONAME + SDlgSetControlBitmaps @216 NONAME + SDlgSetControlBitmaps@28 @216 NONAME + SDlgSetCursor @217 NONAME + SDlgSetCursor@16 @217 NONAME + SDlgSetSystemCursor @218 NONAME + SDlgSetSystemCursor@16 @218 NONAME + SDlgSetTimer @219 NONAME + SDlgSetTimer@16 @219 NONAME + ;SDlgUpdateCursor @220 NONAME + SDlgBltToWindowE @221 NONAME + SDlgSetBitmapE @222 NONAME + ;SDlgSetLocale @223 NONAME + Ordinal224 @224 NONAME + + ;SFileAuthenticateArchive @251 NONAME + SFileCloseArchive @252 NONAME + SFileCloseArchive@4 @252 NONAME + SFileCloseFile @253 NONAME + SFileCloseFile@4 @253 NONAME + ;SFileDdaBegin @254 NONAME + SFileDdaBeginEx @255 NONAME + SFileDdaBeginEx@28 @255 NONAME + SFileDdaDestroy @256 NONAME + SFileDdaDestroy@0 @256 NONAME + SFileDdaEnd @257 NONAME + SFileDdaEnd@4 @257 NONAME + SFileDdaGetPos @258 NONAME + SFileDdaGetPos@12 @258 NONAME + ;SFileDdaGetVolume @259 NONAME + SFileDdaInitialize @260 NONAME + SFileDdaInitialize@4 @260 NONAME + SFileDdaSetVolume @261 NONAME + SFileDdaSetVolume@12 @261 NONAME + SFileDestroy @262 NONAME + SFileEnableDirectAccess @263 NONAME + SFileEnableDirectAccess@4 @263 NONAME + SFileGetFileArchive @264 NONAME + SFileGetFileArchive@8 @264 NONAME + SFileGetFileSize @265 NONAME + SFileGetFileSize@8 @265 NONAME + SFileOpenArchive @266 NONAME + SFileOpenArchive@16 @266 NONAME + SFileOpenFile @267 NONAME + SFileOpenFile@8 @267 NONAME + SFileOpenFileEx @268 NONAME + SFileOpenFileEx@16 @268 NONAME + SFileReadFile @269 NONAME + SFileReadFile@20 @269 NONAME + SFileSetBasePath @270 NONAME + SFileSetBasePath@4 @270 NONAME + SFileSetFilePointer @271 NONAME + SFileSetFilePointer@16 @271 NONAME + SFileSetLocale @272 NONAME + ;SFileGetBasePath @273 NONAME + SFileSetIoErrorMode @274 NONAME + SFileGetArchiveName @275 NONAME + SFileGetFileName @276 NONAME + ;SFileGetArchiveInfo @277 NONAME + ;SFileSetPlatform @278 NONAME + SFileLoadFile @279 NONAME + SFileUnloadFile @280 NONAME + SFileLoadFileEx @281 NONAME + ;SFilePrioritizeRequest @282 NONAME + ;SFileCancelRequest @283 NONAME + ;SFileSetAsyncBudget @284 NONAME + ;SFileSetDataChunkSize @285 NONAME + ;SFileEnableSeekOptimization @286 NONAME + ;SFileReadFileEx @287 NONAME + ;SFileFileExists @288 NONAME + ;SFileFileExistsEx @289 NONAME + ;SFileReadFileEx2 @290 NONAME + ;SFileReadFile2 @291 NONAME + ;SFileLoadFile2 @292 NONAME + ;SFileOpenFileAsArchive @293 NONAME + ;SFileGetLocale @294 NONAME + ;SFileRegisterLoadNotifyProc @295 NONAME + ;SFileGetFileCompressedSize @296 NONAME + ;Ordinal297 @297 NONAME + ;Ordinal298 @298 NONAME + ;SFileAuthenticateArchiveEx @299 NONAME + ;SFileOpenPathAsArchive @300 NONAME + StormDestroy @301 NONAME + ;StormGetInstance @302 NONAME + ;StormGetOption @303 NONAME + ;StormSetOption @304 NONAME + + ;SBltGetSCode @312 NONAME + SBltROP3 @313 NONAME + SBltROP3@32 @313 NONAME + SBltROP3Clipped @314 NONAME + SBltROP3Tiled @315 NONAME + SBltROP3Tiled@40 @315 NONAME + + SBmpDecodeImage @321 NONAME + + SBmpLoadImage @323 NONAME + SBmpLoadImage@28 @323 NONAME + SBmpSaveImage @324 NONAME + SBmpAllocLoadImage @325 NONAME + ;SBmpSaveImageEx @326 NONAME + + SCodeCompile @331 NONAME + SCodeDelete @332 NONAME + + SCodeExecute @334 NONAME + ;SCodeGetPseudocode @335 NONAME + + SDrawAutoInitialize @341 NONAME + SDrawCaptureScreen @342 NONAME + SDrawClearSurface @343 NONAME + SDrawClearSurface@4 @343 NONAME + SDrawDestroy @344 NONAME + ;SDrawFlipPage @345 NONAME + SDrawGetFrameWindow @346 NONAME + SDrawGetFrameWindow@4 @346 NONAME + SDrawGetObjects @347 NONAME + SDrawGetScreenSize @348 NONAME + ;SDrawGetServiceLevel @349 NONAME + SDrawLockSurface @350 NONAME + SDrawManualInitialize @351 NONAME + SDrawManualInitialize@32 @351 NONAME + SDrawMessageBox @352 NONAME + SDrawMessageBox@12 @352 NONAME + SDrawPostClose @353 NONAME + SDrawRealizePalette @354 NONAME + ;SDrawSelectGdiSurface @355 NONAME + SDrawUnlockSurface @356 NONAME + SDrawUpdatePalette @357 NONAME + SDrawUpdatePalette@16 @357 NONAME + ;SDrawUpdateScreen @358 NONAME + ;SDrawWaitForVerticalBlank @359 NONAME + + SEvtDispatch @372 NONAME + ;SEvtRegisterHandler @373 NONAME + ;SEvtUnregisterHandler @374 NONAME + ;SEvtUnregisterType @375 NONAME + ;SEvtPopState @376 NONAME + ;SEvtPushState @377 NONAME + ;SEvtBreakHandlerChain @378 NONAME + + ;SGdiBitBlt @381 NONAME + ;SGdiCreateFont @382 NONAME + SGdiDeleteObject @383 NONAME + SGdiDeleteObject@4 @383 NONAME + ;SGdiDestroy @384 NONAME + SGdiExtTextOut @385 NONAME + SGdiImportFont @386 NONAME + SGdiImportFont@8 @386 NONAME + ;SGdiLoadFont @387 NONAME + ;SGdiRectangle @388 NONAME + SGdiSelectObject @389 NONAME + SGdiSelectObject@4 @389 NONAME + SGdiSetPitch @390 NONAME + SGdiSetPitch@4 @390 NONAME + SGdiTextOut @391 NONAME + SGdiTextOut@24 @391 NONAME + ;SGdi392 @392 NONAME + Ordinal393 @393 NONAME + + ;SMem399 @399 NONAME + + SMemAlloc @401 NONAME + SMemAlloc@16 @401 NONAME + ;SMemDestroy @402 NONAME + SMemFree @403 NONAME + SMemFree@16 @403 NONAME + ;SMemGetSize @404 NONAME + SMemReAlloc @405 NONAME + ;Storm406 @406 NONAME + + ;SMsgDispatchMessage @412 NONAME + ;SMsgDoMessageLoop @413 NONAME + ;SMsgRegisterCommand @414 NONAME + ;SMsgRegisterKeyDown @415 NONAME + ;SMsgRegisterKeyUp @416 NONAME + ;SMsgRegisterMessage @417 NONAME + ;SMsgPopRegisterState @418 NONAME + ;SMsgPushRegisterState @419 NONAME + ;SMsg420 @420 NONAME + SRegLoadData @421 NONAME + SRegLoadData@24 @421 NONAME + SRegLoadString @422 NONAME + SRegLoadString@20 @422 NONAME + SRegLoadValue @423 NONAME + SRegLoadValue@16 @423 NONAME + SRegSaveData @424 NONAME + SRegSaveData@20 @424 NONAME + SRegSaveString @425 NONAME + SRegSaveString@16 @425 NONAME + SRegSaveValue @426 NONAME + SRegSaveValue@16 @426 NONAME + ;SRegGetBaseKey @427 NONAME + SRegDeleteValue @428 NONAME + ;SReg429 @429 NONAME + ;SReg430 @430 NONAME + STransBlt @431 NONAME + STransBlt@20 @431 NONAME + STransBltUsingMask @432 NONAME + STransCreateI @433 NONAME + STransCreateI@28 @433 NONAME + STransDelete @434 NONAME + STransDelete@4 @434 NONAME + + STransDuplicate @436 NONAME + STransIntersectDirtyArray @437 NONAME + STransInvertMask @438 NONAME + ;STransLoadI @439 NONAME + STransSetDirtyArrayInfo @440 NONAME + ;STransUpdateDirtyArray @441 NONAME + STransPointInMask @442 NONAME + STransCombineMasks @443 NONAME + ;STransCreateI @444 NONAME + STransCreateE @445 NONAME + ;STrans446 @446 NONAME + ;STransLoadE @447 NONAME + + SVidDestroy @451 NONAME + SVidDestroy@0 @451 NONAME + SVidGetSize @452 NONAME + SVidInitialize @453 NONAME + SVidInitialize@4 @453 NONAME + SVidPlayBegin @454 NONAME + SVidPlayBegin@28 @454 NONAME + ;SVidPlayBeginFromMemory @455 NONAME + SVidPlayContinue @456 NONAME + SVidPlayContinueSingle @457 NONAME + SVidPlayEnd @458 NONAME + SVidPlayEnd@4 @458 NONAME + ;SVidSetVolume @459 NONAME + ;Storm460 @460 NONAME + SErrDisplayError @461 NONAME + SErrGetErrorStr @462 NONAME + SErrGetErrorStr@12 @462 NONAME + SErrGetLastError @463 NONAME + SErrGetLastError@0 @463 NONAME + ;SErrRegisterMessageSource @464 NONAME + SErrSetLastError @465 NONAME + SErrSetLastError@4 @465 NONAME + ;SErrReportNamedResourceLeak @466 NONAME + ;SErrReportResourceLeak @467 NONAME + SErrSuppressErrors @468 NONAME + ;SErrRegisterHandler @469 NONAME + ;SErrUnregisterHandler @470 NONAME + ;Storm471 @471 NONAME + ;SCmdGetBool @472 NONAME + ;SCmdGetNum @473 NONAME + ;SCmdGetString @474 NONAME + ;SCmdProcess @475 NONAME + ;SCmdRegisterArgList @476 NONAME + ;SCmdRegisterArgument @477 NONAME + ;SCmdStringExists @478 NONAME + ;SCmdProcessCommandLine @479 NONAME + ;Ordinal480 @480 NONAME + ;SMemFindNextBlock @481 NONAME + ;SMemFindNextHeap @482 NONAME + ;SMemGetHeapByCaller @483 NONAME + ;SMemGetHeapByPtr @484 NONAME + ;SMemHeapAlloc @485 NONAME + ;SMemHeapCreate @486 NONAME + ;SMemHeapDestroy @487 NONAME + ;SMemHeapFree @488 NONAME + ;SMemHeapRealloc @489 NONAME + ;SMemHeapSize @490 NONAME + SMemCopy @491 NONAME + SMemFill @492 NONAME + ;SMemMove @493 NONAME + SMemZero @494 NONAME + SMemCmp @495 NONAME + ;SMem496 @496 NONAME + ;SMemDumpState @497 NONAME + ;Ordinal498 @498 NONAME + + SStrCopy @501 NONAME + SStrCopy@12 @501 NONAME + SStrHash @502 NONAME + SStrPack @503 NONAME + SStrPack@12 @503 NONAME + ;SStrTokenize @504 NONAME + ;SStrPack @505 NONAME + SStrLen @506 NONAME + ;SStrDup @507 NONAME + SStrCmp @508 NONAME + SStrCmpI @509 NONAME + SStrUpper @510 NONAME + ;SMsgBreakHandlerChain @511 NONAME + ;SMsgUnregisterCommand @512 NONAME + ;SMsgUnregisterKeyDown @513 NONAME + ;SMsgUnregisterKeyUp @514 NONAME + ;SMsgUnregisterMessage @515 NONAME + ;SMsgGetDispatcher @516 NONAME + ;SMsgSetDefaultWindow @517 NONAME + ;SMsgGetDefaultWindow @518 NONAME + ;SMsg519 @519 NONAME + + ;SRgn521 @521 NONAME + + SRgn523 @523 NONAME + SRgnCreateRegion @524 NONAME + SRgnDeleteRegion @525 NONAME + + ;SRgn527 @527 NONAME + ;SRgn528i @528 NONAME + SRgn529i @529 NONAME + ;SRgn530i @530 NONAME + ;SRgn531i @531 NONAME + ;SRgn532i @532 NONAME + ;SRgn533i @533 NONAME + ;SRgn534 @534 NONAME + ;SRgn535f @535 NONAME + ;SRgn536f @536 NONAME + ;SRgn537f @537 NONAME + ;SRgn538f @538 NONAME + ;SRgn539f @539 NONAME + ;SRgn540f @540 NONAME + ;SLogClose @541 NONAME + ;SLogCreate @542 NONAME + ;SLog543 @543 NONAME + ;SLogDump @544 NONAME + ;SLogFlush @545 NONAME + ;SLogFlushAll @546 NONAME + ;SLogPend @547 NONAME + ;SLogWrite @548 NONAME + ;SLog549 @549 NONAME + ;SLogCriticalLog @550 NONAME + ;SCompCompress @551 NONAME + ;SCompDecompress @552 NONAME + ;SLogVWrite @553 NONAME + ;Ordinal554 @554 NONAME + ;Ordinal555 @555 NONAME + ;Ordinal556 @556 NONAME + ;Ordinal557 @557 NONAME + ;Ordinal558 @558 NONAME + ;Ordinal559 @559 NONAME + ;Ordinal560 @560 NONAME + ;SErrCheckDebugSymbolLibrary @561 NONAME + SErrDisplayErrorFmt @562 NONAME + ;SErrIsDisplayingError @563 NONAME + ;SErrPrepareAppFatal @564 NONAME + ;SErrSetLogTitleString @565 NONAME + ;SErrDisplayAppFatal @566 NONAME + SErrCatchUnhandledExceptions @567 NONAME + ;Storm568 @568 NONAME + ;SStrChr @569 NONAME + ;SStrChrR @570 NONAME + SStrChr @571 NONAME + SStrChrR @572 NONAME + ;SStrToDouble @573 NONAME + ;SStrToFloat @574 NONAME + ;SStrToInt @575 NONAME + ;SStrToUnsigned @576 NONAME + ;SStrToInt64 @577 NONAME + SStrVPrintf @578 NONAME + ;SStrLower @579 NONAME + ;SStrHash64 @580 NONAME + ;SStrPrintf @581 NONAME + ;SDrawSetClientRect @582 NONAME + ;SDrawGetClientRect @583 NONAME + ;SStrStrI @584 NONAME + ;SStrStrI @585 NONAME + ;SStrStr @586 NONAME + ;SStrStr @587 NONAME + ;SNet588 @588 NONAME + + ;SBigAdd @601 NONAME + ;SBigAnd @602 NONAME + ;SBigCompare @603 NONAME + ;SBigCopy @604 NONAME + ;SBigDec @605 NONAME + SBigDel @606 NONAME + ;SBigDiv @607 NONAME + ;SBigFindPrime @608 NONAME + SBigFromBinary @609 NONAME + ;SBigFromStr @610 NONAME + ;SBigFromStream @611 NONAME + ;SBigFromUnsigned @612 NONAME + ;SBigGcd @613 NONAME + ;SBigInc @614 NONAME + ;SBigInvMod @615 NONAME + ;SBigIsEven @616 NONAME + ;SBigIsOdd @617 NONAME + ;SBigIsOne @618 NONAME + ;SBigIsPrime @619 NONAME + ;SBigIsZero @620 NONAME + ;SBigMod @621 NONAME + ;SBigMul @622 NONAME + ;SBigMulMod @623 NONAME + SBigNew @624 NONAME + ;SBigNot @625 NONAME + ;SBigOr @626 NONAME + ;SBigPow @627 NONAME + SBigPowMod @628 NONAME + ;SBigRand @629 NONAME + ;SBigSet2Exp @630 NONAME + ;SBigSetOne @631 NONAME + ;SBigSetZero @632 NONAME + ;SBigShl @633 NONAME + ;SBigShr @634 NONAME + ;SBigSquare @635 NONAME + ;SBigSub @636 NONAME + ;SBigToBinaryArray @637 NONAME + SBigToBinaryBuffer @638 NONAME + ;SBigToBinaryPtr @639 NONAME + ;SBigToStrArray @640 NONAME + ;SBigToStrBuffer @641 NONAME + ;SBigToStrPtr @642 NONAME + ;SBigToStreamArray @643 NONAME + ;SBigToStreamBuffer @644 NONAME + ;SBigToStreamPtr @645 NONAME + ;SBigToUnsigned @646 NONAME + ;SBigXor @647 NONAME + + ;SUniConvertUTF16to8Len @901 NONAME + ;SUniConvertUTF16to8 @902 NONAME + ;SUniConvertUTF8to16Len @903 NONAME + ;SUniConvertUTF8to16 @904 NONAME + ;SUniS905 @905 NONAME + ;SUniS906 @906 NONAME + ;SUniFindAfterUTF8Chr @907 NONAME + ;SUniFindUTF8ChrStart @908 NONAME + ;SUniConvertUTF16To909 @909 NONAME + ;SUniConvertUTF16To910 @910 NONAME + ;SUniConvertUTF16To911 @911 NONAME + ;SUniConvert912 @912 NONAME + ;SUniConvert913 @913 NONAME + ;SUniConvert914 @914 NONAME + ;SUniConvertUTF8ToWin @915 NONAME +; END diff --git a/2020_03_31/Diablo.dsp b/2020_03_31/Diablo.dsp new file mode 100644 index 00000000..4d639d08 --- /dev/null +++ b/2020_03_31/Diablo.dsp @@ -0,0 +1,407 @@ +# Microsoft Developer Studio Project File - Name="Diablo" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=Diablo - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "Diablo.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "Diablo.mak" CFG="Diablo - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "Diablo - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "Diablo - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "Diablo - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Source/WinRel" +# PROP BASE Intermediate_Dir "Source/WinRel" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Source/WinRel" +# PROP Intermediate_Dir "Source/WinRel" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /Gr /MT /W3 /GX /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib advapi32.lib shell32.lib version.lib 3rdParty/Pkware/implode.lib /nologo /subsystem:windows /machine:I386 + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Source/WinDebug" +# PROP BASE Intermediate_Dir "Source/WinDebug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Source/WinDebug" +# PROP Intermediate_Dir "Source/WinDebug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /Gr /MTd /W3 /Gm /GX /Zi /O1 /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib advapi32.lib shell32.lib version.lib 3rdParty/Pkware/implode.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "Diablo - Win32 Release" +# Name "Diablo - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\Source\appfat.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\automap.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\capture.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\codec.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\control.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\cursor.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\dead.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\debug.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\diablo.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\doom.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\drlg_l1.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\drlg_l2.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\drlg_l3.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\drlg_l4.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\dthread.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\dx.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\effects.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\encrypt.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\engine.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\error.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\fault.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\gamemenu.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\gendung.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\gmenu.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\help.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\init.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\interfac.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\inv.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\itemdat.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\items.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\lighting.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\loadsave.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\logging.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\mainmenu.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\minitext.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\misdat.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\missiles.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\monstdat.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\monster.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\movie.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\mpqapi.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\msg.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\msgcmd.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\multi.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\nthread.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\objdat.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\objects.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\pack.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\palette.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\path.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\pfile.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\player.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\plrmsg.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\portal.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\quests.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\restrict.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\scrollrt.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\setmaps.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\sha.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\sound.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\spelldat.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\spells.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\stores.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\sync.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\textdat.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\themes.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\tmsg.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\town.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\towners.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\track.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\trigs.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\wave.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\render.cpp +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# Begin Source File + +SOURCE=.\Diablo.ico +# End Source File +# Begin Source File + +SOURCE=.\Diablo.rc +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\resource.h +# End Source File +# End Group +# End Target +# End Project diff --git a/2020_03_31/Diablo.dsw b/2020_03_31/Diablo.dsw new file mode 100644 index 00000000..e16a3cf6 --- /dev/null +++ b/2020_03_31/Diablo.dsw @@ -0,0 +1,62 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "Diablo"=.\Diablo.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name DiabloUI + End Project Dependency + Begin Project Dependency + Project_Dep_Name Storm + End Project Dependency +}}} + +############################################################################### + +Project: "DiabloUI"=.\DiabloUI\DiabloUI.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name Storm + End Project Dependency +}}} + +############################################################################### + +Project: "Storm"=.\3rdParty\Storm\Source\Storm.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/2020_03_31/Diablo.ico b/2020_03_31/Diablo.ico new file mode 100644 index 00000000..81c3a4a0 Binary files /dev/null and b/2020_03_31/Diablo.ico differ diff --git a/2020_03_31/Diablo.rc b/2020_03_31/Diablo.rc new file mode 100644 index 00000000..5e2d680f --- /dev/null +++ b/2020_03_31/Diablo.rc @@ -0,0 +1,291 @@ +//Microsoft Developer Studio generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_ICON1 ICON DISCARDABLE "Diablo.ico" + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_DIALOG1 DIALOG DISCARDABLE 0, 0, 250, 241 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Direct Draw Error" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "OK",1,193,220,50,14 + LTEXT "Diablo was unable to properly initialize your video card using DirectX. Please try the following solutions to correct the problem:", + -1,7,7,236,18 + LTEXT "Use the Diablo setup program ""SETUP.EXE"" provided on the Diablo CD-ROM to install DirectX 3.0.", + -1,19,26,210,18 + LTEXT "Install the most recent DirectX video drivers provided by the manufacturer of your video card. A list of video card manufactuers can be found at: http://www.blizzard.com/support/vendors.htm", + -1,19,48,210,27 + LTEXT "The error encountered while trying to initialize the video card was:", + -1,7,175,236,9 + LTEXT "unknown error",1000,19,186,210,27 + LTEXT "If you continue to have problems, we have also included Microsoft DirectX 2.0 drivers on the Diablo CD-ROM. This older version of DirectX may work in cases where DirectX 3.0 does not.", + -1,7,79,236,27 + LTEXT "USA telephone: 1-800-426-9400\nInternational telephone: 206-882-8080\nhttp://www.microsoft.com", + -1,19,137,210,27 + LTEXT "If you continue to have problems with DirectX, please contact Microsoft's Technical Support at:", + -1,7,116,236,18 +END + +IDD_DIALOG2 DIALOG DISCARDABLE 0, 0, 250, 213 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Out of Memory Error" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "OK",1,193,192,50,14 + LTEXT "Diablo has exhausted all the memory on your system. This problem can likely be corrected by changing the virtual memory settings for Windows. Ensure that your system has at least 10 megabytes of free disk space, then check your virtual memory settings:", + -1,7,7,236,36 + LTEXT "Select ""Settings - Control Panel"" from the ""Start"" menu\nRun the ""System"" control panel applet\nSelect the ""Performance"" tab, and press ""Virtual Memory""\nUse the ""Let Windows manage my virtual memory..."" option", + -1,23,54,197,36 + LTEXT "The error encountered was:",-1,7,146,236,11 + LTEXT "unknown location",1000,20,157,210,27 + LTEXT "For Windows 95:",-1,7,45,236,9 + LTEXT "Select ""Settings - Control Panel"" from the ""Start"" menu\nRun the ""System"" control panel applet\nSelect the ""Performance"" tab\nPress ""Change"" in ""Virtual Memory"" settings\nEnsure that the virtual memory file is at least 32 megabytes", + -1,17,98,197,45 + LTEXT "For Windows NT:",-1,7,89,236,9 +END + +IDD_DIALOG3 DIALOG DISCARDABLE 0, 0, 265, 114 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Data File Error" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "OK",1,208,93,50,14 + LTEXT "Diablo was unable to open a required file. Please ensure that the Diablo disc is in the CDROM drive. If this problem persists, try uninstalling and reinstalling Diablo using the program ""SETUP.EXE"" on the Diablo CD-ROM.", + -1,7,7,251,36 + LTEXT "The problem occurred while trying to load a file",-1,7, + 48,232,9 + LTEXT "unknown file",1000,20,59,210,27 +END + +IDD_DIALOG4 DIALOG DISCARDABLE 0, 0, 250, 161 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Direct Draw Error" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "OK",1,193,140,50,14 + LTEXT "Diablo was unable to find the file ""ddraw.dll"", which is a component of Microsoft DirectX. Please run the program ""SETUP.EXE"" on the Diablo CD-ROM and install Microsoft DirectX.", + -1,7,7,236,27 + LTEXT "The error encountered while trying to initialize DirectX was:", + -1,7,95,236,9 + LTEXT "unknown error",1000,19,106,210,29 + LTEXT "USA telephone: 1-800-426-9400\nInternational telephone: 206-882-8080\nhttp://www.microsoft.com", + -1,19,60,210,27 + LTEXT "If you continue to have problems with DirectX, please contact Microsoft's Technical Support at:", + -1,7,39,236,18 +END + +IDD_DIALOG5 DIALOG DISCARDABLE 0, 0, 250, 161 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Direct Sound Error" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "OK",1,193,140,50,14 + LTEXT "Diablo was unable to find the file ""dsound.dll"", which is a component of Microsoft DirectX. Please run the program ""SETUP.EXE"" on the Diablo CD-ROM and install Microsoft DirectX.", + -1,7,7,236,27 + LTEXT "The error encountered while trying to initialize DirectX was:", + -1,7,95,236,9 + LTEXT "unknown error",1000,19,106,210,27 + LTEXT "USA telephone: 1-800-426-9400\nInternational telephone: 206-882-8080\nhttp://www.microsoft.com", + -1,19,60,210,27 + LTEXT "If you continue to have problems with DirectX, please contact Microsoft's Technical Support at:", + -1,7,39,236,18 +END + +/* IDD_DIALOG6 DIALOG DISCARDABLE 0, 0, 250, 92 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "System warning" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "&OK",1,130,71,50,14 + LTEXT "Diablo requires an Intel Pentium-class processor to run properly. Your system does not appear to have a Pentium-class processor installed.", + -1,7,7,236,18 + LTEXT "You may still be able to play Diablo if your processor has the performance characteristics of a Pentium.", + -1,7,30,236,18 + LTEXT "Press ""OK"" to proceed, otherwise press ""Cancel"" to exit this program.", + -1,7,53,236,9 + PUSHBUTTON "&Cancel",2,193,71,50,14 +END */ + +IDD_DIALOG7 DIALOG DISCARDABLE 0, 0, 250, 100 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Out of Disk Space" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "OK",1,193,79,50,14 + LTEXT "Diablo requires at least 10 megabytes of free disk space to run properly. The disk:", + -1,7,7,236,18 + LTEXT "",-1,7,43,232,9 + LTEXT "unknown drive",1000,7,33,210,9 + LTEXT "has less than 10 megabytes of free space left. Please free some space on your drive and run Diablo again.", + -1,7,52,236,18 +END + +IDD_DIALOG8 DIALOG DISCARDABLE 0, 0, 250, 161 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Direct Draw Error" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "OK",1,193,140,50,14 + LTEXT "Diablo was unable to switch video modes. This is a common problem for computers with more than one video card. To correct this problem, please set your video resolution to 640 x 480 and try running Diablo again.", + -1,7,7,236,27 + LTEXT "The error encountered while trying to switch video modes was:", + -1,7,95,236,9 + LTEXT "unknown error",1000,19,106,210,27 + LTEXT "Select ""Settings - Control Panel"" from the ""Start"" menu\nRun the ""Display"" control panel applet\nSelect the ""Settings"" tab\nSet the ""Desktop Area"" to ""640 x 480 pixels""", + -1,23,50,197,36 + LTEXT "For Windows 95 and Windows NT",-1,7,41,236,9 +END + +IDD_DIALOG9 DIALOG DISCARDABLE 0, 0, 250, 92 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Data File Error" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "OK",1,136,71,50,14 + LTEXT "Diablo cannot read a required data file. Your Diablo CD may not be in the CDROM drive. Please ensure that the Diablo disc is in the CDROM drive and press OK. To leave the program, press Exit.", + -1,7,7,236,27 + LTEXT "unknown file",1000,20,37,210,27 + PUSHBUTTON "Exit",2,193,71,50,14 +END + +IDD_DIALOG10 DIALOG DISCARDABLE 0, 0, 223, 116 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Windows 2000 Restricted User Advisory" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "OK",1,166,95,50,14 + LTEXT "In order to install, play or patch Diablo using the Windows 2000 operating system, you will need to log in as either an Administrator or as a Power User.", + -1,7,7,209,28 + LTEXT "Users, also known as Restricted Users, do not have sufficient access to install or play the game properly.", + -1,7,39,209,20 + LTEXT "If you have further questions regarding User Rights in Windows 2000, please refer to your Windows 2000 documentation or contact your system administrator.", + -1,7,63,209,28 +END + +IDD_DIALOG11 DIALOG DISCARDABLE 0, 0, 220, 121 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Read-Only Directory Error" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "OK",1,163,100,50,14 + LTEXT "Diablo is being run from:",-1,7,7,206,10 + LTEXT "unknown directory",1000,17,20,186,20 + LTEXT "Diablo or the current user does not seem to have write privilages in this directory. Contact your system administrator.\n\nNote that Windows 2000 Restricted Users can not write to the Windows or Program Files directory hierarchies.", + -1,7,44,206,50 +END + + +#ifndef _MAC +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 2001,5,18,1 + PRODUCTVERSION 1,0,9,2 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "CompanyName", "Blizzard Entertainment\0" + VALUE "FileDescription", "Diablo\0" + VALUE "FileVersion", "2001, 5, 18, 1\0" + VALUE "InternalName", "Diablo\0" + VALUE "LegalCopyright", "Copyright © 1996-2001\0" + VALUE "OriginalFilename", "Diablo.exe\0" + VALUE "ProductName", "Blizzard Entertainment Diablo\0" + VALUE "ProductVersion", "1, 0, 9, 2\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + +#endif // !_MAC + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/2020_03_31/Diablo.sln b/2020_03_31/Diablo.sln new file mode 100644 index 00000000..d65530c2 --- /dev/null +++ b/2020_03_31/Diablo.sln @@ -0,0 +1,37 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.27703.2035 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Diablo", "Diablo.vcxproj", "{23114A83-7D81-4F17-A6B8-2FC51F3D72F2}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DiabloUI", "DiabloUI\DiabloUI.vcxproj", "{8408E35E-3CF5-4D4E-B873-AF3952CDABD4}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Storm", "3rdParty\Storm\Source\Storm.vcxproj", "{B28F69CE-15A1-424D-BBB5-2727258D675B}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x86 = Debug|x86 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {23114A83-7D81-4F17-A6B8-2FC51F3D72F2}.Debug|x86.ActiveCfg = Debug|Win32 + {23114A83-7D81-4F17-A6B8-2FC51F3D72F2}.Debug|x86.Build.0 = Debug|Win32 + {23114A83-7D81-4F17-A6B8-2FC51F3D72F2}.Release|x86.ActiveCfg = Release|Win32 + {23114A83-7D81-4F17-A6B8-2FC51F3D72F2}.Release|x86.Build.0 = Release|Win32 + {8408E35E-3CF5-4D4E-B873-AF3952CDABD4}.Debug|x86.ActiveCfg = Debug|Win32 + {8408E35E-3CF5-4D4E-B873-AF3952CDABD4}.Debug|x86.Build.0 = Debug|Win32 + {8408E35E-3CF5-4D4E-B873-AF3952CDABD4}.Release|x86.ActiveCfg = Release|Win32 + {8408E35E-3CF5-4D4E-B873-AF3952CDABD4}.Release|x86.Build.0 = Release|Win32 + {B28F69CE-15A1-424D-BBB5-2727258D675B}.Debug|x86.ActiveCfg = Debug|Win32 + {B28F69CE-15A1-424D-BBB5-2727258D675B}.Debug|x86.Build.0 = Debug|Win32 + {B28F69CE-15A1-424D-BBB5-2727258D675B}.Release|x86.ActiveCfg = Release|Win32 + {B28F69CE-15A1-424D-BBB5-2727258D675B}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {6252549D-BED6-405B-9D6D-42C9074D0684} + EndGlobalSection +EndGlobal diff --git a/2020_03_31/Diablo.vcxproj b/2020_03_31/Diablo.vcxproj new file mode 100644 index 00000000..4e2f82b0 --- /dev/null +++ b/2020_03_31/Diablo.vcxproj @@ -0,0 +1,305 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + + + {23114A83-7D81-4F17-A6B8-2FC51F3D72F2} + 8.1 + + + + Application + v141 + + + Application + v141 + + + + + + + + + + + + + + + .\Source/WinRel\ + .\Source/WinRel\ + + + .\Source/WinDebug\ + .\Source/WinDebug\ + + + + MultiThreaded + Default + true + MaxSpeed + true + Level3 + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + .\Source/WinRel\ + .\Source/WinRel\ + .\Source/WinRel\ + 4996 + true + true + None + + + true + NDEBUG;%(PreprocessorDefinitions) + .\Source/WinRel\Diablo.tlb + true + NUL + Win32 + + + 0x0409 + NDEBUG;%(PreprocessorDefinitions) + + + .\Source/WinRel\Diablo.bsc + + + Windows + .\Source/WinRel\Diablo.exe + DiabloUI/WinRel/DiabloUI.lib;3rdParty/Storm/Source/WinRel/Storm.lib;version.lib;%(AdditionalDependencies) + false + false + false + + + + + MultiThreadedDebug + OnlyExplicitInline + Disabled + true + Level3 + EditAndContinue + WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + .\Source/WinDebug\ + .\Source/WinDebug\ + .\Source/WinDebug\ + 4996 + true + + + true + _DEBUG;%(PreprocessorDefinitions) + .\Source/WinDebug\Diablo.tlb + true + NUL + Win32 + + + 0x0409 + _DEBUG;%(PreprocessorDefinitions) + + + .\Source/WinDebug\Diablo.bsc + + + true + Windows + .\Source/WinDebug\Diablo.exe + DiabloUI/WinDebug/DiabloUI.lib;3rdParty/Storm/Source/WinDebug/Storm.lib;version.lib;%(AdditionalDependencies) + false + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {b28f69ce-15a1-424d-bbb5-2727258d675b} + false + + + {8408e35e-3cf5-4d4e-b873-af3952cdabd4} + false + + + + + + diff --git a/2020_03_31/Diablo.vcxproj.filters b/2020_03_31/Diablo.vcxproj.filters new file mode 100644 index 00000000..2ddb347e --- /dev/null +++ b/2020_03_31/Diablo.vcxproj.filters @@ -0,0 +1,497 @@ + + + + + {0fb229f0-d459-4ec9-b897-317b016e0a57} + cpp;c;cxx;rc;def;r;odl;idl;hpj;bat + + + {52f34be1-947a-42ee-b303-4a46566a14a7} + ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe + + + {8003aed2-27a6-444b-8fb0-bb8a59530005} + h;hpp;hxx;hm;inl + + + {5dbacde9-4fc8-4776-ba59-92912e0c8ab5} + cpp;c;cxx;rc;def;r;odl;idl;hpj;bat + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + PKWare + + + PKWare + + + + + Resource Files + + + + + Resource Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + PKWare + + + diff --git a/2020_03_31/DiabloUI/DiabloUI.dsp b/2020_03_31/DiabloUI/DiabloUI.dsp new file mode 100644 index 00000000..3bc526ad --- /dev/null +++ b/2020_03_31/DiabloUI/DiabloUI.dsp @@ -0,0 +1,99 @@ +# Microsoft Developer Studio Project File - Name="DiabloUI" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=DiabloUI - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "DiabloUI.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "DiabloUI.mak" CFG="DiabloUI - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "DiabloUI - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "DiabloUI - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "DiabloUI - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "WinRel" +# PROP BASE Intermediate_Dir "WinRel" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "WinRel" +# PROP Intermediate_Dir "WinRel" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 /def:"diabloui.def" + +!ELSEIF "$(CFG)" == "DiabloUI - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "WinDebug" +# PROP BASE Intermediate_Dir "WinDebug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "WinDebug" +# PROP Intermediate_Dir "WinDebug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /O1 /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /def:"diabloui.def" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "DiabloUI - Win32 Release" +# Name "DiabloUI - Win32 Debug" +# Begin Source File + +SOURCE=.\diabloui.cpp +# End Source File +# Begin Source File + +SOURCE=.\diabloui.res +# End Source File +# End Target +# End Project diff --git a/2020_03_31/DiabloUI/DiabloUI.vcxproj b/2020_03_31/DiabloUI/DiabloUI.vcxproj new file mode 100644 index 00000000..51f3dd77 --- /dev/null +++ b/2020_03_31/DiabloUI/DiabloUI.vcxproj @@ -0,0 +1,146 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + + + {8408E35E-3CF5-4D4E-B873-AF3952CDABD4} + + + + DynamicLibrary + v141 + false + + + DynamicLibrary + v141 + false + + + + + + + + + + + + + + + .\WinRel\ + .\WinRel\ + false + + + .\WinDebug\ + .\WinDebug\ + true + + + + MultiThreaded + Default + true + true + MaxSpeed + true + Level3 + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + .\WinRel\ + .\WinRel\DiabloUI.pch + .\WinRel\ + .\WinRel\ + + + true + NDEBUG;%(PreprocessorDefinitions) + .\WinRel\DiabloUI.tlb + true + NUL + Win32 + + + 0x0409 + NDEBUG;%(PreprocessorDefinitions) + + + true + .\WinRel\DiabloUI.bsc + + + true + true + Windows + diabloui.def + .\WinRel\DiabloUI.dll + .\WinRel\DiabloUI.lib + ../3rdParty/Storm/Source/WinRel/Storm.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + MultiThreadedDebug + Default + Disabled + true + Level3 + true + EditAndContinue + WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + .\WinDebug\ + .\WinDebug\DiabloUI.pch + .\WinDebug\ + .\WinDebug\ + + + true + _DEBUG;%(PreprocessorDefinitions) + .\WinDebug\DiabloUI.tlb + true + NUL + Win32 + + + 0x0409 + _DEBUG;%(PreprocessorDefinitions) + + + true + .\WinDebug\DiabloUI.bsc + + + true + true + true + Windows + diabloui.def + .\WinDebug\DiabloUI.dll + .\WinDebug\DiabloUI.lib + ../3rdParty/Storm/Source/WinDebug/Storm.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + + + + + + + + + + + diff --git a/2020_03_31/DiabloUI/_temp_data.cpp b/2020_03_31/DiabloUI/_temp_data.cpp new file mode 100644 index 00000000..8cc2b94c --- /dev/null +++ b/2020_03_31/DiabloUI/_temp_data.cpp @@ -0,0 +1,371 @@ +//rdata +ProfileStruct bnprofiles[4] = +{ + { "profile\\sex", '\x01', 1128, 8 }, + { "profile\\age", '\x01', 1130, 4 }, + { "profile\\location", '\x01', 1132, 40 }, + { "profile\\description", '\x01', 1134, 200 } +}; +int profilemsg1[6] = { 1125, 1127, 1129, 1131, 1133, 0 }; +int profilemsg2[6] = { 1126, 1128, 1130, 1132, 1134, 0 }; +int Connect_cpp_float_value = 2139095040; // weak +int CopyProt_cpp_float_value = 2139095040; // weak +int cr8game_cpp_float_value = 2139095040; // weak +int CreaDung_cpp_float_value = 2139095040; // weak +int CreaStat_cpp_float_value = 2139095040; // weak +int credits_cpp_float_value = 2139095040; // weak +int DiabEdit_cpp_float_value = 2139095040; // weak +int DiabloUI_cpp_float_value = 2139095040; // weak +int disclaim_cpp_float_value = 2139095040; // weak +int doom_cpp_float_value = 2139095040; // weak +int EntName_cpp_float_value = 2139095040; // weak +int fade_cpp_float_value = 2139095040; // weak +int focus_cpp_float_value = 2139095040; // weak +int local_cpp_float_value = 2139095040; // weak +int mainmenu_cpp_float_value = 2139095040; // weak +int OkCancel_cpp_float_value = 2139095040; // weak +int Sbar_cpp_float_value = 2139095040; // weak +int Sbar_cpp_float_value2 = 2139095040; // weak +int SelClass_cpp_float_value = 2139095040; // weak +int SelHero_cpp_float_value = 2139095040; // weak +int SelList_cpp_float_value = 2139095040; // weak +int SelLoad_cpp_float_value = 2139095040; // weak +int SelYesNo_cpp_float_value = 2139095040; // weak +int Title_cpp_float_value = 2139095040; // weak +int titlesnd_cpp_float_value = 2139095040; // weak +int dword_10022258 = 4; // weak +ProfFntStruct proffnts[4] = +{ + { 8, "Arial", 400 }, + { 10, "Arial", 400 }, + { 10, "Arial", 700 }, + { 13, "Time New Roman", 400 } +}; +unsigned char connect_subnet_ip[4][4] = +{ + { 13, 0, 0, 0 }, // 13.0.0.0 + { 128, 128, 128, 0 }, // 128.128.128.0 + { 14, 0, 0, 0 }, // 14.0.0.0 + { 255, 255, 255, 0 } // 255.255.255.0 +}; +int creadung_msgtbl1[3] = { 1038, 1080, 0 }; +int creadung_msgtbl2[2] = { 1097, 0 }; +int creadung_msgtbl3[2] = { 1099, 0 }; +int creadung_msgtbl4[3] = { 1056, 1054, 0 }; +int creadung_msgtbl5[4] = { 1094, 1095, 1096, 0 }; +short defstats[3][4] = { { 30, 15, 20, 30 }, { 25, 20, 30, 20 }, { 15, 35, 25, 20 } }; +int dword_10022A2C[3] = { 1038, 1080, 0 }; +int dword_10022A38[2] = { 1097, 0 }; +int dword_10022A40[2] = { 1102, 0 }; +int dword_10022A48[3] = { 1056, 1054, 0 }; +int dword_10022A54[3] = { 1100, 1101, 0 }; +int disclaim_msgtbl1[3] = { 1082, 1083, 0 }; +int disclaim_msgtbl2[4] = { 1084, 1085, 1086, 0 }; +int dword_10022AFC[2] = { 1038, 0 }; +int dword_10022B04[3] = { 1056, 1054, 0 }; +int dword_10022B10[2] = { 1116, 0 }; +int entname_msgtbl1[2] = { 1038, 0 }; +int entname_msgtbl2[3] = { 1056, 1054, 0 }; +int entname_msgtbl3[2] = { 1065, 0 }; +int menumsgs_1option[2] = { 1042, 0 }; +int menumsgs_5options[6] = { 1044, 1001, 1002, 1003, 2, 0 }; +int dword_10022C4C[2] = { 1038, 0 }; +int dword_10022C54[2] = { 1080, 0 }; +int dword_10022C5C[2] = { 1108, 0 }; +int dword_10022CAC[2] = { 1026, 0 }; +int dword_10022CB4[2] = { 2, 0 }; +int selclass_msgtbl1[2] = { 1038, 0 }; +int selclass_msgtbl2[3] = { 1056, 1054, 0 }; +int selclass_msgtbl3[4] = { 1062, 1063, 1064, 0 }; +int dword_10022ED8[3] = { 1038, 1080, 0 }; +int dword_10022EE4[3] = { 1143, 1147, 0 }; +int dword_10022EF0[4] = { 1081, 1076, 1144, 0 }; +int dword_10022F00[2] = { 1075, 0 }; +int dword_10022F08[4] = { 1056, 1054, 1145, 0 }; +int dword_10022F18[7] = { 1069, 1070, 1071, 1072, 1073, 1074, 0 }; +char *off_10022F8C[4] = { "Entry1", "Entry2", "Entry3", "Entry4" }; +int dword_10022F9C[2] = { 1038, 0 }; +int dword_10022FA4[3] = { 1056, 1054, 0 }; +int dword_10022FB0[7] = { 1117, 1118, 1119, 1120, 1121, 1122, 0 }; +int selhero_msgtbl_string[2] = { 1038, 0 }; +int selhero_msgtbl_3[6] = { 1057, 1058, 1059, 1060, 1061, 0 }; +int selhero_msgtbl_info[6] = { 1014, 1018, 1017, 1016, 1015, 0 }; +int dword_100230F0[3] = { 1038, 1080, 0 }; +int dword_100230FC[2] = { 1097, 0 }; +int dword_10023104[2] = { 1098, 0 }; +int dword_1002310C[3] = { 1056, 1054, 0 }; +int dword_10023118[7] = { 1088, 1089, 1090, 1091, 1092, 1093, 0 }; +int sellist_msgtbl1[2] = { 1038, 0 }; +int sellist_msgtbl2[3] = { 1056, 1054, 0 }; +int sellist_msgtbl3[2] = { 1006, 0 }; +int sellist_msgtbl4[7] = { 1047, 1048, 1049, 1050, 1051, 1052, 0 }; +int selload_msgtbl1[2] = { 1038, 0 }; +int selload_msgtbl2[3] = { 1056, 1054, 0 }; +int selload_msgtbl3[3] = { 1106, 1107, 0 }; +int dword_100231CC[2] = { 1038, 0 }; +int dword_100231D4[3] = { 1080, 1097, 0 }; +int dword_100231E0[2] = { 1123, 0 }; +int dword_100231E8[3] = { 1056, 1054, 0 }; +int dword_100231F4[7] = { 1110, 1111, 1112, 1113, 1114, 1115, 0 }; +int dword_10023244[3] = { 1038, 1080, 0 }; +int dword_10023250[2] = { 1142, 0 }; +int dword_10023258[2] = { 1146, 0 }; +int dword_10023260[3] = { 1056, 1054, 0 }; +int dword_1002326C[7] = { 1135, 1136, 1137, 1138, 1139, 1140, 0 }; +int yesno_msgtbl2[2] = { 1026, 0 }; +int yesno_msgtbl1[3] = { 1109, 2, 0 }; +int titlemsgtbl[2] = { 1067, 0 }; + +//data+bss +int artfont_cpp_float = 0; // weak +FontStruct font42g; +FontStruct *sgpCurrFont; +FontStruct font30g; +FontStruct font16s; +FontStruct font24s; +FontStruct font16g; +FontStruct font24g; +FontStruct font30s; +FontStruct font42y; +LPARAM dword_10029400; // idb +int dword_10029404; // weak +int dword_10029408; // weak +int dword_1002940C; // weak +BYTE *dword_10029410; // idb +int dword_10029414; // weak +int dword_10029418; // weak +int dword_1002941C; // weak +HGDIOBJ dword_10029420; // idb +HGDIOBJ dword_10029424; // idb +BYTE *dword_10029428; // idb +void *dword_1002942C; // idb +int (__stdcall *dword_10029430)(_DWORD, _DWORD, _DWORD, _DWORD); // weak +void *dword_10029434; // idb +int dword_10029438[4]; // weak +char nullcharacter; /* check */ +HGDIOBJ dword_10029450; // idb +int dword_10029454; // weak +int dword_10029458; // weak +int dword_10029460[3]; // idb +int dword_1002946C; // weak +HGDIOBJ dword_10029470; // idb +int dword_10029478; // weak +int dword_10029480; // weak +int dword_10029488; // weak +int dword_1002948C; // weak +int Connect_cpp_float; // weak +int special_frames; // weak +DWORD heroport_data[2]; +char connect_categorystr[128]; +char connect_plrinfostr[128]; +int heronum_frames2; // weak +DWORD special_data[2]; +int heroport_frames; // weak +DWORD heronum_data[2]; +int heronum_frames; // idb +int connect_draw_height; // idb +BYTE *connect_data1; // idb +BYTE *connect_data2; // idb +BYTE *connect_data3; // idb +void *connect_data4; // idb +HANDLE connect_trans[10]; +char *connect_charname; +int connect_color_text; // weak +HGLOBAL copyprot_popupart; // idb +HGLOBAL copyprot_artpal; // idb +int CopyProt_cpp_float; // weak +HGLOBAL copyprot_btnart; // idb +HGDIOBJ cr8game_hobject; // idb +int cr8game_cpp_float; // weak +int cr8_playercount; // weak +DWORD *cr8_somegamestruct; +int cr8_dword_10029638; // weak +int cr8_dword_1002963C; // weak +int cr8_dword_10029640; // weak +int *cr8game_playerID; // idb +_gamedata cr8_gamedata; +HWND cr8_sendmsg1; // idb +HWND cr8_sendmsg2; // idb +int cr8_dword_10029658; // weak +DWORD cr8diffbtns_size[2]; +int cr8_dword_10029668; // weak +int cr8_dword_1002966C; // idb +char cr8_gamename[32]; +char cr8_gamepassword[32]; +BYTE *cr8_creat_bg_ptr; +BYTE *cr8_but_xsm_ptr; // idb +BYTE *cr8_diffbtns_ptr; // idb +int creadung_playername; // weak +int *creadung_playerID; // idb +int CreaDung_cpp_float; // weak +int creadung_dword_100296C8; // weak +int creadung_delspinners; // weak +DWORD *crea_somegamestruct; +int creadung_lasterror; // weak +int creadung_dword_100296D8; // weak +char *creadung_gamename; +int CreaStat_cpp_float; // weak +int credittext_size; // weak +int credits_cpp_float; // weak +HGLOBAL credittext_rsrc; // idb +int credit_vertical_pos2; // idb +int credit_horz_pos; // idb +int credit_vertical_pos1; // weak +int credit_line_count; // weak +void *credit_back_img; // idb +HANDLE creditsobj; // idb +int DiabEdit_cpp_float; // weak +int DiabloUI_cpp_float; // weak +int sgbUiIsInitialized; // weak +HINSTANCE ghUiInst; // idb +int backbmp_flag1; // weak +int backbmp_flag2; // weak +int backbmp_flag3; // weak +int app_is_active; // weak +int sgbIsSpawn; // weak +int dword_10029730; // weak +int dword_10029738; // weak +char byte_1002973C; // idb +char byte_100297BC; // idb +int dword_1002983C; // weak +int dword_10029840; // weak +int dword_10029844; // weak +void *dword_10029848; // idb +int dword_1002984C; // weak +int disclaim_cpp_float; // weak +int doom_cpp_float; // weak +LPSTR dword_10029858; // idb +int dword_1002985C; // weak +int EntName_cpp_float; // weak +char *entname_charname; +int fade_cpp_float; // weak +int sgbFadeRange; // idb +tagPALETTEENTRY fadepal[256]; +int sgbIsFading; // weak +HANDLE SpinnerTransOut[8]; +int focus_spin_width; // idb +int focus_spin_height; // weak +int focus_cpp_float; // weak +int sgbSpinnersLoaded; // weak +int dword_10029CA8; // weak +int dword_10029CAC; // weak +int sgnSpinnerFrame; // weak +int local_cpp_float; // weak +DWORD gdwCursData[2]; // weak +tagPALETTEENTRY artpal[256]; +HGDIOBJ objPalette; // idb +BYTE *gpCursorArt; +BYTE *gpCursorArt2; +int mainmenu_cpp_float; // weak +char menu_version_str[64]; +int menu_item_timer; // weak +int dword_1002A120; // weak +int dword_1002A124; // weak +int dword_1002A128; // weak +int dword_1002A12C; // weak +int dword_1002A130; // weak +int dword_1002A134; // weak +int dword_1002A138; // weak +int dword_1002A13C; // weak +int dword_1002A140; // weak +int dword_1002A144; // weak +int dword_1002A148; // weak +void *dword_1002A14C; // idb +int dword_1002A150; // weak +char byte_1002A154; // idb +char byte_1002A1D4; // idb +int dword_1002A254; // weak +int dword_1002A258; // weak +int dword_1002A25C; // weak +int (*dword_1002A260)(void); // weak +char byte_1002A264; // idb +int OkCancel_cpp_float; // weak +int dword_1002A2E8; // weak +int dword_1002A2EC; // weak +int dword_1002A2F0; // weak +int (*dword_1002A2F4)(void); // weak +int dword_1002A2F8; // weak +BOOL dword_1002A2FC; // idb +int dword_1002A300; // weak +int dword_1002A304; // weak +DWORD dword_1002A308; // idb +DWORD dword_1002A310; // idb +BYTE *dword_1002A318; // idb +BYTE *dword_1002A31C; // idb +BYTE *dword_1002A320; // idb +BYTE *dword_1002A324; // idb +void *dword_1002A328; // idb +int Sbar_cpp_float; // weak +int Sbar_cpp_float2; // weak +int SelClass_cpp_float; // weak +int dword_1002A34C; // idb +int dword_1002A350; // weak +int dword_1002A354; // weak +char *dword_1002A358; // idb +int dword_1002A35C; // weak +int dword_1002A360; // idb +int dword_1002A364; // weak +int dword_1002A368; // weak +int dword_1002A36C; // weak +int dword_1002A370; // weak +int dword_1002A374; // weak +char *dword_1002A378; // idb +int dword_1002A37C; // weak +char byte_1002A380[128]; // weak +int dword_1002A400; // weak +int dword_1002A404; // weak +int dword_1002A408; // weak +BOOL (__stdcall *selhero_fnstats)(int, _uidefaultstats *); +int SelHero_cpp_float; // weak +DWORD selhero_sizedata[2]; // idb +int selhero_difficulty; // weak +int selhero_hero_hassaved; // weak +int selhero_numheroesleft; // weak +char selhero_herolevel[4]; +BOOL (__stdcall *selhero_fnremove)(_uiheroinfo *); +BOOL (__stdcall *selhero_fninfo)(BOOL (__stdcall *fninfo)(_uiheroinfo *)); +char selhero_heromag[4]; +char selhero_heronamestr[16]; +BOOL (__stdcall *selhero_fncreate)(_uiheroinfo *); +char selhero_herodex[4]; +_uiheroinfo *sgpHeroInfo; +int selhero_is_created; // weak +_uiheroinfo heroinfo_create; +int selhero_is_good; // idb +char selhero_herostr[4]; +char selhero_herovit[4]; +BYTE *selhero_buffer; +int dword_1002A49C; // weak +void *dword_1002A4A0; // idb +int dword_1002A4A4; // weak +int dword_1002A4A8; // weak +int dword_1002A4AC; // weak +int dword_1002A4B0; // weak +int dword_1002A4B4; // weak +int dword_1002A4B8; // idb +int dword_1002A4BC; // weak +int SelList_cpp_float; // weak +_uiheroinfo *sellist_pheroinfo; +int SelLoad_cpp_float; // weak +int dword_1002A4CC; // weak +int dword_1002A4D0; // weak +void *dword_1002A4D4; // idb +int dword_1002A4D8; // idb +int dword_1002A4DC; // weak +int dword_1002A4E0; // weak +int dword_1002A4E4; // weak +int dword_1002A4E8; // weak +_uiheroinfo *dword_1002A4EC; // idb +int dword_1002A4F0; // weak +int dword_1002A4F4; // idb +char *yesno_dialog_string; +int SelYesNo_cpp_float; // weak +int yesno_remove_focus; // weak +char *yesno_hero_name; +int (*YesNoFunc)(void); // weak +int yesno_is_popup; // weak +HANDLE titlePHTrans[30]; +int Title_cpp_float; // weak +int titleTransIdx; // weak +int titlesnd_cpp_float; // weak +void (__stdcall *gfnSoundFunction)(const char *file); diff --git a/2020_03_31/DiabloUI/_temp_funcs.h b/2020_03_31/DiabloUI/_temp_funcs.h new file mode 100644 index 00000000..50c0ae64 --- /dev/null +++ b/2020_03_31/DiabloUI/_temp_funcs.h @@ -0,0 +1,640 @@ +void __fastcall artfont_SetArtFont(int nFont); +void __cdecl artfont_InitAllFonts(); +void __cdecl artfont_FreeAllFonts(); +void __fastcall artfont_FreeArtFont(FontStruct *pFont); +BOOL __cdecl artfont_LoadAllFonts(); +void __fastcall artfont_LoadArtFont(FontStruct *pFont, const char *pszBinFile, const char *pszFileName); +int __cdecl artfont_GetFontMaxHeight(); +int __cdecl artfont_GetFontDefWidth(); +int __fastcall artfont_GetFontWidth(char *str); +void __cdecl j_artfont_cpp_init(); +void __cdecl artfont_cpp_init(); +int __fastcall artfont_GetFontBreak(char *str); +void __cdecl artfont_delete_operator(void *ptr); +void __fastcall artfont_PrintFontStr(char *str, DWORD **pSurface, int sx, int sy); + + +signed int bn_prof_100014E8(); +//const char *UiProfileGetString(); +//BOOL __stdcall UiProfileCallback(int a1, int a2, int a3, int a4, LPARAM a5, int a6, int a7, int a8, int (__stdcall *a9)(_DWORD, _DWORD, _DWORD, _DWORD)); +HGDIOBJ __stdcall bn_prof_1000155F(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); +void UNKCALL bn_prof_100016DD(HWND arg); +void __fastcall bn_prof_100018CE(int a1, int a2); +int __fastcall bn_prof_10001938(HDC a1, _DWORD *a2, char *a3, int a4, int a5); +int __fastcall bn_prof_10001A10(HWND a1, HWND a2); +HINSTANCE __fastcall bn_prof_10001B0A(HWND a1, const CHAR *a2); +HWND UNKCALL bn_prof_10001C0E(HWND hWnd); +void __fastcall bn_prof_10001CB9(_DWORD *a1, int a2, void (__fastcall *a3)(_BYTE *, _DWORD, int), int a4); +BOOL UNKCALL bn_prof_10001CF3(HWND hWnd); +HFONT __fastcall bn_prof_10001D81(HWND hWnd, int a2, int a3); +void UNKCALL bn_prof_10001E34(void *arg); +void __fastcall bn_prof_10001E4C(char *a1, LPARAM lParam, HWND hDlg); +void __fastcall bn_prof_10001ED0(char *a1, _BYTE *a2, int a3); +void *bn_prof_10001F29(); +BYTE *bn_prof_10001F84(); +//int __stdcall UiProfileDraw(int, int, int, int, HGDIOBJ ho, int, int, int, int, int, int); // idb +BOOL bn_prof_100021C4(); +void *bn_prof_10002247(); +int j_bn_prof_10002282(); +_DWORD *bn_prof_10002282(); +void __cdecl bn_prof_10002298(); // idb +int UNKCALL bn_prof_100022A2(HWND hWnd); // idb +int UNKCALL bn_prof_10002353(HGDIOBJ h); // idb +HGDIOBJ bn_prof_100023D8(); +_DWORD *__fastcall bn_prof_10002410(HDC hdc, _DWORD *a2); +signed int __fastcall bn_prof_10002456(int a1, const CHAR *a2, char a3, _DWORD *a4); +signed int bn_prof_100026B9(); +signed int UNKCALL bn_prof_100026C4(_DWORD *arg); +void UNKCALL bn_prof_100026F0(_DWORD *arg); +int UNKCALL bn_prof_10002749(_DWORD *arg, _DWORD *location); +_DWORD *UNKCALL bn_prof_10002782(int *arg, int a2, int a3, char a4); +_DWORD *UNKCALL bn_prof_100027CE(_DWORD *arg); +void UNKCALL bn_prof_100027D8(_DWORD *arg); +_DWORD *UNKCALL bn_prof_1000280C(int *arg, _DWORD *a2, int a3, _DWORD *a4); +void UNKCALL bn_prof_1000287D(_DWORD *arg); +void UNKCALL bn_prof_10002890(_DWORD *arg); + + +void UNKCALL BNetGW_100028C2(_DWORD *arg); +void UNKCALL BNetGW_100029BF(_DWORD *arg, int a2); +void *UNKCALL BNetGW_10002A07(_DWORD *arg); +_DWORD *UNKCALL BNetGW_10002A84(_DWORD *arg, signed int a2); +signed int BNetGW_10002AE5(); +int UNKCALL BNetGW_10002AF0(_DWORD *arg, char *a2); +_BYTE *UNKCALL BNetGW_10002B21(_DWORD *arg, signed int a2); +void UNKCALL BNetGW_10002B51(_DWORD *arg, signed int a2); +char *UNKCALL BNetGW_10002B78(void *arg, char *a2); +char *UNKCALL BNetGW_10002C23(_DWORD *arg); +int UNKCALL BNetGW_10002C51(_DWORD *arg); +int UNKCALL BNetGW_10002DBF(_DWORD *arg); +char *__stdcall BNetGW_10002DEB(char *a1, unsigned int a2); +char *__stdcall BNetGW_10002E0B(char *a1, unsigned int a2); + + +void __cdecl Connect_FreeConnectData(); +BOOL __cdecl Connect_LoadGFXAndStuff(); +BOOL __stdcall UiArtCallback(int game_type, unsigned int art_code, PALETTEENTRY *pPalette, void *pBuffer, DWORD dwBuffersize, DWORD *pdwWidth, DWORD *pdwHeight, DWORD *pdwBpp); +void __cdecl j_Connect_cpp_init(); +void __cdecl Connect_cpp_init(); +BOOL __stdcall UiGetDataCallback(int game_type, int data_code, void *a3, int a4, int a5); +BOOL __stdcall UiSoundCallback(int a1, int type, int a3); +BOOL __stdcall UiAuthCallback(int a1, char *a2, char *a3, char a4, char *a5, LPSTR lpBuffer, int cchBufferMax); +BOOL __stdcall UiDrawDescCallback(int arg0, COLORREF color, LPCSTR lpString, char *a4, int a5, UINT align, time_t a7, HDC *a8); +BOOL __stdcall UiCategoryCallback(int a1, int a2, int a3, int a4, int a5, _DWORD *a6, _DWORD *a7); +int __fastcall Connect_GetRankFromLevel(char *str); +BOOL __fastcall Connect_DiffFromString(char *str, _gamedata *gamedata, int a3, int a4); +void __fastcall Connect_SetDiffString(_gamedata *gamedata, const char *str1, char *str2, char *str3, int size); +BOOL __fastcall Connect_GetHeroInfoConc(const char *a1, _uiheroinfo *pInfo); +void __fastcall Connect_MakeDescString(_uiheroinfo *a1, char *name, size_t size); +void __stdcall UiCreateGameCriteria(_uiheroinfo *pInfo, char *str); +BOOL __stdcall UiCreatePlayerDescription(_uiheroinfo *info, int mode, char *desc); +void __stdcall UiSetupPlayerInfo(char *infostr, _uiheroinfo *pInfo, int type); +void __fastcall Connect_CopyPlrDescStrings(char *str1, int size1, char *str2, int size2); + + +BOOL __stdcall UiCopyProtError(int *pdwResult); +LRESULT __stdcall CopyProt_WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); +void __cdecl CopyProt_FreeCopyResrcs(); +BOOL __fastcall CopyProt_LoadCopyStuff(HWND hWnd, int a2); +void __fastcall CopyProt_EndCopyDlg(HWND hWnd, int a2); +void __cdecl j_CopyProt_cpp_init(); +void __cdecl CopyProt_cpp_init(); + + +void __cdecl j_cr8game_cpp_init(); +void __cdecl cr8game_cpp_init(); +BOOL __fastcall cr8game_GetSnetCreaGame(HWND hWnd); +BOOL __stdcall UiCreateGameCallback(int a1, int a2, int a3, int a4, int a5, int a6); +LRESULT __stdcall cr8game_WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); +void __cdecl cr8game_FreeCreaStuff(); +BOOL __fastcall cr8game_LoadCreaGFX(HWND hWnd); +void __fastcall cr8game_FreeMainMem(HWND hWnd); +void __fastcall cr8game_AllocMainMem(HWND hWnd); +void __fastcall cr8game_DoAROP3Blit(HWND hWnd, int frame, int size); +void __fastcall cr8game_SendMessageF5(HWND hWnd); +void __fastcall cr8game_BlitCr8Dialog(HWND hWnd, int a2); +void __fastcall cr8game_SetWindowStr(HWND hWnd, int dlgitem, int a3); +int __fastcall cr8game_CheckValidGameName(char *name); +HFONT __fastcall cr8game_GetCr8Object(HWND hWnd); + + +void __fastcall CreaDung_SetDelSpin(int a1); +void __cdecl j_CreaDung_cpp_init(); +void __cdecl CreaDung_cpp_init(); +LRESULT __stdcall CreaDung_WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); +void __fastcall CreaDung_ParseDungProcs(HWND hWnd, int dlg); +void __fastcall CreaDung_FreeDungProcs(HWND hWnd); +void __fastcall CreaDung_LoadDungGFX(HWND hWnd); +void __fastcall CreaDung_PlaySndAndKill(HWND hWnd, int a2); +void __fastcall CreaDung_DoAllPlaySnd(HWND hWnd); +void __fastcall CreaDung_DoSnetCreaGame(HWND hWnd); +void __fastcall CreaDung_CheckDlgForSnd(HWND hWnd, int a2, int a3); +BOOL __fastcall CreaDung_SelDungDiff(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8); + + +BOOL __stdcall UiGetDefaultStats(int pclass, _uidefaultstats *pStats); +void __cdecl j_CreaStat_cpp_init(); +void __cdecl CreaStat_cpp_init(); + + +void __cdecl j_credits_cpp_init(); +void __cdecl credits_cpp_init(); +BOOL __stdcall UiCreditsDialog(int a1); +LRESULT __stdcall credits_WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); +void __fastcall credits_FreeCreditResrc(HWND hWnd); +void __fastcall credits_LoadImgCreditTxt(HWND hWnd, LPARAM lParam); +void __fastcall credits_CalcPosROP3(HWND hWnd); +void __fastcall credits_PrintCredLines(HWND hWnd); +int __fastcall credits_GetCredLineBreak(char *str); +char *__fastcall credits_GetAdjustText(char *str, int len); + + +void __fastcall DiabEdit_DoPaintBMP(HWND hWnd); +void __cdecl j_DiabEdit_cpp_init(); +void __cdecl DiabEdit_cpp_init(); +void __cdecl DiabEdit_SetupWindow(); +LRESULT __stdcall DiabEdit_WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); +void __fastcall DiabEdit_SendWndCommand(HWND hWnd, WORD a2); +void __fastcall DiabEdit_GetCursorProp(HWND hWnd); +void __fastcall DiabEdit_RestrictAndLimit(HWND hWnd, WPARAM wParam, LPARAM lParam); +void __fastcall DiabEdit_SetTextAndProp(HWND hWnd, WPARAM wParam, LPARAM lParam); +void __fastcall DiabEdit_SetRestrictString(HWND hWnd, LPARAM lParam); +void __fastcall DiabEdit_SetRestrictTimer(HWND hWnd); +void __fastcall DiabEdit_RemoveAllProps(HWND hWnd); + + +int __cdecl DiabloUI_GetSpawned(); +void __stdcall UiOnPaint(int a1); +void __stdcall UiSetBackgroundBitmap(int a1, PALETTEENTRY *a2, int a3, int a4, int a5); +void __stdcall UiSetSpawned(BOOL bSpawned); +void __stdcall UiInitialize(); +void __stdcall UiDestroy(); +void __stdcall UiAppActivate(BOOL bActive); +BOOL __stdcall DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved); +void __cdecl j_DiabloUI_cpp_init(); +void __cdecl DiabloUI_cpp_init(); + + +signed int DirLink_10005CFA(); +BOOL __fastcall DirLink_10005D05(int a1, int a2, int a3, _DWORD *a4, int a5, int a6); +int __stdcall DirLink_10005D63(HWND hWnd, UINT Msg, WPARAM wParam, unsigned int lParam); +int __fastcall DirLink_10005EB2(HWND hDlg, int a2); +int UNKCALL DirLink_10005F1F(HWND hDlg); // idb +int UNKCALL DirLink_10005F7B(HWND hWnd); // idb +int __fastcall DirLink_10006047(int a1, int a2); +void UNKCALL DirLink_10006073(void *arg); +HWND UNKCALL DirLink_100060D1(HWND arg); +int UNKCALL DirLink_10006141(void *arg); +int UNKCALL DirLink_100061E1(void *arg); +int UNKCALL DirLink_100062BF(void *arg, int a2, char *a3, char *a4); +signed int __stdcall DirLink_1000632B(int a1, char *a2, char *a3); +HWND __fastcall DirLink_10006359(HWND hWnd, int a2, int height); + + +BOOL __stdcall UiBetaDisclaimer(int a1); +LRESULT __stdcall disclaim_WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); +void __fastcall disclaim_DelDisclaimProcs(HWND hWnd); +void __fastcall disclaim_LoadDisclaimGFX(HWND hWnd); +void __fastcall disclaim_FadeFromDisclaim(HWND hWnd); +void __cdecl j_disclaim_cpp_init(); +void __cdecl disclaim_cpp_init(); + + +void __cdecl j_Doom_cpp_init(); +void __cdecl Doom_cpp_init(); +void __fastcall Doom_ParseWndProcs(HWND hWnd, int *msgtbl, int a3, int a4); +void __fastcall Doom_GetSetWndText(HWND hWnd, int msg, int nFont, int a4); +void __fastcall Doom_PrintStrWithSpin(HWND hWnd, BOOL a2); +void __fastcall Doom_AllocAndSetBMP(HWND hWnd, int a2, int bmp_flags); /* check args, __stdcall? */ +void __fastcall Doom_GetWindowROP3(HWND hWnd1, HWND hWnd2); +void __fastcall Doom_ParseWndProc2(HWND hWnd, int *msgtbl, int a3, int a4); +void __fastcall Doom_GetSetWndTxt2(HWND hWnd, int msg, int nFont, int a4); +void __fastcall Doom_ParseWndProc3(HWND hWnd, int *msgtbl, int a3); +void __fastcall Doom_GetSetWndTxt3(HWND hWnd, int msg, int nFont); +void __fastcall Doom_PrintStrWithSpn2(HWND hWnd, int justify_type); +void __fastcall Doom_ParseWndProc4(HWND hWnd, int *msgtbl, int a3); +void __fastcall Doom_GetSetWndTxt4(HWND hWnd, int msg, int nFont); +void __fastcall Doom_ParseWndProc5(HWND hWnd, int *msgtbl, int a3); +void __fastcall Doom_GetSetWndTxt5(HWND hWnd, int msg, int nFont); +void __fastcall Doom_PrintTextMsg403(HWND hWnd); +void __fastcall Doom_ParseWndProc6(HWND hWnd, int *msgtbl, int a3); +void __fastcall Doom_GetSetWndTxt6(HWND hWnd, int msg, int nFont); +void __fastcall Doom_DeleteFreeProcs(HWND hWnd, int *msgtbl); + + +int __stdcall EntDial_10006C96(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam); // idb +HWND UNKCALL EntDial_10006D78(HWND hDlg); +HWND USERCALL EntDial_10006DB8(HWND hWnd, int a2); +int __fastcall EntDial_10006EA7(HWND hDlg, int a2); +void __fastcall EntDial_10006EE8(HWND hWnd, unsigned int a2, int a3); +int __fastcall EntDial_10006F16(HWND hDlg, int, int); // idb +signed int EntDial_10006F71(); + + +LRESULT __stdcall EntName_WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); +void __fastcall EntName_DelEntNameMsgs(HWND hWnd); +void __fastcall EntName_LoadFocusChkName(HWND hWnd); +void __fastcall EntName_SetCharName(HWND hWnd, int a2); +void __fastcall EntName_GetMessageName(HWND hWnd, unsigned int a2, int a3); +void __cdecl j_EntName_cpp_init(); +void __cdecl EntName_cpp_init(); + + +void __fastcall Fade_ApplyPaletteRange(int range1, int range2); +void __fastcall Fade_UpdatePaletteRange(int range); +BOOL __cdecl Fade_CheckRange5(); +void __cdecl Fade_Range5SetZero(); +void __fastcall Fade_NoInputAndArt(HWND hWnd, BOOL bShowCurs); +void __fastcall Fade_SetInputWindow(HWND hWnd); +void __fastcall Fade_SetFadeTimer(int nTime); +void __stdcall Fade_TimerFunctionDlg(int a1, int a2, int a3, int a4); +void __cdecl j_Fade_cpp_init(); +void __cdecl Fade_cpp_init(); + + +void __fastcall Focus_CheckPlayMove(LPARAM lParam); +int __cdecl Focus_GetSpinWidthOrZero(); +void __fastcall Focus_BlitSpinner(HWND hWnd1, HWND hWnd2); +void __fastcall Focus_CenterSpinFromSide(HWND hWnd); +void __fastcall Focus_GetAndBlitSpin(HWND hWnd, LPARAM lParam); +BOOL __fastcall Focus_DoBlitSpinIncFrame(HWND hWnd1, HWND hWnd2); +void __cdecl Focus_DeleteSpinners(); +void __cdecl Focus_ResetSpinToZero(); +void __cdecl j_Focus_cpp_init(); +void __cdecl Focus_cpp_init(); +void __fastcall Focus_LoadSpinner(const char *pszFileName); +void __fastcall Focus_SetFocusTimer(HWND hWnd, const char *pszFileName); +void __stdcall Focus_SetFocusAndBlit(int hWnd, int a2, int a3, int a4); +void __fastcall Focus_KillFocusTimer(HWND hWnd); + + +void __cdecl local_InitUiPalette(); +void __cdecl local_DelUiPalette(); +tagPALETTEENTRY *__fastcall local_GetArtPalEntry(int entry); +void __fastcall local_ClearPalette(PALETTEENTRY *pPal); +void __cdecl local_ClearSurface(); +BOOL __fastcall local_LoadArtImage(const char *pszFileName, BYTE **pBuffer, DWORD *pdwSize); +BOOL __fastcall local_LoadArtWithPal(HWND hWnd, int a2, char *src, int mask, int flags, const char *pszFileName, BYTE **pBuffer, DWORD *pdwSize, BOOL a9); +void __fastcall local_AdjustRectSize(tagRECT *pRect, int a2, int a3); +BOOL __fastcall local_SetStaticBmp(HWND hWnd, int nIDDlgItem, BYTE *pBuffer, DWORD *pdwSize); +void __cdecl j_local_cpp_init(); +void __cdecl local_cpp_init(); +BOOL __fastcall local_SetButtonBmp(HWND hWnd, int flags, int a7, void *pBuffer, DWORD *pdwSize); +void __fastcall local_FitButtonDlg(HWND hWnd, int *a2, void *pBuffer, DWORD *pdwSize); +void __fastcall local_SetWhiteText(HDC hdc); +BOOL __fastcall local_GetBottomRect(HWND hWnd1, HWND hWnd2, int width, int height); +void __fastcall local_DlgDoPaint(HWND hWnd); +void __fastcall local_DoUiWndProc(HWND hWnd, DWORD *pdwMsgTbl); +LRESULT __stdcall local_PostUiWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); +void __fastcall local_DoUiWndProc2(HWND hWnd, DWORD *pdwMsgTbl); +LRESULT __stdcall local_PostUiWndProc2(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); +BOOL __fastcall local_DisableKeyWaitMouse(HWND hWnd); +DWORD *__cdecl local_AllocWndLongData(); +void __fastcall local_FreeMemPtr(void **p); +void __fastcall local_SetWndLongStr(int WndLongData, const char *pszStr); +void __cdecl local_LoadArtCursor(); +void __cdecl local_InitArtCursor(); +void __cdecl local_FreeArtCursor(); +void __cdecl local_SetCursorArt(); +void __cdecl local_SetCursorDefault(); +void __fastcall local_SetDiabloCursor(HWND hWnd); + + +void __cdecl j_MainMenu_cpp_init(); +void __cdecl MainMenu_cpp_init(); +BOOL __stdcall UiMainMenuDialog(char *name, int *pdwResult, void (__stdcall *fnSound)(const char *file), int a4); +LRESULT __stdcall MainMenu_WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); +void __fastcall MainMenu_KillAndFreeMenu(HWND hWnd); +void __fastcall MainMenu_SetMenuTimer(HWND hWnd); +void __fastcall MainMenu_LoadMenuGFX(HWND hWnd); +void __fastcall MainMenu_DoOptions(HWND hWnd, int option, int PlaySelect); +BOOL __cdecl MainMenu_CheckEnoughMemory(); +void __fastcall MainMenu_CheckWParamFocus(HWND hWnd, WPARAM wParam); + + +int Modem_1000855D(); +HWND __fastcall Modem_10008563(HWND hDlg, const char *edx0, int a2); +int __stdcall Modem_100085D8(int, char *, char *); // idb +BOOL Modem_10008606(); +char *Modem_1000863D(); +signed int Modem_10008648(); +int Modem_10008653(); +int Modem_10008659(); +int UNKCALL Modem_1000865F(char *); // idb +BOOL __fastcall Modem_10008680(int a1, int a2, int a3, _DWORD *a4, int a5, int a6); +int __stdcall Modem_100086DE(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); // idb +void **UNKCALL Modem_1000879E(HWND hDlg); +BOOL UNKCALL Modem_100087DB(HWND hWnd); +int Modem_10008888(); +int UNKCALL Modem_100088DB(HWND hWnd); // idb +int UNKCALL Modem_1000893D(HWND hWnd); // idb +int __fastcall Modem_10008A38(HWND hWnd, int); // idb +void __cdecl Modem_10008B42(char *a1); +int UNKCALL Modem_10008BB7(HWND hWnd); // idb +int UNKCALL Modem_10008BFE(HWND hWnd); // idb + + +int __stdcall ModmStat_10008C62(char *, int, int, int, int); // idb +int UNKCALL ModmStat_10008C87(void *arg); +int __stdcall ModmStat_10008CA0(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); // idb +int UNKCALL ModmStat_10008DB3(HWND hDlg); // idb +BOOL UNKCALL ModmStat_10008DE4(HWND hWnd); +int __fastcall ModmStat_10008E89(int a1, int a2); +void UNKCALL ModmStat_10008EBF(HWND hDlg); +signed int ModmStat_10008F26(); + + +BOOL __fastcall OkCancel_DrawString(HWND hWnd, char *str); +void __cdecl j_OkCancel_cpp_init(); +void __cdecl OkCancel_cpp_init(); +LRESULT __stdcall OkCancel_WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); +void __fastcall OkCancel_FreeDlgBmp(HWND hWnd); +BOOL __fastcall OkCancel_LoadOkCancGFX(HWND hWnd, DWORD *lParam); +void __fastcall OkCancel_PlaySndEndDlg(HWND hWnd, int a2); +void __fastcall OkCancel_DoOkDialog(HWND hWnd, char *str, int a3); +void __stdcall UiMessageBoxCallback(HWND hWnd, char *lpText, LPCSTR lpCaption, UINT uType); + + +signed int Progress_10009480(); +//BOOL __stdcall UiProgressDialog(int a1, int a2, BOOL a3, int (*a4)(void), int a5); +int __stdcall Progress_100094F4(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); // idb +void *Progress_100095EC(); +BOOL __fastcall Progress_10009675(HWND hWnd, const CHAR *edx0); +BOOL __fastcall Progress_10009805(HWND hWnd, int a2); +void Progress_100098B0(); +void UNKCALL Progress_100098C5(HWND hWnd); +BOOL UNKCALL Progress_1000991C(HWND hWnd); + + +void __cdecl j_Sbar_cpp_init(); +void __cdecl Sbar_cpp_init(); +BOOL __fastcall Sbar_CheckIfNextHero(HWND hWnd); +int __fastcall Sbar_NumScrollLines(HWND hWnd, int width, int height); +void __fastcall Sbar_DrawScrollBar(HWND hWnd, int nIDDlgItem, int width, int height); +void __fastcall Sbar_LoadScrBarGFX(HWND hWnd, int nIDDlgItem); +void __cdecl j_Sbar_cpp_init2(); +void __cdecl Sbar_cpp_init2(); +void __fastcall Sbar_FreeScrollBar(HWND hWnd, int nIDDlgItem); + + +LRESULT __stdcall SelClass_WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); +void __fastcall SelClass_FreeClassMsgTbl(HWND hWnd); +void __fastcall SelClass_LoadClassFocus(HWND hWnd); +void __fastcall SelClass_SetDefaultStats(HWND hWnd, int a2); +void __fastcall SelClass_CheckClassSpawn(HWND hWnd, int a2); +void __cdecl j_SelClass_cpp_init(); +void __cdecl SelClass_cpp_init(); + + +void *SelConn_1000A082(); +signed int SelConn_1000A09B(); +int __stdcall SelConn_1000A0A6(HWND hWnd, UINT Msg, WPARAM wParam, unsigned int lParam); +HWND __fastcall SelConn_1000A226(HWND hDlg, int nIDDlgItem); +HWND UNKCALL SelConn_1000A3E2(HWND hDlg); +int SelConn_1000A3FF(); +void UNKCALL SelConn_1000A43A(HWND hDlg); +BOOL __fastcall SelConn_1000A4B9(_DWORD *a1); +BOOL UNKCALL SelConn_1000A4CD(void *location); +HWND UNKCALL SelConn_1000A4E4(HWND hWnd, char *a2, int a3); +signed int __stdcall SelConn_1000A5F3(int a1, char *a2, char *a3, int a4); +int __fastcall SelConn_1000A670(HWND a1, const char *a2); +void UNKCALL SelConn_1000A6EC(HWND hDlg); +LRESULT __stdcall SelConn_1000A73E(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); +HWND UNKCALL SelConn_1000A866(HWND hWnd); +HWND UNKCALL SelConn_1000A8D7(HWND hWnd); +HWND UNKCALL SelConn_1000A948(HWND hWnd); +int UNKCALL SelConn_1000A9F3(HWND hWnd); // idb +_DWORD *__fastcall SelConn_1000AA28(int a1); +HWND UNKCALL SelConn_1000AA3B(HWND hWnd); +HWND UNKCALL SelConn_1000AAEB(HWND hWnd); +HWND UNKCALL SelConn_1000AB83(HWND hWnd); +int __fastcall SelConn_1000AC07(int a1, int a2); +int UNKCALL SelConn_1000AC30(HWND arg); +int UNKCALL SelConn_1000AC9E(HWND hWnd); // idb +int UNKCALL SelConn_1000ADA8(HWND hWnd); // idb +BOOL UNKCALL SelConn_1000ADD0(HWND hWnd); +int __fastcall SelConn_1000AE19(int a1, UINT a2); +HWND __fastcall SelConn_1000AE59(HWND hWnd, int a2, int height); +//signed int __stdcall UiSelectProvider(int a1, int a2, int a3, int a4, char *a5, int *a6); + + +int UNKCALL SelDial_1000B011(char *arg); +signed int SelDial_1000B0C4(); +int __stdcall SelDial_1000B0CF(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); // idb +HWND __fastcall SelDial_1000B1FB(HWND hWnd, int a2); +HWND UNKCALL SelDial_1000B29A(HWND hDlg); +int __fastcall SelDial_1000B2D8(int a1, int a2); +HWND UNKCALL SelDial_1000B354(HWND hDlg); +HWND UNKCALL SelDial_1000B3D8(HWND hDlg); +HWND UNKCALL SelDial_1000B44C(HWND hDlg); +HWND USERCALL SelDial_1000B483(HWND hWnd, int a2); +int SelDial_1000B5D9(); +int __fastcall SelDial_1000B614(HWND hWnd, int, int); // idb + + +void UNKCALL SelGame_1000B66A(void *arg); +int SelGame_1000B671(); +void UNKCALL SelGame_1000B677(void *arg); +int SelGame_1000B67E(); +//int __stdcall UiSelectGame(int, int, void *, int, int, int); // idb +signed int SelGame_1000B795(); + + +_uiheroinfo *__cdecl SelHero_GetCurrentHeroInfo(); +int __cdecl SelHero_GetNumHeroesLeft(); +void __fastcall SelHero_SetHeroDifficulty(int diff); +char *__cdecl SelHero_GetHeroNameStr(); +_uiheroinfo *__cdecl SelHero_AllocHeroInfo(); +int __cdecl SelHero_GetHeroIsGood(); +int __fastcall SelHero_SetClassStats(int heroclass, _uidefaultstats *pStats); +void __cdecl j_SelHero_cpp_init(); +void __cdecl SelHero_cpp_init(); +void __fastcall SelHero_SetStaticBMP(HWND hWnd, int adjust_size); +void __fastcall SelHero_PrintHeroInfo(HWND hWnd, _uiheroinfo *pInfo); +void __fastcall SelHero_SetStringWithMsg(HWND hWnd, const char *str); +BOOL __fastcall SelHero_IsNameReserved(char *name); +void __fastcall SelHero_SetLastNamePos(char *name); +BOOL __fastcall SelHero_NameHasChar(char *name, char *illegalchrs); +BOOL __fastcall UiValidPlayerName(char *name); +BOOL __stdcall UiSelHeroMultDialog(BOOL (__stdcall *fninfo)(BOOL (__stdcall *fninfofunc)(_uiheroinfo *)), BOOL (__stdcall *fncreate)(_uiheroinfo *), BOOL (__stdcall *fnremove)(_uiheroinfo *), BOOL (__stdcall *fnstats)(int, _uidefaultstats *), int *dlgresult, int *a6, char *name); +LRESULT __stdcall SelHero_WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); +void __fastcall SelHero_DoStuffWithStrings(HWND hWnd); +_uiheroinfo *__fastcall SelHero_GetNextHeroFromStr(_uiheroinfo *pInfo, char *name); +void __fastcall SelHero_FreeSomeMemory(void *ptr); +_uiheroinfo *__fastcall SelHero_GetHeroSlotFromName(_uiheroinfo *pInfo, const char *name); +void __fastcall SelHero_DoHeroSelList(HWND hWnd); +void __fastcall SelHero_DoHeroSelClass(HWND hWnd); +void __fastcall SelHero_DoEnterName(HWND hWnd); +BOOL __fastcall SelHero_CreateHero(HWND hWnd, char *name); +void __fastcall SelHero_DoSelLoad(HWND hWnd); +void __fastcall SelHero_DoSelDiff(HWND hWnd); +void __fastcall SelHero_DeleteAndFree(HWND hWnd); +void __fastcall SelHero_FreeAllHeroes(_uiheroinfo *pInfo); +void __fastcall SelHero_DoHeroEndFade(HWND hWnd, int a2); +void __fastcall SelHero_LoadHeroGFX(HWND hWnd); +void __fastcall SelHero_SelectHeroRegion(HWND hWnd); +BOOL __stdcall SelHero_GetHeroInfo(_uiheroinfo *pInfo); +BOOL __stdcall UiSelHeroSingDialog(BOOL (__stdcall *fninfo)(BOOL (__stdcall *fninfofunc)(_uiheroinfo *)), BOOL (__stdcall *fncreate)(_uiheroinfo *), BOOL (__stdcall *fnremove)(_uiheroinfo *), BOOL (__stdcall *fnstats)(int, _uidefaultstats *), int *dlgresult, char *name, int *difficulty); + + +void *SelIPX_1000C610(); +signed int SelIPX_1000C629(); +BOOL __fastcall SelIPX_1000C634(int a1, int a2, int a3, _DWORD *a4, int a5, int a6); +int __stdcall SelIPX_1000C692(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); // idb +LONG __fastcall SelIPX_1000C818(HWND hDlg, int nIDDlgItem); +HWND UNKCALL SelIPX_1000C982(HWND hDlg); +int SelIPX_1000C99F(); +const char *UNKCALL SelIPX_1000C9DA(HWND hDlg); +void __fastcall SelIPX_1000CA64(_DWORD *a1); +_DWORD **__fastcall SelIPX_1000CA71(_DWORD *a1); +BOOL UNKCALL SelIPX_1000CAC1(void *location); +void *__stdcall SelIPX_1000CAD5(int a1, char *a2, char *a3); +_DWORD *__fastcall SelIPX_1000CB50(_DWORD *a1, _DWORD *a2); +_DWORD *__fastcall SelIPX_1000CB73(_DWORD *a1, int a2); +int __fastcall SelIPX_1000CB83(HWND a1, const char *a2); +int UNKCALL SelIPX_1000CC41(HWND hDlg); // idb +BOOL __fastcall SelIPX_1000CCC5(_DWORD *a1); +HWND UNKCALL SelIPX_1000CCD9(HWND hWnd); +HWND UNKCALL SelIPX_1000CD4A(HWND hWnd); +void UNKCALL SelIPX_1000CEE6(HWND hDlg); +LRESULT __stdcall SelIPX_1000CF38(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); +HWND UNKCALL SelIPX_1000D070(HWND hWnd); +HWND UNKCALL SelIPX_1000D0E1(HWND hWnd); +int UNKCALL SelIPX_1000D18C(HWND hWnd); // idb +_DWORD *__fastcall SelIPX_1000D1C1(int a1); +HWND UNKCALL SelIPX_1000D1D4(HWND hWnd); +HWND UNKCALL SelIPX_1000D284(HWND hWnd); +HWND UNKCALL SelIPX_1000D31C(HWND hWnd); +int __fastcall SelIPX_1000D3A0(int a1, int a2); +HWND USERCALL SelIPX_1000D3C5(HWND hDlg, int a2); +BOOL __fastcall SelIPX_1000D4CA(HWND hDlg, int a2); +char *UNKCALL SelIPX_1000D520(char *arg); +const char *__fastcall SelIPX_1000D58D(const char *a1, const char *a2); +int __fastcall SelIPX_1000D5B0(int a1, int a2); +HWND __fastcall SelIPX_1000D696(HWND hDlg, int a2, int height); + + +void __cdecl j_SelList_cpp_init(); +void __cdecl SelList_cpp_init(); +LRESULT __stdcall SelList_WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); +void __fastcall SelList_DeleteFreeProcs(HWND hWnd); +void __fastcall SelList_GetHeroStats(HWND hWnd, int nIDDlgItem); +void __fastcall SelList_CountHeroList(HWND hWnd); +int __fastcall SelList_GetNextHeroLong(HWND hWnd); +void __fastcall SelList_LoadFocus16(HWND hWnd); +void __fastcall SelList_KillFocus16(HWND hWnd); +void __fastcall SelList_ShowListWindow(HWND hWnd); +void __fastcall SelList_SetHeroDlgLong(HWND hWnd, _uiheroinfo *pInfo); +void __fastcall SelList_DoListOldProc(HWND hWnd); +LRESULT __stdcall SelList_OldListWndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); +void __fastcall SelList_ShiftHeroDlgItems(HWND hWnd); +void __fastcall SelList_ShiftHeroDlgItm2(HWND hWnd); +void __fastcall SelList_HeroesWithBigDialogs(HWND hWnd); +_uiheroinfo *__fastcall SelList_GetHeroFromNum(int heronum); +void __fastcall SelList_HeroesWithHugeDlg(HWND hWnd); +void __fastcall SelList_HeroDlgWithSound(HWND hWnd); +void __fastcall SelList_HeroDlgWithSnd2(HWND hWnd); +void __fastcall SelList_ChooseDlgFromSize(HWND hWnd, int width, int height); + + +LRESULT __stdcall SelLoad_WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); +void __fastcall SelLoad_DeleteProcsAndSpin(HWND hWnd); +void __fastcall SelLoad_LoadFocusAndMsg(HWND hWnd); +void __fastcall SelLoad_SelectSndLoad(HWND hWnd, int a2); +void __cdecl j_SelLoad_cpp_init(); +void __cdecl SelLoad_cpp_init(); + + +signed int SelModem_1000E42A(); +int __fastcall SelModem_1000E435(void *a1, int a2, int a3, char *a4, char *a5); +char *__stdcall SelModem_1000E497(int a1, char *a2, char *a3); +void *SelModem_1000E4EC(); +_DWORD *__fastcall SelModem_1000E500(int a1, _DWORD *a2); +signed int UNKCALL SelModem_1000E505(void *arg); +signed int SelModem_1000E51E(); +BOOL __fastcall SelModem_1000E553(_DWORD *a1); +BOOL UNKCALL SelModem_1000E567(void *location); +int __fastcall SelModem_1000E57B(int a1, int a2); +signed int SelModem_1000E5CC(); +int __stdcall SelModem_1000E63E(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam); // idb +void UNKCALL SelModem_1000E783(HWND hDlg); +HWND UNKCALL SelModem_1000E7E9(HWND hDlg); +int UNKCALL SelModem_1000E80E(HWND hWnd); // idb +HWND UNKCALL SelModem_1000E843(HWND hWnd); +int __fastcall SelModem_1000E932(HWND a1, const char *a2); +void UNKCALL SelModem_1000E9B2(HWND hDlg); +LRESULT __stdcall SelModem_1000EA04(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); +HWND UNKCALL SelModem_1000EB2C(HWND hWnd); +HWND UNKCALL SelModem_1000EB9D(HWND hWnd); +HWND UNKCALL SelModem_1000EC0E(HWND hWnd); +_DWORD *__fastcall SelModem_1000EC9F(int a1); +HWND UNKCALL SelModem_1000ECB2(HWND hWnd); +HWND UNKCALL SelModem_1000ED3B(HWND hWnd); +HWND UNKCALL SelModem_1000EDBC(HWND hWnd); +int __fastcall SelModem_1000EE29(int a1, int a2); +HWND __fastcall SelModem_1000EE78(HWND hWnd, int a2, int height); + + +void *SelRegn_1000EF42(); +_uiheroinfo *__fastcall SelRegn_SetNextHero(_uiheroinfo *pNext, _uiheroinfo *pCurrent); +signed int SelRegn_1000EF60(); +int __stdcall SelRegn_1000EF6B(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); // idb +HWND __fastcall SelRegn_1000F0D7(HWND hDlg, int nIDDlgItem); +HWND UNKCALL SelRegn_1000F109(HWND hDlg); +int SelRegn_1000F126(); +void UNKCALL SelRegn_1000F161(HWND hDlg); +BOOL __fastcall SelRegn_1000F1D4(_DWORD *a1); +BOOL UNKCALL SelRegn_1000F1E8(void *location); +HWND UNKCALL SelRegn_1000F1FC(HWND hWnd); +signed int SelRegn_1000F2ED(); +int __fastcall SelRegn_1000F346(HWND a1, const char *a2); +void UNKCALL SelRegn_1000F3C2(HWND hDlg); +LRESULT __stdcall SelRegn_1000F414(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); +HWND UNKCALL SelRegn_1000F53C(HWND hWnd); +HWND UNKCALL SelRegn_1000F5AD(HWND hWnd); +HWND UNKCALL SelRegn_1000F61E(HWND hWnd); +int UNKCALL SelRegn_1000F6C9(HWND hWnd); // idb +_DWORD *__fastcall SelRegn_1000F6FE(int a1); +HWND UNKCALL SelRegn_1000F711(HWND hWnd); +HWND UNKCALL SelRegn_1000F7C1(HWND hWnd); +HWND UNKCALL SelRegn_1000F859(HWND hWnd); +signed int UNKCALL SelRegn_1000F8DD(void *arg); +signed int SelRegn_1000F8F6(); +HWND __fastcall SelRegn_1000F929(HWND hWnd, int a2, int height); +//signed int __stdcall UiSelectRegion(_DWORD *a1); + + +int __fastcall SelYesNo_YesNoDialog(HWND hWnd, char *dialogstr, char *hero, int nofocus); /* void */ +LRESULT __stdcall SelYesNo_WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); +void __fastcall SelYesNo_RemoveYNDialog(HWND hWnd); +void __fastcall SelYesNo_LoadSelYN_GFX(HWND hWnd); +void __fastcall SelYesNo_DoSelectYesNo(HWND hWnd, int option); +int __fastcall SelYesNo_SelOkDialog(HWND hWnd, char *dialogstr, char *hero, int nofocus); /* void */ +int __fastcall SelYesNo_SpawnErrDialog(HWND hWnd, int string_rsrc, int is_popup); /* void */ +void __cdecl j_SelYesNo_cpp_init(); +void __cdecl SelYesNo_cpp_init(); + + +void __fastcall Title_BlitTitleBuffer(HWND hWnd); +void __cdecl Title_DeletePhTrans(); +void __fastcall Title_FreeTransMem(HWND hWnd); +void __fastcall Title_SetTitleBMP(HWND hWnd); +void __fastcall Title_LoadTitleImage(HWND hWnd, const char *pszFileName); +void __fastcall Title_LoadImgSetTimer(HWND hWnd, const char *pszFileName); +void __stdcall Title_BlitTitleBufFnc(int hWnd, int a2, int a3, int a4); +void __cdecl j_Title_cpp_init(); +void __cdecl Title_cpp_init(); +void __fastcall Title_KillTitleTimer(HWND hWnd); +BOOL __stdcall UiTitleDialog(int a1); +LRESULT __stdcall Title_MainProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); +void __fastcall Title_KillTimerAndFree(HWND hWnd); +void __fastcall Title_LoadAllTitleImgs(HWND hWnd, int time); +void __fastcall Title_KillAndFadeDlg(HWND hWnd); + + +void __fastcall TitleSnd_SetSoundFunction(void (__stdcall *func)(const char *file)); +void __cdecl TitleSnd_InitSoundFunc(); +void __cdecl TitleSnd_PlayMoveSound(); +void __cdecl TitleSnd_PlaySelectSound(); +void __cdecl j_TitleSnd_cpp_init(); +void __cdecl TitleSnd_cpp_init(); diff --git a/2020_03_31/DiabloUI/artfont.cpp b/2020_03_31/DiabloUI/artfont.cpp new file mode 100644 index 00000000..50e5ab11 --- /dev/null +++ b/2020_03_31/DiabloUI/artfont.cpp @@ -0,0 +1,322 @@ +// ref: 0x10001058 +void __fastcall artfont_SetArtFont(int nFont) +{ + switch ( nFont ) + { + case 0: + sgpCurrFont = &font16g; + break; + case 2: + sgpCurrFont = &font24g; + break; + case 3: + sgpCurrFont = &font24s; + break; + case 4: + sgpCurrFont = &font30g; + break; + case 5: + sgpCurrFont = &font30s; + break; + case 6: + sgpCurrFont = &font42g; + break; + case 7: + sgpCurrFont = &font42y; + break; + default: + sgpCurrFont = &font16s; + break; + } +} + +// ref: 0x10001098 +void __cdecl artfont_InitAllFonts() +{ + font42g.active = 0; + font42y.active = 0; + font30g.active = 0; + font30s.active = 0; + font24g.active = 0; + font24s.active = 0; + font16g.active = 0; + font16s.active = 0; + sgpCurrFont = 0; +} + +// ref: 0x100010C8 +void __cdecl artfont_FreeAllFonts() +{ + artfont_FreeArtFont(&font42g); + artfont_FreeArtFont(&font42y); + artfont_FreeArtFont(&font30g); + artfont_FreeArtFont(&font30s); + artfont_FreeArtFont(&font24g); + artfont_FreeArtFont(&font24s); + artfont_FreeArtFont(&font16g); + artfont_FreeArtFont(&font16s); + sgpCurrFont = 0; +} + +// ref: 0x10001120 +void __fastcall artfont_FreeArtFont(FontStruct *pFont) +{ + HANDLE *v2; // esi + signed int v3; // ebx + + if ( pFont->active ) + { + v2 = pFont->fonttrans; + v3 = 256; + do + { + if ( *v2 ) + { + STransDelete(*v2); + *v2 = 0; + } + ++v2; + --v3; + } + while ( v3 ); + pFont->active = 0; + } +} + +// ref: 0x10001159 +BOOL __cdecl artfont_LoadAllFonts() +{ + artfont_LoadArtFont(&font30g, "ui_art\\font30.bin", "ui_art\\font30g.pcx"); + artfont_LoadArtFont(&font30s, "ui_art\\font30.bin", "ui_art\\font30s.pcx"); + artfont_LoadArtFont(&font24g, "ui_art\\font24.bin", "ui_art\\font24g.pcx"); + artfont_LoadArtFont(&font24s, "ui_art\\font24.bin", "ui_art\\font24s.pcx"); + artfont_LoadArtFont(&font16g, "ui_art\\font16.bin", "ui_art\\font16g.pcx"); + artfont_LoadArtFont(&font16s, "ui_art\\font16.bin", "ui_art\\font16s.pcx"); + artfont_LoadArtFont(&font42g, "ui_art\\font42.bin", "ui_art\\font42g.pcx"); + artfont_LoadArtFont(&font42y, "ui_art\\font42.bin", "ui_art\\font42y.pcx"); + return 1; +} + +// ref: 0x100011FB +void __fastcall artfont_LoadArtFont(FontStruct *pFont, const char *pszBinFile, const char *pszFileName) +{ + LONG v4; // eax + signed int v5; // edi + unsigned char v6; // al + int v7; // ecx + int a5[4]; // [esp+8h] [ebp-20h] + DWORD size[2]; // [esp+18h] [ebp-10h] + BYTE *pBuffer; // [esp+20h] [ebp-8h] + HANDLE phFile; // [esp+24h] [ebp-4h] + HANDLE *a1a; // [esp+30h] [ebp+8h] + + if ( !pFont->active && SFileOpenFile(pszBinFile, &phFile) ) + { + v4 = SFileGetFileSize(phFile, 0); + if ( SFileReadFile(phFile, pFont, v4, 0, 0) ) + { + SFileCloseFile(phFile); + local_LoadArtImage(pszFileName, &pBuffer, size); + memset(pFont->fonttrans, 0, 0x400u); + if ( pBuffer ) + { + v5 = 0; + a1a = pFont->fonttrans; + do + { + v6 = pFont->fontbin[v5 + 2]; + if ( v6 ) + { + v7 = pFont->fontbin[1]; + a5[2] = v6; + a5[1] = v5 * v7; + a5[0] = 0; + a5[3] = v7 + v5 * v7 - 1; + STransCreateI(pBuffer, size[0], size[1], 8, (int)a5, 16777248, a1a); + } + ++a1a; + ++v5; + } + while ( v5 <= 256 ); + pFont->active = 1; + SMemFree(pBuffer, "C:\\Src\\Diablo\\DiabloUI\\artfont.cpp", 206, 0); + } + } + else + { + SFileCloseFile(phFile); + } + } +} + +// ref: 0x100012F6 +int __cdecl artfont_GetFontMaxHeight() +{ + int result; // eax + + if ( sgpCurrFont && sgpCurrFont->active ) + result = sgpCurrFont->fontbin[1]; + else + result = 0; + return result; +} + +// ref: 0x10001310 +int __cdecl artfont_GetFontDefWidth() +{ + int result; // eax + + if ( sgpCurrFont && sgpCurrFont->active ) + result = sgpCurrFont->fontbin[0]; + else + result = 0; + return result; +} + +// ref: 0x10001329 +int __fastcall artfont_GetFontWidth(char *str) +{ + int result; // eax + unsigned char i; // bl + unsigned char v3; // bl + int v4; // esi + + result = 0; + if ( !sgpCurrFont || !sgpCurrFont->active ) + return 0; + for ( i = *str; *str; i = *str ) + { + v3 = sgpCurrFont->fontbin[i + 2]; + if ( v3 ) + v4 = v3; + else + v4 = sgpCurrFont->fontbin[0]; + result += v4; + ++str; + } + return result; +} + +// ref: 0x1000136C +void __cdecl artfont_cpp_init() +{ + artfont_cpp_float = 2139095040; +} +// 10026BB0: using guessed type int artfont_cpp_float; + +// ref: 0x10001377 +int __fastcall artfont_GetFontBreak(char *str) +{ + int result; // eax + unsigned char v2; // dl + unsigned char v3; // dl + + result = 0; + if ( !sgpCurrFont || !sgpCurrFont->active ) + return 0; + while ( 1 ) + { + v3 = *str; + if ( !*str ) + break; + if ( v3 == '\n' ) + break; + if ( v3 == ' ' ) + break; + v2 = sgpCurrFont->fontbin[v3 + 2]; + if ( !v2 ) + break; + result += v2; + ++str; + } + return result; +} + +// ref: 0x100013B3 +void __cdecl artfont_delete_operator(void *ptr) +{ + if ( ptr ) + SMemFree(ptr, "delete", -1, 0); +} + +// ref: 0x100013CD +void __fastcall artfont_PrintFontStr(char *str, DWORD **pSurface, int sx, int sy) +{ + FontStruct *v5; // esi + unsigned char v6; // cl + int v7; // edi + unsigned char v8; // dl + int v9; // edi + DWORD *v10; // ecx + HANDLE hTrans; // [esp+Ch] [ebp-8h] + HANDLE hTransa; // [esp+Ch] [ebp-8h] + + if ( pSurface ) + { + if ( *pSurface ) + { + v5 = sgpCurrFont; + if ( sgpCurrFont ) + { + if ( sgpCurrFont->active ) + { + if ( sx < 0 ) + sx = 0; + if ( sy < 0 ) + sy = 0; + v6 = *str; + if ( *str ) + { + while ( 1 ) + { + hTrans = (HANDLE)(sy + v5->fontbin[1]); + if ( sy + v5->fontbin[1] > (signed int)pSurface[2] ) + return; + if ( v6 == '\n' ) + break; + v7 = v6; + v8 = v5->fontbin[v6 + 2]; + if ( !v8 ) + { + v9 = v5->fontbin[0]; + if ( sx + v9 + artfont_GetFontBreak(++str) < (signed int)pSurface[1] ) + { + sx += v9; + } + else + { + sx = 0; + sy = (int)hTrans; + } + goto LABEL_23; + } + hTransa = v5->fonttrans[v6]; + if ( v5->fonttrans[v6] ) + { + v10 = pSurface[1]; + if ( sx + v8 <= (signed int)v10 ) + { + STransBlt(*pSurface, sx, sy, (int)v10, hTransa); + v5 = sgpCurrFont; + sx += sgpCurrFont->fontbin[v7 + 2]; + goto LABEL_22; + } + sx = 0; + sy += v5->fontbin[1]; + } +LABEL_23: + v6 = *str; + if ( !*str ) + return; + } + sx = 0; + sy += v5->fontbin[1]; +LABEL_22: + ++str; + goto LABEL_23; + } + } + } + } + } +} diff --git a/2020_03_31/DiabloUI/bn_prof.cpp b/2020_03_31/DiabloUI/bn_prof.cpp new file mode 100644 index 00000000..854fd26f --- /dev/null +++ b/2020_03_31/DiabloUI/bn_prof.cpp @@ -0,0 +1,1421 @@ +// ref: 0x100014E8 +signed int bn_prof_100014E8() { return 0; } +/* { + signed int result; // eax + + result = 2139095040; + dword_10029404 = 2139095040; + return result; +} */ +// 10029404: using guessed type int dword_10029404; + +// ref: 0x100014F3 +int __stdcall UiProfileGetString() { return 0; } +//const char *UiProfileGetString() { return 0; } +/* { + return "profile\\sex"; +} */ + +// ref: 0x100014F9 +void __stdcall UiProfileCallback() { return; } +//BOOL __stdcall UiProfileCallback(int a1, int a2, int a3, int a4, LPARAM a5, int a6, int a7, int a8, int (__stdcall *a9)(_DWORD, _DWORD, _DWORD, _DWORD)) { return 0; } +/* { + const char *v9; // eax + int v10; // eax + + lParam = a5; + dword_10029408 = a6; + dword_1002941C = a7; + dword_10029418 = a8; + dword_10029430 = a9; + v9 = "DIALOG_PROFILE"; + if ( !a9 ) + v9 = "DIALOG_STATIC_PROFILE"; + v10 = SDlgDialogBoxParam(hInstance, v9, *(_DWORD *)(a3 + 8), bn_prof_1000155F, 0); + return v10 && v10 != -1; +} */ +// 10010370: using guessed type int __stdcall SDlgDialogBoxParam(_DWORD, _DWORD, _DWORD, _DWORD, _DWORD); +// 10029408: using guessed type int dword_10029408; +// 10029418: using guessed type int dword_10029418; +// 1002941C: using guessed type int dword_1002941C; +// 10029430: using guessed type int (__stdcall *dword_10029430)(_DWORD, _DWORD, _DWORD, _DWORD); + +// ref: 0x1000155F +HGDIOBJ __stdcall bn_prof_1000155F(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) { return 0; } +/* { + HWND v4; // eax + HWND v6; // edi + + if ( Msg <= 0x110 ) + { + switch ( Msg ) + { + case 0x110u: + bn_prof_10001C0E(hWnd); + break; + case 2u: + bn_prof_10001F29(); + break; + case 0x2Bu: + if ( wParam == 1134 ) + { + bn_prof_100018CE((int)hWnd, lParam); + return (HGDIOBJ)1; + } + return (HGDIOBJ)SDlgDefDialogProc(hWnd, Msg, wParam, lParam); + default: + if ( Msg > 0x103 && Msg <= 0x105 ) + { + v4 = (HWND)SDrawGetFrameWindow(); + SendMessageA(v4, Msg, wParam, lParam); + } + return (HGDIOBJ)SDlgDefDialogProc(hWnd, Msg, wParam, lParam); + } + return 0; + } + if ( Msg == 273 ) + { + if ( (unsigned short)wParam == 1 ) + { + EnableWindow((HWND)lParam, 0); + TitleSnd_10010315(); + if ( dword_10029430 ) + bn_prof_100016DD(hWnd); + SDlgEndDialog(hWnd, 1); + } + else if ( (unsigned short)wParam == 2 ) + { + EnableWindow((HWND)lParam, 0); + TitleSnd_10010315(); + SDlgEndDialog(hWnd, 0); + } + else + { + if ( (unsigned short)wParam != 1134 || HIWORD(wParam) || dword_10029430 ) + return (HGDIOBJ)SDlgDefDialogProc(hWnd, Msg, wParam, lParam); + bn_prof_10001A10(hWnd, (HWND)lParam); + } + return 0; + } + if ( Msg == 274 ) + { + if ( wParam != 61536 ) + return (HGDIOBJ)SDlgDefDialogProc(hWnd, Msg, wParam, lParam); + v6 = GetParent(hWnd); + SDlgEndDialog(hWnd, 0); + PostMessageA(v6, 0x112u, 0xF060u, lParam); + return 0; + } + if ( Msg != 312 || GetWindowLongA((HWND)lParam, -12) != 1124 ) + return (HGDIOBJ)SDlgDefDialogProc(hWnd, Msg, wParam, lParam); + SetTextColor((HDC)wParam, 0xFFFFu); + return GetStockObject(5); +} */ +// 10010376: using guessed type int __stdcall SDlgEndDialog(_DWORD, _DWORD); +// 1001037C: using guessed type int __stdcall SDlgDefDialogProc(_DWORD, _DWORD, _DWORD, _DWORD); +// 10010382: using guessed type _DWORD __stdcall SDrawGetFrameWindow(); +// 10029430: using guessed type int (__stdcall *dword_10029430)(_DWORD, _DWORD, _DWORD, _DWORD); + +// ref: 0x100016DD +void UNKCALL bn_prof_100016DD(HWND arg) { return; } +/* { + int v1; // ebx + int v2; // eax + const char **v3; // edi + int v4; // eax + int v5; // ebx + int *v6; // ebx + LRESULT v7; // eax + LPARAM v8; // eax + size_t v9; // eax + char *v10; // eax + int v11; // ebx + _DWORD *v12; // edi + int v13; // eax + int v14; // ebx + size_t v15; // [esp+4h] [ebp-28h] + char *v16; // [esp+8h] [ebp-24h] + HWND hDlg; // [esp+Ch] [ebp-20h] + int v18; // [esp+10h] [ebp-1Ch] + int v19; // [esp+14h] [ebp-18h] + int v20; // [esp+18h] [ebp-14h] + char *v21; // [esp+1Ch] [ebp-10h] + int v22; // [esp+20h] [ebp-Ch] + int v23; // [esp+24h] [ebp-8h] + char *v24; // [esp+28h] [ebp-4h] + size_t v25; // [esp+28h] [ebp-4h] + + v1 = 0; + hDlg = arg; + if ( dword_10029430 ) + { + v2 = SMemAlloc(4 * dword_10029408, "C:\\Src\\Diablo\\DiabloUI\\bn_prof.cpp", 193, 0); + v3 = (const char **)v2; + v22 = v2; + v4 = SMemAlloc(4 * dword_10029408, "C:\\Src\\Diablo\\DiabloUI\\bn_prof.cpp", 195, 0); + v18 = v4; + v20 = 0; + v23 = 0; + if ( dword_10029408 > 0 ) + { + v19 = v4 - (_DWORD)v3; + do + { + v5 = 0; + v24 = byte_1001F37C; + v16 = *(char **)(4 * v23 + dword_10029418); + v21 = *(char **)(4 * v23 + dword_1002941C); + while ( 1 ) + { + if ( !_strcmpi(v21, *((const char **)v24 - 1)) ) + { + v15 = strlen(v16); + if ( *v24 & 1 ) + break; + } + v24 += 16; + ++v5; + if ( (signed int)v24 >= (signed int)&unk_1001F3BC ) + goto LABEL_13; + } + v6 = &dword_1001F380[4 * v5]; + v7 = SendDlgItemMessageA(hDlg, *v6, 0xEu, 0, 0); + v25 = v7; + v8 = SMemAlloc(v7 + 1, "C:\\Src\\Diablo\\DiabloUI\\bn_prof.cpp", 218, 0); + *v3 = (const char *)v8; + SendDlgItemMessageA(hDlg, *v6, 0xDu, v25 + 1, v8); + (*v3)[v25] = 0; + if ( v25 == v15 && !_strnicmp(v16, *v3, v25) ) + { + SMemFree(*v3, "C:\\Src\\Diablo\\DiabloUI\\bn_prof.cpp", 236, 0); + } + else + { + v9 = strlen(v21); + v10 = (char *)SMemAlloc(v9 + 1, "C:\\Src\\Diablo\\DiabloUI\\bn_prof.cpp", 232, 0); + *(const char **)((char *)v3 + v19) = v10; + strcpy(v10, v21); + ++v20; + ++v3; + } +LABEL_13: + ++v23; + } + while ( v23 < dword_10029408 ); + v1 = v20; + } + dword_10029430(&byte_10029448, v1, v18, v22); + v11 = v1 - 1; + if ( v11 >= 0 ) + { + v12 = (_DWORD *)(v22 + 4 * v11); + v13 = v18 - v22; + v14 = v11 + 1; + while ( 1 ) + { + SMemFree(*(_DWORD *)((char *)v12 + v13), "C:\\Src\\Diablo\\DiabloUI\\bn_prof.cpp", 250, 0); + SMemFree(*v12, "C:\\Src\\Diablo\\DiabloUI\\bn_prof.cpp", 251, 0); + --v12; + if ( !--v14 ) + break; + v13 = v18 - v22; + } + } + SMemFree(v18, "C:\\Src\\Diablo\\DiabloUI\\bn_prof.cpp", 253, 0); + SMemFree(v22, "C:\\Src\\Diablo\\DiabloUI\\bn_prof.cpp", 254, 0); + } +} */ +// 10010340: using guessed type int __stdcall SMemFree(_DWORD, _DWORD, _DWORD, _DWORD); +// 10010364: using guessed type int __stdcall SMemAlloc(_DWORD, _DWORD, _DWORD, _DWORD); +// 1001F380: using guessed type int dword_1001F380[]; +// 10029408: using guessed type int dword_10029408; +// 10029418: using guessed type int dword_10029418; +// 1002941C: using guessed type int dword_1002941C; +// 10029430: using guessed type int (__stdcall *dword_10029430)(_DWORD, _DWORD, _DWORD, _DWORD); + +// ref: 0x100018CE +void __fastcall bn_prof_100018CE(int a1, int a2) { return; } +/* { + int v2; // esi + LRESULT v3; // eax + WPARAM v4; // edi + char *v5; // ebx + + v2 = a2; + if ( *(_DWORD *)(a2 + 24) && *(_DWORD *)a2 == 5 ) + { + v3 = SendMessageA(*(HWND *)(a2 + 20), 0xEu, 0, 0); + v4 = v3 + 1; + if ( v3 != 0 ) + { + v5 = (char *)SMemAlloc(v3 + 1, "C:\\Src\\Diablo\\DiabloUI\\bn_prof.cpp", 362, 0); + SendMessageA(*(HWND *)(v2 + 20), 0xDu, v4, (LPARAM)v5); + bn_prof_10001938(*(HDC *)(v2 + 24), (_DWORD *)(v2 + 28), v5, 0, 0); + SMemFree(v5, "C:\\Src\\Diablo\\DiabloUI\\bn_prof.cpp", 367, 0); + } + } +} */ +// 10010340: using guessed type int __stdcall SMemFree(_DWORD, _DWORD, _DWORD, _DWORD); +// 10010364: using guessed type int __stdcall SMemAlloc(_DWORD, _DWORD, _DWORD, _DWORD); + +// ref: 0x10001938 +int __fastcall bn_prof_10001938(HDC a1, _DWORD *a2, char *a3, int a4, int a5) { return 0; } +/* { + int result; // eax + char *v6; // edi + char *v7; // eax + char *v8; // esi + char v9; // bl + char *v10; // eax + RECT rc; // [esp+Ch] [ebp-14h] + _DWORD *v12; // [esp+1Ch] [ebp-4h] + char *v13; // [esp+28h] [ebp+8h] + + result = (int)bn_prof_10002410(a1, a2); + v12 = (_DWORD *)result; + if ( result ) + { + v6 = a3; + if ( a3 ) + { + v13 = (char *)(a4 != 0 ? (unsigned int)&rc : 0); + while ( 1 ) + { + v7 = strstr(v6, "http://"); + v8 = v7; + v9 = 0; + if ( v7 ) + { + v9 = *v7; + *v7 = 0; + } + if ( !bn_prof_10002456((int)v12, v6, 1, v13) || !v8 ) + break; + *v8 = v9; + v10 = strpbrk(v8, " \n\r\t"); + v6 = v10; + if ( v10 ) + { + v9 = *v10; + *v10 = 0; + } + if ( !bn_prof_10002456((int)v12, v8, 2, v13) ) + break; + if ( a4 && PtInRect(&rc, *(POINT *)a4) ) + { + if ( a5 ) + *(_DWORD *)a5 = v8; + return 1; + } + if ( !v6 ) + break; + *v6 = v9; + } + } + bn_prof_100026C4(v12); + result = a4 == 0; + } + return result; +} */ + +// ref: 0x10001A10 +int __fastcall bn_prof_10001A10(HWND a1, HWND a2) { return 0; } +/* { + HWND v2; // esi + int result; // eax + WPARAM v4; // esi + HWND v5; // eax + HDC v6; // edi + HWND v7; // eax + struct tagRECT v8; // [esp+Ch] [ebp-3Ch] + struct tagRECT Rect; // [esp+1Ch] [ebp-2Ch] + struct tagPOINT Point; // [esp+2Ch] [ebp-1Ch] + HWND v11; // [esp+34h] [ebp-14h] + int v12; // [esp+38h] [ebp-10h] + int v13; // [esp+3Ch] [ebp-Ch] + HWND hWnd; // [esp+40h] [ebp-8h] + char *v15; // [esp+44h] [ebp-4h] + + v2 = a2; + hWnd = a2; + v11 = a1; + result = GetCursorPos(&Point); + if ( result ) + { + result = GetWindowRect(v2, &Rect); + if ( result ) + { + result = GetClientRect(v2, &v8); + if ( result ) + { + Point.x -= Rect.left; + Point.y -= Rect.top; + result = SendMessageA(v2, 0xEu, 0, 0); + v4 = result + 1; + if ( result + 1 > 1 ) + { + v15 = (char *)SMemAlloc(result + 1, "C:\\Src\\Diablo\\DiabloUI\\bn_prof.cpp", 438, 0); + SendMessageA(hWnd, 0xDu, v4, (LPARAM)v15); + v5 = GetDesktopWindow(); + v6 = GetDC(v5); + hWnd = (HWND)CreateCompatibleDC(v6); + v13 = bn_prof_10001938((HDC)hWnd, &v8, v15, (int)&Point, (int)&v12); + DeleteDC((HDC)hWnd); + v7 = GetDesktopWindow(); + ReleaseDC(v7, v6); + if ( v13 ) + bn_prof_10001B0A(v11, (const CHAR *)v12); + result = SMemFree(v15, "C:\\Src\\Diablo\\DiabloUI\\bn_prof.cpp", 450, 0); + } + } + } + } + return result; +} */ +// 10010340: using guessed type int __stdcall SMemFree(_DWORD, _DWORD, _DWORD, _DWORD); +// 10010364: using guessed type int __stdcall SMemAlloc(_DWORD, _DWORD, _DWORD, _DWORD); + +// ref: 0x10001B0A +HINSTANCE __fastcall bn_prof_10001B0A(HWND a1, const CHAR *a2) { return 0; } +/* { + const CHAR *v2; // ebp + HWND v3; // eax + HWND v4; // eax + HINSTANCE result; // eax + FILE *v6; // eax + HWND v7; // eax + HWND v8; // eax + HWND v9; // eax + HWND hWnd; // [esp+10h] [ebp-348h] + CHAR Caption; // [esp+14h] [ebp-344h] + CHAR Result; // [esp+54h] [ebp-304h] + CHAR Buffer; // [esp+158h] [ebp-200h] + + v2 = a2; + hWnd = a1; + v3 = GetDesktopWindow(); + SetForegroundWindow(v3); + v4 = (HWND)SDrawGetFrameWindow(); + result = ShellExecuteA(v4, "open", v2, 0, 0, 1); + if ( (unsigned int)result <= 0x20 ) + { + v6 = fopen("battle.htm", "wb"); + if ( v6 ) + fclose(v6); + if ( (unsigned int)FindExecutableA("battle.htm", 0, &Result) <= 0x20 ) + { + v7 = (HWND)SDrawGetFrameWindow(); + if ( (unsigned int)ShellExecuteA(v7, "open", &Result, v2, 0, 1) <= 0x20 ) + { + v8 = (HWND)SDrawGetFrameWindow(); + SetActiveWindow(v8); + v9 = (HWND)SDrawGetFrameWindow(); + ShowWindow(v9, 0); + LoadStringA(hInstance, 0x50u, &Buffer, 512); + LoadStringA(hInstance, 0x51u, &Caption, 64); + UiMessageBoxCallback(hWnd, &Buffer, &Caption, 0x30u); + } + } + result = (HINSTANCE)DeleteFileA("battle.htm"); + } + return result; +} */ +// 10010382: using guessed type _DWORD __stdcall SDrawGetFrameWindow(); + +// ref: 0x10001C0E +HWND UNKCALL bn_prof_10001C0E(HWND hWnd) { return 0; } +/* { + HWND v1; // esi + LPARAM v2; // ST10_4 + HWND v3; // eax + HWND v4; // eax + HWND v5; // eax + HWND v6; // eax + + v1 = hWnd; + bn_prof_10001CF3(hWnd); + ho = bn_prof_10001D81(v1, 2, (int)&unk_1001F3B8); + dword_10029424 = bn_prof_10001D81(v1, 1, (int)&unk_1001F3D0); + v2 = lParam; + v3 = GetDlgItem(v1, 1126); + SendMessageA(v3, 0xCu, 0, v2); + bn_prof_10001CB9( + (_DWORD *)dword_1002941C, + dword_10029418, + (void (__fastcall *)(_BYTE *, _DWORD, int))bn_prof_10001ED0, + 0); + bn_prof_10001E34(v1); + if ( dword_10029430 ) + { + v4 = GetDlgItem(v1, 1128); + } + else + { + v5 = GetDlgItem(v1, 1134); + bn_prof_100022A2(v5); + v6 = GetDlgItem(v1, 1); + EnableWindow(v6, 0); + v4 = GetDlgItem(v1, 2); + } + return SetFocus(v4); +} */ +// 10029418: using guessed type int dword_10029418; +// 1002941C: using guessed type int dword_1002941C; +// 10029430: using guessed type int (__stdcall *dword_10029430)(_DWORD, _DWORD, _DWORD, _DWORD); + +// ref: 0x10001CB9 +void __fastcall bn_prof_10001CB9(_DWORD *a1, int a2, void (__fastcall *a3)(_BYTE *, _DWORD, int), int a4) { return; } +/* { + _BYTE *v4; // eax + _DWORD *v5; // esi + int v6; // edi + + if ( a1 ) + { + if ( a2 ) + { + if ( a3 ) + { + v4 = (_BYTE *)*a1; + if ( *(_BYTE *)*a1 ) + { + v5 = a1; + v6 = a2 - (_DWORD)a1; + do + { + a3(v4, *(_DWORD *)((char *)v5 + v6), a4); + ++v5; + v4 = (_BYTE *)*v5; + } + while ( *(_BYTE *)*v5 ); + } + } + } + } +} */ + +// ref: 0x10001CF3 +int UNKCALL bn_prof_10001CF3(HWND hWnd) { return 0; } +/* { + HWND v1; // edi + const char *v2; // eax + int v3; // ST10_4 + HWND v4; // eax + int v6; // [esp+8h] [ebp-14h] + int v7; // [esp+Ch] [ebp-10h] + int v8; // [esp+10h] [ebp-Ch] + char v9; // [esp+14h] [ebp-8h] + + v8 = 0; + v1 = hWnd; + v6 = 1; + v7 = 2; + v2 = "ui_art\\bnprofile.pcx"; + if ( !dword_10029430 ) + v2 = "ui_art\\bnstaticprofile.pcx"; + v3 = (int)v2; + v4 = GetParent(hWnd); + local_10007944((int)v1, (int)v4, "Popup", -1, 1, v3, &dword_10029410, &v9, 1); + local_10007944(0, 0, "Button", -1, 1, (int)"ui_art\\but_xsm.pcx", &dword_10029428, &v9, 1); + return SDlgSetControlBitmaps(v1, &v6, 0, dword_10029428, &v9, 1, -1); +} */ +// 10010388: using guessed type int __stdcall SDlgSetControlBitmaps(_DWORD, _DWORD, _DWORD, _DWORD, _DWORD, _DWORD, _DWORD); +// 10029410: using guessed type int dword_10029410; +// 10029428: using guessed type int dword_10029428; +// 10029430: using guessed type int (__stdcall *dword_10029430)(_DWORD, _DWORD, _DWORD, _DWORD); + +// ref: 0x10001D81 +HFONT __fastcall bn_prof_10001D81(HWND hWnd, int a2, int a3) { return 0; } +/* { + int v3; // esi + void *v4; // ebx + int v5; // esi + int v6; // eax + const char *v7; // ST10_4 + HFONT v8; // ebx + int *v10; // esi + int pv; // [esp+8h] [ebp-40h] + int v12; // [esp+18h] [ebp-30h] + char v13; // [esp+24h] [ebp-24h] + HWND hDlg; // [esp+44h] [ebp-4h] + + v3 = a2; + hDlg = hWnd; + v4 = (void *)SendMessageA(hWnd, 0x31u, 0, 0); + if ( !v4 ) + return 0; + memset(&pv, 0, 0x3Cu); + if ( !GetObjectA(v4, 60, &pv) ) + return 0; + v5 = 3 * v3; + v6 = MulDiv(dword_10022260[v5], 96, 72); + v7 = (&off_10022264)[v5]; + pv = -v6; + v12 = dword_10022268[v5]; + strcpy(&v13, v7); + v8 = CreateFontIndirectA((const LOGFONTA *)&pv); + if ( !v8 ) + return 0; + v10 = (int *)a3; + if ( a3 ) + { + while ( *v10 ) + { + SendDlgItemMessageA(hDlg, *v10, 0x30u, (WPARAM)v8, 0); + ++v10; + } + } + return v8; +} */ +// 10022260: using guessed type int dword_10022260[]; +// 10022264: using guessed type char *off_10022264; +// 10022268: using guessed type int dword_10022268[]; + +// ref: 0x10001E34 +void UNKCALL bn_prof_10001E34(void *arg) { return; } +/* { + bn_prof_10001CB9( + (_DWORD *)dword_1002941C, + dword_10029418, + (void (__fastcall *)(_BYTE *, _DWORD, int))bn_prof_10001E4C, + (int)arg); +} */ +// 10029418: using guessed type int dword_10029418; +// 1002941C: using guessed type int dword_1002941C; + +// ref: 0x10001E4C +void __fastcall bn_prof_10001E4C(char *a1, LPARAM lParam, HWND hDlg) { return; } +/* { + int v3; // esi + unsigned char v4; // zf + LPARAM v5; // ebp + char *v6; // ebx + const char **v7; // edi + int v8; // esi + HWND v9; // ebx + + v3 = 0; + v4 = dword_10022258 == 0; + v5 = lParam; + v6 = a1; + if ( dword_10022258 > 0 ) + { + v7 = (const char **)&off_1001F378; + do + { + if ( !_strcmpi(v6, *v7) ) + break; + ++v3; + v7 += 4; + } + while ( v3 < dword_10022258 ); + v4 = v3 == dword_10022258; + } + if ( !v4 ) + { + v8 = 4 * v3; + if ( !(byte_1001F37C[v8 * 4] & 4) ) + { + v9 = GetDlgItem(hDlg, dword_1001F380[v8]); + SendMessageA(v9, 0xCu, 0, v5); + if ( dword_10029430 ) + SendMessageA(v9, 0xC5u, dword_1001F384[v8], 0); + } + } +} */ +// 1001F378: using guessed type char *off_1001F378; +// 1001F380: using guessed type int dword_1001F380[]; +// 1001F384: using guessed type int dword_1001F384[]; +// 10022258: using guessed type int dword_10022258; +// 10029430: using guessed type int (__stdcall *dword_10029430)(_DWORD, _DWORD, _DWORD, _DWORD); + +// ref: 0x10001ED0 +void __fastcall bn_prof_10001ED0(char *a1, _BYTE *a2, int a3) { return; } +/* { + int v3; // esi + unsigned char v4; // zf + _BYTE *v5; // edi + char *v6; // ebp + const char **v7; // ebx + + v3 = 0; + v4 = dword_10022258 == 0; + v5 = a2; + v6 = a1; + if ( dword_10022258 > 0 ) + { + v7 = (const char **)&off_1001F378; + do + { + if ( !_strcmpi(v6, *v7) ) + break; + ++v3; + v7 += 4; + } + while ( v3 < dword_10022258 ); + v4 = v3 == dword_10022258; + } + if ( !v4 ) + { + if ( *v5 ) + dword_10029438[v3] = (int)v5; + else + dword_10029438[v3] = (int)"0"; + } +} */ +// 1001F378: using guessed type char *off_1001F378; +// 10022258: using guessed type int dword_10022258; + +// ref: 0x10001F29 +void *bn_prof_10001F29() { return 0; } +/* { + int result; // eax + + bn_prof_100023D8(); + bn_prof_10001F84(); + if ( ho ) + DeleteObject(ho); + ho = 0; + if ( dword_10029424 ) + DeleteObject(dword_10029424); + result = dword_10029434; + dword_10029424 = 0; + if ( dword_10029434 ) + result = SMemFree(dword_10029434, "C:\\Src\\Diablo\\DiabloUI\\bn_prof.cpp", 509, 0); + dword_10029434 = 0; + return result; +} */ +// 10010340: using guessed type int __stdcall SMemFree(_DWORD, _DWORD, _DWORD, _DWORD); +// 10029434: using guessed type int dword_10029434; + +// ref: 0x10001F84 +BYTE *bn_prof_10001F84() { return 0; } +/* { + int result; // eax + + if ( dword_10029410 ) + { + SMemFree(dword_10029410, "C:\\Src\\Diablo\\DiabloUI\\bn_prof.cpp", 129, 0); + dword_10029410 = 0; + } + result = dword_10029428; + if ( dword_10029428 ) + { + result = SMemFree(dword_10029428, "C:\\Src\\Diablo\\DiabloUI\\bn_prof.cpp", 133, 0); + dword_10029428 = 0; + } + return result; +} */ +// 10010340: using guessed type int __stdcall SMemFree(_DWORD, _DWORD, _DWORD, _DWORD); +// 10029410: using guessed type int dword_10029410; +// 10029428: using guessed type int dword_10029428; + +// ref: 0x10001FC8 +void __stdcall UiProfileDraw() { return; } +//int __stdcall UiProfileDraw(int a1, int a2, int a3, int a4, HGDIOBJ ho, int a6, int a7, int a8, int a9, int a10, int a11) { return 0; } +/* { + int v11; // eax + HFONT v12; // eax + int v14; // eax + CHAR *v15; // edi + int v16; // esi + CHAR v17; // al + int v18; // ecx + int v19; // eax + int v20; // edx + CHAR Buffer[256]; // [esp+Ch] [ebp-150h] + int v22; // [esp+10Ch] [ebp-50h] + int v23; // [esp+110h] [ebp-4Ch] + int v24; // [esp+114h] [ebp-48h] + int v25; // [esp+118h] [ebp-44h] + int v26; // [esp+11Ch] [ebp-40h] + int v27; // [esp+120h] [ebp-3Ch] + int v28; // [esp+124h] [ebp-38h] + int v29; // [esp+128h] [ebp-34h] + int v30; // [esp+12Ch] [ebp-30h] + int v31; // [esp+130h] [ebp-2Ch] + int v32; // [esp+134h] [ebp-28h] + int v33; // [esp+138h] [ebp-24h] + int v34; // [esp+13Ch] [ebp-20h] + int v35; // [esp+140h] [ebp-1Ch] + int v36; // [esp+144h] [ebp-18h] + int v37; // [esp+148h] [ebp-14h] + int v38; // [esp+14Ch] [ebp-10h] + int v39; // [esp+150h] [ebp-Ch] + int v40; // [esp+154h] [ebp-8h] + int v41; // [esp+158h] [ebp-4h] + HFONT hoa; // [esp+174h] [ebp+18h] + int hob; // [esp+174h] [ebp+18h] + + if ( ho ) + return 0; + if ( !a9 ) + return 0; + if ( !a10 ) + return 0; + if ( !a11 ) + return 0; + v24 = dword_1002940C; + v34 = dword_1002940C; + v30 = 0; + v31 = 0; + v32 = a10; + v33 = a11; + v36 = a10; + v37 = a11; + v22 = 0; + v23 = 0; + v25 = dword_10029414; + v35 = dword_10029414; + if ( !SBltROP3Clipped(a9, &v30, &v36, a10, dword_1002942C, &v22, &v34, dword_1002940C, 0, 13369376) ) + return 0; + if ( !LoadStringA(hInstance, 0x4Fu, Buffer, 255) ) + return 0; + v11 = MulDiv(12, 96, 72); + v12 = CreateFontA(-v11, 0, 0, 0, 400, 0, 0, 0, 0, 0, 0, 0, 0x20u, "Arial"); + hoa = v12; + if ( !v12 ) + return 0; + v41 = 0; + if ( !SGdiImportFont(v12, &v41) ) + return 0; + DeleteObject(hoa); + if ( !v41 || !SGdiSelectObject(v41) ) + return 0; + v26 = 0; + v27 = 0; + v28 = a10; + v29 = a11; + SGdiSetPitch(a10); + v14 = SStrLen(Buffer); + v15 = Buffer; + hob = v14 + 1; + v40 = 8; + Buffer[v14 + 1] = 0; + v16 = v14 + 1; + do + { + if ( v15[v16 - 1] ) + { + v17 = v15[v16 - 1]; + do + { + if ( v17 == 32 ) + break; + if ( v17 == 10 ) + break; + if ( v17 == 9 ) + break; + if ( v16 <= 1 ) + break; + v17 = v15[v16-- - 2]; + } + while ( v17 ); + } + SGdiGetTextExtent(v15, v16, &v38); + if ( v38 >= a10 - 8 ) + { + v20 = a10 * hob % v38; + if ( --v16 >= a10 * hob / v38 ) + v16 = a10 * hob / v38; + } + else + { + v19 = v16 - 1; + if ( v15[v16 - 1] ) + v19 = v16; + SGdiExtTextOut(a9, 8, v40, &v26, 16777471, 1, 0, v15, v19); + if ( v15[v16] == 32 ) + ++v16; + v15 += v16; + v40 += v39; + hob -= v16; + v16 = hob; + } + } + while ( v16 && hob && v40 < a11 - 8 ); + SGdiDeleteObject(v18, v20, v41); + return 1; +} */ +// 1001038E: using guessed type int __fastcall SGdiDeleteObject(_DWORD, _DWORD, _DWORD); +// 10010394: using guessed type int __stdcall SGdiExtTextOut(_DWORD, _DWORD, _DWORD, _DWORD, _DWORD, _DWORD, _DWORD, _DWORD, _DWORD); +// 1001039A: using guessed type int __stdcall SGdiGetTextExtent(_DWORD, _DWORD, _DWORD); +// 100103A0: using guessed type int __stdcall SStrLen(_DWORD); +// 100103A6: using guessed type int __stdcall SGdiSetPitch(_DWORD); +// 100103AC: using guessed type int __stdcall SGdiSelectObject(_DWORD); +// 100103B2: using guessed type int __stdcall SGdiImportFont(_DWORD, _DWORD); +// 100103B8: using guessed type int __stdcall SBltROP3Clipped(_DWORD, _DWORD, _DWORD, _DWORD, _DWORD, _DWORD, _DWORD, _DWORD, _DWORD, _DWORD); +// 1002940C: using guessed type int dword_1002940C; +// 10029414: using guessed type int dword_10029414; +// 1002942C: using guessed type int dword_1002942C; +// 10001FC8: using guessed type CHAR Buffer[256]; + +// ref: 0x100021C4 +int bn_prof_100021C4() { return 0; } +/* { + int v0; // edi + int v2; // [esp+4h] [ebp-8h] + int v3; // [esp+8h] [ebp-4h] + + v3 = 0; + v2 = 0; + if ( !SBmpLoadImage("ui_Art\\profilebkg.pcx", 0, 0, 0, &v3, &v2, 0) || !v3 || !v2 ) + return 0; + v0 = v3 * v2; + dword_1002942C = SMemAlloc(v3 * v2, "C:\\Src\\Diablo\\DiabloUI\\bn_prof.cpp", 760, 0); + dword_1002940C = v3; + dword_10029414 = v2; + return SBmpLoadImage("ui_Art\\profilebkg.pcx", 0, dword_1002942C, v0, &v3, &v2, 0); +} */ +// 10010364: using guessed type int __stdcall SMemAlloc(_DWORD, _DWORD, _DWORD, _DWORD); +// 100103BE: using guessed type int __stdcall SBmpLoadImage(_DWORD, _DWORD, _DWORD, _DWORD, _DWORD, _DWORD, _DWORD); +// 1002940C: using guessed type int dword_1002940C; +// 10029414: using guessed type int dword_10029414; +// 1002942C: using guessed type int dword_1002942C; + +// ref: 0x10002247 +void *bn_prof_10002247() { return 0; } +/* { + int result; // eax + + result = dword_1002942C; + if ( dword_1002942C ) + { + result = SMemFree(dword_1002942C, "C:\\Src\\Diablo\\DiabloUI\\bn_prof.cpp", 776, 0); + dword_1002942C = 0; + dword_1002940C = 0; + dword_10029414 = 0; + } + return result; +} */ +// 10010340: using guessed type int __stdcall SMemFree(_DWORD, _DWORD, _DWORD, _DWORD); +// 1002940C: using guessed type int dword_1002940C; +// 10029414: using guessed type int dword_10029414; +// 1002942C: using guessed type int dword_1002942C; + +// ref: 0x10002278 +int j_bn_prof_10002282() { return 0; } +/* { + bn_prof_10002282(); + return atexit(bn_prof_10002298); +} */ + +// ref: 0x10002282 +_DWORD *bn_prof_10002282() { return 0; } +/* { + _DWORD *result; // eax + _DWORD *v1; // edx + + result = dword_10029460; + v1 = &dword_10029460[1]; + *v1 = 0; + v1[1] = 0; + *v1 = v1; + dword_10029460[0] = 0; + dword_10029460[2] = ~(unsigned int)&dword_10029460[1]; + return result; +} */ + +// ref: 0x10002298 +void __cdecl bn_prof_10002298() { return; } +/* { + bn_prof_100026F0(dword_10029460); +} */ + +// ref: 0x100022A2 +int UNKCALL bn_prof_100022A2(HWND hWnd) { return 0; } +/* { + HFONT v2; // eax + HFONT v3; // eax + char pv; // [esp+4h] [ebp-40h] + char v5; // [esp+19h] [ebp-2Bh] + HANDLE h; // [esp+40h] [ebp-4h] + + if ( !hWnd ) + return 0; + h = (HANDLE)SendMessageA(hWnd, 0x31u, 0, 0); + if ( !h ) + return 0; + memset(&pv, 0, 0x3Cu); + if ( GetObjectA(h, 60, &pv) ) + { + v2 = CreateFontIndirectA((const LOGFONTA *)&pv); + if ( v2 ) + { + dword_10029450 = v2; + dword_10029458 = bn_prof_10002353(v2); + } + } + memset(&pv, 0, 0x3Cu); + if ( GetObjectA(h, 60, &pv) ) + { + v5 = 1; + v3 = CreateFontIndirectA((const LOGFONTA *)&pv); + if ( v3 ) + { + ::h = v3; + dword_1002946C = bn_prof_10002353(v3); + } + } + return 1; +} */ +// 10029458: using guessed type int dword_10029458; +// 1002946C: using guessed type int dword_1002946C; + +// ref: 0x10002353 +int UNKCALL bn_prof_10002353(HGDIOBJ h) { return 0; } +/* { + HGDIOBJ v1; // ebx + HWND v2; // eax + HDC v3; // ebp + HDC v4; // esi + HWND v5; // eax + int v7; // [esp+10h] [ebp-10h] + HGDIOBJ ha; // [esp+14h] [ebp-Ch] + struct tagSIZE psizl; // [esp+18h] [ebp-8h] + + v1 = h; + v2 = GetDesktopWindow(); + v3 = GetDC(v2); + v4 = CreateCompatibleDC(v3); + v7 = 0; + ha = SelectObject(v4, v1); + if ( GetTextExtentPoint32A(v4, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", 52, &psizl) ) + v7 = (psizl.cx / 26 + 1) / 2; + SelectObject(v4, ha); + DeleteDC(v4); + v5 = GetDesktopWindow(); + ReleaseDC(v5, v3); + return v7; +} */ + +// ref: 0x100023D8 +HGDIOBJ bn_prof_100023D8() { return 0; } +/* { + HGDIOBJ result; // eax + int v1; // esi + + if ( dword_10029450 ) + { + DeleteObject(dword_10029450); + dword_10029450 = 0; + } + result = h; + if ( h ) + { + result = (HGDIOBJ)DeleteObject(h); + h = 0; + } + while ( 1 ) + { + v1 = dword_10029460[2]; + if ( v1 <= 0 ) + break; + bn_prof_100027D8((_DWORD *)dword_10029460[2]); + result = (HGDIOBJ)SMemFree(v1, ".?AU_DRAWTEXT@@", -2, 0); + } + return result; +} */ +// 10010340: using guessed type int __stdcall SMemFree(_DWORD, _DWORD, _DWORD, _DWORD); + +// ref: 0x10002410 +_DWORD *__fastcall bn_prof_10002410(HDC hdc, _DWORD *a2) { return 0; } +/* { + HDC v2; // ebp + _DWORD *v3; // esi + _DWORD *v4; // eax + _DWORD *v5; // ebx + _DWORD *v6; // esi + + v2 = hdc; + v3 = a2; + v4 = bn_prof_10002782(dword_10029460, 2, 0, 0); + v5 = v4; + v4[2] = v2; + v4[3] = *v3; + ++v3; + v4[4] = *v3; + ++v3; + v4[5] = *v3; + v4[6] = v3[1]; + v4[7] = 0; + v4[8] = 0; + v6 = v4 + 9; + GetTextMetricsA(v2, (LPTEXTMETRICA)(v4 + 9)); + v5[23] = *v6 + v5[13]; + return v5; +} */ + +// ref: 0x10002456 +signed int __fastcall bn_prof_10002456(int a1, const CHAR *a2, char a3, _DWORD *a4) { return 0; } +/* { + int v4; // esi + HGDIOBJ v6; // edi + int v7; // eax + int v8; // ecx + int v9; // edi + int v10; // eax + int v11; // eax + int v12; // eax + LPCSTR v13; // ebx + LONG v14; // ecx + int v15; // eax + int v16; // eax + int v17; // eax + int v18; // ecx + const CHAR *v19; // eax + int v20; // eax + int v21; // eax + COLORREF v22; // [esp-Ch] [ebp-2Ch] + struct tagSIZE Size; // [esp+4h] [ebp-1Ch] + COLORREF color; // [esp+Ch] [ebp-14h] + HGDIOBJ h; // [esp+10h] [ebp-10h] + int cchString; // [esp+14h] [ebp-Ch] + LPCSTR lpszString; // [esp+18h] [ebp-8h] + int nFit; // [esp+1Ch] [ebp-4h] + int v29; // [esp+28h] [ebp+8h] + + v4 = a1; + lpszString = a2; + if ( !a1 ) + return 0; + cchString = strlen(a2); + if ( a4 ) + memset(a4, 0, 0x10u); + h = 0; + if ( a3 & 2 ) + { + v6 = ::h; + v7 = dword_1002946C; + v22 = 16711680; + } + else + { + v6 = dword_10029450; + v7 = dword_10029458; + v22 = 0xFFFFFF; + } + v29 = v7; + color = SetTextColor(*(HDC *)(v4 + 8), v22); + if ( v6 ) + h = SelectObject(*(HDC *)(v4 + 8), v6); + if ( a4 ) + { + *a4 = *(_DWORD *)(v4 + 28); + a4[1] = *(_DWORD *)(v4 + 32); + } + do + { + while ( cchString > 0 && *(_WORD *)lpszString == 2573 ) + { + v8 = *(_DWORD *)(v4 + 92); + cchString -= 2; + *(_DWORD *)(v4 + 32) += v8; + lpszString += 2; + *(_DWORD *)(v4 + 28) = 0; + } + if ( !cchString ) + break; + nFit = 0; + GetTextExtentExPointA( + *(HDC *)(v4 + 8), + lpszString, + cchString, + *(_DWORD *)(v4 + 20) - *(_DWORD *)(v4 + 28) - *(_DWORD *)(v4 + 12) - v29 + 1, + &nFit, + 0, + &Size); + v9 = nFit; + if ( nFit ) + { + if ( nFit < cchString ) + { + if ( nFit > 0 ) + { + do + { + if ( isspace(lpszString[v9]) ) + break; + --v9; + } + while ( v9 > 0 ); + if ( v9 > 0 ) + { +LABEL_26: + ++v9; + goto LABEL_27; + } + } + if ( *(_DWORD *)(v4 + 28) > 0 ) + { + if ( isspace(lpszString[v9]) ) + goto LABEL_26; +LABEL_27: + nFit = v9; + } + } + v11 = 0; + if ( nFit > 0 ) + { + while ( *(_WORD *)&lpszString[v11] != 2573 && lpszString[v11] != 9 ) + { + if ( ++v11 >= nFit ) + goto LABEL_34; + } + nFit = v11; + } +LABEL_34: + if ( a4 ) + { + v12 = *(_DWORD *)(v4 + 28); + if ( v12 < *a4 ) + *a4 = v12; + } + else + { + ExtTextOutA( + *(HDC *)(v4 + 8), + *(_DWORD *)(v4 + 28), + *(_DWORD *)(v4 + 32), + 4u, + (const RECT *)(v4 + 12), + lpszString, + nFit, + 0); + } + v13 = lpszString; + GetTextExtentPoint32A(*(HDC *)(v4 + 8), lpszString, nFit, &Size); + v14 = Size.cx; + if ( a4 ) + { + v15 = Size.cx + *(_DWORD *)(v4 + 28); + if ( v15 > a4[2] ) + a4[2] = v15; + v16 = Size.cy + *(_DWORD *)(v4 + 32); + if ( v16 > a4[3] ) + a4[3] = v16; + } + v17 = nFit; + *(_DWORD *)(v4 + 28) += v14; + v18 = *(_DWORD *)(v4 + 28); + if ( v17 < cchString ) + { + v19 = &v13[v17]; + if ( *v19 == 9 ) + { + ++nFit; + *(_DWORD *)(v4 + 28) = 8 * v29 + v18 - v18 % (8 * v29); + } + else + { + if ( *(_WORD *)v19 == 2573 ) + nFit += 2; + v20 = *(_DWORD *)(v4 + 92); + *(_DWORD *)(v4 + 28) = 0; + *(_DWORD *)(v4 + 32) += v20; + } + } + cchString -= nFit; + lpszString += nFit; + continue; + } + v10 = *(_DWORD *)(v4 + 92); + *(_DWORD *)(v4 + 28) &= nFit; + *(_DWORD *)(v4 + 32) += v10; + } + while ( cchString > 0 ); + if ( *(_DWORD *)(v4 + 28) > *(_DWORD *)(v4 + 20) - *(_DWORD *)(v4 + 12) - v29 + 1 ) + { + v21 = *(_DWORD *)(v4 + 92); + *(_DWORD *)(v4 + 28) = 0; + *(_DWORD *)(v4 + 32) += v21; + } + if ( h ) + SelectObject(*(HDC *)(v4 + 8), h); + SetTextColor(*(HDC *)(v4 + 8), color); + return 1; +} */ +// 10029458: using guessed type int dword_10029458; +// 1002946C: using guessed type int dword_1002946C; + +// ref: 0x100026B9 +signed int bn_prof_100026B9() { return 0; } +/* { + signed int result; // eax + + result = 2139095040; + dword_10029454 = 2139095040; + return result; +} */ +// 10029454: using guessed type int dword_10029454; + +// ref: 0x100026C4 +signed int UNKCALL bn_prof_100026C4(_DWORD *arg) { return 0; } +/* { + if ( !arg ) + return 0; + bn_prof_10002749((char *)dword_10029460, arg); + return 1; +} */ + +// ref: 0x100026F0 +void UNKCALL bn_prof_100026F0(_DWORD *arg) { return; } +/* { + _DWORD *v1; // esi + + v1 = arg; + bn_prof_1000287D(arg); + bn_prof_10002890(v1 + 1); +} */ + +// ref: 0x10002749 +int UNKCALL bn_prof_10002749(char *arg, _DWORD *a2) { return 0; } +/* { + int v2; // eax + int v3; // eax + int v4; // esi + + v2 = (int)a2; + if ( !a2 ) + v2 = (int)(arg + 4); + v3 = *(_DWORD *)(v2 + 4); + if ( v3 > 0 ) + v4 = v3; + else + v4 = 0; + bn_prof_100027D8(a2); + SMemFree(a2, ".?AU_DRAWTEXT@@", -2, 0); + return v4; +} */ +// 10010340: using guessed type int __stdcall SMemFree(_DWORD, _DWORD, _DWORD, _DWORD); + +// ref: 0x10002782 +_DWORD *UNKCALL bn_prof_10002782(int *arg, int a2, int a3, int a4) { return 0; } +/* { + int v4; // eax + int *v5; // edi + _DWORD *v6; // eax + _DWORD *v7; // esi + + v4 = a4; + LOBYTE(v4) = a4 | 8; + v5 = arg; + v6 = (_DWORD *)SMemAlloc(a3 + 96, ".?AU_DRAWTEXT@@", -2, v4); + if ( v6 ) + v7 = bn_prof_100027CE(v6); + else + v7 = 0; + if ( a2 ) + bn_prof_1000280C(v5, v7, a2, 0); + return v7; +} */ +// 10010364: using guessed type int __stdcall SMemAlloc(_DWORD, _DWORD, _DWORD, _DWORD); + +// ref: 0x100027CE +_DWORD *UNKCALL bn_prof_100027CE(_DWORD *arg) { return 0; } +/* { + _DWORD *result; // eax + + result = arg; + *arg = 0; + arg[1] = 0; + return result; +} */ + +// ref: 0x100027D8 +void UNKCALL bn_prof_100027D8(_DWORD *arg) { return; } +/* { + _DWORD *v1; // ST00_4 + + v1 = arg; + bn_prof_10002890(arg); + bn_prof_10002890(v1); +} */ + +// ref: 0x1000280C +_DWORD *UNKCALL bn_prof_1000280C(int *arg, _DWORD *a2, int a3, _DWORD *a4) { return 0; } +/* { + int *v4; // edi + _DWORD *v5; // esi + _DWORD *result; // eax + int v7; // ecx + int v8; // edx + int v9; // ecx + int v10; // edx + + v4 = arg; + v5 = a2; + if ( !a2 ) + v5 = arg + 1; + if ( *v5 ) + bn_prof_10002890(v5); + result = a4; + if ( !a4 ) + result = v4 + 1; + if ( a3 == 1 ) + { + *v5 = result; + v5[1] = result[1]; + v8 = result[1]; + v9 = *v4; + if ( v8 > 0 ) + { + if ( v9 < 0 ) + v9 = (int)result - *(_DWORD *)(*result + 4); + v10 = v9 + v8; + } + else + { + v10 = ~v8; + } + *(_DWORD *)v10 = v5; + result[1] = a2; + } + else if ( a3 == 2 ) + { + v7 = *result; + *v5 = *result; + v5[1] = *(_DWORD *)(v7 + 4); + *(_DWORD *)(v7 + 4) = a2; + *result = v5; + } + return result; +} */ + +// ref: 0x1000287D +void UNKCALL bn_prof_1000287D(_DWORD *arg) { return; } +/* { + _DWORD *v1; // esi + _DWORD *v2; // ecx + + v1 = arg; + while ( 1 ) + { + v2 = (_DWORD *)v1[2]; + if ( (signed int)v2 <= 0 ) + break; + bn_prof_10002890(v2); + } +} */ + +// ref: 0x10002890 +void UNKCALL bn_prof_10002890(_DWORD *arg) { return; } +/* { + int v1; // esi + int v2; // edx + int v3; // edx + + v1 = *arg; + if ( *arg ) + { + v2 = arg[1]; + if ( v2 > 0 ) + v3 = (int)arg + v2 - *(_DWORD *)(v1 + 4); + else + v3 = ~v2; + *(_DWORD *)v3 = v1; + *(_DWORD *)(*arg + 4) = arg[1]; + *arg = 0; + arg[1] = 0; + } +} */ diff --git a/2020_03_31/DiabloUI/bnetgw.cpp b/2020_03_31/DiabloUI/bnetgw.cpp new file mode 100644 index 00000000..97211fbb --- /dev/null +++ b/2020_03_31/DiabloUI/bnetgw.cpp @@ -0,0 +1,482 @@ +// ref: 0x100028C2 +void UNKCALL BNetGW_100028C2(_DWORD *arg) { return; } +/* { + _DWORD *v1; // esi + unsigned char v2; // zf + unsigned char v3; // sf + int v4; // edi + int v5; // eax + int v6; // edi + int v7; // ST08_4 + int v8; // eax + signed int v9; // eax + struct _TIME_ZONE_INFORMATION TimeZoneInformation; // [esp+Ch] [ebp-B8h] + char *v11; // [esp+B8h] [ebp-Ch] + int v12; // [esp+BCh] [ebp-8h] + int v13; // [esp+C0h] [ebp-4h] + + v1 = arg; + arg[2] = 0; + arg[3] = 0; + arg[4] = 0; + arg[5] = 0; + arg[6] = 0; + *(_BYTE *)arg = 0; + BNetGW_10002C23(arg); + if ( !v1[4] ) + goto LABEL_15; + if ( v1[6] < 0x3E8u ) + { + v1[1] = 0; + BNetGW_10002A07(v1); + SRegDeleteValue("Configuration", "Battle.net gateways", 2u); + } + if ( !v1[4] ) +LABEL_15: + BNetGW_10002C51(v1); + if ( v1[6] >= 0x3E8u ) + { + v2 = v1[5] == 0; + v3 = v1[5] < 0; + v4 = v1[4]; + v13 = -2; + v12 = 0; + if ( !v3 && !v2 ) + { + do + { + v5 = SStrLen(v4) + 1; + v12 += v5; + v4 += v5; + ++v13; + } + while ( v12 < v1[5] ); + } + v6 = v1[4]; + v7 = v1[4]; + v1[2] = v13 / 3; + v8 = SStrLen(v7); + v9 = strtoul((const char *)(v6 + v8 + 1), &v11, 10); + v1[3] = v9; + v1[1] = 0; + if ( v9 < 1 || v9 > v1[2] ) + { + SMemZero(&TimeZoneInformation, 172); + GetTimeZoneInformation(&TimeZoneInformation); + BNetGW_100029BF(v1, TimeZoneInformation.Bias); + } + } + else + { + v1[2] = 0; + v1[3] = 0; + } +} */ +// 100103A0: using guessed type int __stdcall SStrLen(_DWORD); +// 100103C4: using guessed type int __stdcall SMemZero(_DWORD, _DWORD); +// 100103CA: using guessed type int __stdcall SRegDeleteValue(const char *, const char *, unsigned int); + +// ref: 0x100029BF +void UNKCALL BNetGW_100029BF(_DWORD *arg, int a2) { return; } +/* { + _DWORD *v2; // esi + char *v3; // edi + signed int v4; // ebx + signed int v5; // ebp + int v6; // eax + int v7; // eax + + v2 = arg; + v3 = (char *)1; + v4 = 1380; + v5 = 1; + if ( arg[2] >= 1 ) + { + do + { + v6 = BNetGW_10002AF0(v2, v3); + v7 = abs(60 * v6 - a2); + if ( v7 < v4 ) + { + v4 = v7; + v5 = (signed int)v3; + } + ++v3; + } + while ( (signed int)v3 <= v2[2] ); + } + BNetGW_10002B51(v2, v5); +} */ + +// ref: 0x10002A07 +void *UNKCALL BNetGW_10002A07(_DWORD *arg) { return 0; } +/* { + _DWORD *v1; // esi + int v2; // edi + _BYTE *v3; // ecx + const char *v4; // eax + int result; // eax + + v1 = arg; + if ( arg[1] ) + { + v2 = arg[4]; + if ( v2 ) + { + v3 = (_BYTE *)(v2 + SStrLen(arg[4]) + 1); + *v3 = v1[3] / 10 + 48; + v4 = "Override Battle.net gateways"; + v3[1] = v1[3] % 10 + 48; + if ( !v1[7] ) + v4 = "Battle.net gateways"; + SRegSaveData("Configuration", v4, 0x82u, (void *)v1[4], v1[5]); + } + } + result = v1[4]; + if ( result ) + { + result = SMemFree(result, "C:\\Src\\Diablo\\DiabloUI\\BNetGW.cpp", 152, 0); + v1[4] = 0; + v1[5] = 0; + } + return result; +} */ +// 10010340: using guessed type int __stdcall SMemFree(_DWORD, _DWORD, _DWORD, _DWORD); +// 100103A0: using guessed type int __stdcall SStrLen(_DWORD); +// 100103D0: using guessed type int __stdcall SRegSaveData(const char *, const char *, unsigned int, void *, unsigned int); + +// ref: 0x10002A84 +_DWORD *UNKCALL BNetGW_10002A84(_DWORD *arg, signed int a2) { return 0; } +/* { + signed int v2; // eax + signed int v3; // ebx + int v4; // esi + int v5; // edi + unsigned char v6; // sf + unsigned char v7; // of + int v8; // eax + _DWORD *result; // eax + _DWORD *v10; // [esp+8h] [ebp-4h] + _DWORD *v11; // [esp+14h] [ebp+8h] + + v10 = arg; + if ( !arg[4] ) + return arg; + v2 = a2; + v3 = 1; + if ( a2 < 1 || a2 > arg[2] ) + return arg; + v4 = 3 * a2; + v5 = 0; + v11 = (_DWORD *)arg[4]; + if ( 3 * v2 <= 1 ) + { +LABEL_7: + v7 = __OFSUB__(v5, arg[5]); + v6 = v5 - arg[5] < 0; + } + else + { + while ( 1 ) + { + v7 = __OFSUB__(v5, arg[5]); + v6 = v5 - arg[5] < 0; + if ( v5 >= arg[5] ) + break; + v8 = SStrLen(v11); + arg = v10; + v11 = (_DWORD *)((char *)v11 + ++v8); + v5 += v8; + if ( ++v3 >= v4 ) + goto LABEL_7; + } + } + if ( !(v6 ^ v7) ) + return arg; + result = v11; + if ( v3 > v4 ) + return arg; + return result; +} */ +// 100103A0: using guessed type int __stdcall SStrLen(_DWORD); + +// ref: 0x10002AE5 +signed int BNetGW_10002AE5() { return 0; } +/* { + signed int result; // eax + + result = 2139095040; + dword_10029478 = 2139095040; + return result; +} */ +// 10029478: using guessed type int dword_10029478; + +// ref: 0x10002AF0 +int UNKCALL BNetGW_10002AF0(_DWORD *arg, char *a2) { return 0; } +/* { + const char *v2; // eax + const char *v3; // esi + + v2 = (const char *)BNetGW_10002A84(arg, (signed int)a2); + v3 = v2; + if ( *v2 ) + v3 = &v2[SStrLen(v2) + 1]; + return strtol(v3, &a2, 10); +} */ +// 100103A0: using guessed type int __stdcall SStrLen(_DWORD); + +// ref: 0x10002B21 +_BYTE *UNKCALL BNetGW_10002B21(_DWORD *arg, signed int a2) { return 0; } +/* { + _DWORD *v2; // eax + _BYTE *v3; // esi + + v2 = BNetGW_10002A84(arg, a2); + v3 = v2; + if ( *(_BYTE *)v2 ) + { + v3 = (char *)v2 + SStrLen(v2) + 1; + if ( *v3 ) + v3 += SStrLen(v3) + 1; + } + return v3; +} */ +// 100103A0: using guessed type int __stdcall SStrLen(_DWORD); + +// ref: 0x10002B51 +void UNKCALL BNetGW_10002B51(_DWORD *arg, signed int a2) { return; } +/* { + signed int v2; // eax + + if ( arg[4] ) + { + v2 = a2; + if ( a2 >= 1 && a2 <= arg[2] ) + { + if ( a2 > 99 ) + v2 = 99; + arg[3] = v2; + arg[1] = 1; + } + } +} */ + +// ref: 0x10002B78 +char *UNKCALL BNetGW_10002B78(_DWORD *arg, char *a2) { return 0; } +/* { + _DWORD *v2; // esi + char *result; // eax + char *v4; // ST08_4 + void *v5; // eax + char *v6; // [esp+Ch] [ebp-4h] + + v2 = arg; + v6 = 0; + result = (char *)SRegLoadData("Configuration", a2, 0x82u, 0, 0, (unsigned int *)&v6); + if ( result ) + { + result = v6; + if ( v6 ) + { + v4 = v6; + v2[5] = v6; + v5 = (void *)SMemAlloc(v4, "C:\\Src\\Diablo\\DiabloUI\\BNetGW.cpp", 263, 0); + v2[4] = v5; + if ( !SRegLoadData("Configuration", a2, 0x82u, v5, v2[5], 0) ) + { + SMemFree(v2[4], "C:\\Src\\Diablo\\DiabloUI\\BNetGW.cpp", 271, 0); + v2[4] = 0; + v2[5] = 0; + } + result = (char *)v2[4]; + v2[6] = 0; + if ( result ) + { + a2 = result; + v2[6] = strtoul(result, &a2, 10); + result = (char *)v2[4]; + if ( result == a2 ) + v2[6] = 0; + } + } + } + return result; +} */ +// 10010340: using guessed type int __stdcall SMemFree(_DWORD, _DWORD, _DWORD, _DWORD); +// 10010364: using guessed type int __stdcall SMemAlloc(_DWORD, _DWORD, _DWORD, _DWORD); +// 100103D6: using guessed type int __stdcall SRegLoadData(const char *, const char *, unsigned int, void *, unsigned int, unsigned int *); + +// ref: 0x10002C23 +char *UNKCALL BNetGW_10002C23(_DWORD *arg) { return 0; } +/* { + _DWORD *v1; // esi + char *result; // eax + + v1 = arg; + arg[7] = 0; + result = BNetGW_10002B78(arg, "Override Battle.net gateways"); + if ( !v1[4] ) + return BNetGW_10002B78(v1, "Battle.net gateways"); + v1[7] = 1; + return result; +} */ + +// ref: 0x10002C51 +int UNKCALL BNetGW_10002C51(_DWORD *arg) { return 0; } +/* { + int result; // eax + char *v2; // edi + char *v3; // esi + unsigned int v4; // ebx + char *v5; // esi + _BYTE *v6; // esi + char *v7; // eax + char *v8; // eax + _BYTE *v9; // esi + char *v10; // esi + char v11; // al + unsigned int v12; // esi + char *v13; // [esp+4h] [ebp-10h] + int v14; // [esp+8h] [ebp-Ch] + int v15; // [esp+Ch] [ebp-8h] + _DWORD *v16; // [esp+10h] [ebp-4h] + + v15 = 0; + v16 = arg; + result = BNetGW_10002DBF(&v15); + v2 = (char *)result; + v14 = result; + if ( result ) + { + v3 = (char *)SMemAlloc(2 * v15, "C:\\Src\\Diablo\\DiabloUI\\BNetGW.cpp", 358, 0); + v13 = v3; + v4 = (unsigned int)&v2[v15]; + sprintf(v3, "%d", 1000); + v5 = &v3[SStrLen(v3) + 1]; + *v5++ = 48; + *v5++ = 48; + *v5 = 0; + v6 = v5 + 1; + if ( (unsigned int)v2 < v4 ) + { + if ( (unsigned int)v2 >= v4 ) + goto LABEL_8; + do + { + if ( *v2 == 35 ) + { + v7 = BNetGW_10002DEB(v2, v4); + v8 = BNetGW_10002E0B(v7, v4); + } + else + { + do + { + if ( isspace(*v2) ) + break; + *v6++ = *v2++; + } + while ( (unsigned int)v2 < v4 ); +LABEL_8: + *v6 = 0; + v9 = v6 + 1; + if ( (unsigned int)v2 < v4 ) + { + do + { + if ( !isspace(*v2) ) + break; + ++v2; + } + while ( (unsigned int)v2 < v4 ); + while ( (unsigned int)v2 < v4 && !isspace(*v2) ) + *v9++ = *v2++; + } + *v9 = 0; + v10 = v9 + 1; + if ( (unsigned int)v2 < v4 ) + { + do + { + if ( !isspace(*v2) ) + break; + ++v2; + } + while ( (unsigned int)v2 < v4 ); + while ( (unsigned int)v2 < v4 ) + { + v11 = *v2; + if ( *v2 == 13 || v11 == 10 ) + break; + *v10++ = v11; + ++v2; + } + } + *v10 = 0; + v6 = v10 + 1; + v8 = BNetGW_10002E0B(v2, v4); + } + v2 = v8; + } + while ( (unsigned int)v8 < v4 ); + } + *v6 = 0; + v12 = v6 - v13 + 1; + SRegSaveData("Configuration", "Battle.net gateways", 0x82u, v13, v12); + SMemFree(v14, "C:\\Src\\Diablo\\DiabloUI\\BNetGW.cpp", 429, 0); + result = (int)v16; + v16[5] = v12; + *(_DWORD *)(result + 16) = v13; + *(_DWORD *)(result + 24) = 1000; + } + return result; +} */ +// 10010340: using guessed type int __stdcall SMemFree(_DWORD, _DWORD, _DWORD, _DWORD); +// 10010364: using guessed type int __stdcall SMemAlloc(_DWORD, _DWORD, _DWORD, _DWORD); +// 100103A0: using guessed type int __stdcall SStrLen(_DWORD); +// 100103D0: using guessed type int __stdcall SRegSaveData(const char *, const char *, unsigned int, void *, unsigned int); + +// ref: 0x10002DBF +int UNKCALL BNetGW_10002DBF(_DWORD *arg) { return 0; } +/* { + _DWORD *v1; // esi + int v3; // [esp+4h] [ebp-8h] + int v4; // [esp+8h] [ebp-4h] + + v4 = 0; + v1 = arg; + SFileLoadFile("rez\\gateways.txt", &v3, &v4, 0, 0); + *v1 = v4; + return v3; +} */ +// 100103DC: using guessed type int __stdcall SFileLoadFile(_DWORD, _DWORD, _DWORD, _DWORD, _DWORD); + +// ref: 0x10002DEB +char *__stdcall BNetGW_10002DEB(char *a1, unsigned int a2) { return 0; } +/* { + char *result; // eax + char v3; // cl + + for ( result = a1; (unsigned int)result < a2; ++result ) + { + v3 = *result; + if ( !*result || v3 == 13 || v3 == 10 ) + break; + } + return result; +} */ + +// ref: 0x10002E0B +char *__stdcall BNetGW_10002E0B(char *a1, unsigned int a2) { return 0; } +/* { + char *result; // eax + char v3; // cl + + for ( result = a1; (unsigned int)result < a2; ++result ) + { + v3 = *result; + if ( !*result || v3 != 13 && v3 != 10 ) + break; + } + return result; +} */ diff --git a/2020_03_31/DiabloUI/connect.cpp b/2020_03_31/DiabloUI/connect.cpp new file mode 100644 index 00000000..384f5499 --- /dev/null +++ b/2020_03_31/DiabloUI/connect.cpp @@ -0,0 +1,955 @@ +// ref: 0x10002E2B +void __cdecl Connect_FreeConnectData() +{ + HANDLE *v0; // edi + + if ( connect_data1 ) + { + SMemFree(connect_data1, "C:\\Src\\Diablo\\DiabloUI\\Connect.cpp", 124, 0); + connect_data1 = 0; + } + if ( connect_data2 ) + { + SMemFree(connect_data2, "C:\\Src\\Diablo\\DiabloUI\\Connect.cpp", 129, 0); + connect_data2 = 0; + } + v0 = connect_trans; + do + { + if ( *v0 ) + { + STransDelete(*v0); + *v0 = 0; + } + ++v0; + } + while ( (signed int)v0 < (signed int)&connect_trans[10] ); + if ( connect_data3 ) + { + SMemFree(connect_data3, "C:\\Src\\Diablo\\DiabloUI\\Connect.cpp", 141, 0); + connect_data3 = 0; + } + if ( connect_data4 ) + { + SMemFree(connect_data4, "C:\\Src\\Diablo\\DiabloUI\\Connect.cpp", 146, 0); + connect_data4 = 0; + } +} + +// ref: 0x10002EC4 +BOOL __cdecl Connect_LoadGFXAndStuff() +{ + HANDLE *v0; // esi + int v1; // ebx + int a5[4]; // [esp+4h] [ebp-14h] + BYTE *a2; // [esp+14h] [ebp-4h] + + a2 = 0; + if ( !connect_data1 && !connect_trans[0] ) + { + local_LoadArtImage("ui_art\\heroport.pcx", &connect_data1, heroport_data); + local_LoadArtImage("ui_art\\spwnport.pcx", &connect_data2, 0); + local_LoadArtImage("ui_art\\heronum.pcx", &a2, heronum_data); + local_LoadArtImage("ui_art\\special.pcx", &connect_data3, special_data); + connect_draw_height = 14; + heronum_frames = (signed int)heronum_data[1] / 10; + special_frames = (signed int)special_data[1] / 8; + heronum_frames2 = (signed int)heronum_data[1] / 10 * heronum_data[0]; + heroport_frames = 14 * heroport_data[0]; + v0 = connect_trans; + connect_data4 = SMemAlloc(14 * heroport_data[0], "C:\\Src\\Diablo\\DiabloUI\\Connect.cpp", 194, 0); + memset(connect_trans, 0, 0x28u); + if ( a2 ) + { + v1 = 0; + do + { + a5[0] = 0; + a5[2] = heronum_data[0] - 1; + a5[1] = v1 * heronum_frames; + a5[3] = heronum_frames + v1 * heronum_frames - 1; + STransCreateI(a2, heronum_data[0], heronum_frames, 8, (int)a5, 16777455, v0); + ++v0; + ++v1; + } + while ( (signed int)v0 < (signed int)&connect_trans[10] ); + SMemFree(a2, "C:\\Src\\Diablo\\DiabloUI\\Connect.cpp", 218, 0); + } + } + return 1; +} +// 100294A4: using guessed type int special_frames; +// 100295B0: using guessed type int heronum_frames2; +// 100295C0: using guessed type int heroport_frames; + +// ref: 0x10003009 +BOOL __stdcall UiArtCallback(int game_type, unsigned int art_code, PALETTEENTRY *pPalette, void *pBuffer, DWORD dwBuffersize, DWORD *pdwWidth, DWORD *pdwHeight, DWORD *pdwBpp) +{ + BOOL result; // eax + char pszFileName[260]; // [esp+8h] [ebp-104h] + + pszFileName[0] = nullcharacter; + memset(&pszFileName[1], 0, 0x100u); + *(_WORD *)&pszFileName[257] = 0; + pszFileName[259] = 0; + SStrCopy(pszFileName, "ui_art\\", 260); + if ( game_type == 'BNET' ) + { + if ( art_code > 0x80000004 ) + { + switch ( art_code ) + { + case 0x80000005: + SStrPack(pszFileName, "bnconnbg.pcx", 0x104u); + return SBmpLoadImage(pszFileName, pPalette, pBuffer, dwBuffersize, pdwWidth, pdwHeight, pdwBpp); + case 0x80000006: + SStrPack(pszFileName, "bnselchn.pcx", 0x104u); + return SBmpLoadImage(pszFileName, pPalette, pBuffer, dwBuffersize, pdwWidth, pdwHeight, pdwBpp); + case 0x80000007: + SStrPack(pszFileName, "bnlogin.pcx", 0x104u); + return SBmpLoadImage(pszFileName, pPalette, pBuffer, dwBuffersize, pdwWidth, pdwHeight, pdwBpp); + case 0x80000008: + SStrPack(pszFileName, "newaccount.pcx", 0x104u); + return SBmpLoadImage(pszFileName, pPalette, pBuffer, dwBuffersize, pdwWidth, pdwHeight, pdwBpp); + case 0x80000009: + SStrPack(pszFileName, "changepassword.pcx", 0x104u); + return SBmpLoadImage(pszFileName, pPalette, pBuffer, dwBuffersize, pdwWidth, pdwHeight, pdwBpp); + case 0x8000000A: + SStrPack(pszFileName, "bnladder.pcx", 0x104u); + return SBmpLoadImage(pszFileName, pPalette, pBuffer, dwBuffersize, pdwWidth, pdwHeight, pdwBpp); + case 0x8000000B: + SStrPack(pszFileName, "badconn.pcx", 0x104u); + return SBmpLoadImage(pszFileName, pPalette, pBuffer, dwBuffersize, pdwWidth, pdwHeight, pdwBpp); + case 0x8000000C: + SStrPack(pszFileName, "welcome.pcx", 0x104u); + return SBmpLoadImage(pszFileName, pPalette, pBuffer, dwBuffersize, pdwWidth, pdwHeight, pdwBpp); + case 0x8000000D: + SStrPack(pszFileName, "lepopup.pcx", 0x104u); + return SBmpLoadImage(pszFileName, pPalette, pBuffer, dwBuffersize, pdwWidth, pdwHeight, pdwBpp); + case 0x8000000E: + SStrPack(pszFileName, "tos.pcx", 0x104u); + return SBmpLoadImage(pszFileName, pPalette, pBuffer, dwBuffersize, pdwWidth, pdwHeight, pdwBpp); + default: + break; + } + } + else + { + if ( art_code == 0x80000004 ) + { + SStrPack(pszFileName, "redlag.pcx", 0x104u); + return SBmpLoadImage(pszFileName, pPalette, pBuffer, dwBuffersize, pdwWidth, pdwHeight, pdwBpp); + } + if ( art_code > 7 ) + { + switch ( art_code ) + { + case 8u: +LABEL_48: + SStrPack(pszFileName, "but_lrg.pcx", 0x104u); + return SBmpLoadImage(pszFileName, pPalette, pBuffer, dwBuffersize, pdwWidth, pdwHeight, pdwBpp); + case 0x80000000: + SStrPack(pszFileName, "bnbuttns.pcx", 0x104u); + return SBmpLoadImage(pszFileName, pPalette, pBuffer, dwBuffersize, pdwWidth, pdwHeight, pdwBpp); + case 0x80000001: + SStrPack(pszFileName, "chat_bkg.pcx", 0x104u); + return SBmpLoadImage(pszFileName, pPalette, pBuffer, dwBuffersize, pdwWidth, pdwHeight, pdwBpp); + case 0x80000002: + SStrPack(pszFileName, "greenlag.pcx", 0x104u); + return SBmpLoadImage(pszFileName, pPalette, pBuffer, dwBuffersize, pdwWidth, pdwHeight, pdwBpp); + case 0x80000003: + SStrPack(pszFileName, "yellolag.pcx", 0x104u); + return SBmpLoadImage(pszFileName, pPalette, pBuffer, dwBuffersize, pdwWidth, pdwHeight, pdwBpp); + } + } + else + { + switch ( art_code ) + { + case 7u: +LABEL_47: + SStrPack(pszFileName, "but_med.pcx", 0x104u); + return SBmpLoadImage(pszFileName, pPalette, pBuffer, dwBuffersize, pdwWidth, pdwHeight, pdwBpp); + case 0u: + SStrPack(pszFileName, "bn_bkg.pcx", 0x104u); + return SBmpLoadImage(pszFileName, pPalette, pBuffer, dwBuffersize, pdwWidth, pdwHeight, pdwBpp); + case 2u: + SStrPack(pszFileName, "bnjoinbg.pcx", 0x104u); + return SBmpLoadImage(pszFileName, pPalette, pBuffer, dwBuffersize, pdwWidth, pdwHeight, pdwBpp); + case 3u: + SStrPack(pszFileName, "hpopup.pcx", 0x104u); + return SBmpLoadImage(pszFileName, pPalette, pBuffer, dwBuffersize, pdwWidth, pdwHeight, pdwBpp); + case 5u: +LABEL_46: + SStrPack(pszFileName, "but_xsm.pcx", 0x104u); + return SBmpLoadImage(pszFileName, pPalette, pBuffer, dwBuffersize, pdwWidth, pdwHeight, pdwBpp); + case 6u: +LABEL_11: + SStrPack(pszFileName, "but_sml.pcx", 0x104u); + return SBmpLoadImage(pszFileName, pPalette, pBuffer, dwBuffersize, pdwWidth, pdwHeight, pdwBpp); + } + } + } + } + else if ( game_type == 'IPXN' ) + { + if ( !art_code ) + { + SStrPack(pszFileName, "ipx_bkg.pcx", 0x104u); + return SBmpLoadImage(pszFileName, pPalette, pBuffer, dwBuffersize, pdwWidth, pdwHeight, pdwBpp); + } + } + else if ( !game_type && !art_code ) + { + SStrPack(pszFileName, "connect.pcx", 0x104u); + return SBmpLoadImage(pszFileName, pPalette, pBuffer, dwBuffersize, pdwWidth, pdwHeight, pdwBpp); + } + switch ( art_code ) + { + case 0u: + case 2u: + SStrPack(pszFileName, "menu.pcx", 0x104u); + return SBmpLoadImage(pszFileName, pPalette, pBuffer, dwBuffersize, pdwWidth, pdwHeight, pdwBpp); + case 1u: + case 8u: + goto LABEL_48; + case 3u: + case 4u: + SStrPack(pszFileName, "lpopup.pcx", 0x104u); + return SBmpLoadImage(pszFileName, pPalette, pBuffer, dwBuffersize, pdwWidth, pdwHeight, pdwBpp); + case 5u: + goto LABEL_46; + case 6u: + goto LABEL_11; + case 7u: + goto LABEL_47; + case 9u: + SStrPack(pszFileName, "xsmlogo.pcx", 0x104u); + return SBmpLoadImage(pszFileName, pPalette, pBuffer, dwBuffersize, pdwWidth, pdwHeight, pdwBpp); + case 0xAu: + SStrPack(pszFileName, "prog_bg.pcx", 0x104u); + return SBmpLoadImage(pszFileName, pPalette, pBuffer, dwBuffersize, pdwWidth, pdwHeight, pdwBpp); + case 0xBu: + SStrPack(pszFileName, "prog_fil.pcx", 0x104u); + return SBmpLoadImage(pszFileName, pPalette, pBuffer, dwBuffersize, pdwWidth, pdwHeight, pdwBpp); + case 0xCu: + SStrPack(pszFileName, "spopup.pcx", 0x104u); + return SBmpLoadImage(pszFileName, pPalette, pBuffer, dwBuffersize, pdwWidth, pdwHeight, pdwBpp); + case 0xDu: + SStrPack(pszFileName, "scrlarrw.pcx", 0x104u); + return SBmpLoadImage(pszFileName, pPalette, pBuffer, dwBuffersize, pdwWidth, pdwHeight, pdwBpp); + case 0xEu: + SStrPack(pszFileName, "scrlthmb.pcx", 0x104u); + return SBmpLoadImage(pszFileName, pPalette, pBuffer, dwBuffersize, pdwWidth, pdwHeight, pdwBpp); + case 0xFu: + SStrPack(pszFileName, "scrlbar.pcx", 0x104u); + return SBmpLoadImage(pszFileName, pPalette, pBuffer, dwBuffersize, pdwWidth, pdwHeight, pdwBpp); + case 0x10u: + SStrPack(pszFileName, "cmel.pcx", 0x104u); + return SBmpLoadImage(pszFileName, pPalette, pBuffer, dwBuffersize, pdwWidth, pdwHeight, pdwBpp); + case 0x11u: + SStrPack(pszFileName, "cmml.pcx", 0x104u); + return SBmpLoadImage(pszFileName, pPalette, pBuffer, dwBuffersize, pdwWidth, pdwHeight, pdwBpp); + case 0x12u: + SStrPack(pszFileName, "cmbl.pcx", 0x104u); + return SBmpLoadImage(pszFileName, pPalette, pBuffer, dwBuffersize, pdwWidth, pdwHeight, pdwBpp); + case 0x13u: + SStrPack(pszFileName, "cmec.pcx", 0x104u); + return SBmpLoadImage(pszFileName, pPalette, pBuffer, dwBuffersize, pdwWidth, pdwHeight, pdwBpp); + case 0x14u: + SStrPack(pszFileName, "cmmc.pcx", 0x104u); + return SBmpLoadImage(pszFileName, pPalette, pBuffer, dwBuffersize, pdwWidth, pdwHeight, pdwBpp); + case 0x15u: + SStrPack(pszFileName, "cmbc.pcx", 0x104u); + return SBmpLoadImage(pszFileName, pPalette, pBuffer, dwBuffersize, pdwWidth, pdwHeight, pdwBpp); + case 0x16u: + SStrPack(pszFileName, "cmer.pcx", 0x104u); + return SBmpLoadImage(pszFileName, pPalette, pBuffer, dwBuffersize, pdwWidth, pdwHeight, pdwBpp); + case 0x17u: + SStrPack(pszFileName, "cmmr.pcx", 0x104u); + return SBmpLoadImage(pszFileName, pPalette, pBuffer, dwBuffersize, pdwWidth, pdwHeight, pdwBpp); + case 0x18u: + SStrPack(pszFileName, "cmbr.pcx", 0x104u); + return SBmpLoadImage(pszFileName, pPalette, pBuffer, dwBuffersize, pdwWidth, pdwHeight, pdwBpp); + case 0x19u: + SStrPack(pszFileName, "slgray.pcx", 0x104u); + return SBmpLoadImage(pszFileName, pPalette, pBuffer, dwBuffersize, pdwWidth, pdwHeight, pdwBpp); + case 0x1Au: + SStrPack(pszFileName, "slthumb.pcx", 0x104u); + return SBmpLoadImage(pszFileName, pPalette, pBuffer, dwBuffersize, pdwWidth, pdwHeight, pdwBpp); + case 0x1Bu: + SStrPack(pszFileName, "slfocus.pcx", 0x104u); + return SBmpLoadImage(pszFileName, pPalette, pBuffer, dwBuffersize, pdwWidth, pdwHeight, pdwBpp); + case 0x1Cu: + SStrPack(pszFileName, "slleft.pcx", 0x104u); + return SBmpLoadImage(pszFileName, pPalette, pBuffer, dwBuffersize, pdwWidth, pdwHeight, pdwBpp); + case 0x1Du: + SStrPack(pszFileName, "slmiddle.pcx", 0x104u); + return SBmpLoadImage(pszFileName, pPalette, pBuffer, dwBuffersize, pdwWidth, pdwHeight, pdwBpp); + case 0x1Eu: + SStrPack(pszFileName, "slright.pcx", 0x104u); + return SBmpLoadImage(pszFileName, pPalette, pBuffer, dwBuffersize, pdwWidth, pdwHeight, pdwBpp); + case 0x20u: + SStrPack(pszFileName, "but_checkoff.pcx", 0x104u); + return SBmpLoadImage(pszFileName, pPalette, pBuffer, dwBuffersize, pdwWidth, pdwHeight, pdwBpp); + case 0x21u: + SStrPack(pszFileName, "but_checkon.pcx", 0x104u); + return SBmpLoadImage(pszFileName, pPalette, pBuffer, dwBuffersize, pdwWidth, pdwHeight, pdwBpp); + default: + result = 0; + break; + } + return result; +} +// 100103E2: using guessed type unsigned int __stdcall SStrPack(char *, const char *, unsigned int); + +// ref: 0x100033D1 +void __cdecl Connect_cpp_init() +{ + Connect_cpp_float = Connect_cpp_float_value; +} +// 1001F3F4: using guessed type int Connect_cpp_float_value; +// 100294A0: using guessed type int Connect_cpp_float; + +// ref: 0x100033DC +BOOL __stdcall UiGetDataCallback(int game_type, int data_code, void *a3, int a4, int a5) +{ + signed int v5; // edi + _DWORD *v6; // esi + HCURSOR v7; // eax + + v5 = 0; + if ( game_type != 'BNET' || data_code != 0x80000000 ) + { + switch ( data_code ) + { + case 1: + v5 = 16; + if ( !a3 ) + goto LABEL_24; + if ( (unsigned int)a4 >= 0x10 ) + { + memcpy(a3, connect_subnet_ip, 0x10u); + goto LABEL_24; + } + return 0; + case 2: + v6 = (unsigned int *)a3; + v5 = 4; + if ( !a3 ) + goto LABEL_24; + if ( (unsigned int)a4 < 4 ) + return 0; + v7 = LoadCursorA(ghUiInst, "DIABLO_LINKCURSOR"); + break; + case 3: + v6 = (unsigned int *)a3; + v5 = 4; + if ( !a3 ) + goto LABEL_24; + if ( (unsigned int)a4 < 4 ) + return 0; + v7 = LoadCursorA(ghUiInst, "DIABLO_ARROWCURSOR"); + break; + case 4: + v6 = (unsigned int *)a3; + v5 = 4; + if ( !a3 ) + goto LABEL_24; + if ( (unsigned int)a4 < 4 ) + return 0; + v7 = LoadCursorA(ghUiInst, "DIABLOIBEAM"); + break; + default: + goto LABEL_24; + } + *v6 = (unsigned int)v7; + if ( v7 ) + goto LABEL_24; + return 0; + } + v5 = 4; + if ( a3 ) + { + if ( (unsigned int)a4 >= 4 ) + { + *(_DWORD *)a3 = 54; + goto LABEL_24; + } + return 0; + } +LABEL_24: + if ( a5 ) + *(_DWORD *)a5 = v5; + return v5 != 0; +} + +// ref: 0x100034AB +BOOL __stdcall UiSoundCallback(int a1, int type, int a3) +{ + if ( type ) + { + if ( type == 1 ) + TitleSnd_PlaySelectSound(); + } + else + { + TitleSnd_PlayMoveSound(); + } + return 0; +} + +// ref: 0x100034C8 +BOOL __stdcall UiAuthCallback(int a1, char *a2, char *a3, char a4, char *a5, LPSTR lpBuffer, int cchBufferMax) +{ + size_t v7; // edi + size_t v8; // ebx + int v9; // ebx + char *v10; // ebx + size_t v11; // eax + int v12; // eax + int v14; // eax + char v15[256]; // [esp+0h] [ebp-434h] + char a1a[256]; // [esp+100h] [ebp-334h] + char v17[256]; // [esp+200h] [ebp-234h] + char Buffer[256]; // [esp+300h] [ebp-134h] + _uiheroinfo heroinfo; // [esp+400h] [ebp-34h] + _gamedata GameData; // [esp+42Ch] [ebp-8h] + + *(_DWORD *)&GameData.bDiff = 0; + if ( cchBufferMax ) + *lpBuffer = 0; + v7 = strlen(a3) + 1; + v8 = strlen(a5) + 1; + if ( v7 > 0x100 || v8 > 0x100 ) + { + if ( lpBuffer ) + LoadStringA(ghUiInst, 0x413u, lpBuffer, cchBufferMax); + return 0; + } + memcpy(a1a, a3, v7); + memcpy(v17, a5, v8); + if ( Connect_GetHeroInfoConc(a1a, &heroinfo) ) + { + if ( a1 == 1 ) + { + if ( !(a4 & 9) ) + { + v9 = 0; + while ( 1 ) + { + LoadStringA(ghUiInst, v9 + 4, Buffer, 256); + if ( strstr(v17, Buffer) ) + break; + if ( ++v9 >= 3 ) + goto LABEL_16; + } + if ( heroinfo.heroclass != v9 ) + goto LABEL_20; + *(_DWORD *)&GameData.bDiff = 1; +LABEL_16: + LoadStringA(ghUiInst, 0x408u, Buffer, 256); + v10 = strstr(v17, Buffer); + if ( v10 ) + { + v11 = strlen(Buffer); + v12 = atoi(&v10[v11]); + if ( heroinfo.level >= v12 ) + return 1; + } + if ( *(_DWORD *)&GameData.bDiff ) + return 1; +LABEL_20: + if ( lpBuffer ) + { + LoadStringA(ghUiInst, 0x415u, v15, 256); + v14 = sprintf(Buffer, v15, v17) + 1; + if ( cchBufferMax >= v14 ) + { + memcpy(lpBuffer, Buffer, v14); + } + else + { + memcpy(lpBuffer, Buffer, cchBufferMax); + lpBuffer[cchBufferMax - 1] = 0; + } + } + return 0; + } + } + else if ( !(a4 & 8) ) + { + Connect_DiffFromString(v17, &GameData, 0, 0); + if ( GameData.bDiff == 1 ) + { + if ( heroinfo.level < 20u ) + { + if ( lpBuffer ) + LoadStringA(ghUiInst, 0x411u, lpBuffer, cchBufferMax); + return 0; + } + } + else if ( GameData.bDiff == 2 && heroinfo.level < 30u ) + { + if ( lpBuffer ) + LoadStringA(ghUiInst, 0x412u, lpBuffer, cchBufferMax); + return 0; + } + } + return 1; + } + if ( lpBuffer ) + LoadStringA(ghUiInst, 0x414u, lpBuffer, cchBufferMax); + return 0; +} + +// ref: 0x10003710 +BOOL __stdcall UiDrawDescCallback(int arg0, COLORREF color, LPCSTR lpString, char *a4, int a5, UINT align, time_t a7, HDC *a8) +{ + HDC *v8; // ebx + HDC v9; // esi + int v10; // esi + size_t v11; // eax + UINT v13; // eax + BOOL v14; // esi + int v15; // eax + int v16; // eax + HDC v17; // ST20_4 + struct tm *v18; // eax + struct tm *v19; // edi + signed int v20; // eax + int v21; // eax + int v22; // eax + UINT v23; // eax + int v24; // esi + int v25; // eax + int v26; // eax + signed int v27; // [esp-4h] [ebp-2E8h] + char a1[256]; // [esp+Ch] [ebp-2D8h] + char String[128]; // [esp+10Ch] [ebp-1D8h] + char Buffer[128]; // [esp+18Ch] [ebp-158h] + CHAR v31[32]; // [esp+20Ch] [ebp-D8h] + HDC a8a[12]; // [esp+22Ch] [ebp-B8h] + struct tagTEXTMETRICA tm; // [esp+25Ch] [ebp-88h] + _uiheroinfo heroinfo; // [esp+294h] [ebp-50h] + struct tagPOINT pt; // [esp+2C0h] [ebp-24h] + _gamedata gamedata; // [esp+2C8h] [ebp-1Ch] + struct tagRECT rc; // [esp+2D0h] [ebp-14h] + COLORREF v38; // [esp+2E0h] [ebp-4h] + LPCSTR lpStringa; // [esp+2F4h] [ebp+10h] + + Buffer[0] = nullcharacter; + v8 = a8; + memset(&Buffer[1], 0, 0x7Cu); + v9 = a8[4]; + *(_WORD *)&Buffer[125] = 0; + Buffer[127] = 0; + v10 = (unsigned char)v9 & 1; + v11 = strlen(a4) + 1; + if ( v11 > 0x100 ) + return 0; + memcpy(a1, a4, v11); + if ( color == 1 ) + { + a8 = 0; + a4 = 0; + if ( !Connect_DiffFromString(a1, &gamedata, (int)&a8, (int)&a4) ) + return 0; + color = SetTextColor(v8[6], 0xFFFFFFu); + v38 = SetBkColor(v8[6], v10 != 0 ? 0x808080 : 0); + if ( align & 1 ) + { + v13 = strlen(lpString); + ExtTextOutA(v8[6], (int)v8[7], (int)v8[8], 6u, (const RECT *)(v8 + 7), lpString, v13, 0); + } + else + { + v14 = a8 && a4; + if ( gamedata.bDiff < 3u ) + LoadStringA(ghUiInst, gamedata.bDiff + 1003, Buffer, 128); + if ( align & 2 && v14 ) + { + GetTextMetricsA(v8[6], &tm); + lpStringa = (LPCSTR)(tm.tmHeight + tm.tmExternalLeading); + MoveToEx(v8[6], (int)v8[7], (int)v8[8], &pt); + align = SetTextAlign(v8[6], 1u); + v15 = strlen(Buffer); + TextOutA(v8[6], 0, 0, Buffer, v15); + LoadStringA(ghUiInst, 0x409u, String, 128); + MoveToEx(v8[6], (int)v8[7], (int)v8[8] + (_DWORD)lpStringa, 0); + v16 = strlen(String); + TextOutA(v8[6], 0, 0, String, v16); + v17 = v8[6]; + qmemcpy(a8a, v8, sizeof(a8a)); + GetCurrentPositionEx(v17, (LPPOINT)&a8a[7]); + SetTextAlign(v8[6], 0); + connect_color_text = 1; + UiDrawDescCallback(arg0, 2u, (LPCSTR)a8, a4, 0, 1u, 0, a8a); + connect_color_text = 0; + if ( a7 ) + { + SetTextAlign(v8[6], 1u); + LoadStringA(ghUiInst, 0x40Cu, &heroinfo.name[8], 32); + LoadStringA(ghUiInst, 0x40Du, v31, 32); + v18 = localtime(&a7); + v19 = v18; + if ( v18 ) + { + LoadStringA(ghUiInst, (v18->tm_hour > 12) + 1034, (LPSTR)&rc.top, 10); + v20 = v19->tm_hour; + if ( v20 > 12 ) + v19->tm_hour = v20 - 12; + if ( !v19->tm_hour ) + v19->tm_hour = 12; + sprintf(String, &heroinfo.name[8], v31, v19->tm_hour, v19->tm_min, &rc.top); + MoveToEx(v8[6], (int)v8[7], (int)v8[8] + 2 * (_DWORD)lpStringa, 0); + v21 = strlen(String); + TextOutA(v8[6], 0, 0, String, v21); + } + } + MoveToEx(v8[6], pt.x, pt.y, 0); + SetTextAlign(v8[6], align); + } + else + { + v22 = strlen(Buffer); + TextOutA(v8[6], (int)v8[7], (int)v8[8], Buffer, v22); + } + } + goto LABEL_56; + } + GetTextMetricsA(v8[6], &tm); + a4 = (char *)((tm.tmHeight - connect_draw_height) / 2 + 1); + if ( !connect_color_text ) + { + color = SetTextColor(v8[6], 0xFFFFu); + v38 = SetBkColor(v8[6], v10 != 0 ? 0x808080 : 0); + } + if ( align & 1 ) + { + v23 = strlen(lpString); + ExtTextOutA(v8[6], (int)v8[7] + heroport_data[0] + 2, (int)v8[8], 6u, (const RECT *)(v8 + 7), lpString, v23, 0); + } + if ( a5 ) + { + if ( a5 & 0x20 ) + { + v27 = 5; +LABEL_45: + v24 = v27; + goto LABEL_46; + } + if ( a5 & 1 ) + { + v24 = 0; +LABEL_46: + SetRect(&rc, 0, 0, special_data[0] - 1, special_frames - 1); + OffsetRect(&rc, 0, special_frames * v24); + SDlgBltToWindowI( + (HWND)v8[5], + 0, + (char *)v8[7], + (int)v8[8] + (_DWORD)a4, + connect_data3, + &rc, + (SIZE *)special_data, + -1, + 0, + 0xCC0020u); + goto LABEL_55; + } + if ( a5 & 2 ) + { + v27 = 2; + goto LABEL_45; + } + if ( a5 & 4 ) + { + v27 = 3; + goto LABEL_45; + } + if ( a5 & 8 ) + { + v25 = (arg0 != 'BNET') - 1; + _LOBYTE(v25) = v25 & 0xFD; + v24 = v25 + 4; + goto LABEL_46; + } + } + if ( *(_DWORD *)a1 == 'CHAT' ) + { + v27 = 6; + goto LABEL_45; + } + if ( *(_DWORD *)a1 == 'SEXP' || *(_DWORD *)a1 == 'SSHR' || *(_DWORD *)a1 == 'STAR' ) + { + v27 = 7; + goto LABEL_45; + } + if ( Connect_GetHeroInfoConc(a1, &heroinfo) ) + { + if ( heroinfo.spawned ) + { + if ( connect_data2 ) + SBltROP3( + connect_data4, + connect_data2, + heroport_data[0], + connect_draw_height, + heroport_data[0], + heroport_data[0], + 0, + 0xCC0020u); + } + else + { + SBltROP3( + connect_data4, + &connect_data1[heroport_frames * (heroinfo.heroclass + 3 * heroinfo.herorank)], + heroport_data[0], + connect_draw_height, + heroport_data[0], + heroport_data[0], + 0, + 0xCC0020u); + } + v26 = heroinfo.level / 10; + if ( v26 ) + STransBlt( + (char *)connect_data4 + 4 * heroport_data[0] + heroport_data[0] + 14, + 0, + 0, + heroport_data[0], + connect_trans[v26]); + STransBlt( + (char *)connect_data4 + 4 * (heroport_data[0] + 4) + heroport_data[0] + 4, + 0, + 0, + heroport_data[0], + connect_trans[heroinfo.level % 10]); + SetRect(&rc, 0, 0, heroport_data[0] - 1, connect_draw_height - 1); + SDlgBltToWindowI( + (HWND)v8[5], + 0, + (char *)v8[7], + (int)v8[8] + (_DWORD)a4, + connect_data4, + &rc, + (SIZE *)heroport_data, + -1, + 0, + 0xCC0020u); + } +LABEL_55: + if ( !connect_color_text ) + { +LABEL_56: + SetTextColor(v8[6], color); + SetBkColor(v8[6], v38); + } + return 1; +} +// 100294A4: using guessed type int special_frames; +// 100295C0: using guessed type int heroport_frames; +// 10029614: using guessed type int connect_color_text; + +// ref: 0x10003CE4 +BOOL __stdcall UiCategoryCallback(int a1, int a2, int a3, int a4, int a5, _DWORD *a6, _DWORD *a7) +{ + *a7 = 0xFFFF; + *a6 = Connect_GetRankFromLevel(connect_categorystr); + return 1; +} + +// ref: 0x10003D04 +int __fastcall Connect_GetRankFromLevel(char *str) +{ + char a1[512]; // [esp+0h] [ebp-22Ch] + _uiheroinfo a2; // [esp+200h] [ebp-2Ch] + + strcpy(a1, str); + if ( !Connect_GetHeroInfoConc(a1, &a2) || a2.level == 1 ) + return 0; + if ( (signed int)a2.level < 4 ) + return 1; + if ( (signed int)a2.level < 6 ) + return 2; + if ( (signed int)a2.level < 8 ) + return 3; + if ( (signed int)a2.level < 10 ) + return 4; + if ( (signed int)a2.level < 13 ) + return 5; + if ( (signed int)a2.level < 17 ) + return 6; + if ( (signed int)a2.level < 20 ) + return 7; + if ( (signed int)a2.level < 25 ) + return 8; + if ( (signed int)a2.level < 30 ) + return 9; + if ( (signed int)a2.level < 35 ) + return 10; + if ( (signed int)a2.level < 40 ) + return 11; + return ((signed int)a2.level >= 48) + 12; +} + +// ref: 0x10003DAF +BOOL __fastcall Connect_DiffFromString(char *str, _gamedata *gamedata, int a3, int a4) +{ + unsigned char v6; // al + char *v8; // eax + const char *v9; // eax + char *v10; // eax + + if ( !*str ) + return 0; + v6 = atoi(str); + gamedata->bDiff = v6; + if ( v6 >= 3u ) + return 0; + v8 = strchr(str, 13); + if ( v8 ) + { + *v8 = 0; + v9 = v8 + 1; + if ( a3 ) + *(_DWORD *)a3 = (unsigned int)v9; + v10 = (char *)strchr(v9, 13); + if ( v10 ) + { + *v10 = 0; + if ( a4 ) + *(_DWORD *)a4 = (unsigned int)v10 + 1; + } + } + return 1; +} + +// ref: 0x10003E0C +void __fastcall Connect_SetDiffString(_gamedata *gamedata, const char *str1, char *str2, char *str3, int size) +{ + size_t v7; // ebx + size_t v8; // eax + unsigned char v9; // zf + unsigned char v10; // sf + unsigned char v11; // of + int v12; // eax + + v7 = strlen(str1); + v8 = v7 + strlen(str2) + 5; + v11 = __OFSUB__(size, v8); + v9 = size == v8; + v10 = (signed int)(size - v8) < 0; + v12 = gamedata->bDiff; + if ( (unsigned char)(v10 ^ v11) | v9 ) + _itoa(v12, str3, 10); + else + sprintf(str3, "%d\r%s\r%s", v12, str1, str2); +} + +// ref: 0x10003E61 +BOOL __fastcall Connect_GetHeroInfoConc(const char *a1, _uiheroinfo *pInfo) +{ + int v4; // eax + int v5; // edi + int v6; // edx + unsigned short v7; // di + unsigned char v8; // cl + int v10; // [esp+Ch] [ebp-24h] + unsigned int v11; // [esp+10h] [ebp-20h] + unsigned int v12; // [esp+14h] [ebp-1Ch] + unsigned int v13; // [esp+18h] [ebp-18h] + int v14; // [esp+1Ch] [ebp-14h] + int v15; // [esp+20h] [ebp-10h] + int v16; // [esp+24h] [ebp-Ch] + int v17; // [esp+28h] [ebp-8h] + int v18; // [esp+2Ch] [ebp-4h] + + memset(pInfo, 0, 0x2Cu); + if ( !*a1 ) + return 0; + v4 = *(_DWORD *)a1; + if ( *(_DWORD *)a1 != 'DRTL' && v4 != 'DSHR' && v4 != 'DTST' ) + return 0; + if ( sscanf(a1 + 4, "%d %d %d %d %d %d %d %d %d", &v13, &v12, &v11, &v18, &v17, &v16, &v15, &v10, &v14) != 9 ) + return 0; + v5 = *(_DWORD *)a1; + v6 = v14; + if ( v5 == 'DRTL' ) + { + if ( v14 ) + return 0; + } + if ( v5 == 'DSHR' && !v14 ) + return 0; + v7 = v13; + if ( !v13 ) + return 0; + if ( v13 > 0x63 ) + return 0; + v8 = v12; + if ( v12 >= 3 || v11 > 3 || v18 < 0 || v17 < 0 || v16 < 0 || v15 < 0 ) + return 0; + pInfo->herorank = v11; + pInfo->level = v7; + pInfo->strength = (unsigned char)v18; + pInfo->heroclass = v8; + pInfo->magic = (unsigned char)v17; + pInfo->spawned = v6; + pInfo->dexterity = (unsigned char)v16; + pInfo->vitality = (unsigned char)v15; + pInfo->gold = v10; + return 1; +} + +// ref: 0x10003F6F +void __fastcall Connect_MakeDescString(_uiheroinfo *a1, char *name, size_t size) +{ + *(_DWORD *)name = (unsigned int)connect_charname; + _snprintf( + name + 4, + size, + " %d %d %d %d %d %d %d %d %d", + a1->level, + a1->heroclass, + a1->herorank, + a1->strength, + a1->magic, + a1->dexterity, + a1->vitality, + a1->gold, + a1->spawned); +} + +// ref: 0x10003FB7 +void __stdcall UiCreateGameCriteria(_uiheroinfo *pInfo, char *str) +{ + sprintf(str, "#%d?%d", 3, pInfo->level); +} + +// ref: 0x10003FD6 +BOOL __stdcall UiCreatePlayerDescription(_uiheroinfo *info, int mode, char *desc) +{ + connect_charname = (char *)mode; + Connect_MakeDescString(info, desc, 0x80u); + return 1; +} + +// ref: 0x10003FF7 +void __stdcall UiSetupPlayerInfo(char *infostr, _uiheroinfo *pInfo, int type) +{ + connect_charname = (char *)type; + SStrCopy(connect_plrinfostr, infostr, 128); + Connect_MakeDescString(pInfo, connect_categorystr, 0x80u); +} + +// ref: 0x10004028 +void __fastcall Connect_CopyPlrDescStrings(char *str1, int size1, char *str2, int size2) +{ + if ( str1 ) + SStrCopy(str1, connect_plrinfostr, size1); + if ( str2 ) + SStrCopy(str2, connect_categorystr, size2); +} diff --git a/2020_03_31/DiabloUI/copyprot.cpp b/2020_03_31/DiabloUI/copyprot.cpp new file mode 100644 index 00000000..5ed25074 --- /dev/null +++ b/2020_03_31/DiabloUI/copyprot.cpp @@ -0,0 +1,157 @@ +// ref: 0x10004054 +BOOL __stdcall UiCopyProtError(int *pdwResult) +{ + int v1; // eax + int v2; // eax + char Buffer[128]; // [esp+0h] [ebp-80h] + + if ( DiabloUI_GetSpawned() ) + LoadStringA(ghUiInst, 0x3Fu, Buffer, 127); + else + LoadStringA(ghUiInst, 0x1Bu, Buffer, 127); + v1 = (int)SDrawGetFrameWindow(NULL); + v2 = SDlgDialogBoxParam(ghUiInst, "OKCANCEL_DIALOG", v1, CopyProt_WndProc, (int)Buffer); + if ( pdwResult ) + *pdwResult = v2; + return 1; +} +// 10010382: using guessed type _DWORD __stdcall SDrawGetFrameWindow(); + +// ref: 0x100040AF +LRESULT __stdcall CopyProt_WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) +{ + HWND v4; // ecx + int v5; // edx + HWND v6; // eax + LONG v7; // eax + HWND v9; // eax + + if ( Msg == 2 ) + { + CopyProt_FreeCopyResrcs(); + Fade_UpdatePaletteRange(10); + return (LRESULT)SDlgDefDialogProc(hWnd, Msg, (HDC)wParam, (HWND)lParam); + } + if ( Msg <= 0x103 ) + return (LRESULT)SDlgDefDialogProc(hWnd, Msg, (HDC)wParam, (HWND)lParam); + if ( Msg <= 0x105 ) + { + v9 = (HWND)SDrawGetFrameWindow(NULL); + SendMessageA(v9, Msg, wParam, lParam); + return (LRESULT)SDlgDefDialogProc(hWnd, Msg, (HDC)wParam, (HWND)lParam); + } + if ( Msg == 272 ) + { + CopyProt_LoadCopyStuff(hWnd, lParam); + return 1; + } + if ( Msg != 273 ) + return (LRESULT)SDlgDefDialogProc(hWnd, Msg, (HDC)wParam, (HWND)lParam); + switch ( (unsigned short)wParam ) + { + case 1u: + v6 = GetFocus(); + v7 = GetWindowLongA(v6, -12); + v4 = hWnd; + if ( v7 == 1109 ) + { + v5 = 1; + goto LABEL_13; + } + goto LABEL_12; + case 2u: + v4 = hWnd; +LABEL_12: + v5 = 2; + goto LABEL_13; + case 0x455u: + v4 = hWnd; + v5 = 1; +LABEL_13: + CopyProt_EndCopyDlg(v4, v5); + break; + } + return (LRESULT)SDlgDefDialogProc(hWnd, Msg, (HDC)wParam, (HWND)lParam); +} +// 10010382: using guessed type _DWORD __stdcall SDrawGetFrameWindow(); + +// ref: 0x10004173 +void __cdecl CopyProt_FreeCopyResrcs() +{ + if ( copyprot_artpal ) + { + FreeResource(copyprot_artpal); + copyprot_artpal = 0; + } + if ( copyprot_btnart ) + { + FreeResource(copyprot_btnart); + copyprot_btnart = 0; + } + if ( copyprot_popupart ) + { + FreeResource(copyprot_popupart); + copyprot_popupart = 0; + } +} + +// ref: 0x100041B5 +BOOL __fastcall CopyProt_LoadCopyStuff(HWND hWnd, int a2) +{ + HRSRC v2; // eax + HRSRC v3; // eax + HRSRC v4; // eax + void *v5; // edi + void *v6; // ebx + HWND v7; // eax + PALETTEENTRY pPalEntries[256]; // [esp+Ch] [ebp-420h] + int msgs[3]; // [esp+40Ch] [ebp-20h] + DWORD data[2]; // [esp+418h] [ebp-14h] + LPCSTR lpString; // [esp+420h] [ebp-Ch] + void *v13; // [esp+424h] [ebp-8h] + + msgs[2] = 0; + lpString = (LPCSTR)a2; + data[0] = 112; + data[1] = 140; + msgs[0] = 1109; + msgs[1] = 2; + v2 = FindResourceA(ghUiInst, "IDR_POPUPART", "ART_FILES"); + copyprot_popupart = LoadResource(ghUiInst, v2); + v3 = FindResourceA(ghUiInst, "IDR_BTNART", "ART_FILES"); + copyprot_btnart = LoadResource(ghUiInst, v3); + v4 = FindResourceA(ghUiInst, "IDR_ARTPAL", "ART_FILES"); + copyprot_artpal = LoadResource(ghUiInst, v4); + v5 = LockResource(copyprot_popupart); + v6 = LockResource(copyprot_btnart); + v13 = LockResource(copyprot_artpal); + if ( v5 ) + SDlgSetBitmapI(hWnd, 0, &nullcharacter, -1, 1, v5, 0, 284, 148, -1); + ShowCursor(1); + Fade_SetInputWindow(hWnd); + if ( v6 ) + local_FitButtonDlg(hWnd, msgs, v6, data); + if ( v13 ) + { + memcpy(pPalEntries, v13, 0x400u); + SDrawUpdatePalette(0, 0x100u, pPalEntries, 1); + } + v7 = GetDlgItem(hWnd, 1026); + SetWindowTextA(v7, lpString); + return 1; +} + +// ref: 0x1000430C +void __fastcall CopyProt_EndCopyDlg(HWND hWnd, int a2) +{ + ShowCursor(0); + SDlgEndDialog(hWnd, (HANDLE)a2); +} + +// ref: 0x10004329 +void __cdecl CopyProt_cpp_init() +{ + CopyProt_cpp_float = CopyProt_cpp_float_value; +} +// 1001F3F8: using guessed type int CopyProt_cpp_float_value; +// 10029620: using guessed type int CopyProt_cpp_float; diff --git a/2020_03_31/DiabloUI/cr8game.cpp b/2020_03_31/DiabloUI/cr8game.cpp new file mode 100644 index 00000000..71062828 --- /dev/null +++ b/2020_03_31/DiabloUI/cr8game.cpp @@ -0,0 +1,416 @@ +// ref: 0x10004339 +void __cdecl cr8game_cpp_init() +{ + cr8game_cpp_float = cr8game_cpp_float_value; +} +// 1001F3FC: using guessed type int cr8game_cpp_float_value; +// 1002962C: using guessed type int cr8game_cpp_float; + +// ref: 0x10004344 +BOOL __fastcall cr8game_GetSnetCreaGame(HWND hWnd) +{ + BOOL result; // eax + DWORD *v2; // eax + int *v3; // ST24_4 + int v4; // ST18_4 + int v5; // ST14_4 + char *v6; // ST10_4 + int v7; // eax + char Buffer[128]; // [esp+Ch] [ebp-308h] + char Text[256]; // [esp+8Ch] [ebp-288h] + char a4[128]; // [esp+18Ch] [ebp-188h] + char a2[128]; // [esp+20Ch] [ebp-108h] + char str[128]; // [esp+28Ch] [ebp-88h] + BOOL v13; // [esp+30Ch] [ebp-8h] + + Connect_CopyPlrDescStrings(a2, 128, str, 128); + Connect_SetDiffString(&cr8_gamedata, a2, str, a4, 128); + if ( UiAuthCallback(2, a2, str, 0, a4, Text, 256) ) + { + v2 = cr8_somegamestruct; + if ( cr8_somegamestruct[8] >= 8 ) + { + *(_BYTE *)(cr8_somegamestruct[7] + 4) = cr8_gamedata.bDiff; + v2 = cr8_somegamestruct; + } + v3 = cr8game_playerID; + v4 = *(_DWORD *)(cr8_playercount + 8); + v5 = v2[8]; + v6 = (char *)v2[7]; + v7 = Connect_GetRankFromLevel(str); + v13 = SNetCreateGame(cr8_gamename, cr8_gamepassword, a4, v7, v6, v5, v4, a2, 0, (DWORD *)v3); + if ( !v13 ) + { + if ( SErrGetLastError() == 183 ) + { + LoadStringA(ghUiInst, 0x40Fu, Buffer, 128); + sprintf(Text, Buffer, cr8_gamename); + } + else + { + LoadStringA(ghUiInst, 0x410u, Text, 256); + } + UiMessageBoxCallback(hWnd, Text, 0, 0x30u); + } + result = v13; + } + else + { + UiMessageBoxCallback(hWnd, Text, 0, 0x30u); + result = 0; + } + return result; +} +// 10010406: using guessed type _DWORD __stdcall SErrGetLastError(); +// 10029630: using guessed type int cr8_playercount; + +// ref: 0x100044AA +BOOL __stdcall UiCreateGameCallback(int a1, int a2, int a3, int a4, int a5, int a6) +{ + BOOL v6; // eax + + cr8_playercount = a1; + cr8_somegamestruct = (DWORD *)a2; + cr8_dword_10029638 = a3; + cr8_dword_10029640 = a5; + cr8_dword_1002963C = a4; + cr8game_playerID = (int *)a6; + v6 = SDlgDialogBoxParam(ghUiInst, "DIALOG_CREATE_GAME", *(_DWORD *)(a4 + 8), cr8game_WndProc, 0); + return v6 != -1 ? v6 : 0; +} +// 10029630: using guessed type int cr8_playercount; +// 10029638: using guessed type int cr8_dword_10029638; +// 1002963C: using guessed type int cr8_dword_1002963C; +// 10029640: using guessed type int cr8_dword_10029640; + +// ref: 0x10004506 +LRESULT __stdcall cr8game_WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) +{ + signed int v4; // ebx + HWND v6; // eax + HWND v7; // eax + HWND v8; // eax + char Buffer[256]; // [esp+Ch] [ebp-104h] + int a2; // [esp+10Ch] [ebp-4h] + + v4 = Msg; + if ( Msg == 2 ) + { + cr8game_FreeCreaStuff(); + cr8game_FreeMainMem(hWnd); + if ( cr8game_hobject ) + DeleteObject(cr8game_hobject); + cr8_sendmsg1 = 0; + cr8_sendmsg2 = 0; + return (LRESULT)SDlgDefDialogProc(hWnd, v4, (HDC)wParam, (HWND)lParam); + } + if ( Msg > 0x103 ) + { + if ( Msg > 0x105 ) + { + if ( Msg == 272 ) + { + cr8_sendmsg2 = GetDlgItem(hWnd, 1010); + cr8_sendmsg1 = GetDlgItem(hWnd, 1011); + cr8game_LoadCreaGFX(hWnd); + cr8game_AllocMainMem(hWnd); + cr8game_SendMessageF5(hWnd); + cr8game_hobject = cr8game_GetCr8Object(hWnd); + SendMessageA(cr8_sendmsg2, 0xC5u, 0x1Fu, 0); + SendMessageA(cr8_sendmsg1, 0xC5u, 0x1Fu, 0); + return 1; + } + if ( Msg != 273 ) + { + if ( Msg == 312 && GetWindowLongA((HWND)lParam, -12) == 1030 ) + { + local_SetWhiteText((HDC)wParam); + return (LRESULT)GetStockObject(5); + } + return (LRESULT)SDlgDefDialogProc(hWnd, v4, (HDC)wParam, (HWND)lParam); + } + if ( (unsigned short)wParam == 1 ) + { + if ( SendMessageA(cr8_sendmsg2, 0xEu, 0, 0) ) + { + SendMessageA(cr8_sendmsg2, 0xDu, 0x20u, (LPARAM)cr8_gamename); + if ( SelHero_IsNameReserved(cr8_gamename) + || SelHero_NameHasChar(cr8_gamename, &nullcharacter) + || !cr8game_CheckValidGameName(cr8_gamename) ) + { + LoadStringA(ghUiInst, 0x404u, Buffer, 256); + OkCancel_DoOkDialog(hWnd, Buffer, 1); + cr8_gamename[0] = 0; + } + else + { + cr8_gamepassword[0] = 0; + if ( SendMessageA(cr8_sendmsg1, 0xEu, 0, 0) ) + SendMessageA(cr8_sendmsg1, 0xDu, 0x20u, (LPARAM)cr8_gamepassword); + cr8_gamedata.bDiff = cr8_dword_1002966C; + TitleSnd_PlaySelectSound(); + if ( cr8game_GetSnetCreaGame(hWnd) ) + SDlgEndDialog(hWnd, (void *)HANDLE_FLAG_INHERIT); + } + } + else + { + LoadStringA(ghUiInst, 0x3F0u, Buffer, 256); + OkCancel_DoOkDialog(hWnd, Buffer, 1); + } + } + else + { + if ( (unsigned short)wParam != 2 ) + { + if ( (signed int)(unsigned short)wParam > 1031 && (signed int)(unsigned short)wParam <= 1034 ) + { + a2 = (unsigned short)wParam - 1032; + if ( HIWORD(wParam) == 6 ) + SetFocus(cr8_sendmsg2); + if ( cr8_dword_1002966C != (unsigned short)wParam - 1032 ) + { + if ( cr8_dword_1002966C != -1 ) + { + v6 = GetDlgItem(hWnd, cr8_dword_1002966C + 1032); + SendMessageA(v6, 0xF3u, 0, 0); + TitleSnd_PlayMoveSound(); + } + cr8game_BlitCr8Dialog(hWnd, a2); + v7 = GetDlgItem(hWnd, 1040); + cr8game_SetWindowStr(v7, 1029, a2); + v4 = 273; + cr8_dword_1002966C = a2; + } + SendMessageA((HWND)lParam, 0xF3u, 1u, 0); + } + return (LRESULT)SDlgDefDialogProc(hWnd, v4, (HDC)wParam, (HWND)lParam); + } + TitleSnd_PlaySelectSound(); + SDlgEndDialog(hWnd, 0); + } + return 0; + } + v8 = (HWND)SDrawGetFrameWindow(NULL); + SendMessageA(v8, Msg, wParam, lParam); + } + return (LRESULT)SDlgDefDialogProc(hWnd, v4, (HDC)wParam, (HWND)lParam); +} +// 10010382: using guessed type _DWORD __stdcall SDrawGetFrameWindow(); + +// ref: 0x10004828 +void __cdecl cr8game_FreeCreaStuff() +{ + if ( cr8_creat_bg_ptr ) + { + SMemFree(cr8_creat_bg_ptr, "C:\\Src\\Diablo\\DiabloUI\\cr8game.cpp", 55, 0); + cr8_creat_bg_ptr = 0; + } + if ( cr8_but_xsm_ptr ) + { + SMemFree(cr8_but_xsm_ptr, "C:\\Src\\Diablo\\DiabloUI\\cr8game.cpp", 60, 0); + cr8_but_xsm_ptr = 0; + } + if ( cr8_diffbtns_ptr ) + { + SMemFree(cr8_diffbtns_ptr, "C:\\Src\\Diablo\\DiabloUI\\cr8game.cpp", 65, 0); + cr8_diffbtns_ptr = 0; + } +} + +// ref: 0x1000487F +BOOL __fastcall cr8game_LoadCreaGFX(HWND hWnd) +{ + int id[3]; // [esp+8h] [ebp-1Ch] + DWORD a8[2]; // [esp+14h] [ebp-10h] + DWORD a3[2]; // [esp+1Ch] [ebp-8h] + + id[0] = 0; + id[0] = 1; + id[1] = 2; + local_LoadArtWithPal(hWnd, 0, "Dialog", -1, 1, "ui_art\\creat_bg.pcx", &cr8_creat_bg_ptr, a8, 1); + local_LoadArtImage("ui_art\\but_xsm.pcx", &cr8_but_xsm_ptr, a3); + SDlgSetControlBitmaps(hWnd, id, 0, (char *)cr8_but_xsm_ptr, (char *)a3, 1, -1); + local_LoadArtImage("ui_art\\diffbtns.pcx", &cr8_diffbtns_ptr, cr8diffbtns_size); + local_SetStaticBmp(hWnd, 1040, cr8_creat_bg_ptr, a8); + return 1; +} + +// ref: 0x10004914 +void __fastcall cr8game_FreeMainMem(HWND hWnd) +{ + signed int v2; // edi + HWND v3; // esi + void **v4; // eax MAPDST + void *v6; // eax + struct tagRECT Rect; // [esp+10h] [ebp-10h] + + v2 = 0; + do + { + v3 = GetDlgItem(hWnd, v2 + 1032); + GetClientRect(v3, &Rect); + v4 = (void **)GetWindowLongA(v3, -21); + if ( v4 ) + { + v6 = *v4; + if ( *v4 ) + SMemFree(v6, "C:\\Src\\Diablo\\DiabloUI\\cr8game.cpp", 160, 0); + SMemFree(v4, "C:\\Src\\Diablo\\DiabloUI\\cr8game.cpp", 162, 0); + } + ++v2; + } + while ( v2 < 3 ); +} + +// ref: 0x1000497F +void __fastcall cr8game_AllocMainMem(HWND hWnd) +{ + int v1; // ebx + void **v2; // esi + HWND v3; // ST1C_4 + LONG v4; // eax + struct tagRECT Rect; // [esp+Ch] [ebp-18h] + HWND hWnda; // [esp+20h] [ebp-4h] + + v1 = 0; + do + { + hWnda = GetDlgItem(hWnd, v1 + 1032); + GetClientRect(hWnda, &Rect); + v2 = (void **)SMemAlloc(0x110u, "C:\\Src\\Diablo\\DiabloUI\\cr8game.cpp", 177, 0); + *v2 = SMemAlloc(Rect.right * Rect.bottom, "C:\\Src\\Diablo\\DiabloUI\\cr8game.cpp", 178, 0); + v3 = hWnda; + v2[1] = (void *)Rect.right; + v4 = Rect.bottom; + v2[3] = 0; + v2[2] = (void *)v4; + SetWindowLongA(v3, -21, (LONG)v2); + SDlgSetBitmapI(hWnda, 0, &nullcharacter, -1, 241, *v2, 0, (int)v2[1], (int)v2[2], -1); + cr8game_DoAROP3Blit(hWnda, v1++, 0); + } + while ( v1 < 3 ); +} + +// ref: 0x10004A34 +void __fastcall cr8game_DoAROP3Blit(HWND hWnd, int frame, int size) +{ + DWORD *v5; // eax + + v5 = (DWORD *)GetWindowLongA(hWnd, -21); + if ( v5 ) + { + if ( cr8_diffbtns_ptr ) + { + SBltROP3( + (void *)*v5, + &cr8_diffbtns_ptr[cr8diffbtns_size[0] * v5[2] * (size + 2 * frame)], + v5[1], + v5[2], + v5[1], + cr8diffbtns_size[0], + 0, + 0xCC0020u); + InvalidateRect(hWnd, 0, 0); + } + } +} + +// ref: 0x10004A93 +void __fastcall cr8game_SendMessageF5(HWND hWnd) +{ + cr8_dword_1002966C = -1; + cr8_dword_10029658 = 0; + cr8_dword_10029668 = 0; + SendDlgItemMessageA(hWnd, 1032, 0xF5u, 0, 0); +} +// 10029658: using guessed type int cr8_dword_10029658; +// 10029668: using guessed type int cr8_dword_10029668; + +// ref: 0x10004ABA +void __fastcall cr8game_BlitCr8Dialog(HWND hWnd, int a2) +{ + HWND v4; // eax + HWND v5; // eax + + if ( cr8_dword_1002966C != -1 ) + { + v4 = GetDlgItem(hWnd, cr8_dword_1002966C + 1032); + cr8game_DoAROP3Blit(v4, cr8_dword_1002966C, 0); + } + v5 = GetDlgItem(hWnd, a2 + 1032); + cr8game_DoAROP3Blit(v5, a2, 1); +} + +// ref: 0x10004B02 +void __fastcall cr8game_SetWindowStr(HWND hWnd, int dlgitem, int a3) +{ + char Buffer[256]; // [esp+4h] [ebp-100h] + + LoadStringA(ghUiInst, a3 + dlgitem, Buffer, 256); + SetWindowTextA(hWnd, Buffer); +} + +// ref: 0x10004B3F +int __fastcall cr8game_CheckValidGameName(char *name) +{ + signed int v1; // edi + char v2; // al + signed int v3; // esi + int result; // eax + char v5[32]; // [esp+8h] [ebp-24h] + + strcpy(v5, name); + v1 = 0; + if ( v5[0] == 32 ) + { + v2 = 32; + while ( v2 ) + { + v2 = v5[v1++ + 1]; + if ( v2 != 32 ) + goto LABEL_5; + } +LABEL_9: + result = 0; + } + else + { +LABEL_5: + v3 = strlen(v5); + while ( v5[--v3] == 32 ) + { + if ( v3 <= v1 ) + goto LABEL_9; + } + v5[v3 + 1] = 0; + strcpy(name, &v5[v1]); + result = v3 + 1 - v1; + } + return result; +} + +// ref: 0x10004BA8 +HFONT __fastcall cr8game_GetCr8Object(HWND hWnd) +{ + HFONT v2; // eax MAPDST + int pv[15]; // [esp+8h] [ebp-40h] + + v2 = (HFONT)SendMessageA(hWnd, 0x31u, 0, 0); + if ( v2 ) + { + if ( GetObjectA(v2, 60, pv) ) + { + pv[0] = -MulDiv(12, 96, 72); + pv[1] = 0; + v2 = CreateFontIndirectA((const LOGFONTA *)pv); + if ( v2 ) + { + SendDlgItemMessageA(hWnd, 1032, 0x30u, (WPARAM)v2, 0); + SendDlgItemMessageA(hWnd, 1033, 0x30u, (WPARAM)v2, 0); + SendDlgItemMessageA(hWnd, 1034, 0x30u, (WPARAM)v2, 0); + } + } + } + return v2; +} diff --git a/2020_03_31/DiabloUI/creadung.cpp b/2020_03_31/DiabloUI/creadung.cpp new file mode 100644 index 00000000..a377c9db --- /dev/null +++ b/2020_03_31/DiabloUI/creadung.cpp @@ -0,0 +1,305 @@ +// ref: 0x10004C33 +void __fastcall CreaDung_SetDelSpin(int a1) +{ + creadung_delspinners = a1; +} +// 100296CC: using guessed type int creadung_delspinners; + +// ref: 0x10004C3F +void __cdecl CreaDung_cpp_init() +{ + CreaDung_cpp_float = CreaDung_cpp_float_value; +} +// 1001F400: using guessed type int CreaDung_cpp_float_value; +// 100296C4: using guessed type int CreaDung_cpp_float; + +// ref: 0x10004C4A +LRESULT __stdcall CreaDung_WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) +{ + HWND v4; // eax + HWND v6; // eax + + if ( Msg == 2 ) + { + CreaDung_FreeDungProcs(hWnd); + } + else if ( Msg > 0x103 ) + { + if ( Msg > 0x105 ) + { + if ( Msg == 272 ) + { + creadung_dword_100296D8 = lParam; + CreaDung_LoadDungGFX(hWnd); + } + else + { + if ( Msg == 273 ) + { + if ( HIWORD(wParam) == 7 ) + { + Focus_GetAndBlitSpin(hWnd, lParam); + } + else if ( HIWORD(wParam) == 6 ) + { + Focus_CheckPlayMove(lParam); + Focus_DoBlitSpinIncFrame(hWnd, (HWND)lParam); + CreaDung_ParseDungProcs(hWnd, (unsigned short)wParam); + } + else if ( HIWORD(wParam) == 5 || (_WORD)wParam == 1 ) + { + CreaDung_DoAllPlaySnd(hWnd); + } + else if ( (_WORD)wParam == 2 ) + { + CreaDung_PlaySndAndKill(hWnd, 2); + } + return (LRESULT)SDlgDefDialogProc(hWnd, Msg, (HDC)wParam, (HWND)lParam); + } + if ( Msg != 275 ) + { + if ( Msg == 513 ) + CreaDung_CheckDlgForSnd(hWnd, (unsigned short)lParam, (unsigned int)lParam >> 16); + return (LRESULT)SDlgDefDialogProc(hWnd, Msg, (HDC)wParam, (HWND)lParam); + } + if ( wParam == 1 ) + { + v4 = GetFocus(); + Focus_DoBlitSpinIncFrame(hWnd, v4); + } + } + return 0; + } + v6 = (HWND)SDrawGetFrameWindow(NULL); + SendMessageA(v6, Msg, wParam, lParam); + } + return (LRESULT)SDlgDefDialogProc(hWnd, Msg, (HDC)wParam, (HWND)lParam); +} +// 10010382: using guessed type _DWORD __stdcall SDrawGetFrameWindow(); +// 100296D8: using guessed type int creadung_dword_100296D8; + +// ref: 0x10004D75 +void __fastcall CreaDung_ParseDungProcs(HWND hWnd, int dlg) +{ + HWND v3; // eax + int v4; // eax + HWND v5; // eax + int v6; // eax + char Buffer[256]; // [esp+4h] [ebp-100h] + + LoadStringA(ghUiInst, dlg - 1055, Buffer, 255); + v3 = GetDlgItem(hWnd, 1097); + if ( v3 ) + { + v4 = GetWindowLongA(v3, -21); + local_SetWndLongStr(v4, Buffer); + } + Doom_ParseWndProc4(hWnd, creadung_msgtbl2, 5); + LoadStringA(ghUiInst, dlg - 65, Buffer, 255); + v5 = GetDlgItem(hWnd, 1099); + if ( v5 ) + { + v6 = GetWindowLongA(v5, -21); + local_SetWndLongStr(v6, Buffer); + } + Doom_ParseWndProc4(hWnd, creadung_msgtbl3, 1); +} + +// ref: 0x10004E2E +void __fastcall CreaDung_FreeDungProcs(HWND hWnd) +{ + void **v2; // eax + + Doom_DeleteFreeProcs(hWnd, creadung_msgtbl5); + Doom_DeleteFreeProcs(hWnd, creadung_msgtbl4); + Doom_DeleteFreeProcs(hWnd, creadung_msgtbl3); + Doom_DeleteFreeProcs(hWnd, creadung_msgtbl2); + Doom_DeleteFreeProcs(hWnd, creadung_msgtbl1); + v2 = (void **)GetWindowLongA(hWnd, -21); + local_FreeMemPtr(v2); + if ( creadung_delspinners ) + Focus_DeleteSpinners(); +} +// 100296CC: using guessed type int creadung_delspinners; + +// ref: 0x10004E8B +void __fastcall CreaDung_LoadDungGFX(HWND hWnd) +{ + DWORD *v2; // eax MAPDST + + if ( creadung_delspinners ) + Focus_LoadSpinner("ui_art\\focus16.pcx"); + else + Focus_ResetSpinToZero(); + SDlgSetTimer((int)hWnd, 1, 55, 0); + v2 = local_AllocWndLongData(); + if ( v2 ) + { + SetWindowLongA(hWnd, -21, (LONG)v2); + local_LoadArtWithPal(hWnd, 0, "popup", -1, 1, "ui_art\\seldiff.pcx", (BYTE **)v2, v2 + 1, 0); + } + local_DoUiWndProc(hWnd, (DWORD *)creadung_msgtbl5); + Doom_ParseWndProc3(hWnd, creadung_msgtbl1, 5); + Doom_ParseWndProc3(hWnd, creadung_msgtbl2, 5); + Doom_ParseWndProc3(hWnd, creadung_msgtbl3, 1); + Doom_ParseWndProcs(hWnd, creadung_msgtbl4, 4, 0); + Doom_ParseWndProcs(hWnd, creadung_msgtbl5, 2, 1); +} +// 100296CC: using guessed type int creadung_delspinners; + +// ref: 0x10004F40 +void __fastcall CreaDung_PlaySndAndKill(HWND hWnd, int a2) +{ + TitleSnd_PlaySelectSound(); + SDlgKillTimer((int)hWnd, 1); + SDlgEndDialog(hWnd, (HANDLE)a2); +} + +// ref: 0x10004F5D +void __fastcall CreaDung_DoAllPlaySnd(HWND hWnd) +{ + //int v1; // ebp + HWND v2; // esi + HWND v3; // eax + LONG v4; // eax + HWND v5; // edi + HWND v6; // eax + int v7; // [esp-288h] [ebp-28Ch] + int v8; // [esp-188h] [ebp-18Ch] + char *v9; // [esp-108h] [ebp-10Ch] + char *v10; // [esp-88h] [ebp-8Ch] + int v11; // [esp-8h] [ebp-Ch] + char v12; // [esp-4h] [ebp-8h] + //int v13; // [esp+0h] [ebp-4h] + + /* note: stack is hosed, fix me */ + v2 = hWnd; + if ( creadung_dword_100296D8 == 1 ) + { + //v13 = v1; + v5 = hWnd; + Connect_CopyPlrDescStrings((char *)&v10, 128, (char *)&v9, 128); + v6 = GetFocus(); + v12 = GetWindowLongA(v6, -12) - 70; + Connect_SetDiffString((_gamedata *)&v11, (const char *)&v10, (char *)&v9, (char *)&v8, 128); + if ( UiAuthCallback(2, (char *)&v10, (char *)&v9, 0, (char *)&v8, (LPSTR)&v7, 256) ) + CreaDung_DoSnetCreaGame(v5); + else + SelYesNo_SelOkDialog(v5, (char *)&v7, 0, 0); + } + else + { + v3 = GetFocus(); + v4 = GetWindowLongA(v3, -12); + SelHero_SetHeroDifficulty(v4 - 1094); + CreaDung_PlaySndAndKill(v2, 1); + } +} +// 10004F5D: could not find valid save-restore pair for ebp +// 100296D8: using guessed type int creadung_dword_100296D8; + +// ref: 0x10005037 +void __fastcall CreaDung_DoSnetCreaGame(HWND hWnd) +{ + HWND v1; // ebx + DWORD *v2; // eax + DWORD v3; // edi + char a4[256]; // [esp+8h] [ebp-34Ch] + char v5[128]; // [esp+108h] [ebp-24Ch] + char Buffer[192]; // [esp+188h] [ebp-1CCh] + char a3[128]; // [esp+248h] [ebp-10Ch] + char a2[128]; // [esp+2C8h] [ebp-8Ch] + _gamedata a1; // [esp+348h] [ebp-Ch] + + v1 = GetFocus(); + if ( hWnd == GetParent(v1) ) + { + Connect_CopyPlrDescStrings(a2, 128, a3, 128); + a1.bDiff = GetWindowLongA(v1, -12) - 70; + Connect_SetDiffString(&a1, a2, a3, a4, 256); + v2 = crea_somegamestruct; + if ( crea_somegamestruct[8] >= 8 ) + { + v3 = crea_somegamestruct[7]; + *(_BYTE *)(v3 + 4) = GetWindowLongA(v1, -12) - 70; + v2 = crea_somegamestruct; + } + if ( SNetCreateGame( + creadung_gamename, + 0, + a4, + 0, + (char *)v2[7], + v2[8], + *(_DWORD *)(creadung_playername + 8), + a2, + 0, + (DWORD *)creadung_playerID) ) + { + CreaDung_PlaySndAndKill(hWnd, 1); + } + else + { + creadung_lasterror = SErrGetLastError(); + if ( creadung_lasterror == 183 ) + { + LoadStringA(ghUiInst, 0x49u, v5, 127); + wsprintfA(Buffer, v5, creadung_gamename); + } + else + { + LoadStringA(ghUiInst, 0x26u, Buffer, 191); + } + SelYesNo_SelOkDialog(hWnd, Buffer, 0, 0); + } + } +} +// 10010406: using guessed type _DWORD __stdcall SErrGetLastError(); +// 100296BC: using guessed type int creadung_playername; +// 100296D4: using guessed type int creadung_lasterror; + +// ref: 0x1000517E +void __fastcall CreaDung_CheckDlgForSnd(HWND hWnd, int a2, int a3) +{ + HWND v6; // eax + HWND v7; // eax + + v6 = GetDlgItem(hWnd, 1056); + if ( local_GetBottomRect(hWnd, v6, a2, a3) ) + { + CreaDung_DoAllPlaySnd(hWnd); + } + else + { + v7 = GetDlgItem(hWnd, 1054); + if ( local_GetBottomRect(hWnd, v7, a2, a3) ) + CreaDung_PlaySndAndKill(hWnd, 2); + } +} + +// ref: 0x100051D8 +BOOL __fastcall CreaDung_SelDungDiff(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8) +{ + int v8; // ST10_4 + BOOL result; // eax + + creadung_playername = a1; + creadung_dword_100296C8 = a3; + creadung_playerID = (int *)a6; + creadung_delspinners = a7; + crea_somegamestruct = (DWORD *)a2; + creadung_gamename = (char *)a8; + v8 = SelHero_GetHeroIsGood(); + result = SDlgDialogBoxParam(ghUiInst, "SELDIFF_DIALOG", *(_DWORD *)(a4 + 8), CreaDung_WndProc, v8); + if ( result != 1 ) + { + SErrSetLastError(creadung_lasterror); + result = 0; + } + return result; +} +// 1001041E: using guessed type int __stdcall SErrSetLastError(_DWORD); +// 100296BC: using guessed type int creadung_playername; +// 100296C8: using guessed type int creadung_dword_100296C8; +// 100296CC: using guessed type int creadung_delspinners; +// 100296D4: using guessed type int creadung_lasterror; diff --git a/2020_03_31/DiabloUI/creastat.cpp b/2020_03_31/DiabloUI/creastat.cpp new file mode 100644 index 00000000..1a1cab07 --- /dev/null +++ b/2020_03_31/DiabloUI/creastat.cpp @@ -0,0 +1,19 @@ +// ref: 0x1000523E +BOOL __stdcall UiGetDefaultStats(int pclass, _uidefaultstats *pStats) +{ + if ( !pStats ) + return 0; + pStats->strength = defstats[pclass][0]; + pStats->magic = defstats[pclass][1]; + pStats->dexterity = defstats[pclass][2]; + pStats->vitality = defstats[pclass][3]; + return 1; +} + +// ref: 0x10005287 +void __cdecl CreaStat_cpp_init() +{ + CreaStat_cpp_float = CreaStat_cpp_float_value; +} +// 1001F404: using guessed type int CreaStat_cpp_float_value; +// 100296E0: using guessed type int CreaStat_cpp_float; diff --git a/2020_03_31/DiabloUI/credits.cpp b/2020_03_31/DiabloUI/credits.cpp new file mode 100644 index 00000000..501dd08a --- /dev/null +++ b/2020_03_31/DiabloUI/credits.cpp @@ -0,0 +1,254 @@ +// ref: 0x10005297 +void __cdecl credits_cpp_init() +{ + credits_cpp_float = credits_cpp_float_value; +} +// 1001F408: using guessed type int credits_cpp_float_value; +// 100296EC: using guessed type int credits_cpp_float; + +// ref: 0x100052A2 +BOOL __stdcall UiCreditsDialog(int a1) +{ + int v1; // eax + + v1 = (int)SDrawGetFrameWindow(NULL); + SDlgDialogBoxParam(ghUiInst, "CREDITS_DIALOG", v1, credits_WndProc, 25); + return 1; +} +// 10010382: using guessed type _DWORD __stdcall SDrawGetFrameWindow(); + +// ref: 0x100052C7 +LRESULT __stdcall credits_WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) +{ + HWND v5; // eax + + if ( Msg > 0x111 ) + { + if ( Msg == 275 ) + { + credits_CalcPosROP3(hWnd); + return (LRESULT)SDlgDefDialogProc(hWnd, Msg, (HDC)wParam, (HWND)lParam); + } + if ( Msg == 513 || Msg == 516 ) + goto LABEL_12; + if ( Msg != 528 ) + { + if ( Msg == 2024 ) + { + if ( !Fade_CheckRange5() ) + Fade_SetFadeTimer((int)hWnd); + return 0; + } + return (LRESULT)SDlgDefDialogProc(hWnd, Msg, (HDC)wParam, (HWND)lParam); + } + if ( (_WORD)wParam != 513 && (_WORD)wParam != 516 ) + return (LRESULT)SDlgDefDialogProc(hWnd, Msg, (HDC)wParam, (HWND)lParam); +LABEL_25: + Title_KillAndFadeDlg(hWnd); + return (LRESULT)SDlgDefDialogProc(hWnd, Msg, (HDC)wParam, (HWND)lParam); + } + if ( Msg == 273 ) + goto LABEL_25; + if ( Msg != 2 ) + { + if ( Msg == 135 ) + return 4; + if ( Msg != 256 ) + { + if ( Msg > 0x103 ) + { + if ( Msg <= 0x105 ) + { + v5 = (HWND)SDrawGetFrameWindow(NULL); + SendMessageA(v5, Msg, wParam, lParam); + } + else if ( Msg == 272 ) + { + credits_LoadImgCreditTxt(hWnd, lParam); + PostMessageA(hWnd, 0x7E8u, 0, 0); + return 1; + } + } + return (LRESULT)SDlgDefDialogProc(hWnd, Msg, (HDC)wParam, (HWND)lParam); + } + if ( wParam != 32 ) + return 0; +LABEL_12: + Title_KillAndFadeDlg(hWnd); + return 0; + } + credits_FreeCreditResrc(hWnd); + return (LRESULT)SDlgDefDialogProc(hWnd, Msg, (HDC)wParam, (HWND)lParam); +} +// 10010382: using guessed type _DWORD __stdcall SDrawGetFrameWindow(); + +// ref: 0x100053D9 +void __fastcall credits_FreeCreditResrc(HWND hWnd) +{ + void **v2; // eax + + if ( creditsobj ) + { + SGdiDeleteObject(creditsobj); + creditsobj = 0; + } + if ( credit_back_img ) + { + SMemFree(credit_back_img, "C:\\Src\\Diablo\\DiabloUI\\credits.cpp", 46, 0); + credit_back_img = 0; + } + v2 = (void **)GetWindowLongA(hWnd, -21); + local_FreeMemPtr(v2); + if ( credittext_rsrc ) + { + FreeResource(credittext_rsrc); + credittext_rsrc = 0; + } +} + +// ref: 0x1000543A +void __fastcall credits_LoadImgCreditTxt(HWND hWnd, LPARAM lParam) +{ + signed int v2; // eax + HRSRC v3; // eax + HRSRC v4; // eax + DWORD *v5; // eax + DWORD *v6; // esi + int v7; // ebx + int v8; // esi + HFONT v9; // eax MAPDST + BOOL v11; // ebx + struct tagRECT Rect; // [esp+Ch] [ebp-18h] + HWND v13; // [esp+1Ch] [ebp-8h] + + if ( lParam ) + v2 = 1000 / lParam; + else + v2 = 50; + SDlgSetTimer((int)hWnd, 1, v2, 0); + v3 = FindResourceA(ghUiInst, "IDR_CREDITS", "TEXT_FILES"); + credittext_rsrc = LoadResource(ghUiInst, v3); + v4 = FindResourceA(ghUiInst, "IDR_CREDITS", "TEXT_FILES"); + credittext_size = SizeofResource(ghUiInst, v4); + v5 = local_AllocWndLongData(); + v6 = v5; + if ( v5 ) + { + SetWindowLongA(hWnd, -21, (LONG)v5); + local_LoadArtWithPal(hWnd, 0, &nullcharacter, -1, 1, "ui_art\\credits.pcx", (BYTE **)v6, v6 + 1, 0); + Fade_NoInputAndArt(hWnd, 0); + } + v13 = GetDlgItem(hWnd, 1000); + GetWindowRect(v13, &Rect); + v7 = Rect.right - Rect.left; + v8 = Rect.bottom - Rect.top + 60; + credit_back_img = SMemAlloc((Rect.right - Rect.left) * v8, "C:\\Src\\Diablo\\DiabloUI\\credits.cpp", 122, 0); + credit_horz_pos = v7; + credit_vertical_pos1 = v8; + local_AdjustRectSize(&Rect, 0, 30); + SDlgSetBitmapI(v13, 0, 0, -1, 1, credit_back_img, (int)&Rect, v7, v8, -1); + credit_vertical_pos2 = v8 - 30; + credits_CalcPosROP3(hWnd); + v9 = CreateFontA(-17, 0, 0, 0, 700, 0, 0, 0, 0, 0, 0, 0, 0x12u, "Times New Roman"); + if ( !v9 || (v11 = SGdiImportFont(v9, (int)&creditsobj), DeleteObject(v9), !v11) ) + Title_KillAndFadeDlg(hWnd); +} +// 100296E8: using guessed type int credittext_size; +// 100296FC: using guessed type int credit_vertical_pos1; + +// ref: 0x100055C0 +void __fastcall credits_CalcPosROP3(HWND hWnd) +{ + _DWORD *v2; // edi + struct tagRECT Rect; // [esp+Ch] [ebp-14h] + HWND hWnda; // [esp+1Ch] [ebp-4h] + + hWnda = GetDlgItem(hWnd, 1000); + v2 = (_DWORD *)GetWindowLongA(hWnd, -21); + GetWindowRect(hWnda, &Rect); + ScreenToClient(hWnd, (LPPOINT)&Rect); + ScreenToClient(hWnd, (LPPOINT)&Rect.right); + SBltROP3( + (char *)credit_back_img + 30 * credit_horz_pos, + (void *)(Rect.left + *v2 + Rect.top * v2[1]), + credit_horz_pos, + Rect.bottom - Rect.top, + credit_horz_pos, + v2[1], + 0, + 0xCC0020u); + --credit_vertical_pos2; + credits_PrintCredLines(hWnd); + InvalidateRect(hWnda, 0, 0); + UpdateWindow(hWnda); +} + +// ref: 0x10005660 +void __fastcall credits_PrintCredLines(HWND hWnd) +{ + char *v1; // esi + int i; // edi + int v3; // ebp + int v4; // ebx + + v1 = (char *)LockResource(credittext_rsrc); + credit_line_count = credittext_size; + SGdiSelectObject((int)creditsobj); + SGdiSetPitch(credit_horz_pos); + for ( i = credit_vertical_pos2; credit_line_count > 0; v1 = credits_GetAdjustText(v1, v4) ) + { + v3 = 0; + while ( *v1 == 9 ) + { + v3 += 40; + ++v1; + --credit_line_count; + } + v4 = credits_GetCredLineBreak(v1); + if ( v4 == -1 ) + break; + if ( i >= 0 ) + { + if ( i > credit_vertical_pos1 - 30 ) + break; + if ( v4 ) + { + SGdiTextOut(credit_back_img, v3 + 2, i + 2, 0x1000000, v1, v4); + SGdiTextOut(credit_back_img, v3, i, 16777440, v1, v4); + } + } + i += 22; + } + if ( i < 0 ) + Title_KillAndFadeDlg(hWnd); +} +// 100103A6: using guessed type int __stdcall SGdiSetPitch(_DWORD); +// 100103AC: using guessed type int __stdcall SGdiSelectObject(_DWORD); +// 100296E8: using guessed type int credittext_size; +// 100296FC: using guessed type int credit_vertical_pos1; +// 10029700: using guessed type int credit_line_count; + +// ref: 0x10005736 +int __fastcall credits_GetCredLineBreak(char *str) +{ + int result; // eax + + result = 0; + while ( *str != 13 && *str != 10 ) + { + ++result; + ++str; + if ( result > credit_line_count ) + return -1; + } + return result; +} +// 10029700: using guessed type int credit_line_count; + +// ref: 0x10005755 +char *__fastcall credits_GetAdjustText(char *str, int len) +{ + credit_line_count += -2 - len; + return &str[len + 2]; +} +// 10029700: using guessed type int credit_line_count; diff --git a/2020_03_31/DiabloUI/diabedit.cpp b/2020_03_31/DiabloUI/diabedit.cpp new file mode 100644 index 00000000..9a71c876 --- /dev/null +++ b/2020_03_31/DiabloUI/diabedit.cpp @@ -0,0 +1,267 @@ +// ref: 0x10005765 +void __fastcall DiabEdit_DoPaintBMP(HWND hWnd) +{ + struct tagPAINTSTRUCT Paint; // [esp+4h] [ebp-40h] + + BeginPaint(hWnd, &Paint); + SDlgDrawBitmap(hWnd, 1, 0, 0, 0, 0, 0); + EndPaint(hWnd, &Paint); +} + +// ref: 0x1000579B +void __cdecl DiabEdit_cpp_init() +{ + DiabEdit_cpp_float = DiabEdit_cpp_float_value; +} +// 1001F40C: using guessed type int DiabEdit_cpp_float_value; +// 1002970C: using guessed type int DiabEdit_cpp_float; + +// ref: 0x100057A6 +void __cdecl DiabEdit_SetupWindow() +{ + WNDCLASSA WndClass; // [esp+0h] [ebp-28h] + + memset(&WndClass, 0, 0x28u); + WndClass.style = 64; + WndClass.lpfnWndProc = DiabEdit_WndProc; + WndClass.hInstance = GetModuleHandleA(0); + WndClass.lpszClassName = "DIABLOEDIT"; + RegisterClassA(&WndClass); +} + +// ref: 0x100057E8 +LRESULT __stdcall DiabEdit_WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) +{ + if ( Msg <= 0x113 ) + { + if ( Msg == 275 ) + { + DiabEdit_GetCursorProp(hWnd); + return 0; + } + if ( Msg == 1 ) + { + DiabEdit_SetRestrictTimer(hWnd); + } + else if ( Msg == 2 ) + { + DiabEdit_RemoveAllProps(hWnd); + } + else + { + if ( Msg != 7 ) + { + if ( Msg == 15 ) + { + DiabEdit_DoPaintBMP(hWnd); + } + else + { + if ( Msg == 135 ) + return 129; + if ( Msg != 256 ) + { + if ( Msg == 258 ) + DiabEdit_RestrictAndLimit(hWnd, wParam, lParam); + return DefWindowProcA(hWnd, Msg, wParam, lParam); + } + DiabEdit_SetTextAndProp(hWnd, wParam, lParam); + } + return 0; + } + DiabEdit_SendWndCommand(hWnd, 1u); + } + return DefWindowProcA(hWnd, Msg, wParam, lParam); + } + switch ( Msg ) + { + case 0x201u: + SetFocus(hWnd); + return DefWindowProcA(hWnd, Msg, wParam, lParam); + case 0x400u: + SetWindowTextA(hWnd, &nullcharacter); + DiabEdit_SendWndCommand(hWnd, 3u); + return 0; + case 0x401u: + SetPropA(hWnd, "LIMIT", (HANDLE)wParam); + return 0; + case 0x402u: + return (LRESULT)GetPropA(hWnd, "LIMIT"); + } + if ( Msg != 1027 ) + { + if ( Msg == 1028 ) + { + DiabEdit_SetRestrictString(hWnd, lParam); + return 0; + } + return DefWindowProcA(hWnd, Msg, wParam, lParam); + } + return (LRESULT)GetPropA(hWnd, "CURSOR"); +} + +// ref: 0x1000591C +void __fastcall DiabEdit_SendWndCommand(HWND hWnd, WORD a2) +{ + int v4; // ST08_4 + HWND v5; // eax + + v4 = (a2 << 16) | (unsigned short)GetWindowLongA(hWnd, -12); + v5 = GetParent(hWnd); + SendMessageA(v5, 0x111u, v4, (LPARAM)hWnd); +} + +// ref: 0x1000594E +void __fastcall DiabEdit_GetCursorProp(HWND hWnd) +{ + size_t v2; // eax + char *v3; // esi + char String[256]; // [esp+Ch] [ebp-100h] + + String[0] = nullcharacter; + memset(&String[1], 0, 0xFCu); + *(_WORD *)&String[253] = 0; + String[255] = 0; + if ( GetPropA(hWnd, "CURSOR") ) + { + SetPropA(hWnd, "CURSOR", 0); + DiabEdit_SendWndCommand(hWnd, 3u); + } + else + { + SetPropA(hWnd, "CURSOR", (void *)HANDLE_FLAG_INHERIT); + GetWindowTextA(hWnd, String, 255); + String[254] = 0; + v2 = strlen(String); + String[v2 + 1] = 0; + v3 = &String[v2]; + String[v2] = 124; + SetWindowTextA(hWnd, String); + DiabEdit_SendWndCommand(hWnd, 3u); + *v3 = 0; + SetWindowTextA(hWnd, String); + } +} + +// ref: 0x10005A0A +void __fastcall DiabEdit_RestrictAndLimit(HWND hWnd, WPARAM wParam, LPARAM lParam) +{ + unsigned char v3; // bl + char *v4; // eax + char v5; // cl + signed int v6; // eax + signed int v7; // esi + //char v8; // [esp+7h] [ebp-105h] + char String[256]; // [esp+8h] [ebp-104h] + + String[0] = nullcharacter; + v3 = wParam; + memset(&String[1], 0, 0xFCu); + *(_WORD *)&String[253] = 0; + String[255] = 0; + if ( (_BYTE)wParam == 8 ) + goto LABEL_9; + if ( (unsigned char)wParam < 0x20u || (unsigned char)wParam > 0x7Eu && (unsigned char)wParam < 0xC0u ) + return; + v4 = (char *)GetPropA(hWnd, "RESTRICTED"); + if ( !v4 || (v5 = *v4) == 0 ) + { +LABEL_9: + GetWindowTextA(hWnd, String, 255); + String[254] = 0; + v6 = strlen(String); + v7 = v6; + if ( v3 == 8 ) + { + if ( v6 ) + { + String[v6-1] = 0; // *(&v8 + v6) = 0; + goto LABEL_14; + } + } + else if ( v6 < (signed int)GetPropA(hWnd, "LIMIT") ) + { + String[v7] = v3; + String[v7 + 1] = 0; +LABEL_14: + SetWindowTextA(hWnd, String); + goto LABEL_15; + } +LABEL_15: + DiabEdit_GetCursorProp(hWnd); + return; + } + while ( v3 != v5 ) + { + v5 = *++v4; + if ( !*v4 ) + goto LABEL_9; + } +} + +// ref: 0x10005AF4 +void __fastcall DiabEdit_SetTextAndProp(HWND hWnd, WPARAM wParam, LPARAM lParam) +{ + WPARAM v4; // ebx + size_t v5; // eax + //char v6; // [esp+Bh] [ebp-101h] + char String[256]; // [esp+Ch] [ebp-100h] + + String[0] = nullcharacter; + memset(&String[1], 0, 0xFCu); + *(_WORD *)&String[253] = 0; + String[255] = 0; + v4 = wParam; + GetWindowTextA(hWnd, String, 255); + String[254] = 0; + v5 = strlen(String); + if ( v4 == 37 ) + { + if ( v5 ) + { + String[v5-1] = 0; // *(&v6 + v5) = 0; + SetWindowTextA(hWnd, String); + } + DiabEdit_GetCursorProp(hWnd); + } +} + +// ref: 0x10005B70 +void __fastcall DiabEdit_SetRestrictString(HWND hWnd, LPARAM lParam) +{ + const char *v2; // edi + char *v3; // eax MAPDST + + v2 = (const char *)lParam; + v3 = (char *)GetPropA(hWnd, "RESTRICTED"); + if ( v3 ) + { + strncpy(v3, v2, 0xFFu); + v3[255] = 0; + } +} + +// ref: 0x10005B9F +void __fastcall DiabEdit_SetRestrictTimer(HWND hWnd) +{ + unsigned char *v2; // eax + + SDlgSetTimer((int)hWnd, 1, 500, 0); + SetPropA(hWnd, "CURSOR", 0); + v2 = (unsigned char *)SMemAlloc(0x100u, "C:\\Src\\Diablo\\DiabloUI\\DiabEdit.cpp", 185, 0); + *v2 = 0; + SetPropA(hWnd, "RESTRICTED", v2); +} + +// ref: 0x10005BE7 +void __fastcall DiabEdit_RemoveAllProps(HWND hWnd) +{ + HANDLE v2; // eax + + SDlgKillTimer((int)hWnd, 1); + RemovePropA(hWnd, "LIMIT"); + RemovePropA(hWnd, "CURSOR"); + v2 = RemovePropA(hWnd, "RESTRICTED"); + if ( v2 ) + SMemFree(v2, "C:\\Src\\Diablo\\DiabloUI\\DiabEdit.cpp", 200, 0); +} diff --git a/2020_03_31/DiabloUI/diabloui.cpp b/2020_03_31/DiabloUI/diabloui.cpp new file mode 100644 index 00000000..75372312 --- /dev/null +++ b/2020_03_31/DiabloUI/diabloui.cpp @@ -0,0 +1,153 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef _MSC_VER +#pragma warning (disable : 4018) // signed/unsigned mismatch +#endif + +#include "..\defs.h" +#include "..\structs.h" +#include "..\3rdParty\Storm\Source\storm.h" +#include "diabloui.h" + +#define UNKCALL __fastcall +#define USERCALL __fastcall +#define USERPURGE __fastcall + +//temporarily include everything directly +#include "_temp_funcs.h" +#include "_temp_data.cpp" + +#include "artfont.cpp" +#include "bnetgw.cpp" +#include "bn_prof.cpp" +#include "connect.cpp" +#include "copyprot.cpp" +#include "cr8game.cpp" +#include "creadung.cpp" +#include "creastat.cpp" +#include "credits.cpp" +#include "diabedit.cpp" +#include "dirlink.cpp" +#include "disclaim.cpp" +#include "doom.cpp" +#include "entdial.cpp" +#include "entname.cpp" +#include "fade.cpp" +#include "focus.cpp" +#include "local.cpp" +#include "mainmenu.cpp" +#include "modem.cpp" +#include "modmstat.cpp" +#include "okcancel.cpp" +#include "progress.cpp" +#include "sbar.cpp" +#include "selclass.cpp" +#include "selconn.cpp" +#include "seldial.cpp" +#include "selgame.cpp" +#include "selhero.cpp" +#include "selipx.cpp" +#include "sellist.cpp" +#include "selload.cpp" +#include "selmodem.cpp" +#include "selregn.cpp" +#include "selyesno.cpp" +#include "title.cpp" +#include "titlesnd.cpp" + + +// ref: 0x10005C2A +int __cdecl DiabloUI_GetSpawned() +{ + return sgbIsSpawn; +} +// 1002972C: using guessed type int sgbIsSpawn; + +// ref: 0x10005C30 +void __stdcall UiOnPaint(int a1) +{ + return; +} + +// ref: 0x10005C33 +void __stdcall UiSetBackgroundBitmap(int a1, PALETTEENTRY *a2, int a3, int a4, int a5) +{ + backbmp_flag1 = a3; + backbmp_flag2 = a4; + backbmp_flag3 = a5; + SDrawUpdatePalette(0xAu, 0xECu, a2 + 10, 0); +} +// 1002971C: using guessed type int backbmp_flag1; +// 10029720: using guessed type int backbmp_flag2; +// 10029724: using guessed type int backbmp_flag3; + +// ref: 0x10005C67 +void __stdcall UiSetSpawned(BOOL bSpawned) +{ + sgbIsSpawn = bSpawned; +} +// 1002972C: using guessed type int sgbIsSpawn; + +// ref: 0x10005C73 +void __stdcall UiInitialize() +{ + sgbUiIsInitialized = 1; + TitleSnd_InitSoundFunc(); + artfont_InitAllFonts(); + Connect_LoadGFXAndStuff(); + local_LoadArtCursor(); + bn_prof_100021C4(); +} +// 10029714: using guessed type int sgbUiIsInitialized; + +// ref: 0x10005C96 +void __stdcall UiDestroy() +{ + bn_prof_10002247(); + local_FreeArtCursor(); + Connect_FreeConnectData(); + sgbUiIsInitialized = 0; +} +// 10029714: using guessed type int sgbUiIsInitialized; + +// ref: 0x10005CAD +void __stdcall UiAppActivate(BOOL bActive) +{ + app_is_active = bActive; +} +// 10029728: using guessed type int app_is_active; + +// ref: 0x10005CB9 +BOOL __stdcall DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) +{ + if ( fdwReason ) + { + if ( fdwReason == 1 ) + { + ghUiInst = hinstDLL; + DiabEdit_SetupWindow(); + local_InitUiPalette(); + } + } + else + { + local_DelUiPalette(); + } + return 1; +} + +// ref: 0x10005CEA +void __cdecl DiabloUI_cpp_init() +{ + DiabloUI_cpp_float = DiabloUI_cpp_float_value; +} +// 1001F410: using guessed type int DiabloUI_cpp_float_value; +// 10029710: using guessed type int DiabloUI_cpp_float; diff --git a/2020_03_31/DiabloUI/diabloui.def b/2020_03_31/DiabloUI/diabloui.def new file mode 100644 index 00000000..1142f81a --- /dev/null +++ b/2020_03_31/DiabloUI/diabloui.def @@ -0,0 +1,36 @@ +LIBRARY "DiabloUI" + +EXPORTS + UiValidPlayerName + UiAppActivate + UiArtCallback + UiAuthCallback + UiBetaDisclaimer + UiCategoryCallback + UiCopyProtError + UiCreateGameCallback + UiCreateGameCriteria + UiCreatePlayerDescription + UiCreditsDialog + UiDestroy + UiDrawDescCallback + UiGetDataCallback + UiGetDefaultStats + UiInitialize + UiMainMenuDialog + UiMessageBoxCallback + UiOnPaint + UiProfileCallback + UiProfileDraw + UiProfileGetString + UiProgressDialog + UiSelHeroMultDialog + UiSelHeroSingDialog + UiSelectGame + UiSelectProvider + UiSelectRegion + UiSetBackgroundBitmap + UiSetSpawned + UiSetupPlayerInfo + UiSoundCallback + UiTitleDialog diff --git a/2020_03_31/DiabloUI/diabloui.h b/2020_03_31/DiabloUI/diabloui.h new file mode 100644 index 00000000..aad74b2d --- /dev/null +++ b/2020_03_31/DiabloUI/diabloui.h @@ -0,0 +1,65 @@ +//HEADER_GOES_HERE +#ifndef __DIABLOUI_H__ +#define __DIABLOUI_H__ + +#ifdef __GNUC__ +extern "C" { +#endif + +struct FontStruct +{ + unsigned char fontbin[258]; + HANDLE fonttrans[256]; + BOOL active; +}; + +struct ProfileStruct +{ + char *name; + char field_4; + int msg; + int field_C; +}; + +struct ProfFntStruct +{ + int size; + char *fontname; + int field_8; +}; + +void __stdcall UiDestroy(); +BOOL __stdcall UiTitleDialog(int a1); +void __stdcall UiInitialize(); +BOOL __stdcall UiCopyProtError(int *pdwResult); +void __stdcall UiAppActivate(BOOL bActive); +BOOL __fastcall UiValidPlayerName(char *name); /* check __stdcall */ +BOOL __stdcall UiSelHeroMultDialog(BOOL (__stdcall *fninfo)(BOOL (__stdcall *fninfofunc)(_uiheroinfo *)), BOOL (__stdcall *fncreate)(_uiheroinfo *), BOOL (__stdcall *fnremove)(_uiheroinfo *), BOOL (__stdcall *fnstats)(int, _uidefaultstats *), int *dlgresult, int *a6, char *name); +BOOL __stdcall UiSelHeroSingDialog(BOOL (__stdcall *fninfo)(BOOL (__stdcall *fninfofunc)(_uiheroinfo *)), BOOL (__stdcall *fncreate)(_uiheroinfo *), BOOL (__stdcall *fnremove)(_uiheroinfo *), BOOL (__stdcall *fnstats)(int, _uidefaultstats *), int *dlgresult, char *name, int *difficulty); +BOOL __stdcall UiCreditsDialog(int a1); +BOOL __stdcall UiMainMenuDialog(char *name, int *pdwResult, void (__stdcall *fnSound)(const char *file), int a4); +int __stdcall UiProgressDialog(HWND window, char *msg, int a3, void *fnfunc, int a5); +int __stdcall UiProfileGetString(); +void __stdcall UiProfileCallback(); +void __stdcall UiProfileDraw(); +BOOL __stdcall UiCategoryCallback(int a1, int a2, int a3, int a4, int a5, _DWORD *a6, _DWORD *a7); +BOOL __stdcall UiGetDataCallback(int game_type, int data_code, void *a3, int a4, int a5); +BOOL __stdcall UiAuthCallback(int a1, char *a2, char *a3, char a4, char *a5, LPSTR lpBuffer, int cchBufferMax); +BOOL __stdcall UiSoundCallback(int a1, int type, int a3); +void __stdcall UiMessageBoxCallback(HWND hWnd, char *lpText, LPCSTR lpCaption, UINT uType); +BOOL __stdcall UiDrawDescCallback(int arg0, COLORREF color, LPCSTR lpString, char *a4, int a5, UINT align, time_t a7, HDC *a8); +BOOL __stdcall UiCreateGameCallback(int a1, int a2, int a3, int a4, int a5, int a6); +BOOL __stdcall UiArtCallback(int game_type, unsigned int art_code, PALETTEENTRY *pPalette, void *pBuffer, DWORD dwBuffersize, DWORD *pdwWidth, DWORD *pdwHeight, DWORD *pdwBpp); +int __stdcall UiSelectGame(int a1, _SNETPROGRAMDATA *client_info, _SNETPLAYERDATA *user_info, _SNETUIDATA *ui_info, _SNETVERSIONDATA *file_info, DWORD *a6); +int __stdcall UiSelectProvider(int a1, _SNETPROGRAMDATA *client_info, _SNETPLAYERDATA *user_info, _SNETUIDATA *ui_info, _SNETVERSIONDATA *file_info, DWORD *type); +BOOL __stdcall UiCreatePlayerDescription(_uiheroinfo *info, int mode, char *desc); +void __stdcall UiSetupPlayerInfo(char *infostr, _uiheroinfo *pInfo, int type); +void __stdcall UiCreateGameCriteria(_uiheroinfo *pInfo, char *str); +BOOL __stdcall UiGetDefaultStats(int pclass, _uidefaultstats *pStats); +BOOL __stdcall UiBetaDisclaimer(int a1); + +#ifdef __GNUC__ +} +#endif + +#endif /* __DIABLOUI_H__ */ diff --git a/2020_03_31/DiabloUI/diabloui_gcc.def b/2020_03_31/DiabloUI/diabloui_gcc.def new file mode 100644 index 00000000..cabf1f29 --- /dev/null +++ b/2020_03_31/DiabloUI/diabloui_gcc.def @@ -0,0 +1,57 @@ +LIBRARY "DiabloUI" + +EXPORTS + UiValidPlayerName @1 + @UiValidPlayerName@4 @1 NONAME + UiAppActivate @2 + UiAppActivate@4 @2 NONAME + UiArtCallback @3 + UiArtCallback@32 @3 NONAME + UiAuthCallback @4 + UiAuthCallback@28 @4 NONAME + UiBetaDisclaimer @5 + UiBetaDisclaimer@4 @5 NONAME + UiCategoryCallback @6 + UiCategoryCallback@28 @6 NONAME + UiCopyProtError @7 + UiCreateGameCallback @8 + UiCreateGameCallback@24 @8 NONAME + UiCreateGameCriteria @9 + UiCreatePlayerDescription @10 + UiCreatePlayerDescription@12 @10 NONAME + UiCreditsDialog @11 + UiCreditsDialog@4 @11 NONAME + UiDestroy @12 + UiDrawDescCallback @13 + UiDrawDescCallback@32 @13 NONAME + UiGetDataCallback @14 + UiGetDataCallback@20 @14 NONAME + UiGetDefaultStats @15 + UiInitialize @16 + UiMainMenuDialog @17 + UiMainMenuDialog@16 @17 NONAME + UiMessageBoxCallback @18 + UiMessageBoxCallback@16 @18 NONAME + UiOnPaint @19 + UiProfileCallback @20 + UiProfileDraw @21 + UiProfileGetString @22 + UiProgressDialog @23 + UiProgressDialog@20 @23 NONAME + UiSelHeroMultDialog @24 + UiSelHeroMultDialog@28 @24 NONAME + UiSelHeroSingDialog @25 + UiSelHeroSingDialog@28 @25 NONAME + UiSelectGame @26 + UiSelectGame@24 @26 NONAME + UiSelectProvider @27 + UiSelectProvider@24 @27 NONAME + UiSelectRegion @28 + UiSetBackgroundBitmap @29 + UiSetSpawned @30 + UiSetupPlayerInfo @31 + UiSetupPlayerInfo@12 @31 NONAME + UiSoundCallback @32 + UiSoundCallback@12 @32 NONAME + UiTitleDialog @33 + UiTitleDialog@4 @33 NONAME diff --git a/2020_03_31/DiabloUI/dirlink.cpp b/2020_03_31/DiabloUI/dirlink.cpp new file mode 100644 index 00000000..276d1548 --- /dev/null +++ b/2020_03_31/DiabloUI/dirlink.cpp @@ -0,0 +1,384 @@ +// ref: 0x10005CFA +signed int DirLink_10005CFA() { return 0; } +/* { + signed int result; // eax + + result = 2139095040; + dword_10029730 = 2139095040; + return result; +} */ +// 10029730: using guessed type int dword_10029730; + +// ref: 0x10005D05 +BOOL __fastcall DirLink_10005D05(int a1, int a2, int a3, _DWORD *a4, int a5, int a6) { return 0; } +/* { + int v6; // esi + + dword_1002983C = a3; + dword_1002984C = a2; + dword_10029840 = a5; + dword_10029848 = a4; + dword_10029844 = a6; + artfont_10001159(); + v6 = SDlgDialogBoxParam(hInstance, "DIRLINK_DIALOG", a4[2], DirLink_10005D63, 0); + artfont_100010C8(); + return v6 == 1; +} */ +// 10010370: using guessed type int __stdcall SDlgDialogBoxParam(_DWORD, _DWORD, _DWORD, _DWORD, _DWORD); +// 1002983C: using guessed type int dword_1002983C; +// 10029840: using guessed type int dword_10029840; +// 10029844: using guessed type int dword_10029844; +// 1002984C: using guessed type int dword_1002984C; + +// ref: 0x10005D63 +int __stdcall DirLink_10005D63(HWND hWnd, UINT Msg, WPARAM wParam, unsigned int lParam) { return 0; } +/* { + HWND v4; // eax + int v6; // [esp+0h] [ebp-Ch] + char *v7; // [esp+4h] [ebp-8h] + char *v8; // [esp+8h] [ebp-4h] + + if ( Msg > 0x111 ) + { + switch ( Msg ) + { + case 0x113u: + if ( wParam == 3 ) + { + DirLink_100062BF(hWnd, v6, v7, v8); + DirLink_10006073(hWnd); + } + return 0; + case 0x201u: + DirLink_10006359(hWnd, (unsigned short)lParam, lParam >> 16); + break; + case 0x7E8u: + if ( !Fade_1000739F() ) + Fade_100073FD(hWnd, v6); + return 0; + } + return SDlgDefDialogProc(hWnd, Msg, wParam, lParam); + } + if ( Msg == 273 ) + { + if ( HIWORD(wParam) == 7 ) + { + Focus_100075B7(hWnd, (HWND)lParam); + } + else if ( HIWORD(wParam) == 6 ) + { + Focus_10007458((void *)lParam); + Focus_100075DC(hWnd, (HWND)lParam); + DirLink_10005EB2(hWnd, (unsigned short)wParam); + } + else if ( wParam == 327681 ) + { + DirLink_100060D1(hWnd); + } + else if ( (_WORD)wParam == 2 ) + { + DirLink_10006047((int)hWnd, 2); + } + return SDlgDefDialogProc(hWnd, Msg, wParam, lParam); + } + if ( Msg == 2 ) + { + DirLink_10005F1F(hWnd); + return SDlgDefDialogProc(hWnd, Msg, wParam, lParam); + } + if ( Msg <= 0x103 ) + return SDlgDefDialogProc(hWnd, Msg, wParam, lParam); + if ( Msg <= 0x105 ) + { + v4 = (HWND)SDrawGetFrameWindow(); + SendMessageA(v4, Msg, wParam, lParam); + return SDlgDefDialogProc(hWnd, Msg, wParam, lParam); + } + if ( Msg != 272 ) + return SDlgDefDialogProc(hWnd, Msg, wParam, lParam); + PostMessageA(hWnd, 0x7E8u, 0, 0); + DirLink_10005F7B(hWnd); + return 0; +} */ +// 1001037C: using guessed type int __stdcall SDlgDefDialogProc(_DWORD, _DWORD, _DWORD, _DWORD); +// 10010382: using guessed type _DWORD __stdcall SDrawGetFrameWindow(); + +// ref: 0x10005EB2 +int __fastcall DirLink_10005EB2(HWND hDlg, int a2) { return 0; } +/* { + HWND v2; // esi + int v3; // edi + HWND v4; // ebx + int v5; // eax + CHAR Buffer; // [esp+Ch] [ebp-100h] + + v2 = hDlg; + v3 = a2; + v4 = GetDlgItem(hDlg, 1102); + if ( v3 == 1100 ) + LoadStringA(hInstance, 0x2Au, &Buffer, 255); + else + LoadStringA(hInstance, 0x2Fu, &Buffer, 255); + v5 = GetWindowLongA(v4, -21); + local_10007FA4(v5, &Buffer); + return Doom_10006A13(v2, (int *)&unk_10022A40, 1); +} */ + +// ref: 0x10005F1F +int UNKCALL DirLink_10005F1F(HWND hDlg) { return 0; } +/* { + HWND v1; // esi + _DWORD *v2; // eax + + v1 = hDlg; + Doom_10006C53(hDlg, (int *)&unk_10022A54); + Doom_10006C53(v1, (int *)&unk_10022A48); + Doom_10006C53(v1, (int *)&unk_10022A40); + Doom_10006C53(v1, (int *)&unk_10022A38); + Doom_10006C53(v1, (int *)&unk_10022A2C); + v2 = (_DWORD *)GetWindowLongA(v1, -21); + local_10007F72(v2); + Title_100100E7(v1); + return Focus_10007818(v1); +} */ + +// ref: 0x10005F7B +int UNKCALL DirLink_10005F7B(HWND hWnd) { return 0; } +/* { + HWND v1; // esi + HWND v2; // ST1C_4 + int v3; // eax + int *v4; // edi + HWND v6; // [esp-4h] [ebp-Ch] + int v7; // [esp-4h] [ebp-Ch] + char *v8; // [esp+0h] [ebp-8h] + char *v9; // [esp+4h] [ebp-4h] + + v1 = hWnd; + Focus_100077E9((int)hWnd, "ui_art\\focus16.pcx", v6); + Title_1001009E(v1, (int)"ui_art\\smlogo.pcx", v2); + v3 = local_10007F46(); + v4 = (int *)v3; + if ( v3 ) + { + SetWindowLongA(v1, -21, v3); + local_10007944((int)v1, 0, &byte_10029448, -1, 1, (int)"ui_art\\selgame.pcx", v4, v4 + 1, 0); + Fade_100073C5(v1, 1); + } + local_10007CB5(v1, (int *)&unk_10022A54); + Doom_100068AB(v1, (int *)&unk_10022A2C, 5); + Doom_100068AB(v1, (int *)&unk_10022A38, 3); + Doom_100068AB(v1, (int *)&unk_10022A40, 1); + Doom_1000658C(v1, (int *)&unk_10022A48, 4, 0); + Doom_1000658C(v1, (int *)&unk_10022A54, 2, 1); + DirLink_100062BF(v1, v7, v8, v9); + DirLink_10006073(v1); + return SDlgSetTimer(v1, 3, 2000, 0); +} */ +// 10010412: using guessed type int __stdcall SDlgSetTimer(_DWORD, _DWORD, _DWORD, _DWORD); + +// ref: 0x10006047 +int __fastcall DirLink_10006047(int a1, int a2) { return 0; } +/* { + int v2; // edi + int v3; // esi + + v2 = a2; + v3 = a1; + TitleSnd_1001031F(); + Fade_100073B4(); + SDlgKillTimer(v3, 3); + Fade_100072BE(10); + return SDlgEndDialog(v3, v2); +} */ +// 10010376: using guessed type int __stdcall SDlgEndDialog(_DWORD, _DWORD); +// 10010418: using guessed type int __stdcall SDlgKillTimer(_DWORD, _DWORD); + +// ref: 0x10006073 +void UNKCALL DirLink_10006073(void *arg) { return; } +/* { + int v1; // esi + char v2; // [esp+4h] [ebp-100h] + char v3; // [esp+84h] [ebp-80h] + + v1 = (int)arg; + if ( dword_10029738 ) + { + Connect_10004028((int)&v2, 128, (int)&v3, 128); + if ( SNetJoinGame(dword_10029738, &byte_1002973C, 0, &v2, &v3, dword_10029844) ) + DirLink_10006047(v1, 1); + } +} */ +// 10010430: using guessed type int __stdcall SNetJoinGame(_DWORD, _DWORD, _DWORD, _DWORD, _DWORD, _DWORD); +// 10029738: using guessed type int dword_10029738; +// 10029844: using guessed type int dword_10029844; + +// ref: 0x100060D1 +HWND UNKCALL DirLink_100060D1(HWND arg) { return 0; } +/* { + HWND v1; // esi + HWND v2; // eax + HWND v3; // edi + HWND result; // eax + CHAR Buffer; // [esp+8h] [ebp-80h] + + v1 = arg; + v2 = GetFocus(); + v3 = v2; + result = GetParent(v2); + if ( v1 == result ) + { + if ( GetWindowLongA(v3, -12) == 1100 ) + { + result = (HWND)DirLink_10006141(v1); + } + else if ( dword_10029738 ) + { + result = (HWND)DirLink_100061E1(v1); + } + else + { + LoadStringA(hInstance, 0x2Bu, &Buffer, 127); + result = (HWND)SelYesNo_1000FD39((int)v1, &Buffer, 0, 0); + } + } + return result; +} */ +// 10029738: using guessed type int dword_10029738; + +// ref: 0x10006141 +int UNKCALL DirLink_10006141(void *arg) { return 0; } +/* { + int v1; // edi + int result; // eax + char v3; // [esp+8h] [ebp-E0h] + int v4; // [esp+88h] [ebp-60h] + int v5; // [esp+90h] [ebp-58h] + int v6; // [esp+D8h] [ebp-10h] + int v7; // [esp+DCh] [ebp-Ch] + int v8; // [esp+E0h] [ebp-8h] + int v9; // [esp+E4h] [ebp-4h] + + v1 = (int)arg; + Connect_10004028((int)&v3, 128, 0, 0); + memcpy(&v4, dword_10029848, 0x50u); + v4 = 80; + v5 = v1; + memset(&v6, 0, 0x10u); + v6 = 16; + v7 = 1396916812; + v8 = *(_DWORD *)(dword_1002984C + 24); + v9 = 0; + result = CreaDung_100051D8( + (int)&v6, + dword_1002984C, + dword_1002983C, + (int)&v4, + dword_10029840, + dword_10029844, + 0, + (int)&v3); + if ( result ) + result = DirLink_10006047(v1, 1); + return result; +} */ +// 1002983C: using guessed type int dword_1002983C; +// 10029840: using guessed type int dword_10029840; +// 10029844: using guessed type int dword_10029844; +// 1002984C: using guessed type int dword_1002984C; + +// ref: 0x100061E1 +int UNKCALL DirLink_100061E1(void *arg) { return 0; } +/* { + int v1; // ebx + CHAR *v2; // edx + CHAR v4; // [esp+Ch] [ebp-380h] + CHAR v5; // [esp+10Ch] [ebp-280h] + int v6; // [esp+20Ch] [ebp-180h] + char v7; // [esp+28Ch] [ebp-100h] + CHAR Buffer; // [esp+30Ch] [ebp-80h] + + v1 = (int)arg; + Connect_10004028((int)&v6, 128, (int)&v7, 128); + if ( UiAuthCallback(2, (int)&v6, &v7, 0, &byte_100297BC, &v5, 256) ) + { + if ( SNetJoinGame(dword_10029738, &byte_1002973C, 0, &v6, &v7, dword_10029844) ) + return DirLink_10006047(v1, 1); + if ( SErrGetLastError() == -2062548871 ) + LoadStringA(hInstance, 0x32u, &Buffer, 127); + else + LoadStringA(hInstance, 0x25u, &Buffer, 127); + wsprintfA(&v4, &Buffer, &byte_1002973C); + v2 = &v4; + } + else + { + v2 = &v5; + } + return SelYesNo_1000FD39(v1, v2, 0, 0); +} */ +// 10010406: using guessed type _DWORD __stdcall SErrGetLastError(); +// 10010430: using guessed type int __stdcall SNetJoinGame(_DWORD, _DWORD, _DWORD, _DWORD, _DWORD, _DWORD); +// 10029738: using guessed type int dword_10029738; +// 10029844: using guessed type int dword_10029844; + +// ref: 0x100062BF +int UNKCALL DirLink_100062BF(void *arg, int a2, char *a3, char *a4) { return 0; } +/* { + int v4; // esi + int result; // eax + CHAR Buffer; // [esp+8h] [ebp-80h] + + v4 = (int)arg; + dword_10029738 = 0; + byte_1002973C = 0; + byte_100297BC = 0; + result = SNetEnumGames(0, 0, DirLink_1000632B, 0); + if ( !result ) + { + result = SErrGetLastError(); + if ( result == -2062548871 ) + { + LoadStringA(hInstance, 0x32u, &Buffer, 127); + SelYesNo_1000FD39(v4, &Buffer, 0, 0); + result = DirLink_10006047(v4, 2); + } + } + return result; +} */ +// 10010406: using guessed type _DWORD __stdcall SErrGetLastError(); +// 10010436: using guessed type int __stdcall SNetEnumGames(_DWORD, _DWORD, _DWORD, _DWORD); +// 10029738: using guessed type int dword_10029738; + +// ref: 0x1000632B +signed int __stdcall DirLink_1000632B(int a1, char *a2, char *a3) { return 0; } +/* { + dword_10029738 = a1; + strcpy(&byte_1002973C, a2); + strcpy(&byte_100297BC, a3); + return 1; +} */ +// 10029738: using guessed type int dword_10029738; + +// ref: 0x10006359 +HWND __fastcall DirLink_10006359(HWND hWnd, int a2, int a3) { return 0; } +/* { + int v3; // ebx + HWND v4; // esi + int v5; // ST08_4 + HWND v6; // eax + HWND result; // eax + HWND v8; // eax + + v3 = a2; + v4 = hWnd; + v5 = a2; + v6 = GetDlgItem(hWnd, 1056); + if ( local_10007C3B(v4, v6, v5, a3) ) + return DirLink_100060D1(v4); + v8 = GetDlgItem(v4, 1054); + result = (HWND)local_10007C3B(v4, v8, v3, a3); + if ( result ) + result = (HWND)DirLink_10006047((int)v4, 2); + return result; +} */ diff --git a/2020_03_31/DiabloUI/disclaim.cpp b/2020_03_31/DiabloUI/disclaim.cpp new file mode 100644 index 00000000..c6a69e82 --- /dev/null +++ b/2020_03_31/DiabloUI/disclaim.cpp @@ -0,0 +1,109 @@ +// ref: 0x100063B3 +BOOL __stdcall UiBetaDisclaimer(int a1) +{ + int v1; // eax + + v1 = (int)SDrawGetFrameWindow(NULL); + SDlgDialogBoxParam(ghUiInst, "DISCLAIMER_DIALOG", v1, disclaim_WndProc, a1); + return 1; +} +// 10010382: using guessed type _DWORD __stdcall SDrawGetFrameWindow(); + +// ref: 0x100063DA +LRESULT __stdcall disclaim_WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) +{ + HWND v5; // eax + + if ( Msg > 0x111 ) + { + if ( Msg != 513 && Msg != 516 ) + { + if ( Msg == 528 ) + { + if ( (_WORD)wParam == 513 || (_WORD)wParam == 516 ) + disclaim_FadeFromDisclaim(hWnd); + } + else if ( Msg == 2024 ) + { + if ( !Fade_CheckRange5() ) + Fade_SetFadeTimer((int)hWnd); + return 0; + } + return (LRESULT)SDlgDefDialogProc(hWnd, Msg, (HDC)wParam, (HWND)lParam); + } + } + else if ( Msg != 273 ) + { + if ( Msg != 2 ) + { + if ( Msg != 256 ) + { + if ( Msg > 0x103 ) + { + if ( Msg <= 0x105 ) + { + v5 = (HWND)SDrawGetFrameWindow(NULL); + SendMessageA(v5, Msg, wParam, lParam); + } + else if ( Msg == 272 ) + { + disclaim_LoadDisclaimGFX(hWnd); + PostMessageA(hWnd, 0x7E8u, 0, 0); + return 1; + } + } + return (LRESULT)SDlgDefDialogProc(hWnd, Msg, (HDC)wParam, (HWND)lParam); + } + goto LABEL_21; + } + disclaim_DelDisclaimProcs(hWnd); + return (LRESULT)SDlgDefDialogProc(hWnd, Msg, (HDC)wParam, (HWND)lParam); + } +LABEL_21: + disclaim_FadeFromDisclaim(hWnd); + return 0; +} +// 10010382: using guessed type _DWORD __stdcall SDrawGetFrameWindow(); + +// ref: 0x100064C9 +void __fastcall disclaim_DelDisclaimProcs(HWND hWnd) +{ + void **v2; // eax + + Doom_DeleteFreeProcs(hWnd, disclaim_msgtbl2); + Doom_DeleteFreeProcs(hWnd, disclaim_msgtbl1); + v2 = (void **)GetWindowLongA(hWnd, -21); + local_FreeMemPtr(v2); +} + +// ref: 0x100064F3 +void __fastcall disclaim_LoadDisclaimGFX(HWND hWnd) +{ + DWORD *v2; // eax MAPDST + + v2 = local_AllocWndLongData(); + if ( v2 ) + { + SetWindowLongA(hWnd, -21, (LONG)v2); + local_LoadArtWithPal(hWnd, 0, &nullcharacter, -1, 1, "ui_art\\disclaim.pcx", (BYTE **)v2, v2 + 1, 0); + Fade_NoInputAndArt(hWnd, 0); + } + Doom_ParseWndProc3(hWnd, disclaim_msgtbl1, 5); + Doom_ParseWndProc3(hWnd, disclaim_msgtbl2, 2); +} + +// ref: 0x10006552 +void __fastcall disclaim_FadeFromDisclaim(HWND hWnd) +{ + Fade_Range5SetZero(); + Fade_UpdatePaletteRange(10); + SDlgEndDialog(hWnd, (void *)HANDLE_FLAG_INHERIT); +} + +// ref: 0x10006571 +void __cdecl disclaim_cpp_init() +{ + disclaim_cpp_float = disclaim_cpp_float_value; +} +// 1001F418: using guessed type int disclaim_cpp_float_value; +// 10029850: using guessed type int disclaim_cpp_float; diff --git a/2020_03_31/DiabloUI/doom.cpp b/2020_03_31/DiabloUI/doom.cpp new file mode 100644 index 00000000..ba821d30 --- /dev/null +++ b/2020_03_31/DiabloUI/doom.cpp @@ -0,0 +1,404 @@ +// ref: 0x10006581 +void __cdecl Doom_cpp_init() +{ + doom_cpp_float = doom_cpp_float_value; +} +// 1001F41C: using guessed type int doom_cpp_float_value; +// 10029854: using guessed type int doom_cpp_float; + +// ref: 0x1000658C +void __fastcall Doom_ParseWndProcs(HWND hWnd, int *msgtbl, int a3, int a4) +{ + HWND v6; // eax + + while ( *msgtbl ) + { + v6 = GetDlgItem(hWnd, *msgtbl); + Doom_GetSetWndText(hWnd, (int)v6, a3, a4); + ++msgtbl; + } +} + +// ref: 0x100065BB +void __fastcall Doom_GetSetWndText(HWND hWnd, int msg, int nFont, int a4) +{ + HWND v4; // esi + HWND v5; // edi + int v6; // eax + char String[256]; // [esp+8h] [ebp-100h] + + v4 = (HWND)msg; + v5 = hWnd; + if ( msg ) + { + Doom_AllocAndSetBMP(hWnd, msg, 1521); + Doom_GetWindowROP3(v5, v4); + artfont_SetArtFont(nFont); + Doom_PrintStrWithSpin(v4, a4); + GetWindowTextA(v4, String, 255); + if ( strlen(String) ) + { + v6 = GetWindowLongA(v4, -21); + local_SetWndLongStr(v6, String); + SetWindowTextA(v4, &nullcharacter); + } + } +} + +// ref: 0x1000663F +void __fastcall Doom_PrintStrWithSpin(HWND hWnd, BOOL a2) +{ + _DWORD *v3; // eax + _DWORD *v4; // esi + char *v5; // ebx + int v6; // edi + size_t v7; // eax + char *i; // eax + int v9; // kr04_4 + int v10; // eax + char String[256]; // [esp+8h] [ebp-10Ch] + char *v12; // [esp+108h] [ebp-Ch] + int v14; // [esp+110h] [ebp-4h] + + v3 = (_DWORD *)GetWindowLongA(hWnd, -21); + v4 = v3; + if ( v3 && *v3 ) + { + GetWindowTextA(hWnd, String, 255); + v5 = String; + if ( !strlen(String) ) + v5 = (char *)(v4 + 4); + v14 = artfont_GetFontWidth(v5); + if ( a2 ) + { + v6 = v4[1] - 2 * Focus_GetSpinWidthOrZero(); + v7 = strlen(v5); + if ( v14 > v6 ) + { + for ( i = &v5[v7]; ; i = v12 ) + { + v12 = i - 1; + *v12 = 0; + v14 = artfont_GetFontWidth(v5); + if ( v14 <= v6 ) + break; + } + } + } + v9 = v4[1] - v14 - 1; + v10 = artfont_GetFontMaxHeight(); + artfont_PrintFontStr(v5, (DWORD **)v4, v9 / 2, (v4[2] - v10) / 2); + InvalidateRect(hWnd, 0, 0); + } +} + +// ref: 0x10006719 +void __fastcall Doom_AllocAndSetBMP(HWND hWnd, int a2, int bmp_flags) +{ + DWORD *v4; // esi + struct tagRECT Rect; // [esp+8h] [ebp-10h] + + GetClientRect((HWND)a2, &Rect); + v4 = local_AllocWndLongData(); + v4[1] = Rect.right; + v4[2] = Rect.bottom; + *v4 = (DWORD)SMemAlloc(Rect.right * Rect.bottom, "C:\\Src\\Diablo\\DiabloUI\\Doom.cpp", 139, 0); + SetWindowLongA((HWND)a2, -21, (LONG)v4); + SDlgSetBitmapI((HWND)a2, 0, &nullcharacter, -1, bmp_flags, (void *)*v4, 0, v4[1], v4[2], -1); +} + +// ref: 0x1000678A +void __fastcall Doom_GetWindowROP3(HWND hWnd1, HWND hWnd2) +{ + _DWORD *v3; // ebx + LONG v4; // eax MAPDST + struct tagRECT Rect; // [esp+Ch] [ebp-14h] + + v3 = (_DWORD *)GetWindowLongA(hWnd1, -21); + v4 = GetWindowLongA(hWnd2, -21); + if ( v3 && *v3 && v4 ) + { + if ( *(_DWORD *)v4 ) + { + GetWindowRect(hWnd2, &Rect); + ScreenToClient(hWnd1, (LPPOINT)&Rect); + ScreenToClient(hWnd1, (LPPOINT)&Rect.right); + SBltROP3( + *(void **)v4, + (void *)(Rect.left + *v3 + Rect.top * v3[1]), + *(_DWORD *)(v4 + 4), + *(_DWORD *)(v4 + 8), + *(_DWORD *)(v4 + 4), + v3[1], + 0, + 0xCC0020u); + } + } +} + +// ref: 0x1000680A +void __fastcall Doom_ParseWndProc2(HWND hWnd, int *msgtbl, int a3, int a4) +{ + HWND v6; // eax + + while ( *msgtbl ) + { + v6 = GetDlgItem(hWnd, *msgtbl); + Doom_GetSetWndTxt2(hWnd, (int)v6, a3, a4); + ++msgtbl; + } +} + +// ref: 0x10006839 +void __fastcall Doom_GetSetWndTxt2(HWND hWnd, int msg, int nFont, int a4) +{ + HWND v4; // esi + int v5; // eax + char String[256]; // [esp+4h] [ebp-100h] + + v4 = (HWND)msg; + if ( msg ) + { + Doom_GetWindowROP3(hWnd, (HWND)msg); + artfont_SetArtFont(nFont); + Doom_PrintStrWithSpin(v4, a4); + GetWindowTextA(v4, String, 255); + if ( strlen(String) ) + { + v5 = GetWindowLongA(v4, -21); + local_SetWndLongStr(v5, String); + SetWindowTextA(v4, &nullcharacter); + } + } +} + +// ref: 0x100068AB +void __fastcall Doom_ParseWndProc3(HWND hWnd, int *msgtbl, int a3) +{ + HWND v5; // eax + + while ( *msgtbl ) + { + v5 = GetDlgItem(hWnd, *msgtbl); + Doom_GetSetWndTxt3(hWnd, (int)v5, a3); + ++msgtbl; + } +} + +// ref: 0x100068D6 +void __fastcall Doom_GetSetWndTxt3(HWND hWnd, int msg, int nFont) +{ + HWND v3; // esi + HWND v4; // edi + int v5; // eax + int v6; // eax + char String[256]; // [esp+8h] [ebp-100h] + + v3 = (HWND)msg; + v4 = hWnd; + if ( msg ) + { + Doom_AllocAndSetBMP(hWnd, msg, 1); + Doom_GetWindowROP3(v4, v3); + artfont_SetArtFont(nFont); + v5 = GetWindowLongA(v3, -16); + Doom_PrintStrWithSpn2(v3, v5); + GetWindowTextA(v3, String, 255); + if ( strlen(String) ) + { + v6 = GetWindowLongA(v3, -21); + local_SetWndLongStr(v6, String); + SetWindowTextA(v3, &nullcharacter); + } + } +} + +// ref: 0x1000695D +void __fastcall Doom_PrintStrWithSpn2(HWND hWnd, int justify_type) +{ + _DWORD *v2; // eax + _DWORD *v3; // esi + char *v4; // edi + int v5; // eax + char String[256]; // [esp+4h] [ebp-108h] + + v2 = (_DWORD *)GetWindowLongA(hWnd, -21); + v3 = v2; + if ( v2 && *v2 ) + { + GetWindowTextA(hWnd, String, 255); + v4 = String; + if ( !strlen(String) ) + v4 = (char *)(v3 + 4); + if ( justify_type & 2 ) + { + v5 = v3[1] - artfont_GetFontWidth(v4) - 1; + } + else if ( justify_type & 1 ) + { + v5 = (v3[1] - artfont_GetFontWidth(v4) - 1) / 2; + } + else + { + v5 = 0; + } + artfont_PrintFontStr(v4, (DWORD **)v3, v5, 0); + InvalidateRect(hWnd, 0, 0); + } +} + +// ref: 0x10006A13 +void __fastcall Doom_ParseWndProc4(HWND hWnd, int *msgtbl, int a3) +{ + HWND v5; // eax + + while ( *msgtbl ) + { + v5 = GetDlgItem(hWnd, *msgtbl); + Doom_GetSetWndTxt4(hWnd, (int)v5, a3); + ++msgtbl; + } +} + +// ref: 0x10006A3E +void __fastcall Doom_GetSetWndTxt4(HWND hWnd, int msg, int nFont) +{ + HWND v3; // edi + int v4; // eax + int v5; // eax + char String[256]; // [esp+8h] [ebp-100h] + + v3 = (HWND)msg; + if ( msg ) + { + Doom_GetWindowROP3(hWnd, (HWND)msg); + artfont_SetArtFont(nFont); + v4 = GetWindowLongA(v3, -16); + Doom_PrintStrWithSpn2(v3, v4); + GetWindowTextA(v3, String, 255); + if ( strlen(String) ) + { + v5 = GetWindowLongA(v3, -21); + local_SetWndLongStr(v5, String); + SetWindowTextA(v3, &nullcharacter); + } + } +} + +// ref: 0x10006AB8 +void __fastcall Doom_ParseWndProc5(HWND hWnd, int *msgtbl, int a3) +{ + HWND v5; // eax + + while ( *msgtbl ) + { + v5 = GetDlgItem(hWnd, *msgtbl); + Doom_GetSetWndTxt5(hWnd, (int)v5, a3); + ++msgtbl; + } +} + +// ref: 0x10006AE3 +void __fastcall Doom_GetSetWndTxt5(HWND hWnd, int msg, int nFont) +{ + HWND v3; // esi + + v3 = (HWND)msg; + if ( msg ) + { + Doom_AllocAndSetBMP(hWnd, msg, 1); + Doom_GetWindowROP3(hWnd, v3); + artfont_SetArtFont(nFont); + Doom_PrintTextMsg403(v3); + } +} + +// ref: 0x10006B12 +void __fastcall Doom_PrintTextMsg403(HWND hWnd) +{ + BYTE *v2; // eax + int v3; // edi + int v4; // edi + int v5; // esi + int v6; // esi + char *i; // ebx + int v8; // eax + //char v9; // [esp+3h] [ebp-11Dh] + char String[256]; // [esp+4h] [ebp-11Ch] + struct tagRECT Rect; // [esp+104h] [ebp-1Ch] + LRESULT v12; // [esp+114h] [ebp-Ch] + BYTE *pWidthBin; // [esp+118h] [ebp-8h] + size_t v14; // [esp+11Ch] [ebp-4h] + + v2 = (BYTE *)GetWindowLongA(hWnd, -21); + pWidthBin = v2; + if ( v2 && *(_DWORD *)v2 ) + { + GetWindowTextA(hWnd, String, 255); + v14 = strlen(String); + v3 = Focus_GetSpinWidthOrZero(); + v4 = artfont_GetFontDefWidth() + v3; + GetClientRect(hWnd, &Rect); + v5 = Focus_GetSpinWidthOrZero(); + v6 = Rect.right - 2 * (artfont_GetFontDefWidth() + v5); + v12 = SendMessageA(hWnd, 0x403u, 0, 0); + if ( v12 == 1 ) + String[v14-1] = 0; // *(&v9 + v14) = 0; + for ( i = String; *i; ++i ) + { + if ( artfont_GetFontWidth(i) <= v6 ) + break; + } + if ( v12 ) + String[v14-1] = 124; // *(&v9 + v14) = 124; + v8 = artfont_GetFontMaxHeight(); + artfont_PrintFontStr(i, (DWORD **)pWidthBin, v4, (*((_DWORD *)pWidthBin + 2) - v8) / 2); + } +} + +// ref: 0x10006C08 +void __fastcall Doom_ParseWndProc6(HWND hWnd, int *msgtbl, int a3) +{ + HWND v5; // eax + + while ( *msgtbl ) + { + v5 = GetDlgItem(hWnd, *msgtbl); + Doom_GetSetWndTxt6(hWnd, (int)v5, a3); + ++msgtbl; + } +} + +// ref: 0x10006C33 +void __fastcall Doom_GetSetWndTxt6(HWND hWnd, int msg, int nFont) +{ + HWND v3; // esi + + v3 = (HWND)msg; + if ( msg ) + { + Doom_GetWindowROP3(hWnd, (HWND)msg); + artfont_SetArtFont(nFont); + Doom_PrintTextMsg403(v3); + } +} + +// ref: 0x10006C53 +void __fastcall Doom_DeleteFreeProcs(HWND hWnd, int *msgtbl) +{ + int i; // eax + HWND v5; // eax MAPDST + void **v7; // eax + + for ( i = *msgtbl; *msgtbl; i = *msgtbl ) + { + v5 = GetDlgItem(hWnd, i); + if ( v5 ) + { + v7 = (void **)GetWindowLongA(v5, -21); + local_FreeMemPtr(v7); + SetWindowLongA(v5, -21, 0); + } + ++msgtbl; + } +} diff --git a/2020_03_31/DiabloUI/entdial.cpp b/2020_03_31/DiabloUI/entdial.cpp new file mode 100644 index 00000000..2d02be1d --- /dev/null +++ b/2020_03_31/DiabloUI/entdial.cpp @@ -0,0 +1,188 @@ +// ref: 0x10006C96 +int __stdcall EntDial_10006C96(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam) { return 0; } +/* { + int v4; // edx + HWND v5; // eax + HWND v7; // eax + int savedregs; // [esp+Ch] [ebp+0h] + + v4 = 2; + if ( Msg == 2 ) + { + EntDial_10006D78(hDlg); + } + else if ( Msg > 0x103 ) + { + if ( Msg <= 0x105 ) + { + v7 = (HWND)SDrawGetFrameWindow(); + SendMessageA(v7, Msg, wParam, lParam); + } + else + { + if ( Msg == 272 ) + { + lpString = (LPSTR)lParam; + EntDial_10006DB8(hDlg, (int)&savedregs); + return 0; + } + if ( Msg != 273 ) + { + if ( Msg != 275 ) + { + if ( Msg == 513 ) + EntDial_10006F16(hDlg, (unsigned short)lParam, (unsigned int)lParam >> 16); + return SDlgDefDialogProc(hDlg, Msg, wParam, lParam); + } + v5 = GetFocus(); + Focus_100075DC(hDlg, v5); + return 0; + } + if ( (unsigned short)wParam == 1 ) + { + v4 = 1; + } + else if ( (unsigned short)wParam != 2 ) + { + if ( (unsigned short)wParam == 1116 ) + EntDial_10006EE8(hDlg, wParam, lParam); + return SDlgDefDialogProc(hDlg, Msg, wParam, lParam); + } + EntDial_10006EA7(hDlg, v4); + } + } + return SDlgDefDialogProc(hDlg, Msg, wParam, lParam); +} */ +// 1001037C: using guessed type int __stdcall SDlgDefDialogProc(_DWORD, _DWORD, _DWORD, _DWORD); +// 10010382: using guessed type _DWORD __stdcall SDrawGetFrameWindow(); + +// ref: 0x10006D78 +HWND UNKCALL EntDial_10006D78(HWND hDlg) { return 0; } +/* { + HWND v1; // esi + HWND v2; // eax + + v1 = hDlg; + Focus_100076C3(); + Doom_10006C53(v1, (int *)&unk_10022B10); + Doom_10006C53(v1, (int *)&unk_10022B04); + Doom_10006C53(v1, (int *)&unk_10022AFC); + v2 = GetParent(v1); + return Modem_10008563(v2, 0, 0); +} */ + +// ref: 0x10006DB8 +HWND USERCALL EntDial_10006DB8(HWND hWnd, int a2) { return 0; } +/* { + HWND v2; // esi + HWND v3; // eax + LONG v4; // eax + HWND v5; // ebx + HWND v6; // eax + int v8; // [esp-138h] [ebp-144h] + int v9; // [esp-38h] [ebp-44h] + int v10; // [esp+8h] [ebp-4h] + + v2 = hWnd; + v3 = GetParent(hWnd); + v4 = GetWindowLongA(v3, -21); + SetWindowLongA(v2, -21, v4); + Doom_100068AB(v2, (int *)&unk_10022AFC, 5); + Doom_1000658C(v2, (int *)&unk_10022B04, 4, 0); + Doom_10006AB8(v2, (int *)&unk_10022B10, 2); + Focus_10007719("ui_art\\focus.pcx"); + SDlgSetTimer(v2, 1, 55, 0); + v5 = GetDlgItem(v2, 1116); + SendMessageA(v5, 0x401u, 0x1Fu, 0); + SendMessageA(v5, 0x404u, 0, (LPARAM)"<>%&?"); + v10 = a2; + LoadStringA(hInstance, 0x3Bu, (LPSTR)&v9, 63); + LoadStringA(hInstance, 0x3Au, (LPSTR)&v8, 255); + v6 = GetParent(v2); + return Modem_10008563(v6, (const char *)&v9, (int)&v8); +} */ +// 10006DB8: could not find valid save-restore pair for ebp +// 10010412: using guessed type int __stdcall SDlgSetTimer(_DWORD, _DWORD, _DWORD, _DWORD); + +// ref: 0x10006EA7 +int __fastcall EntDial_10006EA7(HWND hDlg, int a2) { return 0; } +/* { + int v2; // edi + HWND v3; // esi + CHAR *v4; // ST08_4 + HWND v5; // eax + + v2 = a2; + v3 = hDlg; + TitleSnd_1001031F(); + SDlgKillTimer(v3, 1); + v4 = lpString; + v5 = GetDlgItem(v3, 1116); + GetWindowTextA(v5, v4, 32); + lpString[31] = 0; + return SDlgEndDialog(v3, v2); +} */ +// 10010376: using guessed type int __stdcall SDlgEndDialog(_DWORD, _DWORD); +// 10010418: using guessed type int __stdcall SDlgKillTimer(_DWORD, _DWORD); + +// ref: 0x10006EE8 +void __fastcall EntDial_10006EE8(HWND hWnd, unsigned int a2, int a3) { return; } +/* { + int v3; // edx + HWND v4; // esi + HWND v5; // eax + + v3 = (a2 >> 16) - 1; + v4 = hWnd; + if ( v3 ) + { + if ( v3 == 2 ) + Doom_10006C08(hWnd, (int *)&unk_10022B10, 2); + } + else + { + v5 = GetFocus(); + Focus_100075DC(v4, v5); + } +} */ + +// ref: 0x10006F16 +int __fastcall EntDial_10006F16(HWND hDlg, int a2, int a3) { return 0; } +/* { + int v3; // ebx + HWND v4; // esi + int v5; // ST08_4 + HWND v6; // eax + int v7; // edx + HWND v8; // eax + int result; // eax + + v3 = a2; + v4 = hDlg; + v5 = a2; + v6 = GetDlgItem(hDlg, 1056); + if ( local_10007C3B(v4, v6, v5, a3) ) + { + v7 = 1; + } + else + { + v8 = GetDlgItem(v4, 1054); + result = local_10007C3B(v4, v8, v3, a3); + if ( !result ) + return result; + v7 = 2; + } + return EntDial_10006EA7(v4, v7); +} */ + +// ref: 0x10006F71 +signed int EntDial_10006F71() { return 0; } +/* { + signed int result; // eax + + result = 2139095040; + dword_1002985C = 2139095040; + return result; +} */ +// 1002985C: using guessed type int dword_1002985C; diff --git a/2020_03_31/DiabloUI/entname.cpp b/2020_03_31/DiabloUI/entname.cpp new file mode 100644 index 00000000..4ebffc47 --- /dev/null +++ b/2020_03_31/DiabloUI/entname.cpp @@ -0,0 +1,147 @@ +// ref: 0x10006F7C +LRESULT __stdcall EntName_WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) +{ + int v4; // edx + HWND v5; // eax + HWND v6; // eax + HWND v7; // eax + HWND v9; // eax + + v4 = 2; + if ( Msg == 2 ) + { + EntName_DelEntNameMsgs(hWnd); + return (LRESULT)SDlgDefDialogProc(hWnd, Msg, (HDC)wParam, (HWND)lParam); + } + if ( Msg <= 0x103 ) + return (LRESULT)SDlgDefDialogProc(hWnd, Msg, (HDC)wParam, (HWND)lParam); + if ( Msg <= 0x105 ) + { + v9 = (HWND)SDrawGetFrameWindow(NULL); + SendMessageA(v9, Msg, wParam, lParam); + return (LRESULT)SDlgDefDialogProc(hWnd, Msg, (HDC)wParam, (HWND)lParam); + } + switch ( Msg ) + { + case 0x110u: + entname_charname = (char *)lParam; + EntName_LoadFocusChkName(hWnd); + return 0; + case 0x111u: + if ( (unsigned short)wParam != 1 ) + { + if ( (unsigned short)wParam != 2 ) + { + if ( (unsigned short)wParam == 1065 ) + EntName_GetMessageName(hWnd, wParam, lParam); + return (LRESULT)SDlgDefDialogProc(hWnd, Msg, (HDC)wParam, (HWND)lParam); + } + goto LABEL_11; + } + goto LABEL_18; + case 0x113u: + v7 = GetFocus(); + Focus_DoBlitSpinIncFrame(hWnd, v7); + return 0; + } + if ( Msg != 513 ) + return (LRESULT)SDlgDefDialogProc(hWnd, Msg, (HDC)wParam, (HWND)lParam); + v5 = GetDlgItem(hWnd, 1056); + if ( local_GetBottomRect(hWnd, v5, (unsigned short)lParam, (unsigned int)lParam >> 16) ) + { +LABEL_18: + v4 = 1; + goto LABEL_11; + } + v6 = GetDlgItem(hWnd, 1054); + if ( local_GetBottomRect(hWnd, v6, (unsigned short)lParam, (unsigned int)lParam >> 16) ) + { + v4 = 2; +LABEL_11: + EntName_SetCharName(hWnd, v4); + } + return (LRESULT)SDlgDefDialogProc(hWnd, Msg, (HDC)wParam, (HWND)lParam); +} +// 10010382: using guessed type _DWORD __stdcall SDrawGetFrameWindow(); + +// ref: 0x1000709E +void __fastcall EntName_DelEntNameMsgs(HWND hWnd) +{ + HWND v2; // eax + + Focus_DeleteSpinners(); + Doom_DeleteFreeProcs(hWnd, entname_msgtbl3); + Doom_DeleteFreeProcs(hWnd, entname_msgtbl2); + Doom_DeleteFreeProcs(hWnd, entname_msgtbl1); + v2 = GetParent(hWnd); + SelHero_SetStringWithMsg(v2, 0); +} + +// ref: 0x100070DB +void __fastcall EntName_LoadFocusChkName(HWND hWnd) +{ + HWND v2; // edi + LONG v3; // eax + HWND v4; // ebx + char Buffer[32]; // [esp+Ch] [ebp-20h] + + v2 = GetParent(hWnd); + if ( SelHero_GetHeroIsGood() == 1 ) + LoadStringA(ghUiInst, 0x20u, Buffer, 31); + else + LoadStringA(ghUiInst, 0x1Fu, Buffer, 31); + SelHero_SetStringWithMsg(v2, Buffer); + v3 = GetWindowLongA(v2, -21); + SetWindowLongA(hWnd, -21, v3); + Doom_ParseWndProc3(hWnd, entname_msgtbl1, 5); + Doom_ParseWndProcs(hWnd, entname_msgtbl2, 4, 0); + Doom_ParseWndProc5(hWnd, entname_msgtbl3, 2); + Focus_LoadSpinner("ui_art\\focus.pcx"); + SDlgSetTimer((int)hWnd, 1, 55, 0); + v4 = GetDlgItem(hWnd, 1065); + SendMessageA(v4, 0x401u, 0xFu, 0); + if ( SelHero_GetHeroIsGood() == 1 ) + SendMessageA(v4, 0x404u, 0, (LPARAM)" ,<>%&\\\"?*#/"); +} + +// ref: 0x100071AC +void __fastcall EntName_SetCharName(HWND hWnd, int a2) +{ + char *v4; // ST08_4 + HWND v5; // eax + + TitleSnd_PlaySelectSound(); + SDlgKillTimer((int)hWnd, 1); + v4 = entname_charname; + v5 = GetDlgItem(hWnd, 1065); + GetWindowTextA(v5, v4, 16); + entname_charname[15] = 0; + SDlgEndDialog(hWnd, (HANDLE)a2); +} + +// ref: 0x100071ED +void __fastcall EntName_GetMessageName(HWND hWnd, unsigned int a2, int a3) +{ + unsigned int v3; // edx + HWND v5; // eax + + v3 = (a2 >> 16) - 1; + if ( v3 ) + { + if ( v3 == 2 ) + Doom_ParseWndProc6(hWnd, entname_msgtbl3, 2); + } + else + { + v5 = GetFocus(); + Focus_DoBlitSpinIncFrame(hWnd, v5); + } +} + +// ref: 0x10007220 +void __cdecl EntName_cpp_init() +{ + EntName_cpp_float = EntName_cpp_float_value; +} +// 1001F424: using guessed type int EntName_cpp_float_value; +// 10029860: using guessed type int EntName_cpp_float; diff --git a/2020_03_31/DiabloUI/fade.cpp b/2020_03_31/DiabloUI/fade.cpp new file mode 100644 index 00000000..04184a51 --- /dev/null +++ b/2020_03_31/DiabloUI/fade.cpp @@ -0,0 +1,157 @@ +// ref: 0x1000722B +void __fastcall Fade_ApplyPaletteRange(int range1, int range2) +{ + tagPALETTEENTRY *v4; // eax MAPDST + BYTE *v6; // esi + BYTE v7; // al + + v4 = local_GetArtPalEntry(0); + if ( range1 == range2 ) + { + memcpy(fadepal, v4, 0x400u); + } + else if ( range2 ) + { + v6 = &fadepal[0].peGreen; + do + { + v7 = range2 * v4->peRed / range1; + ++v4; + *(v6 - 1) = v7; + *v6 = range2 * v4[-1].peGreen / range1; + v6 += 4; + *(v6 - 3) = range2 * v4[-1].peBlue / range1; + } + while ( (signed int)v6 < (signed int)&fadepal[256].peGreen ); + } + else + { + memcpy(fadepal, v4, 0x400u); + local_ClearPalette(fadepal); + } + SDrawUpdatePalette(0, 0x100u, fadepal, 1); +} + +// ref: 0x100072BE +void __fastcall Fade_UpdatePaletteRange(int range) +{ + tagPALETTEENTRY *v2; // eax + tagPALETTEENTRY *v3; // edi + BYTE *v4; // ecx + BYTE v5; // al + HPALETTE v6; // ebx + int v7; // [esp+10h] [ebp-4h] + + v2 = local_GetArtPalEntry(0); + memcpy(fadepal, v2, 0x400u); + if ( range > 0 ) + { + v7 = range; + do + { + v3 = local_GetArtPalEntry(0); + v4 = &fadepal[0].peGreen; + do + { + v5 = v3->peRed / range; + ++v3; + *(v4 - 1) -= v5; + *v4 -= v3[-1].peGreen / range; + v4 += 4; + *(v4 - 3) -= v3[-1].peBlue / range; + } + while ( (signed int)v4 < (signed int)&fadepal[256].peGreen ); + SDrawUpdatePalette(0, 0x100u, fadepal, 1); + --v7; + } + while ( v7 ); + } + local_ClearPalette(fadepal); + SDrawUpdatePalette(0, 0x100u, fadepal, 1); + local_SetCursorDefault(); + SDrawClearSurface(0); + v6 = (HPALETTE)GetStockObject(15); + GetPaletteEntries(v6, 0, 0xAu, fadepal); + GetPaletteEntries(v6, 0xAu, 0xAu, &fadepal[246]); + SDrawUpdatePalette(0, 0x100u, fadepal, 1); +} +// 1001043C: using guessed type int __stdcall SDrawClearSurface(_DWORD); + +// ref: 0x1000739F +BOOL __cdecl Fade_CheckRange5() +{ + BOOL result; // eax + + result = 0; + if ( sgbIsFading ) + { + if ( sgbFadeRange <= 5 ) + result = 1; + } + return result; +} +// 10029C70: using guessed type int sgbIsFading; + +// ref: 0x100073B4 +void __cdecl Fade_Range5SetZero() +{ + if ( Fade_CheckRange5() ) + sgbIsFading = 0; +} +// 10029C70: using guessed type int sgbIsFading; + +// ref: 0x100073C5 +void __fastcall Fade_NoInputAndArt(HWND hWnd, BOOL bShowCurs) +{ + HWND v3; // eax + + v3 = GetParent(hWnd); + local_DisableKeyWaitMouse(v3); + if ( bShowCurs ) + local_SetCursorArt(); + sgbIsFading = 0; + sgbFadeRange = 0; +} +// 10029C70: using guessed type int sgbIsFading; + +// ref: 0x100073EF +void __fastcall Fade_SetInputWindow(HWND hWnd) +{ + HWND v1; // eax + + v1 = GetParent(hWnd); + local_DisableKeyWaitMouse(v1); +} + +// ref: 0x100073FD +void __fastcall Fade_SetFadeTimer(int nTime) +{ + if ( !sgbIsFading ) + { + SDlgSetTimer(nTime, 16, 50, Fade_TimerFunctionDlg); + sgbIsFading = 1; + } +} +// 10029C70: using guessed type int sgbIsFading; + +// ref: 0x10007420 +void __stdcall Fade_TimerFunctionDlg(int a1, int a2, int a3, int a4) +{ + if ( sgbFadeRange > 5 ) + { + SDlgKillTimer(a1, 16); + } + else + { + Fade_ApplyPaletteRange(5, sgbFadeRange); + ++sgbFadeRange; + } +} + +// ref: 0x1000744D +void __cdecl Fade_cpp_init() +{ + fade_cpp_float = fade_cpp_float_value; +} +// 1001F428: using guessed type int fade_cpp_float_value; +// 10029868: using guessed type int fade_cpp_float; diff --git a/2020_03_31/DiabloUI/focus.cpp b/2020_03_31/DiabloUI/focus.cpp new file mode 100644 index 00000000..31d8e853 --- /dev/null +++ b/2020_03_31/DiabloUI/focus.cpp @@ -0,0 +1,246 @@ +// ref: 0x10007458 +void __fastcall Focus_CheckPlayMove(LPARAM lParam) +{ + if ( sgbSpinnersLoaded && lParam != dword_10029CA8 ) + { + if ( dword_10029CAC ) + TitleSnd_PlayMoveSound(); + dword_10029CA8 = lParam; + } +} +// 10029CA4: using guessed type int sgbSpinnersLoaded; +// 10029CA8: using guessed type int dword_10029CA8; +// 10029CAC: using guessed type int dword_10029CAC; + +// ref: 0x10007482 +int __cdecl Focus_GetSpinWidthOrZero() +{ + return sgbSpinnersLoaded != 0 ? focus_spin_width : 0; +} +// 10029CA4: using guessed type int sgbSpinnersLoaded; + +// ref: 0x10007492 +void __fastcall Focus_BlitSpinner(HWND hWnd1, HWND hWnd2) +{ + _DWORD *v2; // edi + LONG v3; // eax MAPDST + int v5; // eax MAPDST + int v7; // eax + struct tagRECT Rect; // [esp+8h] [ebp-18h] + char *v9; // [esp+18h] [ebp-8h] + + v9 = (char *)hWnd1; + v2 = (_DWORD *)GetWindowLongA(hWnd1, -21); + v3 = GetWindowLongA(hWnd2, -21); + if ( v2 && v3 && *v2 ) + { + if ( *(_DWORD *)v3 ) + { + GetWindowRect(hWnd2, &Rect); + ScreenToClient((HWND)v9, (LPPOINT)&Rect); + ScreenToClient((HWND)v9, (LPPOINT)&Rect.right); + SBltROP3( + *(void **)v3, + (void *)(Rect.left + *v2 + Rect.top * v2[1]), + focus_spin_width, + *(_DWORD *)(v3 + 8), + *(_DWORD *)(v3 + 4), + v2[1], + 0, + 0xCC0020u); + v5 = v2[1]; + v7 = *v2 + Rect.top * v5; + v9 = *(char **)(v3 + 4); + SBltROP3( + &v9[*(_DWORD *)v3 - focus_spin_width], + &v9[v7 - focus_spin_width + Rect.left], + focus_spin_width, + *(_DWORD *)(v3 + 8), + (int)v9, + v5, + 0, + 0xCC0020u); + Focus_CenterSpinFromSide(hWnd2); + } + } +} + +// ref: 0x10007566 +void __fastcall Focus_CenterSpinFromSide(HWND hWnd) +{ + struct tagRECT Rect; // [esp+8h] [ebp-10h] + + GetClientRect(hWnd, &Rect); + --Rect.bottom; + Rect.left = --Rect.right - focus_spin_width; + InvalidateRect(hWnd, &Rect, 0); + Rect.left = 0; + Rect.right = focus_spin_width - 1; + InvalidateRect(hWnd, &Rect, 0); +} + +// ref: 0x100075B7 +void __fastcall Focus_GetAndBlitSpin(HWND hWnd, LPARAM lParam) +{ + HWND v2; // esi + + v2 = (HWND)lParam; + GetWindowLongA((HWND)lParam, -12); + Focus_BlitSpinner(hWnd, v2); + dword_10029CAC = 1; +} +// 10029CAC: using guessed type int dword_10029CAC; + +// ref: 0x100075DC +BOOL __fastcall Focus_DoBlitSpinIncFrame(HWND hWnd1, HWND hWnd2) +{ + void **v4; // eax + void **v5; // esi + int v7; // edi + struct tagRECT Rect; // [esp+Ch] [ebp-14h] + + if ( !sgbSpinnersLoaded ) + return 0; + if ( !hWnd2 ) + return 0; + GetWindowLongA(hWnd2, -12); + if ( hWnd1 != GetParent(hWnd2) ) + return 0; + Focus_BlitSpinner(hWnd1, hWnd2); + v4 = (void **)GetWindowLongA(hWnd2, -21); + v5 = v4; + if ( !v4 || !*v4 ) + return 0; + GetWindowRect(hWnd2, &Rect); + ScreenToClient(hWnd1, (LPPOINT)&Rect); + ScreenToClient(hWnd1, (LPPOINT)&Rect.right); + if ( SpinnerTransOut[sgnSpinnerFrame] ) + { + v7 = ((signed int)v5[2] - focus_spin_height) / 2; + STransBlt(*v5, 0, v7, (int)v5[1], SpinnerTransOut[sgnSpinnerFrame]); + STransBlt(*v5, (int)v5[1] - focus_spin_width, v7, (int)v5[1], SpinnerTransOut[sgnSpinnerFrame]); + Focus_CenterSpinFromSide(hWnd2); + } + if ( ++sgnSpinnerFrame >= 8 ) + sgnSpinnerFrame = 0; + return 1; +} +// 10029C9C: using guessed type int focus_spin_height; +// 10029CA4: using guessed type int sgbSpinnersLoaded; +// 10029CB0: using guessed type int sgnSpinnerFrame; + +// ref: 0x100076C3 +void __cdecl Focus_DeleteSpinners() +{ + HANDLE *v0; // esi + + v0 = SpinnerTransOut; + do + { + if ( *v0 ) + { + STransDelete(*v0); + *v0 = 0; + } + ++v0; + } + while ( (signed int)v0 < (signed int)&SpinnerTransOut[8] ); + dword_10029CAC = 0; + dword_10029CA8 = 0; + sgbSpinnersLoaded = 0; +} +// 10029CA4: using guessed type int sgbSpinnersLoaded; +// 10029CA8: using guessed type int dword_10029CA8; +// 10029CAC: using guessed type int dword_10029CAC; + +// ref: 0x100076FA +void __cdecl Focus_ResetSpinToZero() +{ + dword_10029CAC = 0; + dword_10029CA8 = 0; +} +// 10029CA8: using guessed type int dword_10029CA8; +// 10029CAC: using guessed type int dword_10029CAC; + +// ref: 0x1000770E +void __cdecl Focus_cpp_init() +{ + focus_cpp_float = focus_cpp_float_value; +} +// 1001F42C: using guessed type int focus_cpp_float_value; +// 10029CA0: using guessed type int focus_cpp_float; + +// ref: 0x10007719 +void __fastcall Focus_LoadSpinner(const char *pszFileName) +{ + HANDLE *v1; // esi + int v2; // ecx + int v3; // eax + int v4; // ebx + int a5[4]; // [esp+4h] [ebp-1Ch] + DWORD data[2]; // [esp+14h] [ebp-Ch] + BYTE *pBuffer; // [esp+1Ch] [ebp-4h] + + if ( !sgbSpinnersLoaded ) + { + pBuffer = 0; + dword_10029CAC = 0; + dword_10029CA8 = 0; + local_LoadArtImage(pszFileName, &pBuffer, data); + v1 = SpinnerTransOut; + memset(SpinnerTransOut, 0, 0x20u); + if ( pBuffer ) + { + v2 = data[0]; + focus_spin_width = data[0]; + v3 = (signed int)data[1] / 8; + v4 = 0; + focus_spin_height = (signed int)data[1] / 8; + while ( 1 ) + { + a5[2] = v2 - 1; + a5[1] = v4 * v3; + a5[0] = 0; + a5[3] = v3 + v4 * v3 - 1; + STransCreateI(pBuffer, v2, v3, 8, (int)a5, 16777466, v1); + ++v1; + ++v4; + if ( (signed int)v1 >= (signed int)&SpinnerTransOut[8] ) + break; + v3 = focus_spin_height; + v2 = focus_spin_width; + } + SMemFree(pBuffer, "C:\\Src\\Diablo\\DiabloUI\\Focus.cpp", 246, 0); + } + sgnSpinnerFrame = 0; + sgbSpinnersLoaded = 1; + } +} +// 10029C9C: using guessed type int focus_spin_height; +// 10029CA4: using guessed type int sgbSpinnersLoaded; +// 10029CA8: using guessed type int dword_10029CA8; +// 10029CAC: using guessed type int dword_10029CAC; +// 10029CB0: using guessed type int sgnSpinnerFrame; + +// ref: 0x100077E9 +void __fastcall Focus_SetFocusTimer(HWND hWnd, const char *pszFileName) +{ + Focus_LoadSpinner(pszFileName); + SDlgSetTimer((int)hWnd, 1, 55, Focus_SetFocusAndBlit); +} + +// ref: 0x10007804 +void __stdcall Focus_SetFocusAndBlit(int hWnd, int a2, int a3, int a4) +{ + HWND v1; // eax + + v1 = GetFocus(); + Focus_DoBlitSpinIncFrame((HWND)hWnd, v1); +} + +// ref: 0x10007818 +void __fastcall Focus_KillFocusTimer(HWND hWnd) +{ + SDlgKillTimer((int)hWnd, 1); + Focus_DeleteSpinners(); +} diff --git a/2020_03_31/DiabloUI/local.cpp b/2020_03_31/DiabloUI/local.cpp new file mode 100644 index 00000000..21039b95 --- /dev/null +++ b/2020_03_31/DiabloUI/local.cpp @@ -0,0 +1,571 @@ +// ref: 0x10007825 +void __cdecl local_InitUiPalette() +{ + LOGPALETTE *v0; // eax MAPDST + PALETTEENTRY *v2; // eax + int v3; // ecx + + v0 = (LOGPALETTE *)SMemAlloc(0x404u, "C:\\Src\\Diablo\\DiabloUI\\local.cpp", 27, 0); + if ( v0 ) + { + v0->palVersion = 768; + v0->palNumEntries = 256; + v2 = v0->palPalEntry; + v3 = 0; + do + { + v2[v3].peFlags = 2; + ++v3; + } + while ( v3 < 256 ); + objPalette = CreatePalette(v0); + SMemFree(v0, "C:\\Src\\Diablo\\DiabloUI\\local.cpp", 41, 0); + } +} + +// ref: 0x1000787D +void __cdecl local_DelUiPalette() +{ + if ( objPalette ) + { + DeleteObject(objPalette); + objPalette = 0; + } +} + +// ref: 0x10007895 +tagPALETTEENTRY *__fastcall local_GetArtPalEntry(int entry) +{ + return &artpal[entry]; +} + +// ref: 0x1000789D +void __fastcall local_ClearPalette(PALETTEENTRY *pPal) +{ + BYTE *v1; // eax + signed int v2; // ecx + + v1 = &pPal->peBlue; + v2 = 256; + do + { + *(v1 - 2) = 0; + *(v1 - 1) = 0; + *v1 = 0; + v1 += 4; + --v2; + } + while ( v2 ); +} + +// ref: 0x100078B6 +void __cdecl local_ClearSurface() +{ + SDrawClearSurface(0); +} +// 1001043C: using guessed type int __stdcall SDrawClearSurface(_DWORD); + +// ref: 0x100078BE +BOOL __fastcall local_LoadArtImage(const char *pszFileName, BYTE **pBuffer, DWORD *pdwSize) +{ + BYTE *v4; // eax + DWORD v5; // ecx + DWORD dwHeight; // [esp+10h] [ebp-8h] + DWORD dwWidth; // [esp+14h] [ebp-4h] + + *pBuffer = 0; + if ( !SBmpLoadImage(pszFileName, 0, 0, 0, &dwWidth, &dwHeight, 0) ) + return 0; + v4 = (BYTE *)SMemAlloc(dwHeight * dwWidth, "C:\\Src\\Diablo\\DiabloUI\\local.cpp", 93, 0); + v5 = dwWidth; + *pBuffer = v4; + if ( !SBmpLoadImage(pszFileName, 0, v4, dwHeight * v5, 0, 0, 0) ) + { + SMemFree(*pBuffer, "C:\\Src\\Diablo\\DiabloUI\\local.cpp", 95, 0); + *pBuffer = 0; + return 0; + } + if ( pdwSize ) + { + *pdwSize = dwWidth; + pdwSize[1] = dwHeight; + } + return 1; +} + +// ref: 0x10007944 +BOOL __fastcall local_LoadArtWithPal(HWND hWnd, int a2, char *src, int mask, int flags, const char *pszFileName, BYTE **pBuffer, DWORD *pdwSize, BOOL a9) +{ + BYTE *v10; // eax + DWORD v11; // ST18_4 + HPALETTE v13; // edi + tagPALETTEENTRY pPalEntries[256]; // [esp+Ch] [ebp-40Ch] + DWORD pdwWidth; // [esp+410h] [ebp-8h] + DWORD dwHeight; // [esp+414h] [ebp-4h] + + if ( !SBmpLoadImage(pszFileName, 0, 0, 0, &pdwWidth, &dwHeight, 0) ) + return 0; + v10 = (BYTE *)SMemAlloc(dwHeight * pdwWidth, "C:\\Src\\Diablo\\DiabloUI\\local.cpp", 129, 0); + v11 = dwHeight * pdwWidth; + *pBuffer = v10; + if ( !SBmpLoadImage(pszFileName, pPalEntries, v10, v11, 0, 0, 0) + || !SDlgSetBitmapI(hWnd, a2, src, mask, flags, *pBuffer, 0, pdwWidth, dwHeight, -1) ) + { + return 0; + } + if ( !src || !*src ) + { + v13 = (HPALETTE)GetStockObject(15); + GetPaletteEntries(v13, 0, 0xAu, pPalEntries); + GetPaletteEntries(v13, 0xAu, 0xAu, &pPalEntries[246]); + memcpy(artpal, pPalEntries, 0x400u); + if ( a9 ) + { + SDrawUpdatePalette(0, 255, artpal, 1); + } + else + { + local_ClearPalette(pPalEntries); + SDrawUpdatePalette(0, 256, pPalEntries, 1); + } + } + if ( pdwSize ) + { + *pdwSize = pdwWidth; + pdwSize[1] = dwHeight; + } + return 1; +} +// 100103FA: using guessed type int __stdcall SDrawUpdatePalette(_DWORD, _DWORD, _DWORD, _DWORD); + +// ref: 0x10007A68 +void __fastcall local_AdjustRectSize(tagRECT *pRect, int a2, int a3) +{ + int v3; // eax + int v4; // edx + + v3 = a2 - pRect->left; + pRect->left = a2; + pRect->right += v3 - 1; + v4 = a3 - pRect->top; + pRect->top = a3; + pRect->bottom += v4 - 1; +} + +// ref: 0x10007A85 +BOOL __fastcall local_SetStaticBmp(HWND hWnd, int nIDDlgItem, BYTE *pBuffer, DWORD *pdwSize) +{ + HWND v4; // edi + HWND v5; // ebx + struct tagRECT Rect; // [esp+Ch] [ebp-10h] + + v4 = hWnd; + v5 = GetDlgItem(hWnd, nIDDlgItem); + GetWindowRect(v5, &Rect); + ScreenToClient(v4, (LPPOINT)&Rect); + ScreenToClient(v4, (LPPOINT)&Rect.right); + SDlgSetBitmapI(v5, 0, "Static", -1, 1, pBuffer, (int)&Rect, *pdwSize, pdwSize[1], -1); + return 1; +} + +// ref: 0x10007AEA +void __cdecl local_cpp_init() +{ + local_cpp_float = 0x7F800000; +} +// 10029CB8: using guessed type int local_cpp_float; + +// ref: 0x10007AF5 +BOOL __fastcall local_SetButtonBmp(HWND hWnd, int flags, int a7, void *pBuffer, DWORD *pdwSize) +{ + return SDlgSetBitmapI(hWnd, 0, "Button", -1, flags, pBuffer, a7, *pdwSize, pdwSize[1], -1); +} + +// ref: 0x10007B1B +void __fastcall local_FitButtonDlg(HWND hWnd, int *a2, void *pBuffer, DWORD *pdwSize) +{ + int v4; // eax + HWND v5; // esi + struct tagRECT Rect; // [esp+0h] [ebp-1Ch] + int a3; // [esp+14h] [ebp-8h] + int *v9; // [esp+18h] [ebp-4h] + + v4 = *a2; + a3 = 0; + v9 = a2; + if ( v4 ) + { + do + { + v5 = GetDlgItem(hWnd, v4); + if ( v5 ) + { + GetClientRect(v5, &Rect); + local_AdjustRectSize(&Rect, 0, a3); + local_SetButtonBmp(v5, 16, (int)&Rect, pBuffer, pdwSize); + ++Rect.bottom; + ++Rect.right; + local_AdjustRectSize(&Rect, 0, Rect.bottom); + local_SetButtonBmp(v5, 64, (int)&Rect, pBuffer, pdwSize); + ++Rect.bottom; + ++Rect.right; + local_AdjustRectSize(&Rect, 0, Rect.bottom); + local_SetButtonBmp(v5, 32, (int)&Rect, pBuffer, pdwSize); + ++Rect.bottom; + ++Rect.right; + local_AdjustRectSize(&Rect, 0, Rect.bottom); + local_SetButtonBmp(v5, 128, (int)&Rect, pBuffer, pdwSize); + ++Rect.bottom; + ++Rect.right; + local_AdjustRectSize(&Rect, 0, Rect.bottom); + local_SetButtonBmp(v5, 1280, (int)&Rect, pBuffer, pdwSize); + ++Rect.bottom; + ++Rect.right; + a3 = Rect.bottom; + } + ++v9; + v4 = *v9; + } + while ( *v9 ); + } +} + +// ref: 0x10007C2E +void __fastcall local_SetWhiteText(HDC hdc) +{ + SetTextColor(hdc, 0xFFFFu); +} + +// ref: 0x10007C3B +BOOL __fastcall local_GetBottomRect(HWND hWnd1, HWND hWnd2, int width, int height) +{ + BOOL result; // eax + struct tagRECT Rect; // [esp+4h] [ebp-10h] + + if ( hWnd1 + && hWnd2 + && (GetWindowRect(hWnd2, &Rect), + ScreenToClient(hWnd1, (LPPOINT)&Rect), + ScreenToClient(hWnd1, (LPPOINT)&Rect.right), + width >= Rect.left) + && width < Rect.right + && height >= Rect.top ) + { + result = height < Rect.bottom; + } + else + { + result = 0; + } + return result; +} + +// ref: 0x10007C95 +void __fastcall local_DlgDoPaint(HWND hWnd) +{ + char v2[64]; // [esp+4h] [ebp-40h] + + SDlgBeginPaint(hWnd, v2); + SDlgEndPaint(hWnd, v2); +} +// 10010442: using guessed type int __stdcall SDlgEndPaint(_DWORD, _DWORD); +// 10010448: using guessed type int __stdcall SDlgBeginPaint(_DWORD, _DWORD); + +// ref: 0x10007CB5 +void __fastcall local_DoUiWndProc(HWND hWnd, DWORD *pdwMsgTbl) +{ + DWORD *v2; // edi + int i; // eax + HWND v5; // eax + HWND v6; // esi + void *v7; // eax + + v2 = pdwMsgTbl; + for ( i = *pdwMsgTbl; *v2; i = *v2 ) + { + v5 = GetDlgItem(hWnd, i); + v6 = v5; + if ( v5 ) + { + v7 = (void *)GetWindowLongA(v5, -4); + SetPropA(v6, "UIWNDPROC", v7); + SetWindowLongA(v6, -4, (LONG)local_PostUiWndProc); + } + ++v2; + } +} + +// ref: 0x10007D01 +LRESULT __stdcall local_PostUiWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + LRESULT (__stdcall *v4)(HWND, UINT, WPARAM, LPARAM); // ebx + HWND v5; // eax + HWND v6; // eax + HWND v7; // eax + WPARAM v9; // [esp-8h] [ebp-14h] + BOOL v10; // [esp-4h] [ebp-10h] + + v4 = (LRESULT (__stdcall *)(HWND, UINT, WPARAM, LPARAM))GetPropA(hWnd, "UIWNDPROC"); + switch ( uMsg ) + { + case 2u: + RemovePropA(hWnd, "UIWNDPROC"); + if ( !v4 ) + return DefWindowProcA(hWnd, uMsg, wParam, lParam); + SetWindowLongA(hWnd, -4, (LONG)v4); + goto LABEL_21; + case 0xFu: + local_DlgDoPaint(hWnd); + return 0; + case 0x87u: + return 4; + } + if ( uMsg != 256 ) + goto LABEL_21; + switch ( wParam ) + { + case 0xDu: + goto LABEL_26; + case 0x1Bu: + v9 = 2; +LABEL_15: + v7 = GetParent(hWnd); + SendMessageA(v7, 0x111u, v9, 0); + goto LABEL_21; + case 0x20u: +LABEL_26: + v9 = 1; + goto LABEL_15; + } + if ( wParam <= 0x24 ) + goto LABEL_21; + if ( wParam <= 0x26 ) + { + v10 = 1; + } + else + { + if ( wParam > 0x28 ) + goto LABEL_21; + v10 = 0; + } + v5 = GetParent(hWnd); + v6 = GetNextDlgGroupItem(v5, hWnd, v10); + SetFocus(v6); +LABEL_21: + if ( v4 ) + return CallWindowProcA(v4, hWnd, uMsg, wParam, lParam); + return DefWindowProcA(hWnd, uMsg, wParam, lParam); +} + +// ref: 0x10007DE9 +void __fastcall local_DoUiWndProc2(HWND hWnd, DWORD *pdwMsgTbl) +{ + DWORD *v2; // edi + int i; // eax + HWND v5; // eax + HWND v6; // esi + void *v7; // eax + + v2 = pdwMsgTbl; + for ( i = *pdwMsgTbl; *v2; i = *v2 ) + { + v5 = GetDlgItem(hWnd, i); + v6 = v5; + if ( v5 ) + { + v7 = (void *)GetWindowLongA(v5, -4); + SetPropA(v6, "UIWNDPROC", v7); + SetWindowLongA(v6, -4, (LONG)local_PostUiWndProc2); + } + ++v2; + } +} + +// ref: 0x10007E35 +LRESULT __stdcall local_PostUiWndProc2(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + LRESULT (__stdcall *v4)(HWND, UINT, WPARAM, LPARAM); // ebx + WPARAM v5; // ST0C_4 + HWND v6; // eax + HWND v8; // [esp+18h] [ebp+Ch] + + v4 = (LRESULT (__stdcall *)(HWND, UINT, WPARAM, LPARAM))GetPropA(hWnd, "UIWNDPROC"); + switch ( uMsg ) + { + case 2u: + RemovePropA(hWnd, "UIWNDPROC"); + if ( !v4 ) + return DefWindowProcA(hWnd, uMsg, wParam, lParam); + SetWindowLongA(hWnd, -4, (LONG)v4); + break; + case 0xFu: + local_DlgDoPaint(hWnd); + return 0; + case 0x201u: + v8 = GetFocus(); + SetFocus(hWnd); + InvalidateRect(v8, 0, 0); + InvalidateRect(hWnd, 0, 0); + UpdateWindow(v8); + UpdateWindow(hWnd); + v5 = (unsigned short)GetWindowLongA(hWnd, -12); + v6 = GetParent(hWnd); + PostMessageA(v6, 0x111u, v5, (LPARAM)hWnd); + return 0; + } + if ( v4 ) + return CallWindowProcA(v4, hWnd, uMsg, wParam, lParam); + return DefWindowProcA(hWnd, uMsg, wParam, lParam); +} + +// ref: 0x10007F04 +BOOL __fastcall local_DisableKeyWaitMouse(HWND hWnd) +{ + BOOL result; // eax + struct tagMSG Msg; // [esp+8h] [ebp-1Ch] + + do + { + while ( PeekMessageA(&Msg, hWnd, 0x100u, 0x108u, 1u) ) + ; + result = PeekMessageA(&Msg, hWnd, 0x200u, 0x209u, 1u); + } + while ( result ); + return result; +} + +// ref: 0x10007F46 +DWORD *__cdecl local_AllocWndLongData() +{ + DWORD *result; // eax + + result = (DWORD *)SMemAlloc(0x110u, "C:\\Src\\Diablo\\DiabloUI\\local.cpp", 480, 0); + if ( result ) + { + *result = 0; + result[1] = 0; + result[2] = 0; + result[3] = 0; + *((_BYTE *)result + 16) = 0; + } + return result; +} + +// ref: 0x10007F72 +void __fastcall local_FreeMemPtr(void **p) +{ + if ( p ) + { + if ( *p ) + SMemFree(*p, "C:\\Src\\Diablo\\DiabloUI\\local.cpp", 498, 0); + SMemFree(p, "C:\\Src\\Diablo\\DiabloUI\\local.cpp", 499, 0); + } +} + +// ref: 0x10007FA4 +void __fastcall local_SetWndLongStr(int WndLongData, const char *pszStr) +{ + if ( WndLongData ) + { + if ( pszStr ) + { + strncpy((char *)(WndLongData + 16), pszStr, 0xFFu); + *(_BYTE *)(WndLongData + 271) = 0; + } + else + { + *(_BYTE *)(WndLongData + 16) = 0; + } + } +} + +// ref: 0x10007FD0 +void __cdecl local_LoadArtCursor() +{ + DWORD dwHeight; // [esp+8h] [ebp-8h] + DWORD dwWidth; // [esp+Ch] [ebp-4h] + + if ( SBmpLoadImage("ui_art\\cursor.pcx", 0, 0, 0, &dwWidth, &dwHeight, 0) ) + { + gpCursorArt = (BYTE *)SMemAlloc(dwHeight * dwWidth, "C:\\Src\\Diablo\\DiabloUI\\local.cpp", 553, 0); + gpCursorArt2 = (BYTE *)SMemAlloc(dwHeight * dwWidth, "C:\\Src\\Diablo\\DiabloUI\\local.cpp", 554, 0); + if ( SBmpLoadImage("ui_art\\cursor.pcx", 0, gpCursorArt, dwHeight * dwWidth, 0, 0, 0) ) + { + gdwCursData[0] = dwWidth; + gdwCursData[1] = dwHeight; + local_InitArtCursor(); + } + } +} + +// ref: 0x10008062 +void __cdecl local_InitArtCursor() +{ + BYTE *v0; // eax + BYTE *v1; // ecx + int i; // esi + char v3; // dl + + v0 = gpCursorArt2; + v1 = gpCursorArt; + if ( gpCursorArt2 ) + { + if ( gpCursorArt ) + { + for ( i = 0; i < gdwCursData[0] * gdwCursData[1]; ++i ) + { + v3 = *v1++; + if ( v3 ) + *v0 = 0; + else + *v0 = -1; + ++v0; + } + } + } +} + +// ref: 0x100080AD +void __cdecl local_FreeArtCursor() +{ + if ( gpCursorArt ) + { + SMemFree(gpCursorArt, "C:\\Src\\Diablo\\DiabloUI\\local.cpp", 571, 0); + gpCursorArt = 0; + } + if ( gpCursorArt2 ) + { + SMemFree(gpCursorArt2, "C:\\Src\\Diablo\\DiabloUI\\local.cpp", 575, 0); + gpCursorArt2 = 0; + } +} + +// ref: 0x100080F1 +void __cdecl local_SetCursorArt() +{ + if ( !gpCursorArt ) + local_LoadArtCursor(); + SDlgSetSystemCursor(gpCursorArt2, gpCursorArt, (int *)gdwCursData, 32512); +} +// 1001044E: using guessed type int __stdcall SDlgSetSystemCursor(_DWORD, _DWORD, _DWORD, _DWORD); + +// ref: 0x1000811B +void __cdecl local_SetCursorDefault() +{ + SDlgSetSystemCursor(0, 0, 0, 32512); +} +// 1001044E: using guessed type int __stdcall SDlgSetSystemCursor(_DWORD, _DWORD, _DWORD, _DWORD); + +// ref: 0x1000812B +void __fastcall local_SetDiabloCursor(HWND hWnd) +{ + HCURSOR v2; // eax + int v3; // [esp+4h] [ebp-4h] + + v3 = 0; + local_SetCursorDefault(); + v2 = LoadCursorA(ghUiInst, "DIABLOCURSOR"); + SDlgSetCursor(hWnd, v2, 32512, &v3); +} +// 10010454: using guessed type int __stdcall SDlgSetCursor(_DWORD, _DWORD, _DWORD, _DWORD); diff --git a/2020_03_31/DiabloUI/mainmenu.cpp b/2020_03_31/DiabloUI/mainmenu.cpp new file mode 100644 index 00000000..ccd179d3 --- /dev/null +++ b/2020_03_31/DiabloUI/mainmenu.cpp @@ -0,0 +1,230 @@ +// ref: 0x10008164 +void __cdecl MainMenu_cpp_init() +{ + mainmenu_cpp_float = mainmenu_cpp_float_value; +} +// 1001F434: using guessed type int mainmenu_cpp_float_value; +// 1002A0D4: using guessed type int mainmenu_cpp_float; + +// ref: 0x1000816F +BOOL __stdcall UiMainMenuDialog(char *name, int *pdwResult, void (__stdcall *fnSound)(const char *file), int a4) +{ + int v4; // eax + int v5; // esi + + menu_item_timer = a4; + TitleSnd_SetSoundFunction(fnSound); + artfont_LoadAllFonts(); + menu_version_str[0] = 0; + if ( name ) + strncpy(menu_version_str, name, 0x40u); + v4 = (int)SDrawGetFrameWindow(NULL); + v5 = SDlgDialogBoxParam(ghUiInst, "MAINMENU_DIALOG", v4, MainMenu_WndProc, 0); + if ( v5 == 5 ) + artfont_FreeAllFonts(); + if ( pdwResult ) + *pdwResult = v5; + return 1; +} +// 10010382: using guessed type _DWORD __stdcall SDrawGetFrameWindow(); +// 1002A118: using guessed type int menu_item_timer; + +// ref: 0x100081E3 +LRESULT __stdcall MainMenu_WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) +{ + HWND v5; // eax + + if ( Msg <= 0x113 ) + { + if ( Msg != 275 ) + { + if ( Msg == 2 ) + { + MainMenu_KillAndFreeMenu(hWnd); + } + else if ( Msg > 0x103 ) + { + if ( Msg <= 0x105 ) + { + v5 = (HWND)SDrawGetFrameWindow(NULL); + SendMessageA(v5, Msg, wParam, lParam); + } + else + { + if ( Msg == 272 ) + { + MainMenu_LoadMenuGFX(hWnd); + PostMessageA(hWnd, 0x7E8u, 0, 0); + return 1; + } + if ( Msg == 273 ) + { + MainMenu_SetMenuTimer(hWnd); + switch ( HIWORD(wParam) ) + { + case 7: + Focus_GetAndBlitSpin(hWnd, lParam); + break; + case 6: + Focus_CheckPlayMove(lParam); + Focus_DoBlitSpinIncFrame(hWnd, (HWND)lParam); + break; + case 0: + MainMenu_CheckWParamFocus(hWnd, (unsigned short)wParam); + break; + } + } + } + } + return (LRESULT)SDlgDefDialogProc(hWnd, Msg, (HDC)wParam, (HWND)lParam); + } + if ( wParam == 3 && !DiabloUI_GetSpawned() ) + { + if ( app_is_active ) + MainMenu_DoOptions(hWnd, 6, 0); + else + MainMenu_SetMenuTimer(hWnd); + } + return 0; + } + if ( Msg >= 0x200 ) + { + if ( Msg <= 0x202 ) + goto LABEL_34; + if ( Msg <= 0x203 ) + return (LRESULT)SDlgDefDialogProc(hWnd, Msg, (HDC)wParam, (HWND)lParam); + if ( Msg <= 0x205 ) + { +LABEL_34: + MainMenu_SetMenuTimer(hWnd); + return (LRESULT)SDlgDefDialogProc(hWnd, Msg, (HDC)wParam, (HWND)lParam); + } + if ( Msg == 2024 ) + { + if ( !Fade_CheckRange5() ) + Fade_SetFadeTimer((int)hWnd); + return 0; + } + } + return (LRESULT)SDlgDefDialogProc(hWnd, Msg, (HDC)wParam, (HWND)lParam); +} +// 10010382: using guessed type _DWORD __stdcall SDrawGetFrameWindow(); +// 10029728: using guessed type int app_is_active; + +// ref: 0x10008354 +void __fastcall MainMenu_KillAndFreeMenu(HWND hWnd) +{ + void **v2; // eax + + Title_KillTitleTimer(hWnd); + Focus_KillFocusTimer(hWnd); + Doom_DeleteFreeProcs(hWnd, menumsgs_5options); + Doom_DeleteFreeProcs(hWnd, menumsgs_1option); + v2 = (void **)GetWindowLongA(hWnd, -21); + local_FreeMemPtr(v2); + local_SetCursorDefault(); +} + +// ref: 0x10008391 +void __fastcall MainMenu_SetMenuTimer(HWND hWnd) +{ + SDlgSetTimer((int)hWnd, 3, 1000 * menu_item_timer, 0); +} +// 1002A118: using guessed type int menu_item_timer; + +// ref: 0x100083A8 +void __fastcall MainMenu_LoadMenuGFX(HWND hWnd) +{ + DWORD *v2; // eax MAPDST + unsigned char v4; // zf + const char *v5; // eax + HWND v6; // eax + + v2 = local_AllocWndLongData(); + if ( v2 ) + { + SetWindowLongA(hWnd, -21, (LONG)v2); + v4 = DiabloUI_GetSpawned() == 0; + v5 = "ui_art\\swmmenu.pcx"; + if ( v4 ) + v5 = "ui_art\\mainmenu.pcx"; + local_LoadArtWithPal(hWnd, 0, &nullcharacter, -1, 1, v5, (BYTE **)v2, v2 + 1, 0); + Fade_NoInputAndArt(hWnd, 1); + } + v6 = GetDlgItem(hWnd, 1042); + SetWindowTextA(v6, menu_version_str); + Doom_ParseWndProc3(hWnd, menumsgs_1option, 1); + Doom_ParseWndProcs(hWnd, menumsgs_5options, 6, 1); + Focus_SetFocusTimer(hWnd, "ui_art\\focus42.pcx"); + Title_LoadImgSetTimer(hWnd, "ui_art\\smlogo.pcx"); + MainMenu_SetMenuTimer(hWnd); + local_DoUiWndProc2(hWnd, (DWORD *)menumsgs_5options); +} + +// ref: 0x1000845A +void __fastcall MainMenu_DoOptions(HWND hWnd, int option, int PlaySelect) +{ + SDlgKillTimer((int)hWnd, 3); + if ( DiabloUI_GetSpawned() && option == 3 ) + { + SelYesNo_SpawnErrDialog(hWnd, 70, 1); +LABEL_7: + SDlgSetTimer((int)hWnd, 3, 1000 * menu_item_timer, 0); + return; + } + if ( option == 2 && !MainMenu_CheckEnoughMemory() ) + { + SelYesNo_SpawnErrDialog(hWnd, 78, 1); + goto LABEL_7; + } + Fade_Range5SetZero(); + if ( PlaySelect ) + TitleSnd_PlaySelectSound(); + Fade_UpdatePaletteRange(10); + SDlgEndDialog(hWnd, (HANDLE)option); +} +// 1002A118: using guessed type int menu_item_timer; + +// ref: 0x100084D5 +BOOL __cdecl MainMenu_CheckEnoughMemory() +{ + struct _MEMORYSTATUS Buffer; // [esp+0h] [ebp-20h] + + Buffer.dwLength = 32; + GlobalMemoryStatus(&Buffer); + return Buffer.dwTotalPhys > 0xDAC000; +} + +// ref: 0x100084FA +void __fastcall MainMenu_CheckWParamFocus(HWND hWnd, WPARAM wParam) +{ + HWND v3; // eax + LONG v4; // eax + int v5; // [esp-8h] [ebp-Ch] + + switch ( wParam ) + { + case 1u: + v3 = GetFocus(); + v4 = GetWindowLongA(v3, -12); + SendMessageA(hWnd, 0x111u, v4, 0); + return; + case 2u: + v5 = 5; + goto LABEL_12; + case 0x3E9u: + v5 = 2; + goto LABEL_12; + case 0x3EAu: + v5 = 3; + goto LABEL_12; + case 0x3EBu: + v5 = 4; +LABEL_12: + MainMenu_DoOptions(hWnd, v5, 1); + return; + case 0x414u: + MainMenu_DoOptions(hWnd, 1, 1); + break; + } +} diff --git a/2020_03_31/DiabloUI/modem.cpp b/2020_03_31/DiabloUI/modem.cpp new file mode 100644 index 00000000..ada29119 --- /dev/null +++ b/2020_03_31/DiabloUI/modem.cpp @@ -0,0 +1,477 @@ +// ref: 0x1000855D +int Modem_1000855D() { return 0; } +/* { + return dword_1002A124; +} */ +// 1002A124: using guessed type int dword_1002A124; + +// ref: 0x10008563 +HWND __fastcall Modem_10008563(HWND hDlg, const char *a2, int a3) { return 0; } +/* { + HWND v3; // esi + const char *v4; // ebp + HWND result; // eax + + v3 = hDlg; + v4 = a2; + result = GetDlgItem(hDlg, 1108); + if ( result ) + { + result = (HWND)GetWindowLongA(result, -21); + if ( result ) + { + local_10007FA4((int)result, (const char *)a3); + Doom_10006A13(v3, (int *)&unk_10022C5C, 1); + result = GetDlgItem(v3, 1080); + if ( result ) + { + result = (HWND)GetWindowLongA(result, -21); + if ( result ) + { + local_10007FA4((int)result, v4); + result = (HWND)Doom_10006A13(v3, (int *)&unk_10022C54, 3); + } + } + } + } + return result; +} */ + +// ref: 0x100085D8 +int __stdcall Modem_100085D8(int a1, char *a2, char *a3) { return 0; } +/* { + dword_1002A150 = a1; + strcpy(&byte_1002A154, a2); + strcpy(&byte_1002A1D4, a3); + return 1; +} */ +// 1002A150: using guessed type int dword_1002A150; + +// ref: 0x10008606 +BOOL Modem_10008606() { return 0; } +/* { + BOOL result; // eax + + dword_1002A150 = 0; + byte_1002A154 = 0; + byte_1002A1D4 = 0; + if ( SNetEnumGames(0, 0, Modem_100085D8, 0) ) + result = dword_1002A150 != 0; + else + result = 0; + return result; +} */ +// 10010436: using guessed type int __stdcall SNetEnumGames(_DWORD, _DWORD, _DWORD, _DWORD); +// 1002A150: using guessed type int dword_1002A150; + +// ref: 0x1000863D +char *Modem_1000863D() { return 0; } +/* { + return &byte_1002A154; +} */ + +// ref: 0x10008648 +signed int Modem_10008648() { return 0; } +/* { + signed int result; // eax + + result = 2139095040; + dword_1002A128 = 2139095040; + return result; +} */ +// 1002A128: using guessed type int dword_1002A128; + +// ref: 0x10008653 +int Modem_10008653() { return 0; } +/* { + return dword_1002A148; +} */ +// 1002A148: using guessed type int dword_1002A148; + +// ref: 0x10008659 +int Modem_10008659() { return 0; } +/* { + return dword_1002A134; +} */ +// 1002A134: using guessed type int dword_1002A134; + +// ref: 0x1000865F +int UNKCALL Modem_1000865F(char *arg) { return 0; } +/* { + char v1; // al + int result; // eax + + while ( 1 ) + { + v1 = *arg; + if ( !*arg || (unsigned char)v1 >= 0x30u && (unsigned char)v1 <= 0x39u ) + break; + ++arg; + } + if ( *arg ) + result = atoi(arg); + else + result = 0; + return result; +} */ + +// ref: 0x10008680 +BOOL __fastcall Modem_10008680(int a1, int a2, int a3, _DWORD *a4, int a5, int a6) { return 0; } +/* { + int v6; // esi + + dword_1002A13C = a3; + dword_1002A138 = a2; + dword_1002A144 = a5; + dword_1002A14C = a4; + dword_1002A140 = a6; + artfont_10001159(); + v6 = SDlgDialogBoxParam(hInstance, "MODEM_DIALOG", a4[2], Modem_100086DE, 0); + artfont_100010C8(); + return v6 == 1; +} */ +// 10010370: using guessed type int __stdcall SDlgDialogBoxParam(_DWORD, _DWORD, _DWORD, _DWORD, _DWORD); +// 1002A138: using guessed type int dword_1002A138; +// 1002A13C: using guessed type int dword_1002A13C; +// 1002A140: using guessed type int dword_1002A140; +// 1002A144: using guessed type int dword_1002A144; + +// ref: 0x100086DE +int __stdcall Modem_100086DE(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) { return 0; } +/* { + HWND v4; // eax + int v6; // [esp+0h] [ebp-8h] + + if ( Msg > 0x7E8 ) + { + switch ( Msg ) + { + case 0xBD0u: + Modem_100088DB(hWnd); + return 0; + case 0xBD1u: + Modem_10008BB7(hWnd); + return 0; + case 0xBD2u: + Modem_10008BFE(hWnd); + return 0; + } + return SDlgDefDialogProc(hWnd, Msg, wParam, lParam); + } + if ( Msg == 2024 ) + { + if ( !Fade_1000739F() ) + Fade_100073FD(hWnd, v6); + return 0; + } + if ( Msg == 2 ) + { + Modem_1000879E(hWnd); + return SDlgDefDialogProc(hWnd, Msg, wParam, lParam); + } + if ( Msg <= 0x103 ) + return SDlgDefDialogProc(hWnd, Msg, wParam, lParam); + if ( Msg <= 0x105 ) + { + v4 = (HWND)SDrawGetFrameWindow(); + SendMessageA(v4, Msg, wParam, lParam); + return SDlgDefDialogProc(hWnd, Msg, wParam, lParam); + } + if ( Msg != 272 ) + return SDlgDefDialogProc(hWnd, Msg, wParam, lParam); + Modem_100087DB(hWnd); + PostMessageA(hWnd, 0x7E8u, 0, 0); + return 0; +} */ +// 1001037C: using guessed type int __stdcall SDlgDefDialogProc(_DWORD, _DWORD, _DWORD, _DWORD); +// 10010382: using guessed type _DWORD __stdcall SDrawGetFrameWindow(); + +// ref: 0x1000879E +void **UNKCALL Modem_1000879E(HWND hDlg) { return 0; } +/* { + HWND v1; // esi + _DWORD *v2; // eax + + v1 = hDlg; + Doom_10006C53(hDlg, (int *)&unk_10022C5C); + Doom_10006C53(v1, (int *)&unk_10022C54); + Doom_10006C53(v1, (int *)&unk_10022C4C); + v2 = (_DWORD *)GetWindowLongA(v1, -21); + local_10007F72(v2); + return Title_100100E7(v1); +} */ + +// ref: 0x100087DB +BOOL UNKCALL Modem_100087DB(HWND hWnd) { return 0; } +/* { + HWND v1; // esi + int v2; // eax + int *v3; // edi + HWND v5; // [esp+0h] [ebp-10h] + + v1 = hWnd; + Title_1001009E(hWnd, (int)"ui_art\\smlogo.pcx", v5); + v2 = local_10007F46(); + v3 = (int *)v2; + if ( v2 ) + { + SetWindowLongA(v1, -21, v2); + local_10007944((int)v1, 0, &byte_10029448, -1, 1, (int)"ui_art\\selgame.pcx", v3, v3 + 1, 0); + Fade_100073C5(v1, 1); + } + Doom_100068AB(v1, (int *)&unk_10022C4C, 5); + Doom_100068AB(v1, (int *)&unk_10022C54, 3); + Doom_100068AB(v1, (int *)&unk_10022C5C, 1); + Modem_10008888(); + if ( dword_1002A124 ) + return PostMessageA(v1, 0xBD2u, 0, 0); + dword_1002A134 = 1; + dword_1002A130 = 1; + return PostMessageA(v1, 0xBD0u, 0, 0); +} */ +// 1002A124: using guessed type int dword_1002A124; +// 1002A130: using guessed type int dword_1002A130; +// 1002A134: using guessed type int dword_1002A134; + +// ref: 0x10008888 +int Modem_10008888() { return 0; } +/* { + int result; // eax + + dword_1002A150 = 0; + byte_1002A154 = 0; + byte_1002A1D4 = 0; + result = SNetEnumGames(0, 0, Modem_100085D8, 0); + if ( result ) + { + dword_1002A124 = 1; + } + else + { + result = SErrGetLastError(); + if ( result == 1222 ) + { + dword_1002A124 = 0; + result = 1; + dword_1002A134 = 1; + dword_1002A130 = 1; + } + } + return result; +} */ +// 10010406: using guessed type _DWORD __stdcall SErrGetLastError(); +// 10010436: using guessed type int __stdcall SNetEnumGames(_DWORD, _DWORD, _DWORD, _DWORD); +// 1002A124: using guessed type int dword_1002A124; +// 1002A130: using guessed type int dword_1002A130; +// 1002A134: using guessed type int dword_1002A134; +// 1002A150: using guessed type int dword_1002A150; + +// ref: 0x100088DB +int UNKCALL Modem_100088DB(HWND hWnd) { return 0; } +/* { + HWND v1; // esi + int v2; // eax + int v3; // eax + int v5; // [esp+4h] [ebp-20h] + + v1 = hWnd; + v2 = SDlgDialogBoxParam(hInstance, "SELDIAL_DIALOG", hWnd, SelDial_1000B0CF, &v5) - 3; + if ( !v2 ) + return Modem_1000893D(v1); + v3 = v2 - 1; + if ( !v3 ) + return Modem_10008A38(v1, (int)&v5); + if ( v3 == 1 ) + return PostMessageA(v1, 0xBD1u, 0, 0); + return SelHero_1000C3E2((int)v1, 2); +} */ +// 10010370: using guessed type int __stdcall SDlgDialogBoxParam(_DWORD, _DWORD, _DWORD, _DWORD, _DWORD); + +// ref: 0x1000893D +int UNKCALL Modem_1000893D(HWND hWnd) { return 0; } +/* { + HWND v1; // esi + int v2; // eax + int result; // eax + CHAR v4; // [esp+8h] [ebp-C0h] + int v5; // [esp+48h] [ebp-80h] + HWND v6; // [esp+50h] [ebp-78h] + CHAR Buffer; // [esp+98h] [ebp-30h] + int v8; // [esp+B8h] [ebp-10h] + int v9; // [esp+BCh] [ebp-Ch] + int v10; // [esp+C0h] [ebp-8h] + int v11; // [esp+C4h] [ebp-4h] + + v1 = hWnd; + memcpy(&v5, dword_1002A14C, 0x50u); + v5 = 80; + v6 = v1; + memset(&v8, 0, 0x10u); + v8 = 16; + v9 = 1297040461; + v2 = *(_DWORD *)(dword_1002A138 + 24); + v11 = 0; + v10 = v2; + LoadStringA(hInstance, 0x47u, &Buffer, 31); + wsprintfA(&v4, &Buffer, dword_1002A130); + if ( CreaDung_100051D8( + (int)&v8, + dword_1002A138, + dword_1002A13C, + (int)&v5, + dword_1002A144, + dword_1002A140, + 1, + (int)&v4) ) + { + ++dword_1002A130; + result = SelHero_1000C3E2((int)v1, 1); + } + else if ( dword_1002A124 ) + { + if ( SErrGetLastError() == 183 ) + ++dword_1002A130; + result = PostMessageA(v1, 0xBD2u, 0, 0); + } + else + { + result = PostMessageA(v1, 0xBD0u, 0, 0); + } + return result; +} */ +// 10010406: using guessed type _DWORD __stdcall SErrGetLastError(); +// 1002A124: using guessed type int dword_1002A124; +// 1002A130: using guessed type int dword_1002A130; +// 1002A138: using guessed type int dword_1002A138; +// 1002A13C: using guessed type int dword_1002A13C; +// 1002A140: using guessed type int dword_1002A140; +// 1002A144: using guessed type int dword_1002A144; + +// ref: 0x10008A38 +int __fastcall Modem_10008A38(HWND hWnd, int a2) { return 0; } +/* { + char *v2; // ebx + HWND v3; // edi + int v4; // eax + int result; // eax + CHAR Buffer; // [esp+Ch] [ebp-80h] + + v2 = (char *)a2; + v3 = hWnd; + dword_1002A148 = 0; + _beginthread((int)Modem_10008B42, 0, a2); + ModmStat_10008C87(v3); + if ( !dword_1002A120 ) + { + switch ( dword_1002A12C ) + { + case -2062548871: + LoadStringA(hInstance, 0x32u, &Buffer, 127); + break; + case 54: + LoadStringA(hInstance, 0x42u, &Buffer, 127); + break; + case 1204: + LoadStringA(hInstance, 0x4Cu, &Buffer, 127); + break; + case 1222: + LoadStringA(hInstance, 0x41u, &Buffer, 127); + break; + case 1223: + goto LABEL_18; + case 2250: + LoadStringA(hInstance, 0x40u, &Buffer, 127); + break; + default: + LoadStringA(hInstance, 0x33u, &Buffer, 127); + break; + } + SelYesNo_1000FD39((int)v3, &Buffer, 0, 1); +LABEL_18: + if ( dword_1002A124 ) + result = PostMessageA(v3, 0xBD2u, 0, 0); + else + result = PostMessageA(v3, 0xBD0u, 0, 0); + return result; + } + if ( !dword_1002A124 ) + { + SelDial_1000B011(v2); + Modem_10008606(); + } + v4 = Modem_1000865F(&byte_1002A154); + dword_1002A134 = v4; + dword_1002A130 = v4 + 1; + return SelHero_1000C3E2((int)v3, 1); +} */ +// 1002A120: using guessed type int dword_1002A120; +// 1002A124: using guessed type int dword_1002A124; +// 1002A12C: using guessed type int dword_1002A12C; +// 1002A130: using guessed type int dword_1002A130; +// 1002A134: using guessed type int dword_1002A134; +// 1002A148: using guessed type int dword_1002A148; + +// ref: 0x10008B42 +void __cdecl Modem_10008B42(char *a1) { return; } +/* { + char *v1; // eax + char v2; // [esp+0h] [ebp-100h] + char v3; // [esp+80h] [ebp-80h] + + Connect_10004028((int)&v2, 128, (int)&v3, 128); + dword_1002A148 = 0; + v1 = &byte_1002A154; + if ( !dword_1002A124 ) + v1 = a1; + dword_1002A120 = SNetJoinGame(0, v1, 0, &v2, &v3, dword_1002A140); + if ( !dword_1002A120 ) + dword_1002A12C = SErrGetLastError(); + dword_1002A148 = 1; + _endthread(); +} */ +// 10010406: using guessed type _DWORD __stdcall SErrGetLastError(); +// 10010430: using guessed type int __stdcall SNetJoinGame(_DWORD, _DWORD, _DWORD, _DWORD, _DWORD, _DWORD); +// 10011E20: using guessed type int _endthread(void); +// 1002A120: using guessed type int dword_1002A120; +// 1002A124: using guessed type int dword_1002A124; +// 1002A12C: using guessed type int dword_1002A12C; +// 1002A140: using guessed type int dword_1002A140; +// 1002A148: using guessed type int dword_1002A148; + +// ref: 0x10008BB7 +int UNKCALL Modem_10008BB7(HWND hWnd) { return 0; } +/* { + HWND v1; // esi + int result; // eax + int v3; // [esp+4h] [ebp-20h] + + v1 = hWnd; + if ( SDlgDialogBoxParam(hInstance, "ENTERDIAL_DIALOG", hWnd, EntDial_10006C96, &v3) == 1 ) + result = Modem_10008A38(v1, (int)&v3); + else + result = PostMessageA(v1, 0xBD0u, 0, 0); + return result; +} */ +// 10010370: using guessed type int __stdcall SDlgDialogBoxParam(_DWORD, _DWORD, _DWORD, _DWORD, _DWORD); + +// ref: 0x10008BFE +int UNKCALL Modem_10008BFE(HWND hWnd) { return 0; } +/* { + HWND v1; // esi + int v2; // eax + int v3; // eax + + v1 = hWnd; + v2 = SDlgDialogBoxParam(hInstance, "SELCRE8JOIN_DIALOG", hWnd, SelDial_1000B0CF, 0) - 3; + if ( !v2 ) + return Modem_1000893D(v1); + v3 = v2 - 2; + if ( !v3 ) + return Modem_10008A38(v1, (int)&byte_1002A154); + if ( v3 != 1217 ) + return SelHero_1000C3E2((int)v1, 2); + dword_1002A124 = 0; + return PostMessageA(v1, 0xBD0u, 0, 0); +} */ +// 10010370: using guessed type int __stdcall SDlgDialogBoxParam(_DWORD, _DWORD, _DWORD, _DWORD, _DWORD); +// 1002A124: using guessed type int dword_1002A124; diff --git a/2020_03_31/DiabloUI/modmstat.cpp b/2020_03_31/DiabloUI/modmstat.cpp new file mode 100644 index 00000000..65d5590c --- /dev/null +++ b/2020_03_31/DiabloUI/modmstat.cpp @@ -0,0 +1,196 @@ +// ref: 0x10008C62 +int __stdcall ModmStat_10008C62(char *a1, int a2, int a3, int a4, int a5) { return 0; } +/* { + int result; // eax + + strcpy(&byte_1002A264, a1); + result = 1; + dword_1002A258 = 1; + dword_1002A260 = (int (*)(void))a5; + return result; +} */ +// 1002A258: using guessed type int dword_1002A258; +// 1002A260: using guessed type int (*dword_1002A260)(void); + +// ref: 0x10008C87 +int UNKCALL ModmStat_10008C87(void *arg) { return 0; } +/* { + return SDlgDialogBoxParam(hInstance, "MODMSTAT_DIALOG", arg, ModmStat_10008CA0, 0); +} */ +// 10010370: using guessed type int __stdcall SDlgDialogBoxParam(_DWORD, _DWORD, _DWORD, _DWORD, _DWORD); + +// ref: 0x10008CA0 +int __stdcall ModmStat_10008CA0(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) { return 0; } +/* { + HWND v4; // eax + HWND v6; // eax + + if ( Msg == 2 ) + { + ModmStat_10008DB3(hWnd); + } + else if ( Msg > 0x103 ) + { + if ( Msg <= 0x105 ) + { + v6 = (HWND)SDrawGetFrameWindow(); + SendMessageA(v6, Msg, wParam, lParam); + } + else + { + switch ( Msg ) + { + case 0x110u: + ModmStat_10008DE4(hWnd); + return 0; + case 0x111u: + if ( HIWORD(wParam) == 7 ) + { + Focus_100075B7(hWnd, (HWND)lParam); + } + else if ( HIWORD(wParam) == 6 ) + { + Focus_10007458((void *)lParam); + Focus_100075DC(hWnd, (HWND)lParam); + } + else if ( (_WORD)wParam == 1 || (_WORD)wParam == 2 ) + { + ModmStat_10008E89((int)hWnd, 1); + } + break; + case 0x113u: + if ( dword_1002A258 ) + ModmStat_10008EBF(hWnd); + if ( Modem_10008653() ) + { + dword_1002A25C = 1; + ModmStat_10008E89((int)hWnd, 0); + } + v4 = GetFocus(); + Focus_100075DC(hWnd, v4); + return 0; + } + } + } + return SDlgDefDialogProc(hWnd, Msg, wParam, lParam); +} */ +// 1001037C: using guessed type int __stdcall SDlgDefDialogProc(_DWORD, _DWORD, _DWORD, _DWORD); +// 10010382: using guessed type _DWORD __stdcall SDrawGetFrameWindow(); +// 1002A258: using guessed type int dword_1002A258; +// 1002A25C: using guessed type int dword_1002A25C; + +// ref: 0x10008DB3 +int UNKCALL ModmStat_10008DB3(HWND hDlg) { return 0; } +/* { + HWND v1; // esi + _DWORD *v2; // eax + + v1 = hDlg; + v2 = (_DWORD *)GetWindowLongA(hDlg, -21); + local_10007F72(v2); + Focus_100076C3(); + Doom_10006C53(v1, (int *)&unk_10022CB4); + return Doom_10006C53(v1, (int *)&unk_10022CAC); +} */ + +// ref: 0x10008DE4 +BOOL UNKCALL ModmStat_10008DE4(HWND hWnd) { return 0; } +/* { + HWND v1; // esi + int v2; // eax + int *v3; // edi + HWND v4; // eax + BOOL result; // eax + + v1 = hWnd; + v2 = local_10007F46(); + v3 = (int *)v2; + if ( v2 ) + { + SetWindowLongA(v1, -21, v2); + local_10007944((int)v1, 0, "Popup", -1, 1, (int)"ui_art\\black.pcx", v3, v3 + 1, 1); + } + Doom_100068AB(v1, (int *)&unk_10022CAC, 3); + Doom_1000658C(v1, (int *)&unk_10022CB4, 4, 1); + Focus_10007719("ui_art\\focus.pcx"); + SDlgSetTimer(v1, 1, 55, 0); + local_10007DE9(v1, (int *)&unk_10022CB4); + byte_1002A264 = 0; + dword_1002A258 = 0; + dword_1002A260 = 0; + v4 = GetDlgItem(v1, 2); + result = ShowWindow(v4, 0); + dword_1002A25C = 0; + return result; +} */ +// 10010412: using guessed type int __stdcall SDlgSetTimer(_DWORD, _DWORD, _DWORD, _DWORD); +// 1002A258: using guessed type int dword_1002A258; +// 1002A25C: using guessed type int dword_1002A25C; +// 1002A260: using guessed type int (*dword_1002A260)(void); + +// ref: 0x10008E89 +int __fastcall ModmStat_10008E89(int a1, int a2) { return 0; } +/* { + int v2; // edi + int v3; // esi + int result; // eax + + v2 = a2; + v3 = a1; + if ( dword_1002A25C ) + { + TitleSnd_1001031F(); + SDlgKillTimer(v3, 1); + if ( v2 ) + { + if ( dword_1002A260 ) + dword_1002A260(); + } + result = SDlgEndDialog(v3, 0); + } + return result; +} */ +// 1002A260: invalid function type has been ignored +// 10010376: using guessed type int __stdcall SDlgEndDialog(_DWORD, _DWORD); +// 10010418: using guessed type int __stdcall SDlgKillTimer(_DWORD, _DWORD); +// 1002A25C: using guessed type int dword_1002A25C; +// 1002A260: using guessed type int (*dword_1002A260)(void); + +// ref: 0x10008EBF +void UNKCALL ModmStat_10008EBF(HWND hDlg) { return; } +/* { + HWND v1; // edi + HWND v2; // eax + int v3; // eax + HWND v4; // eax + + dword_1002A258 = 0; + v1 = hDlg; + if ( dword_1002A260 ) + { + v2 = GetDlgItem(hDlg, 1026); + if ( v2 ) + { + v3 = GetWindowLongA(v2, -21); + local_10007FA4(v3, &byte_1002A264); + Doom_10006A13(v1, (int *)&unk_10022CAC, 3); + v4 = GetDlgItem(v1, 2); + ShowWindow(v4, 1); + dword_1002A25C = 1; + } + } +} */ +// 1002A258: using guessed type int dword_1002A258; +// 1002A25C: using guessed type int dword_1002A25C; +// 1002A260: using guessed type int (*dword_1002A260)(void); + +// ref: 0x10008F26 +signed int ModmStat_10008F26() { return 0; } +/* { + signed int result; // eax + + result = 2139095040; + dword_1002A254 = 2139095040; + return result; +} */ +// 1002A254: using guessed type int dword_1002A254; diff --git a/2020_03_31/DiabloUI/okcancel.cpp b/2020_03_31/DiabloUI/okcancel.cpp new file mode 100644 index 00000000..387add37 --- /dev/null +++ b/2020_03_31/DiabloUI/okcancel.cpp @@ -0,0 +1,302 @@ +// ref: 0x10008F31 +BOOL __fastcall OkCancel_DrawString(HWND hWnd, char *str) +{ + HDC v3; // edi + void *v4; // eax + int v5; // eax + BOOL result; // eax + LONG v7; // [esp+14h] [ebp-20h] + LONG v8; // [esp+18h] [ebp-1Ch] + struct tagRECT Rect; // [esp+1Ch] [ebp-18h] + HGDIOBJ h; // [esp+2Ch] [ebp-8h] + + if ( !str || !*str ) + goto LABEL_13; + if ( !hWnd ) + goto LABEL_14; + GetClientRect(hWnd, &Rect); + --Rect.right; + --Rect.bottom; + v7 = Rect.right; + v8 = Rect.bottom; + v3 = GetDC(hWnd); + v4 = (void *)SendMessageA(hWnd, 0x31u, 0, 0); + h = SelectObject(v3, v4); + if ( !v3 ) + goto LABEL_13; + v5 = strlen(str); + DrawTextA(v3, str, v5, &Rect, 0x410u); + if ( h ) + SelectObject(v3, h); + ReleaseDC(hWnd, v3); + if ( Rect.bottom > v8 || Rect.right > v7 ) +LABEL_14: + result = 1; + else +LABEL_13: + result = 0; + return result; +} + +// ref: 0x10008FEC +void __cdecl OkCancel_cpp_init() +{ + OkCancel_cpp_float = OkCancel_cpp_float_value; +} +// 1001F440: using guessed type int OkCancel_cpp_float_value; +// 1002A2E4: using guessed type int OkCancel_cpp_float; + +// ref: 0x10008FF7 +LRESULT __stdcall OkCancel_WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) +{ + HWND v5; // ecx + int v6; // edx + HWND v7; // eax + LONG v8; // eax + HWND v9; // eax + + if ( Msg == 2 ) + { + ShowCursor(0); + OkCancel_FreeDlgBmp(hWnd); + return (LRESULT)SDlgDefDialogProc(hWnd, Msg, (HDC)wParam, (HWND)lParam); + } + if ( Msg <= 0x103 ) + return (LRESULT)SDlgDefDialogProc(hWnd, Msg, (HDC)wParam, (HWND)lParam); + if ( Msg <= 0x105 ) + { + v9 = (HWND)SDrawGetFrameWindow(NULL); + SendMessageA(v9, Msg, wParam, lParam); + return (LRESULT)SDlgDefDialogProc(hWnd, Msg, (HDC)wParam, (HWND)lParam); + } + if ( Msg != 272 ) + { + if ( Msg != 273 ) + { + if ( Msg == 312 && GetWindowLongA((HWND)lParam, -12) == 1038 ) + { + local_SetWhiteText((HDC)wParam); + return (LRESULT)GetStockObject(5); + } + return (LRESULT)SDlgDefDialogProc(hWnd, Msg, (HDC)wParam, (HWND)lParam); + } + if ( (unsigned short)wParam == 1 ) + { + v7 = GetFocus(); + v8 = GetWindowLongA(v7, -12); + v5 = hWnd; + if ( v8 == 1109 ) + { + v6 = 1; + goto LABEL_16; + } + } + else + { + if ( (unsigned short)wParam != 2 ) + { + if ( (unsigned short)wParam == 1109 ) + { + v5 = hWnd; + v6 = 1; +LABEL_16: + OkCancel_PlaySndEndDlg(v5, v6); + } + return (LRESULT)SDlgDefDialogProc(hWnd, Msg, (HDC)wParam, (HWND)lParam); + } + v5 = hWnd; + } + v6 = 2; + goto LABEL_16; + } + ShowCursor(1); + if ( !OkCancel_LoadOkCancGFX(hWnd, (DWORD *)lParam) ) + SDlgEndDialog(hWnd, (HANDLE)0xFF000000); + return 1; +} +// 10010382: using guessed type _DWORD __stdcall SDrawGetFrameWindow(); + +// ref: 0x10009117 +void __fastcall OkCancel_FreeDlgBmp(HWND hWnd) +{ + void **v1; // eax MAPDST + void *v3; // eax + void *v4; // eax + + v1 = (void **)RemovePropA(hWnd, "DLGBMP"); + if ( v1 ) + { + v3 = *v1; + if ( v3 ) + SMemFree(v3, "C:\\Src\\Diablo\\DiabloUI\\OkCancel.cpp", 48, 0); + v4 = v1[1]; + if ( v4 ) + SMemFree(v4, "C:\\Src\\Diablo\\DiabloUI\\OkCancel.cpp", 50, 0); + SMemFree(v1, "C:\\Src\\Diablo\\DiabloUI\\OkCancel.cpp", 51, 0); + } +} + +// ref: 0x10009161 +BOOL __fastcall OkCancel_LoadOkCancGFX(HWND hWnd, DWORD *lParam) +{ + unsigned char v3; // zf + HWND v4; // edi + tagPALETTEENTRY *v5; // edi + HWND v6; // eax + HWND v7; // edi + BYTE **v8; // edi + HWND v9; // eax + const CHAR *v10; // ST1C_4 + HWND v11; // eax + HWND v12; // edi + int a2a; // [esp+Ch] [ebp-20h] + int v15; // [esp+10h] [ebp-1Ch] + int v16; // [esp+14h] [ebp-18h] + DWORD data[2]; // [esp+18h] [ebp-14h] + BYTE **pBuffer; // [esp+20h] [ebp-Ch] + char *pszFileName; // [esp+24h] [ebp-8h] + + a2a = 1109; + v15 = 2; + v16 = 0; + pBuffer = (BYTE **)SMemAlloc(8u, "C:\\Src\\Diablo\\DiabloUI\\OkCancel.cpp", 110, 0); + SetPropA(hWnd, "DLGBMP", pBuffer); + if ( lParam[2] ) + { + v3 = lParam[3] == 0; + pszFileName = "ui_art\\lrpopup.pcx"; + if ( v3 ) + pszFileName = "ui_art\\lpopup.pcx"; + } + else if ( lParam[3] ) + { + pszFileName = "ui_art\\srpopup.pcx"; + } + else + { + pszFileName = "ui_art\\spopup.pcx"; + } + v4 = GetParent(hWnd); + if ( (HWND)SDrawGetFrameWindow(NULL) == v4 ) + { + local_LoadArtWithPal(hWnd, 0, &nullcharacter, -1, 1, pszFileName, pBuffer, 0, 1); + v5 = local_GetArtPalEntry(0); + SDrawUpdatePalette(0, 0xAu, v5, 0); + SDrawUpdatePalette(0x70u, 0x90u, v5 + 112, 1); + } + else + { + v6 = GetParent(hWnd); + local_LoadArtWithPal(hWnd, (int)v6, "Popup", -1, 1, pszFileName, pBuffer, 0, 1); + } + v7 = GetParent(hWnd); + if ( (HWND)SDrawGetFrameWindow(NULL) == v7 ) + Fade_SetInputWindow(hWnd); + v8 = pBuffer + 1; + local_LoadArtImage("ui_art\\but_sml.pcx", pBuffer + 1, data); + local_FitButtonDlg(hWnd, &a2a, *v8, data); + v9 = GetDlgItem(hWnd, 1026); + v10 = (const CHAR *)lParam[1]; + pBuffer = (BYTE **)v9; + SetWindowTextA(v9, v10); + if ( lParam[4] && OkCancel_DrawString((HWND)pBuffer, (char *)lParam[1]) ) + return 0; + if ( *lParam ) + { + v11 = GetDlgItem(hWnd, 1038); + v12 = v11; + if ( lParam[4] && OkCancel_DrawString(v11, (char *)*lParam) ) + return 0; + if ( v12 ) + SetWindowTextA(v12, (LPCSTR)*lParam); + } + return 1; +} +// 10010382: using guessed type _DWORD __stdcall SDrawGetFrameWindow(); + +// ref: 0x100092F5 +void __fastcall OkCancel_PlaySndEndDlg(HWND hWnd, int a2) +{ + TitleSnd_PlaySelectSound(); + SDlgEndDialog(hWnd, (HANDLE)a2); +} + +// ref: 0x1000930A +void __fastcall OkCancel_DoOkDialog(HWND hWnd, char *str, int a3) +{ + int a5[5]; // [esp+0h] [ebp-14h] + + a5[1] = (int)str; + a5[2] = 0; + a5[0] = 0; + a5[4] = 0; + a5[3] = a3; + SDlgDialogBoxParam(ghUiInst, "OK_DIALOG", (int)hWnd, OkCancel_WndProc, (int)a5); +} + +// ref: 0x10009342 +void __stdcall UiMessageBoxCallback(HWND hWnd, char *lpText, LPCSTR lpCaption, UINT uType) +{ + int v4; // eax + unsigned char v5; // sf + unsigned char v6; // of + size_t v7; // eax + char *v8; // eax + int v9; // ecx + int a5[5]; // [esp+0h] [ebp-24h] + int v11; // [esp+14h] [ebp-10h] + void *location; // [esp+18h] [ebp-Ch] + char *szDialog; // [esp+1Ch] [ebp-8h] + char *v14; // [esp+20h] [ebp-4h] + + a5[0] = (int)lpCaption; + a5[1] = (int)lpText; + szDialog = "OK_DIALOG"; + a5[4] = 1; + if ( uType & 0xF ) + szDialog = "OKCANCEL_DIALOG"; + a5[3] = (uType & 0xF0) == 16 || (uType & 0xF0) == 48; + v4 = 0; + a5[2] = 0; + while ( 1 ) + { + v14 = (char *)SDlgDialogBoxParam(ghUiInst, &szDialog[32 * v4], (int)hWnd, OkCancel_WndProc, (int)a5); + if ( v14 != (char *)0xFF000000 ) + break; + v4 = a5[2] + 1; + v6 = __OFSUB__(a5[2] + 1, 2); + v5 = a5[2]++ - 1 < 0; + if ( !(v5 ^ v6) ) + { + v7 = strlen(lpText); + v8 = (char *)SMemAlloc(v7 + 256, "C:\\Src\\Diablo\\DiabloUI\\OkCancel.cpp", 392, 0); + v11 = 0; /* check */ + location = v8; + v14 = lpText; + if ( *lpText ) + { + v9 = v11; + do + { + if ( *v14 <= 32 ) + v9 = 0; + *v8++ = *v14; + if ( ++v9 > 18 ) + { + *v8++ = 10; + v9 = 0; + } + ++v14; + } + while ( *v14 ); + } + *v8 = 0; + a5[1] = (int)location; + v14 = (char *)SDlgDialogBoxParam(ghUiInst, szDialog, (int)hWnd, OkCancel_WndProc, (int)a5); + SMemFree(location, "C:\\Src\\Diablo\\DiabloUI\\OkCancel.cpp", 416, 0); + if ( v14 == (char *)0xFF000000 ) + MessageBoxA(hWnd, lpText, lpCaption, uType); + return; + } + } +} diff --git a/2020_03_31/DiabloUI/progress.cpp b/2020_03_31/DiabloUI/progress.cpp new file mode 100644 index 00000000..f57b77be --- /dev/null +++ b/2020_03_31/DiabloUI/progress.cpp @@ -0,0 +1,314 @@ +// ref: 0x10009480 +signed int Progress_10009480() { return 0; } +/* { + signed int result; // eax + + result = 2139095040; + dword_1002A2EC = 2139095040; + return result; +} */ +// 1002A2EC: using guessed type int dword_1002A2EC; + +// ref: 0x1000948B +int __stdcall UiProgressDialog(HWND window, char *msg, int a3, void *fnfunc, int a5) { return 0; } +/* { + HWND v5; // eax + BOOL result; // eax + + dword_1002A2E8 = -1; + dword_1002A2F8 = 0; + dword_1002A2F4 = a4; + bEnable = a3; + dword_1002A2F0 = a5; + v5 = (HWND)SDlgCreateDialogParam(hInstance, "PROGRESS_DIALOG", a1, Progress_100094F4, a2); + result = 0; + if ( v5 ) + { + Progress_1000991C(v5); + if ( dword_1002A2E8 != 2 && dword_1002A2E8 != -1 ) + result = 1; + } + return result; +} */ +// 1001045A: using guessed type int __stdcall SDlgCreateDialogParam(_DWORD, _DWORD, _DWORD, _DWORD, _DWORD); +// 1002A2E8: using guessed type int dword_1002A2E8; +// 1002A2F0: using guessed type int dword_1002A2F0; +// 1002A2F4: using guessed type int (*dword_1002A2F4)(void); +// 1002A2F8: using guessed type int dword_1002A2F8; + +// ref: 0x100094F4 +int __stdcall Progress_100094F4(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) { return 0; } +/* { + HWND v4; // eax + void *v5; // eax + HWND v7; // eax + + if ( Msg == 2 ) + { + ShowCursor(0); + Progress_100095EC(); + } + else if ( Msg > 0x103 ) + { + if ( Msg <= 0x105 ) + { + v7 = (HWND)SDrawGetFrameWindow(); + SendMessageA(v7, Msg, wParam, lParam); + } + else + { + switch ( Msg ) + { + case 0x110u: + Progress_10009675(hWnd, (const CHAR *)lParam); + v5 = (void *)SDrawGetFrameWindow(); + local_1000812B(v5); + local_1000812B(hWnd); + ShowCursor(1); + return 1; + case 0x111u: + if ( (_WORD)wParam == 2 ) + { + SDlgKillTimer(hWnd, 1); + v4 = GetParent(hWnd); + if ( (HWND)SDrawGetFrameWindow() == v4 ) + Fade_100072BE(10); + Progress_100098B0(); + } + break; + case 0x113u: + Progress_100098C5(hWnd); + break; + } + } + } + return SDlgDefDialogProc(hWnd, Msg, wParam, lParam); +} */ +// 1001037C: using guessed type int __stdcall SDlgDefDialogProc(_DWORD, _DWORD, _DWORD, _DWORD); +// 10010382: using guessed type _DWORD __stdcall SDrawGetFrameWindow(); +// 10010418: using guessed type int __stdcall SDlgKillTimer(_DWORD, _DWORD); + +// ref: 0x100095EC +void *Progress_100095EC() { return 0; } +/* { + int result; // eax + + if ( dword_1002A318 ) + { + SMemFree(dword_1002A318, "C:\\Src\\Diablo\\DiabloUI\\Progress.cpp", 88, 0); + dword_1002A318 = 0; + } + if ( dword_1002A31C ) + { + SMemFree(dword_1002A31C, "C:\\Src\\Diablo\\DiabloUI\\Progress.cpp", 92, 0); + dword_1002A31C = 0; + } + if ( dword_1002A320 ) + { + SMemFree(dword_1002A320, "C:\\Src\\Diablo\\DiabloUI\\Progress.cpp", 96, 0); + dword_1002A320 = 0; + } + if ( dword_1002A324 ) + { + SMemFree(dword_1002A324, "C:\\Src\\Diablo\\DiabloUI\\Progress.cpp", 100, 0); + dword_1002A324 = 0; + } + result = dword_1002A328; + if ( dword_1002A328 ) + { + result = SMemFree(dword_1002A328, "C:\\Src\\Diablo\\DiabloUI\\Progress.cpp", 104, 0); + dword_1002A328 = 0; + } + return result; +} */ +// 10010340: using guessed type int __stdcall SMemFree(_DWORD, _DWORD, _DWORD, _DWORD); +// 1002A318: using guessed type int dword_1002A318; +// 1002A31C: using guessed type int dword_1002A31C; +// 1002A320: using guessed type int dword_1002A320; +// 1002A324: using guessed type int dword_1002A324; +// 1002A328: using guessed type int dword_1002A328; + +// ref: 0x10009675 +BOOL __fastcall Progress_10009675(HWND hWnd, const CHAR *a2) { return 0; } +/* { + HWND v2; // ebx + HWND v3; // esi + char *v4; // esi + HWND v5; // eax + HWND v6; // esi + struct tagRECT Rect; // [esp+Ch] [ebp-28h] + char v9; // [esp+1Ch] [ebp-18h] + int v10; // [esp+24h] [ebp-10h] + int v11; // [esp+28h] [ebp-Ch] + LPCSTR lpString; // [esp+2Ch] [ebp-8h] + HWND v13; // [esp+30h] [ebp-4h] + + v2 = hWnd; + lpString = a2; + v10 = 2; + v11 = 0; + if ( dword_1002A2F0 ) + SDlgSetTimer(hWnd, 1, 0x3E8u / dword_1002A2F0, 0); + else + SDlgSetTimer(hWnd, 1, 50, 0); + local_10007944((int)v2, 0, &byte_10029448, -1, 1, (int)"ui_art\\spopup.pcx", &dword_1002A318, 0, 0); + v3 = GetParent(v2); + if ( (HWND)SDrawGetFrameWindow() == v3 ) + Fade_100073EF(v2); + v4 = local_10007895(0); + SDrawUpdatePalette(0, 10, v4, 0); + SDrawUpdatePalette(112, 144, v4 + 448, 1); + local_100078BE((int)"ui_art\\but_sml.pcx", &dword_1002A31C, &v9); + local_10007B1B(v2, &v10, dword_1002A31C, &v9); + local_100078BE((int)"ui_art\\prog_bg.pcx", &dword_1002A320, &dword_1002A310); + local_100078BE((int)"ui_art\\prog_fil.pcx", &dword_1002A324, &dword_1002A308); + v13 = GetDlgItem(v2, 1030); + GetClientRect(v13, &Rect); + dword_1002A328 = SMemAlloc(Rect.right * Rect.bottom, "C:\\Src\\Diablo\\DiabloUI\\Progress.cpp", 170, 0); + dword_1002A300 = Rect.right; + dword_1002A304 = Rect.bottom; + SDlgSetBitmapI(v13, 0, 0, -1, 1, dword_1002A328, 0, Rect.right, Rect.bottom, -1); + Progress_10009805(v2, 0); + v5 = GetDlgItem(v2, 1031); + SetWindowTextA(v5, lpString); + v6 = GetDlgItem(v2, 2); + ShowWindow(v6, bEnable != 0); + return EnableWindow(v6, bEnable); +} */ +// 10010364: using guessed type int __stdcall SMemAlloc(_DWORD, _DWORD, _DWORD, _DWORD); +// 10010382: using guessed type _DWORD __stdcall SDrawGetFrameWindow(); +// 100103FA: using guessed type int __stdcall SDrawUpdatePalette(_DWORD, _DWORD, _DWORD, _DWORD); +// 10010400: using guessed type int __stdcall SDlgSetBitmapI(_DWORD, _DWORD, _DWORD, _DWORD, _DWORD, _DWORD, _DWORD, _DWORD, _DWORD, _DWORD); +// 10010412: using guessed type int __stdcall SDlgSetTimer(_DWORD, _DWORD, _DWORD, _DWORD); +// 1002A2F0: using guessed type int dword_1002A2F0; +// 1002A300: using guessed type int dword_1002A300; +// 1002A304: using guessed type int dword_1002A304; +// 1002A308: using guessed type int dword_1002A308; +// 1002A310: using guessed type int dword_1002A310; +// 1002A318: using guessed type int dword_1002A318; +// 1002A31C: using guessed type int dword_1002A31C; +// 1002A320: using guessed type int dword_1002A320; +// 1002A324: using guessed type int dword_1002A324; +// 1002A328: using guessed type int dword_1002A328; + +// ref: 0x10009805 +BOOL __fastcall Progress_10009805(HWND hWnd, int a2) { return 0; } +/* { + HWND v2; // edi + struct tagRECT Rect; // [esp+8h] [ebp-18h] + HWND hWnda; // [esp+18h] [ebp-8h] + int v6; // [esp+1Ch] [ebp-4h] + + v2 = hWnd; + v6 = a2; + hWnda = GetDlgItem(hWnd, 1030); + SBltROP3( + dword_1002A328, + dword_1002A320, + dword_1002A300, + dword_1002A304, + dword_1002A300, + dword_1002A310, + 0, + 13369376); + SBltROP3( + dword_1002A328, + dword_1002A324, + v6 * dword_1002A300 / 100, + dword_1002A304, + dword_1002A300, + dword_1002A308, + 0, + 13369376); + GetWindowRect(hWnda, &Rect); + ScreenToClient(v2, (LPPOINT)&Rect); + ScreenToClient(v2, (LPPOINT)&Rect.right); + return InvalidateRect(v2, &Rect, 0); +} */ +// 100103F4: using guessed type int __stdcall SBltROP3(_DWORD, _DWORD, _DWORD, _DWORD, _DWORD, _DWORD, _DWORD, _DWORD); +// 1002A300: using guessed type int dword_1002A300; +// 1002A304: using guessed type int dword_1002A304; +// 1002A308: using guessed type int dword_1002A308; +// 1002A310: using guessed type int dword_1002A310; +// 1002A320: using guessed type int dword_1002A320; +// 1002A324: using guessed type int dword_1002A324; +// 1002A328: using guessed type int dword_1002A328; + +// ref: 0x100098B0 +void Progress_100098B0() { return; } +/* { + dword_1002A2E8 = 2; + dword_1002A2F8 = 1; +} */ +// 1002A2E8: using guessed type int dword_1002A2E8; +// 1002A2F8: using guessed type int dword_1002A2F8; + +// ref: 0x100098C5 +void UNKCALL Progress_100098C5(HWND hWnd) { return; } +/* { + HWND v1; // esi + int v2; // eax + HWND v3; // edi + int v4; // edx + + v1 = hWnd; + v2 = dword_1002A2F4(); + if ( v2 >= 100 ) + { + SDlgKillTimer(v1, 1); + v3 = GetParent(v1); + if ( (HWND)SDrawGetFrameWindow() == v3 ) + Fade_100072BE(10); + Progress_100098B0(); + dword_1002A2E8 &= v4; + } + else + { + Progress_10009805(v1, v2); + } +} */ +// 10010382: using guessed type _DWORD __stdcall SDrawGetFrameWindow(); +// 10010418: using guessed type int __stdcall SDlgKillTimer(_DWORD, _DWORD); +// 1002A2E8: using guessed type int dword_1002A2E8; +// 1002A2F4: using guessed type int (*dword_1002A2F4)(void); + +// ref: 0x1000991C +BOOL UNKCALL Progress_1000991C(HWND hWnd) { return 0; } +/* { + HWND v1; // edi + BOOL result; // eax + struct tagMSG Msg; // [esp+Ch] [ebp-1Ch] + + v1 = hWnd; + for ( result = IsWindow(hWnd); result; result = IsWindow(v1) ) + { + if ( dword_1002A2F8 ) + goto LABEL_12; + if ( PeekMessageA(&Msg, 0, 0, 0, 1u) ) + { + if ( Msg.message == 18 ) + { + PostQuitMessage(Msg.wParam); + } + else if ( !IsDialogMessageA(v1, &Msg) ) + { + TranslateMessage(&Msg); + DispatchMessageA(&Msg); + } + } + else + { + SDlgCheckTimers(); + SDlgUpdateCursor(); + } + } + if ( !dword_1002A2F8 ) + return result; +LABEL_12: + result = DestroyWindow(v1); + dword_1002A2F8 = 0; + return result; +} */ +// 10010460: using guessed type _DWORD __stdcall SDlgUpdateCursor(); +// 10010466: using guessed type _DWORD __stdcall SDlgCheckTimers(); +// 1002A2F8: using guessed type int dword_1002A2F8; diff --git a/2020_03_31/DiabloUI/sbar.cpp b/2020_03_31/DiabloUI/sbar.cpp new file mode 100644 index 00000000..0d453ad0 --- /dev/null +++ b/2020_03_31/DiabloUI/sbar.cpp @@ -0,0 +1,245 @@ +// ref: 0x100099B5 +void __cdecl Sbar_cpp_init() +{ + Sbar_cpp_float = Sbar_cpp_float_value; +} +// 1001F448: using guessed type int Sbar_cpp_float_value; +// 1002A338: using guessed type int Sbar_cpp_float; + +// ref: 0x100099C0 +BOOL __fastcall Sbar_CheckIfNextHero(HWND hWnd) +{ + _uiheroinfo *v1; // eax + + v1 = (_uiheroinfo *)GetWindowLongA(hWnd, -21); + if ( !v1 || !v1->next ) + return 0; + v1->next = 0; + return 1; +} + +// ref: 0x100099DC +int __fastcall Sbar_NumScrollLines(HWND hWnd, int width, int height) +{ + _DWORD *v4; // eax + _DWORD *v5; // esi + int result; // eax + signed int v7; // ecx + LONG v8; // ebx + LONG v9; // edi + int v10; // [esp-4h] [ebp-1Ch] + struct tagPOINT Point; // [esp+Ch] [ebp-Ch] + + Point.x = width; + Point.y = height; + if ( !hWnd ) + return 0; + if ( !IsWindowVisible(hWnd) ) + return 0; + v4 = (_DWORD *)GetWindowLongA(hWnd, -21); + v5 = v4; + if ( !v4 ) + return 0; + v7 = v4[13]; + if ( v7 <= 1 ) + v8 = 22; + else + v8 = v4[14] * (v4[3] - v4[9] - 44) / (v7 - 1) + 22; + v9 = v8 + v4[9]; + ScreenToClient(hWnd, &Point); + if ( Point.y >= 22 ) + { + if ( Point.y >= v8 ) + { + if ( Point.y >= v9 ) + { + if ( Point.y >= v5[3] - 22 ) + { + *v5 = 4; + v10 = 2; + } + else + { + *v5 = 8; + v10 = 4; + } + } + else + { + *v5 = 16; + v10 = 5; + } + } + else + { + *v5 = 2; + v10 = 3; + } + result = v10; + } + else + { + result = 1; + *v5 = 1; + } + return result; +} + +// ref: 0x10009A99 +void __fastcall Sbar_DrawScrollBar(HWND hWnd, int nIDDlgItem, int width, int height) +{ + HWND v4; // eax + LONG v5; // eax MAPDST + unsigned char v7; // zf + int v8; // eax + tagRECT DstRect; // [esp+Ch] [ebp-24h] + tagRECT SrcBuffer; // [esp+1Ch] [ebp-14h] + HWND hWnda; // [esp+2Ch] [ebp-4h] + + v4 = GetDlgItem(hWnd, nIDDlgItem); + hWnda = v4; + if ( v4 ) + { + v5 = GetWindowLongA(v4, -21); + if ( v5 ) + { + if ( *(_DWORD *)(v5 + 4) ) + { + v7 = *(_DWORD *)(v5 + 16) == 0; + *(_DWORD *)(v5 + 52) = width; + *(_DWORD *)(v5 + 56) = height; + if ( !v7 ) + { + SrcBuffer.left = 0; + DstRect.left = 0; + SrcBuffer.top = 0; + DstRect.top = 0; + DstRect.right = *(_DWORD *)(v5 + 8) - 1; + DstRect.bottom = *(_DWORD *)(v5 + 12) - 1; + SrcBuffer.right = *(_DWORD *)(v5 + 8) - 1; + SrcBuffer.bottom = *(_DWORD *)(v5 + 24) - 1; + SBltROP3Tiled( + *(void **)(v5 + 4), + &DstRect, + *(POINT **)(v5 + 8), + *(_DWORD *)(v5 + 16), + &SrcBuffer, + *(RECT **)(v5 + 20), + 0, + 0, + 0, + 0xCC0020u); + if ( *(_DWORD *)(v5 + 28) ) + { + if ( width <= 1 ) + v8 = 22; + else + v8 = height * (*(_DWORD *)(v5 + 12) - *(_DWORD *)(v5 + 36) - 44) / (width - 1) + 22; + SBltROP3( + (void *)(v8 * *(_DWORD *)(v5 + 8) + *(_DWORD *)(v5 + 4) + 3), + *(void **)(v5 + 28), + 18, + *(_DWORD *)(v5 + 36), + *(_DWORD *)(v5 + 8), + *(_DWORD *)(v5 + 32), + 0, + 0xCC0020u); + SBltROP3( + *(void **)(v5 + 4), + (void *)(*(_DWORD *)(v5 + 40) + 22 * (~*(_BYTE *)v5 & 1) * *(_DWORD *)(v5 + 44)), + *(_DWORD *)(v5 + 8), + 22, + *(_DWORD *)(v5 + 8), + *(_DWORD *)(v5 + 44), + 0, + 0xCC0020u); + SBltROP3( + (void *)(*(_DWORD *)(v5 + 4) + *(_DWORD *)(v5 + 8) * (*(_DWORD *)(v5 + 12) - 22)), + (void *)(*(_DWORD *)(v5 + 40) + 22 * ((~*(_BYTE *)v5 & 4 | 8u) >> 2) * *(_DWORD *)(v5 + 44)), + *(_DWORD *)(v5 + 8), + 22, + *(_DWORD *)(v5 + 8), + *(_DWORD *)(v5 + 44), + 0, + 0xCC0020u); + InvalidateRect(hWnda, 0, 0); + } + } + } + } + } +} + +// ref: 0x10009BF1 +void __fastcall Sbar_LoadScrBarGFX(HWND hWnd, int nIDDlgItem) +{ + DWORD *v2; // eax MAPDST + void *v4; // eax + struct tagRECT Rect; // [esp+Ch] [ebp-14h] + HWND hWnda; // [esp+1Ch] [ebp-4h] + + hWnda = GetDlgItem(hWnd, nIDDlgItem); + if ( hWnda ) + { + v2 = (DWORD *)SMemAlloc(0x3Cu, "C:\\Src\\Diablo\\DiabloUI\\Sbar.cpp", 221, 0); + if ( v2 ) + { + SetWindowLongA(hWnda, -21, (LONG)v2); + *v2 = 0; + GetClientRect(hWnda, &Rect); + v2[2] = Rect.right; + v2[3] = Rect.bottom; + v4 = SMemAlloc(Rect.right * Rect.bottom, "C:\\Src\\Diablo\\DiabloUI\\Sbar.cpp", 230, 0); + v2[1] = (DWORD)v4; + if ( v4 ) + { + SDlgSetBitmapI(hWnda, 0, &nullcharacter, -1, 1, v4, 0, v2[2], v2[3], -1); + local_LoadArtImage("ui_art\\sb_bg.pcx", (BYTE **)v2 + 4, v2 + 5); + local_LoadArtImage("ui_art\\sb_thumb.pcx", (BYTE **)v2 + 7, v2 + 8); + local_LoadArtImage("ui_art\\sb_arrow.pcx", (BYTE **)v2 + 10, v2 + 11); + } + } + } +} + +// ref: 0x10009CC7 +void __cdecl Sbar_cpp_init2() +{ + Sbar_cpp_float2 = Sbar_cpp_float_value2; +} +// 1001F44C: using guessed type int Sbar_cpp_float_value2; +// 1002A344: using guessed type int Sbar_cpp_float2; + +// ref: 0x10009CD2 +void __fastcall Sbar_FreeScrollBar(HWND hWnd, int nIDDlgItem) +{ + HWND v2; // eax MAPDST + _DWORD *v4; // eax MAPDST + void *v6; // eax + void *v7; // eax + void *v8; // eax + void *v9; // eax + + v2 = GetDlgItem(hWnd, nIDDlgItem); + if ( v2 ) + { + v4 = (_DWORD *)GetWindowLongA(v2, -21); + if ( v4 ) + { + v6 = (void *)v4[1]; + if ( v6 ) + SMemFree(v6, "C:\\Src\\Diablo\\DiabloUI\\Sbar.cpp", 267, 0); + v7 = (void *)v4[4]; + if ( v7 ) + SMemFree(v7, "C:\\Src\\Diablo\\DiabloUI\\Sbar.cpp", 269, 0); + v8 = (void *)v4[7]; + if ( v8 ) + SMemFree(v8, "C:\\Src\\Diablo\\DiabloUI\\Sbar.cpp", 271, 0); + v9 = (void *)v4[10]; + if ( v9 ) + SMemFree(v9, "C:\\Src\\Diablo\\DiabloUI\\Sbar.cpp", 273, 0); + SMemFree(v4, "C:\\Src\\Diablo\\DiabloUI\\Sbar.cpp", 275, 0); + SetWindowLongA(v2, -21, 0); + } + } +} diff --git a/2020_03_31/DiabloUI/selclass.cpp b/2020_03_31/DiabloUI/selclass.cpp new file mode 100644 index 00000000..5bba9991 --- /dev/null +++ b/2020_03_31/DiabloUI/selclass.cpp @@ -0,0 +1,167 @@ +// ref: 0x10009D66 +LRESULT __stdcall SelClass_WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) +{ + HWND v4; // eax + int v5; // edx + HWND v6; // eax + HWND v7; // eax + HWND v9; // eax + + if ( Msg == 2 ) + { + SelClass_FreeClassMsgTbl(hWnd); + return (LRESULT)SDlgDefDialogProc(hWnd, Msg, (HDC)wParam, (HWND)lParam); + } + if ( Msg <= 0x103 ) + return (LRESULT)SDlgDefDialogProc(hWnd, Msg, (HDC)wParam, (HWND)lParam); + if ( Msg <= 0x105 ) + { + v9 = (HWND)SDrawGetFrameWindow(NULL); + SendMessageA(v9, Msg, wParam, lParam); + return (LRESULT)SDlgDefDialogProc(hWnd, Msg, (HDC)wParam, (HWND)lParam); + } + if ( Msg == 272 ) + { + SelClass_LoadClassFocus(hWnd); + return 0; + } + if ( Msg != 273 ) + { + if ( Msg != 275 ) + { + if ( Msg == 513 ) + { + v4 = GetDlgItem(hWnd, 1056); + if ( local_GetBottomRect(hWnd, v4, (unsigned short)lParam, (unsigned int)lParam >> 16) ) + { + v5 = 1; +LABEL_19: + SelClass_CheckClassSpawn(hWnd, v5); + return (LRESULT)SDlgDefDialogProc(hWnd, Msg, (HDC)wParam, (HWND)lParam); + } + v6 = GetDlgItem(hWnd, 1054); + if ( local_GetBottomRect(hWnd, v6, (unsigned short)lParam, (unsigned int)lParam >> 16) ) + { +LABEL_21: + v5 = 2; + goto LABEL_19; + } + } + return (LRESULT)SDlgDefDialogProc(hWnd, Msg, (HDC)wParam, (HWND)lParam); + } + v7 = GetFocus(); + Focus_DoBlitSpinIncFrame(hWnd, v7); + return 0; + } + if ( HIWORD(wParam) == 7 ) + { + Focus_GetAndBlitSpin(hWnd, lParam); + } + else + { + if ( HIWORD(wParam) != 6 ) + { + v5 = 1; + if ( HIWORD(wParam) == 5 || (_WORD)wParam == 1 ) + goto LABEL_19; + if ( (_WORD)wParam != 2 ) + return (LRESULT)SDlgDefDialogProc(hWnd, Msg, (HDC)wParam, (HWND)lParam); + goto LABEL_21; + } + Focus_CheckPlayMove(lParam); + Focus_DoBlitSpinIncFrame(hWnd, (HWND)lParam); + SelClass_SetDefaultStats(hWnd, (unsigned short)wParam); + } + return (LRESULT)SDlgDefDialogProc(hWnd, Msg, (HDC)wParam, (HWND)lParam); +} +// 10010382: using guessed type _DWORD __stdcall SDrawGetFrameWindow(); + +// ref: 0x10009EC0 +void __fastcall SelClass_FreeClassMsgTbl(HWND hWnd) +{ + HWND v2; // eax + + Focus_DeleteSpinners(); + Doom_DeleteFreeProcs(hWnd, selclass_msgtbl3); + Doom_DeleteFreeProcs(hWnd, selclass_msgtbl2); + Doom_DeleteFreeProcs(hWnd, selclass_msgtbl1); + v2 = GetParent(hWnd); + SelHero_SetStringWithMsg(v2, 0); +} + +// ref: 0x10009EFD +void __fastcall SelClass_LoadClassFocus(HWND hWnd) +{ + HWND v1; // edi + HWND v2; // esi + LONG v3; // eax + char Buffer[32]; // [esp+8h] [ebp-20h] + + v1 = hWnd; + v2 = GetParent(hWnd); + if ( SelHero_GetHeroIsGood() == 1 ) + LoadStringA(ghUiInst, 0x20u, Buffer, 31); + else + LoadStringA(ghUiInst, 0x1Fu, Buffer, 31); + SelHero_SetStringWithMsg(v2, Buffer); + v3 = GetWindowLongA(v2, -21); + SetWindowLongA(v1, -21, v3); + local_DoUiWndProc(v1, (DWORD *)selclass_msgtbl3); + Doom_ParseWndProc3(v1, selclass_msgtbl1, 5); + Doom_ParseWndProcs(v1, selclass_msgtbl2, 4, 0); + Doom_ParseWndProcs(v1, selclass_msgtbl3, 2, 1); + Focus_LoadSpinner("ui_art\\focus.pcx"); + SDlgSetTimer((int)v1, 1, 55, 0); +} + +// ref: 0x10009FA2 +void __fastcall SelClass_SetDefaultStats(HWND hWnd, int a2) +{ + char v2; // bl + HWND v4; // eax + _uiheroinfo pInfo; // [esp+8h] [ebp-34h] + _uidefaultstats a2a; // [esp+34h] [ebp-8h] + + v2 = a2; + SelHero_SetClassStats(a2 - 1062, &a2a); + memset(&pInfo, 0, 0x2Cu); + pInfo.strength = a2a.strength; + pInfo.magic = a2a.magic; + pInfo.dexterity = a2a.dexterity; + pInfo.vitality = a2a.vitality; + pInfo.level = 1; + pInfo.heroclass = v2 - 38; + v4 = GetParent(hWnd); + SelHero_PrintHeroInfo(v4, &pInfo); +} + +// ref: 0x1000A00D +void __fastcall SelClass_CheckClassSpawn(HWND hWnd, int a2) +{ + HWND v4; // eax + HWND v5; // eax + + if ( DiabloUI_GetSpawned() && a2 == 1 && (v4 = GetFocus(), GetWindowLongA(v4, -12) != 1062) ) + { + SelYesNo_SpawnErrDialog(hWnd, 69, 0); + } + else + { + TitleSnd_PlaySelectSound(); + SDlgKillTimer((int)hWnd, 1); + if ( a2 == 1 ) + { + v5 = GetFocus(); + a2 = GetWindowLongA(v5, -12); + } + SDlgEndDialog(hWnd, (HANDLE)a2); + } +} + +// ref: 0x1000A077 +void __cdecl SelClass_cpp_init() +{ + SelClass_cpp_float = SelClass_cpp_float_value; +} +// 1001F450: using guessed type int SelClass_cpp_float_value; +// 1002A348: using guessed type int SelClass_cpp_float; diff --git a/2020_03_31/DiabloUI/selconn.cpp b/2020_03_31/DiabloUI/selconn.cpp new file mode 100644 index 00000000..d287c140 --- /dev/null +++ b/2020_03_31/DiabloUI/selconn.cpp @@ -0,0 +1,1146 @@ +// ref: 0x1000A082 +void *SelConn_1000A082() { return 0; } +/* { + return SMemAlloc(272, "C:\\Src\\Diablo\\DiabloUI\\SelConn.cpp", 124, 0); +} */ +// 10010364: using guessed type int __stdcall SMemAlloc(_DWORD, _DWORD, _DWORD, _DWORD); + +// ref: 0x1000A09B +signed int SelConn_1000A09B() { return 0; } +/* { + signed int result; // eax + + result = 2139095040; + dword_1002A350 = 2139095040; + return result; +} */ +// 1002A350: using guessed type int dword_1002A350; + +// ref: 0x1000A0A6 +int __stdcall SelConn_1000A0A6(HWND hWnd, UINT Msg, WPARAM wParam, unsigned int lParam) { return 0; } +/* { + HWND v4; // eax + HWND v6; // eax + char *v7; // [esp+0h] [ebp-Ch] + int v8; // [esp+4h] [ebp-8h] + + if ( Msg > 0x201 ) + { + if ( Msg == 514 ) + { + v6 = GetDlgItem(hWnd, 1105); + if ( !Sbar_100099C0(v6) ) + return SDlgDefDialogProc(hWnd, Msg, wParam, lParam); + goto LABEL_27; + } + if ( Msg != 515 ) + { + if ( Msg != 2024 ) + return SDlgDefDialogProc(hWnd, Msg, wParam, lParam); + if ( !Fade_1000739F() ) + Fade_100073FD(hWnd, (int)v7); + return 0; + } +LABEL_25: + SelConn_1000AE59(hWnd, (unsigned short)lParam, lParam >> 16); + return SDlgDefDialogProc(hWnd, Msg, wParam, lParam); + } + if ( Msg == 513 ) + goto LABEL_25; + if ( Msg == 2 ) + { + SelConn_1000A43A(hWnd); + BNetGW_10002A07(&unk_10029480); + return SDlgDefDialogProc(hWnd, Msg, wParam, lParam); + } + if ( Msg <= 0x103 ) + return SDlgDefDialogProc(hWnd, Msg, wParam, lParam); + if ( Msg <= 0x105 ) + { + v4 = (HWND)SDrawGetFrameWindow(); + SendMessageA(v4, Msg, wParam, lParam); + return SDlgDefDialogProc(hWnd, Msg, wParam, lParam); + } + if ( Msg == 272 ) + { + BNetGW_100028C2(&unk_10029480); + SelConn_1000A4E4(hWnd, v7, v8); + PostMessageA(hWnd, 0x7E8u, 0, 0); + return 0; + } + if ( Msg == 273 ) + { + if ( HIWORD(wParam) == 7 ) + { + Focus_100075B7(hWnd, (HWND)lParam); + return SDlgDefDialogProc(hWnd, Msg, wParam, lParam); + } + if ( HIWORD(wParam) != 6 ) + { + if ( wParam == 327681 ) + { + SelConn_1000AC30(hWnd); + } + else if ( (_WORD)wParam == 2 ) + { + SelConn_1000AC07((int)hWnd, 2); + } + return SDlgDefDialogProc(hWnd, Msg, wParam, lParam); + } + Focus_10007458((void *)lParam); + Focus_100075DC(hWnd, (HWND)lParam); + SelConn_1000A226(hWnd, (unsigned short)wParam); +LABEL_27: + SelConn_1000A3E2(hWnd); + } + return SDlgDefDialogProc(hWnd, Msg, wParam, lParam); +} */ +// 1001037C: using guessed type int __stdcall SDlgDefDialogProc(_DWORD, _DWORD, _DWORD, _DWORD); +// 10010382: using guessed type _DWORD __stdcall SDrawGetFrameWindow(); + +// ref: 0x1000A226 +HWND __fastcall SelConn_1000A226(HWND hDlg, int nIDDlgItem) { return 0; } +/* { + HWND v2; // edi + HWND result; // eax + int v4; // ebx + int v5; // eax + HWND v6; // ebp + unsigned int v7; // eax + int v8; // eax + const char *v9; // ebx + int v10; // eax + HWND v11; // eax + HWND v12; // eax + HWND v13; // eax + HWND v14; // eax + HWND v15; // eax + HWND v16; // eax + HWND v17; // eax + HWND v18; // eax + HWND hWnd; // [esp+10h] [ebp-8Ch] + CHAR Buffer; // [esp+14h] [ebp-88h] + CHAR v21; // [esp+54h] [ebp-48h] + + v2 = hDlg; + result = GetDlgItem(hDlg, nIDDlgItem); + if ( result ) + { + result = (HWND)GetWindowLongA(result, -21); + if ( result ) + { + v4 = *((_DWORD *)result + 3); + if ( v4 ) + { + result = GetDlgItem(v2, 1081); + if ( result ) + { + v5 = GetWindowLongA(result, -21); + local_10007FA4(v5, (const char *)(v4 + 144)); + result = GetDlgItem(v2, 1076); + v6 = result; + if ( result ) + { + LoadStringA(hInstance, 0x21u, &Buffer, 63); + if ( dword_1002A370 ) + { + v7 = *(_DWORD *)(dword_1002A370 + 24); + if ( v7 >= *(_DWORD *)(v4 + 12) ) + v7 = *(_DWORD *)(v4 + 12); + wsprintfA(&v21, &Buffer, v7); + } + else + { + wsprintfA(&v21, &Buffer, *(_DWORD *)(v4 + 12)); + } + v8 = GetWindowLongA(v6, -21); + local_10007FA4(v8, &v21); + if ( *(_DWORD *)(v4 + 8) == 1112425812 ) + { + hWnd = GetDlgItem(v2, 1144); + v9 = BNetGW_10002B21(&unk_10029480, dword_1002948C); + if ( !v9 ) + v9 = &byte_10029448; + if ( hWnd ) + { + v10 = GetWindowLongA(hWnd, -21); + local_10007FA4(v10, v9); + } + v11 = GetDlgItem(v2, 1143); + ShowWindow(v11, 5); + v12 = GetDlgItem(v2, 1147); + ShowWindow(v12, 0); + v13 = GetDlgItem(v2, 1144); + ShowWindow(v13, 5); + v14 = GetDlgItem(v2, 1145); + ShowWindow(v14, 5); + dword_1002A354 = 1; + } + else + { + v15 = GetDlgItem(v2, 1143); + ShowWindow(v15, 0); + v16 = GetDlgItem(v2, 1147); + ShowWindow(v16, 5); + v17 = GetDlgItem(v2, 1144); + ShowWindow(v17, 0); + v18 = GetDlgItem(v2, 1145); + ShowWindow(v18, 0); + dword_1002A354 = 0; + } + result = (HWND)Doom_10006A13(v2, (int *)&unk_10022EF0, 1); + } + } + } + } + } + return result; +} */ +// 1002948C: using guessed type int dword_1002948C; +// 1002A354: using guessed type int dword_1002A354; +// 1002A370: using guessed type int dword_1002A370; + +// ref: 0x1000A3E2 +HWND UNKCALL SelConn_1000A3E2(HWND hDlg) { return 0; } +/* { + HWND v1; // esi + int v2; // eax + + v1 = hDlg; + v2 = SelConn_1000A3FF(); + return Sbar_10009A99(v1, 1105, dword_1002A360, v2); +} */ + +// ref: 0x1000A3FF +int SelConn_1000A3FF() { return 0; } +/* { + HWND v0; // eax + LONG v1; // eax + _DWORD *v2; // ecx + _DWORD *v3; // eax + int v5; // edx + + v0 = GetFocus(); + if ( !v0 ) + return 0; + v1 = GetWindowLongA(v0, -21); + if ( !v1 ) + return 0; + v2 = (_DWORD *)dword_1002A35C; + if ( !dword_1002A35C ) + return 0; + v3 = *(_DWORD **)(v1 + 12); + if ( !v3 ) + return 0; + v5 = 0; + do + { + if ( v2 == v3 ) + break; + v2 = (_DWORD *)*v2; + ++v5; + } + while ( v2 ); + return v5; +} */ +// 1002A35C: using guessed type int dword_1002A35C; + +// ref: 0x1000A43A +void UNKCALL SelConn_1000A43A(HWND hDlg) { return; } +/* { + HWND v1; // esi + _DWORD *v2; // eax + + v1 = hDlg; + Title_100100E7(hDlg); + Focus_10007818(v1); + Sbar_10009CD2(v1, 1105); + SelConn_1000A4B9((_DWORD *)dword_1002A35C); + Doom_10006C53(v1, &dword_10022F18); + Doom_10006C53(v1, (int *)&unk_10022F08); + Doom_10006C53(v1, (int *)&unk_10022ED8); + Doom_10006C53(v1, (int *)&unk_10022EE4); + Doom_10006C53(v1, (int *)&unk_10022F00); + Doom_10006C53(v1, (int *)&unk_10022EF0); + v2 = (_DWORD *)GetWindowLongA(v1, -21); + local_10007F72(v2); +} */ +// 10022F18: using guessed type int dword_10022F18; +// 1002A35C: using guessed type int dword_1002A35C; + +// ref: 0x1000A4B9 +int __fastcall SelConn_1000A4B9(_DWORD *a1) { return 0; } +/* { + _DWORD *v1; // esi + int result; // eax + + if ( a1 ) + { + do + { + v1 = (_DWORD *)*a1; + result = SelConn_1000A4CD(a1); + a1 = v1; + } + while ( v1 ); + } + return result; +} */ + +// ref: 0x1000A4CD +int UNKCALL SelConn_1000A4CD(void *arg) { return 0; } +/* { + int result; // eax + + if ( arg ) + result = SMemFree(arg, "C:\\Src\\Diablo\\DiabloUI\\SelConn.cpp", 130, 0); + return result; +} */ +// 10010340: using guessed type int __stdcall SMemFree(_DWORD, _DWORD, _DWORD, _DWORD); + +// ref: 0x1000A4E4 +HWND UNKCALL SelConn_1000A4E4(HWND hWnd, char *a2, int a3) { return 0; } +/* { + HWND v3; // esi + HWND v4; // ST1C_4 + int v5; // eax + int *v6; // edi + HWND result; // eax + HWND v8; // eax + HWND v9; // [esp+0h] [ebp-Ch] + + v3 = hWnd; + SelConn_1000A6EC(hWnd); + Focus_100077E9((int)v3, "ui_art\\focus16.pcx", v9); + Title_1001009E(v3, (int)"ui_art\\smlogo.pcx", v4); + v5 = local_10007F46(); + v6 = (int *)v5; + if ( v5 ) + { + SetWindowLongA(v3, -21, v5); + local_10007944((int)v3, 0, &byte_10029448, -1, 1, (int)"ui_art\\selconn.pcx", v6, v6 + 1, 0); + Fade_100073C5(v3, 1); + } + Doom_100068AB(v3, (int *)&unk_10022EF0, 1); + Doom_100068AB(v3, (int *)&unk_10022F00, 1); + Doom_100068AB(v3, (int *)&unk_10022ED8, 5); + Doom_100068AB(v3, (int *)&unk_10022EE4, 3); + Doom_1000658C(v3, (int *)&unk_10022F08, 4, 0); + Doom_1000658C(v3, &dword_10022F18, 0, 1); + dword_1002A360 = 0; + dword_1002A368 = dword_10029488; + dword_1002A35C = 0; + SNetEnumProviders(0, SelConn_1000A5F3); + SelConn_1000A670(v3, (const char *)dword_1002A35C); + result = Sbar_10009BF1(v3, 1105); + if ( dword_1002A360 <= 6 ) + { + v8 = GetDlgItem(v3, 1105); + result = (HWND)ShowWindow(v8, 0); + } + return result; +} */ +// 10010472: using guessed type int __stdcall SNetEnumProviders(_DWORD, _DWORD); +// 10022F18: using guessed type int dword_10022F18; +// 10029488: using guessed type int dword_10029488; +// 1002A35C: using guessed type int dword_1002A35C; +// 1002A368: using guessed type int dword_1002A368; + +// ref: 0x1000A5F3 +signed int __stdcall SelConn_1000A5F3(int a1, char *a2, char *a3, int a4) { return 0; } +/* { + int v4; // esi + int v6; // edx + _DWORD *v7; // eax + + v4 = SelConn_1000A082(); + if ( !v4 || a1 == 1112425812 && !dword_1002A368 ) + return 0; + *(_DWORD *)v4 = 0; + v6 = *(_DWORD *)(a4 + 4); + *(_DWORD *)(v4 + 8) = a1; + *(_DWORD *)(v4 + 4) = v6 & 2; + *(_DWORD *)(v4 + 12) = *(_DWORD *)(a4 + 16); + strcpy((char *)(v4 + 16), a2); + strcpy((char *)(v4 + 144), a3); + v7 = SelRegn_1000EF56(dword_1002A35C, (_DWORD *)v4); + ++dword_1002A360; + dword_1002A35C = (int)v7; + return 1; +} */ +// 1002A35C: using guessed type int dword_1002A35C; +// 1002A368: using guessed type int dword_1002A368; + +// ref: 0x1000A670 +int __fastcall SelConn_1000A670(HWND a1, const char *a2) { return 0; } +/* { + const char *v2; // edi + int *v3; // ebx + HWND v4; // eax + HWND v5; // esi + int v6; // eax + HWND hDlg; // [esp+8h] [ebp-4h] + + v2 = a2; + hDlg = a1; + v3 = &dword_10022F18; + if ( dword_10022F18 ) + { + do + { + v4 = GetDlgItem(hDlg, *v3); + v5 = v4; + if ( v4 ) + { + if ( v2 ) + { + EnableWindow(v4, 1); + v6 = GetWindowLongA(v5, -21); + if ( v6 ) + { + *(_DWORD *)(v6 + 12) = v2; + local_10007FA4(v6, v2 + 16); + v2 = *(const char **)v2; + } + } + else + { + EnableWindow(v4, 0); + } + } + ++v3; + } + while ( *v3 ); + } + return Doom_1000680A(hDlg, &dword_10022F18, 0, 1); +} */ +// 10022F18: using guessed type int dword_10022F18; + +// ref: 0x1000A6EC +void UNKCALL SelConn_1000A6EC(HWND hDlg) { return; } +/* { + HWND v1; // ebx + int *v2; // edi + HWND v3; // eax + HWND v4; // esi + void *v5; // eax + + v1 = hDlg; + v2 = &dword_10022F18; + if ( dword_10022F18 ) + { + do + { + v3 = GetDlgItem(v1, *v2); + v4 = v3; + if ( v3 ) + { + v5 = (void *)GetWindowLongA(v3, -4); + SetPropA(v4, "UIOLDPROC", v5); + SetWindowLongA(v4, -4, (LONG)SelConn_1000A73E); + } + ++v2; + } + while ( *v2 ); + } +} */ +// 10022F18: using guessed type int dword_10022F18; + +// ref: 0x1000A73E +LRESULT __stdcall SelConn_1000A73E(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) { return 0; } +/* { + LRESULT (__stdcall *v4)(HWND, UINT, WPARAM, LPARAM); // edi + HWND v5; // eax + WPARAM v7; // [esp-8h] [ebp-14h] + + v4 = (LRESULT (__stdcall *)(HWND, UINT, WPARAM, LPARAM))GetPropA(hWnd, "UIOLDPROC"); + switch ( Msg ) + { + case 2u: + RemovePropA(hWnd, "UIOLDPROC"); + if ( !v4 ) + return DefWindowProcA(hWnd, Msg, wParam, lParam); + SetWindowLongA(hWnd, -4, (LONG)v4); + break; + case 0xFu: + local_10007C95(hWnd); + return 0; + case 0x87u: + return 4; + case 0x100u: + if ( wParam > 0x21 ) + { + if ( wParam == 34 ) + { + SelConn_1000A948(hWnd); + } + else if ( wParam > 0x24 ) + { + if ( wParam <= 0x26 ) + { + SelConn_1000AB83(hWnd); + } + else if ( wParam <= 0x28 ) + { + SelConn_1000AAEB(hWnd); + } + } + return 0; + } + if ( wParam == 33 ) + { + SelConn_1000AA3B(hWnd); + return 0; + } + if ( wParam == 9 ) + { + if ( GetKeyState(16) >= 0 ) + SelConn_1000A866(hWnd); + else + SelConn_1000A8D7(hWnd); + return 0; + } + if ( wParam != 13 ) + { + if ( wParam == 27 ) + { + v7 = 2; + goto LABEL_13; + } + if ( wParam != 32 ) + return 0; + } + v7 = 1; +LABEL_13: + v5 = GetParent(hWnd); + SendMessageA(v5, 0x111u, v7, 0); + return 0; + } + if ( v4 ) + return CallWindowProcA(v4, hWnd, Msg, wParam, lParam); + return DefWindowProcA(hWnd, Msg, wParam, lParam); +} */ + +// ref: 0x1000A866 +HWND UNKCALL SelConn_1000A866(HWND hWnd) { return 0; } +/* { + HWND v1; // edi + HWND v2; // ebx + int nIDDlgItem[1066]; // [esp+0h] [ebp-10CCh] + int v5; // [esp+10A8h] [ebp-24h] + int v6; // [esp+10B4h] [ebp-18h] + int v7; // [esp+10B8h] [ebp-14h] + int v8; // [esp+10BCh] [ebp-10h] + int v9; // [esp+10C0h] [ebp-Ch] + int v10; // [esp+10C4h] [ebp-8h] + int v11; // [esp+10C8h] [ebp-4h] + + v1 = hWnd; + v6 = 1070; + v7 = 1071; + v8 = 1072; + v9 = 1073; + v10 = 1074; + v11 = 1069; + v2 = GetParent(hWnd); + do + { + v5 = nIDDlgItem[GetWindowLongA(v1, -12)]; + v1 = GetDlgItem(v2, v5); + } + while ( !IsWindowEnabled(v1) ); + return SetFocus(v1); +} */ +// 1000A866: using guessed type int nIDDlgItem[1066]; + +// ref: 0x1000A8D7 +HWND UNKCALL SelConn_1000A8D7(HWND hWnd) { return 0; } +/* { + HWND v1; // edi + HWND v2; // ebx + int nIDDlgItem[1066]; // [esp+0h] [ebp-10CCh] + int v5; // [esp+10A8h] [ebp-24h] + int v6; // [esp+10B4h] [ebp-18h] + int v7; // [esp+10B8h] [ebp-14h] + int v8; // [esp+10BCh] [ebp-10h] + int v9; // [esp+10C0h] [ebp-Ch] + int v10; // [esp+10C4h] [ebp-8h] + int v11; // [esp+10C8h] [ebp-4h] + + v1 = hWnd; + v6 = 1074; + v7 = 1069; + v8 = 1070; + v9 = 1071; + v10 = 1072; + v11 = 1073; + v2 = GetParent(hWnd); + do + { + v5 = nIDDlgItem[GetWindowLongA(v1, -12)]; + v1 = GetDlgItem(v2, v5); + } + while ( !IsWindowEnabled(v1) ); + return SetFocus(v1); +} */ +// 1000A8D7: using guessed type int nIDDlgItem[1066]; + +// ref: 0x1000A948 +HWND UNKCALL SelConn_1000A948(HWND hWnd) { return 0; } +/* { + HWND v1; // ebp + HWND result; // eax + HWND v3; // esi + HWND v4; // ebx + HWND v5; // eax + _DWORD *v6; // eax + int v7; // eax + const char *v8; // ebx + int v9; // eax + + v1 = hWnd; + result = GetParent(hWnd); + v3 = result; + if ( result ) + { + result = GetDlgItem(result, 1069); + v4 = result; + if ( result ) + { + v5 = GetDlgItem(v3, 1074); + result = (HWND)GetWindowLongA(v5, -21); + if ( result ) + { + v6 = (_DWORD *)*((_DWORD *)result + 3); + if ( v6 && *v6 ) + { + v7 = SelConn_1000A9F3(v4) + 6; + if ( v7 > dword_1002A360 - 6 ) + v7 = dword_1002A360 - 6; + result = (HWND)SelConn_1000AA28(v7); + v8 = (const char *)result; + if ( result ) + { + TitleSnd_10010315(); + SelConn_1000A670(v3, v8); + v9 = GetWindowLongA(v1, -12); + SelConn_1000A226(v3, v9); + result = SelConn_1000A3E2(v3); + } + } + else + { + result = SelConn_1000A8D7(v4); + } + } + } + } + return result; +} */ + +// ref: 0x1000A9F3 +int UNKCALL SelConn_1000A9F3(HWND hWnd) { return 0; } +/* { + LONG v1; // eax + _DWORD *v2; // ecx + _DWORD *v3; // eax + int v5; // edx + + if ( !hWnd ) + return 0; + v1 = GetWindowLongA(hWnd, -21); + if ( !v1 ) + return 0; + v2 = (_DWORD *)dword_1002A35C; + if ( !dword_1002A35C ) + return 0; + v3 = *(_DWORD **)(v1 + 12); + if ( !v3 ) + return 0; + v5 = 0; + do + { + if ( v2 == v3 ) + break; + v2 = (_DWORD *)*v2; + ++v5; + } + while ( v2 ); + return v5; +} */ +// 1002A35C: using guessed type int dword_1002A35C; + +// ref: 0x1000AA28 +_DWORD *__fastcall SelConn_1000AA28(int a1) { return 0; } +/* { + _DWORD *result; // eax + + result = (_DWORD *)dword_1002A35C; + while ( result && a1 ) + { + result = (_DWORD *)*result; + --a1; + } + return result; +} */ +// 1002A35C: using guessed type int dword_1002A35C; + +// ref: 0x1000AA3B +HWND UNKCALL SelConn_1000AA3B(HWND hWnd) { return 0; } +/* { + HWND result; // eax + HWND v2; // esi + HWND v3; // edi + HWND v4; // eax + int v5; // eax + const char *v6; // edi + int v7; // eax + HWND hWnda; // [esp+10h] [ebp-4h] + + hWnda = hWnd; + result = GetParent(hWnd); + v2 = result; + if ( result ) + { + result = GetDlgItem(result, 1069); + v3 = result; + if ( result ) + { + result = (HWND)GetWindowLongA(result, -21); + if ( result ) + { + result = (HWND)*((_DWORD *)result + 3); + if ( result ) + { + if ( result == (HWND)dword_1002A35C ) + { + v4 = GetDlgItem(v2, 1074); + result = SelConn_1000A866(v4); + } + else + { + v5 = SelConn_1000A9F3(v3) - 6; + if ( v5 < 0 ) + v5 = 0; + result = (HWND)SelConn_1000AA28(v5); + v6 = (const char *)result; + if ( result ) + { + TitleSnd_10010315(); + SelConn_1000A670(v2, v6); + v7 = GetWindowLongA(hWnda, -12); + SelConn_1000A226(v2, v7); + result = SelConn_1000A3E2(v2); + } + } + } + } + } + } + return result; +} */ +// 1002A35C: using guessed type int dword_1002A35C; + +// ref: 0x1000AAEB +HWND UNKCALL SelConn_1000AAEB(HWND hWnd) { return 0; } +/* { + HWND v1; // edi + HWND result; // eax + HWND v3; // eax + const char *v4; // ebp + HWND v5; // eax + int v6; // ebx + HWND v7; // eax + HWND v8; // eax + + v1 = hWnd; + result = (HWND)GetWindowLongA(hWnd, -21); + if ( result ) + { + result = (HWND)*((_DWORD *)result + 3); + if ( result ) + { + if ( *(_DWORD *)result ) + { + if ( GetWindowLongA(v1, -12) >= 1074 ) + { + v3 = GetParent(v1); + result = GetDlgItem(v3, 1070); + if ( result ) + { + result = (HWND)GetWindowLongA(result, -21); + if ( result ) + { + v4 = (const char *)*((_DWORD *)result + 3); + if ( v4 ) + { + TitleSnd_10010315(); + v5 = GetParent(v1); + SelConn_1000A670(v5, v4); + v6 = GetWindowLongA(v1, -12); + v7 = GetParent(v1); + SelConn_1000A226(v7, v6); + v8 = GetParent(v1); + result = SelConn_1000A3E2(v8); + } + } + } + } + else + { + result = SelConn_1000A866(v1); + } + } + } + } + return result; +} */ + +// ref: 0x1000AB83 +HWND UNKCALL SelConn_1000AB83(HWND hWnd) { return 0; } +/* { + HWND v1; // edi + HWND result; // eax + const char *v3; // ebx + HWND v4; // eax + int v5; // ebx + HWND v6; // eax + HWND v7; // eax + + v1 = hWnd; + if ( GetWindowLongA(hWnd, -12) > 1069 ) + return SelConn_1000A8D7(v1); + result = (HWND)GetWindowLongA(v1, -21); + if ( result ) + { + result = (HWND)*((_DWORD *)result + 3); + if ( result ) + { + v3 = (const char *)dword_1002A35C; + if ( result != (HWND)dword_1002A35C ) + { + while ( v3 && *(HWND *)v3 != result ) + v3 = *(const char **)v3; + TitleSnd_10010315(); + v4 = GetParent(v1); + SelConn_1000A670(v4, v3); + v5 = GetWindowLongA(v1, -12); + v6 = GetParent(v1); + SelConn_1000A226(v6, v5); + v7 = GetParent(v1); + result = SelConn_1000A3E2(v7); + } + } + } + return result; +} */ +// 1002A35C: using guessed type int dword_1002A35C; + +// ref: 0x1000AC07 +int __fastcall SelConn_1000AC07(int a1, int a2) { return 0; } +/* { + int v2; // esi + int v3; // edi + + v2 = a2; + v3 = a1; + if ( a2 == 2 ) + TitleSnd_1001031F(); + Fade_100073B4(); + Fade_100072BE(10); + return SDlgEndDialog(v3, v2); +} */ +// 10010376: using guessed type int __stdcall SDlgEndDialog(_DWORD, _DWORD); + +// ref: 0x1000AC30 +int UNKCALL SelConn_1000AC30(HWND arg) { return 0; } +/* { + int v1; // esi + int v2; // edx + int result; // eax + int v4; // eax + int v5; // ecx + UINT v6; // [esp-4h] [ebp-8h] + + v1 = (int)arg; + if ( SelConn_1000AC9E(arg) ) + { + v2 = 1; + return SelConn_1000AC07(v1, v2); + } + if ( SErrGetLastError() == -2062548873 ) + { + dword_1002A374 = 1; + v2 = 0; + return SelConn_1000AC07(v1, v2); + } + result = SelGame_1000B67E(); + switch ( result ) + { + case 1230002254: + goto LABEL_17; + case 1297040461: + v4 = SErrGetLastError(); + v5 = v1; + if ( v4 == 1222 ) + v6 = 46; + else + v6 = 53; + goto LABEL_14; + case 1396916812: +LABEL_17: + v6 = 44; + v5 = v1; +LABEL_14: + result = SelConn_1000AE19(v5, v6); + break; + } + return result; +} */ +// 10010406: using guessed type _DWORD __stdcall SErrGetLastError(); +// 1002A374: using guessed type int dword_1002A374; + +// ref: 0x1000AC9E +int UNKCALL SelConn_1000AC9E(HWND hWnd) { return 0; } +/* { + HWND v1; // ebx + HWND v2; // eax + LONG v3; // eax + int v4; // esi + char *v6; // ST10_4 + int v7; // ST08_4 + int v8; // eax + int v9; // esi + char *v10; // ST14_4 + int v11; // ST0C_4 + void *v12; // eax + char v13; // [esp+8h] [ebp-8Ch] + HWND v14; // [esp+10h] [ebp-84h] + char v15; // [esp+58h] [ebp-3Ch] + + v1 = hWnd; + TitleSnd_1001031F(); + SelGame_1000B677(0); + SelGame_1000B66A(0); + v2 = GetFocus(); + v3 = GetWindowLongA(v2, -21); + if ( !v3 ) + return 0; + v4 = *(_DWORD *)(v3 + 12); + if ( !v4 ) + return 0; + SelGame_1000B677(*(void **)(v4 + 8)); + SelGame_1000B66A(*(void **)(v4 + 4)); + if ( SelGame_1000B67E() == 1112425812 ) + { + BNetGW_10002A07(&unk_10029480); + BNetGW_100028C2(&unk_10029480); + } + if ( dword_1002A364 ) + qmemcpy(&v13, (const void *)dword_1002A364, 0x50u); + v14 = v1; + if ( dword_1002A370 ) + qmemcpy(&v15, (const void *)dword_1002A370, 0x3Cu); + SelConn_1000ADA8(v1); + v6 = dword_1002A358; + v7 = dword_1002A34C; + v8 = SelGame_1000B67E(); + v9 = SNetInitializeProvider(v8, &v15, v7, &v13, v6); + if ( v9 ) + { + v10 = dword_1002A358; + v11 = dword_1002A34C; + v12 = (void *)SelGame_1000B67E(); + v9 = SelModem_1000E435(v12, (int)&v15, v11, &v13, v10); + } + else + { + SNetDestroy(); + } + if ( !v9 ) + SelConn_1000ADD0(v1); + return v9; +} */ +// 10010478: using guessed type _DWORD __stdcall SNetDestroy(); +// 1001047E: using guessed type int __stdcall SNetInitializeProvider(_DWORD, _DWORD, _DWORD, _DWORD, _DWORD); +// 1002A364: using guessed type int dword_1002A364; +// 1002A370: using guessed type int dword_1002A370; + +// ref: 0x1000ADA8 +int UNKCALL SelConn_1000ADA8(HWND hWnd) { return 0; } +/* { + HWND v1; // esi + + v1 = hWnd; + Fade_100072BE(10); + local_1000811B(); + ShowWindow(v1, 0); + Title_100100E7(v1); + return Focus_10007818(v1); +} */ + +// ref: 0x1000ADD0 +BOOL UNKCALL SelConn_1000ADD0(HWND hWnd) { return 0; } +/* { + HWND v1; // esi + HWND v2; // ST10_4 + HWND v4; // [esp+0h] [ebp-4h] + + v1 = hWnd; + Focus_100077E9((int)hWnd, "ui_art\\focus16.pcx", v4); + Title_1001009E(v1, (int)"ui_art\\smlogo.pcx", v2); + local_100080F1(); + Fade_100073C5(v1, 0); + PostMessageA(v1, 0x7E8u, 0, 0); + ShowWindow(v1, 5); + return UpdateWindow(v1); +} */ + +// ref: 0x1000AE19 +int __fastcall SelConn_1000AE19(int a1, UINT a2) { return 0; } +/* { + UINT v2; // esi + int v3; // edi + int result; // eax + CHAR Buffer; // [esp+8h] [ebp-80h] + + v2 = a2; + v3 = a1; + result = SErrGetLastError(); + if ( result != 1223 ) + { + LoadStringA(hInstance, v2, &Buffer, 127); + result = SelYesNo_1000FD39(v3, &Buffer, 0, 0); + } + return result; +} */ +// 10010406: using guessed type _DWORD __stdcall SErrGetLastError(); + +// ref: 0x1000AE59 +HWND __fastcall SelConn_1000AE59(HWND hWnd, int a2, int a3) { return 0; } +/* { + int v3; // ebp + int v4; // ebx + int v5; // ST0C_4 + HWND v6; // esi + int v7; // ST08_4 + HWND v8; // eax + HWND result; // eax + HWND v10; // eax + HWND v11; // eax + HWND v12; // eax + HWND v13; // eax + int v14; // eax + int v15; // eax + int v16; // eax + HWND v17; // eax + HWND v18; // eax + HWND v19; // eax + HWND v20; // eax + + v3 = a3; + v4 = a2; + v5 = a3; + v6 = hWnd; + v7 = a2; + v8 = GetDlgItem(hWnd, 1056); + if ( local_10007C3B(v6, v8, v7, v5) ) + return (HWND)SelConn_1000AC30(v6); + v10 = GetDlgItem(v6, 1054); + if ( local_10007C3B(v6, v10, v4, v3) ) + return (HWND)SelConn_1000AC07((int)v6, 2); + if ( dword_1002A354 && (v11 = GetDlgItem(v6, 1145), local_10007C3B(v6, v11, v4, v3)) ) + { + SelConn_1000ADA8(v6); + TitleSnd_1001031F(); + UiSelectRegion(&a3); + result = (HWND)SelConn_1000ADD0(v6); + } + else + { + v12 = GetDlgItem(v6, 1105); + result = (HWND)local_10007C3B(v6, v12, v4, v3); + if ( result ) + { + v13 = GetDlgItem(v6, 1105); + v14 = Sbar_100099DC(v13, v4, v3) - 1; + if ( v14 ) + { + v15 = v14 - 1; + if ( v15 ) + { + v16 = v15 - 1; + if ( v16 ) + { + result = (HWND)(v16 - 1); + if ( !result ) + { + v17 = GetFocus(); + result = SelConn_1000A948(v17); + } + } + else + { + v18 = GetFocus(); + result = SelConn_1000AA3B(v18); + } + } + else + { + v19 = GetFocus(); + result = SelConn_1000AAEB(v19); + } + } + else + { + v20 = GetFocus(); + result = SelConn_1000AB83(v20); + } + } + } + return result; +} */ +// 1002A354: using guessed type int dword_1002A354; + +// ref: 0x1000AF69 +int __stdcall UiSelectProvider(int a1, _SNETPROGRAMDATA *client_info, _SNETPLAYERDATA *user_info, _SNETUIDATA *ui_info, _SNETVERSIONDATA *file_info, DWORD *type) { return 0; } +/* { + int v6; // eax + int v7; // ebx + + dword_1002A374 = 0; + dword_1002A36C = a1; + dword_1002A370 = a2; + dword_1002A34C = a3; + dword_1002A364 = a4; + dword_1002A358 = a5; + artfont_10001159(); + v6 = SDrawGetFrameWindow(); + v7 = SDlgDialogBoxParam(hInstance, "SELCONNECT_DIALOG", v6, SelConn_1000A0A6, 0); + if ( a6 ) + *a6 = SelGame_1000B67E(); + if ( dword_1002A374 ) + { + artfont_100010C8(); + local_100078B6(); + SErrSetLastError(-2062548873); + } + else + { + if ( v7 == 1 ) + { + artfont_100010C8(); + local_100078B6(); + return 1; + } + SErrSetLastError(1223); + } + return 0; +} */ +// 10010370: using guessed type int __stdcall SDlgDialogBoxParam(_DWORD, _DWORD, _DWORD, _DWORD, _DWORD); +// 10010382: using guessed type _DWORD __stdcall SDrawGetFrameWindow(); +// 1001041E: using guessed type int __stdcall SErrSetLastError(_DWORD); +// 1002A364: using guessed type int dword_1002A364; +// 1002A36C: using guessed type int dword_1002A36C; +// 1002A370: using guessed type int dword_1002A370; +// 1002A374: using guessed type int dword_1002A374; diff --git a/2020_03_31/DiabloUI/seldial.cpp b/2020_03_31/DiabloUI/seldial.cpp new file mode 100644 index 00000000..c396dd5f --- /dev/null +++ b/2020_03_31/DiabloUI/seldial.cpp @@ -0,0 +1,426 @@ +// ref: 0x1000B011 +int UNKCALL SelDial_1000B011(char *arg) { return 0; } +/* { + signed int v1; // edi + int i; // edi + char v4; // [esp+8h] [ebp-24h] + char v5; // [esp+27h] [ebp-5h] + char *v6; // [esp+28h] [ebp-4h] + + v6 = arg; + v1 = 0; + do + { + if ( SRegLoadString("Diablo\\Phone Book", off_10022F8C[v1], 1u, &v4, 0x20u) ) + { + v5 = 0; + if ( !strcmp(&v4, v6) ) + break; + } + ++v1; + } + while ( v1 < 4 ); + if ( v1 == 4 ) + v1 = 3; + for ( i = v1 - 1; i >= 0; --i ) + { + v4 = 0; + if ( SRegLoadString("Diablo\\Phone Book", off_10022F8C[i], 1u, &v4, 0x20u) ) + { + v5 = 0; + if ( strlen(&v4) ) + SRegSaveString("Diablo\\Phone Book", off_10022F90[i], 1u, &v4); + } + } + return SRegSaveString("Diablo\\Phone Book", off_10022F8C[0], 1u, v6); +} */ +// 10010484: using guessed type int __stdcall SRegSaveString(const char *, const char *, unsigned int, const char *); +// 1001048A: using guessed type int __stdcall SRegLoadString(const char *, const char *, unsigned int, char *, unsigned int); +// 10022F8C: using guessed type char *off_10022F8C[4]; +// 10022F90: using guessed type char *off_10022F90[3]; + +// ref: 0x1000B0C4 +signed int SelDial_1000B0C4() { return 0; } +/* { + signed int result; // eax + + result = 2139095040; + dword_1002A37C = 2139095040; + return result; +} */ +// 1002A37C: using guessed type int dword_1002A37C; + +// ref: 0x1000B0CF +int __stdcall SelDial_1000B0CF(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) { return 0; } +/* { + HWND v4; // eax + int v6; // edx + HWND v7; // eax + int savedregs; // [esp+Ch] [ebp+0h] + + if ( Msg == 2 ) + { + SelDial_1000B29A(hWnd); + return SDlgDefDialogProc(hWnd, Msg, wParam, lParam); + } + if ( Msg > 0x103 ) + { + if ( Msg <= 0x105 ) + { + v7 = (HWND)SDrawGetFrameWindow(); + SendMessageA(v7, Msg, wParam, lParam); + return SDlgDefDialogProc(hWnd, Msg, wParam, lParam); + } + if ( Msg == 272 ) + { + dword_1002A378 = (char *)lParam; + SelDial_1000B483(hWnd, (int)&savedregs); + return 0; + } + if ( Msg != 273 ) + { + if ( Msg != 275 ) + { + if ( Msg == 513 ) + SelDial_1000B614(hWnd, (unsigned short)lParam, (unsigned int)lParam >> 16); + return SDlgDefDialogProc(hWnd, Msg, wParam, lParam); + } + if ( wParam == 1 ) + { + v4 = GetFocus(); + Focus_100075DC(hWnd, v4); + } + else if ( wParam == 2 ) + { + SelDial_1000B354(hWnd); + } + return 0; + } + if ( HIWORD(wParam) == 7 ) + { + Focus_100075B7(hWnd, (HWND)lParam); + } + else if ( HIWORD(wParam) == 6 ) + { + Focus_10007458((void *)lParam); + Focus_100075DC(hWnd, (HWND)lParam); + SelDial_1000B1FB(hWnd, (unsigned short)wParam); + } + else + { + v6 = 1; + if ( wParam != 327681 ) + { + if ( (_WORD)wParam != 2 ) + return SDlgDefDialogProc(hWnd, Msg, wParam, lParam); + v6 = 2; + } + SelDial_1000B2D8((int)hWnd, v6); + } + } + return SDlgDefDialogProc(hWnd, Msg, wParam, lParam); +} */ +// 1001037C: using guessed type int __stdcall SDlgDefDialogProc(_DWORD, _DWORD, _DWORD, _DWORD); +// 10010382: using guessed type _DWORD __stdcall SDrawGetFrameWindow(); + +// ref: 0x1000B1FB +HWND __fastcall SelDial_1000B1FB(HWND hWnd, int a2) { return 0; } +/* { + int v2; // edi + HWND v3; // ebx + HWND v4; // eax + CHAR v6; // [esp+Ch] [ebp-140h] + CHAR Buffer; // [esp+10Ch] [ebp-40h] + + v2 = a2; + v3 = hWnd; + LoadStringA(hInstance, 0x39u, &Buffer, 63); + if ( v2 == 1117 ) + { + if ( Modem_1000855D() ) + LoadStringA(hInstance, 0x43u, &v6, 255); + else + LoadStringA(hInstance, 0x36u, &v6, 255); + } + else if ( v2 == 1118 ) + { + if ( Modem_1000855D() ) + LoadStringA(hInstance, 0x44u, &v6, 255); + else + LoadStringA(hInstance, 0x37u, &v6, 255); + } + else + { + LoadStringA(hInstance, 0x38u, &v6, 255); + } + v4 = GetParent(v3); + return Modem_10008563(v4, &Buffer, (int)&v6); +} */ + +// ref: 0x1000B29A +HWND UNKCALL SelDial_1000B29A(HWND hDlg) { return 0; } +/* { + HWND v1; // esi + HWND v2; // eax + + v1 = hDlg; + Doom_10006C53(hDlg, (int *)&unk_10022FB0); + Doom_10006C53(v1, (int *)&unk_10022FA4); + Doom_10006C53(v1, (int *)&unk_10022F9C); + Focus_100076C3(); + v2 = GetParent(v1); + return Modem_10008563(v2, 0, 0); +} */ + +// ref: 0x1000B2D8 +int __fastcall SelDial_1000B2D8(int a1, int a2) { return 0; } +/* { + int v2; // esi + int v3; // edi + HWND v4; // eax + LONG v5; // eax + + v2 = a2; + v3 = a1; + if ( a2 == 1 || a2 == 2 ) + TitleSnd_1001031F(); + SDlgKillTimer(v3, 1); + SDlgKillTimer(v3, 2); + if ( v2 != 1 ) + return SDlgEndDialog(v3, v2); + v4 = GetFocus(); + v5 = GetWindowLongA(v4, -12); + if ( v5 == 1117 ) + return SDlgEndDialog(v3, 3); + if ( v5 == 1118 ) + return SDlgEndDialog(v3, 5); + if ( dword_1002A378 ) + strcpy(dword_1002A378, &byte_1002A380[32 * (v5 - 1119)]); + return SDlgEndDialog(v3, 4); +} */ +// 10010376: using guessed type int __stdcall SDlgEndDialog(_DWORD, _DWORD); +// 10010418: using guessed type int __stdcall SDlgKillTimer(_DWORD, _DWORD); + +// ref: 0x1000B354 +HWND UNKCALL SelDial_1000B354(HWND hDlg) { return 0; } +/* { + HWND v1; // edi + HWND result; // eax + HWND v3; // esi + HWND v4; // eax + + v1 = hDlg; + result = GetDlgItem(hDlg, 1118); + v3 = result; + if ( result ) + { + if ( Modem_10008606() ) + { + SelDial_1000B3D8(v1); + EnableWindow(v3, 1); + result = (HWND)ShowWindow(v3, 1); + } + else if ( SErrGetLastError() == 1222 ) + { + result = (HWND)SelDial_1000B2D8((int)v1, 1222); + } + else + { + if ( GetFocus() == v3 ) + { + v4 = GetDlgItem(v1, 1117); + SetFocus(v4); + } + SelDial_1000B44C(v1); + EnableWindow(v3, 0); + result = (HWND)ShowWindow(v3, 0); + } + } + return result; +} */ +// 10010406: using guessed type _DWORD __stdcall SErrGetLastError(); + +// ref: 0x1000B3D8 +HWND UNKCALL SelDial_1000B3D8(HWND hDlg) { return 0; } +/* { + HWND v1; // esi + HWND result; // eax + HWND v3; // edi + char *v4; // eax + int v5; // ebx + int v6; // eax + CHAR Buffer; // [esp+8h] [ebp-40h] + + v1 = hDlg; + result = GetDlgItem(hDlg, 1118); + v3 = result; + if ( result ) + { + v4 = Modem_1000863D(); + v5 = Modem_1000865F(v4); + if ( v5 <= Modem_10008659() ) + LoadStringA(hInstance, 0x4Au, &Buffer, 63); + else + LoadStringA(hInstance, 0x4Bu, &Buffer, 63); + v6 = GetWindowLongA(v3, -21); + local_10007FA4(v6, &Buffer); + result = (HWND)Doom_1000680A(v1, (int *)&unk_10022FB0, 0, 1); + } + return result; +} */ + +// ref: 0x1000B44C +HWND UNKCALL SelDial_1000B44C(HWND hDlg) { return 0; } +/* { + HWND v1; // esi + HWND result; // eax + int v3; // eax + + v1 = hDlg; + result = GetDlgItem(hDlg, 1118); + if ( result ) + { + v3 = GetWindowLongA(result, -21); + local_10007FA4(v3, 0); + result = (HWND)Doom_1000680A(v1, (int *)&unk_10022FB0, 0, 1); + } + return result; +} */ + +// ref: 0x1000B483 +HWND USERCALL SelDial_1000B483(HWND hWnd, int a2) { return 0; } +/* { + HWND v2; // esi + HWND v3; // eax + LONG v4; // eax + HWND result; // eax + char *v6; // eax + int v7; // ebx + HWND v8; // eax + HWND v9; // edi + int v10; // esi + const char *v11; // edx + int v12; // [esp-64h] [ebp-6Ch] + int v13; // [esp-24h] [ebp-2Ch] + HWND v14; // [esp-4h] [ebp-Ch] + const char *v15; // [esp+0h] [ebp-8h] + int v16; // [esp+4h] [ebp-4h] + + v2 = hWnd; + v3 = GetParent(hWnd); + v4 = GetWindowLongA(v3, -21); + SetWindowLongA(v2, -21, v4); + Focus_10007719("ui_art\\focus16.pcx"); + SDlgSetTimer(v2, 1, 55, 0); + local_10007CB5(v2, (int *)&unk_10022FB0); + Doom_100068AB(v2, (int *)&unk_10022F9C, 5); + Doom_1000658C(v2, (int *)&unk_10022FA4, 4, 0); + Doom_1000658C(v2, (int *)&unk_10022FB0, 0, 1); + if ( Modem_1000855D() ) + { + SDlgSetTimer(v2, 2, 2000, 0); + result = SelDial_1000B354(v2); + } + else + { + v16 = a2; + v14 = v2; + v6 = byte_1002A380; + do + { + *v6 = 0; + v6 += 32; + } + while ( (signed int)v6 < (signed int)&dword_1002A400 ); + SelDial_1000B5D9(); + LoadStringA(hInstance, 0x34u, (LPSTR)&v13, 31); + v7 = 0; + v15 = byte_1002A380; + do + { + v8 = GetDlgItem(v14, v7 + 1119); + v9 = v8; + if ( v8 ) + { + v10 = GetWindowLongA(v8, -21); + if ( v10 ) + { + if ( strlen(v15) ) + { + wsprintfA((LPSTR)&v12, (LPCSTR)&v13, v15); + v11 = (const char *)&v12; + } + else + { + EnableWindow(v9, 0); + v11 = 0; + } + local_10007FA4(v10, v11); + } + } + v15 += 32; + ++v7; + } + while ( (signed int)v15 < (signed int)&dword_1002A400 ); + result = (HWND)Doom_1000680A(v14, (int *)&unk_10022FB0, 0, 1); + } + return result; +} */ +// 1000B483: could not find valid save-restore pair for ebp +// 10010412: using guessed type int __stdcall SDlgSetTimer(_DWORD, _DWORD, _DWORD, _DWORD); +// 1002A400: using guessed type int dword_1002A400; + +// ref: 0x1000B5D9 +int SelDial_1000B5D9() { return 0; } +/* { + char *v0; // esi + const char **v1; // edi + int result; // eax + + v0 = byte_1002A380; + v1 = (const char **)off_10022F8C; + do + { + result = SRegLoadString("Diablo\\Phone Book", *v1, 1u, v0, 0x20u); + if ( result ) + v0[31] = 0; + else + *v0 = 0; + ++v1; + v0 += 32; + } + while ( (signed int)v1 < (signed int)&unk_10022F9C ); + return result; +} */ +// 1001048A: using guessed type int __stdcall SRegLoadString(const char *, const char *, unsigned int, char *, unsigned int); +// 10022F8C: using guessed type char *off_10022F8C[4]; + +// ref: 0x1000B614 +int __fastcall SelDial_1000B614(HWND hWnd, int a2, int a3) { return 0; } +/* { + int v3; // ebx + HWND v4; // esi + int v5; // ST08_4 + HWND v6; // eax + int v7; // edx + HWND v8; // eax + int result; // eax + + v3 = a2; + v4 = hWnd; + v5 = a2; + v6 = GetDlgItem(hWnd, 1056); + if ( local_10007C3B(v4, v6, v5, a3) ) + { + v7 = 1; + } + else + { + v8 = GetDlgItem(v4, 1054); + result = local_10007C3B(v4, v8, v3, a3); + if ( !result ) + return result; + v7 = 2; + } + return SelDial_1000B2D8((int)v4, v7); +} */ diff --git a/2020_03_31/DiabloUI/selgame.cpp b/2020_03_31/DiabloUI/selgame.cpp new file mode 100644 index 00000000..35dcb087 --- /dev/null +++ b/2020_03_31/DiabloUI/selgame.cpp @@ -0,0 +1,85 @@ +// ref: 0x1000B66A +void UNKCALL SelGame_1000B66A(void *arg) { return; } +/* { + dword_1002A408 = (int)arg; +} */ +// 1002A408: using guessed type int dword_1002A408; + +// ref: 0x1000B671 +int SelGame_1000B671() { return 0; } +/* { + return dword_1002A408; +} */ +// 1002A408: using guessed type int dword_1002A408; + +// ref: 0x1000B677 +void UNKCALL SelGame_1000B677(void *arg) { return; } +/* { + dword_1002A404 = (int)arg; +} */ +// 1002A404: using guessed type int dword_1002A404; + +// ref: 0x1000B67E +int SelGame_1000B67E() { return 0; } +/* { + return dword_1002A404; +} */ +// 1002A404: using guessed type int dword_1002A404; + +// ref: 0x1000B684 +int __stdcall UiSelectGame(int a1, _SNETPROGRAMDATA *client_info, _SNETPLAYERDATA *user_info, _SNETUIDATA *ui_info, _SNETVERSIONDATA *file_info, DWORD *a6) { return 0; } +/* { + int v6; // eax + CHAR v8; // [esp+4h] [ebp-110h] + char v9; // [esp+5h] [ebp-10Fh] + short v10; // [esp+81h] [ebp-93h] + char v11; // [esp+83h] [ebp-91h] + CHAR v12; // [esp+84h] [ebp-90h] + char v13; // [esp+85h] [ebp-8Fh] + short v14; // [esp+101h] [ebp-13h] + char v15; // [esp+103h] [ebp-11h] + int v16; // [esp+104h] [ebp-10h] + CHAR *v17; // [esp+108h] [ebp-Ch] + CHAR *v18; // [esp+10Ch] [ebp-8h] + + v12 = byte_10029448; + memset(&v13, 0, 0x7Cu); + v14 = 0; + v15 = 0; + v8 = byte_10029448; + memset(&v9, 0, 0x7Cu); + v10 = 0; + v11 = 0; + Connect_10004028((int)&v12, 128, (int)&v8, 128); + memset(&v16, 0, 0x10u); + if ( a3 ) + memcpy(&v16, a3, 0x10u); + v16 = 16; + v17 = &v12; + v18 = &v8; + if ( SelGame_1000B671() ) + return SelIPX_1000C634(a1, a2, (int)&v16, (_DWORD *)a4, a5, a6); + v6 = SelGame_1000B67E(); + switch ( v6 ) + { + case 1230002254: + return SelIPX_1000C634(a1, a2, (int)&v16, (_DWORD *)a4, a5, a6); + case 1297040461: + return Modem_10008680(a1, a2, (int)&v16, (_DWORD *)a4, a5, a6); + case 1396916812: + return DirLink_10005D05(a1, a2, (int)&v16, (_DWORD *)a4, a5, a6); + } + return SNetSelectGame(a1, a2, &v16, a4, a5, a6); +} */ +// 10010490: using guessed type int __stdcall SNetSelectGame(_DWORD, _DWORD, _DWORD, _DWORD, _DWORD, _DWORD); + +// ref: 0x1000B795 +signed int SelGame_1000B795() { return 0; } +/* { + signed int result; // eax + + result = 2139095040; + dword_1002A400 = 2139095040; + return result; +} */ +// 1002A400: using guessed type int dword_1002A400; diff --git a/2020_03_31/DiabloUI/selhero.cpp b/2020_03_31/DiabloUI/selhero.cpp new file mode 100644 index 00000000..4830f33d --- /dev/null +++ b/2020_03_31/DiabloUI/selhero.cpp @@ -0,0 +1,790 @@ +// ref: 0x1000B7A0 +_uiheroinfo *__cdecl SelHero_GetCurrentHeroInfo() +{ + return sgpHeroInfo; +} + +// ref: 0x1000B7A6 +int __cdecl SelHero_GetNumHeroesLeft() +{ + return selhero_numheroesleft; +} +// 1002A428: using guessed type int selhero_numheroesleft; + +// ref: 0x1000B7AC +void __fastcall SelHero_SetHeroDifficulty(int diff) +{ + selhero_difficulty = diff; +} +// 1002A420: using guessed type int selhero_difficulty; + +// ref: 0x1000B7B3 +char *__cdecl SelHero_GetHeroNameStr() +{ + return selhero_heronamestr; +} + +// ref: 0x1000B7B9 +_uiheroinfo *__cdecl SelHero_AllocHeroInfo() +{ + return (_uiheroinfo *)SMemAlloc(0x2Cu, "C:\\Src\\Diablo\\DiabloUI\\SelHero.cpp", 123, 0); +} + +// ref: 0x1000B7CA +int __cdecl SelHero_GetHeroIsGood() +{ + return selhero_is_good; +} + +// ref: 0x1000B7D0 +int __fastcall SelHero_SetClassStats(int heroclass, _uidefaultstats *pStats) +{ + return selhero_fnstats(heroclass, pStats); +} + +// ref: 0x1000B7DE +void __cdecl SelHero_cpp_init() +{ + SelHero_cpp_float = SelHero_cpp_float_value; +} +// 1001F460: using guessed type int SelHero_cpp_float_value; +// 1002A414: using guessed type int SelHero_cpp_float; + +// ref: 0x1000B899 +void __fastcall SelHero_SetStaticBMP(HWND hWnd, int adjust_size) +{ + HWND v3; // esi + struct tagRECT Rect; // [esp+8h] [ebp-10h] + + v3 = GetDlgItem(hWnd, 1040); + InvalidateRect(v3, 0, 0); + GetClientRect(v3, &Rect); + local_AdjustRectSize(&Rect, 0, adjust_size * Rect.bottom); + SDlgSetBitmapI(v3, 0, "Static", -1, 1, selhero_buffer, (int)&Rect, selhero_sizedata[0], selhero_sizedata[1], -1); +} + +// ref: 0x1000B905 +void __fastcall SelHero_PrintHeroInfo(HWND hWnd, _uiheroinfo *pInfo) +{ + HWND v3; // eax + int v4; // eax + HWND v5; // eax + int v6; // eax + HWND v7; // eax + int v8; // eax + HWND v9; // eax + int v10; // eax + HWND v11; // eax + int v12; // eax + HWND v15; // ebp + int v16; // eax + HWND v17; // ST1C_4 + int v18; // eax + HWND v19; // ST1C_4 + int v20; // eax + HWND v21; // ST1C_4 + int v22; // eax + HWND v23; // ST1C_4 + int v24; // eax + + if ( pInfo->level ) + { + selhero_hero_hassaved = pInfo->hassaved; + strcpy(selhero_heronamestr, pInfo->name); + v15 = GetDlgItem(hWnd, 1014); + wsprintfA(selhero_herolevel, "%d", pInfo->level); + v16 = GetWindowLongA(v15, -21); + local_SetWndLongStr(v16, selhero_herolevel); + v17 = GetDlgItem(hWnd, 1018); + wsprintfA(selhero_herostr, "%d", pInfo->strength); + v18 = GetWindowLongA(v17, -21); + local_SetWndLongStr(v18, selhero_herostr); + v19 = GetDlgItem(hWnd, 1017); + wsprintfA(selhero_heromag, "%d", pInfo->magic); + v20 = GetWindowLongA(v19, -21); + local_SetWndLongStr(v20, selhero_heromag); + v21 = GetDlgItem(hWnd, 1016); + wsprintfA(selhero_herodex, "%d", pInfo->dexterity); + v22 = GetWindowLongA(v21, -21); + local_SetWndLongStr(v22, selhero_herodex); + v23 = GetDlgItem(hWnd, 1015); + wsprintfA(selhero_herovit, "%d", pInfo->vitality); + v24 = GetWindowLongA(v23, -21); + local_SetWndLongStr(v24, selhero_herovit); + SelHero_SetStaticBMP(hWnd, pInfo->heroclass); + Doom_ParseWndProc4(hWnd, selhero_msgtbl_info, 1); + } + else + { + selhero_hero_hassaved = 0; + selhero_heronamestr[0] = 0; + v3 = GetDlgItem(hWnd, 1014); + v4 = GetWindowLongA(v3, -21); + local_SetWndLongStr(v4, "--"); + v5 = GetDlgItem(hWnd, 1018); + v6 = GetWindowLongA(v5, -21); + local_SetWndLongStr(v6, "--"); + v7 = GetDlgItem(hWnd, 1017); + v8 = GetWindowLongA(v7, -21); + local_SetWndLongStr(v8, "--"); + v9 = GetDlgItem(hWnd, 1016); + v10 = GetWindowLongA(v9, -21); + local_SetWndLongStr(v10, "--"); + v11 = GetDlgItem(hWnd, 1015); + v12 = GetWindowLongA(v11, -21); + local_SetWndLongStr(v12, "--"); + SelHero_SetStaticBMP(hWnd, 3); + Doom_ParseWndProc4(hWnd, selhero_msgtbl_info, 1); + } +} +// 1002A424: using guessed type int selhero_hero_hassaved; + +// ref: 0x1000BA7B +void __fastcall SelHero_SetStringWithMsg(HWND hWnd, const char *str) +{ + HWND v4; // eax + int v5; // eax + + v4 = GetDlgItem(hWnd, 1038); + if ( v4 ) + { + v5 = GetWindowLongA(v4, -21); + local_SetWndLongStr(v5, str); + Doom_ParseWndProc4(hWnd, selhero_msgtbl_string, 5); + } +} + +// ref: 0x1000BAB4 +BOOL __fastcall SelHero_IsNameReserved(char *name) +{ + UINT v1; // esi + BOOL result; // eax + char SrcStr[128]; // [esp+4h] [ebp-90h] + char Buffer[16]; // [esp+84h] [ebp-10h] + + strcpy(SrcStr, name); + _strlwr(SrcStr); + v1 = 19; + while ( 1 ) + { + LoadStringA(ghUiInst, v1, Buffer, 15); + SelHero_SetLastNamePos(Buffer); + _strlwr(Buffer); + result = (BOOL)strstr(SrcStr, Buffer); + if ( result ) + break; + if ( (signed int)++v1 > 26 ) + return result; + } + return 1; +} + +// ref: 0x1000BB26 +void __fastcall SelHero_SetLastNamePos(char *name) +{ + while ( *name ) + --*name++; +} + +// ref: 0x1000BB34 +BOOL __fastcall SelHero_NameHasChar(char *name, char *illegalchrs) +{ + char v5; // al + + if ( strpbrk(name, ",<>%&\\\"?*#/:") || strpbrk(name, illegalchrs) ) + return 1; + while ( 1 ) + { + v5 = *name; + if ( !*name ) + break; + if ( (unsigned char)v5 < 0x20u || (unsigned char)v5 > 0x7Eu && (unsigned char)v5 < 0xC0u ) + return 1; + ++name; + } + return 0; +} + +// ref: 0x1000BB75 +BOOL __fastcall UiValidPlayerName(char *name) +{ + BOOL v2; // edi + + v2 = 1; + if ( !strlen(name) ) + v2 = 0; + if ( selhero_is_good == 1 && (SelHero_IsNameReserved(name) || SelHero_NameHasChar(name, " ")) ) + v2 = 0; + return v2; +} + +// ref: 0x1000BBB4 +BOOL __stdcall UiSelHeroMultDialog(BOOL (__stdcall *fninfo)(BOOL (__stdcall *fninfofunc)(_uiheroinfo *)), BOOL (__stdcall *fncreate)(_uiheroinfo *), BOOL (__stdcall *fnremove)(_uiheroinfo *), BOOL (__stdcall *fnstats)(int, _uidefaultstats *), int *dlgresult, int *a6, char *name) +{ + int v7; // eax + int v8; // eax + + artfont_LoadAllFonts(); + selhero_fninfo = fninfo; + selhero_fncreate = fncreate; + selhero_fnremove = fnremove; + selhero_fnstats = fnstats; + sgpHeroInfo = 0; + selhero_is_good = 1; + selhero_is_created = 0; + v7 = (int)SDrawGetFrameWindow(NULL); + v8 = SDlgDialogBoxParam(ghUiInst, "SELHERO_DIALOG", v7, SelHero_WndProc, 0); + if ( dlgresult ) + *dlgresult = v8; + if ( name ) + strcpy(name, selhero_heronamestr); + if ( a6 ) + *a6 = selhero_is_created; + return 1; +} +// 10010382: using guessed type _DWORD __stdcall SDrawGetFrameWindow(); +// 1002A45C: using guessed type int selhero_is_created; + +// ref: 0x1000BC46 +LRESULT __stdcall SelHero_WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) +{ + HWND v4; // eax + int v6; // edx + HWND v7; // ecx + signed int v8; // [esp-4h] [ebp-8h] + + if ( Msg > 0xBD2 ) + { + switch ( Msg ) + { + case 0xBD3u: + SelHero_DoSelLoad(hWnd); + return 0; + case 0xBD4u: + SelHero_DoSelDiff(hWnd); + return 0; + case 0xBD5u: + v7 = hWnd; + if ( selhero_is_good != 1 ) + { + v8 = 2; + goto LABEL_30; + } + break; + case 0xBD6u: + strcpy(selhero_heronamestr, heroinfo_create.name); + v6 = 1; + v7 = hWnd; + if ( selhero_is_good != 1 ) + { + selhero_difficulty = 0; +LABEL_31: + SelHero_DoHeroEndFade(v7, v6); + return 0; + } + break; + case 0xBD7u: + SelHero_DoStuffWithStrings(hWnd); + return 0; + default: + return (LRESULT)SDlgDefDialogProc(hWnd, Msg, (HDC)wParam, (HWND)lParam); + } + v8 = 3; +LABEL_30: + v6 = v8; + goto LABEL_31; + } + if ( Msg == 3026 ) + { + SelHero_DoEnterName(hWnd); + return 0; + } + if ( Msg == 2 ) + { + SelHero_DeleteAndFree(hWnd); + return (LRESULT)SDlgDefDialogProc(hWnd, Msg, (HDC)wParam, (HWND)lParam); + } + if ( Msg <= 0x103 ) + return (LRESULT)SDlgDefDialogProc(hWnd, Msg, (HDC)wParam, (HWND)lParam); + if ( Msg <= 0x105 ) + { + v4 = (HWND)SDrawGetFrameWindow(NULL); + SendMessageA(v4, Msg, wParam, lParam); + return (LRESULT)SDlgDefDialogProc(hWnd, Msg, (HDC)wParam, (HWND)lParam); + } + switch ( Msg ) + { + case 0x110u: + SelHero_LoadHeroGFX(hWnd); + PostMessageA(hWnd, 0x7E8u, 0, 0); + return 0; + case 0x7E8u: + if ( !Fade_CheckRange5() ) + Fade_SetFadeTimer((int)hWnd); + return 0; + case 0xBD0u: + SelHero_DoHeroSelList(hWnd); + return 0; + } + if ( Msg != 3025 ) + return (LRESULT)SDlgDefDialogProc(hWnd, Msg, (HDC)wParam, (HWND)lParam); + SelHero_DoHeroSelClass(hWnd); + return 0; +} +// 10010382: using guessed type _DWORD __stdcall SDrawGetFrameWindow(); +// 1002A420: using guessed type int selhero_difficulty; + +// ref: 0x1000BDAD +void __fastcall SelHero_DoStuffWithStrings(HWND hWnd) +{ + _uiheroinfo *v1; // eax + char dialogstr[80]; // [esp+Ch] [ebp-B4h] + char string64[64]; // [esp+5Ch] [ebp-64h] + char Buffer[32]; // [esp+9Ch] [ebp-24h] + + if ( SelHero_GetHeroIsGood() == 1 ) + LoadStringA(ghUiInst, 0x23u, Buffer, 31); + else + LoadStringA(ghUiInst, 0x22u, Buffer, 31); + LoadStringA(ghUiInst, 7u, string64, 63); + wsprintfA(dialogstr, string64, selhero_heronamestr); + if ( SelYesNo_YesNoDialog(hWnd, dialogstr, Buffer, 1) != 2 ) + { + v1 = SelHero_GetHeroSlotFromName(sgpHeroInfo, selhero_heronamestr); + if ( v1 ) + { + if ( selhero_fnremove(v1) ) + { + sgpHeroInfo = SelHero_GetNextHeroFromStr(sgpHeroInfo, selhero_heronamestr); + --selhero_numheroesleft; + LoadStringA(ghUiInst, 0x1Eu, string64, 15); + if ( !strcmp(string64, sgpHeroInfo->name) ) + { + PostMessageA(hWnd, 0xBD1u, 0, 0); + return; + } + SelHero_PrintHeroInfo(hWnd, sgpHeroInfo); + } + else + { + LoadStringA(ghUiInst, 0x11u, string64, 63); + SelYesNo_SelOkDialog(hWnd, string64, Buffer, 1); + } + } + } + PostMessageA(hWnd, 0xBD0u, 0, 0); +} +// 1002A428: using guessed type int selhero_numheroesleft; + +// ref: 0x1000BEDB +_uiheroinfo *__fastcall SelHero_GetNextHeroFromStr(_uiheroinfo *pInfo, char *name) +{ + _uiheroinfo *v2; // ebx + _uiheroinfo *v3; // ebp + _uiheroinfo *v4; // edi + + v2 = pInfo; + v3 = 0; + v4 = 0; + if ( pInfo ) + { + while ( !v4 ) + { + if ( !strcmp(pInfo->name, name) ) + { + v4 = pInfo; + } + else + { + v3 = pInfo; + pInfo = pInfo->next; + } + if ( !pInfo ) + { + if ( !v4 ) + return v2; + break; + } + } + if ( v3 ) + v3->next = v4->next; + else + v2 = v4->next; + SelHero_FreeSomeMemory(v4); + } + return v2; +} + +// ref: 0x1000BF33 +void __fastcall SelHero_FreeSomeMemory(void *ptr) +{ + if ( ptr ) + SMemFree(ptr, "C:\\Src\\Diablo\\DiabloUI\\SelHero.cpp", 131, 0); +} + +// ref: 0x1000BF4A +_uiheroinfo *__fastcall SelHero_GetHeroSlotFromName(_uiheroinfo *pInfo, const char *name) +{ + _uiheroinfo *i; // esi + + for ( i = pInfo; i && _strcmpi(i->name, name); i = i->next ) + ; + return i; +} + +// ref: 0x1000BF6D +void __fastcall SelHero_DoHeroSelList(HWND hWnd) +{ + BOOL v2; // eax + int v3; // edx + + v2 = SDlgDialogBoxParam(ghUiInst, "SELLIST_DIALOG", (int)hWnd, SelList_WndProc, 0); + if ( v2 == 1 ) + { + if ( !strlen(selhero_heronamestr) ) + { + PostMessageA(hWnd, 0xBD1u, 0, 0); + return; + } + if ( selhero_is_good == 1 ) + { + PostMessageA(hWnd, 0xBD5u, 0, 0); + return; + } + if ( selhero_hero_hassaved ) + { + PostMessageA(hWnd, 0xBD3u, 0, 0); + return; + } + selhero_difficulty = 0; + v3 = 1; +LABEL_13: + SelHero_DoHeroEndFade(hWnd, v3); + return; + } + if ( v2 != 1006 ) + { + v3 = 4; + goto LABEL_13; + } + PostMessageA(hWnd, 0xBD7u, 0, 0); +} +// 1002A420: using guessed type int selhero_difficulty; +// 1002A424: using guessed type int selhero_hero_hassaved; + +// ref: 0x1000BFF9 +void __fastcall SelHero_DoHeroSelClass(HWND hWnd) +{ + BOOL v2; // eax + int v3; // eax + char Buffer[32]; // [esp+8h] [ebp-20h] + + v2 = SDlgDialogBoxParam(ghUiInst, "SELCLASS_DIALOG", (int)hWnd, SelClass_WndProc, 0); + if ( v2 == -1 || v2 == 2 ) + { + LoadStringA(ghUiInst, 0x1Eu, Buffer, 31); + if ( !strcmp(Buffer, sgpHeroInfo->name) ) + SelHero_DoHeroEndFade(hWnd, 4); + else + PostMessageA(hWnd, 0xBD0u, 0, 0); + } + else + { + v3 = v2 - 1063; + if ( v3 ) + { + if ( v3 == 1 ) + heroinfo_create.heroclass = 2; + else + heroinfo_create.heroclass = 0; + } + else + { + heroinfo_create.heroclass = 1; + } + PostMessageA(hWnd, 0xBD2u, 0, 0); + } +} + +// ref: 0x1000C09B +void __fastcall SelHero_DoEnterName(HWND hWnd) +{ + char namestr[16]; // [esp+8h] [ebp-10h] + + if ( SDlgDialogBoxParam(ghUiInst, "ENTERNAME_DIALOG", (int)hWnd, EntName_WndProc, (int)namestr) == 1 ) + { + namestr[15] = 0; + if ( SelHero_CreateHero(hWnd, namestr) ) + PostMessageA(hWnd, 0xBD6u, 0, 0); + else + PostMessageA(hWnd, 0xBD2u, 0, 0); + } + else + { + PostMessageA(hWnd, 0xBD1u, 0, 0); + } +} + +// ref: 0x1000C0F9 +BOOL __fastcall SelHero_CreateHero(HWND hWnd, char *name) +{ + _uiheroinfo *v2; // edi + char dialogstr[144]; // [esp+Ch] [ebp-138h] + char v5[128]; // [esp+9Ch] [ebp-A8h] + char Buffer[32]; // [esp+11Ch] [ebp-28h] + + if ( SelHero_GetHeroIsGood() == 1 ) + LoadStringA(ghUiInst, 0x20u, Buffer, 31); + else + LoadStringA(ghUiInst, 0x1Fu, Buffer, 31); + if ( !UiValidPlayerName(name) ) + { + LoadStringA(ghUiInst, 0xFu, v5, 127); + SelYesNo_SelOkDialog(hWnd, v5, Buffer, 1); + return 0; + } + v2 = SelHero_GetHeroSlotFromName(sgpHeroInfo, name); + if ( v2 ) + { + LoadStringA(ghUiInst, 8u, v5, 127); + wsprintfA(dialogstr, v5, v2->name); + if ( SelYesNo_YesNoDialog(hWnd, dialogstr, Buffer, 1) == 2 ) + return 0; + } + strcpy(heroinfo_create.name, name); + heroinfo_create.hassaved = 0; + if ( !selhero_fncreate(&heroinfo_create) ) + { + LoadStringA(ghUiInst, 0x10u, v5, 127); + OkCancel_DoOkDialog(hWnd, v5, 1); + return 0; + } + selhero_is_created = 1; + return 1; +} +// 1002A45C: using guessed type int selhero_is_created; + +// ref: 0x1000C21A +void __fastcall SelHero_DoSelLoad(HWND hWnd) +{ + BOOL v2; // eax + + v2 = SDlgDialogBoxParam(ghUiInst, "SELLOAD_DIALOG", (int)hWnd, SelLoad_WndProc, 0); + if ( v2 == -1 || v2 == 2 ) + { + PostMessageA(hWnd, 0xBD0u, 0, 0); + } + else if ( v2 == 1106 ) + { + PostMessageA(hWnd, 0xBD5u, 0, 0); + } + else + { + PostMessageA(hWnd, 0xBD4u, 0, 0); + } +} + +// ref: 0x1000C269 +void __fastcall SelHero_DoSelDiff(HWND hWnd) +{ + _uiheroinfo *v3; // eax + int v4; // eax + char Buffer[256]; // [esp+4h] [ebp-208h] + char v6[128]; // [esp+104h] [ebp-108h] + char v7[128]; // [esp+184h] [ebp-88h] + _gamedata gameData; // [esp+204h] [ebp-8h] + + if ( !SelHero_GetHeroIsGood() ) + { + SelHero_SetHeroDifficulty(0); +LABEL_3: + SelHero_DoHeroEndFade(hWnd, 1); + return; + } + CreaDung_SetDelSpin(1); + if ( SDlgDialogBoxParam(ghUiInst, "SELDIFF_DIALOG", (int)hWnd, CreaDung_WndProc, selhero_is_good) == 1 ) + { + v3 = SelHero_GetHeroSlotFromName(sgpHeroInfo, selhero_heronamestr); + UiCreatePlayerDescription(v3, 'DBLO', v7); + gameData.bDiff = selhero_difficulty; + Connect_SetDiffString(&gameData, selhero_heronamestr, v7, v6, 128); + v4 = UiAuthCallback(2, selhero_heronamestr, v7, 0, v6, Buffer, 256); + if ( v4 ) + goto LABEL_3; + SelYesNo_SelOkDialog(hWnd, Buffer, 0, 1); + PostMessageA(hWnd, 0xBD4u, 0, 0); + } + else + { + PostMessageA(hWnd, 0xBD3u, 0, 0); + } +} +// 1002A420: using guessed type int selhero_difficulty; + +// ref: 0x1000C364 +void __fastcall SelHero_DeleteAndFree(HWND hWnd) +{ + void **v2; // eax + + Doom_DeleteFreeProcs(hWnd, selhero_msgtbl_info); + Doom_DeleteFreeProcs(hWnd, selhero_msgtbl_3); + Doom_DeleteFreeProcs(hWnd, selhero_msgtbl_string); + Title_KillTitleTimer(hWnd); + SelHero_FreeAllHeroes(sgpHeroInfo); + if ( selhero_buffer ) + { + SMemFree(selhero_buffer, "C:\\Src\\Diablo\\DiabloUI\\SelHero.cpp", 744, 0); + selhero_buffer = 0; + } + v2 = (void **)GetWindowLongA(hWnd, -21); + local_FreeMemPtr(v2); +} + +// ref: 0x1000C3CE +void __fastcall SelHero_FreeAllHeroes(_uiheroinfo *pInfo) +{ + _uiheroinfo *v1; // esi + + if ( pInfo ) + { + do + { + v1 = pInfo->next; + SelHero_FreeSomeMemory(pInfo); + pInfo = v1; + } + while ( v1 ); + } +} + +// ref: 0x1000C3E2 +void __fastcall SelHero_DoHeroEndFade(HWND hWnd, int a2) +{ + void *v2; // edi + + v2 = (void *)a2; + Fade_Range5SetZero(); + Fade_UpdatePaletteRange(10); + SDlgEndDialog(hWnd, v2); +} + +// ref: 0x1000C3FF +void __fastcall SelHero_LoadHeroGFX(HWND hWnd) +{ + HWND v1; // eax + int v2; // eax + HWND v3; // eax + int v4; // eax + HWND v5; // eax + int v6; // eax + HWND v7; // eax + int v8; // eax + HWND v9; // eax + int v10; // eax + DWORD *v12; // eax MAPDST + + SelHero_SelectHeroRegion(hWnd); + v12 = local_AllocWndLongData(); + if ( v12 ) + { + SetWindowLongA(hWnd, -21, (LONG)v12); + local_LoadArtWithPal(hWnd, 0, &nullcharacter, -1, 1, "ui_art\\selhero.pcx", (BYTE **)v12, v12 + 1, 0); + Fade_NoInputAndArt(hWnd, 1); + } + local_LoadArtImage("ui_art\\heros.pcx", &selhero_buffer, selhero_sizedata); + SetActiveWindow(hWnd); + Title_LoadImgSetTimer(hWnd, "ui_art\\smlogo.pcx"); + Doom_ParseWndProc3(hWnd, selhero_msgtbl_string, 5); + Doom_ParseWndProc3(hWnd, selhero_msgtbl_3, 1); + Doom_ParseWndProc3(hWnd, selhero_msgtbl_info, 1); + selhero_hero_hassaved = 0; + selhero_heronamestr[0] = 0; + v1 = GetDlgItem(hWnd, 1014); + v2 = GetWindowLongA(v1, -21); + local_SetWndLongStr(v2, "--"); + v3 = GetDlgItem(hWnd, 1018); + v4 = GetWindowLongA(v3, -21); + local_SetWndLongStr(v4, "--"); + v5 = GetDlgItem(hWnd, 1017); + v6 = GetWindowLongA(v5, -21); + local_SetWndLongStr(v6, "--"); + v7 = GetDlgItem(hWnd, 1016); + v8 = GetWindowLongA(v7, -21); + local_SetWndLongStr(v8, "--"); + v9 = GetDlgItem(hWnd, 1015); + v10 = GetWindowLongA(v9, -21); + local_SetWndLongStr(v10, "--"); + SelHero_SetStaticBMP(hWnd, 3); + Doom_ParseWndProc4(hWnd, selhero_msgtbl_info, 1); +} +// 1002A424: using guessed type int selhero_hero_hassaved; + +// ref: 0x1000C49F +void __fastcall SelHero_SelectHeroRegion(HWND hWnd) +{ + _uiheroinfo *v2; // esi + _uiheroinfo *v3; // [esp+10h] [ebp-44h] + char Buffer[64]; // [esp+14h] [ebp-40h] + + v2 = SelHero_AllocHeroInfo(); + v2->next = 0; + LoadStringA(ghUiInst, 0x1Eu, v2->name, 15); + v2->level = 0; + sgpHeroInfo = SelRegn_SetNextHero(sgpHeroInfo, v2); + v3 = sgpHeroInfo; + selhero_numheroesleft = 1; + if ( !selhero_fninfo(SelHero_GetHeroInfo) ) + { + LoadStringA(ghUiInst, 0x12u, Buffer, 64); + OkCancel_DoOkDialog(hWnd, Buffer, 1); + } + if ( v3 == sgpHeroInfo ) + PostMessageA(hWnd, 0xBD1u, 0, 0); + else + PostMessageA(hWnd, 0xBD0u, 0, 0); +} +// 1002A428: using guessed type int selhero_numheroesleft; + +// ref: 0x1000C541 +BOOL __stdcall SelHero_GetHeroInfo(_uiheroinfo *pInfo) +{ + _uiheroinfo *v1; // esi + _uiheroinfo *v2; // eax + + v1 = SelHero_AllocHeroInfo(); + memcpy(v1, pInfo, 0x2Cu); + v1->next = 0; + v2 = SelRegn_SetNextHero(sgpHeroInfo, v1); + ++selhero_numheroesleft; + sgpHeroInfo = v2; + return 1; +} +// 1002A428: using guessed type int selhero_numheroesleft; + +// ref: 0x1000C57A +BOOL __stdcall UiSelHeroSingDialog(BOOL (__stdcall *fninfo)(BOOL (__stdcall *fninfofunc)(_uiheroinfo *)), BOOL (__stdcall *fncreate)(_uiheroinfo *), BOOL (__stdcall *fnremove)(_uiheroinfo *), BOOL (__stdcall *fnstats)(int, _uidefaultstats *), int *dlgresult, char *name, int *difficulty) +{ + int v7; // eax + int v8; // edi + + artfont_LoadAllFonts(); + selhero_fninfo = fninfo; + selhero_fncreate = fncreate; + selhero_fnremove = fnremove; + selhero_fnstats = fnstats; + sgpHeroInfo = 0; + selhero_is_good = 0; + v7 = (int)SDrawGetFrameWindow(NULL); + v8 = SDlgDialogBoxParam(ghUiInst, "SELHERO_DIALOG", v7, SelHero_WndProc, 0); + if ( dlgresult ) + *dlgresult = v8; + if ( name ) + strcpy(name, selhero_heronamestr); + if ( difficulty ) + *difficulty = selhero_difficulty; + if ( v8 != 4 ) + artfont_FreeAllFonts(); + return 1; +} +// 10010382: using guessed type _DWORD __stdcall SDrawGetFrameWindow(); +// 1002A420: using guessed type int selhero_difficulty; diff --git a/2020_03_31/DiabloUI/selipx.cpp b/2020_03_31/DiabloUI/selipx.cpp new file mode 100644 index 00000000..ae28e3f2 --- /dev/null +++ b/2020_03_31/DiabloUI/selipx.cpp @@ -0,0 +1,1258 @@ +// ref: 0x1000C610 +void *SelIPX_1000C610() { return 0; } +/* { + return SMemAlloc(268, "C:\\Src\\Diablo\\DiabloUI\\SelIPX.cpp", 105, 0); +} */ +// 10010364: using guessed type int __stdcall SMemAlloc(_DWORD, _DWORD, _DWORD, _DWORD); + +// ref: 0x1000C629 +signed int SelIPX_1000C629() { return 0; } +/* { + signed int result; // eax + + result = 2139095040; + dword_1002A4A4 = 2139095040; + return result; +} */ +// 1002A4A4: using guessed type int dword_1002A4A4; + +// ref: 0x1000C634 +BOOL __fastcall SelIPX_1000C634(int a1, int a2, int a3, _DWORD *a4, int a5, int a6) { return 0; } +/* { + int v6; // esi + + dword_1002A49C = a3; + dword_1002A4AC = a2; + dword_1002A4BC = a5; + dword_1002A4A0 = a4; + dword_1002A4A8 = a6; + artfont_10001159(); + v6 = SDlgDialogBoxParam(hInstance, "SELIPXGAME_DIALOG", a4[2], SelIPX_1000C692, 0); + artfont_100010C8(); + return v6 == 1; +} */ +// 10010370: using guessed type int __stdcall SDlgDialogBoxParam(_DWORD, _DWORD, _DWORD, _DWORD, _DWORD); +// 1002A49C: using guessed type int dword_1002A49C; +// 1002A4A8: using guessed type int dword_1002A4A8; +// 1002A4AC: using guessed type int dword_1002A4AC; +// 1002A4BC: using guessed type int dword_1002A4BC; + +// ref: 0x1000C692 +int __stdcall SelIPX_1000C692(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) { return 0; } +/* { + HWND v4; // eax + HWND v6; // eax + int v7; // [esp+0h] [ebp-Ch] + int savedregs; // [esp+Ch] [ebp+0h] + + if ( Msg > 0x113 ) + { + switch ( Msg ) + { + case 0x201u: + goto LABEL_35; + case 0x202u: + v6 = GetDlgItem(hWnd, 1105); + if ( !Sbar_100099C0(v6) ) + return SDlgDefDialogProc(hWnd, Msg, wParam, lParam); + goto LABEL_12; + case 0x203u: +LABEL_35: + SelIPX_1000D696(hWnd, (unsigned short)lParam, (unsigned int)lParam >> 16); + return SDlgDefDialogProc(hWnd, Msg, wParam, lParam); + } + if ( Msg != 2024 ) + return SDlgDefDialogProc(hWnd, Msg, wParam, lParam); + if ( !Fade_1000739F() ) + Fade_100073FD(hWnd, v7); + return 0; + } + if ( Msg == 275 ) + { + if ( wParam == 3 ) + SelIPX_1000C9DA(hWnd); + return 0; + } + if ( Msg == 2 ) + { + SelIPX_1000CC41(hWnd); + return SDlgDefDialogProc(hWnd, Msg, wParam, lParam); + } + if ( Msg <= 0x103 ) + return SDlgDefDialogProc(hWnd, Msg, wParam, lParam); + if ( Msg <= 0x105 ) + { + v4 = (HWND)SDrawGetFrameWindow(); + SendMessageA(v4, Msg, wParam, lParam); + return SDlgDefDialogProc(hWnd, Msg, wParam, lParam); + } + if ( Msg == 272 ) + { + SelIPX_1000CD4A(hWnd); + PostMessageA(hWnd, 0x7E8u, 0, 0); + return 0; + } + if ( Msg == 273 ) + { + if ( HIWORD(wParam) == 7 ) + { + Focus_100075B7(hWnd, (HWND)lParam); + return SDlgDefDialogProc(hWnd, Msg, wParam, lParam); + } + if ( HIWORD(wParam) != 6 ) + { + if ( wParam == 327681 ) + { + SelIPX_1000D3C5(hWnd, (int)&savedregs); + } + else if ( (_WORD)wParam == 2 ) + { + SelIPX_1000D3A0((int)hWnd, 2); + } + return SDlgDefDialogProc(hWnd, Msg, wParam, lParam); + } + Focus_10007458((void *)lParam); + Focus_100075DC(hWnd, (HWND)lParam); + SelIPX_1000C818(hWnd, (unsigned short)wParam); +LABEL_12: + SelIPX_1000C982(hWnd); + } + return SDlgDefDialogProc(hWnd, Msg, wParam, lParam); +} */ +// 1001037C: using guessed type int __stdcall SDlgDefDialogProc(_DWORD, _DWORD, _DWORD, _DWORD); +// 10010382: using guessed type _DWORD __stdcall SDrawGetFrameWindow(); + +// ref: 0x1000C818 +LONG __fastcall SelIPX_1000C818(HWND hDlg, int nIDDlgItem) { return 0; } +/* { + HWND v2; // ebx + HWND v3; // edi + LONG result; // eax + const char *v5; // edi + int v6; // eax + CHAR *v7; // edx + CHAR v8; // [esp+Ch] [ebp-280h] + CHAR v9; // [esp+10Ch] [ebp-180h] + char v10; // [esp+18Ch] [ebp-100h] + CHAR Buffer; // [esp+20Ch] [ebp-80h] + CHAR v12; // [esp+22Ch] [ebp-60h] + char v13; // [esp+24Ch] [ebp-40h] + unsigned short v14; // [esp+260h] [ebp-2Ch] + unsigned char v15; // [esp+262h] [ebp-2Ah] + char v16; // [esp+278h] [ebp-14h] + unsigned char v17; // [esp+27Ch] [ebp-10h] + int v18; // [esp+280h] [ebp-Ch] + int v19; // [esp+284h] [ebp-8h] + HWND hWnd; // [esp+288h] [ebp-4h] + + v2 = hDlg; + v3 = GetDlgItem(hDlg, nIDDlgItem); + hWnd = GetDlgItem(v2, 1098); + result = GetWindowLongA(v3, -21); + if ( result ) + { + result = *(_DWORD *)(result + 12); + if ( result ) + { + v5 = (const char *)(result + 140); + if ( *(_DWORD *)(result + 4) ) + { + if ( result == -140 || strlen((const char *)(result + 140)) < 0x10 ) + { + v6 = GetWindowLongA(hWnd, -21); + v7 = (CHAR *)&byte_10029448; + } + else + { + v19 = (int)&byte_10029448; + v18 = (int)&byte_10029448; + strcpy(&v10, v5); + if ( Connect_10003DAF(&v10, (int)&v16, (int)&v19, (int)&v18) + && Connect_10003E61((const char *)v18, &v13) ) + { + LoadStringA(hInstance, v17 + 1003, &Buffer, 31); + LoadStringA(hInstance, v15 + 4, &v12, 31); + LoadStringA(hInstance, 0x31u, &v9, 127); + wsprintfA(&v8, &v9, &Buffer, v19, v14, &v12); + v6 = GetWindowLongA(hWnd, -21); + v7 = &v8; + } + else + { + v6 = GetWindowLongA(hWnd, -21); + v7 = 0; + } + } + } + else + { + v6 = GetWindowLongA(hWnd, -21); + v7 = (CHAR *)v5; + } + local_10007FA4(v6, v7); + result = Doom_10006A13(v2, (int *)&unk_10023104, 1); + } + } + return result; +} */ + +// ref: 0x1000C982 +HWND UNKCALL SelIPX_1000C982(HWND hDlg) { return 0; } +/* { + HWND v1; // esi + int v2; // eax + + v1 = hDlg; + v2 = SelIPX_1000C99F(); + return Sbar_10009A99(v1, 1105, dword_1002A4B8, v2); +} */ + +// ref: 0x1000C99F +int SelIPX_1000C99F() { return 0; } +/* { + HWND v0; // eax + LONG v1; // eax + _DWORD *v2; // ecx + _DWORD *v3; // eax + int v5; // edx + + v0 = GetFocus(); + if ( !v0 ) + return 0; + v1 = GetWindowLongA(v0, -21); + if ( !v1 ) + return 0; + v2 = (_DWORD *)dword_1002A4B4; + if ( !dword_1002A4B4 ) + return 0; + v3 = *(_DWORD **)(v1 + 12); + if ( !v3 ) + return 0; + v5 = 0; + do + { + if ( v2 == v3 ) + break; + v2 = (_DWORD *)*v2; + ++v5; + } + while ( v2 ); + return v5; +} */ +// 1002A4B4: using guessed type int dword_1002A4B4; + +// ref: 0x1000C9DA +const char *UNKCALL SelIPX_1000C9DA(HWND hDlg) { return 0; } +/* { + HWND v1; // esi + const char *result; // eax + int v3; // ST0C_4 + HWND v4; // eax + HWND v5; // eax + int v6; // eax + + v1 = hDlg; + dword_1002A4B0 = 0; + SelIPX_1000CA64((_DWORD *)dword_1002A4B4); + SNetEnumGames(0, 0, SelIPX_1000CAD5, 0); + result = (const char *)SelIPX_1000CA71((_DWORD *)dword_1002A4B4); + dword_1002A4B4 = (int)result; + if ( dword_1002A4B0 ) + { + SelIPX_1000CB83(v1, result); + v3 = dword_1002A4B8 > 6; + v4 = GetDlgItem(v1, 1105); + ShowWindow(v4, v3); + v5 = GetFocus(); + v6 = GetWindowLongA(v5, -12); + SelIPX_1000C818(v1, v6); + result = (const char *)SelIPX_1000C982(v1); + } + return result; +} */ +// 10010436: using guessed type int __stdcall SNetEnumGames(_DWORD, _DWORD, _DWORD, _DWORD); +// 1002A4B0: using guessed type int dword_1002A4B0; +// 1002A4B4: using guessed type int dword_1002A4B4; + +// ref: 0x1000CA64 +void __fastcall SelIPX_1000CA64(_DWORD *a1) { return; } +/* { + while ( a1 ) + { + a1[2] = 0; + a1 = (_DWORD *)*a1; + } +} */ + +// ref: 0x1000CA71 +_DWORD **__fastcall SelIPX_1000CA71(_DWORD *a1) { return 0; } +/* { + _DWORD **v1; // edi + _DWORD *v2; // esi + + v1 = (_DWORD **)a1; + v2 = 0; + while ( a1 ) + { + if ( a1[2] || !a1[1] ) + { + v2 = a1; + a1 = (_DWORD *)*a1; + } + else + { + if ( v2 ) + *v2 = *a1; + else + v1 = (_DWORD **)*a1; + SelIPX_1000CAC1(a1); + --dword_1002A4B8; + dword_1002A4B0 = 1; + if ( v2 ) + a1 = (_DWORD *)*v2; + else + a1 = *v1; + } + } + return v1; +} */ +// 1002A4B0: using guessed type int dword_1002A4B0; + +// ref: 0x1000CAC1 +int UNKCALL SelIPX_1000CAC1(void *arg) { return 0; } +/* { + int result; // eax + + if ( arg ) + result = SMemFree(arg, "C:\\Src\\Diablo\\DiabloUI\\SelIPX.cpp", 110, 0); + return result; +} */ +// 10010340: using guessed type int __stdcall SMemFree(_DWORD, _DWORD, _DWORD, _DWORD); + +// ref: 0x1000CAD5 +void *__stdcall SelIPX_1000CAD5(int a1, char *a2, char *a3) { return 0; } +/* { + _DWORD *v3; // eax + int result; // eax + int v5; // esi + _DWORD *v6; // eax + + v3 = SelIPX_1000CB73((_DWORD *)dword_1002A4B4, a1); + if ( v3 ) + { + v3[2] = 1; + } + else + { + result = SelIPX_1000C610(); + v5 = result; + if ( !result ) + return result; + *(_DWORD *)result = 0; + *(_DWORD *)(result + 4) = a1; + *(_DWORD *)(result + 8) = 1; + strcpy((char *)(result + 12), a2); + strcpy((char *)(v5 + 140), a3); + v6 = SelIPX_1000CB50((_DWORD *)dword_1002A4B4, (_DWORD *)v5); + ++dword_1002A4B8; + dword_1002A4B4 = (int)v6; + dword_1002A4B0 = 1; + } + return 1; +} */ +// 1002A4B0: using guessed type int dword_1002A4B0; +// 1002A4B4: using guessed type int dword_1002A4B4; + +// ref: 0x1000CB50 +_DWORD *__fastcall SelIPX_1000CB50(_DWORD *a1, _DWORD *a2) { return 0; } +/* { + _DWORD *result; // eax + _DWORD *v3; // edi + _DWORD *i; // esi + + result = a1; + v3 = 0; + for ( i = a1; i; i = (_DWORD *)*i ) + v3 = i; + *a2 = i; + if ( !v3 ) + return a2; + *v3 = a2; + return result; +} */ + +// ref: 0x1000CB73 +_DWORD *__fastcall SelIPX_1000CB73(_DWORD *a1, int a2) { return 0; } +/* { + _DWORD *result; // eax + + for ( result = a1; result && result[1] != a2; result = (_DWORD *)*result ) + ; + return result; +} */ + +// ref: 0x1000CB83 +int __fastcall SelIPX_1000CB83(HWND a1, const char *a2) { return 0; } +/* { + int *v2; // ebp + HWND v3; // eax + HWND v4; // esi + int v5; // eax + int v6; // eax + const char *v8; // [esp+4h] [ebp-8h] + HWND hDlg; // [esp+8h] [ebp-4h] + + v8 = a2; + hDlg = a1; + v2 = &dword_10023118; + if ( dword_10023118 ) + { + do + { + v3 = GetDlgItem(hDlg, *v2); + v4 = v3; + if ( v3 ) + { + if ( v8 ) + { + EnableWindow(v3, 1); + v6 = GetWindowLongA(v4, -21); + if ( v6 ) + { + *(_DWORD *)(v6 + 12) = v8; + local_10007FA4(v6, v8 + 12); + } + v8 = *(const char **)v8; + } + else + { + if ( v3 == GetFocus() ) + SelIPX_1000CCD9(v4); + EnableWindow(v4, 0); + v5 = GetWindowLongA(v4, -21); + if ( v5 ) + { + *(_DWORD *)(v5 + 12) = 0; + local_10007FA4(v5, &byte_10029448); + } + } + } + ++v2; + } + while ( *v2 ); + } + return Doom_1000680A(hDlg, &dword_10023118, 2, 1); +} */ +// 10023118: using guessed type int dword_10023118; + +// ref: 0x1000CC41 +int UNKCALL SelIPX_1000CC41(HWND hDlg) { return 0; } +/* { + HWND v1; // esi + _DWORD *v2; // eax + + v1 = hDlg; + SelIPX_1000CCC5((_DWORD *)dword_1002A4B4); + dword_1002A4B4 = 0; + Sbar_10009CD2(v1, 1105); + Doom_10006C53(v1, &dword_10023118); + Doom_10006C53(v1, (int *)&unk_1002310C); + Doom_10006C53(v1, (int *)&unk_10023104); + Doom_10006C53(v1, (int *)&unk_100230FC); + Doom_10006C53(v1, (int *)&unk_100230F0); + v2 = (_DWORD *)GetWindowLongA(v1, -21); + local_10007F72(v2); + Title_100100E7(v1); + Focus_10007818(v1); + return SDrawClearSurface(); +} */ +// 1001043C: using guessed type _DWORD __stdcall SDrawClearSurface(); +// 10023118: using guessed type int dword_10023118; +// 1002A4B4: using guessed type int dword_1002A4B4; + +// ref: 0x1000CCC5 +int __fastcall SelIPX_1000CCC5(_DWORD *a1) { return 0; } +/* { + _DWORD *v1; // esi + int result; // eax + + if ( a1 ) + { + do + { + v1 = (_DWORD *)*a1; + result = SelIPX_1000CAC1(a1); + a1 = v1; + } + while ( v1 ); + } + return result; +} */ + +// ref: 0x1000CCD9 +HWND UNKCALL SelIPX_1000CCD9(HWND hWnd) { return 0; } +/* { + HWND v1; // edi + HWND v2; // ebx + int nIDDlgItem[1085]; // [esp+0h] [ebp-1118h] + int v5; // [esp+10F4h] [ebp-24h] + int v6; // [esp+1100h] [ebp-18h] + int v7; // [esp+1104h] [ebp-14h] + int v8; // [esp+1108h] [ebp-10h] + int v9; // [esp+110Ch] [ebp-Ch] + int v10; // [esp+1110h] [ebp-8h] + int v11; // [esp+1114h] [ebp-4h] + + v1 = hWnd; + v6 = 1093; + v7 = 1088; + v8 = 1089; + v9 = 1090; + v10 = 1091; + v11 = 1092; + v2 = GetParent(hWnd); + do + { + v5 = nIDDlgItem[GetWindowLongA(v1, -12)]; + v1 = GetDlgItem(v2, v5); + } + while ( !IsWindowEnabled(v1) ); + return SetFocus(v1); +} */ +// 1000CCD9: using guessed type int nIDDlgItem[1085]; + +// ref: 0x1000CD4A +HWND UNKCALL SelIPX_1000CD4A(HWND hWnd) { return 0; } +/* { + HWND v1; // esi + HWND v2; // ST1C_4 + int v3; // eax + int *v4; // edi + HWND v5; // ebp + int v6; // eax + HWND result; // eax + HWND v8; // eax + HWND v9; // [esp+0h] [ebp-4Ch] + CHAR Buffer; // [esp+Ch] [ebp-40h] + + v1 = hWnd; + SelIPX_1000CEE6(hWnd); + Focus_100077E9((int)v1, "ui_art\\focus16.pcx", v9); + Title_1001009E(v1, (int)"ui_art\\smlogo.pcx", v2); + v3 = local_10007F46(); + v4 = (int *)v3; + if ( v3 ) + { + SetWindowLongA(v1, -21, v3); + local_10007944((int)v1, 0, &byte_10029448, -1, 1, (int)"ui_art\\selgame.pcx", v4, v4 + 1, 0); + Fade_100073C5(v1, 1); + } + if ( SelGame_1000B67E() != 1230002254 ) + { + v5 = GetDlgItem(v1, 1038); + LoadStringA(hInstance, 0x4Du, &Buffer, 63); + SetWindowTextA(v5, &Buffer); + } + Doom_100068AB(v1, (int *)&unk_100230F0, 5); + Doom_100068AB(v1, (int *)&unk_100230FC, 3); + Doom_100068AB(v1, (int *)&unk_10023104, 1); + Doom_1000658C(v1, (int *)&unk_1002310C, 4, 0); + Doom_1000658C(v1, &dword_10023118, 2, 1); + dword_1002A4B8 = 0; + v6 = SelIPX_1000C610(); + dword_1002A4B4 = v6; + if ( v6 ) + { + ++dword_1002A4B8; + *(_DWORD *)(v6 + 4) = 0; + *(_BYTE *)(dword_1002A4B4 + 140) = 0; + *(_DWORD *)dword_1002A4B4 = 0; + LoadStringA(hInstance, 0x24u, (LPSTR)(dword_1002A4B4 + 12), 127); + LoadStringA(hInstance, 0x2Au, (LPSTR)(dword_1002A4B4 + 140), 127); + } + SNetEnumGames(0, 0, SelIPX_1000CAD5, 0); + SelIPX_1000CB83(v1, (const char *)dword_1002A4B4); + SDlgSetTimer(v1, 3, 1000, 0); + result = Sbar_10009BF1(v1, 1105); + if ( dword_1002A4B8 <= 6 ) + { + v8 = GetDlgItem(v1, 1105); + result = (HWND)ShowWindow(v8, 0); + } + return result; +} */ +// 10010412: using guessed type int __stdcall SDlgSetTimer(_DWORD, _DWORD, _DWORD, _DWORD); +// 10010436: using guessed type int __stdcall SNetEnumGames(_DWORD, _DWORD, _DWORD, _DWORD); +// 10023118: using guessed type int dword_10023118; +// 1002A4B4: using guessed type int dword_1002A4B4; + +// ref: 0x1000CEE6 +void UNKCALL SelIPX_1000CEE6(HWND hDlg) { return; } +/* { + HWND v1; // ebx + int *v2; // edi + HWND v3; // eax + HWND v4; // esi + void *v5; // eax + + v1 = hDlg; + v2 = &dword_10023118; + if ( dword_10023118 ) + { + do + { + v3 = GetDlgItem(v1, *v2); + v4 = v3; + if ( v3 ) + { + v5 = (void *)GetWindowLongA(v3, -4); + SetPropA(v4, "UIOLDPROC", v5); + SetWindowLongA(v4, -4, (LONG)SelIPX_1000CF38); + } + ++v2; + } + while ( *v2 ); + } +} */ +// 10023118: using guessed type int dword_10023118; + +// ref: 0x1000CF38 +LRESULT __stdcall SelIPX_1000CF38(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) { return 0; } +/* { + LRESULT (__stdcall *v4)(HWND, UINT, WPARAM, LPARAM); // edi + HWND v5; // eax + UINT v7; // [esp-Ch] [ebp-18h] + WPARAM v8; // [esp-8h] [ebp-14h] + LPARAM v9; // [esp-4h] [ebp-10h] + + v4 = (LRESULT (__stdcall *)(HWND, UINT, WPARAM, LPARAM))GetPropA(hWnd, "UIOLDPROC"); + switch ( Msg ) + { + case 2u: + RemovePropA(hWnd, "UIOLDPROC"); + if ( !v4 ) + return DefWindowProcA(hWnd, Msg, wParam, lParam); + SetWindowLongA(hWnd, -4, (LONG)v4); + break; + case 0xFu: + local_10007C95(hWnd); + return 0; + case 0x87u: + return 4; + case 0x100u: + if ( wParam > 0x21 ) + { + if ( wParam == 34 ) + { + SelIPX_1000D0E1(hWnd); + return 0; + } + if ( wParam > 0x24 ) + { + if ( wParam <= 0x26 ) + { + SelIPX_1000D31C(hWnd); + return 0; + } + if ( wParam <= 0x28 ) + { + SelIPX_1000D284(hWnd); + return 0; + } + if ( wParam == 46 ) + { + v9 = lParam; + v8 = 46; + v7 = 256; + goto LABEL_24; + } + } + } + else + { + switch ( wParam ) + { + case 0x21u: + SelIPX_1000D1D4(hWnd); + break; + case 9u: + if ( GetKeyState(16) >= 0 ) + SelIPX_1000D070(hWnd); + else + SelIPX_1000CCD9(hWnd); + return 0; + case 0xDu: + goto LABEL_38; + case 0x1Bu: + v9 = 0; + v8 = 2; + goto LABEL_12; + case 0x20u: +LABEL_38: + v9 = 0; + v8 = 1; +LABEL_12: + v7 = 273; +LABEL_24: + v5 = GetParent(hWnd); + SendMessageA(v5, v7, v8, v9); + return 0; + } + } + return 0; + } + if ( v4 ) + return CallWindowProcA(v4, hWnd, Msg, wParam, lParam); + return DefWindowProcA(hWnd, Msg, wParam, lParam); +} */ + +// ref: 0x1000D070 +HWND UNKCALL SelIPX_1000D070(HWND hWnd) { return 0; } +/* { + HWND v1; // edi + HWND v2; // ebx + int nIDDlgItem[1085]; // [esp+0h] [ebp-1118h] + int v5; // [esp+10F4h] [ebp-24h] + int v6; // [esp+1100h] [ebp-18h] + int v7; // [esp+1104h] [ebp-14h] + int v8; // [esp+1108h] [ebp-10h] + int v9; // [esp+110Ch] [ebp-Ch] + int v10; // [esp+1110h] [ebp-8h] + int v11; // [esp+1114h] [ebp-4h] + + v1 = hWnd; + v6 = 1089; + v7 = 1090; + v8 = 1091; + v9 = 1092; + v10 = 1093; + v11 = 1088; + v2 = GetParent(hWnd); + do + { + v5 = nIDDlgItem[GetWindowLongA(v1, -12)]; + v1 = GetDlgItem(v2, v5); + } + while ( !IsWindowEnabled(v1) ); + return SetFocus(v1); +} */ +// 1000D070: using guessed type int nIDDlgItem[1085]; + +// ref: 0x1000D0E1 +HWND UNKCALL SelIPX_1000D0E1(HWND hWnd) { return 0; } +/* { + HWND v1; // ebp + HWND result; // eax + HWND v3; // esi + HWND v4; // ebx + HWND v5; // eax + _DWORD *v6; // eax + int v7; // eax + const char *v8; // ebx + int v9; // eax + + v1 = hWnd; + result = GetParent(hWnd); + v3 = result; + if ( result ) + { + result = GetDlgItem(result, 1088); + v4 = result; + if ( result ) + { + v5 = GetDlgItem(v3, 1093); + result = (HWND)GetWindowLongA(v5, -21); + if ( result ) + { + v6 = (_DWORD *)*((_DWORD *)result + 3); + if ( v6 && *v6 ) + { + v7 = SelIPX_1000D18C(v4) + 6; + if ( v7 > dword_1002A4B8 - 6 ) + v7 = dword_1002A4B8 - 6; + result = (HWND)SelIPX_1000D1C1(v7); + v8 = (const char *)result; + if ( result ) + { + TitleSnd_10010315(); + SelIPX_1000CB83(v3, v8); + v9 = GetWindowLongA(v1, -12); + SelIPX_1000C818(v3, v9); + result = SelIPX_1000C982(v3); + } + } + else + { + result = SelIPX_1000CCD9(v4); + } + } + } + } + return result; +} */ + +// ref: 0x1000D18C +int UNKCALL SelIPX_1000D18C(HWND hWnd) { return 0; } +/* { + LONG v1; // eax + _DWORD *v2; // ecx + _DWORD *v3; // eax + int v5; // edx + + if ( !hWnd ) + return 0; + v1 = GetWindowLongA(hWnd, -21); + if ( !v1 ) + return 0; + v2 = (_DWORD *)dword_1002A4B4; + if ( !dword_1002A4B4 ) + return 0; + v3 = *(_DWORD **)(v1 + 12); + if ( !v3 ) + return 0; + v5 = 0; + do + { + if ( v2 == v3 ) + break; + v2 = (_DWORD *)*v2; + ++v5; + } + while ( v2 ); + return v5; +} */ +// 1002A4B4: using guessed type int dword_1002A4B4; + +// ref: 0x1000D1C1 +_DWORD *__fastcall SelIPX_1000D1C1(int a1) { return 0; } +/* { + _DWORD *result; // eax + + result = (_DWORD *)dword_1002A4B4; + while ( result && a1 ) + { + result = (_DWORD *)*result; + --a1; + } + return result; +} */ +// 1002A4B4: using guessed type int dword_1002A4B4; + +// ref: 0x1000D1D4 +HWND UNKCALL SelIPX_1000D1D4(HWND hWnd) { return 0; } +/* { + HWND result; // eax + HWND v2; // esi + HWND v3; // edi + HWND v4; // eax + int v5; // eax + const char *v6; // edi + int v7; // eax + HWND hWnda; // [esp+10h] [ebp-4h] + + hWnda = hWnd; + result = GetParent(hWnd); + v2 = result; + if ( result ) + { + result = GetDlgItem(result, 1088); + v3 = result; + if ( result ) + { + result = (HWND)GetWindowLongA(result, -21); + if ( result ) + { + result = (HWND)*((_DWORD *)result + 3); + if ( result ) + { + if ( result == (HWND)dword_1002A4B4 ) + { + v4 = GetDlgItem(v2, 1093); + result = SelIPX_1000D070(v4); + } + else + { + v5 = SelIPX_1000D18C(v3) - 6; + if ( v5 < 0 ) + v5 = 0; + result = (HWND)SelIPX_1000D1C1(v5); + v6 = (const char *)result; + if ( result ) + { + TitleSnd_10010315(); + SelIPX_1000CB83(v2, v6); + v7 = GetWindowLongA(hWnda, -12); + SelIPX_1000C818(v2, v7); + result = SelIPX_1000C982(v2); + } + } + } + } + } + } + return result; +} */ +// 1002A4B4: using guessed type int dword_1002A4B4; + +// ref: 0x1000D284 +HWND UNKCALL SelIPX_1000D284(HWND hWnd) { return 0; } +/* { + HWND v1; // edi + HWND result; // eax + HWND v3; // eax + const char *v4; // ebp + HWND v5; // eax + int v6; // ebx + HWND v7; // eax + HWND v8; // eax + + v1 = hWnd; + result = (HWND)GetWindowLongA(hWnd, -21); + if ( result ) + { + result = (HWND)*((_DWORD *)result + 3); + if ( result ) + { + if ( *(_DWORD *)result ) + { + if ( GetWindowLongA(v1, -12) >= 1093 ) + { + v3 = GetParent(v1); + result = GetDlgItem(v3, 1089); + if ( result ) + { + result = (HWND)GetWindowLongA(result, -21); + if ( result ) + { + v4 = (const char *)*((_DWORD *)result + 3); + if ( v4 ) + { + TitleSnd_10010315(); + v5 = GetParent(v1); + SelIPX_1000CB83(v5, v4); + v6 = GetWindowLongA(v1, -12); + v7 = GetParent(v1); + SelIPX_1000C818(v7, v6); + v8 = GetParent(v1); + result = SelIPX_1000C982(v8); + } + } + } + } + else + { + result = SelIPX_1000D070(v1); + } + } + } + } + return result; +} */ + +// ref: 0x1000D31C +HWND UNKCALL SelIPX_1000D31C(HWND hWnd) { return 0; } +/* { + HWND v1; // edi + HWND result; // eax + const char *v3; // ebx + HWND v4; // eax + int v5; // ebx + HWND v6; // eax + HWND v7; // eax + + v1 = hWnd; + if ( GetWindowLongA(hWnd, -12) > 1088 ) + return SelIPX_1000CCD9(v1); + result = (HWND)GetWindowLongA(v1, -21); + if ( result ) + { + result = (HWND)*((_DWORD *)result + 3); + if ( result ) + { + v3 = (const char *)dword_1002A4B4; + if ( result != (HWND)dword_1002A4B4 ) + { + while ( v3 && *(HWND *)v3 != result ) + v3 = *(const char **)v3; + TitleSnd_10010315(); + v4 = GetParent(v1); + SelIPX_1000CB83(v4, v3); + v5 = GetWindowLongA(v1, -12); + v6 = GetParent(v1); + SelIPX_1000C818(v6, v5); + v7 = GetParent(v1); + result = SelIPX_1000C982(v7); + } + } + } + return result; +} */ +// 1002A4B4: using guessed type int dword_1002A4B4; + +// ref: 0x1000D3A0 +int __fastcall SelIPX_1000D3A0(int a1, int a2) { return 0; } +/* { + int v2; // edi + int v3; // esi + + v2 = a2; + v3 = a1; + Fade_100073B4(); + SDlgKillTimer(v3, 3); + Fade_100072BE(10); + return SDlgEndDialog(v3, v2); +} */ +// 10010376: using guessed type int __stdcall SDlgEndDialog(_DWORD, _DWORD); +// 10010418: using guessed type int __stdcall SDlgKillTimer(_DWORD, _DWORD); + +// ref: 0x1000D3C5 +HWND USERCALL SelIPX_1000D3C5(HWND hDlg, int a2) { return 0; } +/* { + HWND v2; // edi + HWND v3; // eax + HWND v4; // esi + HWND result; // eax + int v6; // esi + HWND v7; // esi + int v8; // eax + HWND v9; // edi + int v10; // [esp-DCh] [ebp-E4h] + signed int v11; // [esp-5Ch] [ebp-64h] + HWND v12; // [esp-54h] [ebp-5Ch] + signed int v13; // [esp-Ch] [ebp-14h] + signed int v14; // [esp-8h] [ebp-10h] + int v15; // [esp-4h] [ebp-Ch] + int v16; // [esp+0h] [ebp-8h] + int v17; // [esp+4h] [ebp-4h] + + v2 = hDlg; + v3 = GetFocus(); + v4 = v3; + result = GetParent(v3); + if ( v2 == result ) + { + result = (HWND)GetWindowLongA(v4, -21); + if ( result ) + { + v6 = *((_DWORD *)result + 3); + TitleSnd_1001031F(); + if ( *(_DWORD *)(v6 + 4) ) + { + result = (HWND)SelIPX_1000D5B0((int)v2, v6); + } + else + { + v17 = a2; + v7 = v2; + SelIPX_1000C9DA(v2); + memcpy(&v11, dword_1002A4A0, 0x50u); + v11 = 80; + v12 = v2; + memset(&v13, 0, 0x10u); + v13 = 16; + v14 = 1230002254; + v8 = *(_DWORD *)(dword_1002A4AC + 24); + v16 = 0; + v15 = v8; + v9 = GetFocus(); + SelIPX_1000D4CA(v7, 0); + SelIPX_1000D520((char *)&v10); + if ( CreaDung_100051D8( + (int)&v13, + dword_1002A4AC, + dword_1002A49C, + (int)&v11, + dword_1002A4BC, + dword_1002A4A8, + 0, + (int)&v10) ) + { + result = (HWND)SelIPX_1000D3A0((int)v7, 1); + } + else + { + SelIPX_1000D4CA(v7, 1); + result = SetFocus(v9); + } + } + } + } + return result; +} */ +// 1000D3C5: could not find valid save-restore pair for ebp +// 1002A49C: using guessed type int dword_1002A49C; +// 1002A4A8: using guessed type int dword_1002A4A8; +// 1002A4AC: using guessed type int dword_1002A4AC; +// 1002A4BC: using guessed type int dword_1002A4BC; + +// ref: 0x1000D4CA +BOOL __fastcall SelIPX_1000D4CA(HWND hDlg, int a2) { return 0; } +/* { + HWND v2; // ebx + int v3; // ebp + HWND v4; // eax + HWND v5; // eax + BOOL result; // eax + int nCmdShow; // [esp+10h] [ebp-4h] + + nCmdShow = a2; + v2 = hDlg; + v3 = 1088; + do + { + v4 = GetDlgItem(v2, v3); + if ( v4 ) + ShowWindow(v4, nCmdShow); + ++v3; + } + while ( v3 <= 1093 ); + v5 = GetDlgItem(v2, 1105); + if ( dword_1002A4B8 > 6 ) + result = ShowWindow(v5, nCmdShow); + else + result = ShowWindow(v5, 0); + return result; +} */ + +// ref: 0x1000D520 +char *UNKCALL SelIPX_1000D520(char *arg) { return 0; } +/* { + char *v1; // esi + char *result; // eax + signed int v3; // edi + signed int v4; // eax + char v5; // [esp+4h] [ebp-80h] + + v1 = arg; + Connect_10004028((int)&v5, 128, 0, 0); + if ( !SelIPX_1000D58D((const char *)dword_1002A4B4, &v5) ) + return strcpy(v1, &v5); + v3 = 2; + do + { + v4 = v3++; + wsprintfA(v1, "%s %d", &v5, v4); + result = (char *)SelIPX_1000D58D((const char *)dword_1002A4B4, v1); + } + while ( result ); + return result; +} */ +// 1002A4B4: using guessed type int dword_1002A4B4; + +// ref: 0x1000D58D +const char *__fastcall SelIPX_1000D58D(const char *a1, const char *a2) { return 0; } +/* { + const char *v2; // edi + const char *i; // esi + + v2 = a2; + for ( i = a1; i && _strcmpi(i + 12, v2); i = *(const char **)i ) + ; + return i; +} */ + +// ref: 0x1000D5B0 +int __fastcall SelIPX_1000D5B0(int a1, int a2) { return 0; } +/* { + int v2; // esi + CHAR *v3; // edx + CHAR v5; // [esp+Ch] [ebp-384h] + CHAR v6; // [esp+10Ch] [ebp-284h] + char v7; // [esp+20Ch] [ebp-184h] + CHAR Buffer; // [esp+28Ch] [ebp-104h] + int v9; // [esp+30Ch] [ebp-84h] + int v10; // [esp+38Ch] [ebp-4h] + + v2 = a2; + v10 = a1; + Connect_10004028((int)&v9, 128, (int)&v7, 128); + if ( UiAuthCallback(2, (int)&v9, &v7, 0, (char *)(v2 + 140), &v6, 256) ) + { + if ( SNetJoinGame(*(_DWORD *)(v2 + 4), v2 + 12, 0, &v9, &v7, dword_1002A4A8) ) + return SelIPX_1000D3A0(v10, 1); + if ( SErrGetLastError() == -2062548871 ) + LoadStringA(hInstance, 0x32u, &Buffer, 127); + else + LoadStringA(hInstance, 0x25u, &Buffer, 127); + wsprintfA(&v5, &Buffer, v2 + 12); + v3 = &v5; + } + else + { + v3 = &v6; + } + return SelYesNo_1000FD39(v10, v3, 0, 0); +} */ +// 10010406: using guessed type _DWORD __stdcall SErrGetLastError(); +// 10010430: using guessed type int __stdcall SNetJoinGame(_DWORD, _DWORD, _DWORD, _DWORD, _DWORD, _DWORD); +// 1002A4A8: using guessed type int dword_1002A4A8; + +// ref: 0x1000D696 +HWND __fastcall SelIPX_1000D696(HWND hDlg, int a2, int a3) { return 0; } +/* { + int v3; // ebx + HWND v4; // esi + int v5; // ST08_4 + HWND v6; // eax + HWND result; // eax + HWND v8; // eax + HWND v9; // eax + HWND v10; // eax + int v11; // eax + int v12; // eax + int v13; // eax + HWND v14; // eax + HWND v15; // eax + HWND v16; // eax + HWND v17; // eax + + v3 = a2; + v4 = hDlg; + v5 = a2; + v6 = GetDlgItem(hDlg, 1056); + if ( local_10007C3B(v4, v6, v5, a3) ) + return SelIPX_1000D3C5(v4, a3); + v8 = GetDlgItem(v4, 1054); + if ( local_10007C3B(v4, v8, v3, a3) ) + return (HWND)SelIPX_1000D3A0((int)v4, 2); + v9 = GetDlgItem(v4, 1105); + result = (HWND)local_10007C3B(v4, v9, v3, a3); + if ( result ) + { + v10 = GetDlgItem(v4, 1105); + v11 = Sbar_100099DC(v10, v3, a3) - 1; + if ( v11 ) + { + v12 = v11 - 1; + if ( v12 ) + { + v13 = v12 - 1; + if ( v13 ) + { + result = (HWND)(v13 - 1); + if ( !result ) + { + v14 = GetFocus(); + result = SelIPX_1000D0E1(v14); + } + } + else + { + v15 = GetFocus(); + result = SelIPX_1000D1D4(v15); + } + } + else + { + v16 = GetFocus(); + result = SelIPX_1000D284(v16); + } + } + else + { + v17 = GetFocus(); + result = SelIPX_1000D31C(v17); + } + } + return result; +} */ diff --git a/2020_03_31/DiabloUI/sellist.cpp b/2020_03_31/DiabloUI/sellist.cpp new file mode 100644 index 00000000..ce1ff87c --- /dev/null +++ b/2020_03_31/DiabloUI/sellist.cpp @@ -0,0 +1,743 @@ +// ref: 0x1000D769 +void __cdecl SelList_cpp_init() +{ + SelList_cpp_float = SelList_cpp_float_value; +} +// 1001F468: using guessed type int SelList_cpp_float_value; +// 1002A4C0: using guessed type int SelList_cpp_float; + +// ref: 0x1000D774 +LRESULT __stdcall SelList_WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) +{ + HWND v4; // eax + char *v5; // eax + int v6; // edx + HWND v8; // eax + HWND v9; // eax + + if ( Msg > 0x111 ) + { + if ( Msg == 275 ) + { + v9 = GetFocus(); + Focus_DoBlitSpinIncFrame(hWnd, v9); + return 0; + } + if ( Msg != 513 ) + { + if ( Msg == 514 ) + { + v8 = GetDlgItem(hWnd, 1105); + if ( !Sbar_CheckIfNextHero(v8) ) + return (LRESULT)SDlgDefDialogProc(hWnd, Msg, (HDC)wParam, (HWND)lParam); + goto LABEL_23; + } + if ( Msg != 515 ) + return (LRESULT)SDlgDefDialogProc(hWnd, Msg, (HDC)wParam, (HWND)lParam); + } + SelList_ChooseDlgFromSize(hWnd, (unsigned short)lParam, (unsigned int)lParam >> 16); + return (LRESULT)SDlgDefDialogProc(hWnd, Msg, (HDC)wParam, (HWND)lParam); + } + switch ( Msg ) + { + case 0x111u: + if ( HIWORD(wParam) == 7 ) + { + Focus_GetAndBlitSpin(hWnd, lParam); + return (LRESULT)SDlgDefDialogProc(hWnd, Msg, (HDC)wParam, (HWND)lParam); + } + if ( HIWORD(wParam) != 6 ) + { + v6 = 1; + if ( HIWORD(wParam) != 5 && (_WORD)wParam != 1 ) + { + v6 = 2; + if ( (_WORD)wParam != 2 ) + return (LRESULT)SDlgDefDialogProc(hWnd, Msg, (HDC)wParam, (HWND)lParam); + } +LABEL_25: + OkCancel_PlaySndEndDlg(hWnd, v6); + return (LRESULT)SDlgDefDialogProc(hWnd, Msg, (HDC)wParam, (HWND)lParam); + } + Focus_CheckPlayMove(lParam); + Focus_DoBlitSpinIncFrame(hWnd, (HWND)lParam); + SelList_GetHeroStats(hWnd, (unsigned short)wParam); +LABEL_23: + SelList_CountHeroList(hWnd); + return (LRESULT)SDlgDefDialogProc(hWnd, Msg, (HDC)wParam, (HWND)lParam); + case 2u: + SelList_DeleteFreeProcs(hWnd); + return (LRESULT)SDlgDefDialogProc(hWnd, Msg, (HDC)wParam, (HWND)lParam); + case 6u: + if ( (_WORD)wParam == 1 || (_WORD)wParam == 2 ) + SelList_LoadFocus16(hWnd); + else + SelList_KillFocus16(hWnd); + return 0; + case 0x100u: + if ( wParam != 46 ) + return (LRESULT)SDlgDefDialogProc(hWnd, Msg, (HDC)wParam, (HWND)lParam); + v5 = SelHero_GetHeroNameStr(); + if ( !strlen(v5) ) + return (LRESULT)SDlgDefDialogProc(hWnd, Msg, (HDC)wParam, (HWND)lParam); + v6 = 1006; + goto LABEL_25; + } + if ( Msg <= 0x103 ) + return (LRESULT)SDlgDefDialogProc(hWnd, Msg, (HDC)wParam, (HWND)lParam); + if ( Msg <= 0x105 ) + { + v4 = (HWND)SDrawGetFrameWindow(NULL); + SendMessageA(v4, Msg, wParam, lParam); + return (LRESULT)SDlgDefDialogProc(hWnd, Msg, (HDC)wParam, (HWND)lParam); + } + if ( Msg != 272 ) + return (LRESULT)SDlgDefDialogProc(hWnd, Msg, (HDC)wParam, (HWND)lParam); + SelList_ShowListWindow(hWnd); + return 0; +} +// 10010382: using guessed type _DWORD __stdcall SDrawGetFrameWindow(); + +// ref: 0x1000D916 +void __fastcall SelList_DeleteFreeProcs(HWND hWnd) +{ + HWND v2; // eax + + Sbar_FreeScrollBar(hWnd, 1105); + Doom_DeleteFreeProcs(hWnd, sellist_msgtbl4); + Doom_DeleteFreeProcs(hWnd, sellist_msgtbl3); + Doom_DeleteFreeProcs(hWnd, sellist_msgtbl2); + Doom_DeleteFreeProcs(hWnd, sellist_msgtbl1); + v2 = GetParent(hWnd); + SelHero_SetStringWithMsg(v2, 0); +} + +// ref: 0x1000D964 +void __fastcall SelList_GetHeroStats(HWND hWnd, int nIDDlgItem) +{ + HWND v2; // ebp + HWND v3; // eax + int v4; // eax + HWND v5; // eax + int v6; // eax + HWND v7; // eax + int v8; // eax + HWND v9; // eax + int v10; // eax + HWND v11; // eax + int v12; // eax + HWND v14; // eax + LONG v15; // eax + _uiheroinfo *v16; // edi + HWND v17; // eax + HWND v18; // eax + + v14 = GetDlgItem(hWnd, nIDDlgItem); + if ( v14 ) + { + v15 = GetWindowLongA(v14, -21); + if ( v15 ) + { + v16 = *(_uiheroinfo **)(v15 + 12); + if ( v16 ) + { + if ( v16->level ) + Doom_ParseWndProc2(hWnd, sellist_msgtbl3, 4, 0); + else + Doom_ParseWndProc2(hWnd, sellist_msgtbl3, 5, 0); + v17 = GetParent(hWnd); + SelHero_PrintHeroInfo(v17, v16); + } + else + { + Doom_ParseWndProc2(hWnd, sellist_msgtbl3, 5, 0); + v18 = GetParent(hWnd); + selhero_hero_hassaved = 0; + selhero_heronamestr[0] = 0; + v2 = v18; + v3 = GetDlgItem(v18, 1014); + v4 = GetWindowLongA(v3, -21); + local_SetWndLongStr(v4, "--"); + v5 = GetDlgItem(v2, 1018); + v6 = GetWindowLongA(v5, -21); + local_SetWndLongStr(v6, "--"); + v7 = GetDlgItem(v2, 1017); + v8 = GetWindowLongA(v7, -21); + local_SetWndLongStr(v8, "--"); + v9 = GetDlgItem(v2, 1016); + v10 = GetWindowLongA(v9, -21); + local_SetWndLongStr(v10, "--"); + v11 = GetDlgItem(v2, 1015); + v12 = GetWindowLongA(v11, -21); + local_SetWndLongStr(v12, "--"); + SelHero_SetStaticBMP(v2, 3); + Doom_ParseWndProc4(v2, selhero_msgtbl_info, 1); + } + } + } +} +// 1002A424: using guessed type int selhero_hero_hassaved; + +// ref: 0x1000D9CF +void __fastcall SelList_CountHeroList(HWND hWnd) +{ + HWND v2; // eax + int v3; // ST04_4 + int v4; // eax + + v2 = GetFocus(); + v3 = SelList_GetNextHeroLong(v2); + v4 = SelHero_GetNumHeroesLeft(); + Sbar_DrawScrollBar(hWnd, 1105, v4, v3); +} + +// ref: 0x1000D9F4 +int __fastcall SelList_GetNextHeroLong(HWND hWnd) +{ + LONG v1; // esi + _uiheroinfo *v2; // eax + _uiheroinfo *v3; // esi + int v5; // ecx + + if ( !hWnd ) + return 0; + v1 = GetWindowLongA(hWnd, -21); + if ( !v1 ) + return 0; + v2 = SelHero_GetCurrentHeroInfo(); + if ( !v2 ) + return 0; + v3 = *(_uiheroinfo **)(v1 + 12); + if ( !v3 ) + return 0; + v5 = 0; + do + { + if ( v2 == v3 ) + break; + v2 = v2->next; + ++v5; + } + while ( v2 ); + return v5; +} + +// ref: 0x1000DA2D +void __fastcall SelList_LoadFocus16(HWND hWnd) +{ + Focus_LoadSpinner("ui_art\\focus16.pcx"); + SDlgSetTimer((int)hWnd, 1, 55, 0); +} + +// ref: 0x1000DA48 +void __fastcall SelList_KillFocus16(HWND hWnd) +{ + SDlgKillTimer((int)hWnd, 1); + Focus_DeleteSpinners(); +} + +// ref: 0x1000DA55 +void __fastcall SelList_ShowListWindow(HWND hWnd) +{ + HWND v2; // edi + LONG v3; // eax + HWND v4; // eax + char Buffer[32]; // [esp+8h] [ebp-20h] + + v2 = GetParent(hWnd); + SelList_DoListOldProc(hWnd); + if ( SelHero_GetHeroIsGood() == 1 ) + LoadStringA(ghUiInst, 0x1Cu, Buffer, 31); + else + LoadStringA(ghUiInst, 0x1Du, Buffer, 31); + SelHero_SetStringWithMsg(v2, Buffer); + v3 = GetWindowLongA(v2, -21); + SetWindowLongA(hWnd, -21, v3); + Doom_ParseWndProc3(hWnd, sellist_msgtbl1, 5); + Doom_ParseWndProcs(hWnd, sellist_msgtbl2, 4, 0); + Doom_ParseWndProcs(hWnd, sellist_msgtbl3, 4, 0); + Doom_ParseWndProcs(hWnd, sellist_msgtbl4, 2, 1); + sellist_pheroinfo = SelHero_GetCurrentHeroInfo(); + SelList_SetHeroDlgLong(hWnd, sellist_pheroinfo); + Sbar_LoadScrBarGFX(hWnd, 1105); + if ( SelHero_GetNumHeroesLeft() <= 6 ) + { + v4 = GetDlgItem(hWnd, 1105); + ShowWindow(v4, 0); + } +} + +// ref: 0x1000DB2C +void __fastcall SelList_SetHeroDlgLong(HWND hWnd, _uiheroinfo *pInfo) +{ + int *i; // ebp + HWND v4; // eax MAPDST + int v6; // esi + + for ( i = sellist_msgtbl4; *i; ++i ) + { + v4 = GetDlgItem(hWnd, *i); + if ( v4 ) + { + if ( pInfo ) + { + EnableWindow(v4, 1); + v6 = GetWindowLongA(v4, -21); + local_SetWndLongStr(v6, pInfo->name); + if ( v6 ) + *(_DWORD *)(v6 + 12) = (unsigned int)pInfo; + pInfo = pInfo->next; + } + else + { + EnableWindow(v4, 0); + } + } + } + Doom_ParseWndProc2(hWnd, sellist_msgtbl4, 2, 1); +} + +// ref: 0x1000DBAC +void __fastcall SelList_DoListOldProc(HWND hWnd) +{ + int *i; // edi + HWND v3; // eax MAPDST + void *v5; // eax + + for ( i = sellist_msgtbl4; *i; ++i ) + { + v3 = GetDlgItem(hWnd, *i); + if ( v3 ) + { + v5 = (void *)GetWindowLongA(v3, -4); + SetPropA(v3, "UIOLDPROC", v5); + SetWindowLongA(v3, -4, (LONG)SelList_OldListWndProc); + } + } +} + +// ref: 0x1000DBFE +LRESULT __stdcall SelList_OldListWndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) +{ + LRESULT (__stdcall *v4)(HWND, UINT, WPARAM, LPARAM); // edi + HWND v5; // eax + UINT v7; // [esp-Ch] [ebp-18h] + WPARAM v8; // [esp-8h] [ebp-14h] + LPARAM v9; // [esp-4h] [ebp-10h] + + v4 = (LRESULT (__stdcall *)(HWND, UINT, WPARAM, LPARAM))GetPropA(hWnd, "UIOLDPROC"); + switch ( Msg ) + { + case 2u: + RemovePropA(hWnd, "UIOLDPROC"); + if ( !v4 ) + return DefWindowProcA(hWnd, Msg, wParam, lParam); + SetWindowLongA(hWnd, -4, (LONG)v4); + break; + case 0xFu: + local_DlgDoPaint(hWnd); + return 0; + case 0x87u: + return 4; + case 0x100u: + if ( wParam > 0x21 ) + { + if ( wParam == 34 ) + { + SelList_HeroesWithBigDialogs(hWnd); + return 0; + } + if ( wParam > 0x24 ) + { + if ( wParam <= 0x26 ) + { + SelList_HeroDlgWithSnd2(hWnd); + return 0; + } + if ( wParam <= 0x28 ) + { + SelList_HeroDlgWithSound(hWnd); + return 0; + } + if ( wParam == 46 ) + { + v9 = lParam; + v8 = 46; + v7 = 256; + goto LABEL_24; + } + } + } + else + { + switch ( wParam ) + { + case 0x21u: + SelList_HeroesWithHugeDlg(hWnd); + break; + case 9u: + if ( GetKeyState(16) >= 0 ) + SelList_ShiftHeroDlgItems(hWnd); + else + SelList_ShiftHeroDlgItm2(hWnd); + return 0; + case 0xDu: + goto LABEL_38; + case 0x1Bu: + v9 = 0; + v8 = 2; + goto LABEL_12; + case 0x20u: +LABEL_38: + v9 = 0; + v8 = 1; +LABEL_12: + v7 = 273; +LABEL_24: + v5 = GetParent(hWnd); + SendMessageA(v5, v7, v8, v9); + return 0; + } + } + return 0; + } + if ( v4 ) + return CallWindowProcA(v4, hWnd, Msg, wParam, lParam); + return DefWindowProcA(hWnd, Msg, wParam, lParam); +} + +// ref: 0x1000DD36 +void __fastcall SelList_ShiftHeroDlgItems(HWND hWnd) +{ + HWND v2; // ebx + int nIDDlgItem[1053]; // [esp+0h] [ebp-1074h] + + nIDDlgItem[1047] = 1048; + nIDDlgItem[1048] = 1049; + nIDDlgItem[1049] = 1050; + nIDDlgItem[1050] = 1051; + nIDDlgItem[1051] = 1052; + nIDDlgItem[1052] = 1047; + v2 = GetParent(hWnd); + do + { + nIDDlgItem[1044] = nIDDlgItem[GetWindowLongA(hWnd, -12)]; + hWnd = GetDlgItem(v2, nIDDlgItem[1044]); + } + while ( !IsWindowEnabled(hWnd) ); + SetFocus(hWnd); +} + +// ref: 0x1000DDA7 +void __fastcall SelList_ShiftHeroDlgItm2(HWND hWnd) +{ + HWND v2; // ebx + int nIDDlgItem[1053]; // [esp+0h] [ebp-1074h] + + nIDDlgItem[1047] = 1052; + nIDDlgItem[1048] = 1047; + nIDDlgItem[1049] = 1048; + nIDDlgItem[1050] = 1049; + nIDDlgItem[1051] = 1050; + nIDDlgItem[1052] = 1051; + v2 = GetParent(hWnd); + do + { + nIDDlgItem[1044] = nIDDlgItem[GetWindowLongA(hWnd, -12)]; + hWnd = GetDlgItem(v2, nIDDlgItem[1044]); + } + while ( !IsWindowEnabled(hWnd) ); + SetFocus(hWnd); +} + +// ref: 0x1000DE18 +void __fastcall SelList_HeroesWithBigDialogs(HWND hWnd) +{ + HWND v1; // eax MAPDST + HWND v3; // ebp + HWND v4; // eax + LONG v5; // eax + _uiheroinfo *v6; // eax + int v7; // esi + _uiheroinfo *v8; // esi + int v9; // eax + + v1 = GetParent(hWnd); + if ( v1 ) + { + v3 = GetDlgItem(v1, 1047); + if ( v3 ) + { + v4 = GetDlgItem(v1, 1052); + v5 = GetWindowLongA(v4, -21); + if ( v5 ) + { + v6 = *(_uiheroinfo **)(v5 + 12); + if ( v6 && v6->next ) + { + v7 = SelList_GetNextHeroLong(v3) + 6; + if ( v7 > SelHero_GetNumHeroesLeft() - 6 ) + v7 = SelHero_GetNumHeroesLeft() - 6; + v8 = SelList_GetHeroFromNum(v7); + if ( v8 ) + { + TitleSnd_PlayMoveSound(); + SelList_SetHeroDlgLong(v1, v8); + v9 = GetWindowLongA(hWnd, -12); + SelList_GetHeroStats(v1, v9); + SelList_CountHeroList(v1); + } + } + else + { + SelList_ShiftHeroDlgItm2(v3); + } + } + } + } +} + +// ref: 0x1000DEDD +_uiheroinfo *__fastcall SelList_GetHeroFromNum(int heronum) +{ + _uiheroinfo *result; // eax + + result = SelHero_GetCurrentHeroInfo(); + while ( result && heronum ) + { + result = result->next; + --heronum; + } + return result; +} + +// ref: 0x1000DEF4 +void __fastcall SelList_HeroesWithHugeDlg(HWND hWnd) +{ + HWND v1; // eax MAPDST + HWND v3; // eax MAPDST + LONG v5; // eax + _uiheroinfo *v6; // ebp + HWND v7; // eax + int v8; // eax + _uiheroinfo *v9; // edi + int v10; // eax + + v1 = GetParent(hWnd); + if ( v1 ) + { + v3 = GetDlgItem(v1, 1047); + if ( v3 ) + { + v5 = GetWindowLongA(v3, -21); + if ( v5 ) + { + v6 = *(_uiheroinfo **)(v5 + 12); + if ( v6 ) + { + if ( v6 == SelHero_GetCurrentHeroInfo() ) + { + v7 = GetDlgItem(v1, 1052); + SelList_ShiftHeroDlgItems(v7); + } + else + { + v8 = SelList_GetNextHeroLong(v3) - 6; + if ( v8 < 0 ) + v8 = 0; + v9 = SelList_GetHeroFromNum(v8); + if ( v9 ) + { + TitleSnd_PlayMoveSound(); + SelList_SetHeroDlgLong(v1, v9); + v10 = GetWindowLongA(hWnd, -12); + SelList_GetHeroStats(v1, v10); + SelList_CountHeroList(v1); + } + } + } + } + } + } +} + +// ref: 0x1000DFAB +void __fastcall SelList_HeroDlgWithSound(HWND hWnd) +{ + LONG v2; // eax + _uiheroinfo *v3; // eax + HWND v4; // eax + HWND v5; // eax + LONG v6; // eax + _uiheroinfo *v7; // ebp + HWND v8; // eax + int v9; // ebx + HWND v10; // eax + HWND v11; // eax + + v2 = GetWindowLongA(hWnd, -21); + if ( v2 ) + { + v3 = *(_uiheroinfo **)(v2 + 12); + if ( v3 ) + { + if ( v3->next ) + { + if ( GetWindowLongA(hWnd, -12) >= 1052 ) + { + v4 = GetParent(hWnd); + v5 = GetDlgItem(v4, 1048); + if ( v5 ) + { + v6 = GetWindowLongA(v5, -21); + if ( v6 ) + { + v7 = *(_uiheroinfo **)(v6 + 12); + if ( v7 ) + { + TitleSnd_PlayMoveSound(); + v8 = GetParent(hWnd); + SelList_SetHeroDlgLong(v8, v7); + v9 = GetWindowLongA(hWnd, -12); + v10 = GetParent(hWnd); + SelList_GetHeroStats(v10, v9); + v11 = GetParent(hWnd); + SelList_CountHeroList(v11); + } + } + } + } + else + { + SelList_ShiftHeroDlgItems(hWnd); + } + } + } + } +} + +// ref: 0x1000E043 +void __fastcall SelList_HeroDlgWithSnd2(HWND hWnd) +{ + LONG v2; // eax + _uiheroinfo *v3; // esi + _uiheroinfo *v4; // ebx + HWND v5; // eax + int v6; // ebx + HWND v7; // eax + HWND v8; // eax + + if ( GetWindowLongA(hWnd, -12) <= 1047 ) + { + v2 = GetWindowLongA(hWnd, -21); + if ( v2 ) + { + v3 = *(_uiheroinfo **)(v2 + 12); + if ( v3 ) + { + v4 = SelHero_GetCurrentHeroInfo(); + if ( v3 != v4 ) + { + while ( v4 && v4->next != v3 ) + v4 = v4->next; + TitleSnd_PlayMoveSound(); + v5 = GetParent(hWnd); + SelList_SetHeroDlgLong(v5, v4); + v6 = GetWindowLongA(hWnd, -12); + v7 = GetParent(hWnd); + SelList_GetHeroStats(v7, v6); + v8 = GetParent(hWnd); + SelList_CountHeroList(v8); + } + } + } + } + else + { + SelList_ShiftHeroDlgItm2(hWnd); + } +} + +// ref: 0x1000E0CA +void __fastcall SelList_ChooseDlgFromSize(HWND hWnd, int width, int height) +{ + HWND v6; // eax + int v7; // edx + HWND v8; // eax + HWND v9; // eax + char *v10; // eax + HWND v11; // eax + HWND v12; // eax + int v13; // eax + int v14; // eax + int v15; // eax + HWND v16; // eax + HWND v17; // eax + HWND v18; // eax + HWND v19; // eax + + v6 = GetDlgItem(hWnd, 1056); + if ( local_GetBottomRect(hWnd, v6, width, height) ) + { + v7 = 1; +LABEL_3: + OkCancel_PlaySndEndDlg(hWnd, v7); + return; + } + v8 = GetDlgItem(hWnd, 1054); + if ( local_GetBottomRect(hWnd, v8, width, height) ) + { + v7 = 2; + goto LABEL_3; + } + v9 = GetDlgItem(hWnd, 1006); + if ( local_GetBottomRect(hWnd, v9, width, height) ) + { + v10 = SelHero_GetHeroNameStr(); + if ( strlen(v10) ) + { + v7 = 1006; + goto LABEL_3; + } + } + else + { + v11 = GetDlgItem(hWnd, 1105); + if ( local_GetBottomRect(hWnd, v11, width, height) ) + { + v12 = GetDlgItem(hWnd, 1105); + v13 = Sbar_NumScrollLines(v12, width, height) - 1; + if ( v13 ) + { + v14 = v13 - 1; + if ( v14 ) + { + v15 = v14 - 1; + if ( v15 ) + { + if ( v15 == 1 ) + { + v16 = GetFocus(); + SelList_HeroesWithBigDialogs(v16); + } + } + else + { + v17 = GetFocus(); + SelList_HeroesWithHugeDlg(v17); + } + } + else + { + v18 = GetFocus(); + SelList_HeroDlgWithSound(v18); + } + } + else + { + v19 = GetFocus(); + SelList_HeroDlgWithSnd2(v19); + } + } + } +} diff --git a/2020_03_31/DiabloUI/selload.cpp b/2020_03_31/DiabloUI/selload.cpp new file mode 100644 index 00000000..5cdbec3b --- /dev/null +++ b/2020_03_31/DiabloUI/selload.cpp @@ -0,0 +1,134 @@ +// ref: 0x1000E1C2 +LRESULT __stdcall SelLoad_WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) +{ + HWND v4; // eax + int v5; // edx + HWND v6; // eax + HWND v7; // eax + HWND v9; // eax + + if ( Msg == 2 ) + { + SelLoad_DeleteProcsAndSpin(hWnd); + return (LRESULT)SDlgDefDialogProc(hWnd, Msg, (HDC)wParam, (HWND)lParam); + } + if ( Msg <= 0x103 ) + return (LRESULT)SDlgDefDialogProc(hWnd, Msg, (HDC)wParam, (HWND)lParam); + if ( Msg <= 0x105 ) + { + v9 = (HWND)SDrawGetFrameWindow(NULL); + SendMessageA(v9, Msg, wParam, lParam); + return (LRESULT)SDlgDefDialogProc(hWnd, Msg, (HDC)wParam, (HWND)lParam); + } + if ( Msg == 272 ) + { + SelLoad_LoadFocusAndMsg(hWnd); + return 0; + } + if ( Msg != 273 ) + { + if ( Msg != 275 ) + { + if ( Msg == 513 ) + { + v4 = GetDlgItem(hWnd, 1056); + if ( local_GetBottomRect(hWnd, v4, (unsigned short)lParam, (unsigned int)lParam >> 16) ) + { + v5 = 1; +LABEL_19: + SelLoad_SelectSndLoad(hWnd, v5); + return (LRESULT)SDlgDefDialogProc(hWnd, Msg, (HDC)wParam, (HWND)lParam); + } + v6 = GetDlgItem(hWnd, 1054); + if ( local_GetBottomRect(hWnd, v6, (unsigned short)lParam, (unsigned int)lParam >> 16) ) + { +LABEL_21: + v5 = 2; + goto LABEL_19; + } + } + return (LRESULT)SDlgDefDialogProc(hWnd, Msg, (HDC)wParam, (HWND)lParam); + } + v7 = GetFocus(); + Focus_DoBlitSpinIncFrame(hWnd, v7); + return 0; + } + if ( HIWORD(wParam) == 7 ) + { + Focus_GetAndBlitSpin(hWnd, lParam); + } + else + { + if ( HIWORD(wParam) != 6 ) + { + v5 = 1; + if ( HIWORD(wParam) == 5 || (_WORD)wParam == 1 ) + goto LABEL_19; + if ( (_WORD)wParam != 2 ) + return (LRESULT)SDlgDefDialogProc(hWnd, Msg, (HDC)wParam, (HWND)lParam); + goto LABEL_21; + } + Focus_CheckPlayMove(lParam); + Focus_DoBlitSpinIncFrame(hWnd, (HWND)lParam); + } + return (LRESULT)SDlgDefDialogProc(hWnd, Msg, (HDC)wParam, (HWND)lParam); +} +// 10010382: using guessed type _DWORD __stdcall SDrawGetFrameWindow(); + +// ref: 0x1000E30E +void __fastcall SelLoad_DeleteProcsAndSpin(HWND hWnd) +{ + HWND v2; // eax + + Focus_DeleteSpinners(); + Doom_DeleteFreeProcs(hWnd, selload_msgtbl3); + Doom_DeleteFreeProcs(hWnd, selload_msgtbl2); + Doom_DeleteFreeProcs(hWnd, selload_msgtbl1); + v2 = GetParent(hWnd); + SelHero_SetStringWithMsg(v2, 0); +} + +// ref: 0x1000E34B +void __fastcall SelLoad_LoadFocusAndMsg(HWND hWnd) +{ + HWND v2; // edi + LONG v3; // eax + char Buffer[32]; // [esp+8h] [ebp-20h] + + v2 = GetParent(hWnd); + LoadStringA(ghUiInst, 0x1Du, Buffer, 31); + SelHero_SetStringWithMsg(v2, Buffer); + v3 = GetWindowLongA(v2, -21); + SetWindowLongA(hWnd, -21, v3); + local_DoUiWndProc(hWnd, (DWORD *)selload_msgtbl3); + Doom_ParseWndProc3(hWnd, selload_msgtbl1, 5); + Doom_ParseWndProcs(hWnd, selload_msgtbl2, 4, 0); + Doom_ParseWndProcs(hWnd, selload_msgtbl3, 2, 1); + Focus_LoadSpinner("ui_art\\focus16.pcx"); + SDlgSetTimer((int)hWnd, 1, 55, 0); +} + +// ref: 0x1000E3E2 +void __fastcall SelLoad_SelectSndLoad(HWND hWnd, int a2) +{ + int v2; // esi + HWND v4; // eax + + v2 = a2; + TitleSnd_PlaySelectSound(); + SDlgKillTimer((int)hWnd, 1); + if ( v2 == 1 ) + { + v4 = GetFocus(); + v2 = GetWindowLongA(v4, -12); + } + SDlgEndDialog(hWnd, (HANDLE)v2); +} + +// ref: 0x1000E41A +void __cdecl SelLoad_cpp_init() +{ + SelLoad_cpp_float = SelLoad_cpp_float_value; +} +// 1001F46C: using guessed type int SelLoad_cpp_float_value; +// 1002A4C8: using guessed type int SelLoad_cpp_float; diff --git a/2020_03_31/DiabloUI/selmodem.cpp b/2020_03_31/DiabloUI/selmodem.cpp new file mode 100644 index 00000000..3b20b82c --- /dev/null +++ b/2020_03_31/DiabloUI/selmodem.cpp @@ -0,0 +1,893 @@ +// ref: 0x1000E42A +signed int SelModem_1000E42A() { return 0; } +/* { + signed int result; // eax + + result = 2139095040; + dword_1002A4CC = 2139095040; + return result; +} */ +// 1002A4CC: using guessed type int dword_1002A4CC; + +// ref: 0x1000E435 +int __fastcall SelModem_1000E435(void *a1, int a2, int a3, char *a4, char *a5) { return 0; } +/* { + void *v5; // edi + + dword_1002A4DC = 0; + dword_1002A4D8 = 0; + dword_1002A4E8 = a3; + dword_1002A4D4 = a4; + v5 = a1; + dword_1002A4E0 = a2; + dword_1002A4D0 = (int)a5; + SNetEnumDevices(SelModem_1000E497); + if ( !dword_1002A4D8 ) + return SelModem_1000E505(v5); + if ( dword_1002A4D8 == 1 ) + return SelModem_1000E51E(); + return SelModem_1000E5CC(); +} */ +// 10010496: using guessed type int __stdcall SNetEnumDevices(_DWORD); +// 1002A4D0: using guessed type int dword_1002A4D0; +// 1002A4DC: using guessed type int dword_1002A4DC; +// 1002A4E0: using guessed type int dword_1002A4E0; +// 1002A4E8: using guessed type int dword_1002A4E8; + +// ref: 0x1000E497 +char *__stdcall SelModem_1000E497(int a1, char *a2, char *a3) { return 0; } +/* { + int result; // eax + int v4; // esi + _DWORD *v5; // eax + + result = SelModem_1000E4EC(); + v4 = result; + if ( result ) + { + *(_DWORD *)result = 0; + *(_DWORD *)(result + 4) = a1; + strcpy((char *)(result + 8), a2); + strcpy((char *)(v4 + 136), a3); + v5 = SelModem_1000E500(dword_1002A4DC, (_DWORD *)v4); + ++dword_1002A4D8; + dword_1002A4DC = (int)v5; + result = 1; + } + return result; +} */ +// 1002A4DC: using guessed type int dword_1002A4DC; + +// ref: 0x1000E4EC +void *SelModem_1000E4EC() { return 0; } +/* { + return SMemAlloc(264, "C:\\Src\\Diablo\\DiabloUI\\SelModem.cpp", 72, 0); +} */ +// 10010364: using guessed type int __stdcall SMemAlloc(_DWORD, _DWORD, _DWORD, _DWORD); + +// ref: 0x1000E500 +_DWORD *__fastcall SelModem_1000E500(int a1, _DWORD *a2) { return 0; } +/* { + _DWORD *result; // eax + + result = a2; + *a2 = a1; + return result; +} */ + +// ref: 0x1000E505 +signed int UNKCALL SelModem_1000E505(void *arg) { return 0; } +/* { + if ( arg != (void *)1297040461 ) + return 1; + SErrSetLastError(1222); + return 0; +} */ +// 1001041E: using guessed type int __stdcall SErrSetLastError(_DWORD); + +// ref: 0x1000E51E +signed int SelModem_1000E51E() { return 0; } +/* { + signed int result; // eax + + if ( SelModem_1000E57B(*((_DWORD *)dword_1002A4D4 + 2), *(_DWORD *)(dword_1002A4DC + 4)) ) + { + SelModem_1000E553((_DWORD *)dword_1002A4DC); + result = 1; + } + else + { + SErrSetLastError(-2062548879); + result = 0; + } + return result; +} */ +// 1001041E: using guessed type int __stdcall SErrSetLastError(_DWORD); +// 1002A4DC: using guessed type int dword_1002A4DC; + +// ref: 0x1000E553 +int __fastcall SelModem_1000E553(_DWORD *a1) { return 0; } +/* { + _DWORD *v1; // esi + int result; // eax + + if ( a1 ) + { + do + { + v1 = (_DWORD *)*a1; + result = SelModem_1000E567(a1); + a1 = v1; + } + while ( v1 ); + } + return result; +} */ + +// ref: 0x1000E567 +int UNKCALL SelModem_1000E567(void *arg) { return 0; } +/* { + int result; // eax + + if ( arg ) + result = SMemFree(arg, "C:\\Src\\Diablo\\DiabloUI\\SelModem.cpp", 77, 0); + return result; +} */ +// 10010340: using guessed type int __stdcall SMemFree(_DWORD, _DWORD, _DWORD, _DWORD); + +// ref: 0x1000E57B +int __fastcall SelModem_1000E57B(int a1, int a2) { return 0; } +/* { + int v2; // ebx + int v3; // esi + int v5; // [esp+8h] [ebp-50h] + int v6; // [esp+10h] [ebp-48h] + int (__stdcall *v7)(char *, int, int, int, int); // [esp+30h] [ebp-28h] + + v2 = a2; + v3 = a1; + memcpy(&v5, dword_1002A4D4, 0x50u); + v7 = ModmStat_10008C62; + v5 = 80; + v6 = v3; + return SNetInitializeDevice(v2, dword_1002A4E0, dword_1002A4E8, &v5, dword_1002A4D0); +} */ +// 1001049C: using guessed type int __stdcall SNetInitializeDevice(_DWORD, _DWORD, _DWORD, _DWORD, _DWORD); +// 1002A4D0: using guessed type int dword_1002A4D0; +// 1002A4E0: using guessed type int dword_1002A4E0; +// 1002A4E8: using guessed type int dword_1002A4E8; + +// ref: 0x1000E5CC +signed int SelModem_1000E5CC() { return 0; } +/* { + signed int v0; // esi + signed int result; // eax + + v0 = 1; + if ( SDlgDialogBoxParam(hInstance, "SELMODEM_DIALOG", *((_DWORD *)dword_1002A4D4 + 2), SelModem_1000E63E, 0) == 1 ) + { + if ( !SelModem_1000E57B(*((_DWORD *)dword_1002A4D4 + 2), dword_1002A4E4) ) + { + SErrSetLastError(-2062548879); + v0 = 0; + } + SelModem_1000E553((_DWORD *)dword_1002A4DC); + result = v0; + } + else + { + SelModem_1000E553((_DWORD *)dword_1002A4DC); + SErrSetLastError(1223); + result = 0; + } + return result; +} */ +// 10010370: using guessed type int __stdcall SDlgDialogBoxParam(_DWORD, _DWORD, _DWORD, _DWORD, _DWORD); +// 1001041E: using guessed type int __stdcall SErrSetLastError(_DWORD); +// 1002A4DC: using guessed type int dword_1002A4DC; +// 1002A4E4: using guessed type int dword_1002A4E4; + +// ref: 0x1000E63E +int __stdcall SelModem_1000E63E(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam) { return 0; } +/* { + int v4; // edx + HWND v5; // eax + HWND v7; // eax + int v8; // [esp+0h] [ebp-Ch] + + if ( Msg > 0x201 ) + { + if ( Msg == 514 ) + { + v7 = GetDlgItem(hDlg, 1105); + if ( !Sbar_100099C0(v7) ) + return SDlgDefDialogProc(hDlg, Msg, wParam, lParam); +LABEL_27: + SelModem_1000E7E9(hDlg); + return SDlgDefDialogProc(hDlg, Msg, wParam, lParam); + } + if ( Msg != 515 ) + { + if ( Msg != 2024 ) + return SDlgDefDialogProc(hDlg, Msg, wParam, lParam); + if ( !Fade_1000739F() ) + Fade_100073FD(hDlg, v8); + return 0; + } +LABEL_25: + SelModem_1000EE78(hDlg, (unsigned short)lParam, (unsigned int)lParam >> 16); + return SDlgDefDialogProc(hDlg, Msg, wParam, lParam); + } + if ( Msg == 513 ) + goto LABEL_25; + if ( Msg == 2 ) + { + SelModem_1000E783(hDlg); + return SDlgDefDialogProc(hDlg, Msg, wParam, lParam); + } + if ( Msg <= 0x103 ) + return SDlgDefDialogProc(hDlg, Msg, wParam, lParam); + if ( Msg <= 0x105 ) + { + v5 = (HWND)SDrawGetFrameWindow(); + SendMessageA(v5, Msg, wParam, lParam); + return SDlgDefDialogProc(hDlg, Msg, wParam, lParam); + } + if ( Msg == 272 ) + { + SelModem_1000E843(hDlg); + return 0; + } + if ( Msg == 273 ) + { + if ( HIWORD(wParam) == 7 ) + { + Focus_100075B7(hDlg, (HWND)lParam); + return SDlgDefDialogProc(hDlg, Msg, wParam, lParam); + } + if ( HIWORD(wParam) == 6 ) + { + Focus_10007458((void *)lParam); + Focus_100075DC(hDlg, (HWND)lParam); + goto LABEL_27; + } + v4 = 1; + if ( wParam != 327681 ) + { + if ( (_WORD)wParam != 2 ) + return SDlgDefDialogProc(hDlg, Msg, wParam, lParam); + v4 = 2; + } + SelModem_1000EE29((int)hDlg, v4); + } + return SDlgDefDialogProc(hDlg, Msg, wParam, lParam); +} */ +// 1001037C: using guessed type int __stdcall SDlgDefDialogProc(_DWORD, _DWORD, _DWORD, _DWORD); +// 10010382: using guessed type _DWORD __stdcall SDrawGetFrameWindow(); + +// ref: 0x1000E783 +void UNKCALL SelModem_1000E783(HWND hDlg) { return; } +/* { + HWND v1; // esi + _DWORD *v2; // eax + + v1 = hDlg; + Sbar_10009CD2(hDlg, 1105); + Doom_10006C53(v1, &dword_100231F4); + Doom_10006C53(v1, (int *)&unk_100231E8); + Doom_10006C53(v1, (int *)&unk_100231CC); + Doom_10006C53(v1, (int *)&unk_100231D4); + Doom_10006C53(v1, (int *)&unk_100231E0); + Focus_10007818(v1); + local_1000811B(); + v2 = (_DWORD *)GetWindowLongA(v1, -21); + local_10007F72(v2); +} */ +// 100231F4: using guessed type int dword_100231F4; + +// ref: 0x1000E7E9 +HWND UNKCALL SelModem_1000E7E9(HWND hDlg) { return 0; } +/* { + HWND v1; // esi + HWND v2; // eax + int v3; // eax + + v1 = hDlg; + v2 = GetFocus(); + v3 = SelModem_1000E80E(v2); + return Sbar_10009A99(v1, 1105, dword_1002A4D8, v3); +} */ + +// ref: 0x1000E80E +int UNKCALL SelModem_1000E80E(HWND hWnd) { return 0; } +/* { + LONG v1; // eax + _DWORD *v2; // ecx + _DWORD *v3; // eax + int v5; // edx + + if ( !hWnd ) + return 0; + v1 = GetWindowLongA(hWnd, -21); + if ( !v1 ) + return 0; + v2 = (_DWORD *)dword_1002A4DC; + if ( !dword_1002A4DC ) + return 0; + v3 = *(_DWORD **)(v1 + 12); + if ( !v3 ) + return 0; + v5 = 0; + do + { + if ( v2 == v3 ) + break; + v2 = (_DWORD *)*v2; + ++v5; + } + while ( v2 ); + return v5; +} */ +// 1002A4DC: using guessed type int dword_1002A4DC; + +// ref: 0x1000E843 +HWND UNKCALL SelModem_1000E843(HWND hWnd) { return 0; } +/* { + HWND v1; // esi + int v2; // eax + int *v3; // edi + HWND result; // eax + HWND v5; // eax + HWND v6; // [esp+0h] [ebp-Ch] + + v1 = hWnd; + GetParent(hWnd); + SelModem_1000E9B2(v1); + Focus_100077E9((int)v1, "ui_art\\focus16.pcx", v6); + local_100080F1(); + v2 = local_10007F46(); + v3 = (int *)v2; + if ( v2 ) + { + SetWindowLongA(v1, -21, v2); + local_10007944((int)v1, 0, "popup", -1, 1, (int)"ui_art\\seldiff.pcx", v3, v3 + 1, 0); + } + Fade_100073C5(v1, 0); + PostMessageA(v1, 0x7E8u, 0, 0); + Doom_100068AB(v1, (int *)&unk_100231E0, 1); + Doom_100068AB(v1, (int *)&unk_100231D4, 3); + Doom_100068AB(v1, (int *)&unk_100231CC, 5); + Doom_1000658C(v1, (int *)&unk_100231E8, 4, 0); + Doom_1000658C(v1, &dword_100231F4, 0, 1); + SelModem_1000E932(v1, (const char *)dword_1002A4DC); + result = Sbar_10009BF1(v1, 1105); + if ( dword_1002A4D8 <= 6 ) + { + v5 = GetDlgItem(v1, 1105); + result = (HWND)ShowWindow(v5, 0); + } + return result; +} */ +// 100231F4: using guessed type int dword_100231F4; +// 1002A4DC: using guessed type int dword_1002A4DC; + +// ref: 0x1000E932 +int __fastcall SelModem_1000E932(HWND a1, const char *a2) { return 0; } +/* { + const char *v2; // edi + int *v3; // ebp + HWND v4; // eax + HWND v5; // esi + int v6; // esi + HWND hDlg; // [esp+8h] [ebp-4h] + + v2 = a2; + hDlg = a1; + v3 = &dword_100231F4; + if ( dword_100231F4 ) + { + do + { + v4 = GetDlgItem(hDlg, *v3); + v5 = v4; + if ( v4 ) + { + if ( v2 ) + { + EnableWindow(v4, 1); + v6 = GetWindowLongA(v5, -21); + local_10007FA4(v6, v2 + 8); + if ( v6 ) + *(_DWORD *)(v6 + 12) = v2; + v2 = *(const char **)v2; + } + else + { + EnableWindow(v4, 0); + } + } + ++v3; + } + while ( *v3 ); + } + return Doom_1000680A(hDlg, &dword_100231F4, 0, 1); +} */ +// 100231F4: using guessed type int dword_100231F4; + +// ref: 0x1000E9B2 +void UNKCALL SelModem_1000E9B2(HWND hDlg) { return; } +/* { + HWND v1; // ebx + int *v2; // edi + HWND v3; // eax + HWND v4; // esi + void *v5; // eax + + v1 = hDlg; + v2 = &dword_100231F4; + if ( dword_100231F4 ) + { + do + { + v3 = GetDlgItem(v1, *v2); + v4 = v3; + if ( v3 ) + { + v5 = (void *)GetWindowLongA(v3, -4); + SetPropA(v4, "UIOLDPROC", v5); + SetWindowLongA(v4, -4, (LONG)SelModem_1000EA04); + } + ++v2; + } + while ( *v2 ); + } +} */ +// 100231F4: using guessed type int dword_100231F4; + +// ref: 0x1000EA04 +LRESULT __stdcall SelModem_1000EA04(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) { return 0; } +/* { + LRESULT (__stdcall *v4)(HWND, UINT, WPARAM, LPARAM); // edi + HWND v5; // eax + WPARAM v7; // [esp-8h] [ebp-14h] + + v4 = (LRESULT (__stdcall *)(HWND, UINT, WPARAM, LPARAM))GetPropA(hWnd, "UIOLDPROC"); + switch ( Msg ) + { + case 2u: + RemovePropA(hWnd, "UIOLDPROC"); + if ( !v4 ) + return DefWindowProcA(hWnd, Msg, wParam, lParam); + SetWindowLongA(hWnd, -4, (LONG)v4); + break; + case 0xFu: + local_10007C95(hWnd); + return 0; + case 0x87u: + return 4; + case 0x100u: + if ( wParam > 0x21 ) + { + if ( wParam == 34 ) + { + SelModem_1000EC0E(hWnd); + } + else if ( wParam > 0x24 ) + { + if ( wParam <= 0x26 ) + { + SelModem_1000EDBC(hWnd); + } + else if ( wParam <= 0x28 ) + { + SelModem_1000ED3B(hWnd); + } + } + return 0; + } + if ( wParam == 33 ) + { + SelModem_1000ECB2(hWnd); + return 0; + } + if ( wParam == 9 ) + { + if ( GetKeyState(16) >= 0 ) + SelModem_1000EB2C(hWnd); + else + SelModem_1000EB9D(hWnd); + return 0; + } + if ( wParam != 13 ) + { + if ( wParam == 27 ) + { + v7 = 2; + goto LABEL_13; + } + if ( wParam != 32 ) + return 0; + } + v7 = 1; +LABEL_13: + v5 = GetParent(hWnd); + SendMessageA(v5, 0x111u, v7, 0); + return 0; + } + if ( v4 ) + return CallWindowProcA(v4, hWnd, Msg, wParam, lParam); + return DefWindowProcA(hWnd, Msg, wParam, lParam); +} */ + +// ref: 0x1000EB2C +HWND UNKCALL SelModem_1000EB2C(HWND hWnd) { return 0; } +/* { + HWND v1; // edi + HWND v2; // ebx + int nIDDlgItem[1107]; // [esp+0h] [ebp-1170h] + int v5; // [esp+114Ch] [ebp-24h] + int v6; // [esp+1158h] [ebp-18h] + int v7; // [esp+115Ch] [ebp-14h] + int v8; // [esp+1160h] [ebp-10h] + int v9; // [esp+1164h] [ebp-Ch] + int v10; // [esp+1168h] [ebp-8h] + int v11; // [esp+116Ch] [ebp-4h] + + v1 = hWnd; + v6 = 1111; + v7 = 1112; + v8 = 1113; + v9 = 1114; + v10 = 1115; + v11 = 1110; + v2 = GetParent(hWnd); + do + { + v5 = nIDDlgItem[GetWindowLongA(v1, -12)]; + v1 = GetDlgItem(v2, v5); + } + while ( !IsWindowEnabled(v1) ); + return SetFocus(v1); +} */ +// 1000EB2C: using guessed type int nIDDlgItem[1107]; + +// ref: 0x1000EB9D +HWND UNKCALL SelModem_1000EB9D(HWND hWnd) { return 0; } +/* { + HWND v1; // edi + HWND v2; // ebx + int nIDDlgItem[1107]; // [esp+0h] [ebp-1170h] + int v5; // [esp+114Ch] [ebp-24h] + int v6; // [esp+1158h] [ebp-18h] + int v7; // [esp+115Ch] [ebp-14h] + int v8; // [esp+1160h] [ebp-10h] + int v9; // [esp+1164h] [ebp-Ch] + int v10; // [esp+1168h] [ebp-8h] + int v11; // [esp+116Ch] [ebp-4h] + + v1 = hWnd; + v6 = 1115; + v7 = 1110; + v8 = 1111; + v9 = 1112; + v10 = 1113; + v11 = 1114; + v2 = GetParent(hWnd); + do + { + v5 = nIDDlgItem[GetWindowLongA(v1, -12)]; + v1 = GetDlgItem(v2, v5); + } + while ( !IsWindowEnabled(v1) ); + return SetFocus(v1); +} */ +// 1000EB9D: using guessed type int nIDDlgItem[1107]; + +// ref: 0x1000EC0E +HWND UNKCALL SelModem_1000EC0E(HWND hWnd) { return 0; } +/* { + HWND result; // eax + HWND v2; // edi + HWND v3; // ebx + HWND v4; // eax + _DWORD *v5; // eax + int v6; // eax + const char *v7; // esi + + result = GetParent(hWnd); + v2 = result; + if ( result ) + { + result = GetDlgItem(result, 1110); + v3 = result; + if ( result ) + { + v4 = GetDlgItem(v2, 1115); + result = (HWND)GetWindowLongA(v4, -21); + if ( result ) + { + v5 = (_DWORD *)*((_DWORD *)result + 3); + if ( v5 && *v5 ) + { + v6 = SelModem_1000E80E(v3) + 6; + if ( v6 > dword_1002A4D8 - 6 ) + v6 = dword_1002A4D8 - 6; + result = (HWND)SelModem_1000EC9F(v6); + v7 = (const char *)result; + if ( result ) + { + TitleSnd_10010315(); + SelModem_1000E932(v2, v7); + result = SelModem_1000E7E9(v2); + } + } + else + { + result = SelModem_1000EB9D(v3); + } + } + } + } + return result; +} */ + +// ref: 0x1000EC9F +_DWORD *__fastcall SelModem_1000EC9F(int a1) { return 0; } +/* { + _DWORD *result; // eax + + result = (_DWORD *)dword_1002A4DC; + while ( result && a1 ) + { + result = (_DWORD *)*result; + --a1; + } + return result; +} */ +// 1002A4DC: using guessed type int dword_1002A4DC; + +// ref: 0x1000ECB2 +HWND UNKCALL SelModem_1000ECB2(HWND hWnd) { return 0; } +/* { + HWND result; // eax + HWND v2; // edi + HWND v3; // esi + HWND v4; // eax + int v5; // eax + const char *v6; // esi + + result = GetParent(hWnd); + v2 = result; + if ( result ) + { + result = GetDlgItem(result, 1110); + v3 = result; + if ( result ) + { + result = (HWND)GetWindowLongA(result, -21); + if ( result ) + { + result = (HWND)*((_DWORD *)result + 3); + if ( result ) + { + if ( result == (HWND)dword_1002A4DC ) + { + v4 = GetDlgItem(v2, 1115); + result = SelModem_1000EB2C(v4); + } + else + { + v5 = SelModem_1000E80E(v3) - 6; + if ( v5 < 0 ) + v5 = 0; + result = (HWND)SelModem_1000EC9F(v5); + v6 = (const char *)result; + if ( result ) + { + TitleSnd_10010315(); + SelModem_1000E932(v2, v6); + result = SelModem_1000E7E9(v2); + } + } + } + } + } + } + return result; +} */ +// 1002A4DC: using guessed type int dword_1002A4DC; + +// ref: 0x1000ED3B +HWND UNKCALL SelModem_1000ED3B(HWND hWnd) { return 0; } +/* { + HWND v1; // edi + HWND result; // eax + HWND v3; // eax + const char *v4; // esi + HWND v5; // eax + HWND v6; // eax + + v1 = hWnd; + result = (HWND)GetWindowLongA(hWnd, -21); + if ( result ) + { + result = (HWND)*((_DWORD *)result + 3); + if ( result ) + { + if ( *(_DWORD *)result ) + { + if ( GetWindowLongA(v1, -12) >= 1115 ) + { + v3 = GetParent(v1); + result = GetDlgItem(v3, 1111); + if ( result ) + { + result = (HWND)GetWindowLongA(result, -21); + if ( result ) + { + v4 = (const char *)*((_DWORD *)result + 3); + if ( v4 ) + { + TitleSnd_10010315(); + v5 = GetParent(v1); + SelModem_1000E932(v5, v4); + v6 = GetParent(v1); + result = SelModem_1000E7E9(v6); + } + } + } + } + else + { + result = SelModem_1000EB2C(v1); + } + } + } + } + return result; +} */ + +// ref: 0x1000EDBC +HWND UNKCALL SelModem_1000EDBC(HWND hWnd) { return 0; } +/* { + HWND v1; // ebx + HWND result; // eax + const char *v3; // esi + HWND v4; // eax + HWND v5; // eax + + v1 = hWnd; + if ( GetWindowLongA(hWnd, -12) > 1110 ) + return SelModem_1000EB9D(v1); + result = (HWND)GetWindowLongA(v1, -21); + if ( result ) + { + result = (HWND)*((_DWORD *)result + 3); + if ( result ) + { + v3 = (const char *)dword_1002A4DC; + if ( result != (HWND)dword_1002A4DC ) + { + while ( v3 && *(HWND *)v3 != result ) + v3 = *(const char **)v3; + TitleSnd_10010315(); + v4 = GetParent(v1); + SelModem_1000E932(v4, v3); + v5 = GetParent(v1); + result = SelModem_1000E7E9(v5); + } + } + } + return result; +} */ +// 1002A4DC: using guessed type int dword_1002A4DC; + +// ref: 0x1000EE29 +int __fastcall SelModem_1000EE29(int a1, int a2) { return 0; } +/* { + int v2; // esi + int v3; // edi + HWND v4; // eax + LONG v5; // eax + int v6; // eax + + v2 = a2; + v3 = a1; + TitleSnd_1001031F(); + if ( v2 == 1 ) + { + v4 = GetFocus(); + if ( v4 ) + { + v5 = GetWindowLongA(v4, -21); + if ( v5 ) + { + v6 = *(_DWORD *)(v5 + 12); + if ( v6 ) + dword_1002A4E4 = *(_DWORD *)(v6 + 4); + } + } + } + Fade_100073B4(); + Fade_100072BE(10); + return SDlgEndDialog(v3, v2); +} */ +// 10010376: using guessed type int __stdcall SDlgEndDialog(_DWORD, _DWORD); +// 1002A4E4: using guessed type int dword_1002A4E4; + +// ref: 0x1000EE78 +HWND __fastcall SelModem_1000EE78(HWND hWnd, int a2, int a3) { return 0; } +/* { + int v3; // ebx + HWND v4; // esi + int v5; // ST08_4 + HWND v6; // eax + int v7; // edx + HWND result; // eax + HWND v9; // eax + HWND v10; // eax + HWND v11; // eax + int v12; // eax + int v13; // eax + int v14; // eax + HWND v15; // eax + HWND v16; // eax + HWND v17; // eax + HWND v18; // eax + + v3 = a2; + v4 = hWnd; + v5 = a2; + v6 = GetDlgItem(hWnd, 1056); + if ( local_10007C3B(v4, v6, v5, a3) ) + { + v7 = 1; + return (HWND)SelModem_1000EE29((int)v4, v7); + } + v9 = GetDlgItem(v4, 1054); + if ( local_10007C3B(v4, v9, v3, a3) ) + { + v7 = 2; + return (HWND)SelModem_1000EE29((int)v4, v7); + } + v10 = GetDlgItem(v4, 1105); + result = (HWND)local_10007C3B(v4, v10, v3, a3); + if ( result ) + { + v11 = GetDlgItem(v4, 1105); + v12 = Sbar_100099DC(v11, v3, a3) - 1; + if ( v12 ) + { + v13 = v12 - 1; + if ( v13 ) + { + v14 = v13 - 1; + if ( v14 ) + { + result = (HWND)(v14 - 1); + if ( !result ) + { + v15 = GetFocus(); + result = SelModem_1000EC0E(v15); + } + } + else + { + v16 = GetFocus(); + result = SelModem_1000ECB2(v16); + } + } + else + { + v17 = GetFocus(); + result = SelModem_1000ED3B(v17); + } + } + else + { + v18 = GetFocus(); + result = SelModem_1000EDBC(v18); + } + } + return result; +} */ diff --git a/2020_03_31/DiabloUI/selregn.cpp b/2020_03_31/DiabloUI/selregn.cpp new file mode 100644 index 00000000..306a60fb --- /dev/null +++ b/2020_03_31/DiabloUI/selregn.cpp @@ -0,0 +1,892 @@ +// ref: 0x1000EF42 +void *SelRegn_1000EF42() { return 0; } +/* { + return SMemAlloc(136, "C:\\Src\\Diablo\\DiabloUI\\SelRegn.cpp", 76, 0); +} */ +// 10010364: using guessed type int __stdcall SMemAlloc(_DWORD, _DWORD, _DWORD, _DWORD); + +// ref: 0x1000EF56 +_uiheroinfo *__fastcall SelRegn_SetNextHero(_uiheroinfo *pNext, _uiheroinfo *pCurrent) +{ + _uiheroinfo *result; // eax + + result = pCurrent; + pCurrent->next = pNext; + return result; +} + +// ref: 0x1000EF60 +signed int SelRegn_1000EF60() { return 0; } +/* { + signed int result; // eax + + result = 2139095040; + dword_1002A4F0 = 2139095040; + return result; +} */ +// 1002A4F0: using guessed type int dword_1002A4F0; + +// ref: 0x1000EF6B +int __stdcall SelRegn_1000EF6B(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) { return 0; } +/* { + HWND v4; // eax + HWND v6; // eax + int v7; // [esp+0h] [ebp-Ch] + + if ( Msg > 0x201 ) + { + if ( Msg == 514 ) + { + v6 = GetDlgItem(hWnd, 1105); + if ( !Sbar_100099C0(v6) ) + return SDlgDefDialogProc(hWnd, Msg, wParam, lParam); + goto LABEL_27; + } + if ( Msg != 515 ) + { + if ( Msg != 2024 ) + return SDlgDefDialogProc(hWnd, Msg, wParam, lParam); + if ( !Fade_1000739F() ) + Fade_100073FD(hWnd, v7); + return 0; + } +LABEL_25: + SelRegn_1000F929(hWnd, (unsigned short)lParam, (unsigned int)lParam >> 16); + return SDlgDefDialogProc(hWnd, Msg, wParam, lParam); + } + if ( Msg == 513 ) + goto LABEL_25; + if ( Msg == 2 ) + { + SelRegn_1000F161(hWnd); + return SDlgDefDialogProc(hWnd, Msg, wParam, lParam); + } + if ( Msg <= 0x103 ) + return SDlgDefDialogProc(hWnd, Msg, wParam, lParam); + if ( Msg <= 0x105 ) + { + v4 = (HWND)SDrawGetFrameWindow(); + SendMessageA(v4, Msg, wParam, lParam); + return SDlgDefDialogProc(hWnd, Msg, wParam, lParam); + } + if ( Msg == 272 ) + { + SelRegn_1000F1FC(hWnd); + PostMessageA(hWnd, 0x7E8u, 0, 0); + return 0; + } + if ( Msg == 273 ) + { + if ( HIWORD(wParam) == 7 ) + { + Focus_100075B7(hWnd, (HWND)lParam); + return SDlgDefDialogProc(hWnd, Msg, wParam, lParam); + } + if ( HIWORD(wParam) != 6 ) + { + if ( wParam == 327681 ) + { + SelRegn_1000F8DD(hWnd); + } + else if ( (_WORD)wParam == 2 ) + { + SelConn_1000AC07((int)hWnd, 2); + } + return SDlgDefDialogProc(hWnd, Msg, wParam, lParam); + } + Focus_10007458((void *)lParam); + Focus_100075DC(hWnd, (HWND)lParam); + SelRegn_1000F0D7(hWnd, (unsigned short)wParam); +LABEL_27: + SelRegn_1000F109(hWnd); + } + return SDlgDefDialogProc(hWnd, Msg, wParam, lParam); +} */ +// 1001037C: using guessed type int __stdcall SDlgDefDialogProc(_DWORD, _DWORD, _DWORD, _DWORD); +// 10010382: using guessed type _DWORD __stdcall SDrawGetFrameWindow(); + +// ref: 0x1000F0D7 +HWND __fastcall SelRegn_1000F0D7(HWND hDlg, int nIDDlgItem) { return 0; } +/* { + HWND v2; // esi + HWND result; // eax + + v2 = hDlg; + result = GetDlgItem(hDlg, nIDDlgItem); + if ( result ) + { + result = (HWND)GetWindowLongA(result, -21); + if ( result ) + { + if ( *((_DWORD *)result + 3) ) + result = (HWND)Doom_10006A13(v2, (int *)&unk_10023250, 1); + } + } + return result; +} */ + +// ref: 0x1000F109 +HWND UNKCALL SelRegn_1000F109(HWND hDlg) { return 0; } +/* { + HWND v1; // esi + int v2; // eax + + v1 = hDlg; + v2 = SelRegn_1000F126(); + return Sbar_10009A99(v1, 1105, dword_1002A4F4, v2); +} */ + +// ref: 0x1000F126 +int SelRegn_1000F126() { return 0; } +/* { + HWND v0; // eax + LONG v1; // eax + _DWORD *v2; // ecx + _DWORD *v3; // eax + int v5; // edx + + v0 = GetFocus(); + if ( !v0 ) + return 0; + v1 = GetWindowLongA(v0, -21); + if ( !v1 ) + return 0; + v2 = (_DWORD *)dword_1002A4EC; + if ( !dword_1002A4EC ) + return 0; + v3 = *(_DWORD **)(v1 + 12); + if ( !v3 ) + return 0; + v5 = 0; + do + { + if ( v2 == v3 ) + break; + v2 = (_DWORD *)*v2; + ++v5; + } + while ( v2 ); + return v5; +} */ +// 1002A4EC: using guessed type int dword_1002A4EC; + +// ref: 0x1000F161 +void UNKCALL SelRegn_1000F161(HWND hDlg) { return; } +/* { + HWND v1; // esi + _DWORD *v2; // eax + + v1 = hDlg; + Title_100100E7(hDlg); + Focus_10007818(v1); + Sbar_10009CD2(v1, 1105); + SelRegn_1000F1D4((_DWORD *)dword_1002A4EC); + Doom_10006C53(v1, &dword_1002326C); + Doom_10006C53(v1, (int *)&unk_10023260); + Doom_10006C53(v1, (int *)&unk_10023244); + Doom_10006C53(v1, (int *)&unk_10023258); + Doom_10006C53(v1, (int *)&unk_10023250); + v2 = (_DWORD *)GetWindowLongA(v1, -21); + local_10007F72(v2); +} */ +// 1002326C: using guessed type int dword_1002326C; +// 1002A4EC: using guessed type int dword_1002A4EC; + +// ref: 0x1000F1D4 +int __fastcall SelRegn_1000F1D4(_DWORD *a1) { return 0; } +/* { + _DWORD *v1; // esi + int result; // eax + + if ( a1 ) + { + do + { + v1 = (_DWORD *)*a1; + result = SelRegn_1000F1E8(a1); + a1 = v1; + } + while ( v1 ); + } + return result; +} */ + +// ref: 0x1000F1E8 +int UNKCALL SelRegn_1000F1E8(void *arg) { return 0; } +/* { + int result; // eax + + if ( arg ) + result = SMemFree(arg, "C:\\Src\\Diablo\\DiabloUI\\SelRegn.cpp", 82, 0); + return result; +} */ +// 10010340: using guessed type int __stdcall SMemFree(_DWORD, _DWORD, _DWORD, _DWORD); + +// ref: 0x1000F1FC +HWND UNKCALL SelRegn_1000F1FC(HWND hWnd) { return 0; } +/* { + HWND v1; // esi + HWND v2; // ST1C_4 + int v3; // eax + int *v4; // edi + HWND result; // eax + HWND v6; // eax + HWND v7; // [esp+0h] [ebp-Ch] + + v1 = hWnd; + SelRegn_1000F3C2(hWnd); + Focus_100077E9((int)v1, "ui_art\\focus16.pcx", v7); + Title_1001009E(v1, (int)"ui_art\\smlogo.pcx", v2); + v3 = local_10007F46(); + v4 = (int *)v3; + if ( v3 ) + { + SetWindowLongA(v1, -21, v3); + local_10007944((int)v1, 0, &byte_10029448, -1, 1, (int)"ui_art\\selregn.pcx", v4, v4 + 1, 0); + Fade_100073C5(v1, 1); + } + Doom_100068AB(v1, (int *)&unk_10023250, 1); + Doom_100068AB(v1, (int *)&unk_10023258, 1); + Doom_100068AB(v1, (int *)&unk_10023244, 5); + Doom_1000658C(v1, (int *)&unk_10023260, 4, 0); + Doom_1000658C(v1, &dword_1002326C, 0, 1); + dword_1002A4F4 = 0; + dword_1002A4EC = 0; + SelRegn_1000F2ED(); + SelRegn_1000F346(v1, (const char *)dword_1002A4EC); + result = Sbar_10009BF1(v1, 1105); + if ( dword_1002A4F4 <= 6 ) + { + v6 = GetDlgItem(v1, 1105); + result = (HWND)ShowWindow(v6, 0); + } + return result; +} */ +// 1002326C: using guessed type int dword_1002326C; +// 1002A4EC: using guessed type int dword_1002A4EC; + +// ref: 0x1000F2ED +signed int SelRegn_1000F2ED() { return 0; } +/* { + signed int i; // edi + char *v1; // eax + char *v2; // esi + const char *v3; // eax + _DWORD *v4; // eax + + for ( i = dword_10029488; ; --i ) + { + if ( i <= 0 ) + return 1; + v1 = (char *)SelRegn_1000EF42(); + v2 = v1; + if ( !v1 ) + break; + *(_DWORD *)v1 = 0; + *((_DWORD *)v1 + 1) = i; + v3 = BNetGW_10002B21(&unk_10029480, i); + strcpy(v2 + 8, v3); + v4 = SelRegn_1000EF56(dword_1002A4EC, v2); + ++dword_1002A4F4; + dword_1002A4EC = (int)v4; + } + return 0; +} */ +// 10029488: using guessed type int dword_10029488; +// 1002A4EC: using guessed type int dword_1002A4EC; + +// ref: 0x1000F346 +int __fastcall SelRegn_1000F346(HWND a1, const char *a2) { return 0; } +/* { + const char *v2; // edi + int *v3; // ebx + HWND v4; // eax + HWND v5; // esi + int v6; // eax + HWND hDlg; // [esp+8h] [ebp-4h] + + v2 = a2; + hDlg = a1; + v3 = &dword_1002326C; + if ( dword_1002326C ) + { + do + { + v4 = GetDlgItem(hDlg, *v3); + v5 = v4; + if ( v4 ) + { + if ( v2 ) + { + EnableWindow(v4, 1); + v6 = GetWindowLongA(v5, -21); + if ( v6 ) + { + *(_DWORD *)(v6 + 12) = v2; + local_10007FA4(v6, v2 + 8); + v2 = *(const char **)v2; + } + } + else + { + EnableWindow(v4, 0); + } + } + ++v3; + } + while ( *v3 ); + } + return Doom_1000680A(hDlg, &dword_1002326C, 0, 1); +} */ +// 1002326C: using guessed type int dword_1002326C; + +// ref: 0x1000F3C2 +void UNKCALL SelRegn_1000F3C2(HWND hDlg) { return; } +/* { + HWND v1; // ebx + int *v2; // edi + HWND v3; // eax + HWND v4; // esi + void *v5; // eax + + v1 = hDlg; + v2 = &dword_1002326C; + if ( dword_1002326C ) + { + do + { + v3 = GetDlgItem(v1, *v2); + v4 = v3; + if ( v3 ) + { + v5 = (void *)GetWindowLongA(v3, -4); + SetPropA(v4, "UIOLDPROC", v5); + SetWindowLongA(v4, -4, (LONG)SelRegn_1000F414); + } + ++v2; + } + while ( *v2 ); + } +} */ +// 1002326C: using guessed type int dword_1002326C; + +// ref: 0x1000F414 +LRESULT __stdcall SelRegn_1000F414(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) { return 0; } +/* { + LRESULT (__stdcall *v4)(HWND, UINT, WPARAM, LPARAM); // edi + HWND v5; // eax + WPARAM v7; // [esp-8h] [ebp-14h] + + v4 = (LRESULT (__stdcall *)(HWND, UINT, WPARAM, LPARAM))GetPropA(hWnd, "UIOLDPROC"); + switch ( Msg ) + { + case 2u: + RemovePropA(hWnd, "UIOLDPROC"); + if ( !v4 ) + return DefWindowProcA(hWnd, Msg, wParam, lParam); + SetWindowLongA(hWnd, -4, (LONG)v4); + break; + case 0xFu: + local_10007C95(hWnd); + return 0; + case 0x87u: + return 4; + case 0x100u: + if ( wParam > 0x21 ) + { + if ( wParam == 34 ) + { + SelRegn_1000F61E(hWnd); + } + else if ( wParam > 0x24 ) + { + if ( wParam <= 0x26 ) + { + SelRegn_1000F859(hWnd); + } + else if ( wParam <= 0x28 ) + { + SelRegn_1000F7C1(hWnd); + } + } + return 0; + } + if ( wParam == 33 ) + { + SelRegn_1000F711(hWnd); + return 0; + } + if ( wParam == 9 ) + { + if ( GetKeyState(16) >= 0 ) + SelRegn_1000F53C(hWnd); + else + SelRegn_1000F5AD(hWnd); + return 0; + } + if ( wParam != 13 ) + { + if ( wParam == 27 ) + { + v7 = 2; + goto LABEL_13; + } + if ( wParam != 32 ) + return 0; + } + v7 = 1; +LABEL_13: + v5 = GetParent(hWnd); + SendMessageA(v5, 0x111u, v7, 0); + return 0; + } + if ( v4 ) + return CallWindowProcA(v4, hWnd, Msg, wParam, lParam); + return DefWindowProcA(hWnd, Msg, wParam, lParam); +} */ + +// ref: 0x1000F53C +HWND UNKCALL SelRegn_1000F53C(HWND hWnd) { return 0; } +/* { + HWND v1; // edi + HWND v2; // ebx + int nIDDlgItem[1132]; // [esp+0h] [ebp-11D4h] + int v5; // [esp+11B0h] [ebp-24h] + int v6; // [esp+11BCh] [ebp-18h] + int v7; // [esp+11C0h] [ebp-14h] + int v8; // [esp+11C4h] [ebp-10h] + int v9; // [esp+11C8h] [ebp-Ch] + int v10; // [esp+11CCh] [ebp-8h] + int v11; // [esp+11D0h] [ebp-4h] + + v1 = hWnd; + v6 = 1136; + v7 = 1137; + v8 = 1138; + v9 = 1139; + v10 = 1140; + v11 = 1135; + v2 = GetParent(hWnd); + do + { + v5 = nIDDlgItem[GetWindowLongA(v1, -12)]; + v1 = GetDlgItem(v2, v5); + } + while ( !IsWindowEnabled(v1) ); + return SetFocus(v1); +} */ +// 1000F53C: using guessed type int nIDDlgItem[1132]; + +// ref: 0x1000F5AD +HWND UNKCALL SelRegn_1000F5AD(HWND hWnd) { return 0; } +/* { + HWND v1; // edi + HWND v2; // ebx + int nIDDlgItem[1132]; // [esp+0h] [ebp-11D4h] + int v5; // [esp+11B0h] [ebp-24h] + int v6; // [esp+11BCh] [ebp-18h] + int v7; // [esp+11C0h] [ebp-14h] + int v8; // [esp+11C4h] [ebp-10h] + int v9; // [esp+11C8h] [ebp-Ch] + int v10; // [esp+11CCh] [ebp-8h] + int v11; // [esp+11D0h] [ebp-4h] + + v1 = hWnd; + v6 = 1140; + v7 = 1135; + v8 = 1136; + v9 = 1137; + v10 = 1138; + v11 = 1139; + v2 = GetParent(hWnd); + do + { + v5 = nIDDlgItem[GetWindowLongA(v1, -12)]; + v1 = GetDlgItem(v2, v5); + } + while ( !IsWindowEnabled(v1) ); + return SetFocus(v1); +} */ +// 1000F5AD: using guessed type int nIDDlgItem[1132]; + +// ref: 0x1000F61E +HWND UNKCALL SelRegn_1000F61E(HWND hWnd) { return 0; } +/* { + HWND v1; // ebp + HWND result; // eax + HWND v3; // esi + HWND v4; // ebx + HWND v5; // eax + _DWORD *v6; // eax + int v7; // eax + const char *v8; // ebx + int v9; // eax + + v1 = hWnd; + result = GetParent(hWnd); + v3 = result; + if ( result ) + { + result = GetDlgItem(result, 1135); + v4 = result; + if ( result ) + { + v5 = GetDlgItem(v3, 1140); + result = (HWND)GetWindowLongA(v5, -21); + if ( result ) + { + v6 = (_DWORD *)*((_DWORD *)result + 3); + if ( v6 && *v6 ) + { + v7 = SelRegn_1000F6C9(v4) + 6; + if ( v7 > dword_1002A4F4 - 6 ) + v7 = dword_1002A4F4 - 6; + result = (HWND)SelRegn_1000F6FE(v7); + v8 = (const char *)result; + if ( result ) + { + TitleSnd_10010315(); + SelRegn_1000F346(v3, v8); + v9 = GetWindowLongA(v1, -12); + SelRegn_1000F0D7(v3, v9); + result = SelRegn_1000F109(v3); + } + } + else + { + result = SelRegn_1000F5AD(v4); + } + } + } + } + return result; +} */ + +// ref: 0x1000F6C9 +int UNKCALL SelRegn_1000F6C9(HWND hWnd) { return 0; } +/* { + LONG v1; // eax + _DWORD *v2; // ecx + _DWORD *v3; // eax + int v5; // edx + + if ( !hWnd ) + return 0; + v1 = GetWindowLongA(hWnd, -21); + if ( !v1 ) + return 0; + v2 = (_DWORD *)dword_1002A4EC; + if ( !dword_1002A4EC ) + return 0; + v3 = *(_DWORD **)(v1 + 12); + if ( !v3 ) + return 0; + v5 = 0; + do + { + if ( v2 == v3 ) + break; + v2 = (_DWORD *)*v2; + ++v5; + } + while ( v2 ); + return v5; +} */ +// 1002A4EC: using guessed type int dword_1002A4EC; + +// ref: 0x1000F6FE +_DWORD *__fastcall SelRegn_1000F6FE(int a1) { return 0; } +/* { + _DWORD *result; // eax + + result = (_DWORD *)dword_1002A4EC; + while ( result && a1 ) + { + result = (_DWORD *)*result; + --a1; + } + return result; +} */ +// 1002A4EC: using guessed type int dword_1002A4EC; + +// ref: 0x1000F711 +HWND UNKCALL SelRegn_1000F711(HWND hWnd) { return 0; } +/* { + HWND result; // eax + HWND v2; // esi + HWND v3; // edi + HWND v4; // eax + int v5; // eax + const char *v6; // edi + int v7; // eax + HWND hWnda; // [esp+10h] [ebp-4h] + + hWnda = hWnd; + result = GetParent(hWnd); + v2 = result; + if ( result ) + { + result = GetDlgItem(result, 1135); + v3 = result; + if ( result ) + { + result = (HWND)GetWindowLongA(result, -21); + if ( result ) + { + result = (HWND)*((_DWORD *)result + 3); + if ( result ) + { + if ( result == (HWND)dword_1002A4EC ) + { + v4 = GetDlgItem(v2, 1140); + result = SelRegn_1000F53C(v4); + } + else + { + v5 = SelRegn_1000F6C9(v3) - 6; + if ( v5 < 0 ) + v5 = 0; + result = (HWND)SelRegn_1000F6FE(v5); + v6 = (const char *)result; + if ( result ) + { + TitleSnd_10010315(); + SelRegn_1000F346(v2, v6); + v7 = GetWindowLongA(hWnda, -12); + SelRegn_1000F0D7(v2, v7); + result = SelRegn_1000F109(v2); + } + } + } + } + } + } + return result; +} */ +// 1002A4EC: using guessed type int dword_1002A4EC; + +// ref: 0x1000F7C1 +HWND UNKCALL SelRegn_1000F7C1(HWND hWnd) { return 0; } +/* { + HWND v1; // edi + HWND result; // eax + HWND v3; // eax + const char *v4; // ebp + HWND v5; // eax + int v6; // ebx + HWND v7; // eax + HWND v8; // eax + + v1 = hWnd; + result = (HWND)GetWindowLongA(hWnd, -21); + if ( result ) + { + result = (HWND)*((_DWORD *)result + 3); + if ( result ) + { + if ( *(_DWORD *)result ) + { + if ( GetWindowLongA(v1, -12) >= 1140 ) + { + v3 = GetParent(v1); + result = GetDlgItem(v3, 1136); + if ( result ) + { + result = (HWND)GetWindowLongA(result, -21); + if ( result ) + { + v4 = (const char *)*((_DWORD *)result + 3); + if ( v4 ) + { + TitleSnd_10010315(); + v5 = GetParent(v1); + SelRegn_1000F346(v5, v4); + v6 = GetWindowLongA(v1, -12); + v7 = GetParent(v1); + SelRegn_1000F0D7(v7, v6); + v8 = GetParent(v1); + result = SelRegn_1000F109(v8); + } + } + } + } + else + { + result = SelRegn_1000F53C(v1); + } + } + } + } + return result; +} */ + +// ref: 0x1000F859 +HWND UNKCALL SelRegn_1000F859(HWND hWnd) { return 0; } +/* { + HWND v1; // edi + HWND result; // eax + const char *v3; // ebx + HWND v4; // eax + int v5; // ebx + HWND v6; // eax + HWND v7; // eax + + v1 = hWnd; + if ( GetWindowLongA(hWnd, -12) > 1135 ) + return SelRegn_1000F5AD(v1); + result = (HWND)GetWindowLongA(v1, -21); + if ( result ) + { + result = (HWND)*((_DWORD *)result + 3); + if ( result ) + { + v3 = (const char *)dword_1002A4EC; + if ( result != (HWND)dword_1002A4EC ) + { + while ( v3 && *(HWND *)v3 != result ) + v3 = *(const char **)v3; + TitleSnd_10010315(); + v4 = GetParent(v1); + SelRegn_1000F346(v4, v3); + v5 = GetWindowLongA(v1, -12); + v6 = GetParent(v1); + SelRegn_1000F0D7(v6, v5); + v7 = GetParent(v1); + result = SelRegn_1000F109(v7); + } + } + } + return result; +} */ +// 1002A4EC: using guessed type int dword_1002A4EC; + +// ref: 0x1000F8DD +signed int UNKCALL SelRegn_1000F8DD(void *arg) { return 0; } +/* { + int v1; // esi + signed int result; // eax + + v1 = (int)arg; + result = SelRegn_1000F8F6(); + if ( result ) + result = SelConn_1000AC07(v1, 1); + return result; +} */ + +// ref: 0x1000F8F6 +signed int SelRegn_1000F8F6() { return 0; } +/* { + HWND v0; // eax + LONG v1; // eax + int v2; // eax + + TitleSnd_1001031F(); + v0 = GetFocus(); + v1 = GetWindowLongA(v0, -21); + if ( !v1 ) + return 0; + v2 = *(_DWORD *)(v1 + 12); + if ( !v2 ) + return 0; + BNetGW_10002B51(&unk_10029480, *(_DWORD *)(v2 + 4)); + return 1; +} */ + +// ref: 0x1000F929 +HWND __fastcall SelRegn_1000F929(HWND hWnd, int a2, int a3) { return 0; } +/* { + int v3; // ebx + HWND v4; // esi + int v5; // ST08_4 + HWND v6; // eax + HWND result; // eax + HWND v8; // eax + HWND v9; // eax + HWND v10; // eax + int v11; // eax + int v12; // eax + int v13; // eax + HWND v14; // eax + HWND v15; // eax + HWND v16; // eax + HWND v17; // eax + + v3 = a2; + v4 = hWnd; + v5 = a2; + v6 = GetDlgItem(hWnd, 1056); + if ( local_10007C3B(v4, v6, v5, a3) ) + return (HWND)SelRegn_1000F8DD(v4); + v8 = GetDlgItem(v4, 1054); + if ( local_10007C3B(v4, v8, v3, a3) ) + return (HWND)SelConn_1000AC07((int)v4, 2); + v9 = GetDlgItem(v4, 1105); + result = (HWND)local_10007C3B(v4, v9, v3, a3); + if ( result ) + { + v10 = GetDlgItem(v4, 1105); + v11 = Sbar_100099DC(v10, v3, a3) - 1; + if ( v11 ) + { + v12 = v11 - 1; + if ( v12 ) + { + v13 = v12 - 1; + if ( v13 ) + { + result = (HWND)(v13 - 1); + if ( !result ) + { + v14 = GetFocus(); + result = SelRegn_1000F61E(v14); + } + } + else + { + v15 = GetFocus(); + result = SelRegn_1000F711(v15); + } + } + else + { + v16 = GetFocus(); + result = SelRegn_1000F7C1(v16); + } + } + else + { + v17 = GetFocus(); + result = SelRegn_1000F859(v17); + } + } + return result; +} */ + +// ref: 0x1000F9F7 +signed int __stdcall UiSelectRegion(_DWORD *a1) { return 0; } +/* { + int v1; // eax + int v2; // eax + signed int result; // eax + + artfont_10001159(); + v1 = SDrawGetFrameWindow(); + v2 = SDlgDialogBoxParam(hInstance, "SELREGION_DIALOG", v1, SelRegn_1000EF6B, 0); + if ( a1 ) + *a1 = dword_1002948C; + if ( v2 == 1 ) + { + local_100078B6(); + result = 1; + } + else + { + SErrSetLastError(1223); + result = 0; + } + return result; +} */ +// 10010370: using guessed type int __stdcall SDlgDialogBoxParam(_DWORD, _DWORD, _DWORD, _DWORD, _DWORD); +// 10010382: using guessed type _DWORD __stdcall SDrawGetFrameWindow(); +// 1001041E: using guessed type int __stdcall SErrSetLastError(_DWORD); +// 1002948C: using guessed type int dword_1002948C; diff --git a/2020_03_31/DiabloUI/selyesno.cpp b/2020_03_31/DiabloUI/selyesno.cpp new file mode 100644 index 00000000..34f60391 --- /dev/null +++ b/2020_03_31/DiabloUI/selyesno.cpp @@ -0,0 +1,226 @@ +// ref: 0x1000FA49 +int __fastcall SelYesNo_YesNoDialog(HWND hWnd, char *dialogstr, char *hero, int nofocus) +{ + yesno_dialog_string = dialogstr; + yesno_hero_name = hero; + yesno_remove_focus = nofocus; + yesno_is_popup = 0; + YesNoFunc = 0; + return SDlgDialogBoxParam(ghUiInst, "SELYESNO_DIALOG", (int)hWnd, SelYesNo_WndProc, 0); +} +// 1002A500: using guessed type int yesno_remove_focus; +// 1002A508: using guessed type int (*YesNoFunc)(void); +// 1002A50C: using guessed type int yesno_is_popup; + +// ref: 0x1000FA87 +LRESULT __stdcall SelYesNo_WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) +{ + HWND v4; // eax + HWND v5; // eax + int v7; // edx + HWND v8; // eax + LONG v9; // eax + HWND v10; // ecx + HWND v11; // eax + + if ( Msg == 2 ) + { + SelYesNo_RemoveYNDialog(hWnd); + return (LRESULT)SDlgDefDialogProc(hWnd, Msg, (HDC)wParam, (HWND)lParam); + } + if ( Msg > 0x103 ) + { + if ( Msg <= 0x105 ) + { + v11 = (HWND)SDrawGetFrameWindow(NULL); + SendMessageA(v11, Msg, wParam, lParam); + return (LRESULT)SDlgDefDialogProc(hWnd, Msg, (HDC)wParam, (HWND)lParam); + } + switch ( Msg ) + { + case 0x110u: + SelYesNo_LoadSelYN_GFX(hWnd); + return 0; + case 0x111u: + if ( HIWORD(wParam) == 7 ) + { + Focus_GetAndBlitSpin(hWnd, lParam); + } + else if ( HIWORD(wParam) == 6 ) + { + Focus_CheckPlayMove(lParam); + Focus_DoBlitSpinIncFrame(hWnd, (HWND)lParam); + } + else + { + v7 = 1; + if ( (_WORD)wParam == 1 ) + { + v8 = GetFocus(); + v9 = GetWindowLongA(v8, -12); + v10 = hWnd; + if ( v9 == 1109 ) + v7 = 1; + else + v7 = 2; + } + else + { + if ( (_WORD)wParam == 2 ) + { + v7 = 2; + } + else if ( (_WORD)wParam != 1109 ) + { + return (LRESULT)SDlgDefDialogProc(hWnd, Msg, (HDC)wParam, (HWND)lParam); + } + v10 = hWnd; + } + SelYesNo_DoSelectYesNo(v10, v7); + } + break; + case 0x113u: + v4 = GetFocus(); + if ( !Focus_DoBlitSpinIncFrame(hWnd, v4) ) + { + v5 = GetDlgItem(hWnd, 1109); + if ( !v5 ) + v5 = GetDlgItem(hWnd, 2); + SetFocus(v5); + } + return 0; + } + } + return (LRESULT)SDlgDefDialogProc(hWnd, Msg, (HDC)wParam, (HWND)lParam); +} +// 10010382: using guessed type _DWORD __stdcall SDrawGetFrameWindow(); + +// ref: 0x1000FBC7 +void __fastcall SelYesNo_RemoveYNDialog(HWND hWnd) +{ + HWND v1; // esi + void **v2; // eax + HWND v3; // eax + + v1 = hWnd; + v2 = (void **)GetWindowLongA(hWnd, -21); + local_FreeMemPtr(v2); + if ( yesno_remove_focus ) + Focus_DeleteSpinners(); + Doom_DeleteFreeProcs(v1, yesno_msgtbl1); + Doom_DeleteFreeProcs(v1, yesno_msgtbl2); + if ( yesno_hero_name ) + { + v3 = GetParent(v1); + SelHero_SetStringWithMsg(v3, 0); + } +} +// 1002A500: using guessed type int yesno_remove_focus; + +// ref: 0x1000FC1C +void __fastcall SelYesNo_LoadSelYN_GFX(HWND hWnd) +{ + HWND v2; // eax + DWORD *v3; // eax + DWORD *v4; // edi + const char *v5; // eax + char *v6; // ST18_4 + HWND v7; // eax + + v2 = GetParent(hWnd); + if ( yesno_hero_name ) + SelHero_SetStringWithMsg(v2, yesno_hero_name); + v3 = local_AllocWndLongData(); + v4 = v3; + if ( v3 ) + { + SetWindowLongA(hWnd, -21, (LONG)v3); + if ( yesno_is_popup ) + { + if ( DiabloUI_GetSpawned() ) + v5 = "ui_art\\swmmpop.pcx"; + else + v5 = "ui_art\\mmpopup.pcx"; + } + else + { + v5 = "ui_art\\black.pcx"; + } + local_LoadArtWithPal(hWnd, 0, "Popup", -1, 1, v5, (BYTE **)v4, v4 + 1, 1); + } + v6 = yesno_dialog_string; + v7 = GetDlgItem(hWnd, 1026); + SetWindowTextA(v7, v6); + Doom_ParseWndProc3(hWnd, yesno_msgtbl2, 3); + Doom_ParseWndProcs(hWnd, yesno_msgtbl1, 4, 1); + if ( yesno_remove_focus ) + Focus_LoadSpinner("ui_art\\focus.pcx"); + else + Focus_ResetSpinToZero(); + SDlgSetTimer((int)hWnd, 1, 55, 0); + local_DoUiWndProc2(hWnd, (DWORD *)yesno_msgtbl1); +} +// 1002A500: using guessed type int yesno_remove_focus; +// 1002A50C: using guessed type int yesno_is_popup; + +// ref: 0x1000FCF6 +void __fastcall SelYesNo_DoSelectYesNo(HWND hWnd, int option) +{ + HWND v4; // eax + + TitleSnd_PlaySelectSound(); + SDlgKillTimer((int)hWnd, 1); + if ( option == 2 ) + { + if ( !YesNoFunc ) + goto LABEL_6; + YesNoFunc(); + } + if ( option == 1 ) + { + v4 = GetFocus(); + option = GetWindowLongA(v4, -12); + } +LABEL_6: + SDlgEndDialog(hWnd, (HANDLE)option); +} +// 1002A508: using guessed type int (*YesNoFunc)(void); + +// ref: 0x1000FD39 +int __fastcall SelYesNo_SelOkDialog(HWND hWnd, char *dialogstr, char *hero, int nofocus) +{ + yesno_dialog_string = dialogstr; + yesno_hero_name = hero; + yesno_remove_focus = nofocus; + yesno_is_popup = 0; + YesNoFunc = 0; + return SDlgDialogBoxParam(ghUiInst, "SELOK_DIALOG", (int)hWnd, SelYesNo_WndProc, 0); +} +// 1002A500: using guessed type int yesno_remove_focus; +// 1002A508: using guessed type int (*YesNoFunc)(void); +// 1002A50C: using guessed type int yesno_is_popup; + +// ref: 0x1000FD77 +int __fastcall SelYesNo_SpawnErrDialog(HWND hWnd, int string_rsrc, int is_popup) +{ + char Buffer[256]; // [esp+4h] [ebp-100h] + + LoadStringA(ghUiInst, string_rsrc, Buffer, 255); + yesno_is_popup = is_popup; + yesno_remove_focus = 0; + yesno_hero_name = 0; + yesno_dialog_string = Buffer; + YesNoFunc = 0; + return SDlgDialogBoxParam(ghUiInst, "SPAWNERR_DIALOG", (int)hWnd, SelYesNo_WndProc, 0); +} +// 1002A500: using guessed type int yesno_remove_focus; +// 1002A508: using guessed type int (*YesNoFunc)(void); +// 1002A50C: using guessed type int yesno_is_popup; + +// ref: 0x1000FDE3 +void __cdecl SelYesNo_cpp_init() +{ + SelYesNo_cpp_float = SelYesNo_cpp_float_value; +} +// 1001F478: using guessed type int SelYesNo_cpp_float_value; +// 1002A4FC: using guessed type int SelYesNo_cpp_float; diff --git a/2020_03_31/DiabloUI/title.cpp b/2020_03_31/DiabloUI/title.cpp new file mode 100644 index 00000000..3f26c9d9 --- /dev/null +++ b/2020_03_31/DiabloUI/title.cpp @@ -0,0 +1,296 @@ +// ref: 0x1000FDEE +void __fastcall Title_BlitTitleBuffer(HWND hWnd) +{ + _DWORD *v2; // edi + int v3; // eax + HANDLE v4; // esi + struct tagRECT Rect; // [esp+Ch] [ebp-18h] + HWND hWnda; // [esp+20h] [ebp-4h] + + v2 = (_DWORD *)GetWindowLongA(hWnd, -21); + hWnda = GetDlgItem(hWnd, 1043); + if ( IsWindowVisible(hWnd) && hWnda && v2 && *v2 && titlePHTrans[0] ) + { + v3 = titleTransIdx + 1; + titleTransIdx = v3; + if ( !titlePHTrans[v3] || v3 >= 30 ) + titleTransIdx = 0; + GetWindowRect(hWnda, &Rect); + ScreenToClient(hWnd, (LPPOINT)&Rect); + ScreenToClient(hWnd, (LPPOINT)&Rect.right); + v4 = GetPropA(hWnd, "TITLE_BUFFER"); + if ( v4 ) + { + SBltROP3( + *(void **)v4, + (void *)(Rect.left + *v2 + Rect.top * v2[1]), + *((_DWORD *)v4 + 1), + *((_DWORD *)v4 + 2), + *((_DWORD *)v4 + 1), + v2[1], + 0, + 0xCC0020u); + STransBlt(*(void **)v4, 0, 0, *((_DWORD *)v4 + 1), (HANDLE)titlePHTrans[titleTransIdx]); + InvalidateRect(hWnda, 0, 0); + } + } +} +// 1002A58C: using guessed type int titleTransIdx; + +// ref: 0x1000FEED +void __cdecl Title_DeletePhTrans() +{ + int *v0; // esi + + v0 = (int *)titlePHTrans; + do + { + if ( *v0 ) + { + STransDelete((HANDLE)*v0); + *v0 = 0; + } + ++v0; + } + while ( (signed int)v0 < (signed int)&titlePHTrans[30] ); +} + +// ref: 0x1000FF0F +void __fastcall Title_FreeTransMem(HWND hWnd) +{ + void **v2; // eax MAPDST + void *v4; // eax + + Title_DeletePhTrans(); + v2 = (void **)RemovePropA(hWnd, "TITLE_BUFFER"); + if ( v2 ) + { + v4 = *v2; + if ( v4 ) + { + SMemFree(v4, "C:\\Src\\Diablo\\DiabloUI\\Title.cpp", 114, 0); + *v2 = 0; + } + SMemFree(v2, "C:\\Src\\Diablo\\DiabloUI\\Title.cpp", 117, 0); + } +} + +// ref: 0x1000FF51 +void __fastcall Title_SetTitleBMP(HWND hWnd) +{ + HWND v1; // eax MAPDST + _DWORD *v2; // esi + void *v3; // eax + struct tagRECT Rect; // [esp+0h] [ebp-18h] + + Title_FreeTransMem(hWnd); + v1 = GetDlgItem(hWnd, 1043); + if ( v1 ) + { + GetClientRect(v1, &Rect); + v2 = (unsigned int *)SMemAlloc(0xCu, "C:\\Src\\Diablo\\DiabloUI\\Title.cpp", 134, 0); + v3 = SMemAlloc(Rect.right * Rect.bottom, "C:\\Src\\Diablo\\DiabloUI\\Title.cpp", 136, 8); + *v2 = (unsigned int)v3; + v2[1] = Rect.right; + v2[2] = Rect.bottom; + SDlgSetBitmapI(v1, 0, 0, -1, 1, v3, 0, Rect.right, Rect.bottom, -1); + SetPropA(hWnd, "TITLE_BUFFER", v2); + } +} + +// ref: 0x1000FFE8 +void __fastcall Title_LoadTitleImage(HWND hWnd, const char *pszFileName) +{ + int v3; // edi + _DWORD *v4; // eax + _DWORD *v5; // esi + int v6; // ebx + int a5[4]; // [esp+8h] [ebp-20h] + int data[2]; // [esp+18h] [ebp-10h] + HANDLE *phTransOut; // [esp+20h] [ebp-8h] + BYTE *pBuffer; // [esp+24h] [ebp-4h] + + v3 = 0; + pBuffer = 0; + local_LoadArtImage(pszFileName, &pBuffer, (DWORD *)data); + v4 = (unsigned int *)GetPropA(hWnd, "TITLE_BUFFER"); + v5 = v4; + if ( pBuffer ) + { + if ( v4 ) + { + v6 = data[1] / v4[2]; + if ( v6 > 30 ) + v6 = 30; + if ( v6 > 0 ) + { + phTransOut = (HANDLE *)titlePHTrans; + do + { + a5[0] = 0; + a5[2] = v5[1] - 1; + a5[1] = v3 * v5[2]; + a5[3] = v5[2] + a5[1] - 1; + STransCreateI(pBuffer, v5[1], v5[2], 8, (int)a5, 16777466, phTransOut); + ++phTransOut; + ++v3; + } + while ( v3 < v6 ); + } + } + SMemFree(pBuffer, "C:\\Src\\Diablo\\DiabloUI\\Title.cpp", 197, 0); + } + titleTransIdx = 0; +} +// 1002A58C: using guessed type int titleTransIdx; + +// ref: 0x1001009E +void __fastcall Title_LoadImgSetTimer(HWND hWnd, const char *pszFileName) +{ + Title_SetTitleBMP(hWnd); + Title_LoadTitleImage(hWnd, pszFileName); + Title_BlitTitleBuffer(hWnd); + SDlgSetTimer((int)hWnd, 2, 55, Title_BlitTitleBufFnc); +} + +// ref: 0x100100CB +void __stdcall Title_BlitTitleBufFnc(int hWnd, int a2, int a3, int a4) +{ + Title_BlitTitleBuffer((HWND)hWnd); +} + +// ref: 0x100100DC +void __cdecl Title_cpp_init() +{ + Title_cpp_float = Title_cpp_float_value; +} +// 1001F47C: using guessed type int Title_cpp_float_value; +// 1002A588: using guessed type int Title_cpp_float; + +// ref: 0x100100E7 +void __fastcall Title_KillTitleTimer(HWND hWnd) +{ + HWND v1; // esi + + v1 = hWnd; + SDlgKillTimer((int)hWnd, 2); + Title_FreeTransMem(v1); +} + +// ref: 0x100100FA +BOOL __stdcall UiTitleDialog(int a1) +{ + int v1; // eax + + artfont_LoadAllFonts(); + v1 = (int)SDrawGetFrameWindow(NULL); + SDlgDialogBoxParam(ghUiInst, "TITLESCREEN_DIALOG", v1, Title_MainProc, a1); + return 1; +} +// 10010382: using guessed type _DWORD __stdcall SDrawGetFrameWindow(); + +// ref: 0x10010126 +LRESULT __stdcall Title_MainProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + HWND v5; // eax + + if ( uMsg <= 0x111 ) + { + if ( uMsg != 273 ) + { + if ( uMsg != 2 ) + { + if ( uMsg == 135 ) + return 4; + if ( uMsg != 256 ) + { + if ( uMsg > 0x103 ) + { + if ( uMsg <= 0x105 ) + { + v5 = (HWND)SDrawGetFrameWindow(NULL); + SendMessageA(v5, uMsg, wParam, lParam); + } + else if ( uMsg == 272 ) + { + Title_LoadAllTitleImgs(hWnd, lParam); + PostMessageA(hWnd, 0x7E8u, 0, 0); + return 1; + } + } + return (LRESULT)SDlgDefDialogProc(hWnd, uMsg, (HDC)wParam, (HWND)lParam); + } + goto LABEL_25; + } + Title_KillTimerAndFree(hWnd); + return (LRESULT)SDlgDefDialogProc(hWnd, uMsg, (HDC)wParam, (HWND)lParam); + } + goto LABEL_25; + } + if ( uMsg != 275 ) + { + if ( uMsg != 513 && uMsg != 516 ) + { + if ( uMsg == 528 ) + { + if ( (_WORD)wParam == 513 || (_WORD)wParam == 516 ) + Title_KillAndFadeDlg(hWnd); + } + else if ( uMsg == 2024 ) + { + if ( !Fade_CheckRange5() ) + Fade_SetFadeTimer((int)hWnd); + return 0; + } + return (LRESULT)SDlgDefDialogProc(hWnd, uMsg, (HDC)wParam, (HWND)lParam); + } +LABEL_25: + Title_KillAndFadeDlg(hWnd); + return 0; + } + if ( wParam == 1 ) + goto LABEL_25; + return 0; +} +// 1001037C: using guessed type int __stdcall SDlgDefDialogProc(_DWORD, _DWORD, _DWORD, _DWORD); +// 10010382: using guessed type _DWORD __stdcall SDrawGetFrameWindow(); + +// ref: 0x10010235 +void __fastcall Title_KillTimerAndFree(HWND hWnd) +{ + void **v2; // eax + + Title_KillTitleTimer(hWnd); + Doom_DeleteFreeProcs(hWnd, titlemsgtbl); + v2 = (void **)GetWindowLongA(hWnd, -21); + local_FreeMemPtr(v2); +} + +// ref: 0x1001025A +void __fastcall Title_LoadAllTitleImgs(HWND hWnd, int time) +{ + DWORD *v4; // edi + + v4 = local_AllocWndLongData(); + SetWindowLongA(hWnd, -21, (LONG)v4); + if ( v4 ) + { + local_LoadArtWithPal(hWnd, 0, &nullcharacter, -1, 1, "ui_art\\title.pcx", (BYTE **)v4, v4 + 1, 0); + Fade_NoInputAndArt(hWnd, 0); + } + Doom_ParseWndProc3(hWnd, titlemsgtbl, 3); + Title_LoadImgSetTimer(hWnd, "ui_art\\logo.pcx"); + if ( time ) + SDlgSetTimer((int)hWnd, 1, 1000 * time, 0); + else + SDlgSetTimer((int)hWnd, 1, 5000, 0); +} + +// ref: 0x100102D7 +void __fastcall Title_KillAndFadeDlg(HWND hWnd) +{ + Fade_Range5SetZero(); + SDlgKillTimer((int)hWnd, 1); + Fade_UpdatePaletteRange(10); + SDlgEndDialog(hWnd, (void *)HANDLE_FLAG_INHERIT); +} diff --git a/2020_03_31/DiabloUI/titlesnd.cpp b/2020_03_31/DiabloUI/titlesnd.cpp new file mode 100644 index 00000000..ad41f7c2 --- /dev/null +++ b/2020_03_31/DiabloUI/titlesnd.cpp @@ -0,0 +1,33 @@ +// ref: 0x10010306 +void __fastcall TitleSnd_SetSoundFunction(void (__stdcall *func)(const char *file)) +{ + gfnSoundFunction = func; +} + +// ref: 0x1001030D +void __cdecl TitleSnd_InitSoundFunc() +{ + gfnSoundFunction = 0; +} + +// ref: 0x10010315 +void __cdecl TitleSnd_PlayMoveSound() +{ + if ( gfnSoundFunction ) + gfnSoundFunction("sfx\\items\\titlemov.wav"); +} + +// ref: 0x1001031F +void __cdecl TitleSnd_PlaySelectSound() +{ + if ( gfnSoundFunction ) + gfnSoundFunction("sfx\\items\\titlslct.wav"); +} + +// ref: 0x1001032E +void __cdecl TitleSnd_cpp_init() +{ + titlesnd_cpp_float = titlesnd_cpp_float_value; +} +// 1001F480: using guessed type int titlesnd_cpp_float_value; +// 1002A590: using guessed type int titlesnd_cpp_float; diff --git a/2020_03_31/LICENSE b/2020_03_31/LICENSE new file mode 100644 index 00000000..cf1ab25d --- /dev/null +++ b/2020_03_31/LICENSE @@ -0,0 +1,24 @@ +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to diff --git a/2020_03_31/Makefile b/2020_03_31/Makefile new file mode 100644 index 00000000..459ea1af --- /dev/null +++ b/2020_03_31/Makefile @@ -0,0 +1,58 @@ +# mingw32 and mingw64 have different executables +ifdef MINGW32 + CC=mingw32-gcc + CXX=mingw32-g++ + DLLTOOL=dlltool + WINDRES=windres +else + CC=i686-w64-mingw32-gcc + CXX=i686-w64-mingw32-g++ + DLLTOOL=i686-w64-mingw32-dlltool + WINDRES=i686-w64-mingw32-windres +endif + +# Clang doesn't understand permissive compilation, we need to "fix" invalid +# casts from a pointer type there using +# static_cast(reinterpret_cast(ptr)) +# instead of +# (NEW_TYPE)(ptr) +CFLAGS= +CXXFLAGS=-fpermissive -Wno-write-strings +CPPFLAGS=-MMD -MF $*.d +LDLIBS=-lgdi32 -lversion -ldiabloui -lstorm +LDFLAGS=-L./ -static-libgcc -mwindows + +all: devilution.exe + +debug: CXXFLAGS += -D_DEBUG +debug: CPPFLAGS += -D_DEBUG +debug: devilution.exe + +DIABLO_SRC=$(sort $(filter-out Source/_asm.cpp Source/_render.cpp, $(wildcard Source/*.cpp))) +OBJS=$(DIABLO_SRC:.cpp=.o) + +PKWARE_SRC=$(wildcard 3rdParty/Pkware/Source/*.c) +PKWARE_OBJS=$(PKWARE_SRC:.c=.o) + +devilution.exe: $(OBJS) $(PKWARE_OBJS) diabres.o diabloui.lib storm.lib + $(CXX) $(LDFLAGS) -o $@ $^ $(LDLIBS) + +diabres.o: Diablo.rc + $(WINDRES) $< $@ + +diabloui.lib: diabloui.dll DiabloUI/diabloui_gcc.def + $(DLLTOOL) -d DiabloUI/diabloui_gcc.def -D $< -l $@ + +diabloui.dll: +# $(error Please copy diabloui.dll (version 1.09[b]) here) + +storm.lib: storm.dll 3rdParty/Storm/Source/storm_gcc.def + $(DLLTOOL) -d 3rdParty/Storm/Source/storm_gcc.def -D $< -l $@ + +storm.dll: +# $(error Please copy storm.dll (version 1.09[b]) here) + +clean: + @$(RM) -v $(OBJS) $(OBJS:.o=.d) $(PKWARE_OBJS) $(PKWARE_OBJS:.o=d) diabres.o storm.lib diabloui.lib devilution.exe + +.PHONY: clean all diff --git a/2020_03_31/MakefileVC b/2020_03_31/MakefileVC new file mode 100644 index 00000000..c096037b --- /dev/null +++ b/2020_03_31/MakefileVC @@ -0,0 +1,85 @@ +VC5_DIR ?= $(HOME)/DevStudio_5.10/VC + +# The $(VS6_DIR) directory is a copy of the "Microsoft Visual Studio" directory. +# +# To get a working setup on Linux or other "portable" copies of VS, +# the following DLLs have to be copied to the +# $(VS6_DIR)/VC98/Bin directory. +# +# - $(VS6_DIR)/Common/MSDev98/Bin/MSPDB60.DLL +# +# And to the $(VC5_DIR)/bin directory. +# +# - $(VC5_DIR)/SharedIDE/bin/MSDIS100.DLL +# - $(VC5_DIR)/SharedIDE/bin/MSPDB50.DLL +VS6_DIR ?= $(HOME)/VS6 + +VC6_DIR = $(VS6_DIR)/VC98 + +VC6_BIN_DIR = $(VC6_DIR)/Bin +VC6_INC_DIR = $(VC6_DIR)/Include +VC6_LIB_DIR = $(VC6_DIR)/Lib + +VC5_LIB_DIR = $(VC5_DIR)/lib + +IDE_DIR ?= $(VS6_DIR)/Common/MSDev98 +IDE_BIN_DIR = $(IDE_DIR)/bin +ifeq ($(OS),Windows_NT) + CL = $(VC6_BIN_DIR)/CL.EXE + RC = $(IDE_BIN_DIR)/RC.EXE + VC5_LINK = $(VC5_DIR)/bin/link.exe + VC6_LINK = $(VC6_BIN_DIR)/link.exe +else + CL = wine $(VC6_BIN_DIR)/CL.EXE + RC = wine $(IDE_BIN_DIR)/RC.EXE + VC5_LINK = wine $(VC5_DIR)/bin/link.exe + VC6_LINK = wine $(VC6_BIN_DIR)/link.exe +endif + +CFLAGS=/nologo /c /GX /W3 /O1 /I $(VC6_INC_DIR) /FD /Gr /MT /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fp"Diablo.pch" /YX /Gm /Zi +LINKFLAGS=/nologo /subsystem:windows /machine:I386 /incremental:no + +ifeq ($(MAKE_BUILD),pdb) + VC_LINK = $(VC6_LINK) + LINKFLAGS += /pdb:"Diablo.pdb" /LIBPATH:$(VC6_LIB_DIR) /debug +else + VC_LINK=$(VC5_LINK) + LINKFLAGS+= /LIBPATH:$(VC5_LIB_DIR) +endif + +all: Diablo.exe + +# fix compilation order to match the VC6 workspace files and exclude local assembly functions +DIABLO_SRC=$(sort $(filter-out Source/_asm.cpp Source/_render.cpp Source/render.cpp, $(wildcard Source/*.cpp))) +DIABLO_SRC += Source/render.cpp +OBJS=$(DIABLO_SRC:.cpp=.obj) + +STORM_SRC=$(sort $(wildcard 3rdParty/Storm/Source/*.cpp)) +STORM_OBJS=$(STORM_SRC:.cpp=.obj) + +DIABLOUI_SRC=DiabloUI/diabloui.cpp +DIABLOUI_OBJS=$(DIABLOUI_SRC:.cpp=.obj) + +Diablo.exe: main_files diablo.res DiabloUI/diabloui.lib 3rdParty/Storm/Source/storm.lib + $(VC_LINK) /OUT:$@ $(LINKFLAGS) $(OBJS) diablo.res advapi32.lib gdi32.lib shell32.lib user32.lib version.lib DiabloUI/diabloui.lib 3rdParty/Storm/Source/storm.lib 3rdParty/Pkware/implode.lib + +DiabloUI/diabloui.lib: $(DIABLOUI_OBJS) 3rdParty/Storm/Source/storm.lib + $(CL) $^ /link /LINK50COMPAT /nologo /dll /subsystem:windows /machine:I386 /LIBPATH:$(VC6_LIB_DIR) DiabloUI/diabloui.res advapi32.lib gdi32.lib shell32.lib user32.lib version.lib 3rdParty/Storm/Source/storm.lib /def:"DiabloUI/diabloui.def" /out:DiabloUI/diabloui.dll + +3rdParty/Storm/Source/storm.lib: $(STORM_OBJS) + $(CL) $^ /link /LINK50COMPAT /nologo /dll /subsystem:windows /machine:I386 /LIBPATH:$(VC6_LIB_DIR) /def:"3rdParty/Storm/Source/storm.def" /out:3rdParty/Storm/Source/storm.dll + +# compiles all main source files with once compiler call +main_files: + $(CL) $(CFLAGS) /FoSource/ $(DIABLO_SRC) + +%.obj: %.cpp + $(CL) $(CFLAGS) /Fo$@ $< + +diablo.res: Diablo.rc + $(RC) /i $(VC6_INC_DIR) /i $(VC6_DIR)/MFC/Include /l 0x409 /fo $@ $< + +clean: + @$(RM) -v $(OBJS) $(STORM_OBJS) $(DIABLOUI_OBJS) DiabloUI/diabloui.{exp,lib,dll} 3rdParty/Storm/Source/storm.{exp,lib,dll} + +.PHONY: clean all diff --git a/2020_03_31/README.md b/2020_03_31/README.md new file mode 100644 index 00000000..2bffb4f1 --- /dev/null +++ b/2020_03_31/README.md @@ -0,0 +1,118 @@ +[![Build Status](https://travis-ci.org/diasurgical/devilution.svg?branch=master)](https://travis-ci.org/diasurgical/devilution) +[![Build status](https://ci.appveyor.com/api/projects/status/ssk0xjhoka1uu940?svg=true)](https://ci.appveyor.com/project/galaxyhaxz/devilution) + +[Discord](https://discord.gg/XEKDxHK) + +# Devilution +Diablo devolved - magic behind the 1996 computer game + +Reverse engineered by GalaXyHaXz in 2018 + +# Introduction +While most titles from Blizzard receive years of love and support, Diablo stayed in the shadows. Abandoned in favor of a sequel, it remained full of bugs and unfinished potential. The game was last patched in 2001 before being discontinued altogether, a problem I wanted to fix. I played Diablo extensively as a teenager, but as time passed it became difficult to run the game on newer hardware. The lack of many improvements found in the sequel also kept it from aging well. At first the game appeared to be a lost cause, but thankfully a little oversight in 1997 made it not so. + +With Diablo's development team moving on the source code was given to **Synergistic Software** to handle the expansion. Less known however is that it was also given to **Climax Studios** to create a PlayStation port. Now Sony has long been known for letting things slide; _especially_ in Japan. Anything from leaking prototypes to full source code and Diablo was no exception. Symbolic information was accidentally left on the Japanese port. Normally used for debugging, a symbol file contains a map of everything generated during compile time. This includes file names, functions, structures, variables, and more! To top it all off a special build is hidden on the PC release in `DIABDAT.MPQ -> D1221A.MPQ -> DIABLO.EXE`! This build contains debug tools and assert strings further giving away code information. + +After months of piecing these mistakes together, Devilution was born. I present to you a reconstructed form of Diablo's original source code! Once more shall the heroes of Sanctuary return to the depths below! + +# Purpose +Having the source code makes Diablo much easier to update and maintain. For years mod-makers had to rely on tedious code editing and memory injection. A few even went further and reversed most or all of the game. The problem is that they rarely shared their work. Usually being a one-person job, they move on with their lives due to the amount of time required or lack of interest. This brings us back to square one having to do countless hours of work all over again. Devilution aims to fix this by finally making the source code open to the community. + +In order to ensure that everything is preserved, Devilution keeps everything as it was originally designed. This goes as far as bugs and badly written code in the original game. With that it serves as a base for developers to work with making it much easier than before to update, fix, and port the game to other platforms. + +As a side goal Devilution tries to document the unused and cut content from the final game. Development of Diablo was rushed near the end--many ideas were scrapped and multiplayer was quickly hacked in. By examining the source, we can see various quirks of planned development. + +# Compiling +Diablo was developed on Windows 95 using Visual C++ 4.20 and later 5.10 for newer patches. Devilution is optimized for the same tools originally used but is also compatible with modern setups. + +### Building with Visual C++ 4/5/6 +- Open the project workspace `Diablo.dsw`, choose `Debug` or `Release`, and then `Build Diablo.exe`. + +To build a binary as close as possible to the original, use [Visual C++ 5](https://winworldpc.com/product/visual-c/5x) upgraded to [Service Pack 3](http://www.mediafire.com/file/jw4j4sd5dnzze4p/VS97SP3.zip). + +### Building with Visual Studio 2010-2017 +- Open the project solution `Diablo.sln`, choose `Debug` or `Release`, and then `Build Solution`. + +Make sure to disable Data Execution Prevention. `Storm.dll` uses dynamic compilation to improve rendering performance but fails to mark the resulting memory page as executable, leading to a protection fault when trying to draw. +- Configuration options -> Linker -> Advanced -> Data Execution Prevention (DEP). +- Set this value to: No (/NXCOMPAT: NO). + +You will also need the following dependencies installed if you are using Visual Studio 2017. +Make sure to enable these when installing (or modify your installation): +- Requires "Windows 8.1 SDK" (Target Platform) +- Requires "Visual C++ MFC for x86 and x64" (For afxres.h) +- Requires "Windows Universal CRT SDK" (For ctype.h) + +### Building with MinGW +- Execute `make MINGW32=1` for **MinGW32** or `make` for **MinGW64**. Optionally add `debug` to build with debug features. + +To compile with MinGW64 on different platforms, refer to the respective documentation: [Linux](Support/INSTALL_linux.md) | [Windows](Support/INSTALL_windows.md) | [Mac](Support/INSTALL_mac.md). + +[Debug Build Features](Support/debug.md) +| [Compatibility Matrix](Support/compatibility_matrix.md) +| [Troubleshooting](Support/troubleshooting.md) + +# Installing +Once compiled, the Devilution binary will serve as a replacement for `Diablo.exe`. The following files from the original game patched to 1.09(b) need to be present: `DIABDAT.MPQ`, `DiabloUI.dll`, `SmackW32.dll`, `Standard.snp`, and `Storm.dll`. If `COPYPROT` was defined when compiling, the Diablo CD will also be required. + +Additionally, Strange Bytes' [DirectDraw patch](http://www.strangebytes.com/index.php/projects/1-diablo-1-windows-7-vista-patch) is recommended to help fix compatibility issues and run the game in windowed mode. + +# Multiplayer +TODO + +# Contributing +[Guidelines](Support/CONTRIBUTING.md) + +# Modding +Here are some screenshots of a few things I tinkered around with, to demonstrate the relative ease of improving the game: + +![Screenshot 1: Monster lifebar+items](https://s33.postimg.cc/6xnnhhlmn/diabuimon.png "Monster lifebar+items") + +![Screenshot 2: New trade screen](https://s22.postimg.cc/5i5k91vht/diabstore.png "New trade screen, items that couldn't spawn") + +# F.A.Q. +> Wow, does this mean I can download and play Diablo for free now? + +No, you'll need access to the data from the original game. Blizzard has discontinued Diablo, but there's plenty of used copies floating around. (I'm still using an original 1996-disc in 2018 without problems) +> Cool, so I fired your mod up, but there's no 1080p or new features? + +Devilution aims to keep the original code unaltered, for documentation purposes. +> So will you ever add cross-platform support or new features in the future? + +Yes! However, this will be a **_side project_** based on Devilution. I have yet to announce the project. +> When and what can I expect from the upcoming project? + +Honestly I have no idea. More than 1,200 hours went into creating Devilution, and I have other things going on right now. Maybe in 6-12 months? The goal is to create a native Linux port, convert to OpenGL, modernize the UI, etc. you get the drill. There has to be some surprises. ;) +> Ok, so I'm playing Devilution now and all the sudden it crashed. NOW WHAT?? + +Open an issue and provide as much information as possible (OS version, etc.) including any crash logs. +> I thought I'd fix the crash myself, but after looking at the code its a disaster. Do you speak v2-34-v8? + +That is the result of decompiled code. Whenever a program is compiled, much of the source is optimized and stripped away, so it's nearly impossible to decompile it back. Have patience. Everything will be cleaned up eventually. :) +> Will you be reverse engineering Diablo II next? Ooooh please! + +Absolutely not. Diablo II would require far more work and is still supported by Blizzard. Setting that aside, there are rumors that the game will be remastered which takes the point out of it. +> Are you interested in working for me? I have this game I want you to reverse... + +Sorry, but no. This project is time consuming enough as it is, and it's just a hobby. +> I think that's about all, but is Devilution even legal? + +That's a tricky question. Under the DMCA, reverse-engineering has exceptions for the purpose of documentation and interoperability. Devilution provides the necessary documentation needed to achieve the latter. However, it falls into an entirely gray area. The real question is whether or not Blizzard deems it necessary to take action. + +# Credits +- [sanctuary](https://github.com/sanctuary) - extensively documenting Diablo's game engine +- [BWAPI Team](https://github.com/bwapi) - providing library API to work with Storm +- [Ladislav Zezula](https://github.com/ladislav-zezula) - reversing PKWARE library, further documenting Storm +- [fearedbliss](https://github.com/fearedbliss) - being awe-inspiring +- Climax Studios & Sony - secretly helping with their undercover QA :P +- Blizzard North - wait, this was a typo! +- Depression - reason to waste four months of my life doing this ;) + +# Legal +This software is being released to the Public Domain. No assets of Diablo are being provided. You must own a copy of Diablo and have access to the assets beforehand in order to use this software. + +Battle.net(R) - Copyright (C) 1996 Blizzard Entertainment, Inc. All rights reserved. Battle.net and Blizzard Entertainment are trademarks or registered trademarks of Blizzard Entertainment, Inc. in the U.S. and/or other countries. + +Diablo(R) - Copyright (C) 1996 Blizzard Entertainment, Inc. All rights reserved. Diablo and Blizzard Entertainment are trademarks or registered trademarks of Blizzard Entertainment, Inc. in the U.S. and/or other countries. + +This software is in no way associated with or endorsed by Blizzard Entertainment(R). diff --git a/2020_03_31/Source/Data/Excel/xl_ipre.txt b/2020_03_31/Source/Data/Excel/xl_ipre.txt new file mode 100644 index 00000000..06686ce8 --- /dev/null +++ b/2020_03_31/Source/Data/Excel/xl_ipre.txt @@ -0,0 +1,85 @@ +PLName(s) PLPower(i) PLParam1(i) PLParam2(i) PLMinLvl(i) PLIType(i) PLGOE(i) PLDouble(i) PLOk(i) PLMinVal(i) PLMaxVal(i) PLMultVal(i) +Tin IPL_TOHIT_CURSE 6 10 3 PLT_WEAP|PLT_BOW|PLT_MISC 0 1 0 0 0 -3 +Brass IPL_TOHIT_CURSE 1 5 1 PLT_WEAP|PLT_BOW|PLT_MISC 0 1 0 0 0 -2 +Bronze IPL_TOHIT 1 5 1 PLT_WEAP|PLT_BOW|PLT_MISC 0 1 1 100 500 2 +Iron IPL_TOHIT 6 10 4 PLT_WEAP|PLT_BOW|PLT_MISC 0 1 1 600 1000 3 +Steel IPL_TOHIT 11 15 6 PLT_WEAP|PLT_BOW|PLT_MISC 0 1 1 1100 1500 5 +Silver IPL_TOHIT 16 20 9 PLT_WEAP|PLT_BOW|PLT_MISC 16 1 1 1600 2000 7 +Gold IPL_TOHIT 21 30 12 PLT_WEAP|PLT_BOW|PLT_MISC 16 1 1 2100 3000 9 +Platinum IPL_TOHIT 31 40 16 PLT_WEAP|PLT_BOW 16 1 1 3100 4000 11 +Mithril IPL_TOHIT 41 60 20 PLT_WEAP|PLT_BOW 16 1 1 4100 6000 13 +Meteoric IPL_TOHIT 61 80 23 PLT_WEAP|PLT_BOW 0 1 1 6100 10000 15 +Weird IPL_TOHIT 81 100 35 PLT_WEAP|PLT_BOW 0 1 1 10100 14000 17 +Strange IPL_TOHIT 101 150 60 PLT_WEAP|PLT_BOW 0 1 1 14100 20000 20 +Useless IPL_DAMP_CURSE 100 100 5 PLT_WEAP|PLT_BOW 0 1 0 0 0 -8 +Bent IPL_DAMP_CURSE 50 75 3 PLT_WEAP|PLT_BOW 0 1 0 0 0 -4 +Weak IPL_DAMP_CURSE 25 45 1 PLT_WEAP|PLT_BOW 0 1 0 0 0 -3 +Jagged IPL_DAMP 20 35 4 PLT_WEAP|PLT_BOW 0 1 1 250 450 3 +Deadly IPL_DAMP 36 50 6 PLT_WEAP|PLT_BOW 0 1 1 500 700 4 +Heavy IPL_DAMP 51 65 9 PLT_WEAP|PLT_BOW 0 1 1 750 950 5 +Vicious IPL_DAMP 66 80 12 PLT_WEAP|PLT_BOW 1 1 1 1000 1450 8 +Brutal IPL_DAMP 81 95 16 PLT_WEAP|PLT_BOW 0 1 1 1500 1950 10 +Massive IPL_DAMP 96 110 20 PLT_WEAP|PLT_BOW 0 1 1 2000 2450 13 +Savage IPL_DAMP 111 125 23 PLT_WEAP|PLT_BOW 0 1 1 2500 3000 15 +Ruthless IPL_DAMP 126 150 35 PLT_WEAP|PLT_BOW 0 1 1 10100 15000 17 +Merciless IPL_DAMP 151 175 60 PLT_WEAP|PLT_BOW 0 1 1 15000 20000 20 +Clumsy IPL_TOHIT_DAMP_CURSE 50 75 5 PLT_WEAP|PLT_STAFF|PLT_BOW 0 1 0 0 0 -7 +Dull IPL_TOHIT_DAMP_CURSE 25 45 1 PLT_WEAP|PLT_STAFF|PLT_BOW 0 1 0 0 0 -5 +Sharp IPL_TOHIT_DAMP 20 35 1 PLT_WEAP|PLT_STAFF|PLT_BOW 0 1 0 350 950 5 +Fine IPL_TOHIT_DAMP 36 50 6 PLT_WEAP|PLT_STAFF|PLT_BOW 0 1 1 1100 1700 7 +Warrior's IPL_TOHIT_DAMP 51 65 10 PLT_WEAP|PLT_STAFF|PLT_BOW 0 1 1 1850 2450 13 +Soldier's IPL_TOHIT_DAMP 66 80 15 PLT_WEAP|PLT_STAFF 0 1 1 2600 3950 17 +Lord's IPL_TOHIT_DAMP 81 95 19 PLT_WEAP|PLT_STAFF 0 1 1 4100 5950 21 +Knight's IPL_TOHIT_DAMP 96 110 23 PLT_WEAP|PLT_STAFF 0 1 1 6100 8450 26 +Master's IPL_TOHIT_DAMP 111 125 28 PLT_WEAP|PLT_STAFF 0 1 1 8600 13000 30 +Champion's IPL_TOHIT_DAMP 126 150 40 PLT_WEAP|PLT_STAFF 0 1 1 15200 24000 33 +King's IPL_TOHIT_DAMP 151 175 28 PLT_WEAP|PLT_STAFF 0 1 1 24100 35000 38 +Vulnerable IPL_ACP_CURSE 51 100 3 PLT_ARMO|PLT_SHLD 0 1 0 0 0 -3 +Rusted IPL_ACP_CURSE 25 50 1 PLT_ARMO|PLT_SHLD 0 1 0 0 0 -2 +Fine IPL_ACP 20 30 1 PLT_ARMO|PLT_SHLD 0 1 1 20 100 2 +Strong IPL_ACP 31 40 3 PLT_ARMO|PLT_SHLD 0 1 1 120 200 3 +Grand IPL_ACP 41 55 6 PLT_ARMO|PLT_SHLD 0 1 1 220 300 5 +Valiant IPL_ACP 56 70 10 PLT_ARMO|PLT_SHLD 0 1 1 320 400 7 +Glorious IPL_ACP 71 90 14 PLT_ARMO|PLT_SHLD 16 1 1 420 600 9 +Blessed IPL_ACP 91 110 19 PLT_ARMO|PLT_SHLD 16 1 1 620 800 11 +Saintly IPL_ACP 111 130 24 PLT_ARMO|PLT_SHLD 16 1 1 820 1200 13 +Awesome IPL_ACP 131 150 28 PLT_ARMO|PLT_SHLD 16 1 1 1220 2000 15 +Holy IPL_ACP 151 170 35 PLT_ARMO|PLT_SHLD 16 1 1 5200 6000 17 +Godly IPL_ACP 171 200 60 PLT_ARMO|PLT_SHLD 16 1 1 6200 7000 20 +Red IPL_FIRERES 10 20 4 PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_STAFF|PLT_BOW|PLT_MISC 0 0 1 500 1500 2 +Crimson IPL_FIRERES 21 30 10 PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_STAFF|PLT_BOW|PLT_MISC 0 0 1 2100 3000 2 +Crimson IPL_FIRERES 31 40 16 PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_STAFF|PLT_BOW|PLT_MISC 0 0 1 3100 4000 2 +Garnet IPL_FIRERES 41 50 20 PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_STAFF|PLT_BOW|PLT_MISC 0 0 1 8200 12000 3 +Ruby IPL_FIRERES 51 60 26 PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_STAFF|PLT_BOW|PLT_MISC 0 0 1 17100 20000 5 +Blue IPL_LIGHTRES 10 20 4 PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_STAFF|PLT_BOW|PLT_MISC 0 0 1 500 1500 2 +Azure IPL_LIGHTRES 21 30 10 PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_STAFF|PLT_BOW|PLT_MISC 0 0 1 2100 3000 2 +Lapis IPL_LIGHTRES 31 40 16 PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_STAFF|PLT_BOW|PLT_MISC 0 0 1 3100 4000 2 +Cobalt IPL_LIGHTRES 41 50 20 PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_STAFF|PLT_BOW|PLT_MISC 0 0 1 8200 12000 3 +Sapphire IPL_LIGHTRES 51 60 26 PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_STAFF|PLT_BOW|PLT_MISC 0 0 1 17100 20000 5 +White IPL_MAGICRES 10 20 4 PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_STAFF|PLT_BOW|PLT_MISC 0 0 1 500 1500 2 +Pearl IPL_MAGICRES 21 30 10 PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_STAFF|PLT_BOW|PLT_MISC 0 0 1 2100 3000 2 +Ivory IPL_MAGICRES 31 40 16 PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_STAFF|PLT_BOW|PLT_MISC 0 0 1 3100 4000 2 +Crystal IPL_MAGICRES 41 50 20 PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_STAFF|PLT_BOW|PLT_MISC 0 0 1 8200 12000 3 +Diamond IPL_MAGICRES 51 60 26 PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_STAFF|PLT_BOW|PLT_MISC 0 0 1 17100 20000 5 +Topaz IPL_ALLRES 10 15 8 PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_STAFF|PLT_BOW|PLT_MISC 0 0 1 2000 5000 3 +Amber IPL_ALLRES 16 20 12 PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_STAFF|PLT_BOW|PLT_MISC 0 0 1 7400 10000 3 +Jade IPL_ALLRES 21 30 18 PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_STAFF|PLT_BOW|PLT_MISC 0 0 1 11000 15000 3 +Obsidian IPL_ALLRES 31 40 24 PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_STAFF|PLT_BOW|PLT_MISC 0 0 1 24000 40000 4 +Emerald IPL_ALLRES 41 50 31 PLT_SHLD|PLT_WEAP|PLT_STAFF|PLT_BOW 0 0 1 61000 75000 7 +Hyena's IPL_MANA_CURSE 11 25 4 PLT_STAFF|PLT_MISC 0 0 0 100 1000 -2 +Frog's IPL_MANA_CURSE 1 10 1 PLT_STAFF|PLT_MISC 1 0 0 0 0 -2 +Spider's IPL_MANA 10 15 1 PLT_STAFF|PLT_MISC 1 0 1 500 1000 2 +Raven's IPL_MANA 15 20 5 PLT_STAFF|PLT_MISC 0 0 1 1100 2000 3 +Snake's IPL_MANA 21 30 9 PLT_STAFF|PLT_MISC 0 0 1 2100 4000 5 +Serpent's IPL_MANA 30 40 15 PLT_STAFF|PLT_MISC 0 0 1 4100 6000 7 +Drake's IPL_MANA 41 50 21 PLT_STAFF|PLT_MISC 0 0 1 6100 10000 9 +Dragon's IPL_MANA 51 60 27 PLT_STAFF|PLT_MISC 0 0 1 10100 15000 11 +Wyrm's IPL_MANA 61 80 35 PLT_STAFF 0 0 1 15100 19000 12 +Hydra's IPL_MANA 81 100 60 PLT_STAFF 0 0 1 19100 30000 13 +Angel's IPL_SPLLVLADD 1 1 15 PLT_STAFF 16 0 1 25000 25000 2 +Arch-Angel's IPL_SPLLVLADD 2 2 25 PLT_STAFF 16 0 1 50000 50000 3 +Plentiful IPL_CHARGES 2 2 4 PLT_STAFF 0 0 1 2000 2000 2 +Bountiful IPL_CHARGES 3 3 9 PLT_STAFF 0 0 1 3000 3000 3 +Flaming IPL_FIREDAM 1 10 7 PLT_WEAP|PLT_STAFF 0 0 1 5000 5000 2 +Lightning IPL_LIGHTDAM 2 20 18 PLT_WEAP|PLT_STAFF 0 0 1 10000 10000 2 +~ IPL_INVALID 0 0 0 0 0 0 0 0 0 0 diff --git a/2020_03_31/Source/Data/Excel/xl_isuf.txt b/2020_03_31/Source/Data/Excel/xl_isuf.txt new file mode 100644 index 00000000..c20e8f48 --- /dev/null +++ b/2020_03_31/Source/Data/Excel/xl_isuf.txt @@ -0,0 +1,97 @@ +PLName(s) PLPower(i) PLParam1(i) PLParam2(i) PLMinLvl(i) PLIType(i) PLGOE(i) PLDouble(i) PLOk(i) PLMinVal(i) PLMaxVal(i) PLMultVal(i) +quality IPL_DAMMOD 1 2 2 PLT_WEAP|PLT_BOW 0 0 1 100 200 2 +maiming IPL_DAMMOD 3 5 7 PLT_WEAP|PLT_BOW 0 0 1 1300 1500 3 +slaying IPL_DAMMOD 6 8 15 PLT_WEAP 0 0 1 2600 3000 5 +gore IPL_DAMMOD 9 12 25 PLT_WEAP 0 0 1 4100 5000 8 +carnage IPL_DAMMOD 13 16 35 PLT_WEAP 0 0 1 5100 10000 10 +slaughter IPL_DAMMOD 17 20 60 PLT_WEAP 0 0 1 10100 15000 13 +pain IPL_GETHIT_CURSE 2 4 4 PLT_ARMO|PLT_SHLD|PLT_MISC 1 0 0 0 0 -4 +tears IPL_GETHIT_CURSE 1 1 2 PLT_ARMO|PLT_SHLD|PLT_MISC 1 0 0 0 0 -2 +health IPL_GETHIT 1 1 2 PLT_ARMO|PLT_SHLD|PLT_MISC 16 0 1 200 200 2 +protection IPL_GETHIT 2 2 6 PLT_ARMO|PLT_SHLD 16 0 1 400 800 4 +absorption IPL_GETHIT 3 3 12 PLT_ARMO|PLT_SHLD 16 0 1 1001 2500 10 +deflection IPL_GETHIT 4 4 20 PLT_ARMO 16 0 1 2500 6500 15 +osmosis IPL_GETHIT 5 6 50 PLT_ARMO 16 0 1 7500 10000 20 +frailty IPL_STR_CURSE 6 10 3 PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_BOW|PLT_MISC 1 0 0 0 0 -3 +weakness IPL_STR_CURSE 1 5 1 PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_BOW|PLT_MISC 1 0 0 0 0 -2 +strength IPL_STR 1 5 1 PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_BOW|PLT_MISC 0 0 1 200 1000 2 +might IPL_STR 6 10 5 PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_BOW|PLT_MISC 0 0 1 1200 2000 3 +power IPL_STR 11 15 11 PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_BOW|PLT_MISC 0 0 1 2200 3000 4 +giants IPL_STR 16 20 17 PLT_ARMO|PLT_WEAP|PLT_BOW|PLT_MISC 0 0 1 3200 5000 7 +titans IPL_STR 21 30 23 PLT_WEAP|PLT_MISC 0 0 1 5200 10000 10 +paralysis IPL_DEX_CURSE 6 10 3 PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_BOW|PLT_MISC 1 0 0 0 0 -3 +atrophy IPL_DEX_CURSE 1 5 1 PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_BOW|PLT_MISC 1 0 0 0 0 -2 +dexterity IPL_DEX 1 5 1 PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_BOW|PLT_MISC 0 0 1 200 1000 2 +skill IPL_DEX 6 10 5 PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_BOW|PLT_MISC 0 0 1 1200 2000 3 +accuracy IPL_DEX 11 15 11 PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_BOW|PLT_MISC 0 0 1 2200 3000 4 +precision IPL_DEX 16 20 17 PLT_ARMO|PLT_WEAP|PLT_BOW|PLT_MISC 0 0 1 3200 5000 7 +perfection IPL_DEX 21 30 23 PLT_BOW|PLT_MISC 0 0 1 5200 10000 10 +the fool IPL_MAG_CURSE 6 10 3 PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_STAFF|PLT_BOW|PLT_MISC 1 0 0 0 0 -3 +dyslexia IPL_MAG_CURSE 1 5 1 PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_STAFF|PLT_BOW|PLT_MISC 1 0 0 0 0 -2 +magic IPL_MAG 1 5 1 PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_STAFF|PLT_BOW|PLT_MISC 0 0 1 200 1000 2 +the mind IPL_MAG 6 10 5 PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_STAFF|PLT_BOW|PLT_MISC 0 0 1 1200 2000 3 +brilliance IPL_MAG 11 15 11 PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_STAFF|PLT_BOW|PLT_MISC 0 0 1 2200 3000 4 +sorcery IPL_MAG 16 20 17 PLT_ARMO|PLT_WEAP|PLT_STAFF|PLT_BOW|PLT_MISC 0 0 1 3200 5000 7 +wizardry IPL_MAG 21 30 23 PLT_STAFF|PLT_MISC 0 0 1 5200 10000 10 +illness IPL_VIT_CURSE 6 10 3 PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_BOW|PLT_MISC 1 0 0 0 0 -3 +disease IPL_VIT_CURSE 1 5 1 PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_BOW|PLT_MISC 1 0 0 0 0 -2 +vitality IPL_VIT 1 5 1 PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_BOW|PLT_MISC 16 0 1 200 1000 2 +zest IPL_VIT 6 10 5 PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_BOW|PLT_MISC 16 0 1 1200 2000 3 +vim IPL_VIT 11 15 11 PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_BOW|PLT_MISC 16 0 1 2200 3000 4 +vigor IPL_VIT 16 20 17 PLT_ARMO|PLT_WEAP|PLT_BOW|PLT_MISC 16 0 1 3200 5000 7 +life IPL_VIT 21 30 23 PLT_MISC 16 0 1 5200 10000 10 +trouble IPL_ATTRIBS_CURSE 6 10 12 PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_BOW|PLT_MISC 1 0 0 0 0 -10 +the pit IPL_ATTRIBS_CURSE 1 5 5 PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_BOW|PLT_MISC 1 0 0 0 0 -5 +the sky IPL_ATTRIBS 1 3 5 PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_BOW|PLT_MISC 0 0 1 800 4000 5 +the moon IPL_ATTRIBS 4 7 11 PLT_ARMO|PLT_SHLD|PLT_WEAP|PLT_BOW|PLT_MISC 0 0 1 4800 8000 10 +the stars IPL_ATTRIBS 8 11 17 PLT_ARMO|PLT_WEAP|PLT_BOW|PLT_MISC 0 0 1 8800 12000 15 +the heavens IPL_ATTRIBS 12 15 25 PLT_WEAP|PLT_BOW|PLT_MISC 0 0 1 12800 20000 20 +the zodiac IPL_ATTRIBS 16 20 30 PLT_MISC 0 0 1 20800 40000 30 +the vulture IPL_LIFE_CURSE 11 25 4 PLT_ARMO|PLT_SHLD|PLT_MISC 1 0 0 0 0 -4 +the jackal IPL_LIFE_CURSE 1 10 1 PLT_ARMO|PLT_SHLD|PLT_MISC 1 0 0 0 0 -2 +the fox IPL_LIFE 10 15 1 PLT_ARMO|PLT_SHLD|PLT_MISC 0 0 1 100 1000 2 +the jaguar IPL_LIFE 16 20 5 PLT_ARMO|PLT_SHLD|PLT_MISC 0 0 1 1100 2000 3 +the eagle IPL_LIFE 21 30 9 PLT_ARMO|PLT_SHLD|PLT_MISC 0 0 1 2100 4000 5 +the wolf IPL_LIFE 30 40 15 PLT_ARMO|PLT_SHLD|PLT_MISC 0 0 1 4100 6000 7 +the tiger IPL_LIFE 41 50 21 PLT_ARMO|PLT_SHLD|PLT_MISC 0 0 1 6100 10000 9 +the lion IPL_LIFE 51 60 27 PLT_ARMO|PLT_MISC 0 0 1 10100 15000 11 +the mammoth IPL_LIFE 61 80 35 PLT_ARMO 0 0 1 15100 19000 12 +the whale IPL_LIFE 81 100 60 PLT_ARMO 0 0 1 19100 30000 13 +fragility IPL_DUR_CURSE 100 100 3 PLT_ARMO|PLT_SHLD|PLT_WEAP 1 0 0 0 0 -4 +brittleness IPL_DUR_CURSE 26 75 1 PLT_ARMO|PLT_SHLD|PLT_WEAP 1 0 0 0 0 -2 +sturdiness IPL_DUR 26 75 1 PLT_ARMO|PLT_SHLD|PLT_WEAP 0 0 1 100 100 2 +craftsmanship IPL_DUR 51 100 6 PLT_ARMO|PLT_SHLD|PLT_WEAP 0 0 1 200 200 2 +structure IPL_DUR 101 200 12 PLT_ARMO|PLT_SHLD|PLT_WEAP 0 0 1 300 300 2 +the ages IPL_INDESTRUCTIBLE 0 0 25 PLT_ARMO|PLT_SHLD|PLT_WEAP 0 0 1 600 600 5 +the dark IPL_LIGHT_CURSE 4 4 6 PLT_ARMO|PLT_WEAP|PLT_MISC 1 0 0 0 0 -3 +the night IPL_LIGHT_CURSE 2 2 3 PLT_ARMO|PLT_WEAP|PLT_MISC 1 0 0 0 0 -2 +light IPL_LIGHT 2 2 4 PLT_ARMO|PLT_WEAP|PLT_MISC 16 0 1 750 750 2 +radiance IPL_LIGHT 4 4 8 PLT_ARMO|PLT_WEAP|PLT_MISC 16 0 1 1500 1500 3 +flame IPL_FIRE_ARROWS 1 3 1 PLT_BOW 0 0 1 2000 2000 2 +fire IPL_FIRE_ARROWS 1 6 11 PLT_BOW 0 0 1 4000 4000 4 +burning IPL_FIRE_ARROWS 1 16 35 PLT_BOW 0 0 1 6000 6000 6 +shock IPL_LIGHT_ARROWS 1 6 13 PLT_BOW 0 0 1 6000 6000 2 +lightning IPL_LIGHT_ARROWS 1 10 21 PLT_BOW 0 0 1 8000 8000 4 +thunder IPL_LIGHT_ARROWS 1 20 60 PLT_BOW 0 0 1 12000 12000 6 +many IPL_DUR 100 100 3 PLT_BOW 0 0 1 750 750 2 +plenty IPL_DUR 200 200 7 PLT_BOW 0 0 1 1500 1500 3 +thorns IPL_THORNS 1 3 1 PLT_ARMO|PLT_SHLD 0 0 1 500 500 2 +corruption IPL_NOMANA 0 0 5 PLT_ARMO|PLT_SHLD|PLT_WEAP 1 0 0 -1000 -1000 2 +thieves IPL_ABSHALFTRAP 0 0 11 PLT_ARMO|PLT_SHLD|PLT_MISC 0 0 1 1500 1500 2 +the bear IPL_KNOCKBACK 0 0 5 PLT_WEAP|PLT_STAFF|PLT_BOW 1 0 1 750 750 2 +the bat IPL_STEALMANA 3 3 8 PLT_WEAP 0 0 1 7500 7500 3 +vampires IPL_STEALMANA 5 5 19 PLT_WEAP 0 0 1 15000 15000 3 +the leech IPL_STEALLIFE 3 3 8 PLT_WEAP 0 0 1 7500 7500 3 +blood IPL_STEALLIFE 5 5 19 PLT_WEAP 0 0 1 15000 15000 3 +piercing IPL_TARGAC 2 6 1 PLT_WEAP|PLT_BOW 0 0 1 1000 1000 3 +puncturing IPL_TARGAC 4 12 9 PLT_WEAP|PLT_BOW 0 0 1 2000 2000 6 +bashing IPL_TARGAC 8 24 17 PLT_WEAP 0 0 1 4000 4000 12 +readiness IPL_FASTATTACK 1 1 1 PLT_WEAP|PLT_STAFF|PLT_BOW 0 0 1 2000 2000 2 +swiftness IPL_FASTATTACK 2 2 10 PLT_WEAP|PLT_STAFF|PLT_BOW 0 0 1 4000 4000 4 +speed IPL_FASTATTACK 3 3 19 PLT_WEAP|PLT_STAFF 0 0 1 8000 8000 8 +haste IPL_FASTATTACK 4 4 27 PLT_WEAP|PLT_STAFF 0 0 1 16000 16000 16 +balance IPL_FASTRECOVER 1 1 1 PLT_ARMO|PLT_MISC 0 0 1 2000 2000 2 +stability IPL_FASTRECOVER 2 2 10 PLT_ARMO|PLT_MISC 0 0 1 4000 4000 4 +harmony IPL_FASTRECOVER 3 3 20 PLT_ARMO|PLT_MISC 0 0 1 8000 8000 8 +blocking IPL_FASTBLOCK 1 1 5 PLT_SHLD 0 0 1 4000 4000 4 +~ IPL_INVALID 0 0 0 0 0 0 0 0 0 0 diff --git a/2020_03_31/Source/Data/Excel/xl_item.txt b/2020_03_31/Source/Data/Excel/xl_item.txt new file mode 100644 index 00000000..a10cc041 --- /dev/null +++ b/2020_03_31/Source/Data/Excel/xl_item.txt @@ -0,0 +1,158 @@ +iRnd(i) iClass(i) iLoc(i) iCurs(i) itype(i) iItemId(i) iName(s) iSName(s) iMinMLvl(i) iDurability(i) iMinDam(i) iMaxDam(i) iMinAC(i) iMaxAC(i) iMinStr(i) iMinMag(i) iMinDex(i) iFlags(i) iMiscId(i) iSpell(i) iUsable(i) iValue(i) iMaxValue(i) +IDROP_REGULAR ICLASS_GOLD ILOC_UNEQUIPABLE 168 11 UITYPE_NONE Gold NULL 1 0 0 0 0 0 0 0 0 ISPL_NONE IMISC_NONE SPL_NULL 1 0 0 +IDROP_NEVER ICLASS_WEAPON ILOC_ONEHAND 64 1 UITYPE_NONE Short Sword NULL 2 20 2 6 0 0 18 0 0 ISPL_NONE IMISC_NONE SPL_NULL 0 50 50 +IDROP_NEVER ICLASS_ARMOR ILOC_ONEHAND 83 5 UITYPE_NONE Buckler NULL 2 10 0 0 3 3 0 0 0 ISPL_NONE IMISC_NONE SPL_NULL 0 50 50 +IDROP_NEVER ICLASS_WEAPON ILOC_ONEHAND 66 4 UITYPE_SPIKCLUB Club NULL 1 20 1 6 0 0 0 0 0 ISPL_NONE IMISC_NONE SPL_NULL 0 20 20 +IDROP_NEVER ICLASS_WEAPON ILOC_TWOHAND 118 3 UITYPE_NONE Short Bow NULL 1 30 1 4 0 0 0 0 0 ISPL_NONE IMISC_NONE SPL_NULL 0 100 100 +IDROP_NEVER ICLASS_WEAPON ILOC_TWOHAND 109 10 UITYPE_NONE Short Staff of Charged Bolt NULL 1 25 2 4 0 0 0 20 0 ISPL_NONE IMISC_STAFF SPL_CBOLT 0 520 520 +IDROP_NEVER ICLASS_WEAPON ILOC_TWOHAND 106 2 UITYPE_CLEAVER Cleaver NULL 10 10 4 24 0 0 0 0 0 ISPL_NONE IMISC_UNIQUE SPL_NULL 0 2000 2000 +IDROP_NEVER ICLASS_ARMOR ILOC_HELM 78 7 UITYPE_SKCROWN The Undead Crown NULL 0 50 0 0 15 15 0 0 0 ISPL_RNDSTEALLIFE IMISC_UNIQUE SPL_NULL 0 10000 10000 +IDROP_NEVER ICLASS_MISC ILOC_RING 18 12 UITYPE_INFRARING Empyrean Band NULL 0 0 0 0 0 0 0 0 0 ISPL_NONE IMISC_UNIQUE SPL_NULL 0 8000 8000 +IDROP_NEVER ICLASS_QUEST ILOC_UNEQUIPABLE 76 0 UITYPE_NONE Magic Rock NULL 0 0 0 0 0 0 0 0 0 ISPL_NONE IMISC_NONE SPL_NULL 0 0 0 +IDROP_NEVER ICLASS_MISC ILOC_AMULET 44 13 UITYPE_OPTAMULET Optic Amulet NULL 0 0 0 0 0 0 0 0 0 ISPL_NONE IMISC_UNIQUE SPL_NULL 0 5000 5000 +IDROP_NEVER ICLASS_MISC ILOC_RING 10 12 UITYPE_TRING Ring of Truth NULL 0 0 0 0 0 0 0 0 0 ISPL_NONE IMISC_UNIQUE SPL_NULL 0 1000 1000 +IDROP_NEVER ICLASS_QUEST ILOC_UNEQUIPABLE 126 0 UITYPE_NONE Tavern Sign NULL 0 0 0 0 0 0 0 0 0 ISPL_NONE IMISC_NONE SPL_NULL 0 0 0 +IDROP_NEVER ICLASS_ARMOR ILOC_HELM 93 7 UITYPE_HARCREST Harlequin Crest NULL 0 15 0 0 0 0 0 0 0 ISPL_NONE IMISC_UNIQUE SPL_NULL 0 15 20 +IDROP_NEVER ICLASS_ARMOR ILOC_HELM 85 7 UITYPE_STEELVEIL Veil of Steel NULL 0 60 0 0 18 18 0 0 0 ISPL_NONE IMISC_UNIQUE SPL_NULL 0 0 0 +IDROP_NEVER ICLASS_MISC ILOC_UNEQUIPABLE 17 0 UITYPE_ELIXIR Golden Elixir NULL 15 0 0 0 0 0 0 0 0 ISPL_NONE IMISC_NONE SPL_NULL 0 0 0 +IDROP_NEVER ICLASS_QUEST ILOC_UNEQUIPABLE 140 0 UITYPE_NONE Anvil of Fury NULL 0 0 0 0 0 0 0 0 0 ISPL_NONE IMISC_NONE SPL_NULL 0 0 0 +IDROP_NEVER ICLASS_QUEST ILOC_UNEQUIPABLE 89 0 UITYPE_NONE Black Mushroom NULL 0 0 0 0 0 0 0 0 0 ISPL_NONE IMISC_NONE SPL_NULL 0 0 0 +IDROP_NEVER ICLASS_QUEST ILOC_UNEQUIPABLE 40 0 UITYPE_NONE Brain NULL 0 0 0 0 0 0 0 0 0 ISPL_NONE IMISC_NONE SPL_NULL 0 0 0 +IDROP_NEVER ICLASS_QUEST ILOC_UNEQUIPABLE 97 0 UITYPE_NONE Fungal Tome NULL 0 0 0 0 0 0 0 0 0 ISPL_NONE IMISC_NONE SPL_NULL 0 0 0 +IDROP_NEVER ICLASS_MISC ILOC_UNEQUIPABLE 15 0 UITYPE_ELIXIR Spectral Elixir NULL 15 0 0 0 0 0 0 0 0 ISPL_NONE IMISC_SPECELIX SPL_NULL 0 0 0 +IDROP_NEVER ICLASS_QUEST ILOC_UNEQUIPABLE 25 0 UITYPE_NONE Blood Stone NULL 0 0 0 0 0 0 0 0 0 ISPL_NONE IMISC_NONE SPL_NULL 0 0 0 +IDROP_NEVER ICLASS_QUEST ILOC_UNEQUIPABLE 96 0 UITYPE_MAPOFDOOM Map of the Stars NULL 0 0 0 0 0 0 0 0 0 ISPL_NONE IMISC_MAPOFDOOM SPL_NULL 1 0 0 +IDROP_NEVER ICLASS_QUEST ILOC_UNEQUIPABLE 19 0 UITYPE_NONE Heart NULL 0 0 0 0 0 0 0 0 0 ISPL_NONE IMISC_EAR SPL_NULL 0 0 0 +IDROP_NEVER ICLASS_MISC ILOC_UNEQUIPABLE 32 0 UITYPE_NONE Potion of Healing NULL 0 0 0 0 0 0 0 0 0 ISPL_NONE IMISC_HEAL SPL_NULL 1 50 50 +IDROP_NEVER ICLASS_MISC ILOC_UNEQUIPABLE 39 0 UITYPE_NONE Potion of Mana NULL 0 0 0 0 0 0 0 0 0 ISPL_NONE IMISC_MANA SPL_NULL 1 50 50 +IDROP_NEVER ICLASS_MISC ILOC_UNEQUIPABLE 1 0 UITYPE_NONE Scroll of Identify NULL 1 0 0 0 0 0 0 0 0 ISPL_NONE IMISC_SCROLL SPL_IDENTIFY 1 200 200 +IDROP_NEVER ICLASS_MISC ILOC_UNEQUIPABLE 1 0 UITYPE_NONE Scroll of Town Portal NULL 4 0 0 0 0 0 0 0 0 ISPL_NONE IMISC_SCROLL SPL_TOWN 1 200 200 +IDROP_NEVER ICLASS_ARMOR ILOC_ARMOR 157 8 UITYPE_ARMOFVAL Arkaine's Valor NULL 0 40 0 0 0 0 0 0 0 ISPL_NONE IMISC_UNIQUE SPL_NULL 0 0 0 +IDROP_NEVER ICLASS_MISC ILOC_UNEQUIPABLE 35 0 UITYPE_NONE Potion of Full Healing NULL 1 0 0 0 0 0 0 0 0 ISPL_NONE IMISC_FULLHEAL SPL_NULL 1 150 150 +IDROP_NEVER ICLASS_MISC ILOC_UNEQUIPABLE 0 0 UITYPE_NONE Potion of Full Mana NULL 1 0 0 0 0 0 0 0 0 ISPL_NONE IMISC_FULLMANA SPL_NULL 1 150 150 +IDROP_NEVER ICLASS_WEAPON ILOC_ONEHAND 61 1 UITYPE_GRISWOLD Griswold's Edge NULL 8 50 4 12 0 0 40 0 0 ISPL_NONE IMISC_UNIQUE SPL_NULL 0 750 750 +IDROP_NEVER ICLASS_WEAPON ILOC_ONEHAND 59 4 UITYPE_LGTFORGE Lightforge NULL 2 32 1 8 0 0 16 0 0 ISPL_NONE IMISC_UNIQUE SPL_NULL 0 200 200 +IDROP_NEVER ICLASS_MISC ILOC_UNEQUIPABLE 155 0 UITYPE_LAZSTAFF Staff of Lazarus NULL 0 0 0 0 0 0 0 0 0 ISPL_NONE IMISC_NONE SPL_NULL 0 0 0 +IDROP_NEVER ICLASS_MISC ILOC_UNEQUIPABLE 1 0 UITYPE_NONE Scroll of Resurrect NULL 1 0 0 0 0 0 0 0 0 ISPL_NONE IMISC_SCROLLT SPL_RESURRECT 1 250 250 +IDROP_NEVER ICLASS_NONE ILOC_NONE 0 0 UITYPE_NONE NULL NULL 0 0 0 0 0 0 0 0 0 ISPL_NONE IMISC_NONE SPL_NULL 0 0 0 +IDROP_NEVER ICLASS_NONE ILOC_NONE 0 0 UITYPE_NONE NULL NULL 0 0 0 0 0 0 0 0 0 ISPL_NONE IMISC_NONE SPL_NULL 0 0 0 +IDROP_NEVER ICLASS_NONE ILOC_NONE 0 0 UITYPE_NONE NULL NULL 0 0 0 0 0 0 0 0 0 ISPL_NONE IMISC_NONE SPL_NULL 0 0 0 +IDROP_NEVER ICLASS_NONE ILOC_NONE 0 0 UITYPE_NONE NULL NULL 0 0 0 0 0 0 0 0 0 ISPL_NONE IMISC_NONE SPL_NULL 0 0 0 +IDROP_NEVER ICLASS_NONE ILOC_NONE 0 0 UITYPE_NONE NULL NULL 0 0 0 0 0 0 0 0 0 ISPL_NONE IMISC_NONE SPL_NULL 0 0 0 +IDROP_NEVER ICLASS_NONE ILOC_NONE 0 0 UITYPE_NONE NULL NULL 0 0 0 0 0 0 0 0 0 ISPL_NONE IMISC_NONE SPL_NULL 0 0 0 +IDROP_NEVER ICLASS_NONE ILOC_NONE 0 0 UITYPE_NONE NULL NULL 0 0 0 0 0 0 0 0 0 ISPL_NONE IMISC_NONE SPL_NULL 0 0 0 +IDROP_NEVER ICLASS_NONE ILOC_NONE 0 0 UITYPE_NONE NULL NULL 0 0 0 0 0 0 0 0 0 ISPL_NONE IMISC_NONE SPL_NULL 0 0 0 +IDROP_NEVER ICLASS_NONE ILOC_NONE 0 0 UITYPE_NONE NULL NULL 0 0 0 0 0 0 0 0 0 ISPL_NONE IMISC_NONE SPL_NULL 0 0 0 +IDROP_NEVER ICLASS_NONE ILOC_NONE 0 0 UITYPE_NONE NULL NULL 0 0 0 0 0 0 0 0 0 ISPL_NONE IMISC_NONE SPL_NULL 0 0 0 +IDROP_NEVER ICLASS_NONE ILOC_NONE 0 0 UITYPE_NONE NULL NULL 0 0 0 0 0 0 0 0 0 ISPL_NONE IMISC_NONE SPL_NULL 0 0 0 +IDROP_NEVER ICLASS_NONE ILOC_NONE 0 0 UITYPE_NONE NULL NULL 0 0 0 0 0 0 0 0 0 ISPL_NONE IMISC_NONE SPL_NULL 0 0 0 +IDROP_NEVER ICLASS_NONE ILOC_NONE 0 0 UITYPE_NONE NULL NULL 0 0 0 0 0 0 0 0 0 ISPL_NONE IMISC_NONE SPL_NULL 0 0 0 +IDROP_REGULAR ICLASS_ARMOR ILOC_HELM 91 7 UITYPE_NONE Cap Cap 1 15 0 0 1 3 0 0 0 ISPL_NONE IMISC_NONE SPL_NULL 0 15 20 +IDROP_REGULAR ICLASS_ARMOR ILOC_HELM 90 7 UITYPE_SKULLCAP Skull Cap Cap 4 20 0 0 2 4 0 0 0 ISPL_NONE IMISC_NONE SPL_NULL 0 25 30 +IDROP_REGULAR ICLASS_ARMOR ILOC_HELM 82 7 UITYPE_HELM Helm Helm 8 30 0 0 4 6 25 0 0 ISPL_NONE IMISC_NONE SPL_NULL 0 40 70 +IDROP_REGULAR ICLASS_ARMOR ILOC_HELM 75 7 UITYPE_NONE Full Helm Helm 12 35 0 0 6 8 35 0 0 ISPL_NONE IMISC_NONE SPL_NULL 0 90 130 +IDROP_REGULAR ICLASS_ARMOR ILOC_HELM 95 7 UITYPE_CROWN Crown Crown 16 40 0 0 8 12 0 0 0 ISPL_NONE IMISC_NONE SPL_NULL 0 200 300 +IDROP_REGULAR ICLASS_ARMOR ILOC_HELM 98 7 UITYPE_GREATHELM Great Helm Helm 20 60 0 0 10 15 50 0 0 ISPL_NONE IMISC_NONE SPL_NULL 0 400 500 +IDROP_REGULAR ICLASS_ARMOR ILOC_ARMOR 150 6 UITYPE_CAPE Cape Cape 1 12 0 0 1 5 0 0 0 ISPL_NONE IMISC_NONE SPL_NULL 0 10 50 +IDROP_REGULAR ICLASS_ARMOR ILOC_ARMOR 128 6 UITYPE_RAGS Rags Rags 1 6 0 0 2 6 0 0 0 ISPL_NONE IMISC_NONE SPL_NULL 0 5 25 +IDROP_REGULAR ICLASS_ARMOR ILOC_ARMOR 149 6 UITYPE_CLOAK Cloak Cloak 2 18 0 0 3 7 0 0 0 ISPL_NONE IMISC_NONE SPL_NULL 0 40 70 +IDROP_REGULAR ICLASS_ARMOR ILOC_ARMOR 137 6 UITYPE_ROBE Robe Robe 3 24 0 0 4 7 0 0 0 ISPL_NONE IMISC_NONE SPL_NULL 0 75 125 +IDROP_REGULAR ICLASS_ARMOR ILOC_ARMOR 129 6 UITYPE_NONE Quilted Armor Armor 4 30 0 0 7 10 0 0 0 ISPL_NONE IMISC_NONE SPL_NULL 0 200 300 +IDROP_REGULAR ICLASS_ARMOR ILOC_ARMOR 135 6 UITYPE_LEATHARMOR Leather Armor Armor 6 35 0 0 10 13 0 0 0 ISPL_NONE IMISC_NONE SPL_NULL 0 300 400 +IDROP_REGULAR ICLASS_ARMOR ILOC_ARMOR 127 6 UITYPE_NONE Hard Leather Armor Armor 7 40 0 0 11 14 0 0 0 ISPL_NONE IMISC_NONE SPL_NULL 0 450 550 +IDROP_REGULAR ICLASS_ARMOR ILOC_ARMOR 107 6 UITYPE_STUDARMOR Studded Leather Armor Armor 9 45 0 0 15 17 20 0 0 ISPL_NONE IMISC_NONE SPL_NULL 0 700 800 +IDROP_REGULAR ICLASS_ARMOR ILOC_ARMOR 154 8 UITYPE_NONE Ring Mail Mail 11 50 0 0 17 20 25 0 0 ISPL_NONE IMISC_NONE SPL_NULL 0 900 1100 +IDROP_REGULAR ICLASS_ARMOR ILOC_ARMOR 111 8 UITYPE_CHAINMAIL Chain Mail Mail 13 55 0 0 18 22 30 0 0 ISPL_NONE IMISC_NONE SPL_NULL 0 1250 1750 +IDROP_REGULAR ICLASS_ARMOR ILOC_ARMOR 114 8 UITYPE_NONE Scale Mail Mail 15 60 0 0 23 28 35 0 0 ISPL_NONE IMISC_NONE SPL_NULL 0 2300 2800 +IDROP_REGULAR ICLASS_ARMOR ILOC_ARMOR 153 9 UITYPE_BREASTPLATE Breast Plate Plate 16 80 0 0 20 24 40 0 0 ISPL_NONE IMISC_NONE SPL_NULL 0 2800 3200 +IDROP_REGULAR ICLASS_ARMOR ILOC_ARMOR 136 8 UITYPE_NONE Splint Mail Mail 17 65 0 0 30 35 40 0 0 ISPL_NONE IMISC_NONE SPL_NULL 0 3250 3750 +IDROP_REGULAR ICLASS_ARMOR ILOC_ARMOR 103 9 UITYPE_PLATEMAIL Plate Mail Plate 19 75 0 0 42 50 60 0 0 ISPL_NONE IMISC_NONE SPL_NULL 0 4600 5400 +IDROP_REGULAR ICLASS_ARMOR ILOC_ARMOR 103 9 UITYPE_NONE Field Plate Plate 21 80 0 0 40 45 65 0 0 ISPL_NONE IMISC_NONE SPL_NULL 0 5800 6200 +IDROP_REGULAR ICLASS_ARMOR ILOC_ARMOR 152 9 UITYPE_NONE Gothic Plate Plate 23 100 0 0 50 60 80 0 0 ISPL_NONE IMISC_NONE SPL_NULL 0 8000 10000 +IDROP_REGULAR ICLASS_ARMOR ILOC_ARMOR 151 9 UITYPE_FULLPLATE Full Plate Mail Plate 25 90 0 0 60 75 90 0 0 ISPL_NONE IMISC_NONE SPL_NULL 0 6500 8000 +IDROP_REGULAR ICLASS_ARMOR ILOC_ONEHAND 83 5 UITYPE_BUCKLER Buckler Shield 1 16 0 0 1 5 0 0 0 ISPL_NONE IMISC_NONE SPL_NULL 0 30 70 +IDROP_REGULAR ICLASS_ARMOR ILOC_ONEHAND 105 5 UITYPE_SMALLSHIELD Small Shield Shield 5 24 0 0 3 8 25 0 0 ISPL_NONE IMISC_NONE SPL_NULL 0 90 130 +IDROP_REGULAR ICLASS_ARMOR ILOC_ONEHAND 147 5 UITYPE_LARGESHIELD Large Shield Shield 9 32 0 0 5 10 40 0 0 ISPL_NONE IMISC_NONE SPL_NULL 0 200 300 +IDROP_REGULAR ICLASS_ARMOR ILOC_ONEHAND 113 5 UITYPE_KITESHIELD Kite Shield Shield 14 40 0 0 8 15 50 0 0 ISPL_NONE IMISC_NONE SPL_NULL 0 400 700 +IDROP_REGULAR ICLASS_ARMOR ILOC_ONEHAND 132 5 UITYPE_GOTHSHIELD Tower Shield Shield 20 50 0 0 12 20 60 0 0 ISPL_NONE IMISC_NONE SPL_NULL 0 850 1200 +IDROP_REGULAR ICLASS_ARMOR ILOC_ONEHAND 148 5 UITYPE_GOTHSHIELD Gothic Shield Shield 23 60 0 0 14 18 80 0 0 ISPL_NONE IMISC_NONE SPL_NULL 0 2300 2700 +IDROP_REGULAR ICLASS_MISC ILOC_UNEQUIPABLE 32 0 UITYPE_NONE Potion of Healing NULL 1 0 0 0 0 0 0 0 0 ISPL_NONE IMISC_HEAL SPL_NULL 1 50 50 +IDROP_REGULAR ICLASS_MISC ILOC_UNEQUIPABLE 35 0 UITYPE_NONE Potion of Full Healing NULL 1 0 0 0 0 0 0 0 0 ISPL_NONE IMISC_FULLHEAL SPL_NULL 1 150 150 +IDROP_REGULAR ICLASS_MISC ILOC_UNEQUIPABLE 39 0 UITYPE_NONE Potion of Mana NULL 1 0 0 0 0 0 0 0 0 ISPL_NONE IMISC_MANA SPL_NULL 1 50 50 +IDROP_REGULAR ICLASS_MISC ILOC_UNEQUIPABLE 0 0 UITYPE_NONE Potion of Full Mana NULL 1 0 0 0 0 0 0 0 0 ISPL_NONE IMISC_FULLMANA SPL_NULL 1 150 150 +IDROP_REGULAR ICLASS_MISC ILOC_UNEQUIPABLE 37 0 UITYPE_NONE Potion of Rejuvenation NULL 3 0 0 0 0 0 0 0 0 ISPL_NONE IMISC_REJUV SPL_NULL 1 120 120 +IDROP_REGULAR ICLASS_MISC ILOC_UNEQUIPABLE 33 0 UITYPE_NONE Potion of Full Rejuvenation NULL 7 0 0 0 0 0 0 0 0 ISPL_NONE IMISC_FULLREJUV SPL_NULL 1 600 600 +IDROP_REGULAR ICLASS_MISC ILOC_UNEQUIPABLE 38 0 UITYPE_NONE Elixir of Strength NULL 15 0 0 0 0 0 0 0 0 ISPL_NONE IMISC_ELIXSTR SPL_NULL 1 5000 5000 +IDROP_REGULAR ICLASS_MISC ILOC_UNEQUIPABLE 34 0 UITYPE_NONE Elixir of Magic NULL 15 0 0 0 0 0 0 0 0 ISPL_NONE IMISC_ELIXMAG SPL_NULL 1 5000 5000 +IDROP_REGULAR ICLASS_MISC ILOC_UNEQUIPABLE 36 0 UITYPE_NONE Elixir of Dexterity NULL 15 0 0 0 0 0 0 0 0 ISPL_NONE IMISC_ELIXDEX SPL_NULL 1 5000 5000 +IDROP_REGULAR ICLASS_MISC ILOC_UNEQUIPABLE 31 0 UITYPE_NONE Elixir of Vitality NULL 20 0 0 0 0 0 0 0 0 ISPL_NONE IMISC_ELIXVIT SPL_NULL 1 5000 5000 +IDROP_REGULAR ICLASS_MISC ILOC_UNEQUIPABLE 1 0 UITYPE_NONE Scroll of Healing NULL 1 0 0 0 0 0 0 0 0 ISPL_NONE IMISC_SCROLL SPL_HEAL 1 50 50 +IDROP_REGULAR ICLASS_MISC ILOC_UNEQUIPABLE 1 0 UITYPE_NONE Scroll of Lightning NULL 4 0 0 0 0 0 0 0 0 ISPL_NONE IMISC_SCROLLT SPL_LIGHTNING 1 150 150 +IDROP_REGULAR ICLASS_MISC ILOC_UNEQUIPABLE 1 0 UITYPE_NONE Scroll of Identify NULL 1 0 0 0 0 0 0 0 0 ISPL_NONE IMISC_SCROLL SPL_IDENTIFY 1 100 100 +IDROP_REGULAR ICLASS_MISC ILOC_UNEQUIPABLE 1 0 UITYPE_NONE Scroll of Resurrect NULL 1 0 0 0 0 0 0 0 0 ISPL_NONE IMISC_SCROLLT SPL_RESURRECT 1 250 250 +IDROP_REGULAR ICLASS_MISC ILOC_UNEQUIPABLE 1 0 UITYPE_NONE Scroll of Fire Wall NULL 4 0 0 0 0 0 0 17 0 ISPL_NONE IMISC_SCROLLT SPL_FIREWALL 1 400 400 +IDROP_REGULAR ICLASS_MISC ILOC_UNEQUIPABLE 1 0 UITYPE_NONE Scroll of Inferno NULL 1 0 0 0 0 0 0 19 0 ISPL_NONE IMISC_SCROLLT SPL_FLAME 1 100 100 +IDROP_REGULAR ICLASS_MISC ILOC_UNEQUIPABLE 1 0 UITYPE_NONE Scroll of Town Portal NULL 4 0 0 0 0 0 0 0 0 ISPL_NONE IMISC_SCROLL SPL_TOWN 1 200 200 +IDROP_REGULAR ICLASS_MISC ILOC_UNEQUIPABLE 1 0 UITYPE_NONE Scroll of Flash NULL 6 0 0 0 0 0 0 21 0 ISPL_NONE IMISC_SCROLLT SPL_FLASH 1 500 500 +IDROP_REGULAR ICLASS_MISC ILOC_UNEQUIPABLE 1 0 UITYPE_NONE Scroll of Infravision NULL 8 0 0 0 0 0 0 23 0 ISPL_NONE IMISC_SCROLL SPL_INFRA 1 600 600 +IDROP_REGULAR ICLASS_MISC ILOC_UNEQUIPABLE 1 0 UITYPE_NONE Scroll of Phasing NULL 6 0 0 0 0 0 0 25 0 ISPL_NONE IMISC_SCROLL SPL_RNDTELEPORT 1 200 200 +IDROP_REGULAR ICLASS_MISC ILOC_UNEQUIPABLE 1 0 UITYPE_NONE Scroll of Mana Shield NULL 8 0 0 0 0 0 0 0 0 ISPL_NONE IMISC_SCROLL SPL_MANASHIELD 1 1200 1200 +IDROP_REGULAR ICLASS_MISC ILOC_UNEQUIPABLE 1 0 UITYPE_NONE Scroll of Flame Wave NULL 10 0 0 0 0 0 0 29 0 ISPL_NONE IMISC_SCROLLT SPL_WAVE 1 650 650 +IDROP_REGULAR ICLASS_MISC ILOC_UNEQUIPABLE 1 0 UITYPE_NONE Scroll of Fireball NULL 8 0 0 0 0 0 0 31 0 ISPL_NONE IMISC_SCROLLT SPL_FIREBALL 1 300 300 +IDROP_REGULAR ICLASS_MISC ILOC_UNEQUIPABLE 1 0 UITYPE_NONE Scroll of Stone Curse NULL 6 0 0 0 0 0 0 33 0 ISPL_NONE IMISC_SCROLLT SPL_STONE 1 800 800 +IDROP_REGULAR ICLASS_MISC ILOC_UNEQUIPABLE 1 0 UITYPE_NONE Scroll of Chain Lightning NULL 10 0 0 0 0 0 0 35 0 ISPL_NONE IMISC_SCROLLT SPL_CHAIN 1 750 750 +IDROP_REGULAR ICLASS_MISC ILOC_UNEQUIPABLE 1 0 UITYPE_NONE Scroll of Guardian NULL 12 0 0 0 0 0 0 47 0 ISPL_NONE IMISC_SCROLLT SPL_GUARDIAN 1 950 950 +IDROP_NEVER ICLASS_MISC ILOC_UNEQUIPABLE 1 0 UITYPE_NONE Non Item NULL 0 0 0 0 0 0 0 0 0 ISPL_NONE IMISC_NONE SPL_NULL 0 0 0 +IDROP_REGULAR ICLASS_MISC ILOC_UNEQUIPABLE 1 0 UITYPE_NONE Scroll of Nova NULL 14 0 0 0 0 0 0 57 0 ISPL_NONE IMISC_SCROLL SPL_NOVA 1 1300 1300 +IDROP_REGULAR ICLASS_MISC ILOC_UNEQUIPABLE 1 0 UITYPE_NONE Scroll of Golem NULL 10 0 0 0 0 0 0 51 0 ISPL_NONE IMISC_SCROLLT SPL_GOLEM 1 1100 1100 +IDROP_NEVER ICLASS_MISC ILOC_UNEQUIPABLE 1 0 UITYPE_NONE Scroll of None NULL 99 0 0 0 0 0 0 61 0 ISPL_NONE IMISC_SCROLLT SPL_NULL 1 1000 1000 +IDROP_REGULAR ICLASS_MISC ILOC_UNEQUIPABLE 1 0 UITYPE_NONE Scroll of Teleport NULL 14 0 0 0 0 0 0 81 0 ISPL_NONE IMISC_SCROLL SPL_TELEPORT 1 3000 3000 +IDROP_REGULAR ICLASS_MISC ILOC_UNEQUIPABLE 1 0 UITYPE_NONE Scroll of Apocalypse NULL 22 0 0 0 0 0 0 117 0 ISPL_NONE IMISC_SCROLL SPL_APOCA 1 2000 2000 +IDROP_REGULAR ICLASS_MISC ILOC_UNEQUIPABLE 88 0 UITYPE_NONE Book of NULL 2 0 0 0 0 0 0 0 0 ISPL_NONE IMISC_BOOK SPL_NULL 1 0 0 +IDROP_REGULAR ICLASS_MISC ILOC_UNEQUIPABLE 88 0 UITYPE_NONE Book of NULL 8 0 0 0 0 0 0 0 0 ISPL_NONE IMISC_BOOK SPL_NULL 1 0 0 +IDROP_REGULAR ICLASS_MISC ILOC_UNEQUIPABLE 88 0 UITYPE_NONE Book of NULL 14 0 0 0 0 0 0 0 0 ISPL_NONE IMISC_BOOK SPL_NULL 1 0 0 +IDROP_REGULAR ICLASS_MISC ILOC_UNEQUIPABLE 88 0 UITYPE_NONE Book of NULL 20 0 0 0 0 0 0 0 0 ISPL_NONE IMISC_BOOK SPL_NULL 1 0 0 +IDROP_REGULAR ICLASS_WEAPON ILOC_ONEHAND 51 1 UITYPE_DAGGER Dagger Dagger 1 16 1 4 0 0 0 0 0 ISPL_NONE IMISC_NONE SPL_NULL 0 60 60 +IDROP_REGULAR ICLASS_WEAPON ILOC_ONEHAND 64 1 UITYPE_NONE Short Sword Sword 1 24 2 6 0 0 18 0 0 ISPL_NONE IMISC_NONE SPL_NULL 0 120 120 +IDROP_REGULAR ICLASS_WEAPON ILOC_ONEHAND 62 1 UITYPE_FALCHION Falchion Sword 2 20 4 8 0 0 30 0 0 ISPL_NONE IMISC_NONE SPL_NULL 0 250 250 +IDROP_REGULAR ICLASS_WEAPON ILOC_ONEHAND 72 1 UITYPE_SCIMITAR Scimitar Sword 4 28 3 7 0 0 23 0 23 ISPL_NONE IMISC_NONE SPL_NULL 0 200 200 +IDROP_REGULAR ICLASS_WEAPON ILOC_ONEHAND 65 1 UITYPE_CLAYMORE Claymore Sword 5 36 1 12 0 0 35 0 0 ISPL_NONE IMISC_NONE SPL_NULL 0 450 450 +IDROP_REGULAR ICLASS_WEAPON ILOC_ONEHAND 56 1 UITYPE_NONE Blade Blade 4 30 3 8 0 0 25 0 30 ISPL_NONE IMISC_NONE SPL_NULL 0 280 280 +IDROP_REGULAR ICLASS_WEAPON ILOC_ONEHAND 67 1 UITYPE_SABRE Sabre Sabre 1 45 1 8 0 0 17 0 0 ISPL_NONE IMISC_NONE SPL_NULL 0 170 170 +IDROP_REGULAR ICLASS_WEAPON ILOC_ONEHAND 60 1 UITYPE_LONGSWR Long Sword Sword 6 40 2 10 0 0 30 0 30 ISPL_NONE IMISC_NONE SPL_NULL 0 350 350 +IDROP_REGULAR ICLASS_WEAPON ILOC_ONEHAND 61 1 UITYPE_BROADSWR Broad Sword Sword 8 50 4 12 0 0 40 0 0 ISPL_NONE IMISC_NONE SPL_NULL 0 750 750 +IDROP_REGULAR ICLASS_WEAPON ILOC_ONEHAND 57 1 UITYPE_BASTARDSWR Bastard Sword Sword 10 60 6 15 0 0 50 0 0 ISPL_NONE IMISC_NONE SPL_NULL 0 1000 1000 +IDROP_REGULAR ICLASS_WEAPON ILOC_TWOHAND 110 1 UITYPE_TWOHANDSWR Two-Handed Sword Sword 14 75 8 16 0 0 65 0 0 ISPL_NONE IMISC_NONE SPL_NULL 0 1800 1800 +IDROP_REGULAR ICLASS_WEAPON ILOC_TWOHAND 134 1 UITYPE_GREATSWR Great Sword Sword 17 100 10 20 0 0 75 0 0 ISPL_NONE IMISC_NONE SPL_NULL 0 3000 3000 +IDROP_REGULAR ICLASS_WEAPON ILOC_TWOHAND 112 2 UITYPE_SMALLAXE Small Axe Axe 2 24 2 10 0 0 0 0 0 ISPL_NONE IMISC_NONE SPL_NULL 0 150 150 +IDROP_REGULAR ICLASS_WEAPON ILOC_TWOHAND 144 2 UITYPE_NONE Axe Axe 4 32 4 12 0 0 22 0 0 ISPL_NONE IMISC_NONE SPL_NULL 0 450 450 +IDROP_REGULAR ICLASS_WEAPON ILOC_TWOHAND 142 2 UITYPE_LARGEAXE Large Axe Axe 6 40 6 16 0 0 30 0 0 ISPL_NONE IMISC_NONE SPL_NULL 0 750 750 +IDROP_REGULAR ICLASS_WEAPON ILOC_TWOHAND 141 2 UITYPE_BROADAXE Broad Axe Axe 8 50 8 20 0 0 50 0 0 ISPL_NONE IMISC_NONE SPL_NULL 0 1000 1000 +IDROP_REGULAR ICLASS_WEAPON ILOC_TWOHAND 101 2 UITYPE_BATTLEAXE Battle Axe Axe 10 60 10 25 0 0 65 0 0 ISPL_NONE IMISC_NONE SPL_NULL 0 1500 1500 +IDROP_REGULAR ICLASS_WEAPON ILOC_TWOHAND 143 2 UITYPE_GREATAXE Great Axe Axe 12 75 12 30 0 0 80 0 0 ISPL_NONE IMISC_NONE SPL_NULL 0 2500 2500 +IDROP_REGULAR ICLASS_WEAPON ILOC_ONEHAND 59 4 UITYPE_MACE Mace Mace 2 32 1 8 0 0 16 0 0 ISPL_NONE IMISC_NONE SPL_NULL 0 200 200 +IDROP_REGULAR ICLASS_WEAPON ILOC_ONEHAND 63 4 UITYPE_MORNSTAR Morning Star Mace 3 40 1 10 0 0 26 0 0 ISPL_NONE IMISC_NONE SPL_NULL 0 300 300 +IDROP_REGULAR ICLASS_WEAPON ILOC_ONEHAND 121 4 UITYPE_WARHAMMER War Hammer Hammer 5 50 5 9 0 0 40 0 0 ISPL_NONE IMISC_NONE SPL_NULL 0 600 600 +IDROP_REGULAR ICLASS_WEAPON ILOC_ONEHAND 70 4 UITYPE_SPIKCLUB Spiked Club Club 4 20 3 6 0 0 18 0 0 ISPL_NONE IMISC_NONE SPL_NULL 0 225 225 +IDROP_REGULAR ICLASS_WEAPON ILOC_ONEHAND 66 4 UITYPE_SPIKCLUB Club Club 1 20 1 6 0 0 0 0 0 ISPL_NONE IMISC_NONE SPL_NULL 0 20 20 +IDROP_REGULAR ICLASS_WEAPON ILOC_ONEHAND 131 4 UITYPE_FLAIL Flail Flail 7 36 2 12 0 0 30 0 0 ISPL_NONE IMISC_NONE SPL_NULL 0 500 500 +IDROP_REGULAR ICLASS_WEAPON ILOC_TWOHAND 122 4 UITYPE_MAUL Maul Maul 10 50 6 20 0 0 55 0 0 ISPL_NONE IMISC_NONE SPL_NULL 0 900 900 +IDROP_DOUBLE ICLASS_WEAPON ILOC_TWOHAND 118 3 UITYPE_SHORTBOW Short Bow Bow 1 30 1 4 0 0 0 0 0 ISPL_NONE IMISC_NONE SPL_NULL 0 100 100 +IDROP_DOUBLE ICLASS_WEAPON ILOC_TWOHAND 102 3 UITYPE_HUNTBOW Hunter's Bow Bow 3 40 2 5 0 0 20 0 35 ISPL_NONE IMISC_NONE SPL_NULL 0 350 350 +IDROP_DOUBLE ICLASS_WEAPON ILOC_TWOHAND 102 3 UITYPE_LONGBOW Long Bow Bow 5 35 1 6 0 0 25 0 30 ISPL_NONE IMISC_NONE SPL_NULL 0 250 250 +IDROP_DOUBLE ICLASS_WEAPON ILOC_TWOHAND 133 3 UITYPE_COMPBOW Composite Bow Bow 7 45 3 6 0 0 25 0 40 ISPL_NONE IMISC_NONE SPL_NULL 0 600 600 +IDROP_DOUBLE ICLASS_WEAPON ILOC_TWOHAND 167 3 UITYPE_NONE Short Battle Bow Bow 9 45 3 7 0 0 30 0 50 ISPL_NONE IMISC_NONE SPL_NULL 0 750 750 +IDROP_DOUBLE ICLASS_WEAPON ILOC_TWOHAND 119 3 UITYPE_BATTLEBOW Long Battle Bow Bow 11 50 1 10 0 0 30 0 60 ISPL_NONE IMISC_NONE SPL_NULL 0 1000 1000 +IDROP_DOUBLE ICLASS_WEAPON ILOC_TWOHAND 165 3 UITYPE_NONE Short War Bow Bow 15 55 4 8 0 0 35 0 70 ISPL_NONE IMISC_NONE SPL_NULL 0 1500 1500 +IDROP_DOUBLE ICLASS_WEAPON ILOC_TWOHAND 119 3 UITYPE_WARBOW Long War Bow Bow 19 60 1 14 0 0 45 0 80 ISPL_NONE IMISC_NONE SPL_NULL 0 2000 2000 +IDROP_REGULAR ICLASS_WEAPON ILOC_TWOHAND 109 10 UITYPE_SHORTSTAFF Short Staff Staff 1 25 2 4 0 0 0 0 0 ISPL_NONE IMISC_STAFF SPL_NULL 0 30 30 +IDROP_REGULAR ICLASS_WEAPON ILOC_TWOHAND 123 10 UITYPE_LONGSTAFF Long Staff Staff 4 35 4 8 0 0 0 0 0 ISPL_NONE IMISC_STAFF SPL_NULL 0 100 100 +IDROP_REGULAR ICLASS_WEAPON ILOC_TWOHAND 166 10 UITYPE_COMPSTAFF Composite Staff Staff 6 45 5 10 0 0 0 0 0 ISPL_NONE IMISC_STAFF SPL_NULL 0 500 500 +IDROP_REGULAR ICLASS_WEAPON ILOC_TWOHAND 109 10 UITYPE_QUARSTAFF Quarter Staff Staff 9 55 6 12 0 0 20 0 0 ISPL_NONE IMISC_STAFF SPL_NULL 0 1000 1000 +IDROP_REGULAR ICLASS_WEAPON ILOC_TWOHAND 124 10 UITYPE_WARSTAFF War Staff Staff 12 75 8 16 0 0 30 0 0 ISPL_NONE IMISC_STAFF SPL_NULL 0 1500 1500 +IDROP_REGULAR ICLASS_MISC ILOC_RING 12 12 UITYPE_RING Ring Ring 5 0 0 0 0 0 0 0 0 ISPL_NONE IMISC_RING SPL_NULL 0 1000 1000 +IDROP_REGULAR ICLASS_MISC ILOC_RING 12 12 UITYPE_RING Ring Ring 10 0 0 0 0 0 0 0 0 ISPL_NONE IMISC_RING SPL_NULL 0 1000 1000 +IDROP_REGULAR ICLASS_MISC ILOC_RING 12 12 UITYPE_RING Ring Ring 15 0 0 0 0 0 0 0 0 ISPL_NONE IMISC_RING SPL_NULL 0 1000 1000 +IDROP_REGULAR ICLASS_MISC ILOC_AMULET 45 13 UITYPE_AMULET Amulet Amulet 8 0 0 0 0 0 0 0 0 ISPL_NONE IMISC_AMULET SPL_NULL 0 1200 1200 +IDROP_REGULAR ICLASS_MISC ILOC_AMULET 45 13 UITYPE_AMULET Amulet Amulet 16 0 0 0 0 0 0 0 0 ISPL_NONE IMISC_AMULET SPL_NULL 0 1200 1200 +IDROP_NEVER ICLASS_NONE ILOC_INVALID 0 0 UITYPE_NONE NULL NULL 0 0 0 0 0 0 0 0 0 ISPL_NONE IMISC_NONE SPL_NULL 0 0 0 diff --git a/2020_03_31/Source/Data/Excel/xl_mfile.txt b/2020_03_31/Source/Data/Excel/xl_mfile.txt new file mode 100644 index 00000000..bae9d912 --- /dev/null +++ b/2020_03_31/Source/Data/Excel/xl_mfile.txt @@ -0,0 +1,48 @@ +#mAnimName(i) mAnimFAmt(i) mName(s) mFlags(i) mAnimData(a) mAnimDelay(a) mAnimLen(a) mAnimWidth(a) mAnimWidth2(a) +MFILE_ARROWS 1 Arrows 2 "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" +MFILE_FIREBA 16 Fireba 0 "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14" "96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96" "16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16" +MFILE_GUARD 3 Guard 0 "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "15, 14, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "96, 96, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" +MFILE_LGHNING 1 Lghning 0 "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" +MFILE_FIREWAL 2 Firewal 0 "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "13, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "128, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "32, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" +MFILE_MAGBLOS 1 MagBlos 0 "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" +MFILE_PORTAL 2 Portal 0 "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "96, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" +MFILE_BLUEXFR 1 Bluexfr 0 "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" +MFILE_BLUEXBK 1 Bluexbk 0 "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" +MFILE_MANASHLD 1 Manashld 2 "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" +MFILE_BLOOD 4 Blood 0 "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "15, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "96, 128, 128, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "16, 32, 32, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" +MFILE_BONE 3 Bone 0 "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "128, 128, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "32, 32, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" +MFILE_METLHIT 3 Metlhit 0 "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "10, 10, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "96, 96, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" +MFILE_FARROW 16 Farrow 0 "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4" "96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96" "16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16" +MFILE_DOOM 9 Doom 1 "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0" "15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0" "96, 96, 96, 96, 96, 96, 96, 96, 96, 0, 0, 0, 0, 0, 0, 0" "16, 16, 16, 16, 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0" +MFILE_0F 1 1 "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" +MFILE_BLODBUR 2 Blodbur 0 "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "128, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "32, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" +MFILE_NEWEXP 1 Newexp 0 "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" +MFILE_SHATTER1 1 Shatter1 0 "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" +MFILE_BIGEXP 1 Bigexp 0 "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" +MFILE_INFERNO 1 Inferno 0 "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" +MFILE_THINLGHT 1 Thinlght 1 "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" +MFILE_FLARE 1 Flare 0 "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" +MFILE_FLAREEXP 1 Flareexp 0 "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" +MFILE_MAGBALL 8 Magball 1 "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0" "16, 16, 16, 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0" "128, 128, 128, 128, 128, 128, 128, 128, 0, 0, 0, 0, 0, 0, 0, 0" "32, 32, 32, 32, 32, 32, 32, 32, 0, 0, 0, 0, 0, 0, 0, 0" +MFILE_KRULL 1 Krull 1 "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" +MFILE_MINILTNG 1 Miniltng 0 "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" +MFILE_HOLY 16 Holy 0 "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14" "96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96" "16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16" +MFILE_HOLYEXPL 1 Holyexpl 0 "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" +MFILE_LARROW 16 Larrow 0 "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4" "96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96" "16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16" +MFILE_FIRARWEX 1 Firarwex 0 "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" +MFILE_ACIDBF 16 Acidbf 1 "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8" "96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96" "16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16" +MFILE_ACIDSPLA 1 Acidspla 1 "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" +MFILE_ACIDPUD 2 Acidpud 1 "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "9, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "96, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" +MFILE_ETHRSHLD 1 Ethrshld 0 "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" +MFILE_FIRERUN 8 Firerun 0 "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0" "12, 12, 12, 12, 12, 12, 12, 12, 0, 0, 0, 0, 0, 0, 0, 0" "96, 96, 96, 96, 96, 96, 96, 96, 0, 0, 0, 0, 0, 0, 0, 0" "16, 16, 16, 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0" +MFILE_RESSUR1 1 Ressur1 0 "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" +MFILE_SKLBALL 9 Sklball 0 "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0" "16, 16, 16, 16, 16, 16, 16, 16, 8, 0, 0, 0, 0, 0, 0, 0" "96, 96, 96, 96, 96, 96, 96, 96, 96, 0, 0, 0, 0, 0, 0, 0" "16, 16, 16, 16, 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0" +MFILE_RPORTAL 2 Rportal 0 "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "96, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" +MFILE_FIREPLAR 1 Fireplar 1 "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" +MFILE_SCUBMISB 1 Scubmisb 1 "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" +MFILE_SCBSEXPB 1 Scbsexpb 1 "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" +MFILE_SCUBMISC 1 Scubmisc 1 "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" +MFILE_SCBSEXPC 1 Scbsexpc 1 "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" +MFILE_SCUBMISD 1 Scubmisd 1 "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" +MFILE_SCBSEXPD 1 Scbsexpd 1 "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" +255 0 ~ 0 "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" diff --git a/2020_03_31/Source/Data/Excel/xl_mis.txt b/2020_03_31/Source/Data/Excel/xl_mis.txt new file mode 100644 index 00000000..8233ff96 --- /dev/null +++ b/2020_03_31/Source/Data/Excel/xl_mis.txt @@ -0,0 +1,69 @@ +#mName(i) mAddProc(p) mProc(p) mDraw(i) mType(i) mResist(i) mFileNum(i) mlSFX(i) miSFX(i) +MIS_ARROW AddArrow MI_Arrow 1 0 0 MFILE_ARROWS -1 -1 +MIS_FIREBOLT AddFirebolt MI_Firebolt 1 1 1 MFILE_FIREBA LS_FBOLT1 LS_FIRIMP2 +MIS_GUARDIAN AddGuardian MI_Guardian 1 1 0 MFILE_GUARD LS_GUARD LS_GUARDLAN +MIS_RNDTELEPORT AddRndTeleport MI_Teleport 0 1 0 255 LS_TELEPORT -1 +MIS_LIGHTBALL AddLightball MI_Lightball 1 1 2 MFILE_LGHNING -1 -1 +MIS_FIREWALL AddFirewall MI_Firewall 1 1 1 MFILE_FIREWAL LS_WALLLOOP LS_FIRIMP2 +MIS_FIREBALL AddFireball MI_Fireball 1 1 1 MFILE_FIREBA LS_FBOLT1 LS_FIRIMP2 +MIS_LIGHTCTRL AddLightctrl MI_Lightctrl 0 1 2 MFILE_LGHNING -1 -1 +MIS_LIGHTNING AddLightning MI_Lightning 1 1 2 MFILE_LGHNING LS_LNING1 LS_ELECIMP1 +MIS_MISEXP AddMisexp MI_Misexp 1 2 0 MFILE_MAGBLOS -1 -1 +MIS_TOWN AddTown MI_Town 1 1 3 MFILE_PORTAL LS_SENTINEL LS_ELEMENTL +MIS_FLASH AddFlash MI_Flash 1 1 3 MFILE_BLUEXFR LS_NOVA LS_ELECIMP1 +MIS_FLASH2 AddFlash2 MI_Flash2 1 1 3 MFILE_BLUEXBK -1 -1 +MIS_MANASHIELD AddManashield MI_SetManashield 0 1 3 MFILE_MANASHLD LS_MSHIELD -1 +MIS_FIREMOVE AddFiremove MI_Firemove 1 1 1 MFILE_FIREWAL -1 -1 +MIS_CHAIN AddChain MI_Chain 1 1 2 MFILE_LGHNING LS_LNING1 LS_ELECIMP1 +MIS_NULL_10 NULL NULL 1 1 2 MFILE_LGHNING -1 -1 +MIS_NULL_11 miss_null_11 mi_null_11 1 2 0 MFILE_BLOOD LS_BLODSTAR LS_BLSIMPT +MIS_NULL_12 miss_null_12 mi_null_11 1 2 0 MFILE_BONE -1 -1 +MIS_NULL_13 miss_null_13 mi_null_11 1 2 0 MFILE_METLHIT -1 -1 +MIS_RHINO AddRhino MI_Rhino 1 2 0 255 -1 -1 +MIS_MAGMABALL AddMagmaball MI_Firebolt 1 1 1 MFILE_MAGBALL -1 -1 +MIS_LIGHTCTRL2 AddLightctrl MI_Lightctrl 0 1 2 MFILE_THINLGHT -1 -1 +MIS_LIGHTNING2 AddLightning MI_Lightning 1 1 2 MFILE_THINLGHT -1 -1 +MIS_FLARE AddFlare MI_Firebolt 1 1 3 MFILE_FLARE -1 -1 +MIS_MISEXP2 AddMisexp MI_Misexp 1 2 3 MFILE_FLAREEXP -1 -1 +MIS_TELEPORT AddTeleport MI_Teleport 0 1 0 255 LS_ELEMENTL -1 +MIS_FARROW AddLArrow MI_LArrow 1 0 1 MFILE_FARROW -1 -1 +MIS_DOOMSERP NULL NULL 0 1 3 MFILE_DOOM LS_DSERP -1 +MIS_NULL_1D miss_null_1D MI_Firewall 1 2 1 MFILE_FIREWAL -1 -1 +MIS_STONE AddStone MI_Stone 0 1 3 255 LS_SCURIMP -1 +MIS_NULL_1F miss_null_1F MI_Dummy 1 1 0 255 -1 -1 +MIS_INVISIBL NULL NULL 0 1 0 255 LS_INVISIBL -1 +MIS_GOLEM AddGolem MI_Golem 0 1 0 255 LS_GOLUM -1 +MIS_ETHEREALIZE AddEtherealize MI_Etherealize 1 1 0 MFILE_ETHRSHLD LS_ETHEREAL -1 +MIS_NULL_23 miss_null_23 mi_null_11 1 2 0 MFILE_BLODBUR -1 -1 +MIS_BOOM AddBoom MI_Boom 1 2 0 MFILE_NEWEXP -1 -1 +MIS_HEAL AddHeal MI_Dummy 0 1 0 255 -1 -1 +MIS_FIREWALLC AddFirewallC MI_FirewallC 0 1 1 MFILE_FIREWAL -1 -1 +MIS_INFRA AddInfra MI_Infra 0 1 0 255 LS_INFRAVIS -1 +MIS_IDENTIFY AddIdentify MI_Dummy 0 1 0 255 -1 -1 +MIS_WAVE AddWave MI_Wave 1 1 1 MFILE_FIREWAL LS_FLAMWAVE -1 +MIS_NOVA AddNova MI_Nova 1 1 2 MFILE_LGHNING LS_NOVA -1 +MIS_BLODBOIL AddBlodboil MI_Blodboil 1 1 0 255 -1 LS_BLODBOIL +MIS_APOCA AddApoca MI_Apoca 1 1 3 MFILE_NEWEXP LS_APOC -1 +MIS_REPAIR AddRepair MI_Dummy 0 2 0 255 -1 -1 +MIS_RECHARGE AddRecharge MI_Dummy 0 2 0 255 -1 -1 +MIS_DISARM AddDisarm MI_Dummy 0 2 0 255 LS_TRAPDIS -1 +MIS_FLAME AddFlame MI_Flame 1 1 1 MFILE_INFERNO LS_SPOUTSTR -1 +MIS_FLAMEC AddFlamec MI_Flamec 0 1 1 255 -1 -1 +MIS_NULL_32 miss_null_32 mi_null_32 1 2 0 255 -1 -1 +MIS_NULL_33 miss_null_33 mi_null_33 1 0 1 MFILE_KRULL -1 -1 +MIS_CBOLT AddCbolt MI_Cbolt 1 1 2 MFILE_MINILTNG LS_CBOLT -1 +MIS_HBOLT AddHbolt MI_Hbolt 1 1 0 MFILE_HOLY LS_HOLYBOLT LS_ELECIMP1 +MIS_RESURRECT AddResurrect MI_Dummy 0 1 3 255 -1 LS_RESUR +MIS_TELEKINESIS AddTelekinesis MI_Dummy 0 1 0 255 LS_ETHEREAL -1 +MIS_LARROW AddLArrow MI_LArrow 1 0 2 MFILE_LARROW -1 -1 +MIS_ACID AddAcid MI_Firebolt 1 1 4 MFILE_ACIDBF LS_ACID -1 +MIS_MISEXP3 AddMisexp MI_Acidsplat 1 2 4 MFILE_ACIDSPLA -1 -1 +MIS_ACIDPUD AddAcidpud MI_Acidpud 1 2 4 MFILE_ACIDPUD LS_PUDDLE -1 +MIS_HEALOTHER AddHealOther MI_Dummy 0 1 0 255 -1 -1 +MIS_ELEMENT AddElement MI_Element 1 1 1 MFILE_FIRERUN LS_ELEMENTL -1 +MIS_RESURRECTBEAM AddResurrectBeam MI_ResurrectBeam 1 1 0 MFILE_RESSUR1 -1 -1 +MIS_BONESPIRIT AddBoneSpirit MI_Bonespirit 1 1 3 MFILE_SKLBALL LS_BONESP LS_BSIMPCT +MIS_WEAPEXP AddWeapexp MI_Weapexp 1 2 0 255 -1 -1 +MIS_RPORTAL AddRportal MI_Rportal 1 2 0 MFILE_RPORTAL LS_SENTINEL LS_ELEMENTL +MIS_BOOM2 AddBoom MI_Boom 1 2 0 MFILE_FIREPLAR -1 -1 +MIS_DIABAPOCA AddDiabApoca MI_Dummy 0 2 0 255 -1 -1 diff --git a/2020_03_31/Source/Data/Excel/xl_monst.txt b/2020_03_31/Source/Data/Excel/xl_monst.txt new file mode 100644 index 00000000..5375f179 --- /dev/null +++ b/2020_03_31/Source/Data/Excel/xl_monst.txt @@ -0,0 +1,113 @@ +# flags(i) mType(i) GraphicType(s) has_special(i) sndfile(s) snd_special(i) has_trans(i) TransFile(s) Frames(a) Rate(a) mName(s) mMinDLvl(i) mMaxDLvl(i) mLevel(i) mMinHP(i) mMaxHP(i) mAi(i) mFlags(i) mInt(i) mHit(i) mAFNum(i) mMinDamage(i) mMaxDamage(i) mHit2(i) mAFNum2(i) mMinDamage2(i) mMaxDamage2(i) mArmorClass(i) mMonstClass(i) mMagicRes(i) mMagicRes2(i) mTreasure(i) mSelFlag(i) mExp(i) +MT_NZOMBIE 128 799 Monsters\\Zombie\\Zombie%c.CL2 0 Monsters\\Zombie\\Zombie%c%i.WAV 0 0 NULL "11, 24, 12, 6, 16, 0" "4, 0, 0, 0, 0, 0" Zombie 1 3 1 4 7 AI_ZOMBIE 0 0 10 8 2 5 0 0 0 0 5 MC_UNDEAD 72 72 0 3 54 +MT_BZOMBIE 128 799 Monsters\\Zombie\\Zombie%c.CL2 0 Monsters\\Zombie\\Zombie%c%i.WAV 0 1 Monsters\\Zombie\\Bluered.TRN "11, 24, 12, 6, 16, 0" "4, 0, 0, 0, 0, 0" Ghoul 2 4 2 7 11 AI_ZOMBIE 0 1 10 8 3 10 0 0 0 0 10 MC_UNDEAD 72 72 0 3 58 +MT_GZOMBIE 128 799 Monsters\\Zombie\\Zombie%c.CL2 0 Monsters\\Zombie\\Zombie%c%i.WAV 0 1 Monsters\\Zombie\\Grey.TRN "11, 24, 12, 6, 16, 0" "4, 0, 0, 0, 0, 0" Rotting Carcass 2 6 4 15 25 AI_ZOMBIE 0 2 25 8 5 15 0 0 0 0 15 MC_UNDEAD 72 74 0 3 136 +MT_YZOMBIE 128 799 Monsters\\Zombie\\Zombie%c.CL2 0 Monsters\\Zombie\\Zombie%c%i.WAV 0 1 Monsters\\Zombie\\Yellow.TRN "11, 24, 12, 6, 16, 0" "4, 0, 0, 0, 0, 0" Black Death 4 8 6 25 40 AI_ZOMBIE 0 3 30 8 6 22 0 0 0 0 20 MC_UNDEAD 72 76 0 3 240 +MT_RFALLSP 128 543 Monsters\\FalSpear\\Phall%c.CL2 1 Monsters\\FalSpear\\Phall%c%i.WAV 1 1 Monsters\\FalSpear\\FallenT.TRN "11, 11, 13, 11, 18, 13" "3, 0, 0, 0, 0, 0" Fallen One 1 3 1 1 4 AI_FALLEN 0 0 15 7 1 3 0 5 0 0 0 MC_ANIMAL 0 0 0 3 46 +MT_DFALLSP 128 543 Monsters\\FalSpear\\Phall%c.CL2 1 Monsters\\FalSpear\\Phall%c%i.WAV 1 1 Monsters\\FalSpear\\Dark.TRN "11, 11, 13, 11, 18, 13" "3, 0, 0, 0, 0, 0" Carver 2 5 3 4 8 AI_FALLEN 0 2 20 7 2 5 0 5 0 0 5 MC_ANIMAL 0 0 0 3 80 +MT_YFALLSP 128 543 Monsters\\FalSpear\\Phall%c.CL2 1 Monsters\\FalSpear\\Phall%c%i.WAV 1 0 NULL "11, 11, 13, 11, 18, 13" "3, 0, 0, 0, 0, 0" Devil Kin 3 7 5 12 24 AI_FALLEN 0 2 25 7 3 7 0 5 0 0 10 MC_ANIMAL 0 2 0 3 155 +MT_BFALLSP 128 543 Monsters\\FalSpear\\Phall%c.CL2 1 Monsters\\FalSpear\\Phall%c%i.WAV 1 1 Monsters\\FalSpear\\Blue.TRN "11, 11, 13, 11, 18, 13" "3, 0, 0, 0, 0, 0" Dark One 5 9 7 20 36 AI_FALLEN 0 3 30 7 4 8 0 5 0 0 15 MC_ANIMAL 64 68 0 3 255 +MT_WSKELAX 128 553 Monsters\\SkelAxe\\SklAx%c.CL2 1 Monsters\\SkelAxe\\SklAx%c%i.WAV 0 1 Monsters\\SkelAxe\\White.TRN "12, 8, 13, 6, 17, 16" "5, 0, 0, 0, 0, 0" Skeleton 1 3 1 2 4 AI_SKELSD 0 0 20 8 1 4 0 0 0 0 0 MC_UNDEAD 72 72 0 3 64 +MT_TSKELAX 128 553 Monsters\\SkelAxe\\SklAx%c.CL2 1 Monsters\\SkelAxe\\SklAx%c%i.WAV 0 1 Monsters\\SkelAxe\\Skelt.TRN "12, 8, 13, 6, 17, 16" "4, 0, 0, 0, 0, 0" Corpse Axe 2 5 2 4 7 AI_SKELSD 0 1 25 8 3 5 0 0 0 0 0 MC_UNDEAD 72 72 0 3 68 +MT_RSKELAX 128 553 Monsters\\SkelAxe\\SklAx%c.CL2 1 Monsters\\SkelAxe\\SklAx%c%i.WAV 0 0 NULL "12, 8, 13, 6, 17, 16" "2, 0, 0, 0, 0, 0" Burning Dead 2 6 4 8 12 AI_SKELSD 0 2 30 8 3 7 0 0 0 0 5 MC_UNDEAD 74 88 0 3 154 +MT_XSKELAX 128 553 Monsters\\SkelAxe\\SklAx%c.CL2 1 Monsters\\SkelAxe\\SklAx%c%i.WAV 0 1 Monsters\\SkelAxe\\Black.TRN "12, 8, 13, 6, 17, 16" "3, 0, 0, 0, 0, 0" Horror 4 8 6 12 20 AI_SKELSD 0 3 35 8 4 9 0 0 0 0 15 MC_UNDEAD 76 76 0 3 264 +MT_RFALLSD 128 623 Monsters\\FalSword\\Fall%c.CL2 1 Monsters\\FalSword\\Fall%c%i.WAV 1 1 Monsters\\FalSword\\FallenT.TRN "12, 12, 13, 11, 14, 15" "3, 0, 0, 0, 0, 0" Fallen One 1 3 1 2 5 AI_FALLEN 0 0 15 8 1 4 0 5 0 0 10 MC_ANIMAL 0 0 0 3 52 +MT_DFALLSD 128 623 Monsters\\FalSword\\Fall%c.CL2 1 Monsters\\FalSword\\Fall%c%i.WAV 1 1 Monsters\\FalSword\\Dark.TRN "12, 12, 13, 11, 14, 15" "3, 0, 0, 0, 0, 0" Carver 2 5 3 5 9 AI_FALLEN 0 1 20 8 2 7 0 5 0 0 15 MC_ANIMAL 0 0 0 3 90 +MT_YFALLSD 128 623 Monsters\\FalSword\\Fall%c.CL2 1 Monsters\\FalSword\\Fall%c%i.WAV 1 0 NULL "12, 12, 13, 11, 14, 15" "3, 0, 0, 0, 0, 0" Devil Kin 3 7 5 16 24 AI_FALLEN 0 2 25 8 4 10 0 5 0 0 20 MC_ANIMAL 0 2 0 3 180 +MT_BFALLSD 128 623 Monsters\\FalSword\\Fall%c.CL2 1 Monsters\\FalSword\\Fall%c%i.WAV 1 1 Monsters\\FalSword\\Blue.TRN "12, 12, 13, 11, 14, 15" "3, 0, 0, 0, 0, 0" Dark One 5 9 7 24 36 AI_FALLEN 0 3 30 8 4 12 0 5 0 0 25 MC_ANIMAL 64 68 0 3 280 +MT_NSCAV 128 410 Monsters\\Scav\\Scav%c.CL2 1 Monsters\\Scav\\Scav%c%i.WAV 0 0 NULL "12, 8, 12, 6, 20, 11" "2, 0, 0, 0, 0, 0" Scavenger 1 4 2 3 6 AI_SCAV 0 0 20 7 1 5 0 0 0 0 10 MC_ANIMAL 0 2 0 3 80 +MT_BSCAV 128 410 Monsters\\Scav\\Scav%c.CL2 1 Monsters\\Scav\\Scav%c%i.WAV 0 1 Monsters\\Scav\\ScavBr.TRN "12, 8, 12, 6, 20, 11" "2, 0, 0, 0, 0, 0" Plague Eater 3 6 4 12 24 AI_SCAV 0 1 30 7 1 8 0 0 0 0 20 MC_ANIMAL 0 4 0 3 188 +MT_WSCAV 128 410 Monsters\\Scav\\Scav%c.CL2 1 Monsters\\Scav\\Scav%c%i.WAV 0 1 Monsters\\Scav\\ScavBe.TRN "12, 8, 12, 6, 20, 11" "2, 0, 0, 0, 0, 0" Shadow Beast 4 8 6 24 36 AI_SCAV 0 2 35 7 3 12 0 0 0 0 25 MC_ANIMAL 64 66 0 3 375 +MT_YSCAV 128 410 Monsters\\Scav\\Scav%c.CL2 1 Monsters\\Scav\\Scav%c%i.WAV 0 1 Monsters\\Scav\\ScavW.TRN "12, 8, 12, 6, 20, 11" "2, 0, 0, 0, 0, 0" Bone Gasher 6 10 8 28 40 AI_SCAV 0 3 35 7 5 15 0 0 0 0 30 MC_ANIMAL 65 68 0 3 552 +MT_WSKELBW 128 567 Monsters\\SkelBow\\SklBw%c.CL2 1 Monsters\\SkelBow\\SklBw%c%i.WAV 0 1 Monsters\\SkelBow\\White.TRN "9, 8, 16, 5, 16, 16" "4, 0, 0, 0, 0, 0" Skeleton 2 5 3 2 4 AI_SKELBOW 0 0 15 12 1 2 0 0 0 0 0 MC_UNDEAD 72 72 0 3 110 +MT_TSKELBW 128 567 Monsters\\SkelBow\\SklBw%c.CL2 1 Monsters\\SkelBow\\SklBw%c%i.WAV 0 1 Monsters\\SkelBow\\Skelt.TRN "9, 8, 16, 5, 16, 16" "4, 0, 0, 0, 0, 0" Corpse Bow 3 7 5 8 16 AI_SKELBOW 0 1 25 12 1 4 0 0 0 0 0 MC_UNDEAD 72 72 0 3 210 +MT_RSKELBW 128 567 Monsters\\SkelBow\\SklBw%c.CL2 1 Monsters\\SkelBow\\SklBw%c%i.WAV 0 0 NULL "9, 8, 16, 5, 16, 16" "2, 0, 0, 0, 0, 0" Burning Dead 5 9 7 10 24 AI_SKELBOW 0 2 30 12 1 6 0 0 0 0 5 MC_UNDEAD 74 88 0 3 364 +MT_XSKELBW 128 567 Monsters\\SkelBow\\SklBw%c.CL2 1 Monsters\\SkelBow\\SklBw%c%i.WAV 0 1 Monsters\\SkelBow\\Black.TRN "9, 8, 16, 5, 16, 16" "3, 0, 0, 0, 0, 0" Horror 7 11 9 15 45 AI_SKELBOW 0 3 35 12 2 9 0 0 0 0 15 MC_UNDEAD 76 76 0 3 594 +MT_WSKELSD 128 575 Monsters\\SkelSd\\SklSr%c.CL2 1 Monsters\\SkelSd\\SklSr%c%i.WAV 1 1 Monsters\\SkelSd\\White.TRN "13, 8, 12, 7, 15, 16" "4, 0, 0, 0, 0, 0" Skeleton Captain 1 4 2 3 6 AI_SKELSD 0 0 20 8 2 7 0 0 0 0 10 MC_UNDEAD 72 72 0 3 90 +MT_TSKELSD 128 575 Monsters\\SkelSd\\SklSr%c.CL2 1 Monsters\\SkelSd\\SklSr%c%i.WAV 0 1 Monsters\\SkelSd\\Skelt.TRN "13, 8, 12, 7, 15, 16" "4, 0, 0, 0, 0, 0" Corpse Captain 2 6 4 12 20 AI_SKELSD 0 1 30 8 3 9 0 0 0 0 5 MC_UNDEAD 72 72 0 3 200 +MT_RSKELSD 128 575 Monsters\\SkelSd\\SklSr%c.CL2 1 Monsters\\SkelSd\\SklSr%c%i.WAV 0 0 NULL "13, 8, 12, 7, 15, 16" "4, 0, 0, 0, 0, 0" Burning Dead Captain 4 8 6 16 30 AI_SKELSD 0 2 35 8 4 10 0 0 0 0 15 MC_UNDEAD 74 88 0 3 393 +MT_XSKELSD 128 575 Monsters\\SkelSd\\SklSr%c.CL2 1 Monsters\\SkelSd\\SklSr%c%i.WAV 0 1 Monsters\\SkelSd\\Black.TRN "13, 8, 12, 7, 15, 16" "4, 0, 0, 0, 0, 0" Horror Captain 6 10 8 35 50 AI_SKELSD 256 3 40 8 5 14 0 0 0 0 30 MC_UNDEAD 76 76 0 3 604 +MT_INVILORD 128 2000 Monsters\\TSneak\\TSneak%c.CL2 0 Monsters\\TSneak\\Sneakl%c%i.WAV 0 0 NULL "13, 13, 15, 11, 16, 0" "2, 0, 0, 0, 0, 0" Invisible Lord 14 14 14 278 278 AI_SKELSD 256 3 65 8 16 30 0 0 0 0 60 MC_DEMON 71 71 0 3 2000 +MT_SNEAK 128 992 Monsters\\Sneak\\Sneak%c.CL2 1 Monsters\\Sneak\\Sneak%c%i.WAV 0 0 NULL "16, 8, 12, 8, 24, 15" "2, 0, 0, 0, 0, 0" Hidden 3 8 5 8 24 AI_SNEAK 1 0 35 8 3 6 0 0 0 0 25 MC_DEMON 0 64 0 3 278 +MT_STALKER 128 992 Monsters\\Sneak\\Sneak%c.CL2 1 Monsters\\Sneak\\Sneak%c%i.WAV 0 1 Monsters\\Sneak\\Sneakv2.TRN "16, 8, 12, 8, 24, 15" "2, 0, 0, 0, 0, 0" Stalker 8 12 9 30 45 AI_SNEAK 257 1 40 8 8 16 0 0 0 0 30 MC_DEMON 0 64 0 3 630 +MT_UNSEEN 128 992 Monsters\\Sneak\\Sneak%c.CL2 1 Monsters\\Sneak\\Sneak%c%i.WAV 0 1 Monsters\\Sneak\\Sneakv3.TRN "16, 8, 12, 8, 24, 15" "2, 0, 0, 0, 0, 0" Unseen 10 14 11 35 50 AI_SNEAK 257 2 45 8 12 20 0 0 0 0 30 MC_DEMON 65 72 0 3 935 +MT_ILLWEAV 128 992 Monsters\\Sneak\\Sneak%c.CL2 1 Monsters\\Sneak\\Sneak%c%i.WAV 0 1 Monsters\\Sneak\\Sneakv1.TRN "16, 8, 12, 8, 24, 15" "2, 0, 0, 0, 0, 0" Illusion Weaver 14 18 13 40 60 AI_SNEAK 257 3 60 8 16 24 0 0 0 0 30 MC_DEMON 3 74 0 3 1500 +MT_LRDSAYTR 160 2000 Monsters\\GoatLord\\GoatL%c.CL2 0 Monsters\\GoatLord\\Goatl%c%i.WAV 0 0 NULL "13, 13, 14, 9, 16, 0" "2, 0, 0, 0, 0, 0" Lord Sayter 13 13 12 351 351 AI_SKELSD 256 3 80 8 14 24 0 0 0 0 60 MC_DEMON 67 67 0 3 1500 +MT_NGOATMC 128 1030 Monsters\\GoatMace\\Goat%c.CL2 1 Monsters\\GoatMace\\Goat%c%i.WAV 0 0 NULL "12, 8, 12, 6, 20, 12" "2, 0, 0, 0, 1, 0" Flesh Clan 6 10 8 30 45 AI_GOATMC 768 0 50 8 4 10 0 0 0 0 40 MC_DEMON 0 0 0 3 460 +MT_BGOATMC 128 1030 Monsters\\GoatMace\\Goat%c.CL2 1 Monsters\\GoatMace\\Goat%c%i.WAV 0 1 Monsters\\GoatMace\\Beige.TRN "12, 8, 12, 6, 20, 12" "2, 0, 0, 0, 1, 0" Stone Clan 8 12 10 40 55 AI_GOATMC 768 1 60 8 6 12 0 0 0 0 40 MC_DEMON 65 72 0 3 685 +MT_RGOATMC 128 1030 Monsters\\GoatMace\\Goat%c.CL2 1 Monsters\\GoatMace\\Goat%c%i.WAV 0 1 Monsters\\GoatMace\\Red.TRN "12, 8, 12, 6, 20, 12" "2, 0, 0, 0, 1, 0" Fire Clan 10 14 12 50 65 AI_GOATMC 768 2 70 8 8 16 0 0 0 0 45 MC_DEMON 2 16 0 3 906 +MT_GGOATMC 128 1030 Monsters\\GoatMace\\Goat%c.CL2 1 Monsters\\GoatMace\\Goat%c%i.WAV 0 1 Monsters\\GoatMace\\Gray.TRN "12, 8, 12, 6, 20, 12" "2, 0, 0, 0, 1, 0" Night Clan 12 16 14 55 70 AI_GOATMC 768 3 80 8 10 20 15 0 30 30 50 MC_DEMON 65 72 0 3 1190 +MT_FIEND 96 364 Monsters\\Bat\\Bat%c.CL2 0 Monsters\\Bat\\Bat%c%i.WAV 0 1 Monsters\\Bat\\red.trn "9, 13, 10, 9, 13, 0" "0, 0, 0, 0, 0, 0" Fiend 2 5 3 3 6 AI_BAT 0 0 35 5 1 6 0 0 0 0 0 MC_ANIMAL 0 0 16384 6 102 +MT_BLINK 96 364 Monsters\\Bat\\Bat%c.CL2 0 Monsters\\Bat\\Bat%c%i.WAV 0 0 NULL "9, 13, 10, 9, 13, 0" "0, 0, 0, 0, 0, 0" Blink 5 9 7 12 28 AI_BAT 0 1 45 5 1 8 0 0 0 0 15 MC_ANIMAL 0 0 16384 6 340 +MT_GLOOM 96 364 Monsters\\Bat\\Bat%c.CL2 0 Monsters\\Bat\\Bat%c%i.WAV 0 1 Monsters\\Bat\\grey.trn "9, 13, 10, 9, 13, 0" "0, 0, 0, 0, 0, 0" Gloom 7 11 9 28 36 AI_BAT 256 2 70 5 4 12 0 0 0 0 35 MC_ANIMAL 1 65 16384 6 509 +MT_FAMILIAR 96 364 Monsters\\Bat\\Bat%c.CL2 0 Monsters\\Bat\\Bat%c%i.WAV 0 1 Monsters\\Bat\\orange.trn "9, 13, 10, 9, 13, 0" "0, 0, 0, 0, 0, 0" Familiar 11 15 13 20 35 AI_BAT 256 3 50 5 4 16 0 0 0 0 35 MC_DEMON 33 97 16384 6 448 +MT_NGOATBW 128 1040 Monsters\\GoatBow\\GoatB%c.CL2 0 Monsters\\GoatBow\\GoatB%c%i.WAV 0 0 NULL "12, 8, 16, 6, 20, 0" "3, 0, 0, 0, 0, 0" Flesh Clan 6 10 8 20 35 AI_GOATBOW 512 0 35 13 1 7 0 0 0 0 35 MC_DEMON 0 0 0 3 448 +MT_BGOATBW 128 1040 Monsters\\GoatBow\\GoatB%c.CL2 0 Monsters\\GoatBow\\GoatB%c%i.WAV 0 1 Monsters\\GoatBow\\Beige.TRN "12, 8, 16, 6, 20, 0" "3, 0, 0, 0, 0, 0" Stone Clan 8 12 10 30 40 AI_GOATBOW 512 1 40 13 2 9 0 0 0 0 35 MC_DEMON 65 72 0 3 645 +MT_RGOATBW 128 1040 Monsters\\GoatBow\\GoatB%c.CL2 0 Monsters\\GoatBow\\GoatB%c%i.WAV 0 1 Monsters\\GoatBow\\Red.TRN "12, 8, 16, 6, 20, 0" "3, 0, 0, 0, 0, 0" Fire Clan 10 14 12 40 50 AI_GOATBOW 768 2 45 13 3 11 0 0 0 0 35 MC_DEMON 2 16 0 3 822 +MT_GGOATBW 128 1040 Monsters\\GoatBow\\GoatB%c.CL2 0 Monsters\\GoatBow\\GoatB%c%i.WAV 0 1 Monsters\\GoatBow\\Gray.TRN "12, 8, 16, 6, 20, 0" "3, 0, 0, 0, 0, 0" Night Clan 12 16 14 50 65 AI_GOATBOW 768 3 50 13 4 13 15 0 0 0 40 MC_DEMON 65 72 0 3 1092 +MT_NACID 128 716 Monsters\\Acid\\Acid%c.CL2 1 Monsters\\Acid\\Acid%c%i.WAV 1 0 NULL "13, 8, 12, 8, 16, 12" "0, 0, 0, 0, 0, 0" Acid Beast 10 14 11 40 66 AI_ACID 0 0 40 8 4 12 25 8 0 0 30 MC_ANIMAL 128 136 0 3 846 +MT_RACID 128 716 Monsters\\Acid\\Acid%c.CL2 1 Monsters\\Acid\\Acid%c%i.WAV 1 1 Monsters\\Acid\\AcidBlk.TRN "13, 8, 12, 8, 16, 12" "0, 0, 0, 0, 0, 0" Poison Spitter 14 18 15 60 85 AI_ACID 0 1 45 8 4 16 25 8 0 0 30 MC_ANIMAL 128 136 0 3 1248 +MT_BACID 128 716 Monsters\\Acid\\Acid%c.CL2 1 Monsters\\Acid\\Acid%c%i.WAV 1 1 Monsters\\Acid\\AcidB.TRN "13, 8, 12, 8, 16, 12" "0, 0, 0, 0, 0, 0" Pit Beast 18 22 21 80 110 AI_ACID 0 2 55 8 8 18 35 8 0 0 35 MC_ANIMAL 129 140 0 3 2060 +MT_XACID 128 716 Monsters\\Acid\\Acid%c.CL2 1 Monsters\\Acid\\Acid%c%i.WAV 1 1 Monsters\\Acid\\AcidR.TRN "13, 8, 12, 8, 16, 12" "0, 0, 0, 0, 0, 0" Lava Maw 22 27 25 100 150 AI_ACID 0 3 65 8 10 20 40 8 0 0 35 MC_ANIMAL 145 152 0 3 2940 +MT_SKING 160 1010 Monsters\\SKing\\SKing%c.CL2 1 Monsters\\SKing\\SKing%c%i.WAV 1 1 Monsters\\SkelAxe\\White.TRN "8, 6, 16, 6, 16, 6" "2, 0, 0, 0, 0, 2" Skeleton King 6 6 9 140 140 AI_SKELKING 768 3 60 8 6 16 0 0 0 0 70 MC_UNDEAD 78 120 32769 7 570 +MT_CLEAVER 128 980 Monsters\\FatC\\FatC%c.CL2 0 Monsters\\FatC\\FatC%c%i.WAV 0 0 NULL "10, 8, 12, 6, 16, 0" "1, 0, 0, 0, 0, 0" The Butcher 0 0 1 320 320 AI_CLEAVER 0 3 50 8 6 12 0 0 0 0 50 MC_DEMON 6 49 32768 3 710 +MT_FAT 128 1130 Monsters\\Fat\\Fat%c.CL2 1 Monsters\\Fat\\Fat%c%i.WAV 0 0 NULL "8, 10, 15, 6, 16, 10" "4, 0, 0, 0, 0, 0" Overlord 8 12 10 60 80 AI_FAT 0 0 55 8 6 12 0 0 0 0 55 MC_DEMON 0 2 0 3 635 +MT_MUDMAN 128 1130 Monsters\\Fat\\Fat%c.CL2 1 Monsters\\Fat\\Fat%c%i.WAV 0 1 Monsters\\Fat\\Blue.TRN "8, 10, 15, 6, 16, 10" "4, 0, 0, 0, 0, 0" Mud Man 13 17 14 100 125 AI_FAT 256 1 60 8 8 16 0 0 0 0 60 MC_DEMON 0 32 0 3 1165 +MT_TOAD 128 1130 Monsters\\Fat\\Fat%c.CL2 1 Monsters\\Fat\\Fat%c%i.WAV 0 1 Monsters\\Fat\\FatB.TRN "8, 10, 15, 6, 16, 10" "4, 0, 0, 0, 0, 0" Toad Demon 15 19 16 135 160 AI_FAT 256 2 70 8 8 16 40 0 8 20 65 MC_DEMON 8 12 0 3 1380 +MT_FLAYED 128 1130 Monsters\\Fat\\Fat%c.CL2 1 Monsters\\Fat\\Fat%c%i.WAV 0 1 Monsters\\Fat\\FatF.TRN "8, 10, 15, 6, 16, 10" "4, 0, 0, 0, 0, 0" Flayed One 19 23 20 160 200 AI_FAT 256 3 85 8 10 20 0 0 0 0 70 MC_DEMON 17 24 0 3 2058 +MT_WYRM 160 2420 Monsters\\Worm\\Worm%c.CL2 0 Monsters\\Fat\\Fat%c%i.WAV 0 0 NULL "13, 13, 13, 11, 19, 0" "0, 0, 0, 0, 0, 0" Wyrm 9 13 11 60 90 AI_SKELSD 0 0 40 8 4 10 0 0 0 0 25 MC_ANIMAL 1 1 0 3 660 +MT_CAVSLUG 160 2420 Monsters\\Worm\\Worm%c.CL2 0 Monsters\\Fat\\Fat%c%i.WAV 0 0 NULL "13, 13, 13, 11, 19, 0" "0, 0, 0, 0, 0, 0" Cave Slug 11 15 13 75 110 AI_SKELSD 0 1 50 8 6 13 0 0 0 0 30 MC_ANIMAL 1 1 0 3 994 +MT_DVLWYRM 160 2420 Monsters\\Worm\\Worm%c.CL2 0 Monsters\\Fat\\Fat%c%i.WAV 0 0 NULL "13, 13, 13, 11, 19, 0" "0, 0, 0, 0, 0, 0" Devil Wyrm 13 17 15 100 140 AI_SKELSD 0 2 55 8 8 16 0 0 0 0 30 MC_ANIMAL 3 3 0 3 1320 +MT_DEVOUR 160 2420 Monsters\\Worm\\Worm%c.CL2 0 Monsters\\Fat\\Fat%c%i.WAV 0 0 NULL "13, 13, 13, 11, 19, 0" "0, 0, 0, 0, 0, 0" Devourer 15 19 17 125 200 AI_SKELSD 0 3 60 8 10 20 0 0 0 0 35 MC_ANIMAL 67 67 0 3 1827 +MT_NMAGMA 128 1680 Monsters\\Magma\\Magma%c.CL2 1 Monsters\\Magma\\Magma%c%i.WAV 1 0 NULL "8, 10, 14, 7, 18, 18" "2, 0, 0, 0, 1, 0" Magma Demon 14 17 13 50 70 AI_MAGMA 768 0 45 4 2 10 50 13 0 0 45 MC_DEMON 10 24 0 7 1076 +MT_YMAGMA 128 1680 Monsters\\Magma\\Magma%c.CL2 1 Monsters\\Magma\\Magma%c%i.WAV 1 1 Monsters\\Magma\\Yellow.TRN "8, 10, 14, 7, 18, 18" "2, 0, 0, 0, 1, 0" Blood Stone 15 19 14 55 75 AI_MAGMA 768 1 50 4 2 12 50 14 0 0 45 MC_DEMON 24 24 0 7 1309 +MT_BMAGMA 128 1680 Monsters\\Magma\\Magma%c.CL2 1 Monsters\\Magma\\Magma%c%i.WAV 1 1 Monsters\\Magma\\Blue.TRN "8, 10, 14, 7, 18, 18" "2, 0, 0, 0, 1, 0" Hell Stone 16 20 16 60 80 AI_MAGMA 768 2 60 4 2 20 60 14 0 0 50 MC_DEMON 24 24 0 7 1680 +MT_WMAGMA 128 1680 Monsters\\Magma\\Magma%c.CL2 1 Monsters\\Magma\\Magma%c%i.WAV 1 1 Monsters\\Magma\\Wierd.TRN "8, 10, 14, 7, 18, 18" "2, 0, 0, 0, 1, 0" Lava Lord 17 21 18 70 85 AI_MAGMA 768 3 75 4 4 24 60 14 0 0 60 MC_DEMON 24 24 0 7 2124 +MT_HORNED 160 1630 Monsters\\Rhino\\Rhino%c.CL2 1 Monsters\\Rhino\\Rhino%c%i.WAV 1 0 NULL "8, 8, 14, 6, 16, 6" "2, 0, 0, 0, 0, 0" Horned Demon 12 16 13 40 80 AI_RHINO 768 0 60 7 2 16 100 0 5 32 40 MC_ANIMAL 0 2 0 7 1172 +MT_MUDRUN 160 1630 Monsters\\Rhino\\Rhino%c.CL2 1 Monsters\\Rhino\\Rhino%c%i.WAV 1 1 Monsters\\Rhino\\Orange.TRN "8, 8, 14, 6, 16, 6" "2, 0, 0, 0, 0, 0" Mud Runner 14 18 15 50 90 AI_RHINO 768 1 70 7 6 18 100 0 12 36 45 MC_ANIMAL 0 2 0 7 1404 +MT_FROSTC 160 1630 Monsters\\Rhino\\Rhino%c.CL2 1 Monsters\\Rhino\\Rhino%c%i.WAV 1 1 Monsters\\Rhino\\Blue.TRN "8, 8, 14, 6, 16, 6" "2, 0, 0, 0, 0, 0" Frost Charger 16 20 17 60 100 AI_RHINO 768 2 80 7 8 20 100 0 20 40 50 MC_ANIMAL 12 12 0 7 1720 +MT_OBLORD 160 1630 Monsters\\Rhino\\Rhino%c.CL2 1 Monsters\\Rhino\\Rhino%c%i.WAV 1 1 Monsters\\Rhino\\RhinoB.TRN "8, 8, 14, 6, 16, 6" "2, 0, 0, 0, 0, 0" Obsidian Lord 18 22 19 70 110 AI_RHINO 768 3 90 7 10 22 100 0 20 50 55 MC_ANIMAL 12 56 0 7 1809 +MT_BONEDMN 128 1740 Monsters\\Demskel\\Demskl%c.CL2 1 Monsters\\Thin\\Thin%c%i.WAV 1 0 Monsters\\Thin\\Thinv3.TRN "10, 8, 20, 6, 24, 16" "3, 0, 0, 0, 0, 0" Bone Demon 10 14 12 70 70 AI_STORM 0 0 60 8 6 14 12 0 0 0 50 MC_DEMON 72 72 0 7 1344 +MT_REDDTH 160 1740 Monsters\\Thin\\Thin%c.CL2 1 Monsters\\Thin\\Thin%c%i.WAV 1 1 Monsters\\Thin\\Thinv3.TRN "8, 8, 18, 4, 17, 14" "3, 0, 0, 0, 0, 0" Red Death 14 18 16 96 96 AI_STORM 0 1 75 5 10 20 0 0 0 0 60 MC_DEMON 24 24 0 7 2168 +MT_LTCHDMN 160 1740 Monsters\\Thin\\Thin%c.CL2 1 Monsters\\Thin\\Thin%c%i.WAV 1 1 Monsters\\Thin\\Thinv3.TRN "8, 8, 18, 4, 17, 14" "3, 0, 0, 0, 0, 0" Litch Demon 16 20 18 110 110 AI_STORM 0 2 80 5 10 24 0 0 0 0 45 MC_DEMON 104 104 0 7 2736 +MT_UDEDBLRG 160 1740 Monsters\\Thin\\Thin%c.CL2 1 Monsters\\Thin\\Thin%c%i.WAV 1 1 Monsters\\Thin\\Thinv3.TRN "8, 8, 18, 4, 17, 14" "3, 0, 0, 0, 0, 0" Undead Balrog 20 24 22 130 130 AI_STORM 0 3 85 5 12 30 0 0 0 0 65 MC_DEMON 78 78 0 7 3575 +MT_INCIN 128 1460 Monsters\\Fireman\\FireM%c.CL2 1 Monsters\\Acid\\Acid%c%i.WAV 0 0 NULL "14, 19, 20, 8, 14, 23" "0, 0, 0, 0, 0, 0" Incinerator 14 18 16 30 45 AI_FIREMAN 0 0 75 8 8 16 0 0 0 0 25 MC_DEMON 24 24 0 3 1888 +MT_FLAMLRD 128 1460 Monsters\\Fireman\\FireM%c.CL2 1 Monsters\\Acid\\Acid%c%i.WAV 0 0 NULL "14, 19, 20, 8, 14, 23" "0, 0, 0, 0, 0, 0" Flame Lord 16 20 18 40 55 AI_FIREMAN 0 1 75 8 10 20 0 0 0 0 25 MC_DEMON 24 24 0 3 2250 +MT_DOOMFIRE 128 1460 Monsters\\Fireman\\FireM%c.CL2 1 Monsters\\Acid\\Acid%c%i.WAV 0 0 NULL "14, 19, 20, 8, 14, 23" "0, 0, 0, 0, 0, 0" Doom Fire 18 22 20 50 65 AI_FIREMAN 0 2 80 8 12 24 0 0 0 0 30 MC_DEMON 28 28 0 3 2740 +MT_HELLBURN 128 1460 Monsters\\Fireman\\FireM%c.CL2 1 Monsters\\Acid\\Acid%c%i.WAV 0 0 NULL "14, 19, 20, 8, 14, 23" "0, 0, 0, 0, 0, 0" Hell Burner 20 24 22 60 80 AI_FIREMAN 0 3 85 8 15 30 0 0 0 0 30 MC_DEMON 28 28 0 3 3355 +MT_STORM 160 1740 Monsters\\Thin\\Thin%c.CL2 1 Monsters\\Thin\\Thin%c%i.WAV 1 1 Monsters\\Thin\\Thinv3.TRN "8, 8, 18, 4, 17, 14" "3, 0, 0, 0, 0, 0" Red Storm 17 21 18 55 110 AI_STORM 768 0 80 5 8 18 75 8 4 16 30 MC_DEMON 12 40 0 7 2160 +MT_RSTORM 160 1740 Monsters\\Thin\\Thin%c.CL2 1 Monsters\\Thin\\Thin%c%i.WAV 1 0 NULL "8, 8, 18, 4, 17, 14" "3, 0, 0, 0, 0, 0" Storm Rider 19 23 20 60 120 AI_STORM 768 1 80 5 8 18 80 8 4 16 30 MC_DEMON 33 40 0 7 2391 +MT_STORML 160 1740 Monsters\\Thin\\Thin%c.CL2 1 Monsters\\Thin\\Thin%c%i.WAV 1 1 Monsters\\Thin\\Thinv2.TRN "8, 8, 18, 4, 17, 14" "3, 0, 0, 0, 0, 0" Storm Lord 21 25 22 75 135 AI_STORM 768 2 85 5 12 24 75 8 4 16 35 MC_DEMON 33 40 0 7 2775 +MT_MAEL 160 1740 Monsters\\Thin\\Thin%c.CL2 1 Monsters\\Thin\\Thin%c%i.WAV 1 1 Monsters\\Thin\\Thinv1.TRN "8, 8, 18, 4, 17, 14" "3, 0, 0, 0, 0, 0" Maelstorm 23 27 24 90 150 AI_STORM 768 3 90 5 12 28 75 8 4 16 40 MC_DEMON 97 104 0 7 3177 +MT_BIGFALL 128 1650 Monsters\\BigFall\\Fallg%c.CL2 1 Monsters\\BigFall\\Bfal%c%i.WAV 0 0 NULL "10, 8, 11, 8, 17, 0" "0, 0, 0, 0, 2, 2" Devil Kin Brute 20 20 24 160 220 AI_SKELSD 768 3 100 6 18 24 0 0 0 0 75 MC_ANIMAL 0 0 0 6 2000 +MT_WINGED 160 1650 Monsters\\Gargoyle\\Gargo%c.CL2 1 Monsters\\Gargoyle\\Gargo%c%i.WAV 0 0 NULL "14, 14, 14, 10, 18, 14" "0, 0, 0, 0, 0, 2" Winged-Demon 8 12 9 45 60 AI_GARG 512 0 50 7 10 16 0 0 0 0 45 MC_DEMON 74 88 0 6 662 +MT_GARGOYLE 160 1650 Monsters\\Gargoyle\\Gargo%c.CL2 1 Monsters\\Gargoyle\\Gargo%c%i.WAV 0 1 Monsters\\Gargoyle\\GarE.TRN "14, 14, 14, 10, 18, 14" "0, 0, 0, 0, 0, 2" Gargoyle 12 16 13 60 90 AI_GARG 512 1 65 7 10 16 0 0 0 0 45 MC_DEMON 76 104 0 6 1205 +MT_BLOODCLW 160 1650 Monsters\\Gargoyle\\Gargo%c.CL2 1 Monsters\\Gargoyle\\Gargo%c%i.WAV 0 1 Monsters\\Gargoyle\\GargBr.TRN "14, 14, 14, 10, 18, 14" "0, 0, 0, 0, 0, 0" Blood Claw 16 20 19 75 125 AI_GARG 512 2 80 7 14 22 0 0 0 0 50 MC_DEMON 88 92 0 6 1873 +MT_DEATHW 160 1650 Monsters\\Gargoyle\\Gargo%c.CL2 1 Monsters\\Gargoyle\\Gargo%c%i.WAV 0 1 Monsters\\Gargoyle\\GargB.TRN "14, 14, 14, 10, 18, 14" "0, 0, 0, 0, 0, 0" Death Wing 18 22 23 90 150 AI_GARG 512 3 95 7 16 28 0 0 0 0 60 MC_DEMON 104 106 0 6 2278 +MT_MEGA 160 2220 Monsters\\Mega\\Mega%c.CL2 1 Monsters\\Mega\\Mega%c%i.WAV 1 0 NULL "6, 7, 14, 1, 24, 5" "3, 0, 0, 0, 2, 0" Slayer 19 23 20 120 140 AI_MEGA 768 0 100 8 12 20 0 3 0 0 60 MC_DEMON 17 17 0 7 2300 +MT_GUARD 160 2220 Monsters\\Mega\\Mega%c.CL2 1 Monsters\\Mega\\Mega%c%i.WAV 1 1 Monsters\\Mega\\Guard.TRN "6, 7, 14, 1, 24, 5" "3, 0, 0, 0, 2, 0" Guardian 21 25 22 140 160 AI_MEGA 768 1 110 8 14 22 0 3 0 0 65 MC_DEMON 17 17 0 7 2714 +MT_VTEXLRD 160 2220 Monsters\\Mega\\Mega%c.CL2 1 Monsters\\Mega\\Mega%c%i.WAV 1 1 Monsters\\Mega\\Vtexl.TRN "6, 7, 14, 1, 24, 5" "3, 0, 0, 0, 2, 0" Vortex Lord 23 26 24 160 180 AI_MEGA 768 2 120 8 18 24 0 3 0 0 70 MC_DEMON 81 85 0 7 3252 +MT_BALROG 160 2220 Monsters\\Mega\\Mega%c.CL2 1 Monsters\\Mega\\Mega%c%i.WAV 1 1 Monsters\\Mega\\Balr.TRN "6, 7, 14, 1, 24, 5" "3, 0, 0, 0, 2, 0" Balrog 25 29 26 180 200 AI_MEGA 768 3 130 8 22 30 0 3 0 0 75 MC_DEMON 81 85 0 7 3643 +MT_NSNAKE 160 1270 Monsters\\Snake\\Snake%c.CL2 0 Monsters\\Snake\\Snake%c%i.WAV 0 0 NULL "12, 11, 13, 5, 18, 0" "2, 0, 0, 0, 1, 0" Cave Viper 20 24 21 100 150 AI_SNAKE 256 0 90 8 8 20 0 0 0 0 60 MC_DEMON 8 8 0 7 2725 +MT_RSNAKE 160 1270 Monsters\\Snake\\Snake%c.CL2 0 Monsters\\Snake\\Snake%c%i.WAV 0 1 Monsters\\Snake\\SnakR.TRN "12, 11, 13, 5, 18, 0" "2, 0, 0, 0, 1, 0" Fire Drake 22 26 23 120 170 AI_SNAKE 256 1 105 8 12 24 0 0 0 0 65 MC_DEMON 10 24 0 7 3139 +MT_BSNAKE 160 1270 Monsters\\Snake\\Snake%c.CL2 0 Monsters\\Snake\\Snake%c%i.WAV 0 1 Monsters\\Snake\\Snakg.TRN "12, 11, 13, 5, 18, 0" "2, 0, 0, 0, 1, 0" Gold Viper 24 27 25 140 180 AI_SNAKE 256 2 120 8 15 26 0 0 0 0 70 MC_DEMON 12 12 0 7 3540 +MT_GSNAKE 160 1270 Monsters\\Snake\\Snake%c.CL2 0 Monsters\\Snake\\Snake%c%i.WAV 0 1 Monsters\\Snake\\Snakb.TRN "12, 11, 13, 5, 18, 0" "2, 0, 0, 0, 1, 0" Azure Drake 28 30 27 160 200 AI_SNAKE 256 3 130 8 18 30 0 0 0 0 75 MC_DEMON 6 42 0 7 3791 +MT_NBLACK 160 2120 Monsters\\Black\\Black%c.CL2 0 Monsters\\Black\\Black%c%i.WAV 0 0 NULL "8, 8, 16, 4, 24, 0" "2, 0, 0, 0, 0, 0" Black Knight 23 27 24 150 150 AI_SKELSD 256 0 110 8 15 20 0 0 0 0 75 MC_DEMON 69 97 0 7 3360 +MT_RTBLACK 160 2120 Monsters\\Black\\Black%c.CL2 0 Monsters\\Black\\Black%c%i.WAV 0 1 Monsters\\Black\\BlkKntRT.TRN "8, 8, 16, 4, 24, 0" "2, 0, 0, 0, 0, 0" Doom Guard 25 29 26 165 165 AI_SKELSD 256 0 130 8 18 25 0 0 0 0 75 MC_DEMON 67 81 0 7 3650 +MT_BTBLACK 160 2120 Monsters\\Black\\Black%c.CL2 0 Monsters\\Black\\Black%c%i.WAV 0 1 Monsters\\Black\\BlkKntBT.TRN "8, 8, 16, 4, 24, 0" "2, 0, 0, 0, 0, 0" Steel Lord 27 30 28 180 180 AI_SKELSD 256 1 120 8 20 30 0 0 0 0 80 MC_DEMON 85 92 0 7 4252 +MT_RBLACK 160 2120 Monsters\\Black\\Black%c.CL2 0 Monsters\\Black\\Black%c%i.WAV 0 1 Monsters\\Black\\BlkKntBe.TRN "8, 8, 16, 4, 24, 0" "2, 0, 0, 0, 0, 0" Blood Knight 24 26 30 200 200 AI_SKELSD 256 1 130 8 25 35 0 0 0 0 85 MC_DEMON 106 106 0 7 5130 +MT_UNRAV 96 484 Monsters\\Unrav\\Unrav%c.CL2 0 Monsters\\Acid\\Acid%c%i.WAV 0 0 NULL "10, 10, 12, 5, 16, 0" "0, 0, 0, 0, 0, 0" Unraveler 26 28 25 70 150 AI_SKELSD 0 0 75 7 10 20 0 0 0 0 70 MC_UNDEAD 106 106 0 3 3812 +MT_HOLOWONE 96 484 Monsters\\Unrav\\Unrav%c.CL2 0 Monsters\\Acid\\Acid%c%i.WAV 0 0 NULL "10, 10, 12, 5, 16, 0" "0, 0, 0, 0, 0, 0" Hollow One 28 30 27 135 240 AI_SKELSD 0 1 75 7 12 24 0 0 0 0 75 MC_UNDEAD 92 92 0 3 4374 +MT_PAINMSTR 96 484 Monsters\\Unrav\\Unrav%c.CL2 0 Monsters\\Acid\\Acid%c%i.WAV 0 0 NULL "10, 10, 12, 5, 16, 0" "0, 0, 0, 0, 0, 0" Pain Master 27 30 29 110 200 AI_SKELSD 0 2 80 7 16 30 0 0 0 0 80 MC_UNDEAD 92 92 0 3 5147 +MT_REALWEAV 96 484 Monsters\\Unrav\\Unrav%c.CL2 0 Monsters\\Acid\\Acid%c%i.WAV 0 0 NULL "10, 10, 12, 5, 16, 0" "0, 0, 0, 0, 0, 0" Reality Weaver 28 30 30 135 240 AI_SKELSD 0 3 85 7 20 35 0 0 0 0 85 MC_UNDEAD 113 113 0 3 5925 +MT_SUCCUBUS 128 980 Monsters\\Succ\\Scbs%c.CL2 0 Monsters\\Succ\\Scbs%c%i.WAV 0 0 NULL "14, 8, 16, 7, 24, 0" "0, 0, 0, 0, 0, 0" Succubus 22 26 24 120 150 AI_SUCC 512 0 100 10 1 20 0 0 0 0 60 MC_DEMON 1 10 0 3 3696 +MT_SNOWWICH 128 980 Monsters\\Succ\\Scbs%c.CL2 0 Monsters\\Succ\\Scbs%c%i.WAV 0 1 Monsters\\Succ\\Succb.TRN "14, 8, 16, 7, 24, 0" "0, 0, 0, 0, 0, 0" Snow Witch 25 28 26 135 175 AI_SUCC 512 1 110 10 1 24 0 0 0 0 65 MC_DEMON 68 76 0 3 4084 +MT_HLSPWN 128 980 Monsters\\Succ\\Scbs%c.CL2 0 Monsters\\Succ\\Scbs%c%i.WAV 0 1 Monsters\\Succ\\Succrw.TRN "14, 8, 16, 7, 24, 0" "0, 0, 0, 0, 0, 0" Hell Spawn 27 30 28 150 200 AI_SUCC 768 2 115 10 1 30 0 0 0 0 75 MC_DEMON 33 28 0 3 4480 +MT_SOLBRNR 128 980 Monsters\\Succ\\Scbs%c.CL2 0 Monsters\\Succ\\Scbs%c%i.WAV 0 1 Monsters\\Succ\\Succbw.TRN "14, 8, 16, 7, 24, 0" "0, 0, 0, 0, 0, 0" Soul Burner 28 30 30 140 225 AI_SUCC 768 3 120 10 1 35 0 0 0 0 85 MC_DEMON 21 56 0 3 4644 +MT_COUNSLR 128 2000 Monsters\\Mage\\Mage%c.CL2 1 Monsters\\Mage\\Mage%c%i.WAV 0 0 NULL "12, 1, 20, 8, 28, 20" "0, 0, 0, 0, 0, 0" Counselor 24 26 25 70 70 AI_COUNSLR 512 0 90 8 8 20 0 0 0 0 0 MC_DEMON 7 7 0 7 4070 +MT_MAGISTR 128 2000 Monsters\\Mage\\Mage%c.CL2 1 Monsters\\Mage\\Mage%c%i.WAV 0 1 Monsters\\Mage\\Cnselg.TRN "12, 1, 20, 8, 28, 20" "0, 0, 0, 0, 0, 0" Magistrate 26 28 27 85 85 AI_COUNSLR 512 1 100 8 10 24 0 0 0 0 0 MC_DEMON 85 92 0 7 4478 +MT_CABALIST 128 2000 Monsters\\Mage\\Mage%c.CL2 1 Monsters\\Mage\\Mage%c%i.WAV 0 1 Monsters\\Mage\\Cnselgd.TRN "12, 1, 20, 8, 28, 20" "0, 0, 0, 0, 0, 0" Cabalist 28 30 29 120 120 AI_COUNSLR 512 2 110 8 14 30 0 0 0 0 0 MC_DEMON 99 106 0 7 4929 +MT_ADVOCATE 128 2000 Monsters\\Mage\\Mage%c.CL2 1 Monsters\\Mage\\Mage%c%i.WAV 0 1 Monsters\\Mage\\Cnselbk.TRN "12, 1, 20, 8, 28, 20" "0, 0, 0, 0, 0, 0" Advocate 30 30 30 145 145 AI_COUNSLR 512 3 120 8 15 25 0 0 0 0 0 MC_DEMON 106 120 0 7 4968 +MT_GOLEM 96 386 Monsters\\Golem\\Golem%c.CL2 1 Monsters\\Golem\\Golm%c%i.WAV 0 0 NULL "0, 16, 12, 0, 12, 20" "0, 0, 0, 0, 0, 0" Golem 0 0 12 1 1 AI_GOLUM 512 0 0 7 1 1 0 0 0 0 1 MC_DEMON 0 0 0 0 0 +MT_DIABLO 160 2000 Monsters\\Diablo\\Diablo%c.CL2 1 Monsters\\Diablo\\Diablo%c%i.WAV 1 0 NULL "16, 6, 16, 6, 16, 16" "0, 0, 0, 0, 0, 0" The Dark Lord 50 50 30 1666 1666 AI_DIABLO 896 3 220 4 30 60 0 11 0 0 70 MC_DEMON 78 78 0 7 31666 +MT_DARKMAGE 128 1060 Monsters\\DarkMage\\Dmage%c.CL2 1 Monsters\\DarkMage\\Dmag%c%i.WAV 0 0 NULL "6, 1, 21, 6, 23, 18" "0, 0, 0, 0, 0, 0" The Arch-Litch Malignus 30 30 30 160 160 AI_COUNSLR 512 3 120 8 20 40 0 0 0 0 70 MC_DEMON 71 120 0 7 4968 diff --git a/2020_03_31/Source/Data/Excel/xl_obj.txt b/2020_03_31/Source/Data/Excel/xl_obj.txt new file mode 100644 index 00000000..73f8925f --- /dev/null +++ b/2020_03_31/Source/Data/Excel/xl_obj.txt @@ -0,0 +1,100 @@ +# oload(i) ofindex(i) ominlvl(i) omaxlvl(i) olvltype(i) otheme(i) oquest(i) oAnimFlag(i) oAnimDelay(i) oAnimLen(i) oAnimWidth(i) oSolidFlag(i) oMissFlag(i) oLightFlag(i) oBreak(i) oSelFlag(i) oTrapFlag(i) +OBJ_L1LIGHT 1 OFILE_L1BRAZ 1 4 1 -1 -1 1 1 26 64 1 1 0 0 0 0 +OBJ_L1LDOOR 1 OFILE_L1DOORS 1 4 1 -1 -1 0 1 0 64 0 0 1 0 3 1 +OBJ_L1RDOOR 1 OFILE_L1DOORS 1 4 1 -1 -1 0 2 0 64 0 0 1 0 3 1 +OBJ_SKFIRE 3 OFILE_SKULFIRE 0 0 0 3 -1 1 2 11 96 1 1 0 0 0 0 +OBJ_LEVER 1 OFILE_LEVER 1 4 1 -1 -1 0 1 1 96 1 1 1 0 1 1 +OBJ_CHEST1 1 OFILE_CHEST1 1 16 0 -1 -1 0 1 0 96 1 1 1 0 1 1 +OBJ_CHEST2 1 OFILE_CHEST2 1 16 0 -1 -1 0 1 0 96 1 1 1 0 1 1 +OBJ_CHEST3 1 OFILE_CHEST3 1 16 0 -1 -1 0 1 0 96 1 1 1 0 1 1 +OBJ_CANDLE1 2 OFILE_L1BRAZ 0 0 0 -1 -1 0 0 0 0 0 0 0 0 0 0 +OBJ_CANDLE2 3 OFILE_CANDLE2 0 0 0 1 -1 1 2 4 96 1 1 1 0 0 0 +OBJ_CANDLEO 2 OFILE_L1BRAZ 0 0 0 -1 -1 0 0 0 0 0 0 0 0 0 0 +OBJ_BANNERL 3 OFILE_BANNER 0 0 0 3 -1 0 2 0 96 1 1 1 0 0 0 +OBJ_BANNERM 3 OFILE_BANNER 0 0 0 3 -1 0 1 0 96 1 1 1 0 0 0 +OBJ_BANNERR 3 OFILE_BANNER 0 0 0 3 -1 0 3 0 96 1 1 1 0 0 0 +OBJ_SKPILE 2 OFILE_SKULPILE 1 4 0 -1 -1 0 0 1 96 1 1 1 0 0 0 +OBJ_SKSTICK1 2 OFILE_L1BRAZ 0 0 0 -1 -1 0 0 0 0 0 0 0 0 0 0 +OBJ_SKSTICK2 2 OFILE_L1BRAZ 0 0 0 -1 -1 0 0 0 0 0 0 0 0 0 0 +OBJ_SKSTICK3 2 OFILE_L1BRAZ 0 0 0 -1 -1 0 0 0 0 0 0 0 0 0 0 +OBJ_SKSTICK4 2 OFILE_L1BRAZ 0 0 0 -1 -1 0 0 0 0 0 0 0 0 0 0 +OBJ_SKSTICK5 2 OFILE_L1BRAZ 0 0 0 -1 -1 0 0 0 0 0 0 0 0 0 0 +OBJ_CRUX1 2 OFILE_CRUXSK1 0 0 0 -1 -1 0 1 15 96 1 0 1 1 3 0 +OBJ_CRUX2 2 OFILE_CRUXSK2 0 0 0 -1 -1 0 1 15 96 1 0 1 1 3 0 +OBJ_CRUX3 2 OFILE_CRUXSK3 0 0 0 -1 -1 0 1 15 96 1 0 1 1 3 0 +OBJ_STAND 1 OFILE_ROCKSTAN 5 5 0 -1 -1 0 1 0 96 1 1 1 0 0 0 +OBJ_ANGEL 2 OFILE_ANGEL 0 0 0 -1 -1 0 1 0 96 1 0 1 0 0 0 +OBJ_BOOK2L 2 OFILE_BOOK2 0 0 0 -1 -1 0 1 0 96 1 1 1 0 3 0 +OBJ_BCROSS 2 OFILE_BURNCROS 0 0 0 -1 -1 1 0 10 160 1 0 0 0 0 0 +OBJ_NUDEW2R 2 OFILE_NUDE2 0 0 0 -1 -1 1 3 6 128 1 0 1 0 0 0 +OBJ_SWITCHSKL 1 OFILE_SWITCH4 16 16 0 -1 -1 0 1 0 96 1 1 1 0 1 1 +OBJ_TNUDEM1 1 OFILE_TNUDEM 13 16 0 -1 6 0 1 0 128 1 0 1 0 0 0 +OBJ_TNUDEM2 1 OFILE_TNUDEM 13 16 0 6 6 0 2 0 128 1 0 1 0 0 0 +OBJ_TNUDEM3 1 OFILE_TNUDEM 13 16 0 6 6 0 3 0 128 1 0 1 0 0 0 +OBJ_TNUDEM4 1 OFILE_TNUDEM 13 16 0 6 6 0 4 0 128 1 0 1 0 0 0 +OBJ_TNUDEW1 1 OFILE_TNUDEW 13 16 0 6 6 0 1 0 128 1 0 1 0 0 0 +OBJ_TNUDEW2 1 OFILE_TNUDEW 13 16 0 6 6 0 2 0 128 1 0 1 0 0 0 +OBJ_TNUDEW3 1 OFILE_TNUDEW 13 16 0 6 6 0 3 0 128 1 0 1 0 0 0 +OBJ_TORTURE1 1 OFILE_TSOUL 13 16 0 -1 6 0 1 0 128 1 0 1 0 0 0 +OBJ_TORTURE2 1 OFILE_TSOUL 13 16 0 -1 6 0 2 0 128 1 0 1 0 0 0 +OBJ_TORTURE3 1 OFILE_TSOUL 13 16 0 -1 6 0 3 0 128 1 0 1 0 0 0 +OBJ_TORTURE4 1 OFILE_TSOUL 13 16 0 -1 6 0 4 0 128 1 0 1 0 0 0 +OBJ_TORTURE5 1 OFILE_TSOUL 13 16 0 -1 6 0 5 0 128 1 0 1 0 0 0 +OBJ_BOOK2R 1 OFILE_BOOK2 6 6 0 -1 -1 0 4 0 96 1 1 1 0 3 0 +OBJ_L2LDOOR 1 OFILE_L2DOORS 5 8 2 -1 -1 0 1 0 64 0 0 1 0 3 1 +OBJ_L2RDOOR 1 OFILE_L2DOORS 5 8 2 -1 -1 0 2 0 64 0 0 1 0 3 1 +OBJ_TORCHL 1 OFILE_WTORCH4 5 8 2 -1 -1 1 1 9 96 0 1 0 0 0 0 +OBJ_TORCHR 1 OFILE_WTORCH3 5 8 2 -1 -1 1 1 9 96 0 1 0 0 0 0 +OBJ_TORCHL2 1 OFILE_WTORCH1 5 8 2 -1 -1 1 1 9 96 0 1 0 0 0 0 +OBJ_TORCHR2 1 OFILE_WTORCH2 5 8 2 -1 -1 1 1 9 96 0 1 0 0 0 0 +OBJ_SARC 1 OFILE_SARC 1 4 1 -1 -1 0 1 5 128 1 1 1 0 3 1 +OBJ_FLAMEHOLE 2 OFILE_FLAME1 1 4 1 -1 -1 0 1 20 96 0 1 1 0 0 0 +OBJ_FLAMELVR 2 OFILE_LEVER 1 4 1 -1 -1 0 1 2 96 1 1 1 0 1 1 +OBJ_WATER 2 OFILE_MINIWATR 1 4 1 -1 -1 1 1 10 64 1 0 1 0 0 0 +OBJ_BOOKLVR 1 OFILE_BOOK1 3 4 1 -1 -1 0 1 0 96 1 1 1 0 3 0 +OBJ_TRAPL 1 OFILE_TRAPHOLE 1 16 0 -1 -1 0 1 0 64 0 1 1 0 0 0 +OBJ_TRAPR 1 OFILE_TRAPHOLE 1 16 0 -1 -1 0 2 0 64 0 1 1 0 0 0 +OBJ_BOOKSHELF 2 OFILE_BCASE 0 0 0 -1 -1 0 1 0 96 1 0 1 0 0 0 +OBJ_WEAPRACK 2 OFILE_WEAPSTND 0 0 0 -1 -1 0 1 0 96 1 0 1 0 0 0 +OBJ_BARREL 1 OFILE_BARREL 1 16 0 -1 -1 0 1 9 96 1 1 1 1 3 0 +OBJ_BARRELEX 1 OFILE_BARRELEX 1 16 0 -1 -1 0 1 10 96 1 1 1 1 3 0 +OBJ_SHRINEL 3 OFILE_LSHRINEG 0 0 0 1 -1 0 1 11 128 0 0 1 0 3 0 +OBJ_SHRINER 3 OFILE_RSHRINEG 0 0 0 1 -1 0 1 11 128 0 0 1 0 3 0 +OBJ_SKELBOOK 3 OFILE_BOOK2 0 0 0 3 -1 0 4 0 96 1 1 1 0 3 0 +OBJ_BOOKCASEL 3 OFILE_BCASE 0 0 0 5 -1 0 3 0 96 0 0 1 0 3 0 +OBJ_BOOKCASER 3 OFILE_BCASE 0 0 0 5 -1 0 4 0 96 0 0 1 0 3 0 +OBJ_BOOKSTAND 3 OFILE_BOOK2 0 0 0 5 -1 0 1 0 96 1 1 1 0 3 0 +OBJ_BOOKCANDLE 3 OFILE_CANDLE2 0 0 0 5 -1 1 2 4 96 1 1 1 0 0 0 +OBJ_BLOODFTN 3 OFILE_BLOODFNT 0 0 0 7 -1 1 2 10 96 1 1 1 0 3 0 +OBJ_DECAP 1 OFILE_DECAP 13 16 0 8 -1 0 1 0 96 1 1 1 0 1 0 +OBJ_TCHEST1 1 OFILE_CHEST1 1 16 0 -1 -1 0 1 0 96 1 1 1 0 1 1 +OBJ_TCHEST2 1 OFILE_CHEST2 1 16 0 -1 -1 0 1 0 96 1 1 1 0 1 1 +OBJ_TCHEST3 1 OFILE_CHEST3 1 16 0 -1 -1 0 1 0 96 1 1 1 0 1 1 +OBJ_BLINDBOOK 1 OFILE_BOOK1 7 7 2 -1 8 0 1 0 96 1 1 1 0 3 0 +OBJ_BLOODBOOK 1 OFILE_BOOK1 5 5 2 -1 9 0 4 0 96 1 1 1 0 3 0 +OBJ_PEDISTAL 1 OFILE_PEDISTL 5 5 2 -1 9 0 1 0 96 1 1 1 0 3 0 +OBJ_L3LDOOR 1 OFILE_L3DOORS 9 12 3 -1 -1 0 1 0 64 0 0 1 0 3 1 +OBJ_L3RDOOR 1 OFILE_L3DOORS 9 12 3 -1 -1 0 2 0 64 0 0 1 0 3 1 +OBJ_PURIFYINGFTN 3 OFILE_PFOUNTN 0 0 0 9 -1 1 2 10 128 1 1 1 0 3 0 +OBJ_ARMORSTAND 3 OFILE_ARMSTAND 0 0 0 10 -1 0 1 0 96 1 0 1 0 3 0 +OBJ_ARMORSTANDN 3 OFILE_ARMSTAND 0 0 0 10 -1 0 2 0 96 1 0 1 0 0 0 +OBJ_GOATSHRINE 3 OFILE_GOATSHRN 0 0 0 11 -1 1 2 10 96 1 1 1 0 3 0 +OBJ_CAULDRON 1 OFILE_CAULDREN 13 16 0 -1 -1 0 1 0 96 1 0 1 0 3 0 +OBJ_MURKYFTN 3 OFILE_MFOUNTN 0 0 0 13 -1 1 2 10 128 1 1 1 0 3 0 +OBJ_TEARFTN 3 OFILE_TFOUNTN 0 0 0 14 -1 1 2 4 128 1 1 1 0 3 0 +OBJ_ALTBOY 1 OFILE_ALTBOY 0 0 1 -1 15 0 1 0 128 1 1 1 0 0 0 +OBJ_MCIRCLE1 1 OFILE_MCIRL 0 0 1 -1 15 0 1 0 96 0 1 1 0 0 0 +OBJ_MCIRCLE2 1 OFILE_MCIRL 0 0 1 -1 15 0 1 0 96 0 1 1 0 0 0 +OBJ_STORYBOOK 1 OFILE_BKSLBRNT 4 12 0 -1 -1 0 1 0 96 1 1 1 0 3 0 +OBJ_STORYCANDLE 1 OFILE_CANDLE2 2 12 0 -1 15 1 2 4 96 1 1 1 0 0 0 +OBJ_STEELTOME 1 OFILE_BOOK1 13 13 4 -1 11 0 4 0 96 1 1 1 0 3 0 +OBJ_WARARMOR 1 OFILE_ARMSTAND 13 13 0 -1 11 0 1 0 96 1 0 1 0 3 0 +OBJ_WARWEAP 2 OFILE_WEAPSTND 13 13 0 -1 11 0 1 0 96 1 0 1 0 3 0 +OBJ_TBCROSS 2 OFILE_BURNCROS 0 0 0 15 -1 1 0 10 160 1 0 0 0 0 0 +OBJ_WEAPONRACK 2 OFILE_WEAPSTND 0 0 0 16 -1 0 1 0 96 1 0 1 0 3 0 +OBJ_WEAPONRACKN 2 OFILE_WEAPSTND 0 0 0 16 -1 0 2 0 96 1 0 1 0 0 0 +OBJ_MUSHPATCH 2 OFILE_MUSHPTCH 0 0 0 -1 1 0 1 0 96 1 1 1 0 3 1 +OBJ_LAZSTAND 2 OFILE_LZSTAND 0 0 0 -1 15 0 1 0 128 1 0 1 0 3 0 +OBJ_SLAINHERO 1 OFILE_DECAP 9 9 3 -1 -1 0 2 0 96 1 1 1 0 1 0 +OBJ_SIGNCHEST 2 OFILE_CHEST3 0 0 0 -1 -1 0 1 0 96 1 1 1 0 1 1 +-1 -1 0 0 0 -1 -1 -1 0 0 0 0 0 0 0 0 0 0 diff --git a/2020_03_31/Source/Data/Excel/xl_quest.txt b/2020_03_31/Source/Data/Excel/xl_quest.txt new file mode 100644 index 00000000..e2d517d5 --- /dev/null +++ b/2020_03_31/Source/Data/Excel/xl_quest.txt @@ -0,0 +1,17 @@ +_qdlvl(i) _qdmultlvl(i) _qlvlt(i) #_qdtype(i) _qdrnd(i) _qslvl(i) _qflags(i) _qdmsg(i) _qlstr(s) +5 -1 DTYPE_NONE Q_ROCK 100 0 0 TEXT_INFRA5 The Magic Rock +9 -1 DTYPE_NONE Q_MUSHROOM 100 0 0 TEXT_MUSH8 Black Mushroom +4 -1 DTYPE_NONE Q_GARBUD 100 0 0 TEXT_GARBUD1 Gharbad The Weak +8 -1 DTYPE_NONE Q_ZHAR 100 0 0 TEXT_ZHAR1 Zhar the Mad +14 -1 DTYPE_NONE Q_VEIL 100 0 0 TEXT_VEIL9 Lachdanan +15 -1 DTYPE_NONE Q_DIABLO 100 0 1 TEXT_VILE3 Diablo +2 2 DTYPE_NONE Q_BUTCHER 100 0 1 TEXT_BUTCH9 The Butcher +4 -1 DTYPE_NONE Q_LTBANNER 100 0 0 TEXT_BANNER2 Ogden's Sign +7 -1 DTYPE_NONE Q_BLIND 100 0 0 TEXT_BLINDING Halls of the Blind +5 -1 DTYPE_NONE Q_BLOOD 100 0 0 TEXT_BLOODY Valor +10 -1 DTYPE_NONE Q_ANVIL 100 0 0 TEXT_ANVIL5 Anvil of Fury +13 -1 DTYPE_NONE Q_WARLORD 100 0 0 TEXT_BLOODWAR Warlord of Blood +3 3 DTYPE_CATHEDRAL Q_SKELKING 100 SL_SKELKING 1 TEXT_KING2 The Curse of King Leoric +2 -1 DTYPE_CAVES Q_PWATER 100 SL_POISONWATER 0 TEXT_POISON3 Poisoned Water Supply +6 -1 DTYPE_CATACOMBS Q_SCHAMB 100 SL_BONECHAMB 0 TEXT_BONER The Chamber of Bone +15 15 DTYPE_CATHEDRAL Q_BETRAYER 100 SL_VILEBETRAYER 1 TEXT_VILE1 Archbishop Lazarus diff --git a/2020_03_31/Source/Data/Excel/xl_sfx.txt b/2020_03_31/Source/Data/Excel/xl_sfx.txt new file mode 100644 index 00000000..e9aa6842 --- /dev/null +++ b/2020_03_31/Source/Data/Excel/xl_sfx.txt @@ -0,0 +1,859 @@ +# bFlags(i) pszName(s) pSnd(p) +PS_WALK1 2 Sfx\\Misc\\Walk1.wav NULL +PS_WALK2 2 Sfx\\Misc\\Walk2.wav NULL +PS_WALK3 2 Sfx\\Misc\\Walk3.wav NULL +PS_WALK4 2 Sfx\\Misc\\Walk4.wav NULL +PS_BFIRE 2 Sfx\\Misc\\BFire.wav NULL +PS_FMAG 2 Sfx\\Misc\\Fmag.wav NULL +PS_TMAG 2 Sfx\\Misc\\Tmag.wav NULL +PS_LGHIT 2 Sfx\\Misc\\Lghit.wav NULL +PS_LGHIT1 2 Sfx\\Misc\\Lghit1.wav NULL +PS_SWING 2 Sfx\\Misc\\Swing.wav NULL +PS_SWING2 2 Sfx\\Misc\\Swing2.wav NULL +PS_DEAD 2 Sfx\\Misc\\Dead.wav NULL +IS_QUESTDN 1 Sfx\\Misc\\Questdon.wav NULL +IS_ARMRFKD 2 Sfx\\Items\\Armrfkd.wav NULL +IS_BARLFIRE 2 Sfx\\Items\\Barlfire.wav NULL +IS_BARREL 2 Sfx\\Items\\Barrel.wav NULL +IS_BHIT 2 Sfx\\Items\\Bhit.wav NULL +IS_BHIT1 2 Sfx\\Items\\Bhit1.wav NULL +IS_CHEST 2 Sfx\\Items\\Chest.wav NULL +IS_DOORCLOS 2 Sfx\\Items\\Doorclos.wav NULL +IS_DOOROPEN 2 Sfx\\Items\\Dooropen.wav NULL +IS_FANVL 2 Sfx\\Items\\Flipanvl.wav NULL +IS_FAXE 2 Sfx\\Items\\Flipaxe.wav NULL +IS_FBLST 2 Sfx\\Items\\Flipblst.wav NULL +IS_FBODY 2 Sfx\\Items\\Flipbody.wav NULL +IS_FBOOK 2 Sfx\\Items\\Flipbook.wav NULL +IS_FBOW 2 Sfx\\Items\\Flipbow.wav NULL +IS_FCAP 2 Sfx\\Items\\Flipcap.wav NULL +IS_FHARM 2 Sfx\\Items\\Flipharm.wav NULL +IS_FLARM 2 Sfx\\Items\\Fliplarm.wav NULL +IS_FMAG 2 Sfx\\Items\\Flipmag.wav NULL +IS_FMAG1 2 Sfx\\Items\\Flipmag1.wav NULL +IS_FMUSH 2 Sfx\\Items\\Flipmush.wav NULL +IS_FPOT 2 Sfx\\Items\\Flippot.wav NULL +IS_FRING 2 Sfx\\Items\\Flipring.wav NULL +IS_FROCK 2 Sfx\\Items\\Fliprock.wav NULL +IS_FSCRL 2 Sfx\\Items\\Flipscrl.wav NULL +IS_FSHLD 2 Sfx\\Items\\Flipshld.wav NULL +IS_FSIGN 2 Sfx\\Items\\Flipsign.wav NULL +IS_FSTAF 2 Sfx\\Items\\Flipstaf.wav NULL +IS_FSWOR 2 Sfx\\Items\\Flipswor.wav NULL +IS_GOLD 2 Sfx\\Items\\Gold.wav NULL +IS_HLMTFKD 2 Sfx\\Items\\Hlmtfkd.wav NULL +IS_IANVL 2 Sfx\\Items\\Invanvl.wav NULL +IS_IAXE 2 Sfx\\Items\\Invaxe.wav NULL +IS_IBLST 2 Sfx\\Items\\Invblst.wav NULL +IS_IBODY 2 Sfx\\Items\\Invbody.wav NULL +IS_IBOOK 2 Sfx\\Items\\Invbook.wav NULL +IS_IBOW 2 Sfx\\Items\\Invbow.wav NULL +IS_ICAP 2 Sfx\\Items\\Invcap.wav NULL +IS_IGRAB 2 Sfx\\Items\\Invgrab.wav NULL +IS_IHARM 2 Sfx\\Items\\Invharm.wav NULL +IS_ILARM 2 Sfx\\Items\\Invlarm.wav NULL +IS_IMUSH 2 Sfx\\Items\\Invmush.wav NULL +IS_IPOT 2 Sfx\\Items\\Invpot.wav NULL +IS_IRING 2 Sfx\\Items\\Invring.wav NULL +IS_IROCK 2 Sfx\\Items\\Invrock.wav NULL +IS_ISCROL 2 Sfx\\Items\\Invscrol.wav NULL +IS_ISHIEL 2 Sfx\\Items\\Invshiel.wav NULL +IS_ISIGN 2 Sfx\\Items\\Invsign.wav NULL +IS_ISTAF 2 Sfx\\Items\\Invstaf.wav NULL +IS_ISWORD 2 Sfx\\Items\\Invsword.wav NULL +IS_LEVER 2 Sfx\\Items\\Lever.wav NULL +IS_MAGIC 2 Sfx\\Items\\Magic.wav NULL +IS_MAGIC1 2 Sfx\\Items\\Magic1.wav NULL +IS_RBOOK 2 Sfx\\Items\\Readbook.wav NULL +IS_SARC 2 Sfx\\Items\\Sarc.wav NULL +IS_SHLDFKD 2 Sfx\\Items\\Shielfkd.wav NULL +IS_SWRDFKD 2 Sfx\\Items\\Swrdfkd.wav NULL +IS_TITLEMOV 4 Sfx\\Items\\Titlemov.wav NULL +IS_TITLSLCT 4 Sfx\\Items\\Titlslct.wav NULL +SFX_SILENCE 4 Sfx\\Misc\\blank.wav NULL +IS_TRAP 2 Sfx\\Items\\Trap.wav NULL +IS_CAST1 2 Sfx\\Misc\\Cast1.wav NULL +IS_CAST10 2 Sfx\\Misc\\Cast10.wav NULL +IS_CAST12 2 Sfx\\Misc\\Cast12.wav NULL +IS_CAST2 2 Sfx\\Misc\\Cast2.wav NULL +IS_CAST3 2 Sfx\\Misc\\Cast3.wav NULL +IS_CAST4 2 Sfx\\Misc\\Cast4.wav NULL +IS_CAST5 2 Sfx\\Misc\\Cast5.wav NULL +IS_CAST6 2 Sfx\\Misc\\Cast6.wav NULL +IS_CAST7 2 Sfx\\Misc\\Cast7.wav NULL +IS_CAST8 2 Sfx\\Misc\\Cast8.wav NULL +IS_CAST9 2 Sfx\\Misc\\Cast9.wav NULL +LS_HEALING 2 Sfx\\Misc\\Healing.wav NULL +IS_REPAIR 2 Sfx\\Misc\\Repair.wav NULL +LS_ACID 2 Sfx\\Misc\\Acids1.wav NULL +LS_ACIDS 2 Sfx\\Misc\\Acids2.wav NULL +LS_APOC 2 Sfx\\Misc\\Apoc.wav NULL +LS_ARROWALL 2 Sfx\\Misc\\Arrowall.wav NULL +LS_BLODBOIL 2 Sfx\\Misc\\Bldboil.wav NULL +LS_BLODSTAR 2 Sfx\\Misc\\Blodstar.wav NULL +LS_BLSIMPT 2 Sfx\\Misc\\Blsimpt.wav NULL +LS_BONESP 2 Sfx\\Misc\\Bonesp.wav NULL +LS_BSIMPCT 2 Sfx\\Misc\\Bsimpct.wav NULL +LS_CALDRON 2 Sfx\\Misc\\Caldron.wav NULL +LS_CBOLT 2 Sfx\\Misc\\Cbolt.wav NULL +LS_CHLTNING 2 Sfx\\Misc\\Chltning.wav NULL +LS_DSERP 2 Sfx\\Misc\\DSerp.wav NULL +LS_ELECIMP1 2 Sfx\\Misc\\Elecimp1.wav NULL +LS_ELEMENTL 2 Sfx\\Misc\\Elementl.wav NULL +LS_ETHEREAL 2 Sfx\\Misc\\Ethereal.wav NULL +LS_FBALL 2 Sfx\\Misc\\Fball.wav NULL +LS_FBOLT1 2 Sfx\\Misc\\Fbolt1.wav NULL +LS_FBOLT2 2 Sfx\\Misc\\Fbolt2.wav NULL +LS_FIRIMP1 2 Sfx\\Misc\\Firimp1.wav NULL +LS_FIRIMP2 2 Sfx\\Misc\\Firimp2.wav NULL +LS_FLAMWAVE 2 Sfx\\Misc\\Flamwave.wav NULL +LS_FLASH 2 Sfx\\Misc\\Flash.wav NULL +LS_FOUNTAIN 2 Sfx\\Misc\\Fountain.wav NULL +LS_GOLUM 2 Sfx\\Misc\\Golum.wav NULL +LS_GOLUMDED 2 Sfx\\Misc\\Golumded.wav NULL +LS_GSHRINE 2 Sfx\\Misc\\Gshrine.wav NULL +LS_GUARD 2 Sfx\\Misc\\Guard.wav NULL +LS_GUARDLAN 2 Sfx\\Misc\\Grdlanch.wav NULL +LS_HOLYBOLT 2 Sfx\\Misc\\Holybolt.wav NULL +LS_HYPER 2 Sfx\\Misc\\Hyper.wav NULL +LS_INFRAVIS 2 Sfx\\Misc\\Infravis.wav NULL +LS_INVISIBL 2 Sfx\\Misc\\Invisibl.wav NULL +LS_INVPOT 2 Sfx\\Misc\\Invpot.wav NULL +LS_LNING1 2 Sfx\\Misc\\Lning1.wav NULL +LS_LTNING 2 Sfx\\Misc\\Ltning.wav NULL +LS_MSHIELD 2 Sfx\\Misc\\Mshield.wav NULL +LS_NOVA 2 Sfx\\Misc\\Nova.wav NULL +LS_PORTAL 2 Sfx\\Misc\\Portal.wav NULL +LS_PUDDLE 2 Sfx\\Misc\\Puddle.wav NULL +LS_RESUR 2 Sfx\\Misc\\Resur.wav NULL +LS_SCURSE 2 Sfx\\Misc\\Scurse.wav NULL +LS_SCURIMP 2 Sfx\\Misc\\Scurimp.wav NULL +LS_SENTINEL 2 Sfx\\Misc\\Sentinel.wav NULL +LS_SHATTER 2 Sfx\\Misc\\Shatter.wav NULL +LS_SOULFIRE 2 Sfx\\Misc\\Soulfire.wav NULL +LS_SPOUTLOP 2 Sfx\\Misc\\Spoutlop.wav NULL +LS_SPOUTSTR 2 Sfx\\Misc\\Spoutstr.wav NULL +LS_STORM 2 Sfx\\Misc\\Storm.wav NULL +LS_TRAPDIS 2 Sfx\\Misc\\Trapdis.wav NULL +LS_TELEPORT 2 Sfx\\Misc\\Teleport.wav NULL +LS_VTHEFT 2 Sfx\\Misc\\Vtheft.wav NULL +LS_WALLLOOP 2 Sfx\\Misc\\Wallloop.wav NULL +LS_WALLSTRT 2 Sfx\\Misc\\Wallstrt.wav NULL +TSFX_BMAID1 1 Sfx\\Towners\\Bmaid01.wav NULL +TSFX_BMAID2 1 Sfx\\Towners\\Bmaid02.wav NULL +TSFX_BMAID3 1 Sfx\\Towners\\Bmaid03.wav NULL +TSFX_BMAID4 1 Sfx\\Towners\\Bmaid04.wav NULL +TSFX_BMAID5 1 Sfx\\Towners\\Bmaid05.wav NULL +TSFX_BMAID6 1 Sfx\\Towners\\Bmaid06.wav NULL +TSFX_BMAID7 1 Sfx\\Towners\\Bmaid07.wav NULL +TSFX_BMAID8 1 Sfx\\Towners\\Bmaid08.wav NULL +TSFX_BMAID9 1 Sfx\\Towners\\Bmaid09.wav NULL +TSFX_BMAID10 1 Sfx\\Towners\\Bmaid10.wav NULL +TSFX_BMAID11 1 Sfx\\Towners\\Bmaid11.wav NULL +TSFX_BMAID12 1 Sfx\\Towners\\Bmaid12.wav NULL +TSFX_BMAID13 1 Sfx\\Towners\\Bmaid13.wav NULL +TSFX_BMAID14 1 Sfx\\Towners\\Bmaid14.wav NULL +TSFX_BMAID15 1 Sfx\\Towners\\Bmaid15.wav NULL +TSFX_BMAID16 1 Sfx\\Towners\\Bmaid16.wav NULL +TSFX_BMAID17 1 Sfx\\Towners\\Bmaid17.wav NULL +TSFX_BMAID18 1 Sfx\\Towners\\Bmaid18.wav NULL +TSFX_BMAID19 1 Sfx\\Towners\\Bmaid19.wav NULL +TSFX_BMAID20 1 Sfx\\Towners\\Bmaid20.wav NULL +TSFX_BMAID21 1 Sfx\\Towners\\Bmaid21.wav NULL +TSFX_BMAID22 1 Sfx\\Towners\\Bmaid22.wav NULL +TSFX_BMAID23 1 Sfx\\Towners\\Bmaid23.wav NULL +TSFX_BMAID24 1 Sfx\\Towners\\Bmaid24.wav NULL +TSFX_BMAID25 1 Sfx\\Towners\\Bmaid25.wav NULL +TSFX_BMAID26 1 Sfx\\Towners\\Bmaid26.wav NULL +TSFX_BMAID27 1 Sfx\\Towners\\Bmaid27.wav NULL +TSFX_BMAID28 1 Sfx\\Towners\\Bmaid28.wav NULL +TSFX_BMAID29 1 Sfx\\Towners\\Bmaid29.wav NULL +TSFX_BMAID30 1 Sfx\\Towners\\Bmaid30.wav NULL +TSFX_BMAID31 1 Sfx\\Towners\\Bmaid31.wav NULL +TSFX_BMAID32 1 Sfx\\Towners\\Bmaid32.wav NULL +TSFX_BMAID33 1 Sfx\\Towners\\Bmaid33.wav NULL +TSFX_BMAID34 1 Sfx\\Towners\\Bmaid34.wav NULL +TSFX_BMAID35 1 Sfx\\Towners\\Bmaid35.wav NULL +TSFX_BMAID36 1 Sfx\\Towners\\Bmaid36.wav NULL +TSFX_BMAID37 1 Sfx\\Towners\\Bmaid37.wav NULL +TSFX_BMAID38 1 Sfx\\Towners\\Bmaid38.wav NULL +TSFX_BMAID39 1 Sfx\\Towners\\Bmaid39.wav NULL +TSFX_BMAID40 1 Sfx\\Towners\\Bmaid40.wav NULL +TSFX_SMITH1 1 Sfx\\Towners\\Bsmith01.wav NULL +TSFX_SMITH2 1 Sfx\\Towners\\Bsmith02.wav NULL +TSFX_SMITH3 1 Sfx\\Towners\\Bsmith03.wav NULL +TSFX_SMITH4 1 Sfx\\Towners\\Bsmith04.wav NULL +TSFX_SMITH5 1 Sfx\\Towners\\Bsmith05.wav NULL +TSFX_SMITH6 1 Sfx\\Towners\\Bsmith06.wav NULL +TSFX_SMITH7 1 Sfx\\Towners\\Bsmith07.wav NULL +TSFX_SMITH8 1 Sfx\\Towners\\Bsmith08.wav NULL +TSFX_SMITH9 1 Sfx\\Towners\\Bsmith09.wav NULL +TSFX_SMITH10 1 Sfx\\Towners\\Bsmith10.wav NULL +TSFX_SMITH11 1 Sfx\\Towners\\Bsmith11.wav NULL +TSFX_SMITH12 1 Sfx\\Towners\\Bsmith12.wav NULL +TSFX_SMITH13 1 Sfx\\Towners\\Bsmith13.wav NULL +TSFX_SMITH14 1 Sfx\\Towners\\Bsmith14.wav NULL +TSFX_SMITH15 1 Sfx\\Towners\\Bsmith15.wav NULL +TSFX_SMITH16 1 Sfx\\Towners\\Bsmith16.wav NULL +TSFX_SMITH17 1 Sfx\\Towners\\Bsmith17.wav NULL +TSFX_SMITH18 1 Sfx\\Towners\\Bsmith18.wav NULL +TSFX_SMITH19 1 Sfx\\Towners\\Bsmith19.wav NULL +TSFX_SMITH20 1 Sfx\\Towners\\Bsmith20.wav NULL +TSFX_SMITH21 1 Sfx\\Towners\\Bsmith21.wav NULL +TSFX_SMITH22 1 Sfx\\Towners\\Bsmith22.wav NULL +TSFX_SMITH23 1 Sfx\\Towners\\Bsmith23.wav NULL +TSFX_SMITH24 1 Sfx\\Towners\\Bsmith24.wav NULL +TSFX_SMITH25 1 Sfx\\Towners\\Bsmith25.wav NULL +TSFX_SMITH26 1 Sfx\\Towners\\Bsmith26.wav NULL +TSFX_SMITH27 1 Sfx\\Towners\\Bsmith27.wav NULL +TSFX_SMITH28 1 Sfx\\Towners\\Bsmith28.wav NULL +TSFX_SMITH29 1 Sfx\\Towners\\Bsmith29.wav NULL +TSFX_SMITH30 1 Sfx\\Towners\\Bsmith30.wav NULL +TSFX_SMITH31 1 Sfx\\Towners\\Bsmith31.wav NULL +TSFX_SMITH32 1 Sfx\\Towners\\Bsmith32.wav NULL +TSFX_SMITH33 1 Sfx\\Towners\\Bsmith33.wav NULL +TSFX_SMITH34 1 Sfx\\Towners\\Bsmith34.wav NULL +TSFX_SMITH35 1 Sfx\\Towners\\Bsmith35.wav NULL +TSFX_SMITH36 1 Sfx\\Towners\\Bsmith36.wav NULL +TSFX_SMITH37 1 Sfx\\Towners\\Bsmith37.wav NULL +TSFX_SMITH38 1 Sfx\\Towners\\Bsmith38.wav NULL +TSFX_SMITH39 1 Sfx\\Towners\\Bsmith39.wav NULL +TSFX_SMITH40 1 Sfx\\Towners\\Bsmith40.wav NULL +TSFX_SMITH41 1 Sfx\\Towners\\Bsmith41.wav NULL +TSFX_SMITH42 1 Sfx\\Towners\\Bsmith42.wav NULL +TSFX_SMITH43 1 Sfx\\Towners\\Bsmith43.wav NULL +TSFX_SMITH44 1 Sfx\\Towners\\Bsmith44.wav NULL +TSFX_SMITH45 1 Sfx\\Towners\\Bsmith45.wav NULL +TSFX_SMITH46 1 Sfx\\Towners\\Bsmith46.wav NULL +TSFX_SMITH47 1 Sfx\\Towners\\Bsmith47.wav NULL +TSFX_SMITH48 1 Sfx\\Towners\\Bsmith48.wav NULL +TSFX_SMITH49 1 Sfx\\Towners\\Bsmith49.wav NULL +TSFX_SMITH50 1 Sfx\\Towners\\Bsmith50.wav NULL +TSFX_SMITH51 1 Sfx\\Towners\\Bsmith51.wav NULL +TSFX_SMITH52 1 Sfx\\Towners\\Bsmith52.wav NULL +TSFX_SMITH53 1 Sfx\\Towners\\Bsmith53.wav NULL +TSFX_SMITH54 1 Sfx\\Towners\\Bsmith54.wav NULL +TSFX_SMITH55 1 Sfx\\Towners\\Bsmith55.wav NULL +TSFX_SMITH56 1 Sfx\\Towners\\Bsmith56.wav NULL +TSFX_COW1 0 Sfx\\Towners\\Cow1.wav NULL +TSFX_COW2 0 Sfx\\Towners\\Cow2.wav NULL +TSFX_DEADGUY 1 Sfx\\Towners\\Deadguy2.wav NULL +TSFX_DRUNK1 1 Sfx\\Towners\\Drunk01.wav NULL +TSFX_DRUNK2 1 Sfx\\Towners\\Drunk02.wav NULL +TSFX_DRUNK3 1 Sfx\\Towners\\Drunk03.wav NULL +TSFX_DRUNK4 1 Sfx\\Towners\\Drunk04.wav NULL +TSFX_DRUNK5 1 Sfx\\Towners\\Drunk05.wav NULL +TSFX_DRUNK6 1 Sfx\\Towners\\Drunk06.wav NULL +TSFX_DRUNK7 1 Sfx\\Towners\\Drunk07.wav NULL +TSFX_DRUNK8 1 Sfx\\Towners\\Drunk08.wav NULL +TSFX_DRUNK9 1 Sfx\\Towners\\Drunk09.wav NULL +TSFX_DRUNK10 1 Sfx\\Towners\\Drunk10.wav NULL +TSFX_DRUNK11 1 Sfx\\Towners\\Drunk11.wav NULL +TSFX_DRUNK12 1 Sfx\\Towners\\Drunk12.wav NULL +TSFX_DRUNK13 1 Sfx\\Towners\\Drunk13.wav NULL +TSFX_DRUNK14 1 Sfx\\Towners\\Drunk14.wav NULL +TSFX_DRUNK15 1 Sfx\\Towners\\Drunk15.wav NULL +TSFX_DRUNK16 1 Sfx\\Towners\\Drunk16.wav NULL +TSFX_DRUNK17 1 Sfx\\Towners\\Drunk17.wav NULL +TSFX_DRUNK18 1 Sfx\\Towners\\Drunk18.wav NULL +TSFX_DRUNK19 1 Sfx\\Towners\\Drunk19.wav NULL +TSFX_DRUNK20 1 Sfx\\Towners\\Drunk20.wav NULL +TSFX_DRUNK21 1 Sfx\\Towners\\Drunk21.wav NULL +TSFX_DRUNK22 1 Sfx\\Towners\\Drunk22.wav NULL +TSFX_DRUNK23 1 Sfx\\Towners\\Drunk23.wav NULL +TSFX_DRUNK24 1 Sfx\\Towners\\Drunk24.wav NULL +TSFX_DRUNK25 1 Sfx\\Towners\\Drunk25.wav NULL +TSFX_DRUNK26 1 Sfx\\Towners\\Drunk26.wav NULL +TSFX_DRUNK27 1 Sfx\\Towners\\Drunk27.wav NULL +TSFX_DRUNK28 1 Sfx\\Towners\\Drunk28.wav NULL +TSFX_DRUNK29 1 Sfx\\Towners\\Drunk29.wav NULL +TSFX_DRUNK30 1 Sfx\\Towners\\Drunk30.wav NULL +TSFX_DRUNK31 1 Sfx\\Towners\\Drunk31.wav NULL +TSFX_DRUNK32 1 Sfx\\Towners\\Drunk32.wav NULL +TSFX_DRUNK33 1 Sfx\\Towners\\Drunk33.wav NULL +TSFX_DRUNK34 1 Sfx\\Towners\\Drunk34.wav NULL +TSFX_DRUNK35 1 Sfx\\Towners\\Drunk35.wav NULL +TSFX_HEALER1 1 Sfx\\Towners\\Healer01.wav NULL +TSFX_HEALER2 1 Sfx\\Towners\\Healer02.wav NULL +TSFX_HEALER3 1 Sfx\\Towners\\Healer03.wav NULL +TSFX_HEALER4 1 Sfx\\Towners\\Healer04.wav NULL +TSFX_HEALER5 1 Sfx\\Towners\\Healer05.wav NULL +TSFX_HEALER6 1 Sfx\\Towners\\Healer06.wav NULL +TSFX_HEALER7 1 Sfx\\Towners\\Healer07.wav NULL +TSFX_HEALER8 1 Sfx\\Towners\\Healer08.wav NULL +TSFX_HEALER9 1 Sfx\\Towners\\Healer09.wav NULL +TSFX_HEALER10 1 Sfx\\Towners\\Healer10.wav NULL +TSFX_HEALER11 1 Sfx\\Towners\\Healer11.wav NULL +TSFX_HEALER12 1 Sfx\\Towners\\Healer12.wav NULL +TSFX_HEALER13 1 Sfx\\Towners\\Healer13.wav NULL +TSFX_HEALER14 1 Sfx\\Towners\\Healer14.wav NULL +TSFX_HEALER15 1 Sfx\\Towners\\Healer15.wav NULL +TSFX_HEALER16 1 Sfx\\Towners\\Healer16.wav NULL +TSFX_HEALER17 1 Sfx\\Towners\\Healer17.wav NULL +TSFX_HEALER18 1 Sfx\\Towners\\Healer18.wav NULL +TSFX_HEALER19 1 Sfx\\Towners\\Healer19.wav NULL +TSFX_HEALER20 1 Sfx\\Towners\\Healer20.wav NULL +TSFX_HEALER21 1 Sfx\\Towners\\Healer21.wav NULL +TSFX_HEALER22 1 Sfx\\Towners\\Healer22.wav NULL +TSFX_HEALER23 1 Sfx\\Towners\\Healer23.wav NULL +TSFX_HEALER24 1 Sfx\\Towners\\Healer24.wav NULL +TSFX_HEALER25 1 Sfx\\Towners\\Healer25.wav NULL +TSFX_HEALER26 1 Sfx\\Towners\\Healer26.wav NULL +TSFX_HEALER27 1 Sfx\\Towners\\Healer27.wav NULL +TSFX_HEALER28 1 Sfx\\Towners\\Healer28.wav NULL +TSFX_HEALER29 1 Sfx\\Towners\\Healer29.wav NULL +TSFX_HEALER30 1 Sfx\\Towners\\Healer30.wav NULL +TSFX_HEALER31 1 Sfx\\Towners\\Healer31.wav NULL +TSFX_HEALER32 1 Sfx\\Towners\\Healer32.wav NULL +TSFX_HEALER33 1 Sfx\\Towners\\Healer33.wav NULL +TSFX_HEALER34 1 Sfx\\Towners\\Healer34.wav NULL +TSFX_HEALER35 1 Sfx\\Towners\\Healer35.wav NULL +TSFX_HEALER36 1 Sfx\\Towners\\Healer36.wav NULL +TSFX_HEALER37 1 Sfx\\Towners\\Healer37.wav NULL +TSFX_HEALER38 1 Sfx\\Towners\\Healer38.wav NULL +TSFX_HEALER39 1 Sfx\\Towners\\Healer39.wav NULL +TSFX_HEALER40 1 Sfx\\Towners\\Healer40.wav NULL +TSFX_HEALER41 1 Sfx\\Towners\\Healer41.wav NULL +TSFX_HEALER42 1 Sfx\\Towners\\Healer42.wav NULL +TSFX_HEALER43 1 Sfx\\Towners\\Healer43.wav NULL +TSFX_HEALER44 1 Sfx\\Towners\\Healer44.wav NULL +TSFX_HEALER45 1 Sfx\\Towners\\Healer45.wav NULL +TSFX_HEALER46 1 Sfx\\Towners\\Healer46.wav NULL +TSFX_HEALER47 1 Sfx\\Towners\\Healer47.wav NULL +TSFX_PEGBOY1 1 Sfx\\Towners\\Pegboy01.wav NULL +TSFX_PEGBOY2 1 Sfx\\Towners\\Pegboy02.wav NULL +TSFX_PEGBOY3 1 Sfx\\Towners\\Pegboy03.wav NULL +TSFX_PEGBOY4 1 Sfx\\Towners\\Pegboy04.wav NULL +TSFX_PEGBOY5 1 Sfx\\Towners\\Pegboy05.wav NULL +TSFX_PEGBOY6 1 Sfx\\Towners\\Pegboy06.wav NULL +TSFX_PEGBOY7 1 Sfx\\Towners\\Pegboy07.wav NULL +TSFX_PEGBOY8 1 Sfx\\Towners\\Pegboy08.wav NULL +TSFX_PEGBOY9 1 Sfx\\Towners\\Pegboy09.wav NULL +TSFX_PEGBOY10 1 Sfx\\Towners\\Pegboy10.wav NULL +TSFX_PEGBOY11 1 Sfx\\Towners\\Pegboy11.wav NULL +TSFX_PEGBOY12 1 Sfx\\Towners\\Pegboy12.wav NULL +TSFX_PEGBOY13 1 Sfx\\Towners\\Pegboy13.wav NULL +TSFX_PEGBOY14 1 Sfx\\Towners\\Pegboy14.wav NULL +TSFX_PEGBOY15 1 Sfx\\Towners\\Pegboy15.wav NULL +TSFX_PEGBOY16 1 Sfx\\Towners\\Pegboy16.wav NULL +TSFX_PEGBOY17 1 Sfx\\Towners\\Pegboy17.wav NULL +TSFX_PEGBOY18 1 Sfx\\Towners\\Pegboy18.wav NULL +TSFX_PEGBOY19 1 Sfx\\Towners\\Pegboy19.wav NULL +TSFX_PEGBOY20 1 Sfx\\Towners\\Pegboy20.wav NULL +TSFX_PEGBOY21 1 Sfx\\Towners\\Pegboy21.wav NULL +TSFX_PEGBOY22 1 Sfx\\Towners\\Pegboy22.wav NULL +TSFX_PEGBOY23 1 Sfx\\Towners\\Pegboy23.wav NULL +TSFX_PEGBOY24 1 Sfx\\Towners\\Pegboy24.wav NULL +TSFX_PEGBOY25 1 Sfx\\Towners\\Pegboy25.wav NULL +TSFX_PEGBOY26 1 Sfx\\Towners\\Pegboy26.wav NULL +TSFX_PEGBOY27 1 Sfx\\Towners\\Pegboy27.wav NULL +TSFX_PEGBOY28 1 Sfx\\Towners\\Pegboy28.wav NULL +TSFX_PEGBOY29 1 Sfx\\Towners\\Pegboy29.wav NULL +TSFX_PEGBOY30 1 Sfx\\Towners\\Pegboy30.wav NULL +TSFX_PEGBOY31 1 Sfx\\Towners\\Pegboy31.wav NULL +TSFX_PEGBOY32 1 Sfx\\Towners\\Pegboy32.wav NULL +TSFX_PEGBOY33 1 Sfx\\Towners\\Pegboy33.wav NULL +TSFX_PEGBOY34 1 Sfx\\Towners\\Pegboy34.wav NULL +TSFX_PEGBOY35 1 Sfx\\Towners\\Pegboy35.wav NULL +TSFX_PEGBOY36 1 Sfx\\Towners\\Pegboy36.wav NULL +TSFX_PEGBOY37 1 Sfx\\Towners\\Pegboy37.wav NULL +TSFX_PEGBOY38 1 Sfx\\Towners\\Pegboy38.wav NULL +TSFX_PEGBOY39 1 Sfx\\Towners\\Pegboy39.wav NULL +TSFX_PEGBOY40 1 Sfx\\Towners\\Pegboy40.wav NULL +TSFX_PEGBOY41 1 Sfx\\Towners\\Pegboy41.wav NULL +TSFX_PEGBOY42 1 Sfx\\Towners\\Pegboy42.wav NULL +TSFX_PEGBOY43 1 Sfx\\Towners\\Pegboy43.wav NULL +TSFX_PRIEST0 1 Sfx\\Towners\\Priest00.wav NULL +TSFX_PRIEST1 1 Sfx\\Towners\\Priest01.wav NULL +TSFX_PRIEST2 1 Sfx\\Towners\\Priest02.wav NULL +TSFX_PRIEST3 1 Sfx\\Towners\\Priest03.wav NULL +TSFX_PRIEST4 1 Sfx\\Towners\\Priest04.wav NULL +TSFX_PRIEST5 1 Sfx\\Towners\\Priest05.wav NULL +TSFX_PRIEST6 1 Sfx\\Towners\\Priest06.wav NULL +TSFX_PRIEST7 1 Sfx\\Towners\\Priest07.wav NULL +TSFX_STORY0 1 Sfx\\Towners\\Storyt00.wav NULL +TSFX_STORY1 1 Sfx\\Towners\\Storyt01.wav NULL +TSFX_STORY2 1 Sfx\\Towners\\Storyt02.wav NULL +TSFX_STORY3 1 Sfx\\Towners\\Storyt03.wav NULL +TSFX_STORY4 1 Sfx\\Towners\\Storyt04.wav NULL +TSFX_STORY5 1 Sfx\\Towners\\Storyt05.wav NULL +TSFX_STORY6 1 Sfx\\Towners\\Storyt06.wav NULL +TSFX_STORY7 1 Sfx\\Towners\\Storyt07.wav NULL +TSFX_STORY8 1 Sfx\\Towners\\Storyt08.wav NULL +TSFX_STORY9 1 Sfx\\Towners\\Storyt09.wav NULL +TSFX_STORY10 1 Sfx\\Towners\\Storyt10.wav NULL +TSFX_STORY11 1 Sfx\\Towners\\Storyt11.wav NULL +TSFX_STORY12 1 Sfx\\Towners\\Storyt12.wav NULL +TSFX_STORY13 1 Sfx\\Towners\\Storyt13.wav NULL +TSFX_STORY14 1 Sfx\\Towners\\Storyt14.wav NULL +TSFX_STORY15 1 Sfx\\Towners\\Storyt15.wav NULL +TSFX_STORY16 1 Sfx\\Towners\\Storyt16.wav NULL +TSFX_STORY17 1 Sfx\\Towners\\Storyt17.wav NULL +TSFX_STORY18 1 Sfx\\Towners\\Storyt18.wav NULL +TSFX_STORY19 1 Sfx\\Towners\\Storyt19.wav NULL +TSFX_STORY20 1 Sfx\\Towners\\Storyt20.wav NULL +TSFX_STORY21 1 Sfx\\Towners\\Storyt21.wav NULL +TSFX_STORY22 1 Sfx\\Towners\\Storyt22.wav NULL +TSFX_STORY23 1 Sfx\\Towners\\Storyt23.wav NULL +TSFX_STORY24 1 Sfx\\Towners\\Storyt24.wav NULL +TSFX_STORY25 1 Sfx\\Towners\\Storyt25.wav NULL +TSFX_STORY26 1 Sfx\\Towners\\Storyt26.wav NULL +TSFX_STORY27 1 Sfx\\Towners\\Storyt27.wav NULL +TSFX_STORY28 1 Sfx\\Towners\\Storyt28.wav NULL +TSFX_STORY29 1 Sfx\\Towners\\Storyt29.wav NULL +TSFX_STORY30 1 Sfx\\Towners\\Storyt30.wav NULL +TSFX_STORY31 1 Sfx\\Towners\\Storyt31.wav NULL +TSFX_STORY32 1 Sfx\\Towners\\Storyt32.wav NULL +TSFX_STORY33 1 Sfx\\Towners\\Storyt33.wav NULL +TSFX_STORY34 1 Sfx\\Towners\\Storyt34.wav NULL +TSFX_STORY35 1 Sfx\\Towners\\Storyt35.wav NULL +TSFX_STORY36 1 Sfx\\Towners\\Storyt36.wav NULL +TSFX_STORY37 1 Sfx\\Towners\\Storyt37.wav NULL +TSFX_STORY38 1 Sfx\\Towners\\Storyt38.wav NULL +TSFX_TAVERN0 1 Sfx\\Towners\\Tavown00.wav NULL +TSFX_TAVERN1 1 Sfx\\Towners\\Tavown01.wav NULL +TSFX_TAVERN2 1 Sfx\\Towners\\Tavown02.wav NULL +TSFX_TAVERN3 1 Sfx\\Towners\\Tavown03.wav NULL +TSFX_TAVERN4 1 Sfx\\Towners\\Tavown04.wav NULL +TSFX_TAVERN5 1 Sfx\\Towners\\Tavown05.wav NULL +TSFX_TAVERN6 1 Sfx\\Towners\\Tavown06.wav NULL +TSFX_TAVERN7 1 Sfx\\Towners\\Tavown07.wav NULL +TSFX_TAVERN8 1 Sfx\\Towners\\Tavown08.wav NULL +TSFX_TAVERN9 1 Sfx\\Towners\\Tavown09.wav NULL +TSFX_TAVERN10 1 Sfx\\Towners\\Tavown10.wav NULL +TSFX_TAVERN11 1 Sfx\\Towners\\Tavown11.wav NULL +TSFX_TAVERN12 1 Sfx\\Towners\\Tavown12.wav NULL +TSFX_TAVERN13 1 Sfx\\Towners\\Tavown13.wav NULL +TSFX_TAVERN14 1 Sfx\\Towners\\Tavown14.wav NULL +TSFX_TAVERN15 1 Sfx\\Towners\\Tavown15.wav NULL +TSFX_TAVERN16 1 Sfx\\Towners\\Tavown16.wav NULL +TSFX_TAVERN17 1 Sfx\\Towners\\Tavown17.wav NULL +TSFX_TAVERN18 1 Sfx\\Towners\\Tavown18.wav NULL +TSFX_TAVERN19 1 Sfx\\Towners\\Tavown19.wav NULL +TSFX_TAVERN20 1 Sfx\\Towners\\Tavown20.wav NULL +TSFX_TAVERN21 1 Sfx\\Towners\\Tavown21.wav NULL +TSFX_TAVERN22 1 Sfx\\Towners\\Tavown22.wav NULL +TSFX_TAVERN23 1 Sfx\\Towners\\Tavown23.wav NULL +TSFX_TAVERN24 1 Sfx\\Towners\\Tavown24.wav NULL +TSFX_TAVERN25 1 Sfx\\Towners\\Tavown25.wav NULL +TSFX_TAVERN26 1 Sfx\\Towners\\Tavown26.wav NULL +TSFX_TAVERN27 1 Sfx\\Towners\\Tavown27.wav NULL +TSFX_TAVERN28 1 Sfx\\Towners\\Tavown28.wav NULL +TSFX_TAVERN29 1 Sfx\\Towners\\Tavown29.wav NULL +TSFX_TAVERN30 1 Sfx\\Towners\\Tavown30.wav NULL +TSFX_TAVERN31 1 Sfx\\Towners\\Tavown31.wav NULL +TSFX_TAVERN32 1 Sfx\\Towners\\Tavown32.wav NULL +TSFX_TAVERN33 1 Sfx\\Towners\\Tavown33.wav NULL +TSFX_TAVERN34 1 Sfx\\Towners\\Tavown34.wav NULL +TSFX_TAVERN35 1 Sfx\\Towners\\Tavown35.wav NULL +TSFX_TAVERN36 1 Sfx\\Towners\\Tavown36.wav NULL +TSFX_TAVERN37 1 Sfx\\Towners\\Tavown37.wav NULL +TSFX_TAVERN38 1 Sfx\\Towners\\Tavown38.wav NULL +TSFX_TAVERN39 1 Sfx\\Towners\\Tavown39.wav NULL +TSFX_TAVERN40 1 Sfx\\Towners\\Tavown40.wav NULL +TSFX_TAVERN41 1 Sfx\\Towners\\Tavown41.wav NULL +TSFX_TAVERN42 1 Sfx\\Towners\\Tavown42.wav NULL +TSFX_TAVERN43 1 Sfx\\Towners\\Tavown43.wav NULL +TSFX_TAVERN44 1 Sfx\\Towners\\Tavown44.wav NULL +TSFX_TAVERN45 1 Sfx\\Towners\\Tavown45.wav NULL +TSFX_WITCH1 1 Sfx\\Towners\\Witch01.wav NULL +TSFX_WITCH2 1 Sfx\\Towners\\Witch02.wav NULL +TSFX_WITCH3 1 Sfx\\Towners\\Witch03.wav NULL +TSFX_WITCH4 1 Sfx\\Towners\\Witch04.wav NULL +TSFX_WITCH5 1 Sfx\\Towners\\Witch05.wav NULL +TSFX_WITCH6 1 Sfx\\Towners\\Witch06.wav NULL +TSFX_WITCH7 1 Sfx\\Towners\\Witch07.wav NULL +TSFX_WITCH8 1 Sfx\\Towners\\Witch08.wav NULL +TSFX_WITCH9 1 Sfx\\Towners\\Witch09.wav NULL +TSFX_WITCH10 1 Sfx\\Towners\\Witch10.wav NULL +TSFX_WITCH11 1 Sfx\\Towners\\Witch11.wav NULL +TSFX_WITCH12 1 Sfx\\Towners\\Witch12.wav NULL +TSFX_WITCH13 1 Sfx\\Towners\\Witch13.wav NULL +TSFX_WITCH14 1 Sfx\\Towners\\Witch14.wav NULL +TSFX_WITCH15 1 Sfx\\Towners\\Witch15.wav NULL +TSFX_WITCH16 1 Sfx\\Towners\\Witch16.wav NULL +TSFX_WITCH17 1 Sfx\\Towners\\Witch17.wav NULL +TSFX_WITCH18 1 Sfx\\Towners\\Witch18.wav NULL +TSFX_WITCH19 1 Sfx\\Towners\\Witch19.wav NULL +TSFX_WITCH20 1 Sfx\\Towners\\Witch20.wav NULL +TSFX_WITCH21 1 Sfx\\Towners\\Witch21.wav NULL +TSFX_WITCH22 1 Sfx\\Towners\\Witch22.wav NULL +TSFX_WITCH23 1 Sfx\\Towners\\Witch23.wav NULL +TSFX_WITCH24 1 Sfx\\Towners\\Witch24.wav NULL +TSFX_WITCH25 1 Sfx\\Towners\\Witch25.wav NULL +TSFX_WITCH26 1 Sfx\\Towners\\Witch26.wav NULL +TSFX_WITCH27 1 Sfx\\Towners\\Witch27.wav NULL +TSFX_WITCH28 1 Sfx\\Towners\\Witch28.wav NULL +TSFX_WITCH29 1 Sfx\\Towners\\Witch29.wav NULL +TSFX_WITCH30 1 Sfx\\Towners\\Witch30.wav NULL +TSFX_WITCH31 1 Sfx\\Towners\\Witch31.wav NULL +TSFX_WITCH32 1 Sfx\\Towners\\Witch32.wav NULL +TSFX_WITCH33 1 Sfx\\Towners\\Witch33.wav NULL +TSFX_WITCH34 1 Sfx\\Towners\\Witch34.wav NULL +TSFX_WITCH35 1 Sfx\\Towners\\Witch35.wav NULL +TSFX_WITCH36 1 Sfx\\Towners\\Witch36.wav NULL +TSFX_WITCH37 1 Sfx\\Towners\\Witch37.wav NULL +TSFX_WITCH38 1 Sfx\\Towners\\Witch38.wav NULL +TSFX_WITCH39 1 Sfx\\Towners\\Witch39.wav NULL +TSFX_WITCH40 1 Sfx\\Towners\\Witch40.wav NULL +TSFX_WITCH41 1 Sfx\\Towners\\Witch41.wav NULL +TSFX_WITCH42 1 Sfx\\Towners\\Witch42.wav NULL +TSFX_WITCH43 1 Sfx\\Towners\\Witch43.wav NULL +TSFX_WITCH44 1 Sfx\\Towners\\Witch44.wav NULL +TSFX_WITCH45 1 Sfx\\Towners\\Witch45.wav NULL +TSFX_WITCH46 1 Sfx\\Towners\\Witch46.wav NULL +TSFX_WITCH47 1 Sfx\\Towners\\Witch47.wav NULL +TSFX_WITCH48 1 Sfx\\Towners\\Witch48.wav NULL +TSFX_WITCH49 1 Sfx\\Towners\\Witch49.wav NULL +TSFX_WITCH50 1 Sfx\\Towners\\Witch50.wav NULL +TSFX_WOUND 1 Sfx\\Towners\\Wound01.wav NULL +PS_MAGE1 65 Sfx\\Sorceror\\Mage01.wav NULL +PS_MAGE2 65 Sfx\\Sorceror\\Mage02.wav NULL +PS_MAGE3 65 Sfx\\Sorceror\\Mage03.wav NULL +PS_MAGE4 65 Sfx\\Sorceror\\Mage04.wav NULL +PS_MAGE5 65 Sfx\\Sorceror\\Mage05.wav NULL +PS_MAGE6 65 Sfx\\Sorceror\\Mage06.wav NULL +PS_MAGE7 65 Sfx\\Sorceror\\Mage07.wav NULL +PS_MAGE8 65 Sfx\\Sorceror\\Mage08.wav NULL +PS_MAGE9 65 Sfx\\Sorceror\\Mage09.wav NULL +PS_MAGE10 65 Sfx\\Sorceror\\Mage10.wav NULL +PS_MAGE11 65 Sfx\\Sorceror\\Mage11.wav NULL +PS_MAGE12 65 Sfx\\Sorceror\\Mage12.wav NULL +PS_MAGE13 64 Sfx\\Sorceror\\Mage13.wav NULL +PS_MAGE14 64 Sfx\\Sorceror\\Mage14.wav NULL +PS_MAGE15 64 Sfx\\Sorceror\\Mage15.wav NULL +PS_MAGE16 64 Sfx\\Sorceror\\Mage16.wav NULL +PS_MAGE17 64 Sfx\\Sorceror\\Mage17.wav NULL +PS_MAGE18 64 Sfx\\Sorceror\\Mage18.wav NULL +PS_MAGE19 64 Sfx\\Sorceror\\Mage19.wav NULL +PS_MAGE20 64 Sfx\\Sorceror\\Mage20.wav NULL +PS_MAGE21 64 Sfx\\Sorceror\\Mage21.wav NULL +PS_MAGE22 64 Sfx\\Sorceror\\Mage22.wav NULL +PS_MAGE23 64 Sfx\\Sorceror\\Mage23.wav NULL +PS_MAGE24 64 Sfx\\Sorceror\\Mage24.wav NULL +PS_MAGE25 64 Sfx\\Sorceror\\Mage25.wav NULL +PS_MAGE26 64 Sfx\\Sorceror\\Mage26.wav NULL +PS_MAGE27 64 Sfx\\Sorceror\\Mage27.wav NULL +PS_MAGE28 64 Sfx\\Sorceror\\Mage28.wav NULL +PS_MAGE29 64 Sfx\\Sorceror\\Mage29.wav NULL +PS_MAGE30 64 Sfx\\Sorceror\\Mage30.wav NULL +PS_MAGE31 64 Sfx\\Sorceror\\Mage31.wav NULL +PS_MAGE32 64 Sfx\\Sorceror\\Mage32.wav NULL +PS_MAGE33 64 Sfx\\Sorceror\\Mage33.wav NULL +PS_MAGE34 64 Sfx\\Sorceror\\Mage34.wav NULL +PS_MAGE35 64 Sfx\\Sorceror\\Mage35.wav NULL +PS_MAGE36 64 Sfx\\Sorceror\\Mage36.wav NULL +PS_MAGE37 64 Sfx\\Sorceror\\Mage37.wav NULL +PS_MAGE38 64 Sfx\\Sorceror\\Mage38.wav NULL +PS_MAGE39 64 Sfx\\Sorceror\\Mage39.wav NULL +PS_MAGE40 64 Sfx\\Sorceror\\Mage40.wav NULL +PS_MAGE41 64 Sfx\\Sorceror\\Mage41.wav NULL +PS_MAGE42 64 Sfx\\Sorceror\\Mage42.wav NULL +PS_MAGE43 64 Sfx\\Sorceror\\Mage43.wav NULL +PS_MAGE44 64 Sfx\\Sorceror\\Mage44.wav NULL +PS_MAGE45 64 Sfx\\Sorceror\\Mage45.wav NULL +PS_MAGE46 64 Sfx\\Sorceror\\Mage46.wav NULL +PS_MAGE47 64 Sfx\\Sorceror\\Mage47.wav NULL +PS_MAGE48 64 Sfx\\Sorceror\\Mage48.wav NULL +PS_MAGE49 64 Sfx\\Sorceror\\Mage49.wav NULL +PS_MAGE50 64 Sfx\\Sorceror\\Mage50.wav NULL +PS_MAGE51 65 Sfx\\Sorceror\\Mage51.wav NULL +PS_MAGE52 65 Sfx\\Sorceror\\Mage52.wav NULL +PS_MAGE53 65 Sfx\\Sorceror\\Mage53.wav NULL +PS_MAGE54 65 Sfx\\Sorceror\\Mage54.wav NULL +PS_MAGE55 65 Sfx\\Sorceror\\Mage55.wav NULL +PS_MAGE56 65 Sfx\\Sorceror\\Mage56.wav NULL +PS_MAGE57 64 Sfx\\Sorceror\\Mage57.wav NULL +PS_MAGE58 65 Sfx\\Sorceror\\Mage58.wav NULL +PS_MAGE59 65 Sfx\\Sorceror\\Mage59.wav NULL +PS_MAGE60 65 Sfx\\Sorceror\\Mage60.wav NULL +PS_MAGE61 65 Sfx\\Sorceror\\Mage61.wav NULL +PS_MAGE62 65 Sfx\\Sorceror\\Mage62.wav NULL +PS_MAGE63 65 Sfx\\Sorceror\\Mage63.wav NULL +PS_MAGE64 64 Sfx\\Sorceror\\Mage64.wav NULL +PS_MAGE65 64 Sfx\\Sorceror\\Mage65.wav NULL +PS_MAGE66 64 Sfx\\Sorceror\\Mage66.wav NULL +PS_MAGE67 64 Sfx\\Sorceror\\Mage67.wav NULL +PS_MAGE68 64 Sfx\\Sorceror\\Mage68.wav NULL +PS_MAGE69 64 Sfx\\Sorceror\\Mage69.wav NULL +PS_MAGE69B 64 Sfx\\Sorceror\\Mage69b.wav NULL +PS_MAGE70 64 Sfx\\Sorceror\\Mage70.wav NULL +PS_MAGE71 64 Sfx\\Sorceror\\Mage71.wav NULL +PS_MAGE72 64 Sfx\\Sorceror\\Mage72.wav NULL +PS_MAGE73 64 Sfx\\Sorceror\\Mage73.wav NULL +PS_MAGE74 64 Sfx\\Sorceror\\Mage74.wav NULL +PS_MAGE75 64 Sfx\\Sorceror\\Mage75.wav NULL +PS_MAGE76 64 Sfx\\Sorceror\\Mage76.wav NULL +PS_MAGE77 64 Sfx\\Sorceror\\Mage77.wav NULL +PS_MAGE78 64 Sfx\\Sorceror\\Mage78.wav NULL +PS_MAGE79 64 Sfx\\Sorceror\\Mage79.wav NULL +PS_MAGE80 65 Sfx\\Sorceror\\Mage80.wav NULL +PS_MAGE81 65 Sfx\\Sorceror\\Mage81.wav NULL +PS_MAGE82 65 Sfx\\Sorceror\\Mage82.wav NULL +PS_MAGE83 65 Sfx\\Sorceror\\Mage83.wav NULL +PS_MAGE84 65 Sfx\\Sorceror\\Mage84.wav NULL +PS_MAGE85 65 Sfx\\Sorceror\\Mage85.wav NULL +PS_MAGE86 65 Sfx\\Sorceror\\Mage86.wav NULL +PS_MAGE87 65 Sfx\\Sorceror\\Mage87.wav NULL +PS_MAGE88 65 Sfx\\Sorceror\\Mage88.wav NULL +PS_MAGE89 65 Sfx\\Sorceror\\Mage89.wav NULL +PS_MAGE90 65 Sfx\\Sorceror\\Mage90.wav NULL +PS_MAGE91 65 Sfx\\Sorceror\\Mage91.wav NULL +PS_MAGE92 65 Sfx\\Sorceror\\Mage92.wav NULL +PS_MAGE93 65 Sfx\\Sorceror\\Mage93.wav NULL +PS_MAGE94 65 Sfx\\Sorceror\\Mage94.wav NULL +PS_MAGE95 65 Sfx\\Sorceror\\Mage95.wav NULL +PS_MAGE96 65 Sfx\\Sorceror\\Mage96.wav NULL +PS_MAGE97 65 Sfx\\Sorceror\\Mage97.wav NULL +PS_MAGE98 65 Sfx\\Sorceror\\Mage98.wav NULL +PS_MAGE99 65 Sfx\\Sorceror\\Mage99.wav NULL +PS_MAGE100 65 Sfx\\Sorceror\\Mage100.wav NULL +PS_MAGE101 65 Sfx\\Sorceror\\Mage101.wav NULL +PS_MAGE102 65 Sfx\\Sorceror\\Mage102.wav NULL +PS_ROGUE1 17 Sfx\\Rogue\\Rogue01.wav NULL +PS_ROGUE2 17 Sfx\\Rogue\\Rogue02.wav NULL +PS_ROGUE3 17 Sfx\\Rogue\\Rogue03.wav NULL +PS_ROGUE4 17 Sfx\\Rogue\\Rogue04.wav NULL +PS_ROGUE5 17 Sfx\\Rogue\\Rogue05.wav NULL +PS_ROGUE6 17 Sfx\\Rogue\\Rogue06.wav NULL +PS_ROGUE7 17 Sfx\\Rogue\\Rogue07.wav NULL +PS_ROGUE8 17 Sfx\\Rogue\\Rogue08.wav NULL +PS_ROGUE9 17 Sfx\\Rogue\\Rogue09.wav NULL +PS_ROGUE10 17 Sfx\\Rogue\\Rogue10.wav NULL +PS_ROGUE11 17 Sfx\\Rogue\\Rogue11.wav NULL +PS_ROGUE12 17 Sfx\\Rogue\\Rogue12.wav NULL +PS_ROGUE13 16 Sfx\\Rogue\\Rogue13.wav NULL +PS_ROGUE14 16 Sfx\\Rogue\\Rogue14.wav NULL +PS_ROGUE15 16 Sfx\\Rogue\\Rogue15.wav NULL +PS_ROGUE16 16 Sfx\\Rogue\\Rogue16.wav NULL +PS_ROGUE17 16 Sfx\\Rogue\\Rogue17.wav NULL +PS_ROGUE18 16 Sfx\\Rogue\\Rogue18.wav NULL +PS_ROGUE19 16 Sfx\\Rogue\\Rogue19.wav NULL +PS_ROGUE20 16 Sfx\\Rogue\\Rogue20.wav NULL +PS_ROGUE21 16 Sfx\\Rogue\\Rogue21.wav NULL +PS_ROGUE22 16 Sfx\\Rogue\\Rogue22.wav NULL +PS_ROGUE23 16 Sfx\\Rogue\\Rogue23.wav NULL +PS_ROGUE24 16 Sfx\\Rogue\\Rogue24.wav NULL +PS_ROGUE25 16 Sfx\\Rogue\\Rogue25.wav NULL +PS_ROGUE26 16 Sfx\\Rogue\\Rogue26.wav NULL +PS_ROGUE27 16 Sfx\\Rogue\\Rogue27.wav NULL +PS_ROGUE28 16 Sfx\\Rogue\\Rogue28.wav NULL +PS_ROGUE29 16 Sfx\\Rogue\\Rogue29.wav NULL +PS_ROGUE30 16 Sfx\\Rogue\\Rogue30.wav NULL +PS_ROGUE31 16 Sfx\\Rogue\\Rogue31.wav NULL +PS_ROGUE32 16 Sfx\\Rogue\\Rogue32.wav NULL +PS_ROGUE33 16 Sfx\\Rogue\\Rogue33.wav NULL +PS_ROGUE34 16 Sfx\\Rogue\\Rogue34.wav NULL +PS_ROGUE35 16 Sfx\\Rogue\\Rogue35.wav NULL +PS_ROGUE36 16 Sfx\\Rogue\\Rogue36.wav NULL +PS_ROGUE37 16 Sfx\\Rogue\\Rogue37.wav NULL +PS_ROGUE38 16 Sfx\\Rogue\\Rogue38.wav NULL +PS_ROGUE39 16 Sfx\\Rogue\\Rogue39.wav NULL +PS_ROGUE40 16 Sfx\\Rogue\\Rogue40.wav NULL +PS_ROGUE41 16 Sfx\\Rogue\\Rogue41.wav NULL +PS_ROGUE42 16 Sfx\\Rogue\\Rogue42.wav NULL +PS_ROGUE43 16 Sfx\\Rogue\\Rogue43.wav NULL +PS_ROGUE44 16 Sfx\\Rogue\\Rogue44.wav NULL +PS_ROGUE45 16 Sfx\\Rogue\\Rogue45.wav NULL +PS_ROGUE46 16 Sfx\\Rogue\\Rogue46.wav NULL +PS_ROGUE47 16 Sfx\\Rogue\\Rogue47.wav NULL +PS_ROGUE48 16 Sfx\\Rogue\\Rogue48.wav NULL +PS_ROGUE49 16 Sfx\\Rogue\\Rogue49.wav NULL +PS_ROGUE50 16 Sfx\\Rogue\\Rogue50.wav NULL +PS_ROGUE51 17 Sfx\\Rogue\\Rogue51.wav NULL +PS_ROGUE52 17 Sfx\\Rogue\\Rogue52.wav NULL +PS_ROGUE53 17 Sfx\\Rogue\\Rogue53.wav NULL +PS_ROGUE54 17 Sfx\\Rogue\\Rogue54.wav NULL +PS_ROGUE55 17 Sfx\\Rogue\\Rogue55.wav NULL +PS_ROGUE56 17 Sfx\\Rogue\\Rogue56.wav NULL +PS_ROGUE57 16 Sfx\\Rogue\\Rogue57.wav NULL +PS_ROGUE58 17 Sfx\\Rogue\\Rogue58.wav NULL +PS_ROGUE59 17 Sfx\\Rogue\\Rogue59.wav NULL +PS_ROGUE60 17 Sfx\\Rogue\\Rogue60.wav NULL +PS_ROGUE61 17 Sfx\\Rogue\\Rogue61.wav NULL +PS_ROGUE62 17 Sfx\\Rogue\\Rogue62.wav NULL +PS_ROGUE63 17 Sfx\\Rogue\\Rogue63.wav NULL +PS_ROGUE64 16 Sfx\\Rogue\\Rogue64.wav NULL +PS_ROGUE65 16 Sfx\\Rogue\\Rogue65.wav NULL +PS_ROGUE66 16 Sfx\\Rogue\\Rogue66.wav NULL +PS_ROGUE67 16 Sfx\\Rogue\\Rogue67.wav NULL +PS_ROGUE68 16 Sfx\\Rogue\\Rogue68.wav NULL +PS_ROGUE69 16 Sfx\\Rogue\\Rogue69.wav NULL +PS_ROGUE69B 16 Sfx\\Rogue\\Rogue69b.wav NULL +PS_ROGUE70 16 Sfx\\Rogue\\Rogue70.wav NULL +PS_ROGUE71 16 Sfx\\Rogue\\Rogue71.wav NULL +PS_ROGUE72 16 Sfx\\Rogue\\Rogue72.wav NULL +PS_ROGUE73 16 Sfx\\Rogue\\Rogue73.wav NULL +PS_ROGUE74 16 Sfx\\Rogue\\Rogue74.wav NULL +PS_ROGUE75 16 Sfx\\Rogue\\Rogue75.wav NULL +PS_ROGUE76 16 Sfx\\Rogue\\Rogue76.wav NULL +PS_ROGUE77 16 Sfx\\Rogue\\Rogue77.wav NULL +PS_ROGUE78 16 Sfx\\Rogue\\Rogue78.wav NULL +PS_ROGUE79 16 Sfx\\Rogue\\Rogue79.wav NULL +PS_ROGUE80 17 Sfx\\Rogue\\Rogue80.wav NULL +PS_ROGUE81 17 Sfx\\Rogue\\Rogue81.wav NULL +PS_ROGUE82 17 Sfx\\Rogue\\Rogue82.wav NULL +PS_ROGUE83 17 Sfx\\Rogue\\Rogue83.wav NULL +PS_ROGUE84 17 Sfx\\Rogue\\Rogue84.wav NULL +PS_ROGUE85 17 Sfx\\Rogue\\Rogue85.wav NULL +PS_ROGUE86 17 Sfx\\Rogue\\Rogue86.wav NULL +PS_ROGUE87 17 Sfx\\Rogue\\Rogue87.wav NULL +PS_ROGUE88 17 Sfx\\Rogue\\Rogue88.wav NULL +PS_ROGUE89 17 Sfx\\Rogue\\Rogue89.wav NULL +PS_ROGUE90 17 Sfx\\Rogue\\Rogue90.wav NULL +PS_ROGUE91 17 Sfx\\Rogue\\Rogue91.wav NULL +PS_ROGUE92 17 Sfx\\Rogue\\Rogue92.wav NULL +PS_ROGUE93 17 Sfx\\Rogue\\Rogue93.wav NULL +PS_ROGUE94 17 Sfx\\Rogue\\Rogue94.wav NULL +PS_ROGUE95 17 Sfx\\Rogue\\Rogue95.wav NULL +PS_ROGUE96 17 Sfx\\Rogue\\Rogue96.wav NULL +PS_ROGUE97 17 Sfx\\Rogue\\Rogue97.wav NULL +PS_ROGUE98 17 Sfx\\Rogue\\Rogue98.wav NULL +PS_ROGUE99 17 Sfx\\Rogue\\Rogue99.wav NULL +PS_ROGUE100 17 Sfx\\Rogue\\Rogue100.wav NULL +PS_ROGUE101 17 Sfx\\Rogue\\Rogue101.wav NULL +PS_ROGUE102 17 Sfx\\Rogue\\Rogue102.wav NULL +PS_WARR1 33 Sfx\\Warrior\\Warior01.wav NULL +PS_WARR2 33 Sfx\\Warrior\\Warior02.wav NULL +PS_WARR3 33 Sfx\\Warrior\\Warior03.wav NULL +PS_WARR4 33 Sfx\\Warrior\\Warior04.wav NULL +PS_WARR5 33 Sfx\\Warrior\\Warior05.wav NULL +PS_WARR6 33 Sfx\\Warrior\\Warior06.wav NULL +PS_WARR7 33 Sfx\\Warrior\\Warior07.wav NULL +PS_WARR8 33 Sfx\\Warrior\\Warior08.wav NULL +PS_WARR9 33 Sfx\\Warrior\\Warior09.wav NULL +PS_WARR10 33 Sfx\\Warrior\\Warior10.wav NULL +PS_WARR11 33 Sfx\\Warrior\\Warior11.wav NULL +PS_WARR12 33 Sfx\\Warrior\\Warior12.wav NULL +PS_WARR13 32 Sfx\\Warrior\\Warior13.wav NULL +PS_WARR14 32 Sfx\\Warrior\\Warior14.wav NULL +PS_WARR14B 32 Sfx\\Warrior\\Wario14b.wav NULL +PS_WARR14C 32 Sfx\\Warrior\\Wario14c.wav NULL +PS_WARR15 32 Sfx\\Warrior\\Warior15.wav NULL +PS_WARR15B 32 Sfx\\Warrior\\Wario15b.wav NULL +PS_WARR15C 32 Sfx\\Warrior\\Wario15c.wav NULL +PS_WARR16 32 Sfx\\Warrior\\Warior16.wav NULL +PS_WARR16B 32 Sfx\\Warrior\\Wario16b.wav NULL +PS_WARR16C 32 Sfx\\Warrior\\Wario16c.wav NULL +PS_WARR17 32 Sfx\\Warrior\\Warior17.wav NULL +PS_WARR18 32 Sfx\\Warrior\\Warior18.wav NULL +PS_WARR19 32 Sfx\\Warrior\\Warior19.wav NULL +PS_WARR20 32 Sfx\\Warrior\\Warior20.wav NULL +PS_WARR21 32 Sfx\\Warrior\\Warior21.wav NULL +PS_WARR22 32 Sfx\\Warrior\\Warior22.wav NULL +PS_WARR23 32 Sfx\\Warrior\\Warior23.wav NULL +PS_WARR24 32 Sfx\\Warrior\\Warior24.wav NULL +PS_WARR25 32 Sfx\\Warrior\\Warior25.wav NULL +PS_WARR26 32 Sfx\\Warrior\\Warior26.wav NULL +PS_WARR27 32 Sfx\\Warrior\\Warior27.wav NULL +PS_WARR28 32 Sfx\\Warrior\\Warior28.wav NULL +PS_WARR29 32 Sfx\\Warrior\\Warior29.wav NULL +PS_WARR30 32 Sfx\\Warrior\\Warior30.wav NULL +PS_WARR31 32 Sfx\\Warrior\\Warior31.wav NULL +PS_WARR32 32 Sfx\\Warrior\\Warior32.wav NULL +PS_WARR33 32 Sfx\\Warrior\\Warior33.wav NULL +PS_WARR34 32 Sfx\\Warrior\\Warior34.wav NULL +PS_WARR35 32 Sfx\\Warrior\\Warior35.wav NULL +PS_WARR36 32 Sfx\\Warrior\\Warior36.wav NULL +PS_WARR37 32 Sfx\\Warrior\\Warior37.wav NULL +PS_WARR38 32 Sfx\\Warrior\\Warior38.wav NULL +PS_WARR39 32 Sfx\\Warrior\\Warior39.wav NULL +PS_WARR40 32 Sfx\\Warrior\\Warior40.wav NULL +PS_WARR41 32 Sfx\\Warrior\\Warior41.wav NULL +PS_WARR42 32 Sfx\\Warrior\\Warior42.wav NULL +PS_WARR43 32 Sfx\\Warrior\\Warior43.wav NULL +PS_WARR44 32 Sfx\\Warrior\\Warior44.wav NULL +PS_WARR45 32 Sfx\\Warrior\\Warior45.wav NULL +PS_WARR46 32 Sfx\\Warrior\\Warior46.wav NULL +PS_WARR47 32 Sfx\\Warrior\\Warior47.wav NULL +PS_WARR48 32 Sfx\\Warrior\\Warior48.wav NULL +PS_WARR49 32 Sfx\\Warrior\\Warior49.wav NULL +PS_WARR50 32 Sfx\\Warrior\\Warior50.wav NULL +PS_WARR51 33 Sfx\\Warrior\\Warior51.wav NULL +PS_WARR52 33 Sfx\\Warrior\\Warior52.wav NULL +PS_WARR53 33 Sfx\\Warrior\\Warior53.wav NULL +PS_WARR54 33 Sfx\\Warrior\\Warior54.wav NULL +PS_WARR55 33 Sfx\\Warrior\\Warior55.wav NULL +PS_WARR56 33 Sfx\\Warrior\\Warior56.wav NULL +PS_WARR57 32 Sfx\\Warrior\\Warior57.wav NULL +PS_WARR58 33 Sfx\\Warrior\\Warior58.wav NULL +PS_WARR59 33 Sfx\\Warrior\\Warior59.wav NULL +PS_WARR60 33 Sfx\\Warrior\\Warior60.wav NULL +PS_WARR61 33 Sfx\\Warrior\\Warior61.wav NULL +PS_WARR62 33 Sfx\\Warrior\\Warior62.wav NULL +PS_WARR63 33 Sfx\\Warrior\\Warior63.wav NULL +PS_WARR64 32 Sfx\\Warrior\\Warior64.wav NULL +PS_WARR65 32 Sfx\\Warrior\\Warior65.wav NULL +PS_WARR66 32 Sfx\\Warrior\\Warior66.wav NULL +PS_WARR67 32 Sfx\\Warrior\\Warior67.wav NULL +PS_WARR68 32 Sfx\\Warrior\\Warior68.wav NULL +PS_WARR69 32 Sfx\\Warrior\\Warior69.wav NULL +PS_WARR69B 32 Sfx\\Warrior\\Wario69b.wav NULL +PS_WARR70 32 Sfx\\Warrior\\Warior70.wav NULL +PS_WARR71 32 Sfx\\Warrior\\Warior71.wav NULL +PS_WARR72 32 Sfx\\Warrior\\Warior72.wav NULL +PS_WARR73 32 Sfx\\Warrior\\Warior73.wav NULL +PS_WARR74 32 Sfx\\Warrior\\Warior74.wav NULL +PS_WARR75 32 Sfx\\Warrior\\Warior75.wav NULL +PS_WARR76 32 Sfx\\Warrior\\Warior76.wav NULL +PS_WARR77 32 Sfx\\Warrior\\Warior77.wav NULL +PS_WARR78 32 Sfx\\Warrior\\Warior78.wav NULL +PS_WARR79 32 Sfx\\Warrior\\Warior79.wav NULL +PS_WARR80 33 Sfx\\Warrior\\Warior80.wav NULL +PS_WARR81 33 Sfx\\Warrior\\Warior81.wav NULL +PS_WARR82 33 Sfx\\Warrior\\Warior82.wav NULL +PS_WARR83 33 Sfx\\Warrior\\Warior83.wav NULL +PS_WARR84 33 Sfx\\Warrior\\Warior84.wav NULL +PS_WARR85 33 Sfx\\Warrior\\Warior85.wav NULL +PS_WARR86 33 Sfx\\Warrior\\Warior86.wav NULL +PS_WARR87 33 Sfx\\Warrior\\Warior87.wav NULL +PS_WARR88 33 Sfx\\Warrior\\Warior88.wav NULL +PS_WARR89 33 Sfx\\Warrior\\Warior89.wav NULL +PS_WARR90 33 Sfx\\Warrior\\Warior90.wav NULL +PS_WARR91 33 Sfx\\Warrior\\Warior91.wav NULL +PS_WARR92 33 Sfx\\Warrior\\Warior92.wav NULL +PS_WARR93 33 Sfx\\Warrior\\Warior93.wav NULL +PS_WARR94 33 Sfx\\Warrior\\Warior94.wav NULL +PS_WARR95 33 Sfx\\Warrior\\Warior95.wav NULL +PS_WARR95B 33 Sfx\\Warrior\\Wario95b.wav NULL +PS_WARR95C 33 Sfx\\Warrior\\Wario95c.wav NULL +PS_WARR95D 33 Sfx\\Warrior\\Wario95d.wav NULL +PS_WARR95E 33 Sfx\\Warrior\\Wario95e.wav NULL +PS_WARR95F 33 Sfx\\Warrior\\Wario95f.wav NULL +PS_WARR96B 33 Sfx\\Warrior\\Wario96b.wav NULL +PS_WARR97 33 Sfx\\Warrior\\Wario97.wav NULL +PS_WARR98 33 Sfx\\Warrior\\Wario98.wav NULL +PS_WARR99 33 Sfx\\Warrior\\Warior99.wav NULL +PS_WARR100 33 Sfx\\Warrior\\Wario100.wav NULL +PS_WARR101 33 Sfx\\Warrior\\Wario101.wav NULL +PS_WARR102 33 Sfx\\Warrior\\Wario102.wav NULL +PS_NAR1 1 Sfx\\Narrator\\Nar01.wav NULL +PS_NAR2 1 Sfx\\Narrator\\Nar02.wav NULL +PS_NAR3 1 Sfx\\Narrator\\Nar03.wav NULL +PS_NAR4 1 Sfx\\Narrator\\Nar04.wav NULL +PS_NAR5 1 Sfx\\Narrator\\Nar05.wav NULL +PS_NAR6 1 Sfx\\Narrator\\Nar06.wav NULL +PS_NAR7 1 Sfx\\Narrator\\Nar07.wav NULL +PS_NAR8 1 Sfx\\Narrator\\Nar08.wav NULL +PS_NAR9 1 Sfx\\Narrator\\Nar09.wav NULL +PS_DIABLVLINT 1 Sfx\\Misc\\Lvl16int.wav NULL +USFX_CLEAVER 1 Sfx\\Monsters\\Butcher.wav NULL +USFX_GARBUD1 1 Sfx\\Monsters\\Garbud01.wav NULL +USFX_GARBUD2 1 Sfx\\Monsters\\Garbud02.wav NULL +USFX_GARBUD3 1 Sfx\\Monsters\\Garbud03.wav NULL +USFX_GARBUD4 1 Sfx\\Monsters\\Garbud04.wav NULL +USFX_IZUAL1 1 Sfx\\Monsters\\Izual01.wav NULL +USFX_LACH1 1 Sfx\\Monsters\\Lach01.wav NULL +USFX_LACH2 1 Sfx\\Monsters\\Lach02.wav NULL +USFX_LACH3 1 Sfx\\Monsters\\Lach03.wav NULL +USFX_LAZ1 1 Sfx\\Monsters\\Laz01.wav NULL +USFX_LAZ2 1 Sfx\\Monsters\\Laz02.wav NULL +USFX_SKING1 1 Sfx\\Monsters\\Sking01.wav NULL +USFX_SNOT1 1 Sfx\\Monsters\\Snot01.wav NULL +USFX_SNOT2 1 Sfx\\Monsters\\Snot02.wav NULL +USFX_SNOT3 1 Sfx\\Monsters\\Snot03.wav NULL +USFX_WARLRD1 1 Sfx\\Monsters\\Warlrd01.wav NULL +USFX_WLOCK1 1 Sfx\\Monsters\\Wlock01.wav NULL +USFX_ZHAR1 1 Sfx\\Monsters\\Zhar01.wav NULL +USFX_ZHAR2 1 Sfx\\Monsters\\Zhar02.wav NULL +USFX_DIABLOD 1 Sfx\\Monsters\\DiabloD.wav NULL diff --git a/2020_03_31/Source/Data/Excel/xl_spell.txt b/2020_03_31/Source/Data/Excel/xl_spell.txt new file mode 100644 index 00000000..e2553644 --- /dev/null +++ b/2020_03_31/Source/Data/Excel/xl_spell.txt @@ -0,0 +1,38 @@ +#sName(i) sManaCost(i) sType(i) sNameText(s) sSkillText(s) sBookLvl(i) sStaffLvl(i) sTargeted(i) sTownSpell(i) sMinInt(i) sSFX(i) sMissiles(a) sManaAdj(i) sMinMana(i) sStaffMin(i) sStaffMax(i) sBookCost(i) sStaffCost(i) +SPL_NULL 0 0 NULL NULL 0 0 0 0 0 0 "0, 0, 0" 0 0 40 80 0 0 +SPL_FIREBOLT 6 STYPE_FIRE Firebolt Firebolt 1 1 1 0 15 IS_CAST2 "MIS_FIREBOLT, 0, 0" 1 3 40 80 1000 50 +SPL_HEAL 5 STYPE_MAGIC Healing NULL 1 1 0 1 17 IS_CAST8 "MIS_HEAL, 0, 0" 3 1 20 40 1000 50 +SPL_LIGHTNING 10 STYPE_LIGHTNING Lightning NULL 4 3 1 0 20 IS_CAST4 "MIS_LIGHTCTRL, 0, 0" 1 6 20 60 3000 150 +SPL_FLASH 30 STYPE_LIGHTNING Flash NULL 5 4 0 0 33 IS_CAST4 "MIS_FLASH, MIS_FLASH2, 0" 2 16 20 40 7500 500 +SPL_IDENTIFY 13 STYPE_MAGIC Identify Identify -1 -1 0 1 23 IS_CAST6 "MIS_IDENTIFY, 0, 0" 2 1 8 12 0 100 +SPL_FIREWALL 28 STYPE_FIRE Fire Wall NULL 3 2 1 0 27 IS_CAST2 "MIS_FIREWALLC, 0, 0" 2 16 8 16 6000 400 +SPL_TOWN 35 STYPE_MAGIC Town Portal NULL 3 3 1 0 20 IS_CAST6 "MIS_TOWN, 0, 0" 3 18 8 12 3000 200 +SPL_STONE 60 STYPE_MAGIC Stone Curse NULL 6 5 1 0 51 IS_CAST2 "MIS_STONE, 0, 0" 3 40 8 16 12000 800 +SPL_INFRA 40 STYPE_MAGIC Infravision NULL -1 -1 0 0 36 IS_CAST8 "MIS_INFRA, 0, 0" 5 20 0 0 0 600 +SPL_RNDTELEPORT 12 STYPE_MAGIC Phasing NULL 7 6 0 0 39 IS_CAST2 "MIS_RNDTELEPORT, 0, 0" 2 4 40 80 3500 200 +SPL_MANASHIELD 33 STYPE_MAGIC Mana Shield NULL 6 5 0 0 25 IS_CAST2 "MIS_MANASHIELD, 0, 0" 0 33 4 10 16000 1200 +SPL_FIREBALL 16 STYPE_FIRE Fireball NULL 8 7 1 0 48 IS_CAST2 "MIS_FIREBALL, 0, 0" 1 10 40 80 8000 300 +SPL_GUARDIAN 50 STYPE_FIRE Guardian NULL 9 8 1 0 61 IS_CAST2 "MIS_GUARDIAN, 0, 0" 2 30 16 32 14000 950 +SPL_CHAIN 30 STYPE_LIGHTNING Chain Lightning NULL 8 7 0 0 54 IS_CAST2 "MIS_CHAIN, 0, 0" 1 18 20 60 11000 750 +SPL_WAVE 35 STYPE_FIRE Flame Wave NULL 9 8 1 0 54 IS_CAST2 "MIS_WAVE, 0, 0" 3 20 20 40 10000 650 +SPL_DOOMSERP 0 STYPE_LIGHTNING Doom Serpents NULL -1 -1 0 0 0 IS_CAST2 "0, 0, 0" 0 0 40 80 0 0 +SPL_BLODRIT 0 STYPE_MAGIC Blood Ritual NULL -1 -1 0 0 0 IS_CAST2 "0, 0, 0" 0 0 40 80 0 0 +SPL_NOVA 60 STYPE_MAGIC Nova NULL -1 10 0 0 87 IS_CAST4 "MIS_NOVA, 0, 0" 3 35 16 32 21000 1300 +SPL_INVISIBIL 0 STYPE_MAGIC Invisibility NULL -1 -1 0 0 0 IS_CAST2 "0, 0, 0" 0 0 40 80 0 0 +SPL_FLAME 11 STYPE_FIRE Inferno NULL 3 2 1 0 20 IS_CAST2 "MIS_FLAMEC, 0, 0" 1 6 20 40 2000 100 +SPL_GOLEM 100 STYPE_FIRE Golem NULL 11 9 0 0 81 IS_CAST2 "MIS_GOLEM, 0, 0" 6 60 16 32 18000 1100 +SPL_BLODBOIL 0 STYPE_LIGHTNING Blood Boil NULL -1 -1 1 0 0 IS_CAST8 "0, 0, 0" 0 0 0 0 0 0 +SPL_TELEPORT 35 STYPE_MAGIC Teleport NULL 14 12 1 0 105 IS_CAST6 "MIS_TELEPORT, 0, 0" 3 15 16 32 20000 1250 +SPL_APOCA 150 STYPE_FIRE Apocalypse NULL -1 15 0 0 149 IS_CAST2 "MIS_APOCA, 0, 0" 6 90 8 12 30000 2000 +SPL_ETHEREALIZE 100 STYPE_MAGIC Etherealize NULL -1 -1 0 0 93 IS_CAST2 "MIS_ETHEREALIZE, 0, 0" 0 100 2 6 26000 1600 +SPL_REPAIR 0 STYPE_MAGIC Item Repair Item Repair -1 -1 0 1 -1 IS_CAST6 "MIS_REPAIR, 0, 0" 0 0 40 80 0 0 +SPL_RECHARGE 0 STYPE_MAGIC Staff Recharge Staff Recharge -1 -1 0 1 -1 IS_CAST6 "MIS_RECHARGE, 0, 0" 0 0 40 80 0 0 +SPL_DISARM 0 STYPE_MAGIC Trap Disarm Trap Disarm -1 -1 0 0 -1 IS_CAST6 "MIS_DISARM, 0, 0" 0 0 40 80 0 0 +SPL_ELEMENT 35 STYPE_FIRE Elemental NULL 8 6 0 0 68 IS_CAST2 "MIS_ELEMENT, 0, 0" 2 20 20 60 10500 700 +SPL_CBOLT 6 STYPE_LIGHTNING Charged Bolt NULL 1 1 1 0 25 IS_CAST2 "MIS_CBOLT, 0, 0" 1 6 40 80 1000 50 +SPL_HBOLT 7 STYPE_MAGIC Holy Bolt NULL 1 1 1 0 20 IS_CAST2 "MIS_HBOLT, 0, 0" 1 3 40 80 1000 50 +SPL_RESURRECT 20 STYPE_MAGIC Resurrect NULL -1 5 0 1 30 IS_CAST8 "MIS_RESURRECT, 0, 0" 0 20 4 10 4000 250 +SPL_TELEKINESIS 15 STYPE_MAGIC Telekinesis NULL 2 2 0 0 33 IS_CAST2 "MIS_TELEKINESIS, 0, 0" 2 8 20 40 2500 200 +SPL_HEALOTHER 5 STYPE_MAGIC Heal Other NULL 1 1 0 1 17 IS_CAST8 "MIS_HEALOTHER, 0, 0" 3 1 20 40 1000 50 +SPL_FLARE 25 STYPE_MAGIC Blood Star NULL 14 13 0 0 70 IS_CAST2 "MIS_FLARE, 0, 0" 2 14 20 60 27500 1800 +SPL_BONESPIRIT 24 STYPE_MAGIC Bone Spirit NULL 9 7 0 0 34 IS_CAST2 "MIS_BONESPIRIT, 0, 0" 1 12 20 60 11500 800 diff --git a/2020_03_31/Source/Data/Excel/xl_uitem.txt b/2020_03_31/Source/Data/Excel/xl_uitem.txt new file mode 100644 index 00000000..c496b912 --- /dev/null +++ b/2020_03_31/Source/Data/Excel/xl_uitem.txt @@ -0,0 +1,92 @@ +UIName(s) UIItemId(i) UIMinLvl(i) UINumPL(i) UIValue(i) UIPower1(i) UIParam1(i) UIParam2(i) UIPower2(i) UIParam3(i) UIParam4(i) UIPower3(i) UIParam5(i) UIParam6(i) UIPower4(i) UIParam7(i) UIParam8(i) UIPower5(i) UIParam9(i) UIParam10(i) UIPower6(i) UIParam11(i) UIParam12(i) +The Butcher's Cleaver UITYPE_CLEAVER 1 3 3650 IPL_STR 10 10 IPL_SETDAM 4 24 IPL_SETDUR 10 10 IPL_TOHIT 0 0 IPL_TOHIT 0 0 IPL_TOHIT 0 0 +The Undead Crown UITYPE_SKCROWN 1 3 16650 IPL_RNDSTEALLIFE 0 0 IPL_SETAC 8 8 IPL_INVCURS 77 0 IPL_TOHIT 0 0 IPL_TOHIT 0 0 IPL_TOHIT 0 0 +Empyrean Band UITYPE_INFRARING 1 4 8000 IPL_ATTRIBS 2 2 IPL_LIGHT 2 2 IPL_FASTRECOVER 1 1 IPL_ABSHALFTRAP 0 0 IPL_TOHIT 0 0 IPL_TOHIT 0 0 +Optic Amulet UITYPE_OPTAMULET 1 5 9750 IPL_LIGHT 2 2 IPL_LIGHTRES 20 20 IPL_GETHIT 1 1 IPL_MAG 5 5 IPL_INVCURS 44 0 IPL_TOHIT 0 0 +Ring of Truth UITYPE_TRING 1 4 9100 IPL_LIFE 10 10 IPL_GETHIT 1 1 IPL_ALLRES 10 10 IPL_INVCURS 10 0 IPL_TOHIT 0 0 IPL_TOHIT 0 0 +Harlequin Crest UITYPE_HARCREST 1 6 4000 IPL_AC_CURSE 3 3 IPL_GETHIT 1 1 IPL_ATTRIBS 2 2 IPL_LIFE 7 7 IPL_MANA 7 7 IPL_INVCURS 81 0 +Veil of Steel UITYPE_STEELVEIL 1 6 63800 IPL_ALLRES 50 50 IPL_LIGHT_CURSE 2 2 IPL_ACP 60 60 IPL_MANA_CURSE 30 30 IPL_STR 15 15 IPL_VIT 15 15 +Arkaine's Valor UITYPE_ARMOFVAL 1 4 42000 IPL_SETAC 25 25 IPL_VIT 10 10 IPL_GETHIT 3 3 IPL_FASTRECOVER 3 3 IPL_TOHIT 0 0 IPL_TOHIT 0 0 +Griswold's Edge UITYPE_GRISWOLD 1 6 42000 IPL_FIREDAM 1 10 IPL_TOHIT 25 25 IPL_FASTATTACK 2 2 IPL_KNOCKBACK 0 0 IPL_MANA 20 20 IPL_LIFE_CURSE 20 20 +Lightforge UITYPE_MACE 1 6 26675 IPL_LIGHT 4 4 IPL_DAMP 150 150 IPL_TOHIT 25 25 IPL_FIREDAM 10 20 IPL_INDESTRUCTIBLE 0 0 IPL_ATTRIBS 8 8 +The Rift Bow UITYPE_SHORTBOW 1 3 1800 IPL_RNDARROWVEL 0 0 IPL_DAMMOD 2 2 IPL_DEX_CURSE 3 3 IPL_TOHIT 0 0 IPL_TOHIT 0 0 IPL_TOHIT 0 0 +The Needler UITYPE_SHORTBOW 2 4 8900 IPL_TOHIT 50 50 IPL_SETDAM 1 3 IPL_FASTATTACK 2 2 IPL_INVCURS 158 0 IPL_TOHIT 0 0 IPL_TOHIT 0 0 +The Celestial Bow UITYPE_LONGBOW 2 4 1200 IPL_NOMINSTR 0 0 IPL_DAMMOD 2 2 IPL_SETAC 5 5 IPL_INVCURS 133 0 IPL_TOHIT 0 0 IPL_TOHIT 0 0 +Deadly Hunter UITYPE_COMPBOW 3 4 8750 IPL_3XDAMVDEM 10 10 IPL_TOHIT 20 20 IPL_MAG_CURSE 5 5 IPL_INVCURS 108 0 IPL_TOHIT 0 0 IPL_TOHIT 0 0 +Bow of the Dead UITYPE_COMPBOW 5 6 2500 IPL_TOHIT 10 10 IPL_DEX 4 4 IPL_VIT_CURSE 3 3 IPL_LIGHT_CURSE 2 2 IPL_SETDUR 30 30 IPL_INVCURS 108 0 +The Blackoak Bow UITYPE_LONGBOW 5 4 2500 IPL_DEX 10 10 IPL_VIT_CURSE 10 10 IPL_DAMP 50 50 IPL_LIGHT_CURSE 1 1 IPL_TOHIT 0 0 IPL_TOHIT 0 0 +Flamedart UITYPE_HUNTBOW 10 4 14250 IPL_FIRE_ARROWS 0 0 IPL_FIREDAM 1 6 IPL_TOHIT 20 20 IPL_FIRERES 40 40 IPL_TOHIT 0 0 IPL_TOHIT 0 0 +Fleshstinger UITYPE_LONGBOW 13 4 16500 IPL_DEX 15 15 IPL_TOHIT 40 40 IPL_DAMP 80 80 IPL_DUR 6 6 IPL_TOHIT 0 0 IPL_TOHIT 0 0 +Windforce UITYPE_WARBOW 17 4 37750 IPL_STR 5 5 IPL_DAMP 200 200 IPL_KNOCKBACK 0 0 IPL_INVCURS 164 0 IPL_TOHIT 0 0 IPL_TOHIT 0 0 +Eaglehorn UITYPE_BATTLEBOW 26 5 42500 IPL_DEX 20 20 IPL_TOHIT 50 50 IPL_DAMP 100 100 IPL_INDESTRUCTIBLE 0 0 IPL_INVCURS 108 0 IPL_TOHIT 0 0 +Gonnagal's Dirk UITYPE_DAGGER 1 5 7040 IPL_DEX_CURSE 5 5 IPL_DAMMOD 4 4 IPL_FASTATTACK 2 2 IPL_FIRERES 25 25 IPL_INVCURS 54 0 IPL_TOHIT 0 0 +The Defender UITYPE_SABRE 1 3 2000 IPL_SETAC 5 5 IPL_VIT 5 5 IPL_TOHIT_CURSE 5 5 IPL_TOHIT 0 0 IPL_TOHIT 0 0 IPL_TOHIT 0 0 +Gryphons Claw UITYPE_FALCHION 1 4 1000 IPL_DAMP 100 100 IPL_MAG_CURSE 2 2 IPL_DEX_CURSE 5 5 IPL_INVCURS 68 0 IPL_TOHIT 0 0 IPL_TOHIT 0 0 +Black Razor UITYPE_DAGGER 1 4 2000 IPL_DAMP 150 150 IPL_VIT 2 2 IPL_SETDUR 5 5 IPL_INVCURS 53 0 IPL_TOHIT 0 0 IPL_TOHIT 0 0 +Gibbous Moon UITYPE_BROADSWR 2 4 6660 IPL_ATTRIBS 2 2 IPL_DAMP 25 25 IPL_MANA 15 15 IPL_LIGHT_CURSE 3 3 IPL_TOHIT 0 0 IPL_TOHIT 0 0 +Ice Shank UITYPE_LONGSWR 3 3 5250 IPL_FIRERES 40 40 IPL_SETDUR 15 15 IPL_STR 5 10 IPL_TOHIT 0 0 IPL_TOHIT 0 0 IPL_TOHIT 0 0 +The Executioner's Blade UITYPE_FALCHION 3 5 7080 IPL_DAMP 150 150 IPL_LIFE_CURSE 10 10 IPL_LIGHT_CURSE 1 1 IPL_DUR 200 200 IPL_INVCURS 58 0 IPL_TOHIT 0 0 +The Bonesaw UITYPE_CLAYMORE 6 6 4400 IPL_DAMMOD 10 10 IPL_STR 10 10 IPL_MAG_CURSE 5 5 IPL_DEX_CURSE 5 5 IPL_LIFE 10 10 IPL_MANA_CURSE 10 10 +Shadowhawk UITYPE_BROADSWR 8 4 13750 IPL_LIGHT_CURSE 2 2 IPL_STEALLIFE 5 5 IPL_TOHIT 15 15 IPL_ALLRES 5 5 IPL_TOHIT 0 0 IPL_TOHIT 0 0 +Wizardspike UITYPE_DAGGER 11 5 12920 IPL_MAG 15 15 IPL_MANA 35 35 IPL_TOHIT 25 25 IPL_ALLRES 15 15 IPL_INVCURS 50 0 IPL_TOHIT 0 0 +Lightsabre UITYPE_SABRE 13 4 19150 IPL_LIGHT 2 2 IPL_LIGHTDAM 1 10 IPL_TOHIT 20 20 IPL_LIGHTRES 50 50 IPL_TOHIT 0 0 IPL_TOHIT 0 0 +The Falcon's Talon UITYPE_SCIMITAR 15 5 7867 IPL_FASTATTACK 4 4 IPL_TOHIT 20 20 IPL_DAMP_CURSE 33 33 IPL_DEX 10 10 IPL_INVCURS 68 0 IPL_TOHIT 0 0 +Inferno UITYPE_LONGSWR 17 4 34600 IPL_FIREDAM 2 12 IPL_LIGHT 3 3 IPL_MANA 20 20 IPL_FIRERES 80 80 IPL_TOHIT 0 0 IPL_TOHIT 0 0 +Doombringer UITYPE_BASTARDSWR 19 5 18250 IPL_TOHIT 25 25 IPL_DAMP 250 250 IPL_ATTRIBS_CURSE 5 5 IPL_LIFE_CURSE 25 25 IPL_LIGHT_CURSE 2 2 IPL_TOHIT 0 0 +The Grizzly UITYPE_TWOHANDSWR 23 6 50000 IPL_STR 20 20 IPL_VIT_CURSE 5 5 IPL_DAMP 200 200 IPL_KNOCKBACK 0 0 IPL_DUR 100 100 IPL_INVCURS 160 0 +The Grandfather UITYPE_GREATSWR 27 6 119800 IPL_ONEHAND 0 0 IPL_ATTRIBS 5 5 IPL_TOHIT 20 20 IPL_DAMP 70 70 IPL_LIFE 20 20 IPL_INVCURS 161 0 +The Mangler UITYPE_LARGEAXE 2 5 2850 IPL_DAMP 200 200 IPL_DEX_CURSE 5 5 IPL_MAG_CURSE 5 5 IPL_MANA_CURSE 10 10 IPL_INVCURS 144 0 IPL_TOHIT 0 0 +Sharp Beak UITYPE_LARGEAXE 2 4 2850 IPL_LIFE 20 20 IPL_MAG_CURSE 10 10 IPL_MANA_CURSE 10 10 IPL_INVCURS 143 0 IPL_TOHIT 0 0 IPL_TOHIT 0 0 +BloodSlayer UITYPE_BROADAXE 3 5 2500 IPL_DAMP 100 100 IPL_3XDAMVDEM 50 50 IPL_ATTRIBS_CURSE 5 5 IPL_SPLLVLADD -1 -1 IPL_INVCURS 144 0 IPL_TOHIT 0 0 +The Celestial Axe UITYPE_BATTLEAXE 4 4 14100 IPL_NOMINSTR 0 0 IPL_TOHIT 15 15 IPL_LIFE 15 15 IPL_STR_CURSE 15 15 IPL_TOHIT 0 0 IPL_TOHIT 0 0 +Wicked Axe UITYPE_LARGEAXE 5 6 31150 IPL_TOHIT 30 30 IPL_DEX 10 10 IPL_VIT_CURSE 10 10 IPL_GETHIT 1 6 IPL_INDESTRUCTIBLE 0 0 IPL_INVCURS 143 0 +Stonecleaver UITYPE_BROADAXE 7 5 23900 IPL_LIFE 30 30 IPL_TOHIT 20 20 IPL_DAMP 50 50 IPL_LIGHTRES 40 40 IPL_INVCURS 104 0 IPL_TOHIT 0 0 +Aguinara's Hatchet UITYPE_SMALLAXE 12 3 24800 IPL_SPLLVLADD 1 1 IPL_MAG 10 10 IPL_MAGICRES 80 80 IPL_TOHIT 0 0 IPL_TOHIT 0 0 IPL_TOHIT 0 0 +Hellslayer UITYPE_BATTLEAXE 15 5 26200 IPL_STR 8 8 IPL_VIT 8 8 IPL_DAMP 100 100 IPL_LIFE 25 25 IPL_MANA_CURSE 25 25 IPL_TOHIT 0 0 +Messerschmidt's Reaver UITYPE_GREATAXE 25 6 58000 IPL_DAMP 200 200 IPL_DAMMOD 15 15 IPL_ATTRIBS 5 5 IPL_LIFE_CURSE 50 50 IPL_FIREDAM 2 12 IPL_INVCURS 163 0 +Crackrust UITYPE_MACE 1 5 11375 IPL_ATTRIBS 2 2 IPL_INDESTRUCTIBLE 0 0 IPL_ALLRES 15 15 IPL_DAMP 50 50 IPL_SPLLVLADD -1 -1 IPL_TOHIT 0 0 +Hammer of Jholm UITYPE_MAUL 1 4 8700 IPL_DAMP 4 10 IPL_INDESTRUCTIBLE 0 0 IPL_STR 3 3 IPL_TOHIT 15 15 IPL_TOHIT 0 0 IPL_TOHIT 0 0 +Civerb's Cudgel UITYPE_MACE 1 3 2000 IPL_3XDAMVDEM 35 35 IPL_DEX_CURSE 5 5 IPL_MAG_CURSE 2 2 IPL_TOHIT 0 0 IPL_TOHIT 0 0 IPL_TOHIT 0 0 +The Celestial Star UITYPE_FLAIL 2 5 7810 IPL_NOMINSTR 0 0 IPL_LIGHT 2 2 IPL_DAMMOD 10 10 IPL_AC_CURSE 8 8 IPL_INVCURS 131 0 IPL_TOHIT 0 0 +Baranar's Star UITYPE_MORNSTAR 5 6 6850 IPL_TOHIT 12 12 IPL_DAMP 80 80 IPL_FASTATTACK 1 1 IPL_VIT 4 4 IPL_DEX_CURSE 4 4 IPL_SETDUR 60 60 +Gnarled Root UITYPE_SPIKCLUB 9 6 9820 IPL_TOHIT 20 20 IPL_DAMP 300 300 IPL_DEX 10 10 IPL_MAG 5 5 IPL_ALLRES 10 10 IPL_AC_CURSE 10 10 +The Cranium Basher UITYPE_MAUL 12 6 36500 IPL_DAMMOD 20 20 IPL_STR 15 15 IPL_INDESTRUCTIBLE 0 0 IPL_MANA_CURSE 150 150 IPL_ALLRES 5 5 IPL_INVCURS 122 0 +Schaefer's Hammer UITYPE_WARHAMMER 16 6 56125 IPL_DAMP_CURSE 100 100 IPL_LIGHTDAM 1 50 IPL_LIFE 50 50 IPL_TOHIT 30 30 IPL_LIGHTRES 80 80 IPL_LIGHT 1 1 +Dreamflange UITYPE_MACE 26 5 26450 IPL_MAG 30 30 IPL_MANA 50 50 IPL_MAGICRES 50 50 IPL_LIGHT 2 2 IPL_SPLLVLADD 1 1 IPL_TOHIT 0 0 +Staff of Shadows UITYPE_LONGSTAFF 2 5 1250 IPL_MAG_CURSE 10 10 IPL_TOHIT 10 10 IPL_DAMP 60 60 IPL_LIGHT_CURSE 2 2 IPL_FASTATTACK 1 1 IPL_TOHIT 0 0 +Immolator UITYPE_LONGSTAFF 4 4 3900 IPL_FIRERES 20 20 IPL_FIREDAM 4 4 IPL_MANA 10 10 IPL_VIT_CURSE 5 5 IPL_TOHIT 0 0 IPL_TOHIT 0 0 +Storm Spire UITYPE_WARSTAFF 8 4 22500 IPL_LIGHTRES 50 50 IPL_LIGHTDAM 2 8 IPL_STR 10 10 IPL_MAG_CURSE 10 10 IPL_TOHIT 0 0 IPL_TOHIT 0 0 +Gleamsong UITYPE_SHORTSTAFF 8 4 6520 IPL_MANA 25 25 IPL_STR_CURSE 3 3 IPL_VIT_CURSE 3 3 IPL_SPELL 10 76 IPL_TOHIT 0 0 IPL_TOHIT 0 0 +Thundercall UITYPE_COMPSTAFF 14 5 22250 IPL_TOHIT 35 35 IPL_LIGHTDAM 1 10 IPL_SPELL 3 76 IPL_LIGHTRES 30 30 IPL_LIGHT 2 2 IPL_TOHIT 0 0 +The Protector UITYPE_SHORTSTAFF 16 6 17240 IPL_VIT 5 5 IPL_GETHIT 5 5 IPL_SETAC 40 40 IPL_SPELL 2 86 IPL_THORNS 1 3 IPL_INVCURS 162 0 +Naj's Puzzler UITYPE_LONGSTAFF 18 5 34000 IPL_MAG 20 20 IPL_DEX 10 10 IPL_ALLRES 20 20 IPL_SPELL 23 57 IPL_LIFE_CURSE 25 25 IPL_TOHIT 0 0 +Mindcry UITYPE_QUARSTAFF 20 4 41500 IPL_MAG 15 15 IPL_SPELL 13 69 IPL_ALLRES 15 15 IPL_SPLLVLADD 1 1 IPL_TOHIT 0 0 IPL_TOHIT 0 0 +Rod of Onan UITYPE_WARSTAFF 22 3 44167 IPL_SPELL 21 50 IPL_DAMP 100 100 IPL_ATTRIBS 5 5 IPL_TOHIT 0 0 IPL_TOHIT 0 0 IPL_TOHIT 0 0 +Helm of Sprits UITYPE_HELM 1 2 7525 IPL_STEALLIFE 5 5 IPL_INVCURS 77 0 IPL_TOHIT 0 0 IPL_TOHIT 0 0 IPL_TOHIT 0 0 IPL_TOHIT 0 0 +Thinking Cap UITYPE_SKULLCAP 6 5 2020 IPL_MANA 30 30 IPL_SPLLVLADD 2 2 IPL_ALLRES 20 20 IPL_SETDUR 1 1 IPL_INVCURS 93 0 IPL_TOHIT 0 0 +OverLord's Helm UITYPE_HELM 7 6 12500 IPL_STR 20 20 IPL_DEX 15 15 IPL_VIT 5 5 IPL_MAG_CURSE 20 20 IPL_SETDUR 15 15 IPL_INVCURS 99 0 +Fool's Crest UITYPE_HELM 12 5 10150 IPL_ATTRIBS_CURSE 4 4 IPL_LIFE 100 100 IPL_GETHIT_CURSE 1 6 IPL_THORNS 1 3 IPL_INVCURS 80 0 IPL_TOHIT 0 0 +Gotterdamerung UITYPE_GREATHELM 21 6 54900 IPL_ATTRIBS 20 20 IPL_SETAC 60 60 IPL_GETHIT 4 4 IPL_ALLRESZERO 0 0 IPL_LIGHT_CURSE 4 4 IPL_INVCURS 85 0 +Royal Circlet UITYPE_CROWN 27 5 24875 IPL_ATTRIBS 10 10 IPL_MANA 40 40 IPL_SETAC 40 40 IPL_LIGHT 1 1 IPL_INVCURS 79 0 IPL_TOHIT 0 0 +Torn Flesh of Souls UITYPE_RAGS 2 5 4825 IPL_SETAC 8 8 IPL_VIT 10 10 IPL_GETHIT 1 1 IPL_INDESTRUCTIBLE 0 0 IPL_INVCURS 92 0 IPL_TOHIT 0 0 +The Gladiator's Bane UITYPE_STUDARMOR 6 4 3450 IPL_SETAC 25 25 IPL_GETHIT 2 2 IPL_DUR 200 200 IPL_ATTRIBS_CURSE 3 3 IPL_TOHIT 0 0 IPL_TOHIT 0 0 +The Rainbow Cloak UITYPE_CLOAK 2 6 4900 IPL_SETAC 10 10 IPL_ATTRIBS 1 1 IPL_ALLRES 10 10 IPL_LIFE 5 5 IPL_DUR 50 50 IPL_INVCURS 138 0 +Leather of Aut UITYPE_LEATHARMOR 4 5 10550 IPL_SETAC 15 15 IPL_STR 5 5 IPL_MAG_CURSE 5 5 IPL_DEX 5 5 IPL_INDESTRUCTIBLE 0 0 IPL_TOHIT 0 0 +Wisdom's Wrap UITYPE_ROBE 5 6 6200 IPL_MAG 5 5 IPL_MANA 10 10 IPL_LIGHTRES 25 25 IPL_SETAC 15 15 IPL_GETHIT 1 1 IPL_INVCURS 138 0 +Sparking Mail UITYPE_CHAINMAIL 9 2 15750 IPL_SETAC 30 30 IPL_LIGHTDAM 1 10 IPL_TOHIT 0 0 IPL_TOHIT 0 0 IPL_TOHIT 0 0 IPL_TOHIT 0 0 +Scavenger Carapace UITYPE_BREASTPLATE 13 4 14000 IPL_GETHIT 15 15 IPL_AC_CURSE 30 30 IPL_DEX 5 5 IPL_LIGHTRES 40 40 IPL_TOHIT 0 0 IPL_TOHIT 0 0 +Nightscape UITYPE_CAPE 16 6 11600 IPL_FASTRECOVER 2 2 IPL_LIGHT_CURSE 4 4 IPL_SETAC 15 15 IPL_DEX 3 3 IPL_ALLRES 20 20 IPL_INVCURS 138 0 +Naj's Light Plate UITYPE_PLATEMAIL 19 6 78700 IPL_NOMINSTR 0 0 IPL_MAG 5 5 IPL_MANA 20 20 IPL_ALLRES 20 20 IPL_SPLLVLADD 1 1 IPL_INVCURS 159 0 +Demonspike Coat UITYPE_FULLPLATE 25 5 251175 IPL_SETAC 100 100 IPL_GETHIT 6 6 IPL_STR 10 10 IPL_INDESTRUCTIBLE 0 0 IPL_FIRERES 50 50 IPL_TOHIT 0 0 +The Deflector UITYPE_BUCKLER 1 5 1500 IPL_SETAC 7 7 IPL_ALLRES 10 10 IPL_DAMP_CURSE 20 20 IPL_TOHIT_CURSE 5 5 IPL_INVCURS 83 0 IPL_TOHIT 0 0 +Split Skull Shield UITYPE_BUCKLER 1 6 2025 IPL_SETAC 10 10 IPL_LIFE 10 10 IPL_STR 2 2 IPL_LIGHT_CURSE 1 1 IPL_SETDUR 15 15 IPL_INVCURS 116 0 +Dragon's Breach UITYPE_KITESHIELD 2 6 19200 IPL_FIRERES 25 25 IPL_STR 5 5 IPL_SETAC 20 20 IPL_MAG_CURSE 5 5 IPL_INDESTRUCTIBLE 0 0 IPL_INVCURS 117 0 +Blackoak Shield UITYPE_SMALLSHIELD 4 6 5725 IPL_DEX 10 10 IPL_VIT_CURSE 10 10 IPL_SETAC 18 18 IPL_LIGHT_CURSE 1 1 IPL_DUR 150 150 IPL_INVCURS 146 0 +Holy Defender UITYPE_LARGESHIELD 10 6 13800 IPL_SETAC 15 15 IPL_GETHIT 2 2 IPL_FIRERES 20 20 IPL_DUR 200 200 IPL_FASTBLOCK 1 1 IPL_INVCURS 146 0 +Stormshield UITYPE_GOTHSHIELD 24 6 49000 IPL_SETAC 40 40 IPL_GETHIT_CURSE 4 4 IPL_STR 10 10 IPL_INDESTRUCTIBLE 0 0 IPL_FASTBLOCK 1 1 IPL_INVCURS 148 0 +Bramble UITYPE_RING 1 4 1000 IPL_ATTRIBS_CURSE 2 2 IPL_DAMMOD 3 3 IPL_MANA 10 10 IPL_INVCURS 9 0 IPL_TOHIT 0 0 IPL_TOHIT 0 0 +Ring of Regha UITYPE_RING 1 6 4175 IPL_MAG 10 10 IPL_MAGICRES 10 10 IPL_LIGHT 1 1 IPL_STR_CURSE 3 3 IPL_DEX_CURSE 3 3 IPL_INVCURS 11 0 +The Bleeder UITYPE_RING 2 4 8500 IPL_MAGICRES 20 20 IPL_MANA 30 30 IPL_LIFE_CURSE 10 10 IPL_INVCURS 8 0 IPL_TOHIT 0 0 IPL_TOHIT 0 0 +Constricting Ring UITYPE_RING 5 3 62000 IPL_ALLRES 75 75 IPL_DRAINLIFE 0 0 IPL_INVCURS 14 0 IPL_TOHIT 0 0 IPL_TOHIT 0 0 IPL_TOHIT 0 0 +Ring of Engagement UITYPE_RING 11 5 12476 IPL_GETHIT 1 2 IPL_THORNS 1 3 IPL_SETAC 5 5 IPL_TARGAC 4 12 IPL_INVCURS 13 0 IPL_TOHIT 0 0 +~ UITYPE_INVALID 0 0 0 IPL_TOHIT 0 0 IPL_TOHIT 0 0 IPL_TOHIT 0 0 IPL_TOHIT 0 0 IPL_TOHIT 0 0 IPL_TOHIT 0 0 diff --git a/2020_03_31/Source/Data/Excel/xl_umon.txt b/2020_03_31/Source/Data/Excel/xl_umon.txt new file mode 100644 index 00000000..4d303c60 --- /dev/null +++ b/2020_03_31/Source/Data/Excel/xl_umon.txt @@ -0,0 +1,99 @@ +mtype(i) mName(s) mTrnName(s) mlevel(i) mmaxhp(i) mAi(i) mint(i) mMinDamage(i) mMaxDamage(i) mMagicRes(i) mUnqAttr(i) mUnqVar1(i) mUnqVar2(i) mtalkmsg(i) +MT_NGOATMC Gharbad the Weak BSDB 4 120 AI_GARBUD 3 8 16 96 0 0 0 TEXT_GARBUD1 +MT_SKING Skeleton King GENRL 0 240 AI_SKELKING 3 6 16 78 1 0 0 0 +MT_COUNSLR Zhar the Mad GENERAL 8 360 AI_ZHAR 3 16 40 14 0 0 0 TEXT_ZHAR1 +MT_BFALLSP Snotspill BNG 4 220 AI_SNOTSPIL 3 10 18 4 0 0 0 TEXT_BANNER10 +MT_ADVOCATE Arch-Bishop Lazarus GENERAL 0 600 AI_LAZURUS 3 30 50 78 0 0 0 TEXT_VILE13 +MT_HLSPWN Red Vex REDV 0 400 AI_LAZHELP 3 30 50 74 0 0 0 TEXT_VILE13 +MT_HLSPWN BlackJade BLKJD 0 400 AI_LAZHELP 3 30 50 76 0 0 0 TEXT_VILE13 +MT_RBLACK Lachdanan BHKA 14 500 AI_LACHDAN 3 0 0 0 0 0 0 TEXT_VEIL9 +MT_BTBLACK Warlord of Blood GENERAL 13 850 AI_WARLORD 3 35 50 120 0 0 0 TEXT_WARLRD9 +MT_CLEAVER The Butcher GENRL 0 220 AI_CLEAVER 3 6 12 70 0 0 0 0 +MT_TSKELAX Bonehead Keenaxe BHKA 2 91 AI_SKELSD 2 4 10 72 7 100 0 0 +MT_RFALLSD Bladeskin the Slasher BSTS 2 51 AI_FALLEN 0 6 18 2 11 45 0 0 +MT_NZOMBIE Soulpus GENERAL 2 133 AI_ZOMBIE 0 4 8 6 0 0 0 0 +MT_RFALLSP Pukerat the Unclean PTU 2 77 AI_FALLEN 3 1 5 2 0 0 0 0 +MT_WSKELAX Boneripper BR 2 54 AI_BAT 0 6 15 88 3 0 0 0 +MT_NZOMBIE Rotfeast the Hungry ETH 2 85 AI_SKELSD 3 4 12 72 3 0 0 0 +MT_DFALLSD Gutshank the Quick GTQ 3 66 AI_BAT 2 6 16 2 3 0 0 0 +MT_TSKELSD Brokenhead Bangshield BHBS 3 108 AI_SKELSD 3 12 20 76 3 0 0 0 +MT_YFALLSP Bongo BNG 3 178 AI_FALLEN 3 9 21 0 3 0 0 0 +MT_BZOMBIE Rotcarnage RCRN 3 102 AI_ZOMBIE 3 9 24 76 11 45 0 0 +MT_NSCAV Shadowbite SHBT 2 60 AI_SKELSD 3 3 20 16 3 0 0 0 +MT_WSKELBW Deadeye DE 2 49 AI_GOATBOW 0 6 9 74 0 0 0 0 +MT_RSKELAX Madeye the Dead MTD 4 75 AI_BAT 0 9 21 24 11 30 0 0 +MT_BSCAV El Chupacabras GENERAL 3 120 AI_GOATMC 0 10 18 2 3 30 0 0 +MT_TSKELBW Skullfire SKFR 3 125 AI_GOATBOW 1 6 10 16 0 100 0 0 +MT_SNEAK Warpskull TSPO 3 117 AI_SNEAK 2 6 18 6 3 0 0 0 +MT_GZOMBIE Goretongue PMR 3 156 AI_SKELSD 1 15 30 72 0 0 0 0 +MT_WSCAV Pulsecrawler BHKA 4 150 AI_SCAV 0 16 20 20 11 45 0 0 +MT_BLINK Moonbender GENERAL 4 135 AI_BAT 0 9 27 16 3 0 0 0 +MT_BLINK Wrathraven GENERAL 5 135 AI_BAT 2 9 22 16 3 0 0 0 +MT_YSCAV Spineeater GENERAL 4 180 AI_SCAV 1 18 25 96 3 0 0 0 +MT_RSKELBW Blackash the Burning BASHTB 4 120 AI_GOATBOW 0 6 16 24 3 0 0 0 +MT_BFALLSD Shadowcrow GENERAL 5 270 AI_SNEAK 2 12 25 0 3 0 0 0 +MT_LRDSAYTR Blightstone the Weak BHKA 4 360 AI_SKELSD 0 4 12 12 7 70 0 0 +MT_FAT Bilefroth the Pit Master BFTP 6 210 AI_BAT 1 16 23 28 3 0 0 0 +MT_NGOATBW Bloodskin Darkbow BSDB 5 207 AI_GOATBOW 0 3 16 6 11 55 0 0 +MT_GLOOM Foulwing DB 5 246 AI_RHINO 3 12 28 2 3 0 0 0 +MT_XSKELSD Shadowdrinker SHDR 5 300 AI_SNEAK 1 18 26 78 8 45 0 0 +MT_UNSEEN Hazeshifter BHKA 5 285 AI_SNEAK 3 18 30 96 3 0 0 0 +MT_NACID Deathspit BFDS 6 303 AI_ACIDUNIQ 0 12 32 6 3 0 0 0 +MT_RGOATMC Bloodgutter BGBL 6 315 AI_BAT 1 24 34 16 3 0 0 0 +MT_BGOATMC Deathshade Fleshmaul DSFM 6 276 AI_RHINO 0 12 24 10 8 65 0 0 +MT_WYRM Warmaggot the Mad GENERAL 6 246 AI_BAT 3 15 30 4 3 0 0 0 +MT_STORM Glasskull the Jagged BHKA 7 354 AI_STORM 0 18 30 88 3 0 0 0 +MT_RGOATBW Blightfire BLF 7 321 AI_SUCC 2 13 21 16 3 0 0 0 +MT_GARGOYLE Nightwing the Cold GENERAL 7 342 AI_BAT 1 18 26 76 3 0 0 0 +MT_GGOATBW Gorestone GENERAL 7 303 AI_GOATBOW 1 15 28 68 7 70 0 0 +MT_BMAGMA Bronzefist Firestone GENERAL 8 360 AI_MAGMA 0 30 36 10 3 0 0 0 +MT_INCIN Wrathfire the Doomed WFTD 8 270 AI_SKELSD 2 20 30 14 3 0 0 0 +MT_NMAGMA Firewound the Grim BHKA 8 303 AI_MAGMA 0 18 22 10 3 0 0 0 +MT_MUDMAN Baron Sludge BSM 8 315 AI_SNEAK 3 25 34 78 11 75 0 0 +MT_GGOATMC Blighthorn Steelmace BHSM 7 250 AI_RHINO 0 20 28 4 11 45 0 0 +MT_RACID Chaoshowler GENERAL 8 240 AI_ACIDUNIQ 0 12 20 0 3 0 0 0 +MT_REDDTH Doomgrin the Rotting GENERAL 8 405 AI_STORM 3 25 50 78 3 0 0 0 +MT_FLAMLRD Madburner GENERAL 9 270 AI_STORM 0 20 40 56 3 0 0 0 +MT_LTCHDMN Bonesaw the Litch GENERAL 9 495 AI_STORM 2 30 55 78 3 0 0 0 +MT_MUDRUN Breakspine GENERAL 9 351 AI_RHINO 0 25 34 2 3 0 0 0 +MT_REDDTH Devilskull Sharpbone GENERAL 9 444 AI_STORM 1 25 40 16 3 0 0 0 +MT_STORM Brokenstorm GENERAL 9 411 AI_STORM 2 25 36 32 3 0 0 0 +MT_RSTORM Stormbane GENERAL 9 555 AI_STORM 3 30 30 32 3 0 0 0 +MT_TOAD Oozedrool GENERAL 9 483 AI_FAT 3 25 30 4 3 0 0 0 +MT_BLOODCLW Goldblight of the Flame GENERAL 10 405 AI_GARG 0 15 35 24 11 80 0 0 +MT_OBLORD Blackstorm GENERAL 10 525 AI_RHINO 3 20 40 40 11 90 0 0 +MT_RACID Plaguewrath GENERAL 10 450 AI_ACIDUNIQ 2 20 30 74 3 0 0 0 +MT_RSTORM The Flayer GENERAL 10 501 AI_STORM 1 20 35 99 3 0 0 0 +MT_FROSTC Bluehorn GENERAL 11 477 AI_RHINO 1 25 30 10 11 90 0 0 +MT_HELLBURN Warpfire Hellspawn GENERAL 11 525 AI_FIREMAN 3 10 40 17 3 0 0 0 +MT_NSNAKE Fangspeir GENERAL 11 444 AI_SKELSD 1 15 32 80 3 0 0 0 +MT_UDEDBLRG Festerskull GENERAL 11 600 AI_STORM 2 15 30 72 3 0 0 0 +MT_NBLACK Lionskull the Bent GENERAL 12 525 AI_SKELSD 2 25 25 120 3 0 0 0 +MT_COUNSLR Blacktongue GENERAL 12 360 AI_COUNSLR 3 15 30 66 3 0 0 0 +MT_DEATHW Viletouch GENERAL 12 525 AI_GARG 3 20 40 96 3 0 0 0 +MT_RSNAKE Viperflame GENERAL 12 570 AI_SKELSD 1 25 35 20 3 0 0 0 +MT_BSNAKE Fangskin BHKA 14 681 AI_SKELSD 2 15 50 12 3 0 0 0 +MT_SUCCUBUS Witchfire the Unholy GENERAL 12 444 AI_SUCC 3 10 20 28 3 0 0 0 +MT_BALROG Blackskull BHKA 13 750 AI_SKELSD 3 25 40 12 3 0 0 0 +MT_UNRAV Soulslash GENERAL 12 450 AI_SKELSD 0 25 25 72 3 0 0 0 +MT_VTEXLRD Windspawn GENERAL 12 711 AI_SKELSD 1 35 40 24 3 0 0 0 +MT_GSNAKE Lord of the Pit GENERAL 13 762 AI_SKELSD 2 25 42 66 3 0 0 0 +MT_RTBLACK Rustweaver GENERAL 13 400 AI_SKELSD 3 1 60 120 0 0 0 0 +MT_HOLOWONE Howlingire the Shade GENERAL 13 450 AI_SKELSD 2 40 75 6 3 0 0 0 +MT_MAEL Doomcloud GENERAL 13 612 AI_STORM 1 1 60 34 0 0 0 0 +MT_PAINMSTR Bloodmoon Soulfire GENERAL 13 684 AI_SKELSD 1 15 40 14 3 0 0 0 +MT_SNOWWICH Witchmoon GENERAL 13 310 AI_SUCC 3 30 40 4 0 0 0 0 +MT_VTEXLRD Gorefeast GENERAL 13 771 AI_SKELSD 3 20 55 66 0 0 0 0 +MT_RTBLACK Graywar the Slayer GENERAL 14 672 AI_SKELSD 1 30 50 68 0 0 0 0 +MT_MAGISTR Dreadjudge GENERAL 14 540 AI_COUNSLR 1 30 40 14 3 0 0 0 +MT_HLSPWN Stareye the Witch GENERAL 14 726 AI_SUCC 2 30 50 16 0 0 0 0 +MT_BTBLACK Steelskull the Hunter GENERAL 14 831 AI_SKELSD 3 40 50 68 0 0 0 0 +MT_RBLACK Sir Gorash GENERAL 16 1050 AI_SKELSD 1 20 60 64 0 0 0 0 +MT_CABALIST The Vizier GENERAL 15 850 AI_COUNSLR 2 25 40 16 3 0 0 0 +MT_REALWEAV Zamphir GENERAL 15 891 AI_SKELSD 2 30 50 78 3 0 0 0 +MT_HLSPWN Bloodlust GENERAL 15 825 AI_SUCC 1 20 55 104 0 0 0 0 +MT_HLSPWN Webwidow GENERAL 16 774 AI_SUCC 1 20 50 88 0 0 0 0 +MT_SOLBRNR Fleshdancer GENERAL 16 999 AI_SUCC 3 30 50 74 0 0 0 0 +MT_OBLORD Grimspike GENERAL 19 534 AI_SNEAK 1 25 40 74 3 0 0 0 +MT_STORML Doomlock GENERAL 28 534 AI_SNEAK 1 35 55 78 3 0 0 0 +-1 NULL NULL 0 0 0 0 0 0 0 0 0 0 0 diff --git a/2020_03_31/Source/Data/Text/Gossip/adria.txt b/2020_03_31/Source/Data/Text/Gossip/adria.txt new file mode 100644 index 00000000..91fb2581 --- /dev/null +++ b/2020_03_31/Source/Data/Text/Gossip/adria.txt @@ -0,0 +1,71 @@ +[TEXT_ADRIA1] +"I sense a soul in search of answers... |" +0 +5 +TSFX_WITCH38 + +[TEXT_ADRIA2] +"Wisdom is earned, not given. If you discover a tome of knowledge, devour its words. Should you already have knowledge of the arcane mysteries scribed within a book, remember - that level of mastery can always increase. |" +1 +5 +TSFX_WITCH39 + +[TEXT_ADRIA3] +"The greatest power is often the shortest lived. You may find ancient words of power written upon scrolls of parchment. The strength of these scrolls lies in the ability of either apprentice or adept to cast them with equal ability. Their weakness is that they must first be read aloud and can never be kept at the ready in your mind. Know also that these scrolls can be read but once, so use them with care. |" +1 +5 +TSFX_WITCH40 + +[TEXT_ADRIA4] +"Though the heat of the sun is beyond measure, the mere flame of a candle is of greater danger. No energies, no matter how great, can be used without the proper focus. For many spells, ensorcelled Staves may be charged with magical energies many times over. I have the ability to restore their power - but know that nothing is done without a price. |" +1 +5 +TSFX_WITCH41 + +[TEXT_ADRIA5] +"The sum of our knowledge is in the sum of its people. Should you find a book or scroll that you cannot decipher, do not hesitate to bring it to me. If I can make sense of it I will share what I find. |" +1 +5 +TSFX_WITCH42 + +[TEXT_ADRIA6] +"To a man who only knows Iron, there is no greater magic than Steel. The blacksmith Griswold is more of a sorcerer than he knows. His ability to meld fire and metal is unequaled in this land. |" +1 +5 +TSFX_WITCH43 + +[TEXT_ADRIA7] +"Corruption has the strength of deceit, but innocence holds the power of purity. The young woman Gillian has a pure heart, placing the needs of her matriarch over her own. She fears me, but it is only because she does not understand me. |" +1 +5 +TSFX_WITCH44 + +[TEXT_ADRIA8] +"A chest opened in darkness holds no greater treasure than when it is opened in the light. The storyteller Cain is an enigma, but only to those who do not look. His knowledge of what lies beneath the cathedral is far greater than even he allows himself to realize. |" +1 +5 +TSFX_WITCH45 + +[TEXT_ADRIA9] +"The higher you place your faith in one man, the farther it has to fall. Farnham has lost his soul, but not to any demon. It was lost when he saw his fellow townspeople betrayed by the Archbishop Lazarus. He has knowledge to be gleaned, but you must separate fact from fantasy. |" +1 +5 +TSFX_WITCH46 + +[TEXT_ADRIA10] +"The hand, the heart and the mind can perform miracles when they are in perfect harmony. The healer Pepin sees into the body in a way that even I cannot. His ability to restore the sick and injured is magnified by his understanding of the creation of elixirs and potions. He is as great an ally as you have in Tristram. |" +1 +5 +TSFX_WITCH47 + +[TEXT_ADRIA12] +"There is much about the future we cannot see, but when it comes it will be the children who wield it. The boy Wirt has a blackness upon his soul, but he poses no threat to the town or its people. His secretive dealings with the urchins and unspoken guilds of nearby towns gain him access to many devices that cannot be easily found in Tristram. While his methods may be reproachful, Wirt can provide assistance for your battle against the encroaching Darkness. |" +1 +4 +TSFX_WITCH49 + +[TEXT_ADRIA13] +"Earthen walls and thatched canopy do not a home create. The innkeeper Ogden serves more of a purpose in this town than many understand. He provides shelter for Gillian and her matriarch, maintains what life Farnham has left to him, and provides an anchor for all who are left in the town to what Tristram once was. His tavern, and the simple pleasures that can still be found there, provide a glimpse of a life that the people here remember. It is that memory that continues to feed their hopes for your success. |" +1 +4 +TSFX_WITCH50 diff --git a/2020_03_31/Source/Data/Text/Gossip/farnham.txt b/2020_03_31/Source/Data/Text/Gossip/farnham.txt new file mode 100644 index 00000000..ca73bd7d --- /dev/null +++ b/2020_03_31/Source/Data/Text/Gossip/farnham.txt @@ -0,0 +1,71 @@ +[TEXT_FARNHAM1] +"Can't a fella drink in peace? |" +0 +5 +TSFX_DRUNK27 + +[TEXT_FARNHAM2] +"The gal who brings the drinks? Oh, yeah, what a pretty lady. So nice, too. |" +1 +6 +TSFX_DRUNK28 + +[TEXT_FARNHAM3] +"Why don't that old crone do somethin' for a change. Sure, sure, she's got stuff, but you listen to me... she's unnatural. I ain't never seen her eat or drink - and you can't trust somebody who doesn't drink at least a little. |" +1 +5 +TSFX_DRUNK29 + +[TEXT_FARNHAM4] +"Cain isn't what he says he is. Sure, sure, he talks a good story... some of 'em are real scary or funny... but I think he knows more than he knows he knows. |" +1 +5 +TSFX_DRUNK30 + +[TEXT_FARNHAM5] +"Griswold? Good old Griswold. I love him like a brother! We fought together, you know, back when... we... Lazarus... Lazarus... Lazarus!!! |" +1 +5 +TSFX_DRUNK31 + +[TEXT_FARNHAM6] +"Hehehe, I like Pepin. He really tries, you know. Listen here, you should make sure you get to know him. Good fella like that with people always wantin' help. Hey, I guess that would be kinda like you, huh hero? I was a hero too... |" +1 +5 +TSFX_DRUNK32 + +[TEXT_FARNHAM8] +"Wirt is a kid with more problems than even me, and I know all about problems. Listen here - that kid is gotta sweet deal, but he's been there, you know? Lost a leg! Gotta walk around on a piece of wood. So sad, so sad... |" +1 +5 +TSFX_DRUNK34 + +[TEXT_FARNHAM9] +"Ogden is the best man in town. I don't think his wife likes me much, but as long as she keeps tappin' kegs, I'll like her just fine. Seems like I been spendin' more time with Ogden than most, but he's so good to me... |" +1 +5 +TSFX_DRUNK35 + +[TEXT_FARNHAM10] +"I wanna tell ya sumthin', 'cause I know all about this stuff. It's my specialty. This here is the best... theeeee best! That other ale ain't no good since those stupid dogs... |" +1 +5 +TSFX_DRUNK23 + +[TEXT_FARNHAM11] +"No one ever lis... listens to me. Somewhere - I ain't too sure - but somewhere under the church is a whole pile o' gold. Gleamin' and shinin' and just waitin' for someone to get it. |" +1 +5 +TSFX_DRUNK24 + +[TEXT_FARNHAM12] +"I know you gots your own ideas, and I know you're not gonna believe this, but that weapon you got there - it just ain't no good against those big brutes! Oh, I don't care what Griswold says, they can't make anything like they used to in the old days... |" +1 +5 +TSFX_DRUNK25 + +[TEXT_FARNHAM13] +"If I was you... and I ain't... but if I was, I'd sell all that stuff you got and get out of here. That boy out there... He's always got somethin good, but you gotta give him some gold or he won't even show you what he's got. |" +1 +5 +TSFX_DRUNK26 diff --git a/2020_03_31/Source/Data/Text/Gossip/gillian.txt b/2020_03_31/Source/Data/Text/Gossip/gillian.txt new file mode 100644 index 00000000..2841633e --- /dev/null +++ b/2020_03_31/Source/Data/Text/Gossip/gillian.txt @@ -0,0 +1,53 @@ +[TEXT_GILLIAN1] +"Good day! How may I serve you? |" +0 +5 +TSFX_BMAID31 + +[TEXT_GILLIAN2] +"My grandmother had a dream that you would come and talk to me. She has visions, you know and can see into the future. |" +1 +6 +TSFX_BMAID32 + +[TEXT_GILLIAN3] +"The woman at the edge of town is a witch! She seems nice enough, and her name, Adria, is very pleasing to the ear, but I am very afraid of her. \n \nIt would take someone quite brave, like you, to see what she is doing out there. |" +1 +6 +TSFX_BMAID33 + +[TEXT_GILLIAN4] +"Our Blacksmith is a point of pride to the people of Tristram. Not only is he a master craftsman who has won many contests within his guild, but he received praises from our King Leoric himself - may his soul rest in peace. Griswold is also a great hero; just ask Cain. |" +1 +5 +TSFX_BMAID34 + +[TEXT_GILLIAN5] +"Cain has been the storyteller of Tristram for as long as I can remember. He knows so much, and can tell you just about anything about almost everything. |" +1 +6 +TSFX_BMAID35 + +[TEXT_GILLIAN6] +"Farnham is a drunkard who fills his belly with ale and everyone else's ears with nonsense. \n \nI know that both Pepin and Ogden feel sympathy for him, but I get so frustrated watching him slip farther and farther into a befuddled stupor every night. |" +1 +6 +TSFX_BMAID36 + +[TEXT_GILLIAN7] +"Pepin saved my grandmother's life, and I know that I can never repay him for that. His ability to heal any sickness is more powerful than the mightiest sword and more mysterious than any spell you can name. If you ever are in need of healing, Pepin can help you. |" +1 +5 +TSFX_BMAID37 + +[TEXT_GILLIAN9] +"I grew up with Wirt's mother, Canace. Although she was only slightly hurt when those hideous creatures stole him, she never recovered. I think she died of a broken heart. Wirt has become a mean-spirited youngster, looking only to profit from the sweat of others. I know that he suffered and has seen horrors that I cannot even imagine, but some of that darkness hangs over him still. |" +1 +5 +TSFX_BMAID39 + +[TEXT_GILLIAN10] +"Ogden and his wife have taken me and my grandmother into their home and have even let me earn a few gold pieces by working at the inn. I owe so much to them, and hope one day to leave this place and help them start a grand hotel in the east. |" +1 +5 +TSFX_BMAID40 diff --git a/2020_03_31/Source/Data/Text/Gossip/griswold.txt b/2020_03_31/Source/Data/Text/Gossip/griswold.txt new file mode 100644 index 00000000..fe516057 --- /dev/null +++ b/2020_03_31/Source/Data/Text/Gossip/griswold.txt @@ -0,0 +1,71 @@ +[TEXT_GRISWOLD1] +"Well, what can I do for ya? |" +0 +5 +TSFX_SMITH44 + +[TEXT_GRISWOLD2] +"If you're looking for a good weapon, let me show this to you. Take your basic blunt weapon, such as a mace. Works like a charm against most of those undying horrors down there, and there's nothing better to shatter skinny little skeletons! |" +1 +5 +TSFX_SMITH45 + +[TEXT_GRISWOLD3] +"The axe? Aye, that's a good weapon, balanced against any foe. Look how it cleaves the air, and then imagine a nice fat demon head in its path. Keep in mind, however, that it is slow to swing - but talk about dealing a heavy blow! |" +1 +5 +TSFX_SMITH46 + +[TEXT_GRISWOLD4] +"Look at that edge, that balance. A sword in the right hands, and against the right foe, is the master of all weapons. Its keen blade finds little to hack or pierce on the undead, but against a living, breathing enemy, a sword will better slice their flesh! |" +1 +5 +TSFX_SMITH47 + +[TEXT_GRISWOLD5] +"Your weapons and armor will show the signs of your struggles against the Darkness. If you bring them to me, with a bit of work and a hot forge, I can restore them to top fighting form. |" +1 +6 +TSFX_SMITH48 + +[TEXT_GRISWOLD6] +"While I have to practically smuggle in the metals and tools I need from caravans that skirt the edges of our damned town, that witch, Adria, always seems to get whatever she needs. If I knew even the smallest bit about how to harness magic as she did, I could make some truly incredible things. |" +1 +5 +TSFX_SMITH49 + +[TEXT_GRISWOLD7] +"Gillian is a nice lass. Shame that her gammer is in such poor health or I would arrange to get both of them out of here on one of the trading caravans. |" +1 +6 +TSFX_SMITH50 + +[TEXT_GRISWOLD8] +"Sometimes I think that Cain talks too much, but I guess that is his calling in life. If I could bend steel as well as he can bend your ear, I could make a suit of court plate good enough for an Emperor! |" +1 +5 +TSFX_SMITH51 + +[TEXT_GRISWOLD9] +"I was with Farnham that night that Lazarus led us into Labyrinth. I never saw the Archbishop again, and I may not have survived if Farnham was not at my side. I fear that the attack left his soul as crippled as, well, another did my leg. I cannot fight this battle for him now, but I would if I could. |" +1 +5 +TSFX_SMITH52 + +[TEXT_GRISWOLD10] +"A good man who puts the needs of others above his own. You won't find anyone left in Tristram - or anywhere else for that matter - who has a bad thing to say about the healer. |" +1 +6 +TSFX_SMITH53 + +[TEXT_GRISWOLD12] +"That lad is going to get himself into serious trouble... or I guess I should say, again. I've tried to interest him in working here and learning an honest trade, but he prefers the high profits of dealing in goods of dubious origin. I cannot hold that against him after what happened to him, but I do wish he would at least be careful. |" +1 +5 +TSFX_SMITH55 + +[TEXT_GRISWOLD13] +"The Innkeeper has little business and no real way of turning a profit. He manages to make ends meet by providing food and lodging for those who occasionally drift through the village, but they are as likely to sneak off into the night as they are to pay him. If it weren't for the stores of grains and dried meats he kept in his cellar, why, most of us would have starved during that first year when the entire countryside was overrun by demons. |" +1 +5 +TSFX_SMITH56 diff --git a/2020_03_31/Source/Data/Text/Gossip/ogden.txt b/2020_03_31/Source/Data/Text/Gossip/ogden.txt new file mode 100644 index 00000000..f339e70b --- /dev/null +++ b/2020_03_31/Source/Data/Text/Gossip/ogden.txt @@ -0,0 +1,53 @@ +[TEXT_OGDEN1] +"Greetings, good master. Welcome to the Tavern of the Rising Sun! |" +0 +5 +TSFX_TAVERN36 + +[TEXT_OGDEN2] +"Many adventurers have graced the tables of my tavern, and ten times as many stories have been told over as much ale. The only thing that I ever heard any of them agree on was this old axiom. Perhaps it will help you. You can cut the flesh, but you must crush the bone. |" +1 +5 +TSFX_TAVERN37 + +[TEXT_OGDEN3] +"Griswold the blacksmith is extremely knowledgeable about weapons and armor. If you ever need work done on your gear, he is definitely the man to see. |" +1 +6 +TSFX_TAVERN38 + +[TEXT_OGDEN4] +"Farnham spends far too much time here, drowning his sorrows in cheap ale. I would make him leave, but he did suffer so during his time in the Labyrinth. |" +1 +6 +TSFX_TAVERN39 + +[TEXT_OGDEN5] +"Adria is wise beyond her years, but I must admit - she frightens me a little. \n \nWell, no matter. If you ever have need to trade in items of sorcery, she maintains a strangely well-stocked hut just across the river. |" +1 +6 +TSFX_TAVERN40 + +[TEXT_OGDEN6] +"If you want to know more about the history of our village, the storyteller Cain knows quite a bit about the past. |" +1 +6 +TSFX_TAVERN41 + +[TEXT_OGDEN8] +"Wirt is a rapscallion and a little scoundrel. He was always getting into trouble, and it's no surprise what happened to him. \n \nHe probably went fooling about someplace that he shouldn't have been. I feel sorry for the boy, but I don't abide the company that he keeps. |" +1 +6 +TSFX_TAVERN43 + +[TEXT_OGDEN9] +"Pepin is a good man - and certainly the most generous in the village. He is always attending to the needs of others, but trouble of some sort or another does seem to follow him wherever he goes... |" +1 +6 +TSFX_TAVERN44 + +[TEXT_OGDEN10] +"Gillian, my Barmaid? If it were not for her sense of duty to her grand-dam, she would have fled from here long ago. \n \nGoodness knows I begged her to leave, telling her that I would watch after the old woman, but she is too sweet and caring to have done so. |" +1 +6 +TSFX_TAVERN45 diff --git a/2020_03_31/Source/Data/Text/Gossip/pepin.txt b/2020_03_31/Source/Data/Text/Gossip/pepin.txt new file mode 100644 index 00000000..8eacaba2 --- /dev/null +++ b/2020_03_31/Source/Data/Text/Gossip/pepin.txt @@ -0,0 +1,59 @@ +[TEXT_PEPIN1] +"What ails you, my friend? |" +0 +5 +TSFX_HEALER37 + +[TEXT_PEPIN2] +"I have made a very interesting discovery. Unlike us, the creatures in the Labyrinth can heal themselves without the aid of potions or magic. If you hurt one of the monsters, make sure it is dead or it very well may regenerate itself. |" +1 +5 +TSFX_HEALER38 + +[TEXT_PEPIN3] +"Before it was taken over by, well, whatever lurks below, the Cathedral was a place of great learning. There are many books to be found there. If you find any, you should read them all, for some may hold secrets to the workings of the Labyrinth. |" +1 +5 +TSFX_HEALER39 + +[TEXT_PEPIN4] +"Griswold knows as much about the art of war as I do about the art of healing. He is a shrewd merchant, but his work is second to none. Oh, I suppose that may be because he is the only blacksmith left here. |" +1 +5 +TSFX_HEALER40 + +[TEXT_PEPIN5] +"Cain is a true friend and a wise sage. He maintains a vast library and has an innate ability to discern the true nature of many things. If you ever have any questions, he is the person to go to. |" +1 +5 +TSFX_HEALER41 + +[TEXT_PEPIN6] +"Even my skills have been unable to fully heal Farnham. Oh, I have been able to mend his body, but his mind and spirit are beyond anything I can do. |" +1 +5 +TSFX_HEALER42 + +[TEXT_PEPIN7] +"While I use some limited forms of magic to create the potions and elixirs I store here, Adria is a true sorceress. She never seems to sleep, and she always has access to many mystic tomes and artifacts. I believe her hut may be much more than the hovel it appears to be, but I can never seem to get inside the place. |" +1 +5 +TSFX_HEALER43 + +[TEXT_PEPIN9] +"Poor Wirt. I did all that was possible for the child, but I know he despises that wooden peg that I was forced to attach to his leg. His wounds were hideous. No one - and especially such a young child - should have to suffer the way he did. |" +1 +5 +TSFX_HEALER45 + +[TEXT_PEPIN10] +"I really don't understand why Ogden stays here in Tristram. He suffers from a slight nervous condition, but he is an intelligent and industrious man who would do very well wherever he went. I suppose it may be the fear of the many murders that happen in the surrounding countryside, or perhaps the wishes of his wife that keep him and his family where they are. |" +1 +5 +TSFX_HEALER46 + +[TEXT_PEPIN11] +"Ogden's barmaid is a sweet girl. Her grandmother is quite ill, and suffers from delusions. \n \nShe claims that they are visions, but I have no proof of that one way or the other. |" +1 +6 +TSFX_HEALER47 diff --git a/2020_03_31/Source/Data/Text/Gossip/story.txt b/2020_03_31/Source/Data/Text/Gossip/story.txt new file mode 100644 index 00000000..35dcb302 --- /dev/null +++ b/2020_03_31/Source/Data/Text/Gossip/story.txt @@ -0,0 +1,59 @@ +[TEXT_STORY1] +"Hello, my friend. Stay awhile and listen... |" +0 +5 +TSFX_STORY25 + +[TEXT_STORY2] +"While you are venturing deeper into the Labyrinth you may find tomes of great knowledge hidden there. \n \nRead them carefully for they can tell you things that even I cannot. |" +1 +6 +TSFX_STORY26 + +[TEXT_STORY3] +"I know of many myths and legends that may contain answers to questions that may arise in your journeys into the Labyrinth. If you come across challenges and questions to which you seek knowledge, seek me out and I will tell you what I can. |" +1 +5 +TSFX_STORY27 + +[TEXT_STORY4] +"Griswold - a man of great action and great courage. I bet he never told you about the time he went into the Labyrinth to save Wirt, did he? He knows his fair share of the dangers to be found there, but then again - so do you. He is a skilled craftsman, and if he claims to be able to help you in any way, you can count on his honesty and his skill. |" +1 +5 +TSFX_STORY28 + +[TEXT_STORY5] +"Ogden has owned and run the Rising Sun Inn and Tavern for almost four years now. He purchased it just a few short months before everything here went to hell. He and his wife Garda do not have the money to leave as they invested all they had in making a life for themselves here. He is a good man with a deep sense of responsibility. |" +1 +5 +TSFX_STORY29 + +[TEXT_STORY6] +"Poor Farnham. He is a disquieting reminder of the doomed assembly that entered into the Cathedral with Lazarus on that dark day. He escaped with his life, but his courage and much of his sanity were left in some dark pit. He finds comfort only at the bottom of his tankard nowadays, but there are occasional bits of truth buried within his constant ramblings. |" +1 +5 +TSFX_STORY30 + +[TEXT_STORY7] +"The witch, Adria, is an anomaly here in Tristram. She arrived shortly after the Cathedral was desecrated while most everyone else was fleeing. She had a small hut constructed at the edge of town, seemingly overnight, and has access to many strange and arcane artifacts and tomes of knowledge that even I have never seen before. |" +1 +5 +TSFX_STORY31 + +[TEXT_STORY9] +"The story of Wirt is a frightening and tragic one. He was taken from the arms of his mother and dragged into the labyrinth by the small, foul demons that wield wicked spears. There were many other children taken that day, including the son of King Leoric. The Knights of the palace went below, but never returned. The Blacksmith found the boy, but only after the foul beasts had begun to torture him for their sadistic pleasures. |" +1 +5 +TSFX_STORY33 + +[TEXT_STORY10] +"Ah, Pepin. I count him as a true friend - perhaps the closest I have here. He is a bit addled at times, but never a more caring or considerate soul has existed. His knowledge and skills are equaled by few, and his door is always open. |" +1 +5 +TSFX_STORY34 + +[TEXT_STORY11] +"Gillian is a fine woman. Much adored for her high spirits and her quick laugh, she holds a special place in my heart. She stays on at the tavern to support her elderly grandmother who is too sick to travel. I sometimes fear for her safety, but I know that any man in the village would rather die than see her harmed. |" +1 +5 +TSFX_STORY35 diff --git a/2020_03_31/Source/Data/Text/Gossip/wirt.txt b/2020_03_31/Source/Data/Text/Gossip/wirt.txt new file mode 100644 index 00000000..d6e35f22 --- /dev/null +++ b/2020_03_31/Source/Data/Text/Gossip/wirt.txt @@ -0,0 +1,65 @@ +[TEXT_WIRT1] +"Pssst... over here... |" +0 +5 +TSFX_PEGBOY32 + +[TEXT_WIRT2] +"Not everyone in Tristram has a use - or a market - for everything you will find in the labyrinth. Not even me, as hard as that is to believe. \n \nSometimes, only you will be able to find a purpose for some things. |" +1 +6 +TSFX_PEGBOY33 + +[TEXT_WIRT3] +"Don't trust everything the drunk says. Too many ales have fogged his vision and his good sense. |" +1 +6 +TSFX_PEGBOY34 + +[TEXT_WIRT4] +"In case you haven't noticed, I don't buy anything from Tristram. I am an importer of quality goods. If you want to peddle junk, you'll have to see Griswold, Pepin or that witch, Adria. I'm sure that they will snap up whatever you can bring them... |" +1 +5 +TSFX_PEGBOY35 + +[TEXT_WIRT5] +"I guess I owe the blacksmith my life - what there is of it. Sure, Griswold offered me an apprenticeship at the smithy, and he is a nice enough guy, but I'll never get enough money to... well, let's just say that I have definite plans that require a large amount of gold. |" +1 +5 +TSFX_PEGBOY36 + +[TEXT_WIRT6] +"If I were a few years older, I would shower her with whatever riches I could muster, and let me assure you I can get my hands on some very nice stuff. Gillian is a beautiful girl who should get out of Tristram as soon as it is safe. Hmmm... maybe I'll take her with me when I go... |" +1 +5 +TSFX_PEGBOY37 + +[TEXT_WIRT7] +"Cain knows too much. He scares the life out of me - even more than that woman across the river. He keeps telling me about how lucky I am to be alive, and how my story is foretold in legend. I think he's off his crock. |" +1 +5 +TSFX_PEGBOY38 + +[TEXT_WIRT8] +"Farnham - now there is a man with serious problems, and I know all about how serious problems can be. He trusted too much in the integrity of one man, and Lazarus led him into the very jaws of death. Oh, I know what it's like down there, so don't even start telling me about your plans to destroy the evil that dwells in that Labyrinth. Just watch your legs... |" +1 +5 +TSFX_PEGBOY39 + +[TEXT_WIRT9] +"As long as you don't need anything reattached, old Pepin is as good as they come. \n \nIf I'd have had some of those potions he brews, I might still have my leg... |" +1 +6 +TSFX_PEGBOY40 + +[TEXT_WIRT11] +"Adria truly bothers me. Sure, Cain is creepy in what he can tell you about the past, but that witch can see into your past. She always has some way to get whatever she needs, too. Adria gets her hands on more merchandise than I've seen pass through the gates of the King's Bazaar during High Festival. |" +1 +5 +TSFX_PEGBOY42 + +[TEXT_WIRT12] +"Ogden is a fool for staying here. I could get him out of town for a very reasonable price, but he insists on trying to make a go of it with that stupid tavern. I guess at the least he gives Gillian a place to work, and his wife Garda does make a superb Shepherd's pie... |" +1 +5 +TSFX_PEGBOY43 diff --git a/2020_03_31/Source/Data/Text/Quest/anvil.txt b/2020_03_31/Source/Data/Text/Quest/anvil.txt new file mode 100644 index 00000000..1e46249d --- /dev/null +++ b/2020_03_31/Source/Data/Text/Quest/anvil.txt @@ -0,0 +1,59 @@ +[TEXT_ANVIL1] +"Griswold speaks of The Anvil of Fury - a legendary artifact long searched for, but never found. Crafted from the metallic bones of the Razor Pit demons, the Anvil of Fury was smelt around the skulls of the five most powerful magi of the underworld. Carved with runes of power and chaos, any weapon or armor forged upon this Anvil will be immersed into the realm of Chaos, imbedding it with magical properties. It is said that the unpredictable nature of Chaos makes it difficult to know what the outcome of this smithing will be... |" +1 +4 +TSFX_STORY14 + +[TEXT_ANVIL2] +"Don't you think that Griswold would be a better person to ask about this? He's quite handy, you know. |" +1 +7 +TSFX_TAVERN12 + +[TEXT_ANVIL3] +"If you had been looking for information on the Pestle of Curing or the Silver Chalice of Purification, I could have assisted you, my friend. However, in this matter, you would be better served to speak to either Griswold or Cain. |" +1 +6 +TSFX_HEALER12 + +[TEXT_ANVIL4] +"Griswold's father used to tell some of us when we were growing up about a giant anvil that was used to make mighty weapons. He said that when a hammer was struck upon this anvil, the ground would shake with a great fury. Whenever the earth moves, I always remember that story. |" +1 +5 +TSFX_BMAID12 + +[TEXT_ANVIL5] +"Greetings! It's always a pleasure to see one of my best customers! I know that you have been venturing deeper into the Labyrinth, and there is a story I was told that you may find worth the time to listen to...\n \nOne of the men who returned from the Labyrinth told me about a mystic anvil that he came across during his escape. His description reminded me of legends I had heard in my youth about the burning Hellforge where powerful weapons of magic are crafted. The legend had it that deep within the Hellforge rested the Anvil of Fury! This Anvil contained within it the very essence of the demonic underworld...\n \nIt is said that any weapon crafted upon the burning Anvil is imbued with great power. If this anvil is indeed the Anvil of Fury, I may be able to make you a weapon capable of defeating even the darkest lord of Hell! \n \nFind the Anvil for me, and I'll get to work! |" +1 +5 +TSFX_SMITH21 + +[TEXT_ANVIL6] +"Nothing yet, eh? Well, keep searching. A weapon forged upon the Anvil could be your best hope, and I am sure that I can make you one of legendary proportions. |" +1 +5 +TSFX_SMITH22 + +[TEXT_ANVIL7] +"I can hardly believe it! This is the Anvil of Fury - good work, my friend. Now we'll show those bastards that there are no weapons in Hell more deadly than those made by men! Take this and may Light protect you. |" +1 +5 +TSFX_SMITH23 + +[TEXT_ANVIL8] +"Griswold can't sell his anvil. What will he do then? And I'd be angry too if someone took my anvil! |" +1 +6 +TSFX_DRUNK14 + +[TEXT_ANVIL9] +"There are many artifacts within the Labyrinth that hold powers beyond the comprehension of mortals. Some of these hold fantastic power that can be used by either the Light or the Darkness. Securing the Anvil from below could shift the course of the Sin War towards the Light. |" +1 +5 +TSFX_WITCH14 + +[TEXT_ANVIL10] +"If you were to find this artifact for Griswold, it could put a serious damper on my business here. Awwww, you'll never find it. |" +1 +6 +TSFX_PEGBOY13 diff --git a/2020_03_31/Source/Data/Text/Quest/banner.txt b/2020_03_31/Source/Data/Text/Quest/banner.txt new file mode 100644 index 00000000..4917c005 --- /dev/null +++ b/2020_03_31/Source/Data/Text/Quest/banner.txt @@ -0,0 +1,71 @@ +[TEXT_BANNER1] +"I see that this strange behavior puzzles you as well. I would surmise that since many demons fear the light of the sun and believe that it holds great power, it may be that the rising sun depicted on the sign you speak of has led them to believe that it too holds some arcane powers. Hmm, perhaps they are not all as smart as we had feared... |" +1 +5 +TSFX_STORY2 + +[TEXT_BANNER2] +"Master, I have a strange experience to relate. I know that you have a great knowledge of those monstrosities that inhabit the labyrinth, and this is something that I cannot understand for the very life of me... I was awakened during the night by a scraping sound just outside of my tavern. When I looked out from my bedroom, I saw the shapes of small demon-like creatures in the inn yard. After a short time, they ran off, but not before stealing the sign to my inn. I don't know why the demons would steal my sign but leave my family in peace... 'tis strange, no? |" +1 +5 +TSFX_TAVERN24 + +[TEXT_BANNER3] +"Oh, you didn't have to bring back my sign, but I suppose that it does save me the expense of having another one made. Well, let me see, what could I give you as a fee for finding it? Hmmm, what have we here... ah, yes! This cap was left in one of the rooms by a magician who stayed here some time ago. Perhaps it may be of some value to you. |" +1 +5 +TSFX_TAVERN25 + +[TEXT_BANNER4] +"My goodness, demons running about the village at night, pillaging our homes - is nothing sacred? I hope that Ogden and Garda are all right. I suppose that they would come to see me if they were hurt... |" +1 +5 +TSFX_HEALER2 + +[TEXT_BANNER5] +"Oh my! Is that where the sign went? My Grandmother and I must have slept right through the whole thing. Thank the Light that those monsters didn't attack the inn. |" +1 +6 +TSFX_BMAID2 + +[TEXT_BANNER6] +"Demons stole Ogden's sign, you say? That doesn't sound much like the atrocities I've heard of - or seen. \n \nDemons are concerned with ripping out your heart, not your signpost. |" +1 +6 +TSFX_SMITH2 + +[TEXT_BANNER7] +"You know what I think? Somebody took that sign, and they gonna want lots of money for it. If I was Ogden... and I'm not, but if I was... I'd just buy a new sign with some pretty drawing on it. Maybe a nice mug of ale or a piece of cheese... |" +1 +5 +TSFX_DRUNK2 + +[TEXT_BANNER8] +"No mortal can truly understand the mind of the demon. \n \nNever let their erratic actions confuse you, as that too may be their plan. |" +1 +6 +TSFX_WITCH2 + +[TEXT_BANNER9] +"What - is he saying I took that? I suppose that Griswold is on his side, too. \n \nLook, I got over simple sign stealing months ago. You can't turn a profit on a piece of wood. |" +1 +6 +TSFX_PEGBOY2 + +[TEXT_BANNER10] +"Hey - You that one that kill all! You get me Magic Banner or we attack! You no leave with life! You kill big uglies and give back Magic. Go past corner and door, find uglies. You give, you go! |" +1 +5 +USFX_SNOT1 + +[TEXT_BANNER11] +"You kill uglies, get banner. You bring to me, or else... |" +1 +6 +USFX_SNOT2 + +[TEXT_BANNER12] +"You give! Yes, good! Go now, we strong. We kill all with big Magic! |" +1 +6 +USFX_SNOT3 diff --git a/2020_03_31/Source/Data/Text/Quest/blind.txt b/2020_03_31/Source/Data/Text/Quest/blind.txt new file mode 100644 index 00000000..0e09f84d --- /dev/null +++ b/2020_03_31/Source/Data/Text/Quest/blind.txt @@ -0,0 +1,47 @@ +[TEXT_BLIND1] +"You recite an interesting rhyme written in a style that reminds me of other works. Let me think now - what was it?\n \n...Darkness shrouds the Hidden. Eyes glowing unseen with only the sounds of razor claws briefly scraping to torment those poor souls who have been made sightless for all eternity. The prison for those so damned is named the Halls of the Blind... |" +1 +5 +TSFX_STORY12 + +[TEXT_BLIND2] +"I never much cared for poetry. Occasionally, I had cause to hire minstrels when the inn was doing well, but that seems like such a long time ago now. \n \nWhat? Oh, yes... uh, well, I suppose you could see what someone else knows. |" +1 +6 +TSFX_TAVERN10 + +[TEXT_BLIND3] +"This does seem familiar, somehow. I seem to recall reading something very much like that poem while researching the history of demonic afflictions. It spoke of a place of great evil that... wait - you're not going there are you? |" +1 +5 +TSFX_HEALER10 + +[TEXT_BLIND4] +"If you have questions about blindness, you should talk to Pepin. I know that he gave my grandmother a potion that helped clear her vision, so maybe he can help you, too. |" +1 +6 +TSFX_BMAID10 + +[TEXT_BLIND5] +"I am afraid that I have neither heard nor seen a place that matches your vivid description, my friend. Perhaps Cain the Storyteller could be of some help. |" +1 +6 +TSFX_SMITH12 + +[TEXT_BLIND6] +"Look here... that's pretty funny, huh? Get it? Blind - look here? |" +1 +6 +TSFX_DRUNK12 + +[TEXT_BLIND7] +"This is a place of great anguish and terror, and so serves its master well. \n \nTread carefully or you may yourself be staying much longer than you had anticipated. |" +1 +6 +TSFX_WITCH12 + +[TEXT_BLIND8] +"Lets see, am I selling you something? No. Are you giving me money to tell you about this? No. Are you now leaving and going to talk to the storyteller who lives for this kind of thing? Yes. |" +1 +5 +TSFX_PEGBOY11 diff --git a/2020_03_31/Source/Data/Text/Quest/blood.txt b/2020_03_31/Source/Data/Text/Quest/blood.txt new file mode 100644 index 00000000..7b8e30f5 --- /dev/null +++ b/2020_03_31/Source/Data/Text/Quest/blood.txt @@ -0,0 +1,47 @@ +[TEXT_BLOOD1] +"The Gateway of Blood and the Halls of Fire are landmarks of mystic origin. Wherever this book you read from resides it is surely a place of great power.\n \nLegends speak of a pedestal that is carved from obsidian stone and has a pool of boiling blood atop its bone encrusted surface. There are also allusions to Stones of Blood that will open a door that guards an ancient treasure...\n \nThe nature of this treasure is shrouded in speculation, my friend, but it is said that the ancient hero Arkaine placed the holy armor Valor in a secret vault. Arkaine was the first mortal to turn the tide of the Sin War and chase the legions of darkness back to the Burning Hells.\n \nJust before Arkaine died, his armor was hidden away in a secret vault. It is said that when this holy armor is again needed, a hero will arise to don Valor once more. Perhaps you are that hero... |" +1 +3 +TSFX_STORY15 + +[TEXT_BLOOD2] +"Every child hears the story of the warrior Arkaine and his mystic armor known as Valor. If you could find its resting place, you would be well protected against the evil in the Labyrinth. |" +1 +6 +TSFX_TAVERN13 + +[TEXT_BLOOD3] +"Hmm... it sounds like something I should remember, but I've been so busy learning new cures and creating better elixirs that I must have forgotten. Sorry... |" +1 +6 +TSFX_HEALER13 + +[TEXT_BLOOD4] +"The story of the magic armor called Valor is something I often heard the boys talk about. You had better ask one of the men in the village. |" +1 +6 +TSFX_BMAID13 + +[TEXT_BLOOD5] +"The armor known as Valor could be what tips the scales in your favor. I will tell you that many have looked for it - including myself. Arkaine hid it well, my friend, and it will take more than a bit of luck to unlock the secrets that have kept it concealed oh, lo these many years. |" +1 +5 +TSFX_SMITH14 + +[TEXT_BLOOD6] +"Zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz... |" +1 +7 +TSFX_DRUNK15 + +[TEXT_BLOOD7] +"Should you find these Stones of Blood, use them carefully. \n \nThe way is fraught with danger and your only hope rests within your self trust. |" +1 +6 +TSFX_WITCH15 + +[TEXT_BLOOD8] +"You intend to find the armor known as Valor? \n \nNo one has ever figured out where Arkaine stashed the stuff, and if my contacts couldn't find it, I seriously doubt you ever will either. |" +1 +6 +TSFX_PEGBOY14 diff --git a/2020_03_31/Source/Data/Text/Quest/bone.txt b/2020_03_31/Source/Data/Text/Quest/bone.txt new file mode 100644 index 00000000..f23d16aa --- /dev/null +++ b/2020_03_31/Source/Data/Text/Quest/bone.txt @@ -0,0 +1,47 @@ +[TEXT_BONE1] +"A book that speaks of a chamber of human bones? Well, a Chamber of Bone is mentioned in certain archaic writings that I studied in the libraries of the East. These tomes inferred that when the Lords of the underworld desired to protect great treasures, they would create domains where those who died in the attempt to steal that treasure would be forever bound to defend it. A twisted, but strangely fitting, end? |" +1 +4 +TSFX_STORY7 + +[TEXT_BONE2] +"I am afraid that I don't know anything about that, good master. Cain has many books that may be of some help. |" +1 +6 +TSFX_TAVERN5 + +[TEXT_BONE3] +"This sounds like a very dangerous place. If you venture there, please take great care. |" +1 +6 +TSFX_HEALER5 + +[TEXT_BONE4] +"I am afraid that I haven't heard anything about that. Perhaps Cain the Storyteller could be of some help. |" +1 +6 +TSFX_BMAID6 + +[TEXT_BONE5] +"I know nothing of this place, but you may try asking Cain. He talks about many things, and it would not surprise me if he had some answers to your question. |" +1 +6 +TSFX_SMITH7 + +[TEXT_BONE6] +"Okay, so listen. There's this chamber of wood, see. And his wife, you know - her - tells the tree... cause you gotta wait. Then I says, that might work against him, but if you think I'm gonna PAY for this... you... uh... yeah. |" +1 +5 +TSFX_DRUNK7 + +[TEXT_BONE7] +"You will become an eternal servant of the dark lords should you perish within this cursed domain. \n \nEnter the Chamber of Bone at your own peril. |" +1 +6 +TSFX_WITCH7 + +[TEXT_BONE8] +"A vast and mysterious treasure, you say? Maybe I could be interested in picking up a few things from you... or better yet, don't you need some rare and expensive supplies to get you through this ordeal? |" +1 +5 +TSFX_PEGBOY7 diff --git a/2020_03_31/Source/Data/Text/Quest/butch.txt b/2020_03_31/Source/Data/Text/Quest/butch.txt new file mode 100644 index 00000000..9652a1b1 --- /dev/null +++ b/2020_03_31/Source/Data/Text/Quest/butch.txt @@ -0,0 +1,59 @@ +[TEXT_BUTCH1] +"It seems that the Archbishop Lazarus goaded many of the townsmen into venturing into the Labyrinth to find the King's missing son. He played upon their fears and whipped them into a frenzied mob. None of them were prepared for what lay within the cold earth... Lazarus abandoned them down there - left in the clutches of unspeakable horrors - to die. |" +1 +5 +TSFX_STORY10 + +[TEXT_BUTCH2] +"Yes, Farnham has mumbled something about a hulking brute who wielded a fierce weapon. I believe he called him a butcher. |" +1 +6 +TSFX_TAVERN8 + +[TEXT_BUTCH3] +"By the Light, I know of this vile demon. There were many that bore the scars of his wrath upon their bodies when the few survivors of the charge led by Lazarus crawled from the Cathedral. I don't know what he used to slice open his victims, but it could not have been of this world. It left wounds festering with disease and even I found them almost impossible to treat. Beware if you plan to battle this fiend... |" +1 +5 +TSFX_HEALER8 + +[TEXT_BUTCH4] +"When Farnham said something about a butcher killing people, I immediately discounted it. But since you brought it up, maybe it is true. |" +1 +6 +TSFX_BMAID8 + +[TEXT_BUTCH5] +"I saw what Farnham calls the Butcher as it swathed a path through the bodies of my friends. He swung a cleaver as large as an axe, hewing limbs and cutting down brave men where they stood. I was separated from the fray by a host of small screeching demons and somehow found the stairway leading out. I never saw that hideous beast again, but his blood-stained visage haunts me to this day. |" +1 +5 +TSFX_SMITH10 + +[TEXT_BUTCH6] +"Big! Big cleaver killing all my friends. Couldn't stop him, had to run away, couldn't save them. Trapped in a room with so many bodies... so many friends... NOOOOOOOOOO! |" +1 +5 +TSFX_DRUNK10 + +[TEXT_BUTCH7] +"The Butcher is a sadistic creature that delights in the torture and pain of others. You have seen his handiwork in the drunkard Farnham. His destruction will do much to ensure the safety of this village. |" +1 +5 +TSFX_WITCH10 + +[TEXT_BUTCH8] +"I know more than you'd think about that grisly fiend. His little friends got a hold of me and managed to get my leg before Griswold pulled me out of that hole. \n \nI'll put it bluntly - kill him before he kills you and adds your corpse to his collection. |" +1 +6 +TSFX_PEGBOY10 + +[TEXT_BUTCH9] +"Please, listen to me. The Archbishop Lazarus, he led us down here to find the lost prince. The bastard led us into a trap! Now everyone is dead...killed by a demon he called the Butcher. Avenge us! Find this Butcher and slay him so that our souls may finally rest... |" +1 +5 +TSFX_WOUND + +[TEXT_BUTCH10] +" |" +1 +5 +USFX_CLEAVER diff --git a/2020_03_31/Source/Data/Text/Quest/doom.txt b/2020_03_31/Source/Data/Text/Quest/doom.txt new file mode 100644 index 00000000..16fe18ca --- /dev/null +++ b/2020_03_31/Source/Data/Text/Quest/doom.txt @@ -0,0 +1,59 @@ +[TEXT_DOOM1] +"So, the legend of the Map is real. Even I never truly believed any of it! I suppose it is time that I told you the truth about who I am, my friend. You see, I am not all that I seem...\n \nMy true name is Deckard Cain the Elder, and I am the last descendant of an ancient Brotherhood that was dedicated to keeping and safeguarding the secrets of a timeless evil. An evil that quite obviously has now been released...\n \nThe evil that you move against is the dark Lord of Terror - known to mortal men as Diablo. It was he who was imprisoned within the Labyrinth many centuries ago. The Map that you hold now was created ages ago to mark the time when Diablo would rise again from his imprisonment. When the two stars on that map align, Diablo will be at the height of his power. He will be all but invincible...\n \nYou are now in a race against time, my friend! Find Diablo and destroy him before the stars align, for we may never have a chance to rid the world of his evil again! |" +1 +2 +TSFX_STORY22 + +[TEXT_DOOM2] +"Our time is running short! I sense his dark power building and only you can stop him from attaining his full might. |" +1 +6 +TSFX_STORY23 + +[TEXT_DOOM3] +"I am sure that you tried your best, but I fear that even your strength and will may not be enough. Diablo is now at the height of his earthly power, and you will need all your courage and strength to defeat him. May the Light protect and guide you, my friend. I will help in any way that I am able. |" +1 +5 +TSFX_STORY24 + +[TEXT_DOOM4] +"If the witch can't help you and suggests you see Cain, what makes you think that I would know anything? It sounds like this is a very serious matter. You should hurry along and see the storyteller as Adria suggests. |" +1 +6 +TSFX_TAVERN20 + +[TEXT_DOOM5] +"I can't make much of the writing on this map, but perhaps Adria or Cain could help you decipher what this refers to. \n \nI can see that it is a map of the stars in our sky, but any more than that is beyond my talents. |" +1 +6 +TSFX_HEALER19 + +[TEXT_DOOM6] +"The best person to ask about that sort of thing would be our storyteller. \n \nCain is very knowledgeable about ancient writings, and that is easily the oldest looking piece of paper that I have ever seen. |" +1 +6 +TSFX_BMAID20 + +[TEXT_DOOM7] +"I have never seen a map of this sort before. Where'd you get it? Although I have no idea how to read this, Cain or Adria may be able to provide the answers that you seek. |" +1 +6 +TSFX_SMITH20 + +[TEXT_DOOM8] +"Listen here, come close. I don't know if you know what I know, but you have really got somethin' here. That's a map. |" +1 +5 +TSFX_DRUNK21 + +[TEXT_DOOM9] +"Oh, I'm afraid this does not bode well at all. This map of the stars portends great disaster, but its secrets are not mine to tell. The time has come for you to have a very serious conversation with the Storyteller... |" +1 +5 +TSFX_WITCH21 + +[TEXT_DOOM10] +"I've been looking for a map, but that certainly isn't it. You should show that to Adria - she can probably tell you what it is. I'll say one thing; it looks old, and old usually means valuable. |" +1 +5 +TSFX_PEGBOY20 diff --git a/2020_03_31/Source/Data/Text/Quest/garbud.txt b/2020_03_31/Source/Data/Text/Quest/garbud.txt new file mode 100644 index 00000000..68ed2cbe --- /dev/null +++ b/2020_03_31/Source/Data/Text/Quest/garbud.txt @@ -0,0 +1,23 @@ +[TEXT_GARBUD1] +"Pleeeease, no hurt. No Kill. Keep alive and next time good bring to you. |" +1 +6 +USFX_GARBUD1 + +[TEXT_GARBUD2] +"Something for you I am making. Again, not kill Gharbad. Live and give good. \n \nYou take this as proof I keep word... |" +1 +6 +USFX_GARBUD2 + +[TEXT_GARBUD3] +"Nothing yet! Almost done. \n \nVery powerful, very strong. Live! Live! \n \nNo pain and promise I keep! |" +1 +6 +USFX_GARBUD3 + +[TEXT_GARBUD4] +"This too good for you. Very Powerful! You want - you take! |" +1 +6 +USFX_GARBUD4 diff --git a/2020_03_31/Source/Data/Text/Quest/infra.txt b/2020_03_31/Source/Data/Text/Quest/infra.txt new file mode 100644 index 00000000..0330e608 --- /dev/null +++ b/2020_03_31/Source/Data/Text/Quest/infra.txt @@ -0,0 +1,59 @@ +[TEXT_INFRA1] +"Griswold speaks of the Heaven Stone that was destined for the enclave located in the east. It was being taken there for further study. This stone glowed with an energy that somehow granted vision beyond that which a normal man could possess. I do not know what secrets it holds, my friend, but finding this stone would certainly prove most valuable. |" +1 +5 +TSFX_STORY20 + +[TEXT_INFRA2] +"The caravan stopped here to take on some supplies for their journey to the east. I sold them quite an array of fresh fruits and some excellent sweetbreads that Garda has just finished baking. Shame what happened to them... |" +1 +6 +TSFX_TAVERN18 + +[TEXT_INFRA3] +"I don't know what it is that they thought they could see with that rock, but I will say this. If rocks are falling from the sky, you had better be careful! |" +1 +6 +TSFX_HEALER18 + +[TEXT_INFRA4] +"Well, a caravan of some very important people did stop here, but that was quite a while ago. They had strange accents and were starting on a long journey, as I recall. \n \nI don't see how you could hope to find anything that they would have been carrying. |" +1 +6 +TSFX_BMAID18 + +[TEXT_INFRA5] +"Stay for a moment - I have a story you might find interesting. A caravan that was bound for the eastern kingdoms passed through here some time ago. It was supposedly carrying a piece of the heavens that had fallen to earth! The caravan was ambushed by cloaked riders just north of here along the roadway. I searched the wreckage for this sky rock, but it was nowhere to be found. If you should find it, I believe that I can fashion something useful from it. |" +1 +5 +TSFX_SMITH24 + +[TEXT_INFRA6] +"I am still waiting for you to bring me that stone from the heavens. I know that I can make something powerful out of it. |" +1 +6 +TSFX_SMITH25 + +[TEXT_INFRA7] +"Let me see that - aye... aye, it is as I believed. Give me a moment...\n \nAh, Here you are. I arranged pieces of the stone within a silver ring that my father left me. I hope it serves you well. |" +1 +5 +TSFX_SMITH26 + +[TEXT_INFRA8] +"I used to have a nice ring; it was a really expensive one, with blue and green and red and silver. Don't remember what happened to it, though. I really miss that ring... |" +1 +5 +TSFX_DRUNK19 + +[TEXT_INFRA9] +"The Heaven Stone is very powerful, and were it any but Griswold who bid you find it, I would prevent it. He will harness its powers and its use will be for the good of us all. |" +1 +5 +TSFX_WITCH20 + +[TEXT_INFRA10] +"If anyone can make something out of that rock, Griswold can. He knows what he is doing, and as much as I try to steal his customers, I respect the quality of his work. |" +1 +6 +TSFX_PEGBOY18 diff --git a/2020_03_31/Source/Data/Text/Quest/king.txt b/2020_03_31/Source/Data/Text/Quest/king.txt new file mode 100644 index 00000000..b9d8222f --- /dev/null +++ b/2020_03_31/Source/Data/Text/Quest/king.txt @@ -0,0 +1,65 @@ +[TEXT_KING1] +" 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 + +[TEXT_KING2] +"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... |" +1 +5 +TSFX_TAVERN21 + +[TEXT_KING3] +"As I told you, good master, the King was entombed three levels below. He's down there, waiting in the putrid darkness for his chance to destroy this land... |" +1 +6 +TSFX_TAVERN22 + +[TEXT_KING4] +"The curse of our King has passed, but I fear that it was only part of a greater evil at work. However, we may yet be saved from the darkness that consumes our land, for your victory is a good omen. May Light guide you on your way, good master. |" +1 +5 +TSFX_TAVERN23 + +[TEXT_KING5] +"The loss of his son was too much for King Leoric. I did what I could to ease his madness, but in the end it overcame him. A black curse has hung over this kingdom from that day forward, but perhaps if you were to free his spirit from his earthly prison, the curse would be lifted... |" +1 +5 +TSFX_HEALER1 + +[TEXT_KING6] +"I don't like to think about how the King died. I like to remember him for the kind and just ruler that he was. His death was so sad and seemed very wrong, somehow. |" +1 +6 +TSFX_BMAID1 + +[TEXT_KING7] +"I made many of the weapons and most of the armor that King Leoric used to outfit his knights. I even crafted a huge two-handed sword of the finest mithril for him, as well as a field crown to match. I still cannot believe how he died, but it must have been some sinister force that drove him insane! |" +1 +5 +TSFX_SMITH1 + +[TEXT_KING8] +"I don't care about that. Listen, no skeleton is gonna be MY king. Leoric is King. King, so you hear me? HAIL TO THE KING! |" +1 +5 +TSFX_DRUNK1 + +[TEXT_KING9] +"The dead who walk among the living follow the cursed King. He holds the power to raise yet more warriors for an ever growing army of the undead. If you do not stop his reign, he will surely march across this land and slay all who still live here. |" +1 +5 +TSFX_WITCH1 + +[TEXT_KING10] +"Look, I'm running a business here. I don't sell information, and I don't care about some King that's been dead longer than I've been alive. If you need something to use against this King of the undead, then I can help you out... |" +1 +5 +TSFX_PEGBOY1 + +[TEXT_KING11] +"The warmth of life has entered my tomb. Prepare yourself, mortal, to serve my Master for eternity! |" +0 +5 +USFX_SKING1 diff --git a/2020_03_31/Source/Data/Text/Quest/mush.txt b/2020_03_31/Source/Data/Text/Quest/mush.txt new file mode 100644 index 00000000..e4ad7b0d --- /dev/null +++ b/2020_03_31/Source/Data/Text/Quest/mush.txt @@ -0,0 +1,77 @@ +[TEXT_MUSH1] +"The witch Adria seeks a black mushroom? I know as much about Black Mushrooms as I do about Red Herrings. Perhaps Pepin the Healer could tell you more, but this is something that cannot be found in any of my stories or books. |" +1 +5 +TSFX_STORY21 + +[TEXT_MUSH2] +"Let me just say this. Both Garda and I would never, EVER serve black mushrooms to our honored guests. If Adria wants some mushrooms in her stew, then that is her business, but I can't help you find any. Black mushrooms... disgusting! |" +1 +5 +TSFX_TAVERN19 + +[TEXT_MUSH3] +"The witch told me that you were searching for the brain of a demon to assist me in creating my elixir. It should be of great value to the many who are injured by those foul beasts, if I can just unlock the secrets I suspect that its alchemy holds. If you can remove the brain of a demon when you kill it, I would be grateful if you could bring it to me. |" +1 +5 +TSFX_HEALER26 + +[TEXT_MUSH4] +"Excellent, this is just what I had in mind. I was able to finish the elixir without this, but it can't hurt to have this to study. Would you please carry this to the witch? I believe that she is expecting it. |" +1 +5 +TSFX_HEALER27 + +[TEXT_MUSH5] +"I think Ogden might have some mushrooms in the storage cellar. Why don't you ask him? |" +1 +7 +TSFX_BMAID19 + +[TEXT_MUSH6] +"If Adria doesn't have one of these, you can bet that's a rare thing indeed. I can offer you no more help than that, but it sounds like... a huge, gargantuan, swollen, bloated mushroom! Well, good hunting, I suppose. |" +1 +5 +TSFX_SMITH19 + +[TEXT_MUSH7] +"Ogden mixes a MEAN black mushroom, but I get sick if I drink that. Listen, listen... here's the secret - moderation is the key! |" +1 +5 +TSFX_DRUNK20 + +[TEXT_MUSH8] +"What do we have here? Interesting, it looks like a book of reagents. Keep your eyes open for a black mushroom. It should be fairly large and easy to identify. If you find it, bring it to me, won't you? |" +1 +5 +TSFX_WITCH22 + +[TEXT_MUSH9] +"It's a big, black mushroom that I need. Now run off and get it for me so that I can use it for a special concoction that I am working on. |" +1 +6 +TSFX_WITCH23 + +[TEXT_MUSH10] +"Yes, this will be perfect for a brew that I am creating. By the way, the healer is looking for the brain of some demon or another so he can treat those who have been afflicted by their poisonous venom. I believe that he intends to make an elixir from it. If you help him find what he needs, please see if you can get a sample of the elixir for me. |" +1 +5 +TSFX_WITCH24 + +[TEXT_MUSH11] +"Why have you brought that here? I have no need for a demon's brain at this time. I do need some of the elixir that the Healer is working on. He needs that grotesque organ that you are holding, and then bring me the elixir. Simple when you think about it, isn't it? |" +1 +5 +TSFX_WITCH25 + +[TEXT_MUSH12] +"What? Now you bring me that elixir from the healer? I was able to finish my brew without it. Why don't you just keep it... |" +1 +6 +TSFX_WITCH26 + +[TEXT_MUSH13] +"I don't have any mushrooms of any size or color for sale. How about something a bit more useful? |" +1 +6 +TSFX_PEGBOY19 diff --git a/2020_03_31/Source/Data/Text/Quest/poison.txt b/2020_03_31/Source/Data/Text/Quest/poison.txt new file mode 100644 index 00000000..72be1711 --- /dev/null +++ b/2020_03_31/Source/Data/Text/Quest/poison.txt @@ -0,0 +1,59 @@ +[TEXT_POISON1] +"Hmm, I don't know what I can really tell you about this that will be of any help. The water that fills our wells comes from an underground spring. I have heard of a tunnel that leads to a great lake - perhaps they are one and the same. Unfortunately, I do not know what would cause our water supply to be tainted. |" +1 +5 +TSFX_STORY4 + +[TEXT_POISON2] +"I have always tried to keep a large supply of foodstuffs and drink in our storage cellar, but with the entire town having no source of fresh water, even our stores will soon run dry. \n \nPlease, do what you can or I don't know what we will do. |" +1 +6 +TSFX_TAVERN2 + +[TEXT_POISON3] +"I'm glad I caught up to you in time! Our wells have become brackish and stagnant and some of the townspeople have become ill drinking from them. Our reserves of fresh water are quickly running dry. I believe that there is a passage that leads to the springs that serve our town. Please find what has caused this calamity, or we all will surely perish. |" +1 +5 +TSFX_HEALER20 + +[TEXT_POISON4] +"Please, you must hurry. Every hour that passes brings us closer to having no water to drink. \n \nWe cannot survive for long without your help. |" +1 +6 +TSFX_HEALER21 + +[TEXT_POISON5] +"What's that you say - the mere presence of the demons had caused the water to become tainted? Oh, truly a great evil lurks beneath our town, but your perseverance and courage gives us hope. Please take this ring - perhaps it will aid you in the destruction of such vile creatures. |" +1 +5 +TSFX_HEALER22 + +[TEXT_POISON6] +"My grandmother is very weak, and Garda says that we cannot drink the water from the wells. Please, can you do something to help us? |" +1 +6 +TSFX_BMAID4 + +[TEXT_POISON7] +"Pepin has told you the truth. We will need fresh water badly, and soon. I have tried to clear one of the smaller wells, but it reeks of stagnant filth. It must be getting clogged at the source. |" +1 +5 +TSFX_SMITH4 + +[TEXT_POISON8] +"You drink water? |" +1 +8 +TSFX_DRUNK4 + +[TEXT_POISON9] +"The people of Tristram will die if you cannot restore fresh water to their wells. \n \nKnow this - demons are at the heart of this matter, but they remain ignorant of what they have spawned. |" +1 +6 +TSFX_WITCH4 + +[TEXT_POISON10] +"For once, I'm with you. My business runs dry - so to speak - if I have no market to sell to. You better find out what is going on, and soon! |" +1 +6 +TSFX_PEGBOY4 diff --git a/2020_03_31/Source/Data/Text/Quest/veil.txt b/2020_03_31/Source/Data/Text/Quest/veil.txt new file mode 100644 index 00000000..eb0bc916 --- /dev/null +++ b/2020_03_31/Source/Data/Text/Quest/veil.txt @@ -0,0 +1,65 @@ +[TEXT_VEIL1] +"You claim to have spoken with Lachdanan? He was a great hero during his life. Lachdanan was an honorable and just man who served his King faithfully for years. But of course, you already know that.\n \nOf those who were caught within the grasp of the King's Curse, Lachdanan would be the least likely to submit to the darkness without a fight, so I suppose that your story could be true. If I were in your place, my friend, I would find a way to release him from his torture. |" +1 +5 +TSFX_STORY13 + +[TEXT_VEIL2] +"You speak of a brave warrior long dead! I'll have no such talk of speaking with departed souls in my inn yard, thank you very much. |" +1 +6 +TSFX_TAVERN11 + +[TEXT_VEIL3] +"A golden elixir, you say. I have never concocted a potion of that color before, so I can't tell you how it would effect you if you were to try to drink it. As your healer, I strongly advise that should you find such an elixir, do as Lachdanan asks and DO NOT try to use it. |" +1 +5 +TSFX_HEALER11 + +[TEXT_VEIL4] +"I've never heard of a Lachdanan before. I'm sorry, but I don't think that I can be of much help to you. |" +1 +7 +TSFX_BMAID11 + +[TEXT_VEIL5] +"If it is actually Lachdanan that you have met, then I would advise that you aid him. I dealt with him on several occasions and found him to be honest and loyal in nature. The curse that fell upon the followers of King Leoric would fall especially hard upon him. |" +1 +5 +TSFX_SMITH13 + +[TEXT_VEIL6] +" Lachdanan is dead. Everybody knows that, and you can't fool me into thinking any other way. You can't talk to the dead. I know! |" +1 +5 +TSFX_DRUNK13 + +[TEXT_VEIL7] +"You may meet people who are trapped within the Labyrinth, such as Lachdanan. \n \nI sense in him honor and great guilt. Aid him, and you aid all of Tristram. |" +1 +6 +TSFX_WITCH13 + +[TEXT_VEIL8] +"Wait, let me guess. Cain was swallowed up in a gigantic fissure that opened beneath him. He was incinerated in a ball of hellfire, and can't answer your questions anymore. Oh, that isn't what happened? Then I guess you'll be buying something or you'll be on your way. |" +1 +5 +TSFX_PEGBOY12 + +[TEXT_VEIL9] +"Please, don't kill me, just hear me out. I was once Captain of King Leoric's Knights, upholding the laws of this land with justice and honor. Then his dark Curse fell upon us for the role we played in his tragic death. As my fellow Knights succumbed to their twisted fate, I fled from the King's burial chamber, searching for some way to free myself from the Curse. I failed...\n \nI have heard of a Golden Elixir that could lift the Curse and allow my soul to rest, but I have been unable to find it. My strength now wanes, and with it the last of my humanity as well. Please aid me and find the Elixir. I will repay your efforts - I swear upon my honor. |" +1 +3 +USFX_LACH1 + +[TEXT_VEIL10] +"You have not found the Golden Elixir. I fear that I am doomed for eternity. Please, keep trying... |" +1 +6 +USFX_LACH2 + +[TEXT_VEIL11] +"You have saved my soul from damnation, and for that I am in your debt. If there is ever a way that I can repay you from beyond the grave I will find it, but for now - take my helm. On the journey I am about to take I will have little use for it. May it protect you against the dark powers below. Go with the Light, my friend... |" +1 +4 +USFX_LACH3 diff --git a/2020_03_31/Source/Data/Text/Quest/vile.txt b/2020_03_31/Source/Data/Text/Quest/vile.txt new file mode 100644 index 00000000..fc5d73ca --- /dev/null +++ b/2020_03_31/Source/Data/Text/Quest/vile.txt @@ -0,0 +1,83 @@ +[TEXT_VILE1] +"This does not bode well, for it confirms my darkest fears. While I did not allow myself to believe the ancient legends, I cannot deny them now. Perhaps the time has come to reveal who I am.\n \nMy true name is Deckard Cain the Elder, and I am the last descendant of an ancient Brotherhood that was dedicated to safeguarding the secrets of a timeless evil. An evil that quite obviously has now been released.\n \nThe Archbishop Lazarus, once King Leoric's most trusted advisor, led a party of simple townsfolk into the Labyrinth to find the King's missing son, Albrecht. Quite some time passed before they returned, and only a few of them escaped with their lives.\n \nCurse me for a fool! I should have suspected his veiled treachery then. It must have been Lazarus himself who kidnapped Albrecht and has since hidden him within the Labyrinth. I do not understand why the Archbishop turned to the darkness, or what his interest is in the child. unless he means to sacrifice him to his dark masters!\n \nThat must be what he has planned! The survivors of his 'rescue party' say that Lazarus was last seen running into the deepest bowels of the labyrinth. You must hurry and save the prince from the sacrificial blade of this demented fiend! |" +1 +3 +TSFX_STORY36 + +[TEXT_VILE2] +"You must hurry and rescue Albrecht from the hands of Lazarus. The prince and the people of this kingdom are counting on you! |" +1 +5 +TSFX_STORY37 + +[TEXT_VILE3] +"Your story is quite grim, my friend. Lazarus will surely burn in Hell for his horrific deed. The boy that you describe is not our prince, but I believe that Albrecht may yet be in danger. The symbol of power that you speak of must be a portal in the very heart of the labyrinth.\n \nKnow this, my friend - The evil that you move against is the dark Lord of Terror. He is known to mortal men as Diablo. It was he who was imprisoned within the Labyrinth many centuries ago and I fear that he seeks to once again sow chaos in the realm of mankind. You must venture through the portal and destroy Diablo before it is too late! |" +1 +5 +TSFX_STORY38 + +[TEXT_VILE4] +"Lazarus was the Archbishop who led many of the townspeople into the labyrinth. I lost many good friends that day, and Lazarus never returned. I suppose he was killed along with most of the others. If you would do me a favor, good master - please do not talk to Farnham about that day. |" +1 +6 +TSFX_TAVERN1 + +[TEXT_VILE5] +"|" +1 +5 +TSFX_STORY38 + +[TEXT_VILE6] +"|" +1 +5 +TSFX_STORY38 + +[TEXT_VILE7] +"I was shocked when I heard of what the townspeople were planning to do that night. I thought that of all people, Lazarus would have had more sense than that. He was an Archbishop, and always seemed to care so much for the townsfolk of Tristram. So many were injured, I could not save them all... |" +1 +5 +TSFX_HEALER3 + +[TEXT_VILE8] +"I remember Lazarus as being a very kind and giving man. He spoke at my mother's funeral, and was supportive of my grandmother and myself in a very troubled time. I pray every night that somehow, he is still alive and safe. |" +1 +5 +TSFX_BMAID3 + +[TEXT_VILE9] +"I was there when Lazarus led us into the labyrinth. He spoke of holy retribution, but when we started fighting those hellspawn, he did not so much as lift his mace against them. He just ran deeper into the dim, endless chambers that were filled with the servants of darkness! |" +1 +5 +TSFX_SMITH3 + +[TEXT_VILE10] +"They stab, then bite, then they're all around you. Liar! LIAR! They're all dead! Dead! Do you hear me? They just keep falling and falling... their blood spilling out all over the floor... all his fault... |" +1 +5 +TSFX_DRUNK3 + +[TEXT_VILE11] +"I did not know this Lazarus of whom you speak, but I do sense a great conflict within his being. He poses a great danger, and will stop at nothing to serve the powers of darkness which have claimed him as theirs. |" +1 +5 +TSFX_WITCH3 + +[TEXT_VILE12] +"Yes, the righteous Lazarus, who was sooo effective against those monsters down there. Didn't help save my leg, did it? Look, I'll give you a free piece of advice. Ask Farnham, he was there. |" +1 +5 +TSFX_PEGBOY3 + +[TEXT_VILE13] +"Abandon your foolish quest. All that awaits you is the wrath of my Master! You are too late to save the child. Now you will join him in Hell! |" +0 +5 +USFX_LAZ1 + +[TEXT_VILE14] +" |" +0 +5 +USFX_LAZ1 diff --git a/2020_03_31/Source/Data/Text/Quest/warlrd.txt b/2020_03_31/Source/Data/Text/Quest/warlrd.txt new file mode 100644 index 00000000..9d3630b0 --- /dev/null +++ b/2020_03_31/Source/Data/Text/Quest/warlrd.txt @@ -0,0 +1,53 @@ +[TEXT_WARLRD1] +"I know of only one legend that speaks of such a warrior as you describe. His story is found within the ancient chronicles of the Sin War...\n \nStained by a thousand years of war, blood and death, the Warlord of Blood stands upon a mountain of his tattered victims. His dark blade screams a black curse to the living; a tortured invitation to any who would stand before this Executioner of Hell.\n \nIt is also written that although he was once a mortal who fought beside the Legion of Darkness during the Sin War, he lost his humanity to his insatiable hunger for blood. |" +1 +5 +TSFX_STORY18 + +[TEXT_WARLRD2] +"I am afraid that I haven't heard anything about such a vicious warrior, good master. I hope that you do not have to fight him, for he sounds extremely dangerous. |" +1 +6 +TSFX_TAVERN16 + +[TEXT_WARLRD3] +"Cain would be able to tell you much more about something like this than I would ever wish to know. |" +1 +7 +TSFX_HEALER16 + +[TEXT_WARLRD4] +"If you are to battle such a fierce opponent, may Light be your guide and your defender. I will keep you in my thoughts. |" +1 +6 +TSFX_BMAID16 + +[TEXT_WARLRD5] +"Dark and wicked legends surrounds the one Warlord of Blood. Be well prepared, my friend, for he shows no mercy or quarter. |" +1 +6 +TSFX_SMITH17 + +[TEXT_WARLRD6] +"Always you gotta talk about Blood? What about flowers, and sunshine, and that pretty girl that brings the drinks. Listen here, friend - you're obsessive, you know that? |" +1 +5 +TSFX_DRUNK17 + +[TEXT_WARLRD7] +"His prowess with the blade is awesome, and he has lived for thousands of years knowing only warfare. I am sorry... I can not see if you will defeat him. |" +1 +5 +TSFX_WITCH18 + +[TEXT_WARLRD8] +"I haven't ever dealt with this Warlord you speak of, but he sounds like he's going through a lot of swords. Wouldn't mind supplying his armies... |" +1 +6 +TSFX_PEGBOY17 + +[TEXT_WARLRD9] +"My blade sings for your blood, mortal, and by my dark masters it shall not be denied. |" +0 +6 +USFX_WARLRD1 diff --git a/2020_03_31/Source/Data/Text/Quest/zhar.txt b/2020_03_31/Source/Data/Text/Quest/zhar.txt new file mode 100644 index 00000000..f9e2642a --- /dev/null +++ b/2020_03_31/Source/Data/Text/Quest/zhar.txt @@ -0,0 +1,11 @@ +[TEXT_ZHAR1] +"What?! Why are you here? All these interruptions are enough to make one insane. Here, take this and leave me to my work. Trouble me no more! |" +1 +6 +USFX_ZHAR1 + +[TEXT_ZHAR2] +"Arrrrgh! Your curiosity will be the death of you!!! |" +1 +7 +USFX_ZHAR2 diff --git a/2020_03_31/Source/Data/Text/speech.txt b/2020_03_31/Source/Data/Text/speech.txt new file mode 100644 index 00000000..bbc44ae4 --- /dev/null +++ b/2020_03_31/Source/Data/Text/speech.txt @@ -0,0 +1,189 @@ +#include "Quest\king.txt" +#include "Quest\banner.txt" +#include "Quest\vile.txt" +#include "Quest\poison.txt" +#include "Quest\bone.txt" +#include "Quest\butch.txt" +#include "Quest\blind.txt" +#include "Quest\veil.txt" +#include "Quest\anvil.txt" +#include "Quest\blood.txt" +#include "Quest\warlrd.txt" +#include "Quest\infra.txt" +#include "Quest\mush.txt" +#include "Quest\doom.txt" +#include "Quest\garbud.txt" +#include "Quest\zhar.txt" + +#include "Gossip\story.txt" +#include "Gossip\ogden.txt" +#include "Gossip\pepin.txt" +#include "Gossip\gillian.txt" +#include "Gossip\griswold.txt" +#include "Gossip\farnham.txt" +#include "Gossip\adria.txt" +#include "Gossip\wirt.txt" + + +//-------------------------------------------------- +// Player +//-------------------------------------------------- + +[TEXT_BONER] +"Beyond the Hall of Heroes lies the Chamber of Bone. Eternal death awaits any who would seek to steal the treasures secured within this room. So speaks the Lord of Terror, and so it is written. |" +1 +5 +PS_WARR1 + +[TEXT_BLOODY] +"...and so, locked beyond the Gateway of Blood and past the Hall of Fire, Valor awaits for the Hero of Light to awaken... |" +1 +6 +PS_WARR10 + +[TEXT_BLINDING] +"I can see what you see not.\nVision milky then eyes rot.\nWhen you turn they will be gone,\nWhispering their hidden song.\nThen you see what cannot be,\nShadows move where light should be.\nOut of darkness, out of mind,\nCast down into the Halls of the Blind. |\n" +1 +5 +PS_WARR11 + +[TEXT_BLOODWAR] +"The armories of Hell are home to the Warlord of Blood. In his wake lay the mutilated bodies of thousands. Angels and man alike have been cut down to fulfill his endless sacrifices to the Dark ones who scream for one thing - blood. |" +1 +5 +PS_WARR12 + +[TEXT_MBONER] +"Beyond the Hall of Heroes lies the Chamber of Bone. Eternal death awaits any who would seek to steal the treasures secured within this room. So speaks the Lord of Terror, and so it is written. |" +1 +5 +PS_MAGE1 + +[TEXT_MBLOODY] +"...and so, locked beyond the Gateway of Blood and past the Hall of Fire, Valor awaits for the Hero of Light to awaken... |" +1 +6 +PS_MAGE10 + +[TEXT_MBLINDING] +"I can see what you see not.\nVision milky then eyes rot.\nWhen you turn they will be gone,\nWhispering their hidden song.\nThen you see what cannot be,\nShadows move where light should be.\nOut of darkness, out of mind,\nCast down into the Halls of the Blind. |\n" +1 +4 +PS_MAGE11 + +[TEXT_MBLOODWAR] +"The armories of Hell are home to the Warlord of Blood. In his wake lay the mutilated bodies of thousands. Angels and man alike have been cut down to fulfill his endless sacrifices to the Dark ones who scream for one thing - blood. |" +1 +5 +PS_MAGE12 + +[TEXT_RBONER] +"Beyond the Hall of Heroes lies the Chamber of Bone. Eternal death awaits any who would seek to steal the treasures secured within this room. So speaks the Lord of Terror, and so it is written. |" +1 +5 +PS_ROGUE1 + +[TEXT_RBLOODY] +"...and so, locked beyond the Gateway of Blood and past the Hall of Fire, Valor awaits for the Hero of Light to awaken... |" +1 +5 +PS_ROGUE10 + +[TEXT_RBLINDING] +"I can see what you see not.\nVision milky then eyes rot.\nWhen you turn they will be gone,\nWhispering their hidden song.\nThen you see what cannot be,\nShadows move where light should be.\nOut of darkness, out of mind,\nCast down into the Halls of the Blind. |\n" +1 +5 +PS_ROGUE11 + +[TEXT_RBLOODWAR] +"The armories of Hell are home to the Warlord of Blood. In his wake lay the mutilated bodies of thousands. Angels and man alike have been cut down to fulfill his endless sacrifices to the Dark ones who scream for one thing - blood. |" +1 +5 +PS_ROGUE12 + + +//-------------------------------------------------- +// Animal +//-------------------------------------------------- + +[TEXT_COW1] +" |" +0 +5 +TSFX_COW1 + +[TEXT_COW2] +" |" +0 +5 +TSFX_COW2 + + +//-------------------------------------------------- +// Narrator +//-------------------------------------------------- + +[TEXT_BOOK11] +"Take heed and bear witness to the truths that lie herein, for they are the last legacy of the Horadrim. There is a war that rages on even now, beyond the fields that we know - between the utopian kingdoms of the High Heavens and the chaotic pits of the Burning Hells. This war is known as the Great Conflict, and it has raged and burned longer than any of the stars in the sky. Neither side ever gains sway for long as the forces of Light and Darkness constantly vie for control over all creation. |" +1 +5 +PS_NAR1 + +[TEXT_BOOK12] +"Take heed and bear witness to the truths that lie herein, for they are the last legacy of the Horadrim. When the Eternal Conflict between the High Heavens and the Burning Hells falls upon mortal soil, it is called the Sin War. Angels and Demons walk amongst humanity in disguise, fighting in secret, away from the prying eyes of mortals. Some daring, powerful mortals have even allied themselves with either side, and helped to dictate the course of the Sin War. |" +1 +4 +PS_NAR2 + +[TEXT_BOOK13] +"Take heed and bear witness to the truths that lie herein, for they are the last legacy of the Horadrim. Nearly three hundred years ago, it came to be known that the Three Prime Evils of the Burning Hells had mysteriously come to our world. The Three Brothers ravaged the lands of the east for decades, while humanity was left trembling in their wake. Our Order - the Horadrim - was founded by a group of secretive magi to hunt down and capture the Three Evils once and for all.\n \nThe original Horadrim captured two of the Three within powerful artifacts known as Soulstones and buried them deep beneath the desolate eastern sands. The third Evil escaped capture and fled to the west with many of the Horadrim in pursuit. The Third Evil - known as Diablo, the Lord of Terror - was eventually captured, his essence set in a Soulstone and buried within this Labyrinth.\n \nBe warned that the soulstone must be kept from discovery by those not of the faith. If Diablo were to be released, he would seek a body that is easily controlled as he would be very weak - perhaps that of an old man or a child. |" +1 +3 +PS_NAR3 + +[TEXT_BOOK21] +"So it came to be that there was a great revolution within the Burning Hells known as The Dark Exile. The Lesser Evils overthrew the Three Prime Evils and banished their spirit forms to the mortal realm. The demons Belial (the Lord of Lies) and Azmodan (the Lord of Sin) fought to claim rulership of Hell during the absence of the Three Brothers. All of Hell polarized between the factions of Belial and Azmodan while the forces of the High Heavens continually battered upon the very Gates of Hell. |" +1 +4 +PS_NAR4 + +[TEXT_BOOK22] +"Many demons traveled to the mortal realm in search of the Three Brothers. These demons were followed to the mortal plane by Angels who hunted them throughout the vast cities of the East. The Angels allied themselves with a secretive Order of mortal magi named the Horadrim, who quickly became adept at hunting demons. They also made many dark enemies in the underworlds. |" +1 +5 +PS_NAR5 + +[TEXT_BOOK23] +"So it came to be that the Three Prime Evils were banished in spirit form to the mortal realm and after sewing chaos across the East for decades, they were hunted down by the cursed Order of the mortal Horadrim. The Horadrim used artifacts called Soulstones to contain the essence of Mephisto, the Lord of Hatred and his brother Baal, the Lord of Destruction. The youngest brother - Diablo, the Lord of Terror - escaped to the west.\n \nEventually the Horadrim captured Diablo within a Soulstone as well, and buried him under an ancient, forgotten Cathedral. There, the Lord of Terror sleeps and awaits the time of his rebirth. Know ye that he will seek a body of youth and power to possess - one that is innocent and easily controlled. He will then arise to free his Brothers and once more fan the flames of the Sin War... |" +1 +3 +PS_NAR6 + +[TEXT_BOOK31] +"All praises to Diablo - Lord of Terror and Survivor of The Dark Exile. When he awakened from his long slumber, my Lord and Master spoke to me of secrets that few mortals know. He told me the kingdoms of the High Heavens and the pits of the Burning Hells engage in an eternal war. He revealed the powers that have brought this discord to the realms of man. My lord has named the battle for this world and all who exist here the Sin War. |" +1 +4 +PS_NAR7 + +[TEXT_BOOK32] +"Glory and Approbation to Diablo - Lord of Terror and Leader of the Three. My Lord spoke to me of his two Brothers, Mephisto and Baal, who were banished to this world long ago. My Lord wishes to bide his time and harness his awesome power so that he may free his captive brothers from their tombs beneath the sands of the east. Once my Lord releases his Brothers, the Sin War will once again know the fury of the Three. |" +1 +4 +PS_NAR8 + +[TEXT_BOOK33] +"Hail and Sacrifice to Diablo - Lord of Terror and Destroyer of Souls. When I awoke my Master from his sleep, he attempted to possess a mortal's form. Diablo attempted to claim the body of King Leoric, but my Master was too weak from his imprisonment. My Lord required a simple and innocent anchor to this world, and so found the boy Albrecht to be perfect for the task. While the good King Leoric was left maddened by Diablo's unsuccessful possession, I kidnapped his son Albrecht and brought him before my Master. I now await Diablo's call and pray that I will be rewarded when he at last emerges as the Lord of this world. |" +1 +3 +PS_NAR9 + + +//-------------------------------------------------- +// Introduction +//-------------------------------------------------- + +[TEXT_INTRO] +"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 diff --git a/2020_03_31/Source/Data/m.bat b/2020_03_31/Source/Data/m.bat new file mode 100644 index 00000000..34ed9a7d --- /dev/null +++ b/2020_03_31/Source/Data/m.bat @@ -0,0 +1,33 @@ +@echo off + +cd Excel +set PATH=..\..\..\Utils\Bin +call :COMPILE_XL xl_ipre +call :COMPILE_XL xl_isuf +call :COMPILE_XL xl_item +call :COMPILE_XL xl_mfile +call :COMPILE_XL xl_mis +call :COMPILE_XL xl_monst +call :COMPILE_XL xl_obj +call :COMPILE_XL xl_quest +call :COMPILE_XL xl_sfx +call :COMPILE_XL xl_spell +call :COMPILE_XL xl_uitem +call :COMPILE_XL xl_umon +cd .. + +cd Text +set PATH=..\..\..\Utils\Bin +call :COMPILE_TXT speech +cd .. + +pause +exit + +:COMPILE_XL +MakeXL %1.txt ..\%1.cpp ..\%1.h +goto :eof + +:COMPILE_TXT +MakeText %1.txt ..\%1.cpp ..\%1.h +goto :eof diff --git a/2020_03_31/Source/_asm.cpp b/2020_03_31/Source/_asm.cpp new file mode 100644 index 00000000..cdc7f0f4 --- /dev/null +++ b/2020_03_31/Source/_asm.cpp @@ -0,0 +1,137 @@ +static __inline void asm_cel_light_edge(unsigned char w, BYTE *tbl, BYTE *&dst, BYTE *&src); +static __inline void asm_cel_light_square(unsigned char w, BYTE *tbl, BYTE *&dst, BYTE *&src); +static __inline void asm_trans_light_cel_0_2(unsigned char w, BYTE *tbl, BYTE *&dst, BYTE *&src); +static __inline void asm_trans_light_edge_0_2(unsigned char w, BYTE *tbl, BYTE *&dst, BYTE *&src); +static __inline void asm_trans_light_square_0_2(unsigned char w, BYTE *tbl, BYTE *&dst, BYTE *&src); +static __inline void asm_trans_light_cel_1_3(unsigned char w, BYTE *tbl, BYTE *&dst, BYTE *&src); +static __inline void asm_trans_light_edge_1_3(unsigned char w, BYTE *tbl, BYTE *&dst, BYTE *&src); +static __inline void asm_trans_light_square_1_3(unsigned char w, BYTE *tbl, BYTE *&dst, BYTE *&src); +static __inline unsigned int asm_trans_light_mask(unsigned char w, BYTE *tbl, BYTE *&dst, BYTE *&src, unsigned int mask); + +static __inline void asm_cel_light_edge(unsigned char w, BYTE *tbl, BYTE *&dst, BYTE *&src) +{ + unsigned char l = w >> 1; + + if ( w & 1 ) + { + dst[0] = tbl[src[0]]; + src++; + dst++; + } + if ( l & 1 ) + { + dst[0] = tbl[src[0]]; + dst[1] = tbl[src[1]]; + src += 2; + dst += 2; + } + + asm_cel_light_square(l >> 1, tbl, dst, src); +} + +static __inline void asm_cel_light_square(unsigned char w, BYTE *tbl, BYTE *&dst, BYTE *&src) +{ + for ( ; w; --w ) + { + dst[0] = tbl[src[0]]; + dst[1] = tbl[src[1]]; + dst[2] = tbl[src[2]]; + dst[3] = tbl[src[3]]; + src += 4; + dst += 4; + } +} + +static __inline void asm_trans_light_cel_0_2(unsigned char w, BYTE *tbl, BYTE *&dst, BYTE *&src) +{ + if ( !(w & 1) ) + { + asm_trans_light_edge_1_3(w >> 1, tbl, dst, src); + } + else + { + src++; + dst++; + asm_trans_light_edge_0_2(w >> 1, tbl, dst, src); + } +} + +static __inline void asm_trans_light_edge_0_2(unsigned char w, BYTE *tbl, BYTE *&dst, BYTE *&src) +{ + unsigned char l = w >> 1; + + if ( w & 1 ) + { + dst[0] = tbl[src[0]]; + src += 2; + dst += 2; + } + if ( l ) + { + asm_trans_light_square_0_2(l, tbl, dst, src); + } +} + +static __inline void asm_trans_light_square_0_2(unsigned char w, BYTE *tbl, BYTE *&dst, BYTE *&src) +{ + for ( ; w; --w ) + { + dst[0] = tbl[src[0]]; + dst[2] = tbl[src[2]]; + src += 4; + dst += 4; + } +} + +static __inline void asm_trans_light_cel_1_3(unsigned char w, BYTE *tbl, BYTE *&dst, BYTE *&src) +{ + if ( !(w & 1) ) + { + asm_trans_light_edge_0_2(w >> 1, tbl, dst, src); + } + else + { + dst[0] = tbl[src[0]]; + src++; + dst++; + asm_trans_light_edge_1_3(w >> 1, tbl, dst, src); + } +} + +static __inline void asm_trans_light_edge_1_3(unsigned char w, BYTE *tbl, BYTE *&dst, BYTE *&src) +{ + unsigned char l = w >> 1; + + if ( w & 1 ) + { + dst[1] = tbl[src[1]]; + src += 2; + dst += 2; + } + if ( l ) + { + asm_trans_light_square_1_3(l, tbl, dst, src); + } +} + +static __inline void asm_trans_light_square_1_3(unsigned char w, BYTE *tbl, BYTE *&dst, BYTE *&src) +{ + for ( ; w; --w ) + { + dst[1] = tbl[src[1]]; + dst[3] = tbl[src[3]]; + src += 4; + dst += 4; + } +} + +static __inline unsigned int asm_trans_light_mask(unsigned char w, BYTE *tbl, BYTE *&dst, BYTE *&src, unsigned int mask) +{ + for ( ; w; --w, src++, dst++, mask *= 2 ) + { + if ( mask & 0x80000000 ) + dst[0] = tbl[src[0]]; + } + + return mask; +} diff --git a/2020_03_31/Source/_render.cpp b/2020_03_31/Source/_render.cpp new file mode 100644 index 00000000..f1f6ce06 --- /dev/null +++ b/2020_03_31/Source/_render.cpp @@ -0,0 +1,10251 @@ +__declspec(naked) void drawTopArchesUpperScreen(BYTE *pBuff) +{ + __asm { + push ebx + push edx + push edi + push esi + mov edi, offset SpeedFrameTbl + mov gpCelFrame, edi + mov edi, ecx + mov eax, light_table_index + test al, al + jz loc_46316A + cmp al, lightmax + jz loc_4631CA + mov eax, level_cel_block + and eax, 8000h + jnz loc_4630FE + mov ebx, pDungeonCels + mov esi, ebx + mov eax, level_cel_block + and eax, 0FFFh + shl eax, 2 + add ebx, eax + add esi, [ebx] + mov ebx, light_table_index + shl ebx, 8 + add ebx, pLightTbl + mov eax, level_cel_block + mov al, ah + shr eax, 4 + and eax, 0Fh + jz loc_463255 + cmp ax, 1 + jz loc_4632C5 + cmp ax, 2 + jz loc_463425 + cmp ax, 3 + jz loc_463698 + cmp ax, 4 + jz loc_46390B + jmp loc_463AB3 + loc_4630FE: + mov esi, gpCelFrame + mov eax, level_cel_block + and eax, 0FFFh + shl eax, 4 + add eax, light_table_index + shl eax, 2 + add esi, eax + mov eax, [esi] + mov esi, pSpeedCels + add esi, eax + mov eax, level_cel_block + mov al, ah + shr eax, 4 + and eax, 0Fh + loc_463133: + cmp ax, 8 + jz loc_463C5B + cmp ax, 9 + jz loc_463CC2 + cmp ax, 0Ah + jz loc_463DA3 + cmp ax, 0Bh + jz loc_463ED8 + cmp ax, 0Ch + jz loc_464011 + jmp loc_464112 + loc_46316A: + mov eax, level_cel_block + and eax, 8000h + jz loc_46319C + mov esi, gpCelFrame + mov eax, level_cel_block + and eax, 0FFFh + shl eax, 6 + add esi, eax + mov eax, level_cel_block + and eax, 0F000h + add eax, [esi] + mov level_cel_block, eax + loc_46319C: + mov ebx, pDungeonCels + mov esi, ebx + mov eax, level_cel_block + and eax, 0FFFh + shl eax, 2 + add ebx, eax + add esi, [ebx] + mov eax, level_cel_block + mov al, ah + shr eax, 4 + and eax, 7 + add eax, 8 + jmp loc_463133 + loc_4631CA: + mov eax, level_cel_block + and eax, 8000h + jz loc_4631FC + mov esi, gpCelFrame + mov eax, level_cel_block + and eax, 0FFFh + shl eax, 6 + add esi, eax + mov eax, level_cel_block + and eax, 0F000h + add eax, [esi] + mov level_cel_block, eax + loc_4631FC: + mov ebx, pDungeonCels + mov esi, ebx + mov eax, level_cel_block + and eax, 0FFFh + shl eax, 2 + add ebx, eax + add esi, [ebx] + mov eax, level_cel_block + mov al, ah + shr eax, 4 + and eax, 7 + jz loc_46420F + cmp ax, 1 + jz loc_464263 + cmp ax, 2 + jz loc_464321 + cmp ax, 3 + jz loc_46440E + cmp ax, 4 + jz loc_4644FB + jmp loc_4645C7 + loc_463255: + push ebp + mov ebp, 10h + loc_46325B: + cmp edi, gpBufEnd + jb loc_4632BF + mov ecx, 8 + loc_463268: + mov eax, [esi] + add esi, 4 + mov dl, ah + shr eax, 10h + mov dl, [ebx+edx] + mov [edi+1], dl + mov dl, ah + add edi, 4 + mov dl, [ebx+edx] + dec ecx + mov [edi-1], dl + jnz loc_463268 + sub edi, 320h + cmp edi, gpBufEnd + jb loc_4632BF + mov ecx, 8 + loc_463299: + mov eax, [esi] + add esi, 4 + mov dl, al + shr eax, 10h + mov dl, [ebx+edx] + mov [edi], dl + mov dl, al + add edi, 4 + mov dl, [ebx+edx] + dec ecx + mov [edi-2], dl + jnz loc_463299 + sub edi, 320h + dec ebp + jnz loc_46325B + loc_4632BF: + pop ebp + jmp loc_464688 + loc_4632C5: + push ebp + mov eax, edi + and eax, 1 + mov WorldBoolFlag, eax + mov ebp, 20h + loc_4632D5: + mov edx, 20h + loc_4632DA: + xor eax, eax + mov al, [esi] + inc esi + test al, al + js loc_4633F8 + sub edx, eax + cmp edi, gpBufEnd + jb loc_46341F + mov ecx, eax + mov eax, edi + and eax, 1 + cmp eax, WorldBoolFlag + jnz loc_463377 + push edx + shr ecx, 1 + jb loc_463340 + shr ecx, 1 + jnb loc_46331C + mov dl, [esi+1] + mov dl, [ebx+edx] + add esi, 2 + mov [edi+1], dl + add edi, 2 + loc_46331C: + test cl, cl + jz loc_46333E + loc_463320: + mov eax, [esi] + add esi, 4 + mov dl, ah + shr eax, 10h + mov dl, [ebx+edx] + mov [edi+1], dl + mov dl, ah + add edi, 4 + mov dl, [ebx+edx] + dec ecx + mov [edi-1], dl + jnz loc_463320 + loc_46333E: + jmp loc_463374 + loc_463340: + inc esi + inc edi + shr ecx, 1 + jnb loc_463353 + mov dl, [esi] + mov dl, [ebx+edx] + add esi, 2 + mov [edi], dl + add edi, 2 + loc_463353: + test cl, cl + jz loc_463374 + loc_463357: + mov eax, [esi] + add esi, 4 + mov dl, al + shr eax, 10h + mov dl, [ebx+edx] + mov [edi], dl + mov dl, al + add edi, 4 + mov dl, [ebx+edx] + dec ecx + mov [edi-2], dl + jnz loc_463357 + loc_463374: + pop edx + jmp loc_4633EF + loc_463377: + push edx + shr ecx, 1 + jb loc_4633B0 + shr ecx, 1 + jnb loc_46338D + mov dl, [esi] + mov dl, [ebx+edx] + add esi, 2 + mov [edi], dl + add edi, 2 + loc_46338D: + test cl, cl + jz loc_4633AE + loc_463391: + mov eax, [esi] + add esi, 4 + mov dl, al + shr eax, 10h + mov dl, [ebx+edx] + mov [edi], dl + mov dl, al + add edi, 4 + mov dl, [ebx+edx] + dec ecx + mov [edi-2], dl + jnz loc_463391 + loc_4633AE: + jmp loc_4633EE + loc_4633B0: + mov dl, [esi] + mov dl, [ebx+edx] + inc esi + mov [edi], dl + inc edi + shr ecx, 1 + jnb loc_4633CC + mov dl, [esi+1] + mov dl, [ebx+edx] + add esi, 2 + mov [edi+1], dl + add edi, 2 + loc_4633CC: + test cl, cl + jz loc_4633EE + loc_4633D0: + mov eax, [esi] + add esi, 4 + mov dl, ah + shr eax, 10h + mov dl, [ebx+edx] + mov [edi+1], dl + mov dl, ah + add edi, 4 + mov dl, [ebx+edx] + dec ecx + mov [edi-1], dl + jnz loc_4633D0 + loc_4633EE: + pop edx + loc_4633EF: + test edx, edx + jz loc_463404 + jmp loc_4632DA + loc_4633F8: + neg al + add edi, eax + sub edx, eax + jnz loc_4632DA + loc_463404: + mov eax, WorldBoolFlag + inc eax + and eax, 1 + mov WorldBoolFlag, eax + sub edi, 320h + dec ebp + jnz loc_4632D5 + loc_46341F: + pop ebp + jmp loc_464688 + loc_463425: + push ebp + xor eax, eax + mov WorldBoolFlag, eax + mov ebp, 1Eh + loc_463432: + cmp edi, gpBufEnd + jb loc_463692 + add edi, ebp + mov ecx, 20h + sub ecx, ebp + mov eax, WorldBoolFlag + inc eax + and eax, 1 + mov WorldBoolFlag, eax + jz loc_4634D2 + mov edx, ecx + and edx, 2 + add esi, edx + shr ecx, 1 + jb loc_463499 + shr ecx, 1 + jnb loc_463475 + mov dl, [esi+1] + mov dl, [ebx+edx] + add esi, 2 + mov [edi+1], dl + add edi, 2 + loc_463475: + test cl, cl + jz loc_463497 + loc_463479: + mov eax, [esi] + add esi, 4 + mov dl, ah + shr eax, 10h + mov dl, [ebx+edx] + mov [edi+1], dl + mov dl, ah + add edi, 4 + mov dl, [ebx+edx] + dec ecx + mov [edi-1], dl + jnz loc_463479 + loc_463497: + jmp loc_4634CD + loc_463499: + inc esi + inc edi + shr ecx, 1 + jnb loc_4634AC + mov dl, [esi] + mov dl, [ebx+edx] + add esi, 2 + mov [edi], dl + add edi, 2 + loc_4634AC: + test cl, cl + jz loc_4634CD + loc_4634B0: + mov eax, [esi] + add esi, 4 + mov dl, al + shr eax, 10h + mov dl, [ebx+edx] + mov [edi], dl + mov dl, al + add edi, 4 + mov dl, [ebx+edx] + dec ecx + mov [edi-2], dl + jnz loc_4634B0 + loc_4634CD: + jmp $+82h + loc_4634D2: + mov edx, ecx + and edx, 2 + add esi, edx + shr ecx, 1 + jb loc_463511 + shr ecx, 1 + jnb loc_4634EE + mov dl, [esi] + mov dl, [ebx+edx] + add esi, 2 + mov [edi], dl + add edi, 2 + loc_4634EE: + test cl, cl + jz loc_46350F + loc_4634F2: + mov eax, [esi] + add esi, 4 + mov dl, al + shr eax, 10h + mov dl, [ebx+edx] + mov [edi], dl + mov dl, al + add edi, 4 + mov dl, [ebx+edx] + dec ecx + mov [edi-2], dl + jnz loc_4634F2 + loc_46350F: + jmp loc_46354F + loc_463511: + mov dl, [esi] + mov dl, [ebx+edx] + inc esi + mov [edi], dl + inc edi + shr ecx, 1 + jnb loc_46352D + mov dl, [esi+1] + mov dl, [ebx+edx] + add esi, 2 + mov [edi+1], dl + add edi, 2 + loc_46352D: + test cl, cl + jz loc_46354F + loc_463531: + mov eax, [esi] + add esi, 4 + mov dl, ah + shr eax, 10h + mov dl, [ebx+edx] + mov [edi+1], dl + mov dl, ah + add edi, 4 + mov dl, [ebx+edx] + dec ecx + mov [edi-1], dl + jnz loc_463531 + loc_46354F: + sub edi, 320h + sub ebp, 2 + jge loc_463432 + mov ebp, 2 + loc_463563: + cmp edi, gpBufEnd + jb loc_463692 + add edi, ebp + mov ecx, 20h + sub ecx, ebp + mov eax, WorldBoolFlag + inc eax + and eax, 1 + mov WorldBoolFlag, eax + jz loc_463603 + mov edx, ecx + and edx, 2 + add esi, edx + shr ecx, 1 + jb loc_4635CA + shr ecx, 1 + jnb loc_4635A6 + mov dl, [esi+1] + mov dl, [ebx+edx] + add esi, 2 + mov [edi+1], dl + add edi, 2 + loc_4635A6: + test cl, cl + jz loc_4635C8 + loc_4635AA: + mov eax, [esi] + add esi, 4 + mov dl, ah + shr eax, 10h + mov dl, [ebx+edx] + mov [edi+1], dl + mov dl, ah + add edi, 4 + mov dl, [ebx+edx] + dec ecx + mov [edi-1], dl + jnz loc_4635AA + loc_4635C8: + jmp loc_4635FE + loc_4635CA: + inc esi + inc edi + shr ecx, 1 + jnb loc_4635DD + mov dl, [esi] + mov dl, [ebx+edx] + add esi, 2 + mov [edi], dl + add edi, 2 + loc_4635DD: + test cl, cl + jz loc_4635FE + loc_4635E1: + mov eax, [esi] + add esi, 4 + mov dl, al + shr eax, 10h + mov dl, [ebx+edx] + mov [edi], dl + mov dl, al + add edi, 4 + mov dl, [ebx+edx] + dec ecx + mov [edi-2], dl + jnz loc_4635E1 + loc_4635FE: + jmp $+82h + loc_463603: + mov edx, ecx + and edx, 2 + add esi, edx + shr ecx, 1 + jb loc_463642 + shr ecx, 1 + jnb loc_46361F + mov dl, [esi] + mov dl, [ebx+edx] + add esi, 2 + mov [edi], dl + add edi, 2 + loc_46361F: + test cl, cl + jz loc_463640 + loc_463623: + mov eax, [esi] + add esi, 4 + mov dl, al + shr eax, 10h + mov dl, [ebx+edx] + mov [edi], dl + mov dl, al + add edi, 4 + mov dl, [ebx+edx] + dec ecx + mov [edi-2], dl + jnz loc_463623 + loc_463640: + jmp loc_463680 + loc_463642: + mov dl, [esi] + mov dl, [ebx+edx] + inc esi + mov [edi], dl + inc edi + shr ecx, 1 + jnb loc_46365E + mov dl, [esi+1] + mov dl, [ebx+edx] + add esi, 2 + mov [edi+1], dl + add edi, 2 + loc_46365E: + test cl, cl + jz loc_463680 + loc_463662: + mov eax, [esi] + add esi, 4 + mov dl, ah + shr eax, 10h + mov dl, [ebx+edx] + mov [edi+1], dl + mov dl, ah + add edi, 4 + mov dl, [ebx+edx] + dec ecx + mov [edi-1], dl + jnz loc_463662 + loc_463680: + sub edi, 320h + add ebp, 2 + cmp ebp, 20h + jnz loc_463563 + loc_463692: + pop ebp + jmp loc_464688 + loc_463698: + push ebp + xor eax, eax + mov WorldBoolFlag, eax + mov ebp, 1Eh + loc_4636A5: + cmp edi, gpBufEnd + jb loc_463905 + mov ecx, 20h + sub ecx, ebp + mov eax, WorldBoolFlag + inc eax + and eax, 1 + mov WorldBoolFlag, eax + jz loc_463743 + shr ecx, 1 + jb loc_463703 + shr ecx, 1 + jnb loc_4636DF + mov dl, [esi+1] + mov dl, [ebx+edx] + add esi, 2 + mov [edi+1], dl + add edi, 2 + loc_4636DF: + test cl, cl + jz loc_463701 + loc_4636E3: + mov eax, [esi] + add esi, 4 + mov dl, ah + shr eax, 10h + mov dl, [ebx+edx] + mov [edi+1], dl + mov dl, ah + add edi, 4 + mov dl, [ebx+edx] + dec ecx + mov [edi-1], dl + jnz loc_4636E3 + loc_463701: + jmp loc_463737 + loc_463703: + inc esi + inc edi + shr ecx, 1 + jnb loc_463716 + mov dl, [esi] + mov dl, [ebx+edx] + add esi, 2 + mov [edi], dl + add edi, 2 + loc_463716: + test cl, cl + jz loc_463737 + loc_46371A: + mov eax, [esi] + add esi, 4 + mov dl, al + shr eax, 10h + mov dl, [ebx+edx] + mov [edi], dl + mov dl, al + add edi, 4 + mov dl, [ebx+edx] + dec ecx + mov [edi-2], dl + jnz loc_46371A + loc_463737: + mov edx, esi + and edx, 2 + add esi, edx + jmp $+82h + loc_463743: + shr ecx, 1 + jb loc_46377B + shr ecx, 1 + jnb loc_463758 + mov dl, [esi] + mov dl, [ebx+edx] + add esi, 2 + mov [edi], dl + add edi, 2 + loc_463758: + test cl, cl + jz loc_463779 + loc_46375C: + mov eax, [esi] + add esi, 4 + mov dl, al + shr eax, 10h + mov dl, [ebx+edx] + mov [edi], dl + mov dl, al + add edi, 4 + mov dl, [ebx+edx] + dec ecx + mov [edi-2], dl + jnz loc_46375C + loc_463779: + jmp loc_4637B9 + loc_46377B: + mov dl, [esi] + mov dl, [ebx+edx] + inc esi + mov [edi], dl + inc edi + shr ecx, 1 + jnb loc_463797 + mov dl, [esi+1] + mov dl, [ebx+edx] + add esi, 2 + mov [edi+1], dl + add edi, 2 + loc_463797: + test cl, cl + jz loc_4637B9 + loc_46379B: + mov eax, [esi] + add esi, 4 + mov dl, ah + shr eax, 10h + mov dl, [ebx+edx] + mov [edi+1], dl + mov dl, ah + add edi, 4 + mov dl, [ebx+edx] + dec ecx + mov [edi-1], dl + jnz loc_46379B + loc_4637B9: + mov edx, esi + and edx, 2 + add esi, edx + // loc_4637C0: + sub edi, 320h + add edi, ebp + sub ebp, 2 + jge loc_4636A5 + mov ebp, 2 + loc_4637D6: + cmp edi, gpBufEnd + jb loc_463905 + mov ecx, 20h + sub ecx, ebp + mov eax, WorldBoolFlag + inc eax + and eax, 1 + mov WorldBoolFlag, eax + jz loc_463874 + shr ecx, 1 + jb loc_463834 + shr ecx, 1 + jnb loc_463810 + mov dl, [esi+1] + mov dl, [ebx+edx] + add esi, 2 + mov [edi+1], dl + add edi, 2 + loc_463810: + test cl, cl + jz loc_463832 + loc_463814: + mov eax, [esi] + add esi, 4 + mov dl, ah + shr eax, 10h + mov dl, [ebx+edx] + mov [edi+1], dl + mov dl, ah + add edi, 4 + mov dl, [ebx+edx] + dec ecx + mov [edi-1], dl + jnz loc_463814 + loc_463832: + jmp loc_463868 + loc_463834: + inc esi + inc edi + shr ecx, 1 + jnb loc_463847 + mov dl, [esi] + mov dl, [ebx+edx] + add esi, 2 + mov [edi], dl + add edi, 2 + loc_463847: + test cl, cl + jz loc_463868 + loc_46384B: + mov eax, [esi] + add esi, 4 + mov dl, al + shr eax, 10h + mov dl, [ebx+edx] + mov [edi], dl + mov dl, al + add edi, 4 + mov dl, [ebx+edx] + dec ecx + mov [edi-2], dl + jnz loc_46384B + loc_463868: + mov edx, esi + and edx, 2 + add esi, edx + jmp $+82h + loc_463874: + shr ecx, 1 + jb loc_4638AC + shr ecx, 1 + jnb loc_463889 + mov dl, [esi] + mov dl, [ebx+edx] + add esi, 2 + mov [edi], dl + add edi, 2 + loc_463889: + test cl, cl + jz loc_4638AA + loc_46388D: + mov eax, [esi] + add esi, 4 + mov dl, al + shr eax, 10h + mov dl, [ebx+edx] + mov [edi], dl + mov dl, al + add edi, 4 + mov dl, [ebx+edx] + dec ecx + mov [edi-2], dl + jnz loc_46388D + loc_4638AA: + jmp loc_4638EA + loc_4638AC: + mov dl, [esi] + mov dl, [ebx+edx] + inc esi + mov [edi], dl + inc edi + shr ecx, 1 + jnb loc_4638C8 + mov dl, [esi+1] + mov dl, [ebx+edx] + add esi, 2 + mov [edi+1], dl + add edi, 2 + loc_4638C8: + test cl, cl + jz loc_4638EA + loc_4638CC: + mov eax, [esi] + add esi, 4 + mov dl, ah + shr eax, 10h + mov dl, [ebx+edx] + mov [edi+1], dl + mov dl, ah + add edi, 4 + mov dl, [ebx+edx] + dec ecx + mov [edi-1], dl + jnz loc_4638CC + loc_4638EA: + mov edx, esi + and edx, 2 + add esi, edx + // loc_4638F1: + sub edi, 320h + add edi, ebp + add ebp, 2 + cmp ebp, 20h + jnz loc_4637D6 + loc_463905: + pop ebp + jmp loc_464688 + loc_46390B: + push ebp + xor eax, eax + mov WorldBoolFlag, eax + mov ebp, 1Eh + loc_463918: + cmp edi, gpBufEnd + jb loc_463AAD + add edi, ebp + mov ecx, 20h + sub ecx, ebp + mov eax, WorldBoolFlag + inc eax + and eax, 1 + mov WorldBoolFlag, eax + jz loc_4639B8 + mov edx, ecx + and edx, 2 + add esi, edx + shr ecx, 1 + jb loc_46397F + shr ecx, 1 + jnb loc_46395B + mov dl, [esi+1] + mov dl, [ebx+edx] + add esi, 2 + mov [edi+1], dl + add edi, 2 + loc_46395B: + test cl, cl + jz loc_46397D + loc_46395F: + mov eax, [esi] + add esi, 4 + mov dl, ah + shr eax, 10h + mov dl, [ebx+edx] + mov [edi+1], dl + mov dl, ah + add edi, 4 + mov dl, [ebx+edx] + dec ecx + mov [edi-1], dl + jnz loc_46395F + loc_46397D: + jmp loc_4639B3 + loc_46397F: + inc esi + inc edi + shr ecx, 1 + jnb loc_463992 + mov dl, [esi] + mov dl, [ebx+edx] + add esi, 2 + mov [edi], dl + add edi, 2 + loc_463992: + test cl, cl + jz loc_4639B3 + loc_463996: + mov eax, [esi] + add esi, 4 + mov dl, al + shr eax, 10h + mov dl, [ebx+edx] + mov [edi], dl + mov dl, al + add edi, 4 + mov dl, [ebx+edx] + dec ecx + mov [edi-2], dl + jnz loc_463996 + loc_4639B3: + jmp $+82h + loc_4639B8: + mov edx, ecx + and edx, 2 + add esi, edx + shr ecx, 1 + jb loc_4639F7 + shr ecx, 1 + jnb loc_4639D4 + mov dl, [esi] + mov dl, [ebx+edx] + add esi, 2 + mov [edi], dl + add edi, 2 + loc_4639D4: + test cl, cl + jz loc_4639F5 + loc_4639D8: + mov eax, [esi] + add esi, 4 + mov dl, al + shr eax, 10h + mov dl, [ebx+edx] + mov [edi], dl + mov dl, al + add edi, 4 + mov dl, [ebx+edx] + dec ecx + mov [edi-2], dl + jnz loc_4639D8 + loc_4639F5: + jmp loc_463A35 + loc_4639F7: + mov dl, [esi] + mov dl, [ebx+edx] + inc esi + mov [edi], dl + inc edi + shr ecx, 1 + jnb loc_463A13 + mov dl, [esi+1] + mov dl, [ebx+edx] + add esi, 2 + mov [edi+1], dl + add edi, 2 + loc_463A13: + test cl, cl + jz loc_463A35 + loc_463A17: + mov eax, [esi] + add esi, 4 + mov dl, ah + shr eax, 10h + mov dl, [ebx+edx] + mov [edi+1], dl + mov dl, ah + add edi, 4 + mov dl, [ebx+edx] + dec ecx + mov [edi-1], dl + jnz loc_463A17 + loc_463A35: + sub edi, 320h + sub ebp, 2 + jge loc_463918 + mov ebp, 8 + loc_463A49: + cmp edi, gpBufEnd + jb loc_463AAD + mov ecx, 8 + loc_463A56: + mov eax, [esi] + add esi, 4 + mov dl, ah + shr eax, 10h + mov dl, [ebx+edx] + mov [edi+1], dl + mov dl, ah + add edi, 4 + mov dl, [ebx+edx] + dec ecx + mov [edi-1], dl + jnz loc_463A56 + sub edi, 320h + cmp edi, gpBufEnd + jb loc_463AAD + mov ecx, 8 + loc_463A87: + mov eax, [esi] + add esi, 4 + mov dl, al + shr eax, 10h + mov dl, [ebx+edx] + mov [edi], dl + mov dl, al + add edi, 4 + mov dl, [ebx+edx] + dec ecx + mov [edi-2], dl + jnz loc_463A87 + sub edi, 320h + dec ebp + jnz loc_463A49 + loc_463AAD: + pop ebp + jmp loc_464688 + loc_463AB3: + push ebp + xor eax, eax + mov WorldBoolFlag, eax + mov ebp, 1Eh + loc_463AC0: + cmp edi, gpBufEnd + jb loc_463C55 + mov ecx, 20h + sub ecx, ebp + mov eax, WorldBoolFlag + inc eax + and eax, 1 + mov WorldBoolFlag, eax + jz loc_463B5E + shr ecx, 1 + jb loc_463B1E + shr ecx, 1 + jnb loc_463AFA + mov dl, [esi+1] + mov dl, [ebx+edx] + add esi, 2 + mov [edi+1], dl + add edi, 2 + loc_463AFA: + test cl, cl + jz loc_463B1C + loc_463AFE: + mov eax, [esi] + add esi, 4 + mov dl, ah + shr eax, 10h + mov dl, [ebx+edx] + mov [edi+1], dl + mov dl, ah + add edi, 4 + mov dl, [ebx+edx] + dec ecx + mov [edi-1], dl + jnz loc_463AFE + loc_463B1C: + jmp loc_463B52 + loc_463B1E: + inc esi + inc edi + shr ecx, 1 + jnb loc_463B31 + mov dl, [esi] + mov dl, [ebx+edx] + add esi, 2 + mov [edi], dl + add edi, 2 + loc_463B31: + test cl, cl + jz loc_463B52 + loc_463B35: + mov eax, [esi] + add esi, 4 + mov dl, al + shr eax, 10h + mov dl, [ebx+edx] + mov [edi], dl + mov dl, al + add edi, 4 + mov dl, [ebx+edx] + dec ecx + mov [edi-2], dl + jnz loc_463B35 + loc_463B52: + mov edx, esi + and edx, 2 + add esi, edx + jmp $+82h + loc_463B5E: + shr ecx, 1 + jb loc_463B96 + shr ecx, 1 + jnb loc_463B73 + mov dl, [esi] + mov dl, [ebx+edx] + add esi, 2 + mov [edi], dl + add edi, 2 + loc_463B73: + test cl, cl + jz loc_463B94 + loc_463B77: + mov eax, [esi] + add esi, 4 + mov dl, al + shr eax, 10h + mov dl, [ebx+edx] + mov [edi], dl + mov dl, al + add edi, 4 + mov dl, [ebx+edx] + dec ecx + mov [edi-2], dl + jnz loc_463B77 + loc_463B94: + jmp loc_463BD4 + loc_463B96: + mov dl, [esi] + mov dl, [ebx+edx] + inc esi + mov [edi], dl + inc edi + shr ecx, 1 + jnb loc_463BB2 + mov dl, [esi+1] + mov dl, [ebx+edx] + add esi, 2 + mov [edi+1], dl + add edi, 2 + loc_463BB2: + test cl, cl + jz loc_463BD4 + loc_463BB6: + mov eax, [esi] + add esi, 4 + mov dl, ah + shr eax, 10h + mov dl, [ebx+edx] + mov [edi+1], dl + mov dl, ah + add edi, 4 + mov dl, [ebx+edx] + dec ecx + mov [edi-1], dl + jnz loc_463BB6 + loc_463BD4: + mov edx, esi + and edx, 2 + add esi, edx + // loc_463BDB: + sub edi, 320h + add edi, ebp + sub ebp, 2 + jge loc_463AC0 + mov ebp, 8 + loc_463BF1: + cmp edi, gpBufEnd + jb loc_463C55 + mov ecx, 8 + loc_463BFE: + mov eax, [esi] + add esi, 4 + mov dl, ah + shr eax, 10h + mov dl, [ebx+edx] + mov [edi+1], dl + mov dl, ah + add edi, 4 + mov dl, [ebx+edx] + dec ecx + mov [edi-1], dl + jnz loc_463BFE + sub edi, 320h + cmp edi, gpBufEnd + jb loc_463C55 + mov ecx, 8 + loc_463C2F: + mov eax, [esi] + add esi, 4 + mov dl, al + shr eax, 10h + mov dl, [ebx+edx] + mov [edi], dl + mov dl, al + add edi, 4 + mov dl, [ebx+edx] + dec ecx + mov [edi-2], dl + jnz loc_463C2F + sub edi, 320h + dec ebp + jnz loc_463BF1 + loc_463C55: + pop ebp + jmp loc_464688 + loc_463C5B: + mov edx, 10h + loc_463C60: + cmp edi, gpBufEnd + jb loc_464688 + mov ecx, 8 + loc_463C71: + mov eax, [esi] + add esi, 4 + inc edi + ror eax, 8 + mov [edi], al + add edi, 2 + ror eax, 10h + mov [edi], al + inc edi + dec ecx + jnz loc_463C71 + sub edi, 320h + cmp edi, gpBufEnd + jb loc_464688 + mov ecx, 8 + loc_463C9F: + mov eax, [esi] + add esi, 4 + mov [edi], al + add edi, 2 + ror eax, 10h + mov [edi], al + add edi, 2 + dec ecx + jnz loc_463C9F + sub edi, 320h + dec edx + jnz loc_463C60 + jmp loc_464688 + loc_463CC2: + push ebp + mov eax, edi + and eax, 1 + mov WorldBoolFlag, eax + mov ebp, 20h + loc_463CD2: + mov edx, 20h + loc_463CD7: + xor eax, eax + mov al, [esi] + inc esi + test al, al + js loc_463D76 + sub edx, eax + cmp edi, gpBufEnd + jb loc_463D9D + mov ecx, eax + mov eax, edi + and eax, 1 + cmp eax, WorldBoolFlag + jnz loc_463D36 + shr ecx, 1 + jnb loc_463D0D + inc esi + inc edi + test ecx, ecx + jz loc_463D6D + jmp loc_463D46 + loc_463D0D: + shr ecx, 1 + jnb loc_463D1D + inc esi + inc edi + mov al, [esi] + inc esi + mov [edi], al + inc edi + test ecx, ecx + jz loc_463D6D + loc_463D1D: + mov eax, [esi] + add esi, 4 + inc edi + ror eax, 8 + mov [edi], al + add edi, 2 + ror eax, 10h + mov [edi], al + inc edi + dec ecx + jnz loc_463D1D + jmp loc_463D6D + loc_463D36: + shr ecx, 1 + jnb loc_463D46 + mov al, [esi] + inc esi + mov [edi], al + inc edi + test ecx, ecx + jz loc_463D6D + jmp loc_463D0D + loc_463D46: + shr ecx, 1 + jnb loc_463D58 + mov al, [esi] + add esi, 2 + mov [edi], al + add edi, 2 + test ecx, ecx + jz loc_463D6D + loc_463D58: + mov eax, [esi] + add esi, 4 + mov [edi], al + add edi, 2 + ror eax, 10h + mov [edi], al + add edi, 2 + dec ecx + jnz loc_463D58 + loc_463D6D: + test edx, edx + jz loc_463D82 + jmp loc_463CD7 + loc_463D76: + neg al + add edi, eax + sub edx, eax + jnz loc_463CD7 + loc_463D82: + mov eax, WorldBoolFlag + inc eax + and eax, 1 + mov WorldBoolFlag, eax + sub edi, 320h + dec ebp + jnz loc_463CD2 + loc_463D9D: + pop ebp + jmp loc_464688 + loc_463DA3: + xor eax, eax + mov WorldBoolFlag, eax + mov edx, 1Eh + loc_463DAF: + cmp edi, gpBufEnd + jb loc_464688 + add edi, edx + mov ecx, 20h + sub ecx, edx + mov eax, WorldBoolFlag + inc eax + and eax, 1 + mov WorldBoolFlag, eax + jz loc_463E04 + shr ecx, 2 + jnb loc_463DEB + mov ax, [esi+2] + add esi, 4 + inc edi + ror eax, 8 + mov [edi], al + inc edi + test ecx, ecx + jz loc_463E2E + loc_463DEB: + mov eax, [esi] + add esi, 4 + inc edi + ror eax, 8 + mov [edi], al + add edi, 2 + ror eax, 10h + mov [edi], al + inc edi + dec ecx + jnz loc_463DEB + jmp loc_463E2E + loc_463E04: + shr ecx, 2 + jnb loc_463E19 + mov ax, [esi+2] + add esi, 4 + mov [edi], al + add edi, 2 + test ecx, ecx + jz loc_463E2E + loc_463E19: + mov eax, [esi] + add esi, 4 + mov [edi], al + add edi, 2 + ror eax, 10h + mov [edi], al + add edi, 2 + dec ecx + jnz loc_463E19 + loc_463E2E: + sub edi, 320h + sub edx, 2 + jge loc_463DAF + mov edx, 2 + loc_463E42: + cmp edi, gpBufEnd + jb loc_464688 + add edi, edx + mov ecx, 20h + sub ecx, edx + mov eax, WorldBoolFlag + inc eax + and eax, 1 + mov WorldBoolFlag, eax + jz loc_463E97 + shr ecx, 2 + jnb loc_463E7E + mov ax, [esi+2] + add esi, 4 + inc edi + ror eax, 8 + mov [edi], al + inc edi + test ecx, ecx + jz loc_463EC1 + loc_463E7E: + mov eax, [esi] + add esi, 4 + inc edi + ror eax, 8 + mov [edi], al + add edi, 2 + ror eax, 10h + mov [edi], al + inc edi + dec ecx + jnz loc_463E7E + jmp loc_463EC1 + loc_463E97: + shr ecx, 2 + jnb loc_463EAC + mov ax, [esi+2] + add esi, 4 + mov [edi], al + add edi, 2 + test ecx, ecx + jz loc_463EC1 + loc_463EAC: + mov eax, [esi] + add esi, 4 + mov [edi], al + add edi, 2 + ror eax, 10h + mov [edi], al + add edi, 2 + dec ecx + jnz loc_463EAC + loc_463EC1: + sub edi, 320h + add edx, 2 + cmp edx, 20h + jnz loc_463E42 + jmp loc_464688 + loc_463ED8: + push ebp + xor eax, eax + mov WorldBoolFlag, eax + mov edx, 1Eh + loc_463EE5: + cmp edi, gpBufEnd + jb loc_46400B + mov ecx, 20h + sub ecx, edx + mov eax, WorldBoolFlag + inc eax + and eax, 1 + mov ebp, ecx + mov WorldBoolFlag, eax + jz loc_463F3A + shr ecx, 2 + jz loc_463F26 + loc_463F0F: + mov eax, [esi] + add esi, 4 + inc edi + ror eax, 8 + mov [edi], al + add edi, 2 + ror eax, 10h + mov [edi], al + inc edi + dec ecx + jnz loc_463F0F + loc_463F26: + and ebp, 2 + jz loc_463F64 + mov ax, [esi] + add esi, 4 + inc edi + ror eax, 8 + mov [edi], al + inc edi + jmp loc_463F64 + loc_463F3A: + shr ecx, 2 + jz loc_463F54 + loc_463F3F: + mov eax, [esi] + add esi, 4 + mov [edi], al + add edi, 2 + ror eax, 10h + mov [edi], al + add edi, 2 + dec ecx + jnz loc_463F3F + loc_463F54: + and ebp, 2 + jz loc_463F64 + mov ax, [esi] + add esi, 4 + mov [edi], al + add edi, 2 + loc_463F64: + sub edi, 320h + add edi, edx + sub edx, 2 + jge loc_463EE5 + mov edx, 2 + loc_463F7A: + cmp edi, gpBufEnd + jb loc_46400B + mov ecx, 20h + sub ecx, edx + mov eax, WorldBoolFlag + inc eax + and eax, 1 + mov WorldBoolFlag, eax + jz loc_463FCD + shr ecx, 2 + jz loc_463FB9 + loc_463FA2: + mov eax, [esi] + add esi, 4 + inc edi + ror eax, 8 + mov [edi], al + add edi, 2 + ror eax, 10h + mov [edi], al + inc edi + dec ecx + jnz loc_463FA2 + loc_463FB9: + and ebp, 2 + jz loc_463FF7 + mov ax, [esi] + add esi, 4 + inc edi + ror eax, 8 + mov [edi], al + inc edi + jmp loc_463FF7 + loc_463FCD: + shr ecx, 2 + jz loc_463FE7 + loc_463FD2: + mov eax, [esi] + add esi, 4 + mov [edi], al + add edi, 2 + ror eax, 10h + mov [edi], al + add edi, 2 + dec ecx + jnz loc_463FD2 + loc_463FE7: + and ebp, 2 + jz loc_463FF7 + mov ax, [esi] + add esi, 4 + mov [edi], al + add edi, 2 + loc_463FF7: + sub edi, 320h + add edi, edx + add edx, 2 + cmp edx, 20h + jnz loc_463F7A + loc_46400B: + pop ebp + jmp loc_464688 + loc_464011: + xor eax, eax + mov WorldBoolFlag, eax + mov edx, 1Eh + loc_46401D: + cmp edi, gpBufEnd + jb loc_464688 + add edi, edx + mov ecx, 20h + sub ecx, edx + mov eax, WorldBoolFlag + inc eax + and eax, 1 + mov WorldBoolFlag, eax + jz loc_464072 + shr ecx, 2 + jnb loc_464059 + mov ax, [esi+2] + add esi, 4 + inc edi + ror eax, 8 + mov [edi], al + inc edi + test ecx, ecx + jz loc_46409C + loc_464059: + mov eax, [esi] + add esi, 4 + inc edi + ror eax, 8 + mov [edi], al + add edi, 2 + ror eax, 10h + mov [edi], al + inc edi + dec ecx + jnz loc_464059 + jmp loc_46409C + loc_464072: + shr ecx, 2 + jnb loc_464087 + mov ax, [esi+2] + add esi, 4 + mov [edi], al + add edi, 2 + test ecx, ecx + jz loc_46409C + loc_464087: + mov eax, [esi] + add esi, 4 + mov [edi], al + add edi, 2 + ror eax, 10h + mov [edi], al + add edi, 2 + dec ecx + jnz loc_464087 + loc_46409C: + sub edi, 320h + sub edx, 2 + jge loc_46401D + mov edx, 8 + loc_4640B0: + cmp edi, gpBufEnd + jb loc_464688 + mov ecx, 8 + loc_4640C1: + mov eax, [esi] + add esi, 4 + inc edi + ror eax, 8 + mov [edi], al + add edi, 2 + ror eax, 10h + mov [edi], al + inc edi + dec ecx + jnz loc_4640C1 + sub edi, 320h + cmp edi, gpBufEnd + jb loc_464688 + mov ecx, 8 + loc_4640EF: + mov eax, [esi] + add esi, 4 + mov [edi], al + add edi, 2 + ror eax, 10h + mov [edi], al + add edi, 2 + dec ecx + jnz loc_4640EF + sub edi, 320h + dec edx + jnz loc_4640B0 + jmp loc_464688 + loc_464112: + push ebp + xor eax, eax + mov WorldBoolFlag, eax + mov edx, 1Eh + loc_46411F: + cmp edi, gpBufEnd + jb loc_464209 + mov ecx, 20h + sub ecx, edx + mov eax, WorldBoolFlag + inc eax + and eax, 1 + mov ebp, ecx + mov WorldBoolFlag, eax + jz loc_464174 + shr ecx, 2 + jz loc_464160 + loc_464149: + mov eax, [esi] + add esi, 4 + inc edi + ror eax, 8 + mov [edi], al + add edi, 2 + ror eax, 10h + mov [edi], al + inc edi + dec ecx + jnz loc_464149 + loc_464160: + and ebp, 2 + jz loc_46419E + mov ax, [esi] + add esi, 4 + inc edi + ror eax, 8 + mov [edi], al + inc edi + jmp loc_46419E + loc_464174: + shr ecx, 2 + jz loc_46418E + loc_464179: + mov eax, [esi] + add esi, 4 + mov [edi], al + add edi, 2 + ror eax, 10h + mov [edi], al + add edi, 2 + dec ecx + jnz loc_464179 + loc_46418E: + and ebp, 2 + jz loc_46419E + mov ax, [esi] + add esi, 4 + mov [edi], al + add edi, 2 + loc_46419E: + sub edi, 320h + add edi, edx + sub edx, 2 + jge loc_46411F + mov edx, 8 + loc_4641B4: + cmp edi, gpBufEnd + jb loc_464209 + mov ecx, 8 + loc_4641C1: + mov eax, [esi] + add esi, 4 + inc edi + ror eax, 8 + mov [edi], al + add edi, 2 + ror eax, 10h + mov [edi], al + inc edi + dec ecx + jnz loc_4641C1 + sub edi, 320h + cmp edi, gpBufEnd + jb loc_464209 + mov ecx, 8 + loc_4641EB: + mov eax, [esi] + add esi, 4 + mov [edi], al + add edi, 2 + ror eax, 10h + mov [edi], al + add edi, 2 + dec ecx + jnz loc_4641EB + sub edi, 320h + dec edx + jnz loc_4641B4 + loc_464209: + pop ebp + jmp loc_464688 + loc_46420F: + mov edx, 10h + xor eax, eax + loc_464216: + cmp edi, gpBufEnd + jb loc_464688 + mov ecx, 8 + loc_464227: + mov [edi+1], al + mov [edi+3], al + add edi, 4 + dec ecx + jnz loc_464227 + sub edi, 320h + cmp edi, gpBufEnd + jb loc_464688 + mov ecx, 8 + loc_46424A: + mov [edi], al + mov [edi+2], al + add edi, 4 + dec ecx + jnz loc_46424A + sub edi, 320h + dec edx + jnz loc_464216 + jmp loc_464688 + loc_464263: + push ebp + mov eax, edi + and eax, 1 + mov WorldBoolFlag, eax + mov ebp, 20h + loc_464273: + mov edx, 20h + loc_464278: + xor eax, eax + mov al, [esi] + inc esi + test al, al + js loc_4642F4 + sub edx, eax + cmp edi, gpBufEnd + jb loc_46431B + mov ecx, eax + add esi, ecx + mov eax, edi + and eax, 1 + cmp eax, WorldBoolFlag + jnz loc_4642C7 + xor eax, eax + shr ecx, 1 + jnb loc_4642AD + inc edi + test ecx, ecx + jz loc_4642EE + jmp loc_4642D6 + loc_4642AD: + shr ecx, 1 + jnb loc_4642B9 + inc edi + mov [edi], al + inc edi + test ecx, ecx + jz loc_4642EE + loc_4642B9: + mov [edi+1], al + mov [edi+3], al + add edi, 4 + dec ecx + jnz loc_4642B9 + jmp loc_4642EE + loc_4642C7: + xor eax, eax + shr ecx, 1 + jnb loc_4642D6 + mov [edi], al + inc edi + test ecx, ecx + jz loc_4642EE + jmp loc_4642AD + loc_4642D6: + shr ecx, 1 + jnb loc_4642E3 + mov [edi], al + add edi, 2 + test ecx, ecx + jz loc_4642EE + loc_4642E3: + mov [edi], al + mov [edi+2], al + add edi, 4 + dec ecx + jnz loc_4642E3 + loc_4642EE: + test edx, edx + jz loc_464300 + jmp loc_464278 + loc_4642F4: + neg al + add edi, eax + sub edx, eax + jnz loc_464278 + loc_464300: + mov eax, WorldBoolFlag + inc eax + and eax, 1 + mov WorldBoolFlag, eax + sub edi, 320h + dec ebp + jnz loc_464273 + loc_46431B: + pop ebp + jmp loc_464688 + loc_464321: + xor eax, eax + mov WorldBoolFlag, eax + mov edx, 1Eh + loc_46432D: + cmp edi, gpBufEnd + jb loc_464688 + add edi, edx + mov ecx, 20h + sub ecx, edx + mov eax, WorldBoolFlag + inc eax + and eax, 1 + mov WorldBoolFlag, eax + jz loc_46436F + xor eax, eax + shr ecx, 2 + jnb loc_464361 + inc edi + mov [edi], al + inc edi + test ecx, ecx + jz loc_46438A + loc_464361: + mov [edi+1], al + mov [edi+3], al + add edi, 4 + dec ecx + jnz loc_464361 + jmp loc_46438A + loc_46436F: + xor eax, eax + shr ecx, 2 + jnb loc_46437F + mov [edi], al + add edi, 2 + test ecx, ecx + jz loc_46438A + loc_46437F: + mov [edi], al + mov [edi+2], al + add edi, 4 + dec ecx + jnz loc_46437F + loc_46438A: + sub edi, 320h + test edx, edx + jz loc_464399 + sub edx, 2 + jmp loc_46432D + loc_464399: + mov edx, 2 + loc_46439E: + cmp edi, gpBufEnd + jb loc_464688 + add edi, edx + mov ecx, 20h + sub ecx, edx + mov eax, WorldBoolFlag + inc eax + and eax, 1 + mov WorldBoolFlag, eax + jz loc_4643E0 + xor eax, eax + shr ecx, 2 + jnb loc_4643D2 + inc edi + mov [edi], al + inc edi + test ecx, ecx + jz loc_4643FB + loc_4643D2: + mov [edi+1], al + mov [edi+3], al + add edi, 4 + dec ecx + jnz loc_4643D2 + jmp loc_4643FB + loc_4643E0: + xor eax, eax + shr ecx, 2 + jnb loc_4643F0 + mov [edi], al + add edi, 2 + test ecx, ecx + jz loc_4643FB + loc_4643F0: + mov [edi], al + mov [edi+2], al + add edi, 4 + dec ecx + jnz loc_4643F0 + loc_4643FB: + sub edi, 320h + add edx, 2 + cmp edx, 20h + jnz loc_46439E + jmp loc_464688 + loc_46440E: + xor eax, eax + mov WorldBoolFlag, eax + mov edx, 1Eh + loc_46441A: + cmp edi, gpBufEnd + jb loc_464688 + mov ecx, 20h + sub ecx, edx + mov eax, WorldBoolFlag + inc eax + and eax, 1 + mov WorldBoolFlag, eax + jz loc_46445A + xor eax, eax + shr ecx, 2 + jnb loc_46444C + inc edi + mov [edi], al + inc edi + test ecx, ecx + jz loc_464475 + loc_46444C: + mov [edi+1], al + mov [edi+3], al + add edi, 4 + dec ecx + jnz loc_46444C + jmp loc_464475 + loc_46445A: + xor eax, eax + shr ecx, 2 + jnb loc_46446A + mov [edi], al + add edi, 2 + test ecx, ecx + jz loc_464475 + loc_46446A: + mov [edi], al + mov [edi+2], al + add edi, 4 + dec ecx + jnz loc_46446A + loc_464475: + sub edi, 320h + test edx, edx + jz loc_464486 + add edi, edx + sub edx, 2 + jmp loc_46441A + loc_464486: + mov edx, 2 + loc_46448B: + cmp edi, gpBufEnd + jb loc_464688 + mov ecx, 20h + sub ecx, edx + mov eax, WorldBoolFlag + inc eax + and eax, 1 + mov WorldBoolFlag, eax + jz loc_4644CB + xor eax, eax + shr ecx, 2 + jnb loc_4644BD + inc edi + mov [edi], al + inc edi + test ecx, ecx + jz loc_4644E6 + loc_4644BD: + mov [edi+1], al + mov [edi+3], al + add edi, 4 + dec ecx + jnz loc_4644BD + jmp loc_4644E6 + loc_4644CB: + xor eax, eax + shr ecx, 2 + jnb loc_4644DB + mov [edi], al + add edi, 2 + test ecx, ecx + jz loc_4644E6 + loc_4644DB: + mov [edi], al + mov [edi+2], al + add edi, 4 + dec ecx + jnz loc_4644DB + loc_4644E6: + sub edi, 320h + add edi, edx + add edx, 2 + cmp edx, 20h + jnz loc_46448B + jmp loc_464688 + loc_4644FB: + xor eax, eax + mov WorldBoolFlag, eax + mov edx, 1Eh + loc_464507: + cmp edi, gpBufEnd + jb loc_464688 + add edi, edx + mov ecx, 20h + sub ecx, edx + mov eax, WorldBoolFlag + inc eax + and eax, 1 + mov WorldBoolFlag, eax + jz loc_464549 + xor eax, eax + shr ecx, 2 + jnb loc_46453B + inc edi + mov [edi], al + inc edi + test ecx, ecx + jz loc_464564 + loc_46453B: + mov [edi+1], al + mov [edi+3], al + add edi, 4 + dec ecx + jnz loc_46453B + jmp loc_464564 + loc_464549: + xor eax, eax + shr ecx, 2 + jnb loc_464559 + mov [edi], al + add edi, 2 + test ecx, ecx + jz loc_464564 + loc_464559: + mov [edi], al + mov [edi+2], al + add edi, 4 + dec ecx + jnz loc_464559 + loc_464564: + sub edi, 320h + test edx, edx + jz loc_464573 + sub edx, 2 + jmp loc_464507 + loc_464573: + mov edx, 8 + xor eax, eax + loc_46457A: + cmp edi, gpBufEnd + jb loc_464688 + mov ecx, 8 + loc_46458B: + mov [edi+1], al + mov [edi+3], al + add edi, 4 + dec ecx + jnz loc_46458B + sub edi, 320h + cmp edi, gpBufEnd + jb loc_464688 + mov ecx, 8 + loc_4645AE: + mov [edi], al + mov [edi+2], al + add edi, 4 + dec ecx + jnz loc_4645AE + sub edi, 320h + dec edx + jnz loc_46457A + jmp loc_464688 + loc_4645C7: + xor eax, eax + mov WorldBoolFlag, eax + mov edx, 1Eh + loc_4645D3: + cmp edi, gpBufEnd + jb loc_464688 + mov ecx, 20h + sub ecx, edx + mov eax, WorldBoolFlag + inc eax + and eax, 1 + mov WorldBoolFlag, eax + jz loc_464613 + xor eax, eax + shr ecx, 2 + jnb loc_464605 + inc edi + mov [edi], al + inc edi + test ecx, ecx + jz loc_46462E + loc_464605: + mov [edi+1], al + mov [edi+3], al + add edi, 4 + dec ecx + jnz loc_464605 + jmp loc_46462E + loc_464613: + xor eax, eax + shr ecx, 2 + jnb loc_464623 + mov [edi], al + add edi, 2 + test ecx, ecx + jz loc_46462E + loc_464623: + mov [edi], al + mov [edi+2], al + add edi, 4 + dec ecx + jnz loc_464623 + loc_46462E: + sub edi, 320h + test edx, edx + jz loc_46463F + add edi, edx + sub edx, 2 + jmp loc_4645D3 + loc_46463F: + mov edx, 8 + xor eax, eax + loc_464646: + cmp edi, gpBufEnd + jb loc_464688 + mov ecx, 8 + loc_464653: + mov [edi+1], al + mov [edi+3], al + add edi, 4 + dec ecx + jnz loc_464653 + sub edi, 320h + cmp edi, gpBufEnd + jb loc_464688 + mov ecx, 8 + loc_464672: + mov [edi], al + mov [edi+2], al + add edi, 4 + dec ecx + jnz loc_464672 + sub edi, 320h + dec edx + jnz loc_464646 + jmp loc_464688 + loc_464688: + pop esi + pop edi + pop edx + pop ebx + retn + } +} + +__declspec(naked) void drawBottomArchesUpperScreen(BYTE *pBuff, unsigned int *pMask) +{ + __asm { + push ebx + push edi + push esi + mov edi, offset SpeedFrameTbl + mov gpCelFrame, edi + mov edi, ecx + mov gpDrawMask, edx + mov eax, light_table_index + test al, al + jz loc_4647A2 + cmp al, lightmax + jz loc_464802 + mov eax, level_cel_block + and eax, 8000h + jnz loc_464736 + mov ebx, pDungeonCels + mov esi, ebx + mov eax, level_cel_block + and eax, 0FFFh + shl eax, 2 + add ebx, eax + add esi, [ebx] + mov ebx, light_table_index + shl ebx, 8 + add ebx, pLightTbl + mov eax, level_cel_block + mov al, ah + shr eax, 4 + and eax, 0Fh + jz loc_46488D + jz loc_464FBC + cmp ax, 1 + jz loc_4648D5 + cmp ax, 2 + jz loc_464964 + cmp ax, 3 + jz loc_464A30 + cmp ax, 4 + jz loc_464AFE + jmp loc_464BBC + loc_464736: + mov esi, gpCelFrame + mov eax, level_cel_block + and eax, 0FFFh + shl eax, 4 + add eax, light_table_index + shl eax, 2 + add esi, eax + mov eax, [esi] + mov esi, pSpeedCels + add esi, eax + mov eax, level_cel_block + mov al, ah + shr eax, 4 + and eax, 0Fh + loc_46476B: + cmp ax, 8 + jz loc_464C7A + cmp ax, 9 + jz loc_464CC1 + cmp ax, 0Ah + jz loc_464D4B + cmp ax, 0Bh + jz loc_464DE3 + cmp ax, 0Ch + jz loc_464E7D + jmp loc_464F19 + loc_4647A2: + mov eax, level_cel_block + and eax, 8000h + jz loc_4647D4 + mov esi, gpCelFrame + mov eax, level_cel_block + and eax, 0FFFh + shl eax, 6 + add esi, eax + mov eax, level_cel_block + and eax, 0F000h + add eax, [esi] + mov level_cel_block, eax + loc_4647D4: + mov ebx, pDungeonCels + mov esi, ebx + mov eax, level_cel_block + and eax, 0FFFh + shl eax, 2 + add ebx, eax + add esi, [ebx] + mov eax, level_cel_block + mov al, ah + shr eax, 4 + and eax, 7 + add eax, 8 + jmp loc_46476B + loc_464802: + mov eax, level_cel_block + and eax, 8000h + jz loc_464834 + mov esi, gpCelFrame + mov eax, level_cel_block + and eax, 0FFFh + shl eax, 6 + add esi, eax + mov eax, level_cel_block + and eax, 0F000h + add eax, [esi] + mov level_cel_block, eax + loc_464834: + mov ebx, pDungeonCels + mov esi, ebx + mov eax, level_cel_block + and eax, 0FFFh + shl eax, 2 + add ebx, eax + add esi, [ebx] + mov eax, level_cel_block + mov al, ah + shr eax, 4 + and eax, 7 + jz loc_464FBC + cmp ax, 1 + jz loc_465002 + cmp ax, 2 + jz loc_465091 + cmp ax, 3 + jz loc_465117 + cmp ax, 4 + jz loc_46519D + jmp loc_465232 + loc_46488D: + mov edx, 20h + loc_464892: + cmp edi, gpBufEnd + jb loc_4652C1 + push edx + mov eax, gpDrawMask + mov edx, [eax] + mov ecx, 20h + loc_4648AB: + mov al, [esi] + inc esi + shl edx, 1 + jnb loc_4648B5 + xlat + mov [edi], al + loc_4648B5: + inc edi + dec ecx + jnz loc_4648AB + pop edx + sub edi, 320h + mov eax, gpDrawMask + sub eax, 4 + mov gpDrawMask, eax + dec edx + jnz loc_464892 + jmp loc_4652C1 + loc_4648D5: + mov ecx, 20h + loc_4648DA: + push ecx + mov eax, gpDrawMask + mov eax, [eax] + mov gdwCurrentMask, eax + mov edx, 20h + loc_4648EC: + xor eax, eax + mov al, [esi] + inc esi + test al, al + js loc_464927 + sub edx, eax + cmp edi, gpBufEnd + jb loc_4652C0 + mov ecx, eax + push edx + mov edx, gdwCurrentMask + loc_46490C: + mov al, [esi] + inc esi + shl edx, 1 + jnb loc_464916 + xlat + mov [edi], al + loc_464916: + inc edi + dec ecx + jnz loc_46490C + mov gdwCurrentMask, edx + pop edx + test edx, edx + jz loc_464944 + jmp loc_4648EC + loc_464927: + neg al + add edi, eax + mov ecx, eax + and ecx, 1Fh + jz loc_464940 + push eax + mov eax, gdwCurrentMask + shl eax, cl + mov gdwCurrentMask, eax + pop eax + loc_464940: + sub edx, eax + jnz loc_4648EC + loc_464944: + pop ecx + sub edi, 320h + mov eax, gpDrawMask + sub eax, 4 + mov gpDrawMask, eax + dec ecx + jnz loc_4648DA + jmp loc_4652C1 + loc_464964: + mov edx, 1Eh + loc_464969: + cmp edi, gpBufEnd + jb loc_4652C1 + add edi, edx + mov ecx, 20h + sub ecx, edx + shr ecx, 2 + jnb loc_46499E + mov ax, [esi+2] + add esi, 4 + xlat + ror ax, 8 + xlat + ror ax, 8 + mov [edi], ax + add edi, 2 + test ecx, ecx + jz loc_4649BB + loc_46499E: + mov eax, [esi] + add esi, 4 + xlat + ror eax, 8 + xlat + ror eax, 8 + xlat + ror eax, 8 + xlat + ror eax, 8 + mov [edi], eax + add edi, 4 + dec ecx + jnz loc_46499E + loc_4649BB: + sub edi, 320h + sub edx, 2 + jge loc_464969 + mov edx, 2 + loc_4649CB: + cmp edi, gpBufEnd + jb loc_4652C1 + add edi, edx + mov ecx, 20h + sub ecx, edx + shr ecx, 2 + jnb loc_464A00 + mov ax, [esi+2] + add esi, 4 + xlat + ror ax, 8 + xlat + ror ax, 8 + mov [edi], ax + add edi, 2 + test ecx, ecx + jz loc_464A1D + loc_464A00: + mov eax, [esi] + add esi, 4 + xlat + ror eax, 8 + xlat + ror eax, 8 + xlat + ror eax, 8 + xlat + ror eax, 8 + mov [edi], eax + add edi, 4 + dec ecx + jnz loc_464A00 + loc_464A1D: + sub edi, 320h + add edx, 2 + cmp edx, 20h + jnz loc_4649CB + jmp loc_4652C1 + loc_464A30: + push ebp + mov edx, 1Eh + loc_464A36: + cmp edi, gpBufEnd + jb loc_464AF8 + mov ecx, 20h + sub ecx, edx + mov ebp, ecx + shr ecx, 2 + jz loc_464A6D + loc_464A50: + mov eax, [esi] + add esi, 4 + xlat + ror eax, 8 + xlat + ror eax, 8 + xlat + ror eax, 8 + xlat + ror eax, 8 + mov [edi], eax + add edi, 4 + dec ecx + jnz loc_464A50 + loc_464A6D: + and ebp, 2 + jz loc_464A88 + mov ax, [esi] + add esi, 4 + xlat + ror ax, 8 + xlat + ror ax, 8 + mov [edi], ax + add edi, 2 + loc_464A88: + sub edi, 320h + add edi, edx + sub edx, 2 + jge loc_464A36 + mov edx, 2 + loc_464A9A: + cmp edi, gpBufEnd + jb loc_464AF8 + mov ecx, 20h + sub ecx, edx + mov ebp, ecx + shr ecx, 2 + jz loc_464ACD + loc_464AB0: + mov eax, [esi] + add esi, 4 + xlat + ror eax, 8 + xlat + ror eax, 8 + xlat + ror eax, 8 + xlat + ror eax, 8 + mov [edi], eax + add edi, 4 + dec ecx + jnz loc_464AB0 + loc_464ACD: + and ebp, 2 + jz loc_464AE8 + mov ax, [esi] + add esi, 4 + xlat + ror ax, 8 + xlat + ror ax, 8 + mov [edi], ax + add edi, 2 + loc_464AE8: + sub edi, 320h + add edi, edx + add edx, 2 + cmp edx, 20h + jnz loc_464A9A + loc_464AF8: + pop ebp + jmp loc_4652C1 + loc_464AFE: + mov edx, 1Eh + loc_464B03: + cmp edi, gpBufEnd + jb loc_4652C1 + add edi, edx + mov ecx, 20h + sub ecx, edx + shr ecx, 2 + jnb loc_464B38 + mov ax, [esi+2] + add esi, 4 + xlat + ror ax, 8 + xlat + ror ax, 8 + mov [edi], ax + add edi, 2 + test ecx, ecx + jz loc_464B55 + loc_464B38: + mov eax, [esi] + add esi, 4 + xlat + ror eax, 8 + xlat + ror eax, 8 + xlat + ror eax, 8 + xlat + ror eax, 8 + mov [edi], eax + add edi, 4 + dec ecx + jnz loc_464B38 + loc_464B55: + sub edi, 320h + sub edx, 2 + jge loc_464B03 + mov eax, gpDrawMask + sub eax, 40h + mov gpDrawMask, eax + mov edx, 10h + loc_464B72: + cmp edi, gpBufEnd + jb loc_4652C1 + push edx + mov eax, gpDrawMask + mov edx, [eax] + mov ecx, 20h + mov eax, esi + and eax, 2 + add esi, eax + loc_464B92: + mov al, [esi] + inc esi + shl edx, 1 + jnb loc_464B9C + xlat + mov [edi], al + loc_464B9C: + inc edi + dec ecx + jnz loc_464B92 + pop edx + sub edi, 320h + mov eax, gpDrawMask + sub eax, 4 + mov gpDrawMask, eax + dec edx + jnz loc_464B72 + jmp loc_4652C1 + loc_464BBC: + push ebp + mov edx, 1Eh + loc_464BC2: + cmp edi, gpBufEnd + jb loc_464C74 + mov ecx, 20h + sub ecx, edx + mov ebp, ecx + shr ecx, 2 + jz loc_464BF9 + loc_464BDC: + mov eax, [esi] + add esi, 4 + xlat + ror eax, 8 + xlat + ror eax, 8 + xlat + ror eax, 8 + xlat + ror eax, 8 + mov [edi], eax + add edi, 4 + dec ecx + jnz loc_464BDC + loc_464BF9: + and ebp, 2 + jz loc_464C14 + mov ax, [esi] + add esi, 4 + xlat + ror ax, 8 + xlat + ror ax, 8 + mov [edi], ax + add edi, 2 + loc_464C14: + sub edi, 320h + add edi, edx + sub edx, 2 + jge loc_464BC2 + mov eax, gpDrawMask + sub eax, 40h + mov gpDrawMask, eax + mov edx, 10h + loc_464C33: + cmp edi, gpBufEnd + jb loc_464C74 + push edx + mov eax, gpDrawMask + mov edx, [eax] + mov ecx, 20h + loc_464C48: + mov al, [esi] + inc esi + shl edx, 1 + jnb loc_464C52 + xlat + mov [edi], al + loc_464C52: + inc edi + dec ecx + jnz loc_464C48 + mov ebp, esi + and ebp, 2 + add esi, ebp + pop edx + sub edi, 320h + mov eax, gpDrawMask + sub eax, 4 + mov gpDrawMask, eax + dec edx + jnz loc_464C33 + loc_464C74: + pop ebp + jmp loc_4652C1 + loc_464C7A: + mov edx, 20h + loc_464C7F: + cmp edi, gpBufEnd + jb loc_4652C1 + push edx + mov eax, gpDrawMask + mov edx, [eax] + mov ecx, 20h + loc_464C98: + mov al, [esi] + inc esi + shl edx, 1 + jnb loc_464CA1 + mov [edi], al + loc_464CA1: + inc edi + dec ecx + jnz loc_464C98 + pop edx + sub edi, 320h + mov eax, gpDrawMask + sub eax, 4 + mov gpDrawMask, eax + dec edx + jnz loc_464C7F + jmp loc_4652C1 + loc_464CC1: + mov ecx, 20h + loc_464CC6: + push ecx + mov eax, gpDrawMask + mov eax, [eax] + mov gdwCurrentMask, eax + mov edx, 20h + loc_464CD8: + xor eax, eax + mov al, [esi] + inc esi + test al, al + js loc_464D12 + sub edx, eax + cmp edi, gpBufEnd + jb loc_4652C0 + push edx + mov edx, gdwCurrentMask + mov ecx, eax + loc_464CF8: + mov al, [esi] + inc esi + shl edx, 1 + jnb loc_464D01 + mov [edi], al + loc_464D01: + inc edi + dec ecx + jnz loc_464CF8 + mov gdwCurrentMask, edx + pop edx + test edx, edx + jz loc_464D2F + jmp loc_464CD8 + loc_464D12: + neg al + add edi, eax + mov ecx, eax + and ecx, 1Fh + jz loc_464D2B + mov ebx, gdwCurrentMask + shl ebx, cl + mov gdwCurrentMask, ebx + loc_464D2B: + sub edx, eax + jnz loc_464CD8 + loc_464D2F: + pop ecx + sub edi, 320h + mov eax, gpDrawMask + sub eax, 4 + mov gpDrawMask, eax + dec ecx + jnz loc_464CC6 + jmp loc_4652C1 + loc_464D4B: + mov edx, 1Eh + loc_464D50: + cmp edi, gpBufEnd + jb loc_4652C1 + add edi, edx + mov ecx, 20h + sub ecx, edx + shr ecx, 2 + jnb loc_464D7B + mov ax, [esi+2] + add esi, 4 + mov [edi], ax + add edi, 2 + test ecx, ecx + jz loc_464D88 + loc_464D7B: + mov eax, [esi] + add esi, 4 + mov [edi], eax + dec ecx + lea edi, [edi+4] + jnz loc_464D7B + loc_464D88: + sub edi, 320h + sub edx, 2 + jge loc_464D50 + mov edx, 2 + loc_464D98: + cmp edi, gpBufEnd + jb loc_4652C1 + add edi, edx + mov ecx, 20h + sub ecx, edx + shr ecx, 2 + jnb loc_464DC3 + mov ax, [esi+2] + add esi, 4 + mov [edi], ax + test ecx, ecx + lea edi, [edi+2] + jz loc_464DD0 + loc_464DC3: + mov eax, [esi] + add esi, 4 + mov [edi], eax + add edi, 4 + dec ecx + jnz loc_464DC3 + loc_464DD0: + sub edi, 320h + add edx, 2 + cmp edx, 20h + jnz loc_464D98 + jmp loc_4652C1 + loc_464DE3: + push ebp + mov edx, 1Eh + loc_464DE9: + cmp edi, gpBufEnd + jb loc_464E77 + mov ecx, 20h + sub ecx, edx + mov ebp, ecx + shr ecx, 2 + jz loc_464E10 + loc_464E03: + mov eax, [esi] + add esi, 4 + mov [edi], eax + add edi, 4 + dec ecx + jnz loc_464E03 + loc_464E10: + and ebp, 2 + jz loc_464E21 + mov ax, [esi] + add esi, 4 + mov [edi], ax + add edi, 2 + loc_464E21: + sub edi, 320h + add edi, edx + sub edx, 2 + jge loc_464DE9 + mov edx, 2 + loc_464E33: + cmp edi, gpBufEnd + jb loc_464E77 + mov ecx, 20h + sub ecx, edx + mov ebp, ecx + shr ecx, 2 + jz loc_464E56 + loc_464E49: + mov eax, [esi] + add esi, 4 + mov [edi], eax + add edi, 4 + dec ecx + jnz loc_464E49 + loc_464E56: + and ebp, 2 + jz loc_464E67 + mov ax, [esi] + add esi, 4 + mov [edi], ax + add edi, 2 + loc_464E67: + sub edi, 320h + add edi, edx + add edx, 2 + cmp edx, 20h + jnz loc_464E33 + loc_464E77: + pop ebp + jmp loc_4652C1 + loc_464E7D: + mov edx, 1Eh + loc_464E82: + cmp edi, gpBufEnd + jb loc_4652C1 + add edi, edx + mov ecx, 20h + sub ecx, edx + shr ecx, 2 + jnb loc_464EAD + mov ax, [esi+2] + add esi, 4 + mov [edi], ax + add edi, 2 + test ecx, ecx + jz loc_464EBA + loc_464EAD: + mov eax, [esi] + add esi, 4 + mov [edi], eax + add edi, 4 + dec ecx + jnz loc_464EAD + loc_464EBA: + sub edi, 320h + sub edx, 2 + jge loc_464E82 + mov eax, gpDrawMask + sub eax, 40h + mov gpDrawMask, eax + mov edx, 10h + loc_464ED7: + cmp edi, gpBufEnd + jb loc_4652C1 + push edx + mov eax, gpDrawMask + mov edx, [eax] + mov ecx, 20h + loc_464EF0: + mov al, [esi] + inc esi + shl edx, 1 + jnb loc_464EF9 + mov [edi], al + loc_464EF9: + inc edi + dec ecx + jnz loc_464EF0 + pop edx + sub edi, 320h + mov eax, gpDrawMask + sub eax, 4 + mov gpDrawMask, eax + dec edx + jnz loc_464ED7 + jmp loc_4652C1 + loc_464F19: + push ebp + mov edx, 1Eh + loc_464F1F: + cmp edi, gpBufEnd + jb loc_464FB6 + mov ecx, 20h + sub ecx, edx + mov ebp, ecx + shr ecx, 2 + jz loc_464F46 + loc_464F39: + mov eax, [esi] + add esi, 4 + mov [edi], eax + add edi, 4 + dec ecx + jnz loc_464F39 + loc_464F46: + and ebp, 2 + jz loc_464F57 + mov ax, [esi] + add esi, 4 + mov [edi], ax + add edi, 2 + loc_464F57: + sub edi, 320h + add edi, edx + sub edx, 2 + jge loc_464F1F + mov eax, gpDrawMask + sub eax, 40h + mov gpDrawMask, eax + mov edx, 10h + loc_464F76: + cmp edi, gpBufEnd + jb loc_464FB6 + push edx + mov eax, gpDrawMask + mov edx, [eax] + mov ecx, 20h + loc_464F8B: + mov al, [esi] + inc esi + shl edx, 1 + jnb loc_464F94 + mov [edi], al + loc_464F94: + inc edi + dec ecx + jnz loc_464F8B + mov ebp, esi + and ebp, 2 + add esi, ebp + pop edx + sub edi, 320h + mov eax, gpDrawMask + sub eax, 4 + mov gpDrawMask, eax + dec edx + jnz loc_464F76 + loc_464FB6: + pop ebp + jmp loc_4652C1 + loc_464FBC: + mov edx, 20h + loc_464FC1: + cmp edi, gpBufEnd + jb loc_4652C1 + push edx + mov eax, gpDrawMask + mov edx, [eax] + xor eax, eax + mov ecx, 20h + loc_464FDC: + shl edx, 1 + jnb loc_464FE2 + mov [edi], al + loc_464FE2: + inc edi + dec ecx + jnz loc_464FDC + pop edx + sub edi, 320h + mov eax, gpDrawMask + sub eax, 4 + mov gpDrawMask, eax + dec edx + jnz loc_464FC1 + jmp loc_4652C1 + loc_465002: + mov ecx, 20h + loc_465007: + push ecx + mov eax, gpDrawMask + mov eax, [eax] + mov gdwCurrentMask, eax + mov edx, 20h + loc_465019: + xor eax, eax + mov al, [esi] + inc esi + test al, al + js loc_465054 + sub edx, eax + cmp edi, gpBufEnd + jb loc_4652C0 + push edx + mov edx, gdwCurrentMask + mov ecx, eax + add esi, ecx + xor eax, eax + loc_46503D: + shl edx, 1 + jnb loc_465043 + mov [edi], al + loc_465043: + inc edi + dec ecx + jnz loc_46503D + mov gdwCurrentMask, edx + pop edx + test edx, edx + jz loc_465071 + jmp loc_465019 + loc_465054: + neg al + add edi, eax + mov ecx, eax + and ecx, 1Fh + jz loc_46506D + mov ebx, gdwCurrentMask + shl ebx, cl + mov gdwCurrentMask, ebx + loc_46506D: + sub edx, eax + jnz loc_465019 + loc_465071: + pop ecx + sub edi, 320h + mov eax, gpDrawMask + sub eax, 4 + mov gpDrawMask, eax + dec ecx + jnz loc_465007 + jmp loc_4652C1 + loc_465091: + mov edx, 1Eh + xor eax, eax + loc_465098: + cmp edi, gpBufEnd + jb loc_4652C1 + add edi, edx + mov ecx, 20h + sub ecx, edx + shr ecx, 2 + jnb loc_4650BC + mov [edi], ax + add edi, 2 + test ecx, ecx + jz loc_4650C4 + loc_4650BC: + mov [edi], eax + add edi, 4 + dec ecx + jnz loc_4650BC + loc_4650C4: + sub edi, 320h + test edx, edx + jz loc_4650D3 + sub edx, 2 + jmp loc_465098 + loc_4650D3: + mov edx, 2 + loc_4650D8: + cmp edi, gpBufEnd + jb loc_4652C1 + add edi, edx + mov ecx, 20h + sub ecx, edx + shr ecx, 2 + jnb loc_4650FC + mov [edi], ax + add edi, 2 + test ecx, ecx + jz loc_465104 + loc_4650FC: + mov [edi], eax + add edi, 4 + dec ecx + jnz loc_4650FC + loc_465104: + sub edi, 320h + add edx, 2 + cmp edx, 20h + jnz loc_4650D8 + jmp loc_4652C1 + loc_465117: + mov edx, 1Eh + xor eax, eax + loc_46511E: + cmp edi, gpBufEnd + jb loc_4652C1 + mov ecx, 20h + sub ecx, edx + shr ecx, 2 + jnb loc_465140 + mov [edi], ax + add edi, 2 + test ecx, ecx + jz loc_465148 + loc_465140: + mov [edi], eax + add edi, 4 + dec ecx + jnz loc_465140 + loc_465148: + sub edi, 320h + test edx, edx + jz loc_465159 + add edi, edx + sub edx, 2 + jmp loc_46511E + loc_465159: + mov edx, 2 + loc_46515E: + cmp edi, gpBufEnd + jb loc_4652C1 + mov ecx, 20h + sub ecx, edx + shr ecx, 2 + jnb loc_465180 + mov [edi], ax + add edi, 2 + test ecx, ecx + jz loc_465188 + loc_465180: + mov [edi], eax + add edi, 4 + dec ecx + jnz loc_465180 + loc_465188: + sub edi, 320h + add edi, edx + add edx, 2 + cmp edx, 20h + jnz loc_46515E + jmp loc_4652C1 + loc_46519D: + mov edx, 1Eh + xor eax, eax + loc_4651A4: + cmp edi, gpBufEnd + jb loc_4652C1 + add edi, edx + mov ecx, 20h + sub ecx, edx + shr ecx, 2 + jnb loc_4651C8 + mov [edi], ax + add edi, 2 + test ecx, ecx + jz loc_4651D0 + loc_4651C8: + mov [edi], eax + add edi, 4 + dec ecx + jnz loc_4651C8 + loc_4651D0: + sub edi, 320h + test edx, edx + jz loc_4651DF + sub edx, 2 + jmp loc_4651A4 + loc_4651DF: + mov eax, gpDrawMask + sub eax, 40h + mov gpDrawMask, eax + mov edx, 10h + loc_4651F1: + cmp edi, gpBufEnd + jb loc_4652C1 + push edx + mov eax, gpDrawMask + mov edx, [eax] + xor eax, eax + mov ecx, 20h + loc_46520C: + shl edx, 1 + jnb loc_465212 + mov [edi], al + loc_465212: + inc edi + dec ecx + jnz loc_46520C + pop edx + sub edi, 320h + mov eax, gpDrawMask + sub eax, 4 + mov gpDrawMask, eax + dec edx + jnz loc_4651F1 + jmp loc_4652C1 + loc_465232: + mov edx, 1Eh + xor eax, eax + loc_465239: + cmp edi, gpBufEnd + jb $+82h + mov ecx, 20h + sub ecx, edx + shr ecx, 2 + jnb loc_46525B + mov [edi], ax + add edi, 2 + test ecx, ecx + jz loc_465263 + loc_46525B: + mov [edi], eax + add edi, 4 + dec ecx + jnz loc_46525B + loc_465263: + sub edi, 320h + test edx, edx + jz loc_465274 + add edi, edx + sub edx, 2 + jmp loc_465239 + loc_465274: + mov eax, gpDrawMask + sub eax, 40h + mov gpDrawMask, eax + mov edx, 10h + loc_465286: + cmp edi, gpBufEnd + jb loc_4652C1 + push edx + mov eax, gpDrawMask + mov edx, [eax] + xor eax, eax + mov ecx, 20h + loc_46529D: + shl edx, 1 + jnb loc_4652A3 + mov [edi], al + loc_4652A3: + inc edi + dec ecx + jnz loc_46529D + pop edx + sub edi, 320h + mov eax, gpDrawMask + sub eax, 4 + mov gpDrawMask, eax + dec edx + jnz loc_465286 + jmp loc_4652C1 + loc_4652C0: + pop eax + loc_4652C1: + pop esi + pop edi + pop ebx + retn + } +} + +__declspec(naked) void drawUpperScreen(BYTE *pBuff) +{ + __asm { + push ebx + push edx + push edi + push esi + mov edx, cel_transparency_active + test edx, edx + jz loc_465372 + mov dl, arch_draw_type + cmp dl, 0 + jnz loc_4652EC + call drawTopArchesUpperScreen + jmp loc_465F33 + loc_4652EC: + cmp dl, 1 + jnz loc_46532F + mov ebx, level_piece_id + mov al, block_lvid[ebx] + cmp al, 1 + jz loc_465307 + cmp al, 3 + jz loc_465307 + jmp loc_46532F + loc_465307: + mov edx, offset LeftMask + add edx, 7Ch + call drawBottomArchesUpperScreen + jmp loc_465F33 + cmp al, 4 + jnz loc_46532F + mov edx, offset RightMask + add edx, 7Ch + call drawBottomArchesUpperScreen + jmp loc_465F33 + loc_46532F: + cmp dl, 2 + jnz loc_465372 + mov ebx, level_piece_id + mov al, block_lvid[ebx] + cmp al, 2 + jz loc_46534A + cmp al, 3 + jz loc_46534A + jmp loc_465372 + loc_46534A: + mov edx, offset RightMask + add edx, 7Ch + call drawBottomArchesUpperScreen + jmp loc_465F33 + cmp al, 4 + jnz loc_465372 + mov edx, offset LeftMask + add edx, 7Ch + call drawBottomArchesUpperScreen + jmp loc_465F33 + loc_465372: + mov edi, offset SpeedFrameTbl + mov gpCelFrame, edi + mov edi, ecx + mov eax, light_table_index + test al, al + jz loc_465474 + cmp al, lightmax + jz loc_4654D4 + mov eax, level_cel_block + and eax, 8000h + jnz loc_46540A + mov ebx, pDungeonCels + mov esi, ebx + mov eax, level_cel_block + and eax, 0FFFh + shl eax, 2 + add ebx, eax + add esi, [ebx] + mov ebx, light_table_index + shl ebx, 8 + add ebx, pLightTbl + mov eax, level_cel_block + shr eax, 0Ch + and eax, 0Fh + jz loc_46555D + cmp ax, 1 + jz loc_4655B5 + cmp ax, 2 + jz loc_465663 + cmp ax, 3 + jz loc_465765 + cmp ax, 4 + jz loc_465867 + jmp loc_465939 + loc_46540A: + mov esi, gpCelFrame + mov eax, level_cel_block + and eax, 0FFFh + shl eax, 4 + add eax, light_table_index + shl eax, 2 + add esi, eax + mov eax, [esi] + mov esi, pSpeedCels + add esi, eax + mov eax, level_cel_block + shr eax, 0Ch + and eax, 0Fh + loc_46543D: + cmp ax, 8 + jz loc_465A0B + cmp ax, 9 + jz loc_465A3C + cmp ax, 0Ah + jz loc_465AA8 + cmp ax, 0Bh + jz loc_465B40 + cmp ax, 0Ch + jz loc_465BDA + jmp loc_465C53 + loc_465474: + mov eax, level_cel_block + and eax, 8000h + jz loc_4654A6 + mov esi, gpCelFrame + mov eax, level_cel_block + and eax, 0FFFh + shl eax, 6 + add esi, eax + mov eax, level_cel_block + and eax, 0F000h + add eax, [esi] + mov level_cel_block, eax + loc_4654A6: + mov ebx, pDungeonCels + mov esi, ebx + mov eax, level_cel_block + and eax, 0FFFh + shl eax, 2 + add ebx, eax + add esi, [ebx] + mov eax, level_cel_block + mov al, ah + shr eax, 4 + and eax, 7 + add eax, 8 + jmp loc_46543D + loc_4654D4: + mov eax, level_cel_block + and eax, 8000h + jz loc_465506 + mov esi, gpCelFrame + mov eax, level_cel_block + and eax, 0FFFh + shl eax, 6 + add esi, eax + mov eax, level_cel_block + and eax, 0F000h + add eax, [esi] + mov level_cel_block, eax + loc_465506: + mov ebx, pDungeonCels + mov esi, ebx + mov eax, level_cel_block + and eax, 0FFFh + shl eax, 2 + add ebx, eax + add esi, [ebx] + mov eax, level_cel_block + shr eax, 0Ch + and eax, 7 + jz loc_465CC8 + cmp ax, 1 + jz loc_465CF6 + cmp ax, 2 + jz loc_465D58 + cmp ax, 3 + jz loc_465DDE + cmp ax, 4 + jz loc_465E64 + jmp loc_465ECF + loc_46555D: + mov edx, 20h + loc_465562: + cmp edi, gpBufEnd + jb loc_465F33 + mov ecx, 20h + push edx + loc_465574: + mov eax, [esi] + add esi, 4 + mov dl, al + mov ch, [ebx+edx] + mov dl, ah + ror eax, 10h + mov [edi], ch + mov ch, [ebx+edx] + mov dl, al + mov [edi+1], ch + mov ch, [ebx+edx] + mov dl, ah + mov [edi+2], ch + mov ch, [ebx+edx] + mov [edi+3], ch + add edi, 4 + sub cl, 4 + cmp cl, 4 + jge loc_465574 + pop edx + sub edi, 320h + dec edx + jnz loc_465562 + jmp loc_465F33 + loc_4655B5: + push ebp + mov ebp, 20h + loc_4655BB: + mov edx, 20h + loc_4655C0: + xor eax, eax + mov al, [esi] + inc esi + test al, al + js loc_465644 + sub edx, eax + cmp edi, gpBufEnd + jb loc_46565D + mov ecx, eax + push edx + cmp cl, 4 + jl loc_465611 + loc_4655DF: + mov eax, [esi] + add esi, 4 + mov dl, al + mov ch, [ebx+edx] + mov dl, ah + ror eax, 10h + mov [edi], ch + mov ch, [ebx+edx] + mov dl, al + mov [edi+1], ch + mov ch, [ebx+edx] + mov dl, ah + mov [edi+2], ch + mov ch, [ebx+edx] + mov [edi+3], ch + add edi, 4 + sub cl, 4 + cmp cl, 4 + jge loc_4655DF + loc_465611: + cmp cl, 2 + jl loc_46562C + mov dl, [esi] + mov ch, [ebx+edx] + mov [edi], ch + mov dl, [esi+1] + mov ch, [ebx+edx] + mov [edi+1], ch + add esi, 2 + add edi, 2 + loc_46562C: + and cl, 1 + jz loc_46563A + mov dl, [esi] + inc esi + mov dl, [ebx+edx] + mov [edi], dl + inc edi + loc_46563A: + pop edx + test edx, edx + jz loc_465650 + jmp loc_4655C0 + loc_465644: + neg al + add edi, eax + sub edx, eax + jnz loc_4655C0 + loc_465650: + sub edi, 320h + dec ebp + jnz loc_4655BB + loc_46565D: + pop ebp + jmp loc_465F33 + loc_465663: + push ebp + mov ebp, 1Eh + loc_465669: + cmp edi, gpBufEnd + jb loc_46575F + add edi, ebp + mov ecx, 20h + sub ecx, ebp + mov edx, ecx + and edx, 2 + add esi, edx + cmp cl, 4 + jl loc_4656BC + loc_46568A: + mov eax, [esi] + add esi, 4 + mov dl, al + mov ch, [ebx+edx] + mov dl, ah + ror eax, 10h + mov [edi], ch + mov ch, [ebx+edx] + mov dl, al + mov [edi+1], ch + mov ch, [ebx+edx] + mov dl, ah + mov [edi+2], ch + mov ch, [ebx+edx] + mov [edi+3], ch + add edi, 4 + sub cl, 4 + cmp cl, 4 + jge loc_46568A + loc_4656BC: + cmp cl, 2 + jl loc_4656D7 + mov dl, [esi] + mov ch, [ebx+edx] + mov [edi], ch + mov dl, [esi+1] + mov ch, [ebx+edx] + mov [edi+1], ch + add esi, 2 + add edi, 2 + loc_4656D7: + sub edi, 320h + sub ebp, 2 + jge loc_465669 + mov ebp, 2 + loc_4656E7: + cmp edi, gpBufEnd + jb loc_46575F + add edi, ebp + mov ecx, 20h + sub ecx, ebp + mov edx, ecx + and edx, 2 + add esi, edx + cmp cl, 4 + jl loc_465736 + loc_465704: + mov eax, [esi] + add esi, 4 + mov dl, al + mov ch, [ebx+edx] + mov dl, ah + ror eax, 10h + mov [edi], ch + mov ch, [ebx+edx] + mov dl, al + mov [edi+1], ch + mov ch, [ebx+edx] + mov dl, ah + mov [edi+2], ch + mov ch, [ebx+edx] + mov [edi+3], ch + add edi, 4 + sub cl, 4 + cmp cl, 4 + jge loc_465704 + loc_465736: + cmp cl, 2 + jl loc_465751 + mov dl, [esi] + mov ch, [ebx+edx] + mov [edi], ch + mov dl, [esi+1] + mov ch, [ebx+edx] + mov [edi+1], ch + add esi, 2 + add edi, 2 + loc_465751: + sub edi, 320h + add ebp, 2 + cmp ebp, 20h + jnz loc_4656E7 + loc_46575F: + pop ebp + jmp loc_465F33 + loc_465765: + push ebp + mov ebp, 1Eh + loc_46576B: + cmp edi, gpBufEnd + jb loc_465861 + mov ecx, 20h + sub ecx, ebp + cmp cl, 4 + jl loc_4657B5 + loc_465783: + mov eax, [esi] + add esi, 4 + mov dl, al + mov ch, [ebx+edx] + mov dl, ah + ror eax, 10h + mov [edi], ch + mov ch, [ebx+edx] + mov dl, al + mov [edi+1], ch + mov ch, [ebx+edx] + mov dl, ah + mov [edi+2], ch + mov ch, [ebx+edx] + mov [edi+3], ch + add edi, 4 + sub cl, 4 + cmp cl, 4 + jge loc_465783 + loc_4657B5: + cmp cl, 2 + jl loc_4657D0 + mov dl, [esi] + mov ch, [ebx+edx] + mov [edi], ch + mov dl, [esi+1] + mov ch, [ebx+edx] + mov [edi+1], ch + add esi, 2 + add edi, 2 + loc_4657D0: + mov edx, esi + and edx, 2 + add esi, edx + sub edi, 320h + add edi, ebp + sub ebp, 2 + jge loc_46576B + mov ebp, 2 + loc_4657E9: + cmp edi, gpBufEnd + jb loc_465861 + mov ecx, 20h + sub ecx, ebp + cmp cl, 4 + jl loc_46582F + loc_4657FD: + mov eax, [esi] + add esi, 4 + mov dl, al + mov ch, [ebx+edx] + mov dl, ah + ror eax, 10h + mov [edi], ch + mov ch, [ebx+edx] + mov dl, al + mov [edi+1], ch + mov ch, [ebx+edx] + mov dl, ah + mov [edi+2], ch + mov ch, [ebx+edx] + mov [edi+3], ch + add edi, 4 + sub cl, 4 + cmp cl, 4 + jge loc_4657FD + loc_46582F: + cmp cl, 2 + jl loc_46584A + mov dl, [esi] + mov ch, [ebx+edx] + mov [edi], ch + mov dl, [esi+1] + mov ch, [ebx+edx] + mov [edi+1], ch + add esi, 2 + add edi, 2 + loc_46584A: + mov edx, esi + and edx, 2 + add esi, edx + sub edi, 320h + add edi, ebp + add ebp, 2 + cmp ebp, 20h + jnz loc_4657E9 + loc_465861: + pop ebp + jmp loc_465F33 + loc_465867: + push ebp + mov ebp, 1Eh + loc_46586D: + cmp edi, gpBufEnd + jb loc_465933 + add edi, ebp + mov ecx, 20h + sub ecx, ebp + mov edx, ecx + and edx, 2 + add esi, edx + cmp cl, 4 + jl loc_4658C0 + loc_46588E: + mov eax, [esi] + add esi, 4 + mov dl, al + mov ch, [ebx+edx] + mov dl, ah + ror eax, 10h + mov [edi], ch + mov ch, [ebx+edx] + mov dl, al + mov [edi+1], ch + mov ch, [ebx+edx] + mov dl, ah + mov [edi+2], ch + mov ch, [ebx+edx] + mov [edi+3], ch + add edi, 4 + sub cl, 4 + cmp cl, 4 + jge loc_46588E + loc_4658C0: + cmp cl, 2 + jl loc_4658DB + mov dl, [esi] + mov ch, [ebx+edx] + mov [edi], ch + mov dl, [esi+1] + mov ch, [ebx+edx] + mov [edi+1], ch + add esi, 2 + add edi, 2 + loc_4658DB: + sub edi, 320h + sub ebp, 2 + jge loc_46586D + mov ebp, 10h + loc_4658EB: + cmp edi, gpBufEnd + jb loc_465933 + mov ecx, 20h + loc_4658F8: + mov eax, [esi] + add esi, 4 + mov dl, al + mov ch, [ebx+edx] + mov dl, ah + ror eax, 10h + mov [edi], ch + mov ch, [ebx+edx] + mov dl, al + mov [edi+1], ch + mov ch, [ebx+edx] + mov dl, ah + mov [edi+2], ch + mov ch, [ebx+edx] + mov [edi+3], ch + add edi, 4 + sub cl, 4 + cmp cl, 4 + jge loc_4658F8 + sub edi, 320h + dec ebp + jnz loc_4658EB + loc_465933: + pop ebp + jmp loc_465F33 + loc_465939: + push ebp + mov ebp, 1Eh + loc_46593F: + cmp edi, gpBufEnd + jb loc_465A05 + mov ecx, 20h + sub ecx, ebp + cmp cl, 4 + jl loc_465989 + loc_465957: + mov eax, [esi] + add esi, 4 + mov dl, al + mov ch, [ebx+edx] + mov dl, ah + ror eax, 10h + mov [edi], ch + mov ch, [ebx+edx] + mov dl, al + mov [edi+1], ch + mov ch, [ebx+edx] + mov dl, ah + mov [edi+2], ch + mov ch, [ebx+edx] + mov [edi+3], ch + add edi, 4 + sub cl, 4 + cmp cl, 4 + jge loc_465957 + loc_465989: + cmp cl, 2 + jl loc_4659A4 + mov dl, [esi] + mov ch, [ebx+edx] + mov [edi], ch + mov dl, [esi+1] + mov ch, [ebx+edx] + mov [edi+1], ch + add esi, 2 + add edi, 2 + loc_4659A4: + mov edx, esi + and edx, 2 + add esi, edx + sub edi, 320h + add edi, ebp + sub ebp, 2 + jge loc_46593F + mov ebp, 10h + loc_4659BD: + cmp edi, gpBufEnd + jb loc_465A05 + mov ecx, 20h + loc_4659CA: + mov eax, [esi] + add esi, 4 + mov dl, al + mov ch, [ebx+edx] + mov dl, ah + ror eax, 10h + mov [edi], ch + mov ch, [ebx+edx] + mov dl, al + mov [edi+1], ch + mov ch, [ebx+edx] + mov dl, ah + mov [edi+2], ch + mov ch, [ebx+edx] + mov [edi+3], ch + add edi, 4 + sub cl, 4 + cmp cl, 4 + jge loc_4659CA + sub edi, 320h + dec ebp + jnz loc_4659BD + loc_465A05: + pop ebp + jmp loc_465F33 + loc_465A0B: + mov edx, 20h + loc_465A10: + cmp edi, gpBufEnd + jb loc_465F33 + mov ecx, 8 + loc_465A21: + mov eax, [esi] + add esi, 4 + mov [edi], eax + add edi, 4 + dec ecx + jnz loc_465A21 + sub edi, 320h + dec edx + jnz loc_465A10 + jmp loc_465F33 + loc_465A3C: + push ebp + mov ebp, 20h + loc_465A42: + mov edx, 20h + loc_465A47: + xor eax, eax + mov al, [esi] + inc esi + test al, al + js loc_465A91 + sub edx, eax + cmp edi, gpBufEnd + jb loc_465AA2 + mov ecx, eax + shr ecx, 1 + jnb loc_465A6A + mov al, [esi] + inc esi + mov [edi], al + inc edi + test ecx, ecx + jz loc_465A8B + loc_465A6A: + shr ecx, 1 + jnb loc_465A7E + mov ax, [esi] + add esi, 2 + mov [edi], ax + add edi, 2 + test ecx, ecx + jz loc_465A8B + loc_465A7E: + mov eax, [esi] + add esi, 4 + mov [edi], eax + add edi, 4 + dec ecx + jnz loc_465A7E + loc_465A8B: + test edx, edx + jz loc_465A99 + jmp loc_465A47 + loc_465A91: + neg al + add edi, eax + sub edx, eax + jnz loc_465A47 + loc_465A99: + sub edi, 320h + dec ebp + jnz loc_465A42 + loc_465AA2: + pop ebp + jmp loc_465F33 + loc_465AA8: + mov edx, 1Eh + loc_465AAD: + cmp edi, gpBufEnd + jb loc_465F33 + add edi, edx + mov ecx, 20h + sub ecx, edx + shr ecx, 2 + jnb loc_465AD8 + mov ax, [esi+2] + add esi, 4 + mov [edi], ax + add edi, 2 + test ecx, ecx + jz loc_465AE5 + loc_465AD8: + mov eax, [esi] + add esi, 4 + mov [edi], eax + add edi, 4 + dec ecx + jnz loc_465AD8 + loc_465AE5: + sub edi, 320h + sub edx, 2 + jge loc_465AAD + mov edx, 2 + loc_465AF5: + cmp edi, gpBufEnd + jb loc_465F33 + add edi, edx + mov ecx, 20h + sub ecx, edx + shr ecx, 2 + jnb loc_465B20 + mov ax, [esi+2] + add esi, 4 + mov [edi], ax + add edi, 2 + test ecx, ecx + jz loc_465B2D + loc_465B20: + mov eax, [esi] + add esi, 4 + mov [edi], eax + add edi, 4 + dec ecx + jnz loc_465B20 + loc_465B2D: + sub edi, 320h + add edx, 2 + cmp edx, 20h + jnz loc_465AF5 + jmp loc_465F33 + loc_465B40: + push ebp + mov edx, 1Eh + loc_465B46: + cmp edi, gpBufEnd + jb loc_465BD4 + mov ecx, 20h + sub ecx, edx + mov ebp, ecx + shr ecx, 2 + jz loc_465B6D + loc_465B60: + mov eax, [esi] + add esi, 4 + mov [edi], eax + add edi, 4 + dec ecx + jnz loc_465B60 + loc_465B6D: + and ebp, 2 + jz loc_465B7E + mov ax, [esi] + add esi, 4 + mov [edi], ax + add edi, 2 + loc_465B7E: + sub edi, 320h + add edi, edx + sub edx, 2 + jge loc_465B46 + mov edx, 2 + loc_465B90: + cmp edi, gpBufEnd + jb loc_465BD4 + mov ecx, 20h + sub ecx, edx + mov ebp, ecx + shr ecx, 2 + jz loc_465BB3 + loc_465BA6: + mov eax, [esi] + add esi, 4 + mov [edi], eax + add edi, 4 + dec ecx + jnz loc_465BA6 + loc_465BB3: + and ebp, 2 + jz loc_465BC4 + mov ax, [esi] + add esi, 4 + mov [edi], ax + add edi, 2 + loc_465BC4: + sub edi, 320h + add edi, edx + add edx, 2 + cmp edx, 20h + jnz loc_465B90 + loc_465BD4: + pop ebp + jmp loc_465F33 + loc_465BDA: + mov edx, 1Eh + loc_465BDF: + cmp edi, gpBufEnd + jb loc_465F33 + add edi, edx + mov ecx, 20h + sub ecx, edx + shr ecx, 2 + jnb loc_465C0A + mov ax, [esi+2] + add esi, 4 + mov [edi], ax + add edi, 2 + test ecx, ecx + jz loc_465C17 + loc_465C0A: + mov eax, [esi] + add esi, 4 + mov [edi], eax + add edi, 4 + dec ecx + jnz loc_465C0A + loc_465C17: + sub edi, 320h + sub edx, 2 + jge loc_465BDF + mov edx, 10h + loc_465C27: + cmp edi, gpBufEnd + jb loc_465F33 + mov ecx, 8 + loc_465C38: + mov eax, [esi] + add esi, 4 + mov [edi], eax + add edi, 4 + dec ecx + jnz loc_465C38 + sub edi, 320h + dec edx + jnz loc_465C27 + jmp loc_465F33 + loc_465C53: + push ebp + mov edx, 1Eh + loc_465C59: + cmp edi, gpBufEnd + jb loc_465CC2 + mov ecx, 20h + sub ecx, edx + mov ebp, ecx + shr ecx, 2 + jz loc_465C7C + loc_465C6F: + mov eax, [esi] + add esi, 4 + mov [edi], eax + add edi, 4 + dec ecx + jnz loc_465C6F + loc_465C7C: + and ebp, 2 + jz loc_465C8D + mov ax, [esi] + add esi, 4 + mov [edi], ax + add edi, 2 + loc_465C8D: + sub edi, 320h + add edi, edx + sub edx, 2 + jge loc_465C59 + mov edx, 10h + loc_465C9F: + cmp edi, gpBufEnd + jb loc_465CC2 + mov ecx, 8 + loc_465CAC: + mov eax, [esi] + add esi, 4 + mov [edi], eax + add edi, 4 + dec ecx + jnz loc_465CAC + sub edi, 320h + dec edx + jnz loc_465C9F + loc_465CC2: + pop ebp + jmp loc_465F33 + loc_465CC8: + mov edx, 20h + xor eax, eax + loc_465CCF: + cmp edi, gpBufEnd + jb loc_465F33 + mov ecx, 8 + loc_465CE0: + mov [edi], eax + add edi, 4 + dec ecx + jnz loc_465CE0 + sub edi, 320h + dec edx + jnz loc_465CCF + jmp loc_465F33 + loc_465CF6: + push ebp + mov ebp, 20h + loc_465CFC: + mov edx, 20h + loc_465D01: + xor eax, eax + mov al, [esi] + inc esi + test al, al + js loc_465D41 + sub edx, eax + cmp edi, gpBufEnd + jb loc_465D52 + mov ecx, eax + add esi, ecx + xor eax, eax + shr ecx, 1 + jnb loc_465D25 + mov [edi], al + inc edi + test ecx, ecx + jz loc_465D3B + loc_465D25: + shr ecx, 1 + jnb loc_465D33 + mov [edi], ax + add edi, 2 + test ecx, ecx + jz loc_465D3B + loc_465D33: + mov [edi], eax + add edi, 4 + dec ecx + jnz loc_465D33 + loc_465D3B: + test edx, edx + jz loc_465D49 + jmp loc_465D01 + loc_465D41: + neg al + add edi, eax + sub edx, eax + jnz loc_465D01 + loc_465D49: + sub edi, 320h + dec ebp + jnz loc_465CFC + loc_465D52: + pop ebp + jmp loc_465F33 + loc_465D58: + mov edx, 1Eh + xor eax, eax + loc_465D5F: + cmp edi, gpBufEnd + jb loc_465F33 + add edi, edx + mov ecx, 20h + sub ecx, edx + shr ecx, 2 + jnb loc_465D83 + mov [edi], ax + add edi, 2 + test ecx, ecx + jz loc_465D8B + loc_465D83: + mov [edi], eax + add edi, 4 + dec ecx + jnz loc_465D83 + loc_465D8B: + sub edi, 320h + test edx, edx + jz loc_465D9A + sub edx, 2 + jmp loc_465D5F + loc_465D9A: + mov edx, 2 + loc_465D9F: + cmp edi, gpBufEnd + jb loc_465F33 + add edi, edx + mov ecx, 20h + sub ecx, edx + shr ecx, 2 + jnb loc_465DC3 + mov [edi], ax + add edi, 2 + test ecx, ecx + jz loc_465DCB + loc_465DC3: + mov [edi], eax + add edi, 4 + dec ecx + jnz loc_465DC3 + loc_465DCB: + sub edi, 320h + add edx, 2 + cmp edx, 20h + jnz loc_465D9F + jmp loc_465F33 + loc_465DDE: + mov edx, 1Eh + xor eax, eax + loc_465DE5: + cmp edi, gpBufEnd + jb loc_465F33 + mov ecx, 20h + sub ecx, edx + shr ecx, 2 + jnb loc_465E07 + mov [edi], ax + add edi, 2 + test ecx, ecx + jz loc_465E0F + loc_465E07: + mov [edi], eax + add edi, 4 + dec ecx + jnz loc_465E07 + loc_465E0F: + sub edi, 320h + test edx, edx + jz loc_465E20 + add edi, edx + sub edx, 2 + jmp loc_465DE5 + loc_465E20: + mov edx, 2 + loc_465E25: + cmp edi, gpBufEnd + jb loc_465F33 + mov ecx, 20h + sub ecx, edx + shr ecx, 2 + jnb loc_465E47 + mov [edi], ax + add edi, 2 + test ecx, ecx + jz loc_465E4F + loc_465E47: + mov [edi], eax + add edi, 4 + dec ecx + jnz loc_465E47 + loc_465E4F: + sub edi, 320h + add edi, edx + add edx, 2 + cmp edx, 20h + jnz loc_465E25 + jmp loc_465F33 + loc_465E64: + mov edx, 1Eh + xor eax, eax + loc_465E6B: + cmp edi, gpBufEnd + jb loc_465F33 + add edi, edx + mov ecx, 20h + sub ecx, edx + shr ecx, 2 + jnb loc_465E8F + mov [edi], ax + add edi, 2 + test ecx, ecx + jz loc_465E97 + loc_465E8F: + mov [edi], eax + add edi, 4 + dec ecx + jnz loc_465E8F + loc_465E97: + sub edi, 320h + test edx, edx + jz loc_465EA6 + sub edx, 2 + jmp loc_465E6B + loc_465EA6: + mov edx, 10h + loc_465EAB: + cmp edi, gpBufEnd + jb $+82h + mov ecx, 8 + loc_465EBC: + mov [edi], eax + add edi, 4 + dec ecx + jnz loc_465EBC + sub edi, 320h + dec edx + jnz loc_465EAB + jmp loc_465F33 + loc_465ECF: + mov edx, 1Eh + xor eax, eax + loc_465ED6: + cmp edi, gpBufEnd + jb loc_465F33 + mov ecx, 20h + sub ecx, edx + shr ecx, 2 + jnb loc_465EF4 + mov [edi], ax + add edi, 2 + test ecx, ecx + jz loc_465EFC + loc_465EF4: + mov [edi], eax + add edi, 4 + dec ecx + jnz loc_465EF4 + loc_465EFC: + sub edi, 320h + test edx, edx + jz loc_465F0D + add edi, edx + sub edx, 2 + jmp loc_465ED6 + loc_465F0D: + mov edx, 10h + loc_465F12: + cmp edi, gpBufEnd + jb loc_465F33 + mov ecx, 8 + loc_465F1F: + mov [edi], eax + add edi, 4 + dec ecx + jnz loc_465F1F + sub edi, 320h + dec edx + jnz loc_465F12 + jmp loc_465F33 + pop eax + loc_465F33: + pop esi + pop edi + pop edx + pop ebx + retn + } +} + +__declspec(naked) void drawTopArchesLowerScreen(BYTE *pBuff) +{ + __asm { + push ebx + push edx + push edi + push esi + mov edi, offset SpeedFrameTbl + mov gpCelFrame, edi + mov edi, ecx + mov eax, light_table_index + test al, al + jz loc_466042 + cmp al, lightmax + jz loc_4660A2 + mov eax, level_cel_block + and eax, 8000h + jnz loc_465FD6 + mov ebx, pDungeonCels + mov esi, ebx + mov eax, level_cel_block + and eax, 0FFFh + shl eax, 2 + add ebx, eax + add esi, [ebx] + mov ebx, light_table_index + shl ebx, 8 + add ebx, pLightTbl + mov eax, level_cel_block + mov al, ah + shr eax, 4 + and eax, 0Fh + jz loc_46612D + cmp ax, 1 + jz loc_4661AD + cmp ax, 2 + jz loc_466310 + cmp ax, 3 + jz loc_466611 + cmp ax, 4 + jz loc_466912 + jmp loc_466B11 + loc_465FD6: + mov esi, gpCelFrame + mov eax, level_cel_block + and eax, 0FFFh + shl eax, 4 + add eax, light_table_index + shl eax, 2 + add esi, eax + mov eax, [esi] + mov esi, pSpeedCels + add esi, eax + mov eax, level_cel_block + mov al, ah + shr eax, 4 + and eax, 0Fh + loc_46600B: + cmp ax, 8 + jz loc_466D10 + cmp ax, 9 + jz loc_466D7F + cmp ax, 0Ah + jz loc_466E62 + cmp ax, 0Bh + jz loc_46701C + cmp ax, 0Ch + jz loc_4671E1 + jmp loc_46732D + loc_466042: + mov eax, level_cel_block + and eax, 8000h + jz loc_466074 + mov esi, gpCelFrame + mov eax, level_cel_block + and eax, 0FFFh + shl eax, 6 + add esi, eax + mov eax, level_cel_block + and eax, 0F000h + add eax, [esi] + mov level_cel_block, eax + loc_466074: + mov ebx, pDungeonCels + mov esi, ebx + mov eax, level_cel_block + and eax, 0FFFh + shl eax, 2 + add ebx, eax + add esi, [ebx] + mov eax, level_cel_block + mov al, ah + shr eax, 4 + and eax, 7 + add eax, 8 + jmp loc_46600B + loc_4660A2: + mov eax, level_cel_block + and eax, 8000h + jz loc_4660D4 + mov esi, gpCelFrame + mov eax, level_cel_block + and eax, 0FFFh + shl eax, 6 + add esi, eax + mov eax, level_cel_block + and eax, 0F000h + add eax, [esi] + mov level_cel_block, eax + loc_4660D4: + mov ebx, pDungeonCels + mov esi, ebx + mov eax, level_cel_block + and eax, 0FFFh + shl eax, 2 + add ebx, eax + add esi, [ebx] + mov eax, level_cel_block + mov al, ah + shr eax, 4 + and eax, 7 + jz loc_46747D + cmp ax, 1 + jz loc_4674D9 + cmp ax, 2 + jz loc_467599 + cmp ax, 3 + jz loc_467692 + cmp ax, 4 + jz loc_46778F + jmp loc_46786B + loc_46612D: + push ebp + mov ebp, 10h + loc_466133: + cmp edi, gpBufEnd + jb loc_466143 + add esi, 20h + add edi, 20h + jmp loc_466166 + loc_466143: + mov ecx, 8 + loc_466148: + mov eax, [esi] + add esi, 4 + mov dl, ah + shr eax, 10h + mov dl, [ebx+edx] + mov [edi+1], dl + mov dl, ah + add edi, 4 + mov dl, [ebx+edx] + dec ecx + mov [edi-1], dl + jnz loc_466148 + loc_466166: + sub edi, 320h + cmp edi, gpBufEnd + jb loc_46617C + add esi, 20h + add edi, 20h + jmp loc_46619E + loc_46617C: + mov ecx, 8 + loc_466181: + mov eax, [esi] + add esi, 4 + mov dl, al + shr eax, 10h + mov dl, [ebx+edx] + mov [edi], dl + mov dl, al + add edi, 4 + mov dl, [ebx+edx] + dec ecx + mov [edi-2], dl + jnz loc_466181 + loc_46619E: + sub edi, 320h + dec ebp + jnz loc_466133 + pop ebp + jmp loc_467944 + loc_4661AD: + push ebp + mov eax, edi + and eax, 1 + mov WorldBoolFlag, eax + mov ecx, 20h + loc_4661BD: + push ecx + mov ebp, 20h + loc_4661C3: + xor eax, eax + mov al, [esi] + inc esi + test al, al + js loc_4662E2 + sub ebp, eax + cmp edi, gpBufEnd + jb loc_4661E3 + add esi, eax + add edi, eax + jmp loc_4662D9 + loc_4661E3: + mov ecx, eax + mov eax, edi + and eax, 1 + cmp eax, WorldBoolFlag + jnz loc_466263 + shr ecx, 1 + jb loc_46622D + shr ecx, 1 + jnb loc_466209 + mov dl, [esi+1] + mov dl, [ebx+edx] + add esi, 2 + mov [edi+1], dl + add edi, 2 + loc_466209: + test cl, cl + jz loc_46622B + loc_46620D: + mov eax, [esi] + add esi, 4 + mov dl, ah + shr eax, 10h + mov dl, [ebx+edx] + mov [edi+1], dl + mov dl, ah + add edi, 4 + mov dl, [ebx+edx] + dec ecx + mov [edi-1], dl + jnz loc_46620D + loc_46622B: + jmp loc_466261 + loc_46622D: + inc esi + inc edi + shr ecx, 1 + jnb loc_466240 + mov dl, [esi] + mov dl, [ebx+edx] + add esi, 2 + mov [edi], dl + add edi, 2 + loc_466240: + test cl, cl + jz loc_466261 + loc_466244: + mov eax, [esi] + add esi, 4 + mov dl, al + shr eax, 10h + mov dl, [ebx+edx] + mov [edi], dl + mov dl, al + add edi, 4 + mov dl, [ebx+edx] + dec ecx + mov [edi-2], dl + jnz loc_466244 + loc_466261: + jmp loc_4662D9 + loc_466263: + shr ecx, 1 + jb loc_46629B + shr ecx, 1 + jnb loc_466278 + mov dl, [esi] + mov dl, [ebx+edx] + add esi, 2 + mov [edi], dl + add edi, 2 + loc_466278: + test cl, cl + jz loc_466299 + loc_46627C: + mov eax, [esi] + add esi, 4 + mov dl, al + shr eax, 10h + mov dl, [ebx+edx] + mov [edi], dl + mov dl, al + add edi, 4 + mov dl, [ebx+edx] + dec ecx + mov [edi-2], dl + jnz loc_46627C + loc_466299: + jmp loc_4662D9 + loc_46629B: + mov dl, [esi] + mov dl, [ebx+edx] + inc esi + mov [edi], dl + inc edi + shr ecx, 1 + jnb loc_4662B7 + mov dl, [esi+1] + mov dl, [ebx+edx] + add esi, 2 + mov [edi+1], dl + add edi, 2 + loc_4662B7: + test cl, cl + jz loc_4662D9 + loc_4662BB: + mov eax, [esi] + add esi, 4 + mov dl, ah + shr eax, 10h + mov dl, [ebx+edx] + mov [edi+1], dl + mov dl, ah + add edi, 4 + mov dl, [ebx+edx] + dec ecx + mov [edi-1], dl + jnz loc_4662BB + loc_4662D9: + test ebp, ebp + jz loc_4662EE + jmp loc_4661C3 + loc_4662E2: + neg al + add edi, eax + sub ebp, eax + jnz loc_4661C3 + loc_4662EE: + pop ecx + mov eax, WorldBoolFlag + inc eax + and eax, 1 + mov WorldBoolFlag, eax + sub edi, 320h + dec ecx + jnz loc_4661BD + pop ebp + jmp loc_467944 + loc_466310: + push ebp + xor eax, eax + mov WorldBoolFlag, eax + mov ebp, 1Eh + mov eax, edi + sub eax, gpBufEnd + jb loc_466370 + add eax, 3FFh + shr eax, 8 + cmp eax, 2Dh + jg loc_46635F + mov ecx, WorldTbl3x16[eax*4] + mov eax, ecx + add esi, WorldTbl17_1[ecx] + shl eax, 6 + lea eax, [eax+eax*2] + shr ecx, 1 + sub edi, eax + sub ebp, ecx + mov eax, WorldBoolFlag + shr ecx, 1 + add eax, ecx + mov WorldBoolFlag, eax + jmp loc_466370 + loc_46635F: + sub edi, 3000h + add esi, 120h + jmp loc_466490 + loc_466370: + add edi, ebp + mov ecx, 20h + sub ecx, ebp + mov eax, WorldBoolFlag + inc eax + and eax, 1 + mov WorldBoolFlag, eax + jz loc_466404 + mov edx, ecx + and edx, 2 + add esi, edx + shr ecx, 1 + jb loc_4663CB + shr ecx, 1 + jnb loc_4663A7 + mov dl, [esi+1] + mov dl, [ebx+edx] + add esi, 2 + mov [edi+1], dl + add edi, 2 + loc_4663A7: + test cl, cl + jz loc_4663C9 + loc_4663AB: + mov eax, [esi] + add esi, 4 + mov dl, ah + shr eax, 10h + mov dl, [ebx+edx] + mov [edi+1], dl + mov dl, ah + add edi, 4 + mov dl, [ebx+edx] + dec ecx + mov [edi-1], dl + jnz loc_4663AB + loc_4663C9: + jmp loc_4663FF + loc_4663CB: + inc esi + inc edi + shr ecx, 1 + jnb loc_4663DE + mov dl, [esi] + mov dl, [ebx+edx] + add esi, 2 + mov [edi], dl + add edi, 2 + loc_4663DE: + test cl, cl + jz loc_4663FF + loc_4663E2: + mov eax, [esi] + add esi, 4 + mov dl, al + shr eax, 10h + mov dl, [ebx+edx] + mov [edi], dl + mov dl, al + add edi, 4 + mov dl, [ebx+edx] + dec ecx + mov [edi-2], dl + jnz loc_4663E2 + loc_4663FF: + jmp $+82h + loc_466404: + mov edx, ecx + and edx, 2 + add esi, edx + shr ecx, 1 + jb loc_466443 + shr ecx, 1 + jnb loc_466420 + mov dl, [esi] + mov dl, [ebx+edx] + add esi, 2 + mov [edi], dl + add edi, 2 + loc_466420: + test cl, cl + jz loc_466441 + loc_466424: + mov eax, [esi] + add esi, 4 + mov dl, al + shr eax, 10h + mov dl, [ebx+edx] + mov [edi], dl + mov dl, al + add edi, 4 + mov dl, [ebx+edx] + dec ecx + mov [edi-2], dl + jnz loc_466424 + loc_466441: + jmp loc_466481 + loc_466443: + mov dl, [esi] + mov dl, [ebx+edx] + inc esi + mov [edi], dl + inc edi + shr ecx, 1 + jnb loc_46645F + mov dl, [esi+1] + mov dl, [ebx+edx] + add esi, 2 + mov [edi+1], dl + add edi, 2 + loc_46645F: + test cl, cl + jz loc_466481 + loc_466463: + mov eax, [esi] + add esi, 4 + mov dl, ah + shr eax, 10h + mov dl, [ebx+edx] + mov [edi+1], dl + mov dl, ah + add edi, 4 + mov dl, [ebx+edx] + dec ecx + mov [edi-1], dl + jnz loc_466463 + loc_466481: + sub edi, 320h + sub ebp, 2 + jge loc_466370 + loc_466490: + mov ebp, 2 + mov eax, edi + sub eax, gpBufEnd + jb loc_4664E8 + add eax, 3FFh + shr eax, 8 + cmp eax, 2Ah + jg loc_4664D7 + mov ecx, WorldTbl3x16[eax*4] + mov eax, ecx + add esi, WorldTbl17_2[ecx] + shl eax, 6 + lea eax, [eax+eax*2] + shr ecx, 1 + sub edi, eax + add ebp, ecx + mov eax, WorldBoolFlag + shr ecx, 1 + add eax, ecx + mov WorldBoolFlag, eax + jmp loc_4664E8 + loc_4664D7: + sub edi, 2D00h + add esi, 100h + jmp loc_46660B + loc_4664E8: + add edi, ebp + mov ecx, 20h + sub ecx, ebp + mov eax, WorldBoolFlag + inc eax + and eax, 1 + mov WorldBoolFlag, eax + jz loc_46657C + mov edx, ecx + and edx, 2 + add esi, edx + shr ecx, 1 + jb loc_466543 + shr ecx, 1 + jnb loc_46651F + mov dl, [esi+1] + mov dl, [ebx+edx] + add esi, 2 + mov [edi+1], dl + add edi, 2 + loc_46651F: + test cl, cl + jz loc_466541 + loc_466523: + mov eax, [esi] + add esi, 4 + mov dl, ah + shr eax, 10h + mov dl, [ebx+edx] + mov [edi+1], dl + mov dl, ah + add edi, 4 + mov dl, [ebx+edx] + dec ecx + mov [edi-1], dl + jnz loc_466523 + loc_466541: + jmp loc_466577 + loc_466543: + inc esi + inc edi + shr ecx, 1 + jnb loc_466556 + mov dl, [esi] + mov dl, [ebx+edx] + add esi, 2 + mov [edi], dl + add edi, 2 + loc_466556: + test cl, cl + jz loc_466577 + loc_46655A: + mov eax, [esi] + add esi, 4 + mov dl, al + shr eax, 10h + mov dl, [ebx+edx] + mov [edi], dl + mov dl, al + add edi, 4 + mov dl, [ebx+edx] + dec ecx + mov [edi-2], dl + jnz loc_46655A + loc_466577: + jmp $+82h + loc_46657C: + mov edx, ecx + and edx, 2 + add esi, edx + shr ecx, 1 + jb loc_4665BB + shr ecx, 1 + jnb loc_466598 + mov dl, [esi] + mov dl, [ebx+edx] + add esi, 2 + mov [edi], dl + add edi, 2 + loc_466598: + test cl, cl + jz loc_4665B9 + loc_46659C: + mov eax, [esi] + add esi, 4 + mov dl, al + shr eax, 10h + mov dl, [ebx+edx] + mov [edi], dl + mov dl, al + add edi, 4 + mov dl, [ebx+edx] + dec ecx + mov [edi-2], dl + jnz loc_46659C + loc_4665B9: + jmp loc_4665F9 + loc_4665BB: + mov dl, [esi] + mov dl, [ebx+edx] + inc esi + mov [edi], dl + inc edi + shr ecx, 1 + jnb loc_4665D7 + mov dl, [esi+1] + mov dl, [ebx+edx] + add esi, 2 + mov [edi+1], dl + add edi, 2 + loc_4665D7: + test cl, cl + jz loc_4665F9 + loc_4665DB: + mov eax, [esi] + add esi, 4 + mov dl, ah + shr eax, 10h + mov dl, [ebx+edx] + mov [edi+1], dl + mov dl, ah + add edi, 4 + mov dl, [ebx+edx] + dec ecx + mov [edi-1], dl + jnz loc_4665DB + loc_4665F9: + sub edi, 320h + add ebp, 2 + cmp ebp, 20h + jnz loc_4664E8 + loc_46660B: + pop ebp + jmp loc_467944 + loc_466611: + push ebp + xor eax, eax + mov WorldBoolFlag, eax + mov ebp, 1Eh + mov eax, edi + sub eax, gpBufEnd + jb loc_466671 + add eax, 3FFh + shr eax, 8 + cmp eax, 2Dh + jg loc_466660 + mov ecx, WorldTbl3x16[eax*4] + mov eax, ecx + add esi, WorldTbl17_1[ecx] + shl eax, 6 + lea eax, [eax+eax*2] + shr ecx, 1 + sub edi, eax + sub ebp, ecx + mov eax, WorldBoolFlag + shr ecx, 1 + add eax, ecx + mov WorldBoolFlag, eax + jmp loc_466671 + loc_466660: + sub edi, 3000h + add esi, 120h + jmp loc_466791 + loc_466671: + mov ecx, 20h + sub ecx, ebp + mov eax, WorldBoolFlag + inc eax + and eax, 1 + mov WorldBoolFlag, eax + jz loc_466703 + shr ecx, 1 + jb loc_4666C3 + shr ecx, 1 + jnb loc_46669F + mov dl, [esi+1] + mov dl, [ebx+edx] + add esi, 2 + mov [edi+1], dl + add edi, 2 + loc_46669F: + test cl, cl + jz loc_4666C1 + loc_4666A3: + mov eax, [esi] + add esi, 4 + mov dl, ah + shr eax, 10h + mov dl, [ebx+edx] + mov [edi+1], dl + mov dl, ah + add edi, 4 + mov dl, [ebx+edx] + dec ecx + mov [edi-1], dl + jnz loc_4666A3 + loc_4666C1: + jmp loc_4666F7 + loc_4666C3: + inc esi + inc edi + shr ecx, 1 + jnb loc_4666D6 + mov dl, [esi] + mov dl, [ebx+edx] + add esi, 2 + mov [edi], dl + add edi, 2 + loc_4666D6: + test cl, cl + jz loc_4666F7 + loc_4666DA: + mov eax, [esi] + add esi, 4 + mov dl, al + shr eax, 10h + mov dl, [ebx+edx] + mov [edi], dl + mov dl, al + add edi, 4 + mov dl, [ebx+edx] + dec ecx + mov [edi-2], dl + jnz loc_4666DA + loc_4666F7: + mov edx, esi + and edx, 2 + add esi, edx + jmp $+82h + loc_466703: + shr ecx, 1 + jb loc_46673B + shr ecx, 1 + jnb loc_466718 + mov dl, [esi] + mov dl, [ebx+edx] + add esi, 2 + mov [edi], dl + add edi, 2 + loc_466718: + test cl, cl + jz loc_466739 + loc_46671C: + mov eax, [esi] + add esi, 4 + mov dl, al + shr eax, 10h + mov dl, [ebx+edx] + mov [edi], dl + mov dl, al + add edi, 4 + mov dl, [ebx+edx] + dec ecx + mov [edi-2], dl + jnz loc_46671C + loc_466739: + jmp loc_466779 + loc_46673B: + mov dl, [esi] + mov dl, [ebx+edx] + inc esi + mov [edi], dl + inc edi + shr ecx, 1 + jnb loc_466757 + mov dl, [esi+1] + mov dl, [ebx+edx] + add esi, 2 + mov [edi+1], dl + add edi, 2 + loc_466757: + test cl, cl + jz loc_466779 + loc_46675B: + mov eax, [esi] + add esi, 4 + mov dl, ah + shr eax, 10h + mov dl, [ebx+edx] + mov [edi+1], dl + mov dl, ah + add edi, 4 + mov dl, [ebx+edx] + dec ecx + mov [edi-1], dl + jnz loc_46675B + loc_466779: + mov edx, esi + and edx, 2 + add esi, edx + // loc_466780: + sub edi, 320h + add edi, ebp + sub ebp, 2 + jge loc_466671 + loc_466791: + mov ebp, 2 + mov eax, edi + sub eax, gpBufEnd + jb loc_4667E9 + add eax, 3FFh + shr eax, 8 + cmp eax, 2Ah + jg loc_4667D8 + mov ecx, WorldTbl3x16[eax*4] + mov eax, ecx + add esi, WorldTbl17_2[ecx] + shl eax, 6 + lea eax, [eax+eax*2] + shr ecx, 1 + sub edi, eax + add ebp, ecx + mov eax, WorldBoolFlag + shr ecx, 1 + add eax, ecx + mov WorldBoolFlag, eax + jmp loc_4667E9 + loc_4667D8: + sub edi, 2D00h + add esi, 100h + jmp loc_46690C + loc_4667E9: + mov ecx, 20h + sub ecx, ebp + mov eax, WorldBoolFlag + inc eax + and eax, 1 + mov WorldBoolFlag, eax + jz loc_46687B + shr ecx, 1 + jb loc_46683B + shr ecx, 1 + jnb loc_466817 + mov dl, [esi+1] + mov dl, [ebx+edx] + add esi, 2 + mov [edi+1], dl + add edi, 2 + loc_466817: + test cl, cl + jz loc_466839 + loc_46681B: + mov eax, [esi] + add esi, 4 + mov dl, ah + shr eax, 10h + mov dl, [ebx+edx] + mov [edi+1], dl + mov dl, ah + add edi, 4 + mov dl, [ebx+edx] + dec ecx + mov [edi-1], dl + jnz loc_46681B + loc_466839: + jmp loc_46686F + loc_46683B: + inc esi + inc edi + shr ecx, 1 + jnb loc_46684E + mov dl, [esi] + mov dl, [ebx+edx] + add esi, 2 + mov [edi], dl + add edi, 2 + loc_46684E: + test cl, cl + jz loc_46686F + loc_466852: + mov eax, [esi] + add esi, 4 + mov dl, al + shr eax, 10h + mov dl, [ebx+edx] + mov [edi], dl + mov dl, al + add edi, 4 + mov dl, [ebx+edx] + dec ecx + mov [edi-2], dl + jnz loc_466852 + loc_46686F: + mov edx, esi + and edx, 2 + add esi, edx + jmp $+82h + loc_46687B: + shr ecx, 1 + jb loc_4668B3 + shr ecx, 1 + jnb loc_466890 + mov dl, [esi] + mov dl, [ebx+edx] + add esi, 2 + mov [edi], dl + add edi, 2 + loc_466890: + test cl, cl + jz loc_4668B1 + loc_466894: + mov eax, [esi] + add esi, 4 + mov dl, al + shr eax, 10h + mov dl, [ebx+edx] + mov [edi], dl + mov dl, al + add edi, 4 + mov dl, [ebx+edx] + dec ecx + mov [edi-2], dl + jnz loc_466894 + loc_4668B1: + jmp loc_4668F1 + loc_4668B3: + mov dl, [esi] + mov dl, [ebx+edx] + inc esi + mov [edi], dl + inc edi + shr ecx, 1 + jnb loc_4668CF + mov dl, [esi+1] + mov dl, [ebx+edx] + add esi, 2 + mov [edi+1], dl + add edi, 2 + loc_4668CF: + test cl, cl + jz loc_4668F1 + loc_4668D3: + mov eax, [esi] + add esi, 4 + mov dl, ah + shr eax, 10h + mov dl, [ebx+edx] + mov [edi+1], dl + mov dl, ah + add edi, 4 + mov dl, [ebx+edx] + dec ecx + mov [edi-1], dl + jnz loc_4668D3 + loc_4668F1: + mov edx, esi + and edx, 2 + add esi, edx + // loc_4668F8: + sub edi, 320h + add edi, ebp + add ebp, 2 + cmp ebp, 20h + jnz loc_4667E9 + loc_46690C: + pop ebp + jmp loc_467944 + loc_466912: + push ebp + xor eax, eax + mov WorldBoolFlag, eax + mov ebp, 1Eh + mov eax, edi + sub eax, gpBufEnd + jb loc_466972 + add eax, 3FFh + shr eax, 8 + cmp eax, 2Dh + jg loc_466961 + mov ecx, WorldTbl3x16[eax*4] + mov eax, ecx + add esi, WorldTbl17_1[ecx] + shl eax, 6 + lea eax, [eax+eax*2] + shr ecx, 1 + sub edi, eax + sub ebp, ecx + mov eax, WorldBoolFlag + shr ecx, 1 + add eax, ecx + mov WorldBoolFlag, eax + jmp loc_466972 + loc_466961: + sub edi, 3000h + add esi, 120h + jmp loc_466A92 + loc_466972: + add edi, ebp + mov ecx, 20h + sub ecx, ebp + mov eax, WorldBoolFlag + inc eax + and eax, 1 + mov WorldBoolFlag, eax + jz loc_466A06 + mov edx, ecx + and edx, 2 + add esi, edx + shr ecx, 1 + jb loc_4669CD + shr ecx, 1 + jnb loc_4669A9 + mov dl, [esi+1] + mov dl, [ebx+edx] + add esi, 2 + mov [edi+1], dl + add edi, 2 + loc_4669A9: + test cl, cl + jz loc_4669CB + loc_4669AD: + mov eax, [esi] + add esi, 4 + mov dl, ah + shr eax, 10h + mov dl, [ebx+edx] + mov [edi+1], dl + mov dl, ah + add edi, 4 + mov dl, [ebx+edx] + dec ecx + mov [edi-1], dl + jnz loc_4669AD + loc_4669CB: + jmp loc_466A01 + loc_4669CD: + inc esi + inc edi + shr ecx, 1 + jnb loc_4669E0 + mov dl, [esi] + mov dl, [ebx+edx] + add esi, 2 + mov [edi], dl + add edi, 2 + loc_4669E0: + test cl, cl + jz loc_466A01 + loc_4669E4: + mov eax, [esi] + add esi, 4 + mov dl, al + shr eax, 10h + mov dl, [ebx+edx] + mov [edi], dl + mov dl, al + add edi, 4 + mov dl, [ebx+edx] + dec ecx + mov [edi-2], dl + jnz loc_4669E4 + loc_466A01: + jmp $+82h + loc_466A06: + mov edx, ecx + and edx, 2 + add esi, edx + shr ecx, 1 + jb loc_466A45 + shr ecx, 1 + jnb loc_466A22 + mov dl, [esi] + mov dl, [ebx+edx] + add esi, 2 + mov [edi], dl + add edi, 2 + loc_466A22: + test cl, cl + jz loc_466A43 + loc_466A26: + mov eax, [esi] + add esi, 4 + mov dl, al + shr eax, 10h + mov dl, [ebx+edx] + mov [edi], dl + mov dl, al + add edi, 4 + mov dl, [ebx+edx] + dec ecx + mov [edi-2], dl + jnz loc_466A26 + loc_466A43: + jmp loc_466A83 + loc_466A45: + mov dl, [esi] + mov dl, [ebx+edx] + inc esi + mov [edi], dl + inc edi + shr ecx, 1 + jnb loc_466A61 + mov dl, [esi+1] + mov dl, [ebx+edx] + add esi, 2 + mov [edi+1], dl + add edi, 2 + loc_466A61: + test cl, cl + jz loc_466A83 + loc_466A65: + mov eax, [esi] + add esi, 4 + mov dl, ah + shr eax, 10h + mov dl, [ebx+edx] + mov [edi+1], dl + mov dl, ah + add edi, 4 + mov dl, [ebx+edx] + dec ecx + mov [edi-1], dl + jnz loc_466A65 + loc_466A83: + sub edi, 320h + sub ebp, 2 + jge loc_466972 + loc_466A92: + mov ebp, 8 + loc_466A97: + cmp edi, gpBufEnd + jb loc_466AA7 + add esi, 20h + add edi, 20h + jmp loc_466ACA + loc_466AA7: + mov ecx, 8 + loc_466AAC: + mov eax, [esi] + add esi, 4 + mov dl, ah + shr eax, 10h + mov dl, [ebx+edx] + mov [edi+1], dl + mov dl, ah + add edi, 4 + mov dl, [ebx+edx] + dec ecx + mov [edi-1], dl + jnz loc_466AAC + loc_466ACA: + sub edi, 320h + cmp edi, gpBufEnd + jb loc_466AE0 + add esi, 20h + add edi, 20h + jmp loc_466B02 + loc_466AE0: + mov ecx, 8 + loc_466AE5: + mov eax, [esi] + add esi, 4 + mov dl, al + shr eax, 10h + mov dl, [ebx+edx] + mov [edi], dl + mov dl, al + add edi, 4 + mov dl, [ebx+edx] + dec ecx + mov [edi-2], dl + jnz loc_466AE5 + loc_466B02: + sub edi, 320h + dec ebp + jnz loc_466A97 + pop ebp + jmp loc_467944 + loc_466B11: + push ebp + xor eax, eax + mov WorldBoolFlag, eax + mov ebp, 1Eh + mov eax, edi + sub eax, gpBufEnd + jb loc_466B71 + add eax, 3FFh + shr eax, 8 + cmp eax, 2Dh + jg loc_466B60 + mov ecx, WorldTbl3x16[eax*4] + mov eax, ecx + add esi, WorldTbl17_1[ecx] + shl eax, 6 + lea eax, [eax+eax*2] + shr ecx, 1 + sub edi, eax + sub ebp, ecx + mov eax, WorldBoolFlag + shr ecx, 1 + add eax, ecx + mov WorldBoolFlag, eax + jmp loc_466B71 + loc_466B60: + sub edi, 3000h + add esi, 120h + jmp loc_466C91 + loc_466B71: + mov ecx, 20h + sub ecx, ebp + mov eax, WorldBoolFlag + inc eax + and eax, 1 + mov WorldBoolFlag, eax + jz loc_466C03 + shr ecx, 1 + jb loc_466BC3 + shr ecx, 1 + jnb loc_466B9F + mov dl, [esi+1] + mov dl, [ebx+edx] + add esi, 2 + mov [edi+1], dl + add edi, 2 + loc_466B9F: + test cl, cl + jz loc_466BC1 + loc_466BA3: + mov eax, [esi] + add esi, 4 + mov dl, ah + shr eax, 10h + mov dl, [ebx+edx] + mov [edi+1], dl + mov dl, ah + add edi, 4 + mov dl, [ebx+edx] + dec ecx + mov [edi-1], dl + jnz loc_466BA3 + loc_466BC1: + jmp loc_466BF7 + loc_466BC3: + inc esi + inc edi + shr ecx, 1 + jnb loc_466BD6 + mov dl, [esi] + mov dl, [ebx+edx] + add esi, 2 + mov [edi], dl + add edi, 2 + loc_466BD6: + test cl, cl + jz loc_466BF7 + loc_466BDA: + mov eax, [esi] + add esi, 4 + mov dl, al + shr eax, 10h + mov dl, [ebx+edx] + mov [edi], dl + mov dl, al + add edi, 4 + mov dl, [ebx+edx] + dec ecx + mov [edi-2], dl + jnz loc_466BDA + loc_466BF7: + mov edx, esi + and edx, 2 + add esi, edx + jmp $+82h + loc_466C03: + shr ecx, 1 + jb loc_466C3B + shr ecx, 1 + jnb loc_466C18 + mov dl, [esi] + mov dl, [ebx+edx] + add esi, 2 + mov [edi], dl + add edi, 2 + loc_466C18: + test cl, cl + jz loc_466C39 + loc_466C1C: + mov eax, [esi] + add esi, 4 + mov dl, al + shr eax, 10h + mov dl, [ebx+edx] + mov [edi], dl + mov dl, al + add edi, 4 + mov dl, [ebx+edx] + dec ecx + mov [edi-2], dl + jnz loc_466C1C + loc_466C39: + jmp loc_466C79 + loc_466C3B: + mov dl, [esi] + mov dl, [ebx+edx] + inc esi + mov [edi], dl + inc edi + shr ecx, 1 + jnb loc_466C57 + mov dl, [esi+1] + mov dl, [ebx+edx] + add esi, 2 + mov [edi+1], dl + add edi, 2 + loc_466C57: + test cl, cl + jz loc_466C79 + loc_466C5B: + mov eax, [esi] + add esi, 4 + mov dl, ah + shr eax, 10h + mov dl, [ebx+edx] + mov [edi+1], dl + mov dl, ah + add edi, 4 + mov dl, [ebx+edx] + dec ecx + mov [edi-1], dl + jnz loc_466C5B + loc_466C79: + mov edx, esi + and edx, 2 + add esi, edx + // loc_466C80: + sub edi, 320h + add edi, ebp + sub ebp, 2 + jge loc_466B71 + loc_466C91: + mov ebp, 8 + loc_466C96: + cmp edi, gpBufEnd + jb loc_466CA6 + add esi, 20h + add edi, 20h + jmp loc_466CC9 + loc_466CA6: + mov ecx, 8 + loc_466CAB: + mov eax, [esi] + add esi, 4 + mov dl, ah + shr eax, 10h + mov dl, [ebx+edx] + mov [edi+1], dl + mov dl, ah + add edi, 4 + mov dl, [ebx+edx] + dec ecx + mov [edi-1], dl + jnz loc_466CAB + loc_466CC9: + sub edi, 320h + cmp edi, gpBufEnd + jb loc_466CDF + add esi, 20h + add edi, 20h + jmp loc_466D01 + loc_466CDF: + mov ecx, 8 + loc_466CE4: + mov eax, [esi] + add esi, 4 + mov dl, al + shr eax, 10h + mov dl, [ebx+edx] + mov [edi], dl + mov dl, al + add edi, 4 + mov dl, [ebx+edx] + dec ecx + mov [edi-2], dl + jnz loc_466CE4 + loc_466D01: + sub edi, 320h + dec ebp + jnz loc_466C96 + pop ebp + jmp loc_467944 + loc_466D10: + mov edx, 10h + loc_466D15: + cmp edi, gpBufEnd + jb loc_466D25 + add esi, 20h + add edi, 20h + jmp loc_466D41 + loc_466D25: + mov ecx, 8 + loc_466D2A: + mov eax, [esi] + add esi, 4 + inc edi + ror eax, 8 + mov [edi], al + add edi, 2 + ror eax, 10h + mov [edi], al + inc edi + dec ecx + jnz loc_466D2A + loc_466D41: + sub edi, 320h + cmp edi, gpBufEnd + jb loc_466D57 + add esi, 20h + add edi, 20h + jmp loc_466D71 + loc_466D57: + mov ecx, 8 + loc_466D5C: + mov eax, [esi] + add esi, 4 + mov [edi], al + add edi, 2 + ror eax, 10h + mov [edi], al + add edi, 2 + dec ecx + jnz loc_466D5C + loc_466D71: + sub edi, 320h + dec edx + jnz loc_466D15 + jmp loc_467944 + loc_466D7F: + mov eax, edi + and eax, 1 + mov WorldBoolFlag, eax + mov ecx, 20h + loc_466D8E: + push ecx + mov edx, 20h + loc_466D94: + xor eax, eax + mov al, [esi] + inc esi + test al, al + js loc_466E35 + sub edx, eax + cmp edi, gpBufEnd + jb loc_466DB1 + add esi, eax + add edi, eax + jmp loc_466E2C + loc_466DB1: + mov ecx, eax + mov eax, edi + and eax, 1 + cmp eax, WorldBoolFlag + jnz loc_466DF5 + shr ecx, 1 + jnb loc_466DCC + inc esi + inc edi + test ecx, ecx + jz loc_466E2C + jmp loc_466E05 + loc_466DCC: + shr ecx, 1 + jnb loc_466DDC + inc esi + inc edi + mov al, [esi] + inc esi + mov [edi], al + inc edi + test ecx, ecx + jz loc_466E2C + loc_466DDC: + mov eax, [esi] + add esi, 4 + inc edi + ror eax, 8 + mov [edi], al + add edi, 2 + ror eax, 10h + mov [edi], al + inc edi + dec ecx + jnz loc_466DDC + jmp loc_466E2C + loc_466DF5: + shr ecx, 1 + jnb loc_466E05 + mov al, [esi] + inc esi + mov [edi], al + inc edi + test ecx, ecx + jz loc_466E2C + jmp loc_466DCC + loc_466E05: + shr ecx, 1 + jnb loc_466E17 + mov al, [esi] + add esi, 2 + mov [edi], al + add edi, 2 + test ecx, ecx + jz loc_466E2C + loc_466E17: + mov eax, [esi] + add esi, 4 + mov [edi], al + add edi, 2 + ror eax, 10h + mov [edi], al + add edi, 2 + dec ecx + jnz loc_466E17 + loc_466E2C: + test edx, edx + jz loc_466E41 + jmp loc_466D94 + loc_466E35: + neg al + add edi, eax + sub edx, eax + jnz loc_466D94 + loc_466E41: + pop ecx + mov eax, WorldBoolFlag + inc eax + and eax, 1 + mov WorldBoolFlag, eax + sub edi, 320h + dec ecx + jnz loc_466D8E + jmp loc_467944 + loc_466E62: + xor eax, eax + mov WorldBoolFlag, eax + mov edx, 1Eh + mov eax, edi + sub eax, gpBufEnd + jb loc_466EC1 + add eax, 3FFh + shr eax, 8 + cmp eax, 2Dh + jg loc_466EB0 + mov ecx, WorldTbl3x16[eax*4] + mov eax, ecx + add esi, WorldTbl17_1[ecx] + shl eax, 6 + lea eax, [eax+eax*2] + shr ecx, 1 + sub edi, eax + sub edx, ecx + mov eax, WorldBoolFlag + shr ecx, 1 + add eax, ecx + mov WorldBoolFlag, eax + jmp loc_466EC1 + loc_466EB0: + sub edi, 3000h + add esi, 120h + jmp $+83h + loc_466EC1: + add edi, edx + mov ecx, 20h + sub ecx, edx + mov eax, WorldBoolFlag + inc eax + and eax, 1 + mov WorldBoolFlag, eax + jz loc_466F0A + shr ecx, 2 + jnb loc_466EF1 + mov ax, [esi+2] + add esi, 4 + inc edi + ror eax, 8 + mov [edi], al + inc edi + test ecx, ecx + jz loc_466F34 + loc_466EF1: + mov eax, [esi] + add esi, 4 + inc edi + ror eax, 8 + mov [edi], al + add edi, 2 + ror eax, 10h + mov [edi], al + inc edi + dec ecx + jnz loc_466EF1 + jmp loc_466F34 + loc_466F0A: + shr ecx, 2 + jnb loc_466F1F + mov ax, [esi+2] + add esi, 4 + mov [edi], al + add edi, 2 + test ecx, ecx + jz loc_466F34 + loc_466F1F: + mov eax, [esi] + add esi, 4 + mov [edi], al + add edi, 2 + ror eax, 10h + mov [edi], al + add edi, 2 + dec ecx + jnz loc_466F1F + loc_466F34: + sub edi, 320h + sub edx, 2 + jge loc_466EC1 + // loc_466F3F: + mov edx, 2 + mov eax, edi + sub eax, gpBufEnd + jb loc_466F97 + add eax, 3FFh + shr eax, 8 + cmp eax, 2Ah + jg loc_466F86 + mov ecx, WorldTbl3x16[eax*4] + mov eax, ecx + add esi, WorldTbl17_2[ecx] + shl eax, 6 + lea eax, [eax+eax*2] + shr ecx, 1 + sub edi, eax + add edx, ecx + mov eax, WorldBoolFlag + shr ecx, 1 + add eax, ecx + mov WorldBoolFlag, eax + jmp loc_466F97 + loc_466F86: + sub edi, 2D00h + add esi, 100h + jmp loc_467944 + loc_466F97: + add edi, edx + mov ecx, 20h + sub ecx, edx + mov eax, WorldBoolFlag + inc eax + and eax, 1 + mov WorldBoolFlag, eax + jz loc_466FE0 + shr ecx, 2 + jnb loc_466FC7 + mov ax, [esi+2] + add esi, 4 + inc edi + ror eax, 8 + mov [edi], al + inc edi + test ecx, ecx + jz loc_467009 + loc_466FC7: + mov eax, [esi] + add esi, 4 + inc edi + ror eax, 8 + mov [edi], al + add edi, 2 + ror eax, 10h + mov [edi], al + inc edi + dec ecx + jnz loc_466FC7 + jmp loc_467009 + loc_466FE0: + shr ecx, 2 + jnb loc_466FF4 + mov ax, [esi+2] + add esi, 4 + mov [edi], al + add edi, 2 + dec ecx + jz loc_467009 + loc_466FF4: + mov eax, [esi] + add esi, 4 + mov [edi], al + add edi, 2 + ror eax, 10h + mov [edi], al + add edi, 2 + dec ecx + jnz loc_466FF4 + loc_467009: + sub edi, 320h + add edx, 2 + cmp edx, 20h + jnz loc_466F97 + jmp loc_467944 + loc_46701C: + push ebp + xor eax, eax + mov WorldBoolFlag, eax + mov edx, 1Eh + mov eax, edi + sub eax, gpBufEnd + jb loc_46707C + add eax, 3FFh + shr eax, 8 + cmp eax, 2Dh + jg loc_46706B + mov ecx, WorldTbl3x16[eax*4] + mov eax, ecx + add esi, WorldTbl17_1[ecx] + shl eax, 6 + lea eax, [eax+eax*2] + shr ecx, 1 + sub edi, eax + sub edx, ecx + mov eax, WorldBoolFlag + shr ecx, 1 + add eax, ecx + mov WorldBoolFlag, eax + jmp loc_46707C + loc_46706B: + sub edi, 3000h + add esi, 120h + jmp loc_4670FC + loc_46707C: + mov ecx, 20h + sub ecx, edx + mov eax, WorldBoolFlag + inc eax + and eax, 1 + mov ebp, ecx + mov WorldBoolFlag, eax + jz loc_4670C5 + shr ecx, 2 + jz loc_4670B1 + loc_46709A: + mov eax, [esi] + add esi, 4 + inc edi + ror eax, 8 + mov [edi], al + add edi, 2 + ror eax, 10h + mov [edi], al + inc edi + dec ecx + jnz loc_46709A + loc_4670B1: + and ebp, 2 + jz loc_4670EF + mov ax, [esi] + add esi, 4 + inc edi + ror eax, 8 + mov [edi], al + inc edi + jmp loc_4670EF + loc_4670C5: + shr ecx, 2 + jz loc_4670DF + loc_4670CA: + mov eax, [esi] + add esi, 4 + mov [edi], al + add edi, 2 + ror eax, 10h + mov [edi], al + add edi, 2 + dec ecx + jnz loc_4670CA + loc_4670DF: + and ebp, 2 + jz loc_4670EF + mov ax, [esi] + add esi, 4 + mov [edi], al + add edi, 2 + loc_4670EF: + sub edi, 320h + add edi, edx + sub edx, 2 + jge loc_46707C + loc_4670FC: + mov edx, 2 + mov eax, edi + sub eax, gpBufEnd + jb loc_467154 + add eax, 3FFh + shr eax, 8 + cmp eax, 2Ah + jg loc_467143 + mov ecx, WorldTbl3x16[eax*4] + mov eax, ecx + add esi, WorldTbl17_2[ecx] + shl eax, 6 + lea eax, [eax+eax*2] + shr ecx, 1 + sub edi, eax + add edx, ecx + mov eax, WorldBoolFlag + shr ecx, 1 + add eax, ecx + mov WorldBoolFlag, eax + jmp loc_467154 + loc_467143: + sub edi, 2D00h + add esi, 100h + jmp loc_4671DB + loc_467154: + mov ecx, 20h + sub ecx, edx + mov eax, WorldBoolFlag + inc eax + and eax, 1 + mov ebp, ecx + mov WorldBoolFlag, eax + jz loc_46719D + shr ecx, 2 + jz loc_467189 + loc_467172: + mov eax, [esi] + add esi, 4 + inc edi + ror eax, 8 + mov [edi], al + add edi, 2 + ror eax, 10h + mov [edi], al + inc edi + dec ecx + jnz loc_467172 + loc_467189: + and ebp, 2 + jz loc_4671C7 + mov ax, [esi] + add esi, 4 + inc edi + ror eax, 8 + mov [edi], al + inc edi + jmp loc_4671C7 + loc_46719D: + shr ecx, 2 + jz loc_4671B7 + loc_4671A2: + mov eax, [esi] + add esi, 4 + mov [edi], al + add edi, 2 + ror eax, 10h + mov [edi], al + add edi, 2 + dec ecx + jnz loc_4671A2 + loc_4671B7: + and ebp, 2 + jz loc_4671C7 + mov ax, [esi] + add esi, 4 + mov [edi], al + add edi, 2 + loc_4671C7: + sub edi, 320h + add edi, edx + add edx, 2 + cmp edx, 20h + jnz loc_467154 + loc_4671DB: + pop ebp + jmp loc_467944 + loc_4671E1: + xor eax, eax + mov WorldBoolFlag, eax + mov edx, 1Eh + mov eax, edi + sub eax, gpBufEnd + jb loc_467240 + add eax, 3FFh + shr eax, 8 + cmp eax, 2Dh + jg loc_46722F + mov ecx, WorldTbl3x16[eax*4] + mov eax, ecx + add esi, WorldTbl17_1[ecx] + shl eax, 6 + lea eax, [eax+eax*2] + shr ecx, 1 + sub edi, eax + sub edx, ecx + mov eax, WorldBoolFlag + shr ecx, 1 + add eax, ecx + mov WorldBoolFlag, eax + jmp loc_467240 + loc_46722F: + sub edi, 3000h + add esi, 120h + jmp $+83h + loc_467240: + add edi, edx + mov ecx, 20h + sub ecx, edx + mov eax, WorldBoolFlag + inc eax + and eax, 1 + mov WorldBoolFlag, eax + jz loc_467289 + shr ecx, 2 + jnb loc_467270 + mov ax, [esi+2] + add esi, 4 + inc edi + ror eax, 8 + mov [edi], al + inc edi + test ecx, ecx + jz loc_4672B3 + loc_467270: + mov eax, [esi] + add esi, 4 + inc edi + ror eax, 8 + mov [edi], al + add edi, 2 + ror eax, 10h + mov [edi], al + inc edi + dec ecx + jnz loc_467270 + jmp loc_4672B3 + loc_467289: + shr ecx, 2 + jnb loc_46729E + mov ax, [esi+2] + add esi, 4 + mov [edi], al + test ecx, ecx + lea edi, [edi+2] + jz loc_4672B3 + loc_46729E: + mov eax, [esi] + add esi, 4 + mov [edi], al + add edi, 2 + ror eax, 10h + mov [edi], al + dec ecx + lea edi, [edi+2] + jnz loc_46729E + loc_4672B3: + sub edi, 320h + sub edx, 2 + jge loc_467240 + // loc_4672BE: + mov edx, 8 + loc_4672C3: + cmp edi, gpBufEnd + jb loc_4672D3 + add esi, 20h + add edi, 20h + jmp loc_4672EF + loc_4672D3: + mov ecx, 8 + loc_4672D8: + mov eax, [esi] + add esi, 4 + inc edi + ror eax, 8 + mov [edi], al + add edi, 2 + ror eax, 10h + mov [edi], al + inc edi + dec ecx + jnz loc_4672D8 + loc_4672EF: + sub edi, 320h + cmp edi, gpBufEnd + jb loc_467305 + add esi, 20h + add edi, 20h + jmp loc_46731F + loc_467305: + mov ecx, 8 + loc_46730A: + mov eax, [esi] + add esi, 4 + mov [edi], al + add edi, 2 + ror eax, 10h + mov [edi], al + add edi, 2 + dec ecx + jnz loc_46730A + loc_46731F: + sub edi, 320h + dec edx + jnz loc_4672C3 + jmp loc_467944 + loc_46732D: + push ebp + xor eax, eax + mov WorldBoolFlag, eax + mov edx, 1Eh + mov eax, edi + sub eax, gpBufEnd + jb loc_46738D + add eax, 3FFh + shr eax, 8 + cmp eax, 2Dh + jg loc_46737C + mov ecx, WorldTbl3x16[eax*4] + mov eax, ecx + add esi, WorldTbl17_1[ecx] + shl eax, 6 + lea eax, [eax+eax*2] + shr ecx, 1 + sub edi, eax + sub edx, ecx + mov eax, WorldBoolFlag + shr ecx, 1 + add eax, ecx + mov WorldBoolFlag, eax + jmp loc_46738D + loc_46737C: + sub edi, 3000h + add esi, 120h + jmp loc_46740D + loc_46738D: + mov ecx, 20h + sub ecx, edx + mov eax, WorldBoolFlag + inc eax + and eax, 1 + mov ebp, ecx + mov WorldBoolFlag, eax + jz loc_4673D6 + shr ecx, 2 + jz loc_4673C2 + loc_4673AB: + mov eax, [esi] + add esi, 4 + inc edi + ror eax, 8 + mov [edi], al + add edi, 2 + ror eax, 10h + mov [edi], al + inc edi + dec ecx + jnz loc_4673AB + loc_4673C2: + and ebp, 2 + jz loc_467400 + mov ax, [esi] + add esi, 4 + inc edi + ror eax, 8 + mov [edi], al + inc edi + jmp loc_467400 + loc_4673D6: + shr ecx, 2 + jz loc_4673F0 + loc_4673DB: + mov eax, [esi] + add esi, 4 + mov [edi], al + add edi, 2 + ror eax, 10h + mov [edi], al + add edi, 2 + dec ecx + jnz loc_4673DB + loc_4673F0: + and ebp, 2 + jz loc_467400 + mov ax, [esi] + add esi, 4 + mov [edi], al + add edi, 2 + loc_467400: + sub edi, 320h + add edi, edx + sub edx, 2 + jge loc_46738D + loc_46740D: + mov edx, 8 + loc_467412: + cmp edi, gpBufEnd + jb loc_467422 + add esi, 20h + add edi, 20h + jmp loc_46743E + loc_467422: + mov ecx, 8 + loc_467427: + mov eax, [esi] + add esi, 4 + inc edi + ror eax, 8 + mov [edi], al + add edi, 2 + ror eax, 10h + mov [edi], al + inc edi + dec ecx + jnz loc_467427 + loc_46743E: + sub edi, 320h + cmp edi, gpBufEnd + jb loc_467454 + add esi, 20h + add edi, 20h + jmp loc_46746E + loc_467454: + mov ecx, 8 + loc_467459: + mov eax, [esi] + add esi, 4 + mov [edi], al + add edi, 2 + ror eax, 10h + mov [edi], al + add edi, 2 + dec ecx + jnz loc_467459 + loc_46746E: + sub edi, 320h + dec edx + jnz loc_467412 + pop ebp + jmp loc_467944 + loc_46747D: + mov edx, 10h + xor eax, eax + loc_467484: + cmp edi, gpBufEnd + jb loc_467494 + add esi, 20h + add edi, 20h + jmp loc_4674A5 + loc_467494: + mov ecx, 8 + loc_467499: + mov [edi+1], al + mov [edi+3], al + add edi, 4 + dec ecx + jnz loc_467499 + loc_4674A5: + sub edi, 320h + cmp edi, gpBufEnd + jb loc_4674BB + add esi, 20h + add edi, 20h + jmp loc_4674CB + loc_4674BB: + mov ecx, 8 + loc_4674C0: + mov [edi], al + mov [edi+2], al + add edi, 4 + dec ecx + jnz loc_4674C0 + loc_4674CB: + sub edi, 320h + dec edx + jnz loc_467484 + jmp loc_467944 + loc_4674D9: + mov eax, edi + and eax, 1 + mov WorldBoolFlag, eax + mov ecx, 20h + loc_4674E8: + push ecx + mov edx, 20h + loc_4674EE: + xor eax, eax + mov al, [esi] + inc esi + test al, al + js loc_46756C + sub edx, eax + cmp edi, gpBufEnd + jb loc_467507 + add esi, eax + add edi, eax + jmp loc_467566 + loc_467507: + mov ecx, eax + add esi, ecx + mov eax, edi + and eax, 1 + cmp eax, WorldBoolFlag + jnz loc_46753F + xor eax, eax + shr ecx, 1 + jnb loc_467525 + inc edi + test ecx, ecx + jz loc_467566 + jmp loc_46754E + loc_467525: + shr ecx, 1 + jnb loc_467531 + inc edi + mov [edi], al + inc edi + test ecx, ecx + jz loc_467566 + loc_467531: + mov [edi+1], al + mov [edi+3], al + add edi, 4 + dec ecx + jnz loc_467531 + jmp loc_467566 + loc_46753F: + xor eax, eax + shr ecx, 1 + jnb loc_46754E + mov [edi], al + inc edi + test ecx, ecx + jz loc_467566 + jmp loc_467525 + loc_46754E: + shr ecx, 1 + jnb loc_46755B + mov [edi], al + add edi, 2 + test ecx, ecx + jz loc_467566 + loc_46755B: + mov [edi], al + mov [edi+2], al + add edi, 4 + dec ecx + jnz loc_46755B + loc_467566: + test edx, edx + jz loc_467578 + jmp loc_4674EE + loc_46756C: + neg al + add edi, eax + sub edx, eax + jnz loc_4674EE + loc_467578: + pop ecx + mov eax, WorldBoolFlag + inc eax + and eax, 1 + mov WorldBoolFlag, eax + sub edi, 320h + dec ecx + jnz loc_4674E8 + jmp loc_467944 + loc_467599: + xor eax, eax + mov WorldBoolFlag, eax + mov edx, 1Eh + loc_4675A5: + cmp edi, gpBufEnd + jb loc_4675B7 + add esi, 20h + sub esi, edx + add edi, 20h + jmp loc_467608 + loc_4675B7: + add edi, edx + mov ecx, 20h + sub ecx, edx + mov eax, WorldBoolFlag + inc eax + and eax, 1 + mov WorldBoolFlag, eax + jz loc_4675ED + xor eax, eax + shr ecx, 2 + jnb loc_4675DF + inc edi + mov [edi], al + inc edi + test ecx, ecx + jz loc_467608 + loc_4675DF: + mov [edi+1], al + mov [edi+3], al + add edi, 4 + dec ecx + jnz loc_4675DF + jmp loc_467608 + loc_4675ED: + xor eax, eax + shr ecx, 2 + jnb loc_4675FD + mov [edi], al + add edi, 2 + test ecx, ecx + jz loc_467608 + loc_4675FD: + mov [edi], al + mov [edi+2], al + add edi, 4 + dec ecx + jnz loc_4675FD + loc_467608: + sub edi, 320h + test edx, edx + jz loc_467617 + sub edx, 2 + jmp loc_4675A5 + loc_467617: + mov edx, 2 + loc_46761C: + cmp edi, gpBufEnd + jb loc_46762E + add esi, 20h + sub esi, edx + add edi, 20h + jmp loc_46767F + loc_46762E: + add edi, edx + mov ecx, 20h + sub ecx, edx + mov eax, WorldBoolFlag + inc eax + and eax, 1 + mov WorldBoolFlag, eax + jz loc_467664 + xor eax, eax + shr ecx, 2 + jnb loc_467656 + inc edi + mov [edi], al + inc edi + test ecx, ecx + jz loc_46767F + loc_467656: + mov [edi+1], al + mov [edi+3], al + add edi, 4 + dec ecx + jnz loc_467656 + jmp loc_46767F + loc_467664: + xor eax, eax + shr ecx, 2 + jnb loc_467674 + mov [edi], al + add edi, 2 + test ecx, ecx + jz loc_46767F + loc_467674: + mov [edi], al + mov [edi+2], al + add edi, 4 + dec ecx + jnz loc_467674 + loc_46767F: + sub edi, 320h + add edx, 2 + cmp edx, 20h + jnz loc_46761C + jmp loc_467944 + loc_467692: + xor eax, eax + mov WorldBoolFlag, eax + mov edx, 1Eh + loc_46769E: + cmp edi, gpBufEnd + jb loc_4676B2 + add esi, 20h + sub esi, edx + add edi, 20h + sub edi, edx + jmp loc_467701 + loc_4676B2: + mov ecx, 20h + sub ecx, edx + mov eax, WorldBoolFlag + inc eax + and eax, 1 + mov WorldBoolFlag, eax + jz loc_4676E6 + xor eax, eax + shr ecx, 2 + jnb loc_4676D8 + inc edi + mov [edi], al + inc edi + test ecx, ecx + jz loc_467701 + loc_4676D8: + mov [edi+1], al + mov [edi+3], al + add edi, 4 + dec ecx + jnz loc_4676D8 + jmp loc_467701 + loc_4676E6: + xor eax, eax + shr ecx, 2 + jnb loc_4676F6 + mov [edi], al + add edi, 2 + test ecx, ecx + jz loc_467701 + loc_4676F6: + mov [edi], al + mov [edi+2], al + add edi, 4 + dec ecx + jnz loc_4676F6 + loc_467701: + sub edi, 320h + test edx, edx + jz loc_467712 + add edi, edx + sub edx, 2 + jmp loc_46769E + loc_467712: + mov edx, 2 + loc_467717: + cmp edi, gpBufEnd + jb loc_46772B + add esi, 20h + sub esi, edx + add edi, 20h + sub edi, edx + jmp loc_46777A + loc_46772B: + mov ecx, 20h + sub ecx, edx + mov eax, WorldBoolFlag + inc eax + and eax, 1 + mov WorldBoolFlag, eax + jz loc_46775F + xor eax, eax + shr ecx, 2 + jnb loc_467751 + inc edi + mov [edi], al + inc edi + test ecx, ecx + jz loc_46777A + loc_467751: + mov [edi+1], al + mov [edi+3], al + add edi, 4 + dec ecx + jnz loc_467751 + jmp loc_46777A + loc_46775F: + xor eax, eax + shr ecx, 2 + jnb loc_46776F + mov [edi], al + add edi, 2 + test ecx, ecx + jz loc_46777A + loc_46776F: + mov [edi], al + mov [edi+2], al + add edi, 4 + dec ecx + jnz loc_46776F + loc_46777A: + sub edi, 320h + add edi, edx + add edx, 2 + cmp edx, 20h + jnz loc_467717 + jmp loc_467944 + loc_46778F: + xor eax, eax + mov WorldBoolFlag, eax + mov edx, 1Eh + loc_46779B: + cmp edi, gpBufEnd + jb loc_4677AD + add esi, 20h + sub esi, edx + add edi, 20h + jmp loc_4677FE + loc_4677AD: + add edi, edx + mov ecx, 20h + sub ecx, edx + mov eax, WorldBoolFlag + inc eax + and eax, 1 + mov WorldBoolFlag, eax + jz loc_4677E3 + xor eax, eax + shr ecx, 2 + jnb loc_4677D5 + inc edi + mov [edi], al + inc edi + test ecx, ecx + jz loc_4677FE + loc_4677D5: + mov [edi+1], al + mov [edi+3], al + add edi, 4 + dec ecx + jnz loc_4677D5 + jmp loc_4677FE + loc_4677E3: + xor eax, eax + shr ecx, 2 + jnb loc_4677F3 + mov [edi], al + add edi, 2 + test ecx, ecx + jz loc_4677FE + loc_4677F3: + mov [edi], al + mov [edi+2], al + add edi, 4 + dec ecx + jnz loc_4677F3 + loc_4677FE: + sub edi, 320h + test edx, edx + jz loc_46780D + sub edx, 2 + jmp loc_46779B + loc_46780D: + mov edx, 8 + loc_467812: + cmp edi, gpBufEnd + jb loc_467822 + add esi, 20h + add edi, 20h + jmp loc_467835 + loc_467822: + mov ecx, 8 + xor eax, eax + loc_467829: + mov [edi+1], al + mov [edi+3], al + add edi, 4 + dec ecx + jnz loc_467829 + loc_467835: + sub edi, 320h + cmp edi, gpBufEnd + jb loc_46784B + add esi, 20h + add edi, 20h + jmp loc_46785D + loc_46784B: + mov ecx, 8 + xor eax, eax + loc_467852: + mov [edi], al + mov [edi+2], al + add edi, 4 + dec ecx + jnz loc_467852 + loc_46785D: + sub edi, 320h + dec edx + jnz loc_467812 + jmp loc_467944 + loc_46786B: + xor eax, eax + mov WorldBoolFlag, eax + mov edx, 1Eh + loc_467877: + cmp edi, gpBufEnd + jb loc_46788B + add esi, 20h + sub esi, edx + add edi, 20h + sub edi, edx + jmp loc_4678DA + loc_46788B: + mov ecx, 20h + sub ecx, edx + mov eax, WorldBoolFlag + inc eax + and eax, 1 + mov WorldBoolFlag, eax + jz loc_4678BF + xor eax, eax + shr ecx, 2 + jnb loc_4678B1 + inc edi + mov [edi], al + inc edi + test ecx, ecx + jz loc_4678DA + loc_4678B1: + mov [edi+1], al + mov [edi+3], al + add edi, 4 + dec ecx + jnz loc_4678B1 + jmp loc_4678DA + loc_4678BF: + xor eax, eax + shr ecx, 2 + jnb loc_4678CF + mov [edi], al + add edi, 2 + test ecx, ecx + jz loc_4678DA + loc_4678CF: + mov [edi], al + mov [edi+2], al + add edi, 4 + dec ecx + jnz loc_4678CF + loc_4678DA: + sub edi, 320h + test edx, edx + jz loc_4678EB + add edi, edx + sub edx, 2 + jmp loc_467877 + loc_4678EB: + mov edx, 8 + loc_4678F0: + cmp edi, gpBufEnd + jb loc_467900 + add esi, 20h + add edi, 20h + jmp loc_467913 + loc_467900: + mov ecx, 8 + xor eax, eax + loc_467907: + mov [edi+1], al + mov [edi+3], al + add edi, 4 + dec ecx + jnz loc_467907 + loc_467913: + sub edi, 320h + cmp edi, gpBufEnd + jb loc_467929 + add esi, 20h + add edi, 20h + jmp loc_46793B + loc_467929: + mov ecx, 8 + xor eax, eax + loc_467930: + mov [edi], al + mov [edi+2], al + add edi, 4 + dec ecx + jnz loc_467930 + loc_46793B: + sub edi, 320h + dec edx + jnz loc_4678F0 + loc_467944: + pop esi + pop edi + pop edx + pop ebx + retn + } +} + +__declspec(naked) void drawBottomArchesLowerScreen(BYTE *pBuff, unsigned int *pMask) +{ + __asm { + push ebx + push edi + push esi + mov edi, offset SpeedFrameTbl + mov gpCelFrame, edi + mov edi, ecx + mov gpDrawMask, edx + mov eax, light_table_index + test al, al + jz loc_467A58 + cmp al, lightmax + jz loc_467AB8 + mov eax, level_cel_block + and eax, 8000h + jnz loc_4679EC + mov ebx, pDungeonCels + mov esi, ebx + mov eax, level_cel_block + and eax, 0FFFh + shl eax, 2 + add ebx, eax + add esi, [ebx] + mov ebx, light_table_index + shl ebx, 8 + add ebx, pLightTbl + mov eax, level_cel_block + mov al, ah + shr eax, 4 + and eax, 0Fh + jz loc_467B43 + cmp ax, 1 + jz loc_467B8F + cmp ax, 2 + jz loc_467C20 + cmp ax, 3 + jz loc_467D5B + cmp ax, 4 + jz loc_467E99 + jmp loc_467F8A + loc_4679EC: + mov esi, gpCelFrame + mov eax, level_cel_block + and eax, 0FFFh + shl eax, 4 + add eax, light_table_index + shl eax, 2 + add esi, eax + mov eax, [esi] + mov esi, pSpeedCels + add esi, eax + mov eax, level_cel_block + mov al, ah + shr eax, 4 + and eax, 0Fh + loc_467A21: + cmp ax, 8 + jz loc_468086 + cmp ax, 9 + jz loc_4680D1 + cmp ax, 0Ah + jz loc_468161 + cmp ax, 0Bh + jz loc_468268 + cmp ax, 0Ch + jz loc_468372 + jmp loc_468448 + loc_467A58: + mov eax, level_cel_block + and eax, 8000h + jz loc_467A8A + mov esi, gpCelFrame + mov eax, level_cel_block + and eax, 0FFFh + shl eax, 6 + add esi, eax + mov eax, level_cel_block + and eax, 0F000h + add eax, [esi] + mov level_cel_block, eax + loc_467A8A: + mov ebx, pDungeonCels + mov esi, ebx + mov eax, level_cel_block + and eax, 0FFFh + shl eax, 2 + add ebx, eax + add esi, [ebx] + mov eax, level_cel_block + mov al, ah + shr eax, 4 + and eax, 7 + add eax, 8 + jmp loc_467A21 + loc_467AB8: + mov eax, level_cel_block + and eax, 8000h + jz loc_467AEA + mov esi, gpCelFrame + mov eax, level_cel_block + and eax, 0FFFh + shl eax, 6 + add esi, eax + mov eax, level_cel_block + and eax, 0F000h + add eax, [esi] + mov level_cel_block, eax + loc_467AEA: + mov ebx, pDungeonCels + mov esi, ebx + mov eax, level_cel_block + and eax, 0FFFh + shl eax, 2 + add ebx, eax + add esi, [ebx] + mov eax, level_cel_block + mov al, ah + shr eax, 4 + and eax, 7 + jz loc_468529 + cmp ax, 1 + jz loc_468573 + cmp ax, 2 + jz loc_468604 + cmp ax, 3 + jz loc_468696 + cmp ax, 4 + jz loc_46872C + jmp loc_4687CB + loc_467B43: + push ebp + mov ebp, 20h + loc_467B49: + cmp edi, gpBufEnd + jb loc_467B59 + add esi, 20h + add edi, 20h + jmp loc_467B73 + loc_467B59: + mov eax, gpDrawMask + mov edx, [eax] + mov ecx, 20h + loc_467B65: + mov al, [esi] + inc esi + shl edx, 1 + jnb loc_467B6F + xlat + mov [edi], al + loc_467B6F: + inc edi + dec ecx + jnz loc_467B65 + loc_467B73: + sub edi, 320h + mov eax, gpDrawMask + sub eax, 4 + mov gpDrawMask, eax + dec ebp + jnz loc_467B49 + pop ebp + jmp loc_468867 + loc_467B8F: + mov ecx, 20h + loc_467B94: + push ecx + mov eax, gpDrawMask + mov eax, [eax] + mov gdwCurrentMask, eax + mov edx, 20h + loc_467BA6: + xor eax, eax + mov al, [esi] + inc esi + test al, al + js loc_467BE3 + sub edx, eax + cmp edi, gpBufEnd + jb loc_467BBF + add esi, eax + add edi, eax + jmp loc_467BDD + loc_467BBF: + mov ecx, eax + push edx + mov edx, gdwCurrentMask + loc_467BC8: + mov al, [esi] + inc esi + shl edx, 1 + jnb loc_467BD2 + xlat + mov [edi], al + loc_467BD2: + inc edi + dec ecx + jnz loc_467BC8 + mov gdwCurrentMask, edx + pop edx + loc_467BDD: + test edx, edx + jz loc_467C00 + jmp loc_467BA6 + loc_467BE3: + neg al + add edi, eax + mov ecx, eax + and ecx, 1Fh + jz loc_467BFC + push eax + mov eax, gdwCurrentMask + shl eax, cl + mov gdwCurrentMask, eax + pop eax + loc_467BFC: + sub edx, eax + jnz loc_467BA6 + loc_467C00: + pop ecx + sub edi, 320h + mov eax, gpDrawMask + sub eax, 4 + mov gpDrawMask, eax + dec ecx + jnz loc_467B94 + jmp loc_468867 + loc_467C20: + mov edx, 1Eh + mov eax, edi + sub eax, gpBufEnd + jb loc_467C67 + add eax, 3FFh + shr eax, 8 + cmp eax, 2Dh + jg loc_467C59 + mov ecx, WorldTbl3x16[eax*4] + mov eax, ecx + add esi, WorldTbl17_1[ecx] + shl eax, 6 + lea eax, [eax+eax*2] + shr ecx, 1 + sub edi, eax + sub edx, ecx + jmp loc_467C67 + loc_467C59: + sub edi, 3000h + add esi, 120h + jmp loc_467CB8 + loc_467C67: + add edi, edx + mov ecx, 20h + sub ecx, edx + shr ecx, 2 + jnb loc_467C90 + mov ax, [esi+2] + add esi, 4 + xlat + ror ax, 8 + xlat + ror ax, 8 + mov [edi], ax + add edi, 2 + test ecx, ecx + jz loc_467CAD + loc_467C90: + mov eax, [esi] + add esi, 4 + xlat + ror eax, 8 + xlat + ror eax, 8 + xlat + ror eax, 8 + xlat + ror eax, 8 + mov [edi], eax + add edi, 4 + dec ecx + jnz loc_467C90 + loc_467CAD: + sub edi, 320h + sub edx, 2 + jge loc_467C67 + loc_467CB8: + mov edx, 2 + mov eax, edi + sub eax, gpBufEnd + jb loc_467D02 + add eax, 3FFh + shr eax, 8 + cmp eax, 2Ah + jg loc_467CF1 + mov ecx, WorldTbl3x16[eax*4] + mov eax, ecx + add esi, WorldTbl17_2[ecx] + shl eax, 6 + lea eax, [eax+eax*2] + shr ecx, 1 + sub edi, eax + add edx, ecx + jmp loc_467D02 + loc_467CF1: + sub edi, 2D00h + add esi, 100h + jmp loc_468867 + loc_467D02: + add edi, edx + mov ecx, 20h + sub ecx, edx + shr ecx, 2 + jnb loc_467D2B + mov ax, [esi+2] + add esi, 4 + xlat + ror ax, 8 + xlat + ror ax, 8 + mov [edi], ax + add edi, 2 + test ecx, ecx + jz loc_467D48 + loc_467D2B: + mov eax, [esi] + add esi, 4 + xlat + ror eax, 8 + xlat + ror eax, 8 + xlat + ror eax, 8 + xlat + ror eax, 8 + mov [edi], eax + add edi, 4 + dec ecx + jnz loc_467D2B + loc_467D48: + sub edi, 320h + add edx, 2 + cmp edx, 20h + jnz loc_467D02 + jmp loc_468867 + loc_467D5B: + push ebp + mov edx, 1Eh + mov eax, edi + sub eax, gpBufEnd + jb loc_467DA3 + add eax, 3FFh + shr eax, 8 + cmp eax, 2Dh + jg loc_467D95 + mov ecx, WorldTbl3x16[eax*4] + mov eax, ecx + add esi, WorldTbl17_1[ecx] + shl eax, 6 + lea eax, [eax+eax*2] + shr ecx, 1 + sub edi, eax + sub edx, ecx + jmp loc_467DA3 + loc_467D95: + sub edi, 3000h + add esi, 120h + jmp loc_467DF6 + loc_467DA3: + mov ecx, 20h + sub ecx, edx + mov ebp, ecx + shr ecx, 2 + jz loc_467DCE + loc_467DB1: + mov eax, [esi] + add esi, 4 + xlat + ror eax, 8 + xlat + ror eax, 8 + xlat + ror eax, 8 + xlat + ror eax, 8 + mov [edi], eax + add edi, 4 + dec ecx + jnz loc_467DB1 + loc_467DCE: + and ebp, 2 + jz loc_467DE9 + mov ax, [esi] + add esi, 4 + xlat + ror ax, 8 + xlat + ror ax, 8 + mov [edi], ax + add edi, 2 + loc_467DE9: + sub edi, 320h + add edi, edx + sub edx, 2 + jge loc_467DA3 + loc_467DF6: + mov edx, 2 + mov eax, edi + sub eax, gpBufEnd + jb loc_467E3D + add eax, 3FFh + shr eax, 8 + cmp eax, 2Ah + jg loc_467E2F + mov ecx, WorldTbl3x16[eax*4] + mov eax, ecx + add esi, WorldTbl17_2[ecx] + shl eax, 6 + lea eax, [eax+eax*2] + shr ecx, 1 + sub edi, eax + add edx, ecx + jmp loc_467E3D + loc_467E2F: + sub edi, 2D00h + add esi, 100h + jmp loc_467E93 + loc_467E3D: + mov ecx, 20h + sub ecx, edx + mov ebp, ecx + shr ecx, 2 + jz loc_467E68 + loc_467E4B: + mov eax, [esi] + add esi, 4 + xlat + ror eax, 8 + xlat + ror eax, 8 + xlat + ror eax, 8 + xlat + ror eax, 8 + mov [edi], eax + add edi, 4 + dec ecx + jnz loc_467E4B + loc_467E68: + and ebp, 2 + jz loc_467E83 + mov ax, [esi] + add esi, 2 + xlat + ror ax, 8 + xlat + ror ax, 8 + mov [edi], ax + add edi, 2 + loc_467E83: + sub edi, 320h + add edi, edx + add edx, 2 + cmp edx, 20h + jnz loc_467E3D + loc_467E93: + pop ebp + jmp loc_468867 + loc_467E99: + mov edx, 1Eh + mov eax, edi + sub eax, gpBufEnd + jb loc_467EE0 + add eax, 3FFh + shr eax, 8 + cmp eax, 2Dh + jg loc_467ED2 + mov ecx, WorldTbl3x16[eax*4] + mov eax, ecx + add esi, WorldTbl17_1[ecx] + shl eax, 6 + lea eax, [eax+eax*2] + shr ecx, 1 + sub edi, eax + sub edx, ecx + jmp loc_467EE0 + loc_467ED2: + sub edi, 3000h + add esi, 120h + jmp loc_467F31 + loc_467EE0: + add edi, edx + mov ecx, 20h + sub ecx, edx + shr ecx, 2 + jnb loc_467F09 + mov ax, [esi+2] + add esi, 4 + xlat + ror ax, 8 + xlat + ror ax, 8 + mov [edi], ax + add edi, 2 + test ecx, ecx + jz loc_467F26 + loc_467F09: + mov eax, [esi] + add esi, 4 + xlat + ror eax, 8 + xlat + ror eax, 8 + xlat + ror eax, 8 + xlat + ror eax, 8 + mov [edi], eax + add edi, 4 + dec ecx + jnz loc_467F09 + loc_467F26: + sub edi, 320h + sub edx, 2 + jge loc_467EE0 + loc_467F31: + mov eax, gpDrawMask + sub eax, 40h + mov gpDrawMask, eax + mov edx, 10h + loc_467F43: + cmp edi, gpBufEnd + jb loc_467F53 + add esi, 20h + add edi, 20h + jmp loc_467F6F + loc_467F53: + push edx + mov eax, gpDrawMask + mov edx, [eax] + mov ecx, 20h + loc_467F60: + mov al, [esi] + inc esi + shl edx, 1 + jnb loc_467F6A + xlat + mov [edi], al + loc_467F6A: + inc edi + dec ecx + jnz loc_467F60 + pop edx + loc_467F6F: + sub edi, 320h + mov eax, gpDrawMask + sub eax, 4 + mov gpDrawMask, eax + dec edx + jnz loc_467F43 + jmp loc_468867 + loc_467F8A: + push ebp + mov edx, 1Eh + mov eax, edi + sub eax, gpBufEnd + jb loc_467FD2 + add eax, 3FFh + shr eax, 8 + cmp eax, 2Dh + jg loc_467FC4 + mov ecx, WorldTbl3x16[eax*4] + mov eax, ecx + add esi, WorldTbl17_1[ecx] + shl eax, 6 + lea eax, [eax+eax*2] + shr ecx, 1 + sub edi, eax + sub edx, ecx + jmp loc_467FD2 + loc_467FC4: + sub edi, 3000h + add esi, 120h + jmp loc_468025 + loc_467FD2: + mov ecx, 20h + sub ecx, edx + mov ebp, ecx + shr ecx, 2 + jz loc_467FFD + loc_467FE0: + mov eax, [esi] + add esi, 4 + xlat + ror eax, 8 + xlat + ror eax, 8 + xlat + ror eax, 8 + xlat + ror eax, 8 + mov [edi], eax + add edi, 4 + dec ecx + jnz loc_467FE0 + loc_467FFD: + and ebp, 2 + jz loc_468018 + mov ax, [esi] + add esi, 4 + xlat + ror ax, 8 + xlat + ror ax, 8 + mov [edi], ax + add edi, 2 + loc_468018: + sub edi, 320h + add edi, edx + sub edx, 2 + jge loc_467FD2 + loc_468025: + mov eax, gpDrawMask + sub eax, 40h + mov gpDrawMask, eax + mov edx, 10h + loc_468037: + cmp edi, gpBufEnd + jb loc_468047 + add esi, 20h + add edi, 20h + jmp loc_46806A + loc_468047: + push edx + mov eax, gpDrawMask + mov edx, [eax] + mov ecx, 20h + loc_468054: + mov al, [esi] + inc esi + shl edx, 1 + jnb loc_46805E + xlat + mov [edi], al + loc_46805E: + inc edi + dec ecx + jnz loc_468054 + mov ebp, esi + and ebp, 2 + add esi, ebp + pop edx + loc_46806A: + sub edi, 320h + mov eax, gpDrawMask + sub eax, 4 + mov gpDrawMask, eax + dec edx + jnz loc_468037 + pop ebp + jmp loc_468867 + loc_468086: + mov edx, 20h + loc_46808B: + cmp edi, gpBufEnd + jb loc_46809B + add esi, 20h + add edi, 20h + jmp loc_4680B6 + loc_46809B: + push edx + mov eax, gpDrawMask + mov edx, [eax] + mov ecx, 20h + loc_4680A8: + mov al, [esi] + inc esi + shl edx, 1 + jnb loc_4680B1 + mov [edi], al + loc_4680B1: + inc edi + dec ecx + jnz loc_4680A8 + pop edx + loc_4680B6: + sub edi, 320h + mov eax, gpDrawMask + sub eax, 4 + mov gpDrawMask, eax + dec edx + jnz loc_46808B + jmp loc_468867 + loc_4680D1: + mov ecx, 20h + loc_4680D6: + push ecx + mov eax, gpDrawMask + mov eax, [eax] + mov gdwCurrentMask, eax + mov edx, 20h + loc_4680E8: + xor eax, eax + mov al, [esi] + inc esi + test al, al + js loc_468124 + sub edx, eax + cmp edi, gpBufEnd + jb loc_468101 + add esi, eax + add edi, eax + jmp loc_46811E + loc_468101: + mov ecx, eax + push edx + mov edx, gdwCurrentMask + loc_46810A: + mov al, [esi] + inc esi + shl edx, 1 + jnb loc_468113 + mov [edi], al + loc_468113: + inc edi + dec ecx + jnz loc_46810A + mov gdwCurrentMask, edx + pop edx + loc_46811E: + test edx, edx + jz loc_468141 + jmp loc_4680E8 + loc_468124: + neg al + add edi, eax + mov ecx, eax + and ecx, 1Fh + jz loc_46813D + mov ebx, gdwCurrentMask + shl ebx, cl + mov gdwCurrentMask, ebx + loc_46813D: + sub edx, eax + jnz loc_4680E8 + loc_468141: + pop ecx + sub edi, 320h + mov eax, gpDrawMask + sub eax, 4 + mov gpDrawMask, eax + dec ecx + jnz loc_4680D6 + jmp loc_468867 + loc_468161: + mov edx, 1Eh + mov eax, edi + sub eax, gpBufEnd + jb loc_4681A8 + add eax, 3FFh + shr eax, 8 + cmp eax, 2Dh + jg loc_46819A + mov ecx, WorldTbl3x16[eax*4] + mov eax, ecx + add esi, WorldTbl17_1[ecx] + shl eax, 6 + lea eax, [eax+eax*2] + shr ecx, 1 + sub edi, eax + sub edx, ecx + jmp loc_4681A8 + loc_46819A: + sub edi, 3000h + add esi, 120h + jmp loc_4681DF + loc_4681A8: + add edi, edx + mov ecx, 20h + sub ecx, edx + shr ecx, 2 + jnb loc_4681C7 + mov ax, [esi+2] + add esi, 4 + mov [edi], ax + add edi, 2 + test ecx, ecx + jz loc_4681D4 + loc_4681C7: + mov eax, [esi] + add esi, 4 + mov [edi], eax + add edi, 4 + dec ecx + jnz loc_4681C7 + loc_4681D4: + sub edi, 320h + sub edx, 2 + jge loc_4681A8 + loc_4681DF: + mov edx, 2 + mov eax, edi + sub eax, gpBufEnd + jb loc_468229 + add eax, 3FFh + shr eax, 8 + cmp eax, 2Ah + jg loc_468218 + mov ecx, WorldTbl3x16[eax*4] + mov eax, ecx + add esi, WorldTbl17_2[ecx] + shl eax, 6 + lea eax, [eax+eax*2] + shr ecx, 1 + sub edi, eax + add edx, ecx + jmp loc_468229 + loc_468218: + sub edi, 2D00h + add esi, 100h + jmp loc_468867 + loc_468229: + add edi, edx + mov ecx, 20h + sub ecx, edx + shr ecx, 2 + jnb loc_468248 + mov ax, [esi+2] + add esi, 4 + mov [edi], ax + add edi, 2 + test ecx, ecx + jz loc_468255 + loc_468248: + mov eax, [esi] + add esi, 4 + mov [edi], eax + add edi, 4 + dec ecx + jnz loc_468248 + loc_468255: + sub edi, 320h + add edx, 2 + cmp edx, 20h + jnz loc_468229 + jmp loc_468867 + loc_468268: + push ebp + mov edx, 1Eh + mov eax, edi + sub eax, gpBufEnd + jb loc_4682B0 + add eax, 3FFh + shr eax, 8 + cmp eax, 2Dh + jg loc_4682A2 + mov ecx, WorldTbl3x16[eax*4] + mov eax, ecx + add esi, WorldTbl17_1[ecx] + shl eax, 6 + lea eax, [eax+eax*2] + shr ecx, 1 + sub edi, eax + sub edx, ecx + jmp loc_4682B0 + loc_4682A2: + sub edi, 3000h + add esi, 120h + jmp loc_4682E9 + loc_4682B0: + mov ecx, 20h + sub ecx, edx + mov ebp, ecx + shr ecx, 2 + jz loc_4682CB + loc_4682BE: + mov eax, [esi] + add esi, 4 + mov [edi], eax + add edi, 4 + dec ecx + jnz loc_4682BE + loc_4682CB: + and ebp, 2 + jz loc_4682DC + mov ax, [esi] + add esi, 4 + mov [edi], ax + add edi, 2 + loc_4682DC: + sub edi, 320h + add edi, edx + sub edx, 2 + jge loc_4682B0 + loc_4682E9: + mov edx, 2 + mov eax, edi + sub eax, gpBufEnd + jb loc_468330 + add eax, 3FFh + shr eax, 8 + cmp eax, 2Ah + jg loc_468322 + mov ecx, WorldTbl3x16[eax*4] + mov eax, ecx + add esi, WorldTbl17_2[ecx] + shl eax, 6 + lea eax, [eax+eax*2] + shr ecx, 1 + sub edi, eax + add edx, ecx + jmp loc_468330 + loc_468322: + sub edi, 2D00h + add esi, 100h + jmp loc_46836C + loc_468330: + mov ecx, 20h + sub ecx, edx + mov ebp, ecx + shr ecx, 2 + jz loc_46834B + loc_46833E: + mov eax, [esi] + add esi, 4 + mov [edi], eax + add edi, 4 + dec ecx + jnz loc_46833E + loc_46834B: + and ebp, 2 + jz loc_46835C + mov ax, [esi] + add esi, 4 + mov [edi], ax + add edi, 2 + loc_46835C: + sub edi, 320h + add edi, edx + add edx, 2 + cmp edx, 20h + jnz loc_468330 + loc_46836C: + pop ebp + jmp loc_468867 + loc_468372: + mov edx, 1Eh + mov eax, edi + sub eax, gpBufEnd + jb loc_4683B9 + add eax, 3FFh + shr eax, 8 + cmp eax, 2Dh + jg loc_4683AB + mov ecx, WorldTbl3x16[eax*4] + mov eax, ecx + add esi, WorldTbl17_1[ecx] + shl eax, 6 + lea eax, [eax+eax*2] + shr ecx, 1 + sub edi, eax + sub edx, ecx + jmp loc_4683B9 + loc_4683AB: + sub edi, 3000h + add esi, 120h + jmp loc_4683F0 + loc_4683B9: + add edi, edx + mov ecx, 20h + sub ecx, edx + shr ecx, 2 + jnb loc_4683D8 + mov ax, [esi+2] + add esi, 4 + mov [edi], ax + add edi, 2 + test ecx, ecx + jz loc_4683E5 + loc_4683D8: + mov eax, [esi] + add esi, 4 + mov [edi], eax + add edi, 4 + dec ecx + jnz loc_4683D8 + loc_4683E5: + sub edi, 320h + sub edx, 2 + jge loc_4683B9 + loc_4683F0: + mov eax, gpDrawMask + sub eax, 40h + mov gpDrawMask, eax + mov edx, 10h + loc_468402: + cmp edi, gpBufEnd + jb loc_468412 + add esi, 20h + add edi, 20h + jmp loc_46842D + loc_468412: + push edx + mov eax, gpDrawMask + mov edx, [eax] + mov ecx, 20h + loc_46841F: + mov al, [esi] + inc esi + shl edx, 1 + jnb loc_468428 + mov [edi], al + loc_468428: + inc edi + dec ecx + jnz loc_46841F + pop edx + loc_46842D: + sub edi, 320h + mov eax, gpDrawMask + sub eax, 4 + mov gpDrawMask, eax + dec edx + jnz loc_468402 + jmp loc_468867 + loc_468448: + push ebp + mov edx, 1Eh + mov eax, edi + sub eax, gpBufEnd + jb loc_468490 + add eax, 3FFh + shr eax, 8 + cmp eax, 2Dh + jg loc_468482 + mov ecx, WorldTbl3x16[eax*4] + mov eax, ecx + add esi, WorldTbl17_1[ecx] + shl eax, 6 + lea eax, [eax+eax*2] + shr ecx, 1 + sub edi, eax + sub edx, ecx + jmp loc_468490 + loc_468482: + sub edi, 3000h + add esi, 120h + jmp loc_4684C9 + loc_468490: + mov ecx, 20h + sub ecx, edx + mov ebp, ecx + shr ecx, 2 + jz loc_4684AB + loc_46849E: + mov eax, [esi] + add esi, 4 + mov [edi], eax + add edi, 4 + dec ecx + jnz loc_46849E + loc_4684AB: + and ebp, 2 + jz loc_4684BC + mov ax, [esi] + add esi, 4 + mov [edi], ax + add edi, 2 + loc_4684BC: + sub edi, 320h + add edi, edx + sub edx, 2 + jge loc_468490 + loc_4684C9: + mov eax, gpDrawMask + sub eax, 40h + mov gpDrawMask, eax + mov edx, 10h + loc_4684DB: + cmp edi, gpBufEnd + jb loc_4684EB + add esi, 20h + add edi, 20h + jmp loc_46850D + loc_4684EB: + push edx + mov eax, gpDrawMask + mov edx, [eax] + mov ecx, 20h + loc_4684F8: + mov al, [esi] + inc esi + shl edx, 1 + jnb loc_468501 + mov [edi], al + loc_468501: + inc edi + dec ecx + jnz loc_4684F8 + mov ebp, esi + and ebp, 2 + add esi, ebp + pop edx + loc_46850D: + sub edi, 320h + mov eax, gpDrawMask + sub eax, 4 + mov gpDrawMask, eax + dec edx + jnz loc_4684DB + pop ebp + jmp loc_468867 + loc_468529: + mov edx, 20h + loc_46852E: + cmp edi, gpBufEnd + jb loc_46853E + add esi, 20h + add edi, 20h + jmp loc_468558 + loc_46853E: + push edx + mov eax, gpDrawMask + mov edx, [eax] + xor eax, eax + mov ecx, 20h + loc_46854D: + shl edx, 1 + jnb loc_468553 + mov [edi], al + loc_468553: + inc edi + dec ecx + jnz loc_46854D + pop edx + loc_468558: + sub edi, 320h + mov eax, gpDrawMask + sub eax, 4 + mov gpDrawMask, eax + dec edx + jnz loc_46852E + jmp loc_468867 + loc_468573: + mov ecx, 20h + loc_468578: + push ecx + mov eax, gpDrawMask + mov eax, [eax] + mov gdwCurrentMask, eax + mov edx, 20h + loc_46858A: + xor eax, eax + mov al, [esi] + inc esi + test al, al + js loc_4685C7 + sub edx, eax + cmp edi, gpBufEnd + jb loc_4685A3 + add esi, eax + add edi, eax + jmp loc_4685C1 + loc_4685A3: + mov ecx, eax + add esi, ecx + push edx + mov edx, gdwCurrentMask + xor eax, eax + loc_4685B0: + shl edx, 1 + jnb loc_4685B6 + mov [edi], al + loc_4685B6: + inc edi + dec ecx + jnz loc_4685B0 + mov gdwCurrentMask, edx + pop edx + loc_4685C1: + test edx, edx + jz loc_4685E4 + jmp loc_46858A + loc_4685C7: + neg al + add edi, eax + mov ecx, eax + and ecx, 1Fh + jz loc_4685E0 + mov ebx, gdwCurrentMask + shl ebx, cl + mov gdwCurrentMask, ebx + loc_4685E0: + sub edx, eax + jnz loc_46858A + loc_4685E4: + pop ecx + sub edi, 320h + mov eax, gpDrawMask + sub eax, 4 + mov gpDrawMask, eax + dec ecx + jnz loc_468578 + jmp loc_468867 + loc_468604: + mov edx, 1Eh + xor eax, eax + loc_46860B: + cmp edi, gpBufEnd + jb loc_46861D + add esi, 20h + sub esi, edx + add edi, 20h + jmp loc_46863D + loc_46861D: + add edi, edx + mov ecx, 20h + sub ecx, edx + shr ecx, 2 + jnb loc_468635 + mov [edi], ax + add edi, 2 + test ecx, ecx + jz loc_46863D + loc_468635: + mov [edi], eax + add edi, 4 + dec ecx + jnz loc_468635 + loc_46863D: + sub edi, 320h + test edx, edx + jz loc_46864C + sub edx, 2 + jmp loc_46860B + loc_46864C: + mov edx, 2 + loc_468651: + cmp edi, gpBufEnd + jb loc_468663 + add esi, 20h + sub esi, edx + add edi, 20h + jmp loc_468683 + loc_468663: + add edi, edx + mov ecx, 20h + sub ecx, edx + shr ecx, 2 + jnb loc_46867B + mov [edi], ax + add edi, 2 + test ecx, ecx + jz loc_468683 + loc_46867B: + mov [edi], eax + add edi, 4 + dec ecx + jnz loc_46867B + loc_468683: + sub edi, 320h + add edx, 2 + cmp edx, 20h + jnz loc_468651 + jmp loc_468867 + loc_468696: + mov edx, 1Eh + xor eax, eax + loc_46869D: + cmp edi, gpBufEnd + jb loc_4686B1 + add esi, 20h + sub esi, edx + add edi, 20h + sub edi, edx + jmp loc_4686CF + loc_4686B1: + mov ecx, 20h + sub ecx, edx + shr ecx, 2 + jnb loc_4686C7 + mov [edi], ax + add edi, 2 + test ecx, ecx + jz loc_4686CF + loc_4686C7: + mov [edi], eax + add edi, 4 + dec ecx + jnz loc_4686C7 + loc_4686CF: + sub edi, 320h + test edx, edx + jz loc_4686E0 + add edi, edx + sub edx, 2 + jmp loc_46869D + loc_4686E0: + mov edx, 2 + loc_4686E5: + cmp edi, gpBufEnd + jb loc_4686F9 + add esi, 20h + sub esi, edx + add edi, 20h + sub edi, edx + jmp loc_468717 + loc_4686F9: + mov ecx, 20h + sub ecx, edx + shr ecx, 2 + jnb loc_46870F + mov [edi], ax + add edi, 2 + test ecx, ecx + jz loc_468717 + loc_46870F: + mov [edi], eax + add edi, 4 + dec ecx + jnz loc_46870F + loc_468717: + sub edi, 320h + add edi, edx + add edx, 2 + cmp edx, 20h + jnz loc_4686E5 + jmp loc_468867 + loc_46872C: + mov edx, 1Eh + xor eax, eax + loc_468733: + cmp edi, gpBufEnd + jb loc_468745 + add esi, 20h + sub esi, edx + add edi, 20h + jmp loc_468765 + loc_468745: + add edi, edx + mov ecx, 20h + sub ecx, edx + shr ecx, 2 + jnb loc_46875D + mov [edi], ax + add edi, 2 + test ecx, ecx + jz loc_468765 + loc_46875D: + mov [edi], eax + add edi, 4 + dec ecx + jnz loc_46875D + loc_468765: + sub edi, 320h + test edx, edx + jz loc_468774 + sub edx, 2 + jmp loc_468733 + loc_468774: + mov eax, gpDrawMask + sub eax, 40h + mov gpDrawMask, eax + mov edx, 10h + loc_468786: + cmp edi, gpBufEnd + jb loc_468796 + add esi, 20h + add edi, 20h + jmp loc_4687B0 + loc_468796: + push edx + mov eax, gpDrawMask + mov edx, [eax] + xor eax, eax + mov ecx, 20h + loc_4687A5: + shl edx, 1 + jnb loc_4687AB + mov [edi], al + loc_4687AB: + inc edi + dec ecx + jnz loc_4687A5 + pop edx + loc_4687B0: + sub edi, 320h + mov eax, gpDrawMask + sub eax, 4 + mov gpDrawMask, eax + dec edx + jnz loc_468786 + jmp loc_468867 + loc_4687CB: + mov edx, 1Eh + xor eax, eax + loc_4687D2: + cmp edi, gpBufEnd + jb loc_4687E6 + add esi, 20h + sub esi, edx + add edi, 20h + sub edi, edx + jmp loc_468804 + loc_4687E6: + mov ecx, 20h + sub ecx, edx + shr ecx, 2 + jnb loc_4687FC + mov [edi], ax + add edi, 2 + test ecx, ecx + jz loc_468804 + loc_4687FC: + mov [edi], eax + add edi, 4 + dec ecx + jnz loc_4687FC + loc_468804: + sub edi, 320h + test edx, edx + jz loc_468815 + add edi, edx + sub edx, 2 + jmp loc_4687D2 + loc_468815: + mov eax, gpDrawMask + sub eax, 40h + mov gpDrawMask, eax + mov edx, 10h + loc_468827: + cmp edi, gpBufEnd + jb loc_468837 + add esi, 20h + add edi, 20h + jmp loc_468851 + loc_468837: + push edx + mov eax, gpDrawMask + mov edx, [eax] + xor eax, eax + mov ecx, 20h + loc_468846: + shl edx, 1 + jnb loc_46884C + mov [edi], al + loc_46884C: + inc edi + dec ecx + jnz loc_468846 + pop edx + loc_468851: + sub edi, 320h + mov eax, gpDrawMask + sub eax, 4 + mov gpDrawMask, eax + dec edx + jnz loc_468827 + loc_468867: + pop esi + pop edi + pop ebx + retn + } +} + +__declspec(naked) void drawLowerScreen(BYTE *pBuff) +{ + __asm { + push ebx + push edx + push edi + push esi + mov edx, cel_transparency_active + test edx, edx + jz loc_468918 + mov dl, arch_draw_type + cmp dl, 0 + jnz loc_468892 + call drawTopArchesLowerScreen + jmp loc_4696B9 + loc_468892: + cmp dl, 1 + jnz loc_4688D5 + mov ebx, level_piece_id + mov al, block_lvid[ebx] + cmp al, 1 + jz loc_4688AD + cmp al, 3 + jz loc_4688AD + jmp loc_4688D5 + loc_4688AD: + mov edx, offset LeftMask + add edx, 7Ch + call drawBottomArchesLowerScreen + jmp loc_4696B9 + cmp al, 4 + jnz loc_4688D5 + mov edx, offset RightMask + add edx, 7Ch + call drawBottomArchesLowerScreen + jmp loc_4696B9 + loc_4688D5: + cmp dl, 2 + jnz loc_468918 + mov ebx, level_piece_id + mov al, block_lvid[ebx] + cmp al, 2 + jz loc_4688F0 + cmp al, 3 + jz loc_4688F0 + jmp loc_468918 + loc_4688F0: + mov edx, offset RightMask + add edx, 7Ch + call drawBottomArchesLowerScreen + jmp loc_4696B9 + cmp al, 4 + jnz loc_468918 + mov edx, offset LeftMask + add edx, 7Ch + call drawBottomArchesLowerScreen + jmp loc_4696B9 + loc_468918: + mov edi, offset SpeedFrameTbl + mov gpCelFrame, edi + mov edi, ecx + mov eax, light_table_index + test al, al + jz loc_468A1A + cmp al, lightmax + jz loc_468A78 + mov eax, level_cel_block + and eax, 8000h + jnz loc_4689B0 + mov ebx, pDungeonCels + mov esi, ebx + mov eax, level_cel_block + and eax, 0FFFh + shl eax, 2 + add ebx, eax + add esi, [ebx] + mov ebx, light_table_index + shl ebx, 8 + add ebx, pLightTbl + mov eax, level_cel_block + shr eax, 0Ch + and eax, 0Fh + jz loc_468B03 + cmp ax, 1 + jz loc_468B5B + cmp ax, 2 + jz loc_468C06 + cmp ax, 3 + jz loc_468CEC + cmp ax, 4 + jz loc_468DD2 + jmp loc_468EE2 + loc_4689B0: + mov esi, gpCelFrame + mov eax, level_cel_block + and eax, 0FFFh + shl eax, 4 + add eax, light_table_index + shl eax, 2 + add esi, eax + mov eax, [esi] + mov esi, pSpeedCels + add esi, eax + mov eax, level_cel_block + shr eax, 0Ch + and eax, 0Fh + loc_4689E3: + cmp ax, 8 + jz loc_468FF2 + cmp ax, 9 + jz loc_469027 + cmp ax, 0Ah + jz loc_469099 + cmp ax, 0Bh + jz loc_46919D + cmp ax, 0Ch + jz loc_4692A5 + jmp loc_469358 + loc_468A1A: + mov eax, level_cel_block + and eax, 8000h + jz loc_468A4C + mov esi, gpCelFrame + mov eax, level_cel_block + and eax, 0FFFh + shl eax, 6 + add esi, eax + mov eax, level_cel_block + and eax, 0F000h + add eax, [esi] + mov level_cel_block, eax + loc_468A4C: + mov ebx, pDungeonCels + mov esi, ebx + mov eax, level_cel_block + and eax, 0FFFh + shl eax, 2 + add ebx, eax + add esi, [ebx] + mov eax, level_cel_block + shr eax, 0Ch + and eax, 7 + add eax, 8 + jmp loc_4689E3 + loc_468A78: + mov eax, level_cel_block + and eax, 8000h + jz loc_468AAA + mov esi, gpCelFrame + mov eax, level_cel_block + and eax, 0FFFh + shl eax, 6 + add esi, eax + mov eax, level_cel_block + and eax, 0F000h + add eax, [esi] + mov level_cel_block, eax + loc_468AAA: + mov ebx, pDungeonCels + mov esi, ebx + mov eax, level_cel_block + and eax, 0FFFh + shl eax, 2 + add ebx, eax + add esi, [ebx] + mov eax, level_cel_block + mov al, ah + shr eax, 4 + and eax, 7 + jz loc_46940D + cmp ax, 1 + jz loc_46943F + cmp ax, 2 + jz loc_4694A7 + cmp ax, 3 + jz loc_469539 + cmp ax, 4 + jz loc_4695CF + jmp loc_469644 + loc_468B03: + mov edx, 20h + push ebp + loc_468B09: + push edx + cmp edi, gpBufEnd + jb loc_468B1A + add esi, 20h + add edi, 20h + jmp loc_468B4B + loc_468B1A: + xor edx, edx + mov ebp, 8 + loc_468B21: + mov eax, [esi] + add esi, 4 + ror eax, 10h + mov dl, al + mov cl, [ebx+edx] + mov dl, ah + mov ch, [ebx+edx] + ror eax, 10h + shl ecx, 10h + mov dl, al + mov cl, [ebx+edx] + mov dl, ah + mov ch, [ebx+edx] + mov [edi], ecx + add edi, 4 + dec ebp + jnz loc_468B21 + loc_468B4B: + sub edi, 320h + pop edx + dec edx + jnz loc_468B09 + pop ebp + jmp loc_4696B9 + loc_468B5B: + push ebp + mov ecx, 20h + loc_468B61: + push ecx + mov ebp, 20h + loc_468B67: + xor eax, eax + mov al, [esi] + inc esi + test al, al + jns loc_468B78 + neg al + add edi, eax + sub ebp, eax + jmp loc_468BEA + loc_468B78: + sub ebp, eax + cmp edi, gpBufEnd + jb loc_468B88 + add esi, eax + add edi, eax + jmp loc_468BEA + loc_468B88: + mov ecx, eax + cmp cl, 4 + jl loc_468BC1 + loc_468B8F: + mov eax, [esi] + add esi, 4 + mov dl, al + mov ch, [ebx+edx] + mov dl, ah + ror eax, 10h + mov [edi], ch + mov ch, [ebx+edx] + mov dl, al + mov [edi+1], ch + mov ch, [ebx+edx] + mov dl, ah + mov [edi+2], ch + mov ch, [ebx+edx] + mov [edi+3], ch + add edi, 4 + sub cl, 4 + cmp cl, 4 + jge loc_468B8F + loc_468BC1: + cmp cl, 2 + jl loc_468BDC + mov dl, [esi] + mov ch, [ebx+edx] + mov [edi], ch + mov dl, [esi+1] + mov ch, [ebx+edx] + mov [edi+1], ch + add esi, 2 + add edi, 2 + loc_468BDC: + and cl, 1 + jz loc_468BEA + mov dl, [esi] + inc esi + mov dl, [ebx+edx] + mov [edi], dl + inc edi + loc_468BEA: + test ebp, ebp + jnz loc_468B67 + pop ecx + sub edi, 320h + dec ecx + jnz loc_468B61 + pop ebp + jmp loc_4696B9 + loc_468C06: + push ebp + mov ebp, 1Eh + mov eax, edi + sub eax, gpBufEnd + jb loc_468C4E + add eax, 3FFh + shr eax, 8 + cmp eax, 2Dh + jg loc_468C40 + mov ecx, WorldTbl3x16[eax*4] + mov eax, ecx + add esi, WorldTbl17_1[ecx] + shl eax, 6 + lea eax, [eax+eax*2] + shr ecx, 1 + sub edi, eax + sub ebp, ecx + jmp loc_468C4E + loc_468C40: + sub edi, 3000h + add esi, 120h + jmp loc_468C75 + loc_468C4E: + add edi, ebp + mov ecx, 20h + sub ecx, ebp + mov edx, ecx + and edx, 2 + add esi, edx + loc_468C5E: + mov dl, [esi] + inc esi + mov dl, [ebx+edx] + mov [edi], dl + inc edi + dec ecx + jnz loc_468C5E + sub edi, 320h + sub ebp, 2 + jge loc_468C4E + loc_468C75: + mov ebp, 2 + mov eax, edi + sub eax, gpBufEnd + jb loc_468CBC + add eax, 3FFh + shr eax, 8 + cmp eax, 2Ah + jg loc_468CAE + mov ecx, WorldTbl3x16[eax*4] + mov eax, ecx + add esi, WorldTbl17_2[ecx] + shl eax, 6 + lea eax, [eax+eax*2] + shr ecx, 1 + sub edi, eax + add ebp, ecx + jmp loc_468CBC + loc_468CAE: + sub edi, 2D00h + add esi, 100h + jmp loc_468CE6 + loc_468CBC: + add edi, ebp + mov ecx, 20h + sub ecx, ebp + mov edx, ecx + and edx, 2 + add esi, edx + loc_468CCC: + mov dl, [esi] + inc esi + mov dl, [ebx+edx] + mov [edi], dl + inc edi + dec ecx + jnz loc_468CCC + add ebp, 2 + sub edi, 320h + cmp ebp, 20h + jnz loc_468CBC + loc_468CE6: + pop ebp + jmp loc_4696B9 + loc_468CEC: + push ebp + mov ebp, 1Eh + mov eax, edi + sub eax, gpBufEnd + jb loc_468D34 + add eax, 3FFh + shr eax, 8 + cmp eax, 2Dh + jg loc_468D26 + mov ecx, WorldTbl3x16[eax*4] + mov eax, ecx + add esi, WorldTbl17_1[ecx] + shl eax, 6 + lea eax, [eax+eax*2] + shr ecx, 1 + sub edi, eax + sub ebp, ecx + jmp loc_468D34 + loc_468D26: + sub edi, 3000h + add esi, 120h + jmp loc_468D5B + loc_468D34: + mov ecx, 20h + sub ecx, ebp + loc_468D3B: + mov dl, [esi] + inc esi + mov dl, [ebx+edx] + mov [edi], dl + inc edi + dec ecx + jnz loc_468D3B + mov edx, esi + and edx, 2 + add esi, edx + sub edi, 320h + add edi, ebp + sub ebp, 2 + jge loc_468D34 + loc_468D5B: + mov ebp, 2 + mov eax, edi + sub eax, gpBufEnd + jb loc_468DA2 + add eax, 3FFh + shr eax, 8 + cmp eax, 2Ah + jg loc_468D94 + mov ecx, WorldTbl3x16[eax*4] + mov eax, ecx + add esi, WorldTbl17_2[ecx] + shl eax, 6 + lea eax, [eax+eax*2] + shr ecx, 1 + sub edi, eax + add ebp, ecx + jmp loc_468DA2 + loc_468D94: + sub edi, 2D00h + add esi, 100h + jmp loc_468DCC + loc_468DA2: + mov ecx, 20h + sub ecx, ebp + loc_468DA9: + mov dl, [esi] + inc esi + mov dl, [ebx+edx] + mov [edi], dl + inc edi + dec ecx + jnz loc_468DA9 + mov edx, esi + and edx, 2 + add esi, edx + sub edi, 320h + add edi, ebp + add ebp, 2 + cmp ebp, 20h + jnz loc_468DA2 + loc_468DCC: + pop ebp + jmp loc_4696B9 + loc_468DD2: + push ebp + mov ebp, 1Eh + mov eax, edi + sub eax, gpBufEnd + jb loc_468E1A + add eax, 3FFh + shr eax, 8 + cmp eax, 2Dh + jg loc_468E0C + mov ecx, WorldTbl3x16[eax*4] + mov eax, ecx + add esi, WorldTbl17_1[ecx] + shl eax, 6 + lea eax, [eax+eax*2] + shr ecx, 1 + sub edi, eax + sub ebp, ecx + jmp loc_468E1A + loc_468E0C: + sub edi, 3000h + add esi, 120h + jmp loc_468E87 + loc_468E1A: + add edi, ebp + mov ecx, 20h + sub ecx, ebp + mov edx, ecx + and edx, 2 + add esi, edx + cmp cl, 4 + jl loc_468E61 + loc_468E2F: + mov eax, [esi] + add esi, 4 + mov dl, al + mov ch, [ebx+edx] + mov dl, ah + ror eax, 10h + mov [edi], ch + mov ch, [ebx+edx] + mov dl, al + mov [edi+1], ch + mov ch, [ebx+edx] + mov dl, ah + mov [edi+2], ch + mov ch, [ebx+edx] + mov [edi+3], ch + add edi, 4 + sub cl, 4 + cmp cl, 4 + jge loc_468E2F + loc_468E61: + cmp cl, 2 + jl loc_468E7C + mov dl, [esi] + mov ch, [ebx+edx] + mov [edi], ch + mov dl, [esi+1] + mov ch, [ebx+edx] + mov [edi+1], ch + add esi, 2 + add edi, 2 + loc_468E7C: + sub edi, 320h + sub ebp, 2 + jge loc_468E1A + loc_468E87: + mov ebp, 10h + loc_468E8C: + cmp edi, gpBufEnd + jb loc_468E9C + add esi, 20h + add edi, 20h + jmp loc_468ED3 + loc_468E9C: + mov ecx, 20h + loc_468EA1: + mov eax, [esi] + add esi, 4 + mov dl, al + mov ch, [ebx+edx] + mov dl, ah + ror eax, 10h + mov [edi], ch + mov ch, [ebx+edx] + mov dl, al + mov [edi+1], ch + mov ch, [ebx+edx] + mov dl, ah + mov [edi+2], ch + mov ch, [ebx+edx] + mov [edi+3], ch + add edi, 4 + sub cl, 4 + cmp cl, 4 + jge loc_468EA1 + loc_468ED3: + sub edi, 320h + dec ebp + jnz loc_468E8C + pop ebp + jmp loc_4696B9 + loc_468EE2: + push ebp + mov ebp, 1Eh + mov eax, edi + sub eax, gpBufEnd + jb loc_468F2A + add eax, 3FFh + shr eax, 8 + cmp eax, 2Dh + jg loc_468F1C + mov ecx, WorldTbl3x16[eax*4] + mov eax, ecx + add esi, WorldTbl17_1[ecx] + shl eax, 6 + lea eax, [eax+eax*2] + shr ecx, 1 + sub edi, eax + sub ebp, ecx + jmp loc_468F2A + loc_468F1C: + sub edi, 3000h + add esi, 120h + jmp loc_468F97 + loc_468F2A: + mov ecx, 20h + sub ecx, ebp + cmp cl, 4 + jl loc_468F68 + loc_468F36: + mov eax, [esi] + add esi, 4 + mov dl, al + mov ch, [ebx+edx] + mov dl, ah + ror eax, 10h + mov [edi], ch + mov ch, [ebx+edx] + mov dl, al + mov [edi+1], ch + mov ch, [ebx+edx] + mov dl, ah + mov [edi+2], ch + mov ch, [ebx+edx] + mov [edi+3], ch + add edi, 4 + sub cl, 4 + cmp cl, 4 + jge loc_468F36 + loc_468F68: + cmp cl, 2 + jl loc_468F83 + mov dl, [esi] + mov ch, [ebx+edx] + mov [edi], ch + mov dl, [esi+1] + mov ch, [ebx+edx] + mov [edi+1], ch + add esi, 2 + add edi, 2 + loc_468F83: + mov edx, esi + and edx, 2 + add esi, edx + sub edi, 320h + add edi, ebp + sub ebp, 2 + jge loc_468F2A + loc_468F97: + mov ebp, 10h + loc_468F9C: + cmp edi, gpBufEnd + jb loc_468FAC + add esi, 20h + add edi, 20h + jmp loc_468FE3 + loc_468FAC: + mov ecx, 20h + loc_468FB1: + mov eax, [esi] + add esi, 4 + mov dl, al + mov ch, [ebx+edx] + mov dl, ah + ror eax, 10h + mov [edi], ch + mov ch, [ebx+edx] + mov dl, al + mov [edi+1], ch + mov ch, [ebx+edx] + mov dl, ah + mov [edi+2], ch + mov ch, [ebx+edx] + mov [edi+3], ch + add edi, 4 + sub cl, 4 + cmp cl, 4 + jge loc_468FB1 + loc_468FE3: + sub edi, 320h + dec ebp + jnz loc_468F9C + pop ebp + jmp loc_4696B9 + loc_468FF2: + mov edx, 20h + loc_468FF7: + cmp edi, gpBufEnd + jb loc_469007 + add esi, 20h + add edi, 20h + jmp loc_469019 + loc_469007: + mov ecx, 8 + loc_46900C: + mov eax, [esi] + add esi, 4 + mov [edi], eax + add edi, 4 + dec ecx + jnz loc_46900C + loc_469019: + sub edi, 320h + dec edx + jnz loc_468FF7 + jmp loc_4696B9 + loc_469027: + mov ecx, 20h + loc_46902C: + push ecx + mov edx, 20h + loc_469032: + xor eax, eax + mov al, [esi] + inc esi + test al, al + js loc_469082 + sub edx, eax + cmp edi, gpBufEnd + jb loc_46904B + add esi, eax + add edi, eax + jmp loc_46907C + loc_46904B: + mov ecx, eax + shr ecx, 1 + jnb loc_46905B + mov al, [esi] + inc esi + mov [edi], al + inc edi + test ecx, ecx + jz loc_46907C + loc_46905B: + shr ecx, 1 + jnb loc_46906F + mov ax, [esi] + add esi, 2 + mov [edi], ax + add edi, 2 + test ecx, ecx + jz loc_46907C + loc_46906F: + mov eax, [esi] + add esi, 4 + mov [edi], eax + add edi, 4 + dec ecx + jnz loc_46906F + loc_46907C: + test edx, edx + jz loc_46908A + jmp loc_469032 + loc_469082: + neg al + add edi, eax + sub edx, eax + jnz loc_469032 + loc_46908A: + pop ecx + sub edi, 320h + dec ecx + jnz loc_46902C + jmp loc_4696B9 + loc_469099: + mov edx, 1Eh + mov eax, edi + sub eax, gpBufEnd + jb loc_4690E0 + add eax, 3FFh + shr eax, 8 + cmp eax, 2Dh + jg loc_4690D2 + mov ecx, WorldTbl3x16[eax*4] + mov eax, ecx + add esi, WorldTbl17_1[ecx] + shl eax, 6 + lea eax, [eax+eax*2] + shr ecx, 1 + sub edi, eax + sub edx, ecx + jmp loc_4690E0 + loc_4690D2: + sub edi, 3000h + add esi, 120h + jmp loc_469117 + loc_4690E0: + add edi, edx + mov ecx, 20h + sub ecx, edx + shr ecx, 2 + jnb loc_4690FF + mov ax, [esi+2] + add esi, 4 + mov [edi], ax + add edi, 2 + test ecx, ecx + jz loc_46910C + loc_4690FF: + mov eax, [esi] + add esi, 4 + mov [edi], eax + add edi, 4 + dec ecx + jnz loc_4690FF + loc_46910C: + sub edi, 320h + sub edx, 2 + jge loc_4690E0 + loc_469117: + mov edx, 2 + mov eax, edi + sub eax, gpBufEnd + jb loc_46915E + add eax, 3FFh + shr eax, 8 + cmp eax, 2Ah + jg loc_469150 + mov ecx, WorldTbl3x16[eax*4] + mov eax, ecx + add esi, WorldTbl17_2[ecx] + shl eax, 6 + lea eax, [eax+eax*2] + shr ecx, 1 + sub edi, eax + add edx, ecx + jmp loc_46915E + loc_469150: + sub edi, 2D00h + add esi, 100h + jmp loc_469198 + loc_46915E: + mov ecx, 20h + add edi, edx + sub ecx, edx + shr ecx, 2 + jnb loc_46917D + mov ax, [esi+2] + add esi, 4 + mov [edi], ax + add edi, 2 + test ecx, ecx + jz loc_46918A + loc_46917D: + mov eax, [esi] + add esi, 4 + mov [edi], eax + add edi, 4 + dec ecx + jnz loc_46917D + loc_46918A: + add edx, 2 + sub edi, 320h + cmp edx, 20h + jl loc_46915E + loc_469198: + jmp loc_4696B9 + loc_46919D: + mov edx, 1Eh + mov eax, edi + sub eax, gpBufEnd + jb loc_4691E4 + add eax, 3FFh + shr eax, 8 + cmp eax, 2Dh + jg loc_4691D6 + mov ecx, WorldTbl3x16[eax*4] + mov eax, ecx + add esi, WorldTbl17_1[ecx] + shl eax, 6 + lea eax, [eax+eax*2] + shr ecx, 1 + sub edi, eax + sub edx, ecx + jmp loc_4691E4 + loc_4691D6: + sub edi, 3000h + add esi, 120h + jmp loc_46921D + loc_4691E4: + mov ecx, 20h + sub ecx, edx + mov ebx, ecx + shr ecx, 2 + jz loc_4691FF + loc_4691F2: + mov eax, [esi] + add esi, 4 + mov [edi], eax + add edi, 4 + dec ecx + jnz loc_4691F2 + loc_4691FF: + and ebx, 2 + jz loc_469210 + mov ax, [esi] + add esi, 4 + mov [edi], ax + add edi, 2 + loc_469210: + add edi, edx + sub edi, 320h + sub edx, 2 + jge loc_4691E4 + loc_46921D: + mov edx, 2 + mov eax, edi + sub eax, gpBufEnd + jb loc_469264 + add eax, 3FFh + shr eax, 8 + cmp eax, 2Ah + jg loc_469256 + mov ecx, WorldTbl3x16[eax*4] + mov eax, ecx + add esi, WorldTbl17_2[ecx] + shl eax, 6 + lea eax, [eax+eax*2] + shr ecx, 1 + sub edi, eax + add edx, ecx + jmp loc_469264 + loc_469256: + sub edi, 2D00h + add esi, 100h + jmp loc_4692A0 + loc_469264: + mov ecx, 20h + sub ecx, edx + mov ebx, ecx + shr ecx, 2 + jz loc_46927F + loc_469272: + mov eax, [esi] + add esi, 4 + mov [edi], eax + add edi, 4 + dec ecx + jnz loc_469272 + loc_46927F: + and ebx, 2 + jz loc_469290 + mov ax, [esi] + add esi, 4 + mov [edi], ax + add edi, 2 + loc_469290: + add edi, edx + add edx, 2 + sub edi, 320h + cmp edx, 20h + jl loc_469264 + loc_4692A0: + jmp loc_4696B9 + loc_4692A5: + mov edx, 1Eh + mov eax, edi + sub eax, gpBufEnd + jb loc_4692EC + add eax, 3FFh + shr eax, 8 + cmp eax, 2Dh + jg loc_4692DE + mov ecx, WorldTbl3x16[eax*4] + mov eax, ecx + add esi, WorldTbl17_1[ecx] + shl eax, 6 + lea eax, [eax+eax*2] + shr ecx, 1 + sub edi, eax + sub edx, ecx + jmp loc_4692EC + loc_4692DE: + sub edi, 3000h + add esi, 120h + jmp loc_469323 + loc_4692EC: + add edi, edx + mov ecx, 20h + sub ecx, edx + shr ecx, 2 + jnb loc_46930B + mov ax, [esi+2] + add esi, 4 + mov [edi], ax + add edi, 2 + test ecx, ecx + jz loc_469318 + loc_46930B: + mov eax, [esi] + add esi, 4 + mov [edi], eax + add edi, 4 + dec ecx + jnz loc_46930B + loc_469318: + sub edi, 320h + sub edx, 2 + jge loc_4692EC + loc_469323: + mov edx, 10h + loc_469328: + cmp edi, gpBufEnd + jb loc_469338 + add esi, 20h + add edi, 20h + jmp loc_46934A + loc_469338: + mov ecx, 8 + loc_46933D: + mov eax, [esi] + add esi, 4 + mov [edi], eax + add edi, 4 + dec ecx + jnz loc_46933D + loc_46934A: + sub edi, 320h + dec edx + jnz loc_469328 + jmp loc_4696B9 + loc_469358: + mov edx, 1Eh + mov eax, edi + sub eax, gpBufEnd + jb loc_46939F + add eax, 3FFh + shr eax, 8 + cmp eax, 2Dh + jg loc_469391 + mov ecx, WorldTbl3x16[eax*4] + mov eax, ecx + add esi, WorldTbl17_1[ecx] + shl eax, 6 + lea eax, [eax+eax*2] + shr ecx, 1 + sub edi, eax + sub edx, ecx + jmp loc_46939F + loc_469391: + sub edi, 3000h + add esi, 120h + jmp loc_4693D8 + loc_46939F: + mov ecx, 20h + sub ecx, edx + mov ebx, ecx + shr ecx, 2 + jz loc_4693BA + loc_4693AD: + mov eax, [esi] + add esi, 4 + mov [edi], eax + add edi, 4 + dec ecx + jnz loc_4693AD + loc_4693BA: + and ebx, 2 + jz loc_4693CB + mov ax, [esi] + add esi, 4 + mov [edi], ax + add edi, 2 + loc_4693CB: + sub edi, 320h + add edi, edx + sub edx, 2 + jge loc_46939F + loc_4693D8: + mov edx, 10h + loc_4693DD: + cmp edi, gpBufEnd + jb loc_4693ED + add esi, 20h + add edi, 20h + jmp loc_4693FF + loc_4693ED: + mov ecx, 8 + loc_4693F2: + mov eax, [esi] + add esi, 4 + mov [edi], eax + add edi, 4 + dec ecx + jnz loc_4693F2 + loc_4693FF: + sub edi, 320h + dec edx + jnz loc_4693DD + jmp loc_4696B9 + loc_46940D: + mov edx, 20h + xor eax, eax + loc_469414: + cmp edi, gpBufEnd + jb loc_469424 + add esi, 20h + add edi, 20h + jmp loc_469431 + loc_469424: + mov ecx, 8 + loc_469429: + mov [edi], eax + add edi, 4 + dec ecx + jnz loc_469429 + loc_469431: + sub edi, 320h + dec edx + jnz loc_469414 + jmp loc_4696B9 + loc_46943F: + mov ecx, 20h + loc_469444: + push ecx + mov edx, 20h + loc_46944A: + xor eax, eax + mov al, [esi] + inc esi + test al, al + js loc_469490 + sub edx, eax + cmp edi, gpBufEnd + jb loc_469463 + add esi, eax + add edi, eax + jmp loc_46948A + loc_469463: + mov ecx, eax + add esi, ecx + xor eax, eax + shr ecx, 1 + jnb loc_469474 + mov [edi], al + inc edi + test ecx, ecx + jz loc_46948A + loc_469474: + shr ecx, 1 + jnb loc_469482 + mov [edi], ax + add edi, 2 + test ecx, ecx + jz loc_46948A + loc_469482: + mov [edi], eax + add edi, 4 + dec ecx + jnz loc_469482 + loc_46948A: + test edx, edx + jz loc_469498 + jmp loc_46944A + loc_469490: + neg al + add edi, eax + sub edx, eax + jnz loc_46944A + loc_469498: + pop ecx + sub edi, 320h + dec ecx + jnz loc_469444 + jmp loc_4696B9 + loc_4694A7: + mov edx, 1Eh + xor eax, eax + loc_4694AE: + cmp edi, gpBufEnd + jb loc_4694C0 + add esi, 20h + sub esi, edx + add edi, 20h + jmp loc_4694E0 + loc_4694C0: + add edi, edx + mov ecx, 20h + sub ecx, edx + shr ecx, 2 + jnb loc_4694D8 + mov [edi], ax + add edi, 2 + test ecx, ecx + jz loc_4694E0 + loc_4694D8: + mov [edi], eax + add edi, 4 + dec ecx + jnz loc_4694D8 + loc_4694E0: + sub edi, 320h + test edx, edx + jz loc_4694EF + sub edx, 2 + jmp loc_4694AE + loc_4694EF: + mov edx, 2 + loc_4694F4: + cmp edi, gpBufEnd + jb loc_469506 + add esi, 20h + sub esi, edx + add edi, 20h + jmp loc_469526 + loc_469506: + add edi, edx + mov ecx, 20h + sub ecx, edx + shr ecx, 2 + jnb loc_46951E + mov [edi], ax + add edi, 2 + test ecx, ecx + jz loc_469526 + loc_46951E: + mov [edi], eax + add edi, 4 + dec ecx + jnz loc_46951E + loc_469526: + sub edi, 320h + add edx, 2 + cmp edx, 20h + jnz loc_4694F4 + jmp loc_4696B9 + loc_469539: + mov edx, 1Eh + xor eax, eax + loc_469540: + cmp edi, gpBufEnd + jb loc_469554 + add esi, 20h + sub esi, edx + add edi, 20h + sub edi, edx + jmp loc_469572 + loc_469554: + mov ecx, 20h + sub ecx, edx + shr ecx, 2 + jnb loc_46956A + mov [edi], ax + add edi, 2 + test ecx, ecx + jz loc_469572 + loc_46956A: + mov [edi], eax + add edi, 4 + dec ecx + jnz loc_46956A + loc_469572: + sub edi, 320h + test edx, edx + jz loc_469583 + add edi, edx + sub edx, 2 + jmp loc_469540 + loc_469583: + mov edx, 2 + loc_469588: + cmp edi, gpBufEnd + jb loc_46959C + add esi, 20h + sub esi, edx + add edi, 20h + sub edi, edx + jmp loc_4695BA + loc_46959C: + mov ecx, 20h + sub ecx, edx + shr ecx, 2 + jnb loc_4695B2 + mov [edi], ax + add edi, 2 + test ecx, ecx + jz loc_4695BA + loc_4695B2: + mov [edi], eax + add edi, 4 + dec ecx + jnz loc_4695B2 + loc_4695BA: + sub edi, 320h + add edi, edx + add edx, 2 + cmp edx, 20h + jnz loc_469588 + jmp loc_4696B9 + loc_4695CF: + mov edx, 1Eh + xor eax, eax + loc_4695D6: + cmp edi, gpBufEnd + jb loc_4695E8 + add esi, 20h + sub esi, edx + add edi, 20h + jmp loc_469608 + loc_4695E8: + add edi, edx + mov ecx, 20h + sub ecx, edx + shr ecx, 2 + jnb loc_469600 + mov [edi], ax + add edi, 2 + test ecx, ecx + jz loc_469608 + loc_469600: + mov [edi], eax + add edi, 4 + dec ecx + jnz loc_469600 + loc_469608: + sub edi, 320h + test edx, edx + jz loc_469617 + sub edx, 2 + jmp loc_4695D6 + loc_469617: + mov edx, 10h + loc_46961C: + cmp edi, gpBufEnd + jb loc_46962C + add esi, 20h + add edi, 20h + jmp loc_469639 + loc_46962C: + mov ecx, 8 + loc_469631: + mov [edi], eax + add edi, 4 + dec ecx + jnz loc_469631 + loc_469639: + sub edi, 320h + dec edx + jnz loc_46961C + jmp loc_4696B9 + loc_469644: + mov edx, 1Eh + xor eax, eax + loc_46964B: + cmp edi, gpBufEnd + jb loc_46965F + add esi, 20h + sub esi, edx + add edi, 20h + sub edi, edx + jmp loc_46967D + loc_46965F: + mov ecx, 20h + sub ecx, edx + shr ecx, 2 + jnb loc_469675 + mov [edi], ax + add edi, 2 + test ecx, ecx + jz loc_46967D + loc_469675: + mov [edi], eax + add edi, 4 + dec ecx + jnz loc_469675 + loc_46967D: + sub edi, 320h + test edx, edx + jz loc_46968E + add edi, edx + sub edx, 2 + jmp loc_46964B + loc_46968E: + mov edx, 10h + loc_469693: + cmp edi, gpBufEnd + jb loc_4696A3 + add esi, 20h + add edi, 20h + jmp loc_4696B0 + loc_4696A3: + mov ecx, 8 + loc_4696A8: + mov [edi], eax + add edi, 4 + dec ecx + jnz loc_4696A8 + loc_4696B0: + sub edi, 320h + dec edx + jnz loc_469693 + loc_4696B9: + pop esi + pop edi + pop edx + pop ebx + retn + } +} + +__declspec(naked) void world_draw_black_tile(BYTE *pBuff) +{ + __asm { + push ebx + push edx + push edi + push esi + mov edi, ecx + mov edx, 1Eh + mov ebx, 1 + xor eax, eax + loc_4696D0: + add edi, edx + mov ecx, ebx + loc_4696D4: + mov [edi], eax + add edi, 4 + dec ecx + jnz loc_4696D4 + add edi, edx + sub edi, 340h + test edx, edx + jz loc_4696EE + sub edx, 2 + inc ebx + jmp loc_4696D0 + loc_4696EE: + mov edx, 2 + mov ebx, 0Fh + loc_4696F8: + add edi, edx + mov ecx, ebx + loc_4696FC: + mov [edi], eax + add edi, 4 + dec ecx + jnz loc_4696FC + add edi, edx + sub edi, 340h + dec ebx + add edx, 2 + cmp edx, 20h + jnz loc_4696F8 + pop esi + pop edi + pop edx + pop ebx + retn + } +} diff --git a/2020_03_31/Source/appfat.cpp b/2020_03_31/Source/appfat.cpp new file mode 100644 index 00000000..36cfa77b --- /dev/null +++ b/2020_03_31/Source/appfat.cpp @@ -0,0 +1,663 @@ +#include "diablo.h" +#include "../3rdParty/Storm/Source/storm.h" + +char sz_error_buf[256]; +int terminating; // weak +int cleanup_thread_id; // weak + +void TriggerBreak() +{ +#ifdef _DEBUG + LPTOP_LEVEL_EXCEPTION_FILTER pFilter; + + pFilter = SetUnhandledExceptionFilter(BreakFilter); +#ifdef USE_ASM + __asm { + int 3 + } +#else + __debugbreak(); +#endif + SetUnhandledExceptionFilter(pFilter); +#endif +} + +#ifdef _DEBUG +LONG __stdcall BreakFilter(PEXCEPTION_POINTERS pExc) +{ + if(pExc->ExceptionRecord == NULL) { + return 0; + } + if(pExc->ExceptionRecord->ExceptionCode != EXCEPTION_BREAKPOINT) { + return 0; + } + + if(((BYTE *)pExc->ContextRecord->Eip)[0] == 0xCC) { // int 3 + pExc->ContextRecord->Eip++; + } + + return -1; +} +#endif + +char *GetErrorStr(int error_code) +{ + int v1; // edi + unsigned int v2; // eax + signed int v4; // eax + char *i; // ecx + + v1 = error_code; + v2 = ((unsigned int)error_code >> 16) & 0x1FFF; + if ( v2 == 0x0878 ) + { + TraceErrorDS(error_code, sz_error_buf, 256); + } + else if ( v2 == 0x0876 ) + { + TraceErrorDD(error_code, sz_error_buf, 256); + } + else + { + if ( !SErrGetErrorStr(error_code, sz_error_buf, 256) && !FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, v1, 0x400u, sz_error_buf, 0x100u, NULL) ) + wsprintf(sz_error_buf, "unknown error 0x%08x", v1); + } + v4 = strlen(sz_error_buf); + for ( i = &sz_error_buf[v4-1]; v4 > 0; *i = 0 ) + { + --v4; + --i; + if ( *i != '\r' && *i != '\n' ) + break; + } + return sz_error_buf; +} + +void TraceErrorDD(HRESULT hError, char *pszBuffer, DWORD dwMaxChars) +{ + const char *szError; + + switch(hError) { + case DDERR_CANTPAGEUNLOCK: + szError = "DDERR_CANTPAGEUNLOCK"; + break; + case DDERR_NOTPAGELOCKED: + szError = "DDERR_NOTPAGELOCKED"; + break; + case DD_OK: + szError = "DD_OK"; + break; + case DDERR_CANTPAGELOCK: + szError = "DDERR_CANTPAGELOCK"; + break; + case DDERR_BLTFASTCANTCLIP: + szError = "DDERR_BLTFASTCANTCLIP"; + break; + case DDERR_NOBLTHW: + szError = "DDERR_NOBLTHW"; + break; + case DDERR_NODDROPSHW: + szError = "DDERR_NODDROPSHW"; + break; + case DDERR_OVERLAYNOTVISIBLE: + szError = "DDERR_OVERLAYNOTVISIBLE"; + break; + case DDERR_NOOVERLAYDEST: + szError = "DDERR_NOOVERLAYDEST"; + break; + case DDERR_INVALIDPOSITION: + szError = "DDERR_INVALIDPOSITION"; + break; + case DDERR_NOTAOVERLAYSURFACE: + szError = "DDERR_NOTAOVERLAYSURFACE"; + break; + case DDERR_EXCLUSIVEMODEALREADYSET: + szError = "DDERR_EXCLUSIVEMODEALREADYSET"; + break; + case DDERR_NOTFLIPPABLE: + szError = "DDERR_NOTFLIPPABLE"; + break; + case DDERR_CANTDUPLICATE: + szError = "DDERR_CANTDUPLICATE"; + break; + case DDERR_NOTLOCKED: + szError = "DDERR_NOTLOCKED"; + break; + case DDERR_CANTCREATEDC: + szError = "DDERR_CANTCREATEDC"; + break; + case DDERR_NODC: + szError = "DDERR_NODC"; + break; + case DDERR_WRONGMODE: + szError = "DDERR_WRONGMODE"; + break; + case DDERR_IMPLICITLYCREATED: + szError = "DDERR_IMPLICITLYCREATED"; + break; + case DDERR_NOTPALETTIZED: + szError = "DDERR_NOTPALETTIZED"; + break; + case DDERR_NOMIPMAPHW: + szError = "DDERR_NOMIPMAPHW"; + break; + case DDERR_INVALIDSURFACETYPE: + szError = "DDERR_INVALIDSURFACETYPE"; + break; + case DDERR_DCALREADYCREATED: + szError = "DDERR_DCALREADYCREATED"; + break; + case DDERR_NOPALETTEHW: + szError = "DDERR_NOPALETTEHW"; + break; + case DDERR_DIRECTDRAWALREADYCREATED: + szError = "DDERR_DIRECTDRAWALREADYCREATED"; + break; + case DDERR_NODIRECTDRAWHW: + szError = "DDERR_NODIRECTDRAWHW"; + break; + case DDERR_PRIMARYSURFACEALREADYEXISTS: + szError = "DDERR_PRIMARYSURFACEALREADYEXISTS"; + break; + case DDERR_NOEMULATION: + szError = "DDERR_NOEMULATION"; + break; + case DDERR_REGIONTOOSMALL: + szError = "DDERR_REGIONTOOSMALL"; + break; + case DDERR_CLIPPERISUSINGHWND: + szError = "DDERR_CLIPPERISUSINGHWND"; + break; + case DDERR_NOCLIPPERATTACHED: + szError = "DDERR_NOCLIPPERATTACHED"; + break; + case DDERR_NOHWND: + szError = "DDERR_NOHWND"; + break; + case DDERR_HWNDSUBCLASSED: + szError = "DDERR_HWNDSUBCLASSED"; + break; + case DDERR_HWNDALREADYSET: + szError = "DDERR_HWNDALREADYSET"; + break; + case DDERR_NOPALETTEATTACHED: + szError = "DDERR_NOPALETTEATTACHED"; + break; + case DDERR_INVALIDDIRECTDRAWGUID: + szError = "DDERR_INVALIDDIRECTDRAWGUID"; + break; + case DDERR_UNSUPPORTEDFORMAT: + szError = "DDERR_UNSUPPORTEDFORMAT"; + break; + case DDERR_UNSUPPORTEDMASK: + szError = "DDERR_UNSUPPORTEDMASK"; + break; + case DDERR_VERTICALBLANKINPROGRESS: + szError = "DDERR_VERTICALBLANKINPROGRESS"; + break; + case DDERR_WASSTILLDRAWING: + szError = "DDERR_WASSTILLDRAWING"; + break; + case DDERR_XALIGN: + szError = "DDERR_XALIGN"; + break; + case DDERR_TOOBIGWIDTH: + szError = "DDERR_TOOBIGWIDTH"; + break; + case DDERR_CANTLOCKSURFACE: + szError = "DDERR_CANTLOCKSURFACE"; + break; + case DDERR_SURFACEISOBSCURED: + szError = "DDERR_SURFACEISOBSCURED"; + break; + case DDERR_SURFACELOST: + szError = "DDERR_SURFACELOST"; + break; + case DDERR_SURFACENOTATTACHED: + szError = "DDERR_SURFACENOTATTACHED"; + break; + case DDERR_TOOBIGHEIGHT: + szError = "DDERR_TOOBIGHEIGHT"; + break; + case DDERR_TOOBIGSIZE: + szError = "DDERR_TOOBIGSIZE"; + break; + case DDERR_SURFACEBUSY: + szError = "DDERR_SURFACEBUSY"; + break; + case DDERR_OVERLAYCOLORKEYONLYONEACTIVE: + szError = "DDERR_OVERLAYCOLORKEYONLYONEACTIVE"; + break; + case DDERR_PALETTEBUSY: + szError = "DDERR_PALETTEBUSY"; + break; + case DDERR_COLORKEYNOTSET: + szError = "DDERR_COLORKEYNOTSET"; + break; + case DDERR_SURFACEALREADYATTACHED: + szError = "DDERR_SURFACEALREADYATTACHED"; + break; + case DDERR_SURFACEALREADYDEPENDENT: + szError = "DDERR_SURFACEALREADYDEPENDENT"; + break; + case DDERR_OVERLAYCANTCLIP: + szError = "DDERR_OVERLAYCANTCLIP"; + break; + case DDERR_NOVSYNCHW: + szError = "DDERR_NOVSYNCHW"; + break; + case DDERR_NOZBUFFERHW: + szError = "DDERR_NOZBUFFERHW"; + break; + case DDERR_NOZOVERLAYHW: + szError = "DDERR_NOZOVERLAYHW"; + break; + case DDERR_OUTOFCAPS: + szError = "DDERR_OUTOFCAPS"; + break; + case DDERR_OUTOFVIDEOMEMORY: + szError = "DDERR_OUTOFVIDEOMEMORY"; + break; + case DDERR_NOTEXTUREHW: + szError = "DDERR_NOTEXTUREHW"; + break; + case DDERR_NOROTATIONHW: + szError = "DDERR_NOROTATIONHW"; + break; + case DDERR_NOSTRETCHHW: + szError = "DDERR_NOSTRETCHHW"; + break; + case DDERR_NOT4BITCOLOR: + szError = "DDERR_NOT4BITCOLOR"; + break; + case DDERR_NOT4BITCOLORINDEX: + szError = "DDERR_NOT4BITCOLORINDEX"; + break; + case DDERR_NOT8BITCOLOR: + szError = "DDERR_NOT8BITCOLOR"; + break; + case DDERR_NORASTEROPHW: + szError = "DDERR_NORASTEROPHW"; + break; + case DDERR_NOEXCLUSIVEMODE: + szError = "DDERR_NOEXCLUSIVEMODE"; + break; + case DDERR_NOFLIPHW: + szError = "DDERR_NOFLIPHW"; + break; + case DDERR_NOGDI: + szError = "DDERR_NOGDI"; + break; + case DDERR_NOMIRRORHW: + szError = "DDERR_NOMIRRORHW"; + break; + case DDERR_NOTFOUND: + szError = "DDERR_NOTFOUND"; + break; + case DDERR_NOOVERLAYHW: + szError = "DDERR_NOOVERLAYHW"; + break; + case DDERR_NOCOLORKEYHW: + szError = "DDERR_NOCOLORKEYHW"; + break; + case DDERR_NOALPHAHW: + szError = "DDERR_NOALPHAHW"; + break; + case DDERR_NOCLIPLIST: + szError = "DDERR_NOCLIPLIST"; + break; + case DDERR_NOCOLORCONVHW: + szError = "DDERR_NOCOLORCONVHW"; + break; + case DDERR_NOCOOPERATIVELEVELSET: + szError = "DDERR_NOCOOPERATIVELEVELSET"; + break; + case DDERR_NOCOLORKEY: + szError = "DDERR_NOCOLORKEY"; + break; + case DDERR_NO3D: + szError = "DDERR_NO3D"; + break; + case DDERR_INVALIDMODE: + szError = "DDERR_INVALIDMODE"; + break; + case DDERR_INVALIDOBJECT: + szError = "DDERR_INVALIDOBJECT"; + break; + case DDERR_INVALIDPIXELFORMAT: + szError = "DDERR_INVALIDPIXELFORMAT"; + break; + case DDERR_INVALIDRECT: + szError = "DDERR_INVALIDRECT"; + break; + case DDERR_LOCKEDSURFACES: + szError = "DDERR_LOCKEDSURFACES"; + break; + case DDERR_INVALIDCLIPLIST: + szError = "DDERR_INVALIDCLIPLIST"; + break; + case DDERR_CURRENTLYNOTAVAIL: + szError = "DDERR_CURRENTLYNOTAVAIL"; + break; + case DDERR_EXCEPTION: + szError = "DDERR_EXCEPTION"; + break; + case DDERR_HEIGHTALIGN: + szError = "DDERR_HEIGHTALIGN"; + break; + case DDERR_INCOMPATIBLEPRIMARY: + szError = "DDERR_INCOMPATIBLEPRIMARY"; + break; + case DDERR_INVALIDCAPS: + szError = "DDERR_INVALIDCAPS"; + break; + case DDERR_CANNOTDETACHSURFACE: + szError = "DDERR_CANNOTDETACHSURFACE"; + break; + case DDERR_UNSUPPORTED: + szError = "DDERR_UNSUPPORTED"; + break; + case DDERR_GENERIC: + szError = "DDERR_GENERIC"; + break; + case DDERR_OUTOFMEMORY: + szError = "DDERR_OUTOFMEMORY"; + break; + case DDERR_INVALIDPARAMS: + szError = "DDERR_INVALIDPARAMS"; + break; + case DDERR_ALREADYINITIALIZED: + szError = "DDERR_ALREADYINITIALIZED"; + break; + case DDERR_CANNOTATTACHSURFACE: + szError = "DDERR_CANNOTATTACHSURFACE"; + break; + default: + const char szUnknown[] = "DDERR unknown 0x%x"; + /// ASSERT: assert(dwMaxChars >= sizeof(szUnknown) + 10); + sprintf(pszBuffer, szUnknown, hError); + return; + } + + strncpy(pszBuffer, szError, dwMaxChars); +} + +void TraceErrorDS(HRESULT hError, char *pszBuffer, DWORD dwMaxChars) +{ + const char *szError; + + switch(hError) { + case DSERR_PRIOLEVELNEEDED: + szError = "DSERR_PRIOLEVELNEEDED"; + break; + case DSERR_BADFORMAT: + szError = "DSERR_BADFORMAT"; + break; + case DSERR_NODRIVER: + szError = "DSERR_NODRIVER"; + break; + case DSERR_ALREADYINITIALIZED: + szError = "DSERR_ALREADYINITIALIZED"; + break; + case DSERR_BUFFERLOST: + szError = "DSERR_BUFFERLOST"; + break; + case DS_OK: + szError = "DS_OK"; + break; + case DSERR_INVALIDCALL: + szError = "DSERR_INVALIDCALL"; + break; + case E_NOINTERFACE: + szError = "E_NOINTERFACE"; + break; + case DSERR_NOAGGREGATION: + szError = "DSERR_NOAGGREGATION"; + break; + case DSERR_OUTOFMEMORY: + szError = "DSERR_OUTOFMEMORY"; + break; + case DSERR_INVALIDPARAM: + szError = "DSERR_INVALIDPARAM"; + break; + case DSERR_ALLOCATED: + szError = "DSERR_ALLOCATED"; + break; + case DSERR_CONTROLUNAVAIL: + szError = "DSERR_CONTROLUNAVAIL"; + break; + default: + const char szUnknown[] = "DSERR unknown 0x%x"; + /// ASSERT: assert(dwMaxChars >= sizeof(szUnknown) + 10); + sprintf(pszBuffer, szUnknown, hError); + return; + } + + strncpy(pszBuffer, szError, dwMaxChars); +} + +char *TraceLastError() +{ + int v0; // eax + + v0 = GetLastError(); + return GetErrorStr(v0); +} + +void __cdecl app_fatal(const char *pszFmt, ...) +{ + va_list arglist; // [esp+8h] [ebp+8h] + + va_start(arglist, pszFmt); + FreeDlg(); +#ifdef _DEBUG + TriggerBreak(); +#endif + if ( pszFmt ) + MsgBox(pszFmt, arglist); + init_cleanup(0); + exit(1); +} + +void MsgBox(const char *pszFmt, va_list va) +{ + char Text[256]; // [esp+0h] [ebp-100h] + + wvsprintf(Text, pszFmt, va); + if ( ghMainWnd ) + SetWindowPos(ghMainWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOSIZE); + MessageBox(ghMainWnd, Text, "ERROR", MB_TASKMODAL|MB_ICONHAND); +} + +void FreeDlg() +{ + if ( terminating && cleanup_thread_id != GetCurrentThreadId() ) + Sleep(20000u); + terminating = 1; + cleanup_thread_id = GetCurrentThreadId(); + dx_cleanup(); + if ( (unsigned char)gbMaxPlayers > 1u ) + { + if ( SNetLeaveGame(3) ) + Sleep(2000u); + } + SNetDestroy(); + ShowCursor(1); +} + +void __cdecl DrawDlg(char *pszFmt, ...) +{ + char text[256]; // [esp+0h] [ebp-100h] + va_list arglist; // [esp+10Ch] [ebp+Ch] + + va_start(arglist, pszFmt); + wvsprintf(text, pszFmt, arglist); + SDrawMessageBox(text, "Diablo", MB_TASKMODAL|MB_ICONEXCLAMATION); +} + +#ifdef _DEBUG +void assert_fail(int nLineNo, const char *pszFile, const char *pszFail) +{ + app_fatal("assertion failed (%d:%s)\n%s", nLineNo, pszFile, pszFail); +} +#endif + +void DDErrMsg(HRESULT hError, int nLineNo, const char *pszFile) +{ + if(hError == DD_OK) { + return; + } + + app_fatal("Direct draw error (%s:%d)\n%s", pszFile, nLineNo, GetErrorStr(hError)); +} + +void DSErrMsg(HRESULT hError, int nLineNo, const char *pszFile) +{ + if(hError == DS_OK) { + return; + } + + app_fatal("Direct sound error (%s:%d)\n%s", pszFile, nLineNo, GetErrorStr(hError)); +} + +void center_window(HWND hWnd) +{ + int w, h, hr, vr; + RECT Rect; + HDC hdc; + + GetWindowRect(hWnd, &Rect); + w = Rect.right - Rect.left; + h = Rect.bottom - Rect.top; + + hdc = GetDC(hWnd); + hr = GetDeviceCaps(hdc, HORZRES); + vr = GetDeviceCaps(hdc, VERTRES); + ReleaseDC(hWnd, hdc); + + if(!SetWindowPos(hWnd, HWND_TOP, (hr - w) / 2, (vr - h) / 2, 0, 0, SWP_NOZORDER | SWP_NOSIZE)) { + app_fatal("center_window: %s", TraceLastError()); + } +} + +void ErrDlg(int nResource, DWORD dwError, const char *pszFile, int nLineNo) +{ + char *s; + char szBuffer[512]; + + FreeDlg(); + + s = strrchr(pszFile, '\\'); + if(s != NULL) { + pszFile = s + 1; + } + + wsprintf(szBuffer, "%s\nat: %s line %d", GetErrorStr(dwError), pszFile, nLineNo); + + if(DialogBoxParam(ghInst, MAKEINTRESOURCE(nResource), ghMainWnd, (DLGPROC)FuncDlg, (LPARAM)szBuffer) == -1) { + app_fatal("ErrDlg: %d", nResource); + } + + app_fatal(NULL); +} + +BOOL __stdcall FuncDlg(HWND hDlg, UINT uMsg, WPARAM wParam, char *text) +{ + if ( uMsg == WM_INITDIALOG ) + { + TextDlg(hDlg, text); + } + else + { + if ( uMsg != WM_COMMAND ) + return 0; + if ( (_WORD)wParam == 1 ) + { + EndDialog(hDlg, 1); + } + else if ( (_WORD)wParam == 2 ) + { + EndDialog(hDlg, 0); + } + } + return 1; +} + +void TextDlg(HWND hDlg, char *text) +{ + char *v2; // esi + HWND v3; // edi + + v2 = text; + v3 = hDlg; + center_window(hDlg); + if ( v2 ) + SetDlgItemText(v3, 1000, v2); +} + +void ErrOkDlg(int template_id, int error_code, char *log_file_path, int log_line_nr) +{ + char *v4; // esi + int v5; // edi + unsigned short v6; // bx + char *v7; // eax + char *v8; // eax + LPARAM dwInitParam[128]; // [esp+Ch] [ebp-200h] + + v4 = log_file_path; + v5 = error_code; + v6 = template_id; + v7 = strrchr(log_file_path, '\\'); + if ( v7 ) + v4 = v7 + 1; + v8 = GetErrorStr(v5); + wsprintf((LPSTR)dwInitParam, "%s\nat: %s line %d", v8, v4, log_line_nr); + DialogBoxParam(ghInst, MAKEINTRESOURCE(v6), ghMainWnd, (DLGPROC)FuncDlg, (LPARAM)dwInitParam); +} + +void FileErrDlg(char *error) +{ + char *v1; // esi + + v1 = error; + FreeDlg(); + if ( !v1 ) + v1 = ""; + if ( DialogBoxParam(ghInst, MAKEINTRESOURCE(IDD_DIALOG3), ghMainWnd, (DLGPROC)FuncDlg, (LPARAM)v1) == -1 ) + app_fatal("FileErrDlg"); + app_fatal(0); +} + +void DiskFreeDlg(char *error) +{ + char *v1; // esi + + v1 = error; + FreeDlg(); + if ( DialogBoxParam(ghInst, MAKEINTRESOURCE(IDD_DIALOG7), ghMainWnd, (DLGPROC)FuncDlg, (LPARAM)v1) == -1 ) + app_fatal("DiskFreeDlg"); + app_fatal(0); +} + +_bool InsertCDDlg() +{ + int v0; // edi + + ShowCursor(1); + v0 = DialogBoxParam(ghInst, MAKEINTRESOURCE(IDD_DIALOG9), ghMainWnd, (DLGPROC)FuncDlg, (LPARAM)""); + if ( v0 == -1 ) + app_fatal("InsertCDDlg"); + ShowCursor(0); + return v0 == 1; +} + +void DirErrorDlg(char *error) +{ + char *v1; // esi + + v1 = error; + FreeDlg(); + if ( DialogBoxParam(ghInst, MAKEINTRESOURCE(IDD_DIALOG11), ghMainWnd, (DLGPROC)FuncDlg, (LPARAM)v1) == -1 ) + app_fatal("DirErrorDlg"); + app_fatal(0); +} diff --git a/2020_03_31/Source/appfat.h b/2020_03_31/Source/appfat.h new file mode 100644 index 00000000..66bbe499 --- /dev/null +++ b/2020_03_31/Source/appfat.h @@ -0,0 +1,36 @@ +//HEADER_GOES_HERE +#ifndef __APPFAT_H__ +#define __APPFAT_H__ + +extern char sz_error_buf[256]; +extern int terminating; // weak +extern int cleanup_thread_id; // weak + +void TriggerBreak(); +#ifdef _DEBUG +LONG __stdcall BreakFilter(PEXCEPTION_POINTERS pExc); +#endif +char *GetErrorStr(int error_code); +void TraceErrorDD(HRESULT hError, char *pszBuffer, DWORD dwMaxChars); +void TraceErrorDS(HRESULT hError, char *pszBuffer, DWORD dwMaxChars); +char *TraceLastError(); +void __cdecl app_fatal(const char *pszFmt, ...); +void MsgBox(const char *pszFmt, va_list va); +void FreeDlg(); +void __cdecl DrawDlg(char *pszFmt, ...); +#ifdef _DEBUG +void assert_fail(int nLineNo, const char *pszFile, const char *pszFail); +#endif +void DDErrMsg(HRESULT hError, int nLineNo, const char *pszFile); +void DSErrMsg(HRESULT hError, int nLineNo, const char *pszFile); +void center_window(HWND hWnd); +void ErrDlg(int nResource, DWORD dwError, const char *pszFile, int nLineNo); +BOOL __stdcall FuncDlg(HWND hDlg, UINT uMsg, WPARAM wParam, char *text); +void TextDlg(HWND hDlg, char *text); +void ErrOkDlg(int template_id, int error_code, char *log_file_path, int log_line_nr); +void FileErrDlg(char *error); +void DiskFreeDlg(char *error); +_bool InsertCDDlg(); +void DirErrorDlg(char *error); + +#endif /* __APPFAT_H__ */ diff --git a/2020_03_31/Source/automap.cpp b/2020_03_31/Source/automap.cpp new file mode 100644 index 00000000..4072e284 --- /dev/null +++ b/2020_03_31/Source/automap.cpp @@ -0,0 +1,664 @@ +#include "diablo.h" + +WORD automaptype[512]; +int AutoMapX; // weak +int AutoMapY; // weak +BOOL automapflag; // idb +char AmShiftTab[31]; +BOOLEAN automapview[40][40]; +int AutoMapScale; // idb +int AutoMapXOfs; // weak +int AutoMapYOfs; // weak +int AmLine64; // weak +int AmLine32; // weak +int AmLine16; // weak +int AmLine8; // weak +int AmLine4; // weak + +void InitAutomapOnce() +{ + automapflag = 0; + AutoMapScale = 50; + AmLine64 = (AutoMapScale << 6) / 100; + AmLine32 = AmLine64 >> 1; + AmLine16 = AmLine32 >> 1; + AmLine8 = AmLine16 >> 1; + AmLine4 = AmLine8 >> 1; +} + +void InitAutomap() +{ + int i, j, l, s; + BYTE b1, b2; + DWORD dwTiles, d; + BYTE *pAFile, *pTmp; + + l = 50; + for(i = 0; i < 31; i++) { + s = (l << 6) / 100; + AmShiftTab[i] = 2 * (320 / s) + 1; + if(320 % s) { + AmShiftTab[i]++; + } + if(320 % s >= (l << 5) / 100) { + AmShiftTab[i]++; + } + l += 5; + } + + memset(automaptype, 0, sizeof(automaptype)); + + switch(leveltype) { + case DTYPE_CATHEDRAL: + pAFile = DiabLoad("Levels\\L1Data\\L1.AMP", &dwTiles, 'AMAP'); + dwTiles >>= 1; + break; + case DTYPE_CATACOMBS: + pAFile = DiabLoad("Levels\\L2Data\\L2.AMP", &dwTiles, 'AMAP'); + dwTiles >>= 1; + break; + case DTYPE_CAVES: + pAFile = DiabLoad("Levels\\L3Data\\L3.AMP", &dwTiles, 'AMAP'); + dwTiles >>= 1; + break; + case DTYPE_HELL: + pAFile = DiabLoad("Levels\\L4Data\\L4.AMP", &dwTiles, 'AMAP'); + dwTiles >>= 1; + break; + default: + return; + } + + pTmp = pAFile; + for(d = 1; d <= dwTiles; d++) { + b1 = *pTmp++; + b2 = *pTmp++; + automaptype[d] = b1 + (b2 << 8); + } + + MemFreeDbg(pAFile); + memset(automapview, 0, sizeof(automapview)); + + for(j = 0; j < MAXDUNY; j++) { + for(i = 0; i < MAXDUNX; i++) { + dFlags[i][j] &= ~0x80; + } + } +} + +void StartAutomap() +{ + AutoMapXOfs = 0; + AutoMapYOfs = 0; + automapflag = 1; +} + +void AutomapUp() +{ + AutoMapXOfs--; + AutoMapYOfs--; +} + +void AutomapDown() +{ + AutoMapXOfs++; + AutoMapYOfs++; +} + +void AutomapLeft() +{ + AutoMapXOfs--; + AutoMapYOfs++; +} + +void AutomapRight() +{ + AutoMapXOfs++; + AutoMapYOfs--; +} + +void AutomapZoomIn() +{ + if(AutoMapScale < 200) { + AutoMapScale += 5; + AmLine64 = (AutoMapScale << 6) / 100; + AmLine32 = AmLine64 >> 1; + AmLine16 = AmLine32 >> 1; + AmLine8 = AmLine16 >> 1; + AmLine4 = AmLine8 >> 1; + } +} + +void AutomapZoomOut() +{ + if(AutoMapScale > 50) { + AutoMapScale -= 5; + AmLine64 = (AutoMapScale << 6) / 100; + AmLine32 = AmLine64 >> 1; + AmLine16 = AmLine32 >> 1; + AmLine8 = AmLine16 >> 1; + AmLine4 = AmLine8 >> 1; + } +} + +void DrawAutomap() +{ + int MapX, MapY, Sx, Sy, Len, i, j, Px, Py; + WORD Tile; + + if(leveltype == DTYPE_TOWN) { + DrawAutomapText(); + return; + } + + /// ASSERT: assert(gpBuffer); + gpBufEnd = &gpBuffer[(352 + SCREEN_Y) * BUFFER_WIDTH]; + + AutoMapX = (ViewX - 16) >> 1; + while(AutoMapX + AutoMapXOfs < 0) { + AutoMapXOfs++; + } + while(AutoMapX + AutoMapXOfs >= DMAXX) { + AutoMapXOfs--; + } + AutoMapX += AutoMapXOfs; + + AutoMapY = (ViewY - 16) >> 1; + while(AutoMapY + AutoMapYOfs < 0) { + AutoMapYOfs++; + } + while(AutoMapY + AutoMapYOfs >= DMAXY) { + AutoMapYOfs--; + } + AutoMapY += AutoMapYOfs; + + Len = AmShiftTab[(AutoMapScale - 50) / 5]; + if(ScrollInfo._sxoff + ScrollInfo._syoff) { + Len++; + } + + MapX = AutoMapX - Len; + MapY = AutoMapY - 1; + + if(Len & 1) { + Sx = 640 / 2 + SCREEN_X - AmLine64 * ((Len - 1) >> 1); + Sy = 352 / 2 + SCREEN_Y - AmLine32 * ((Len + 1) >> 1); + } else { + Sx = 640 / 2 + SCREEN_X - AmLine64 * (Len >> 1) + AmLine32; + Sy = 352 / 2 + SCREEN_Y - AmLine32 * (Len >> 1) - AmLine16; + } + + if(ViewX & 1) { + Sx -= AmLine16; + Sy -= AmLine8; + } + if(ViewY & 1) { + Sx += AmLine16; + Sy -= AmLine8; + } + + Sx += ScrollInfo._sxoff * AutoMapScale / 100 >> 1; + Sy += ScrollInfo._syoff * AutoMapScale / 100 >> 1; + + if(invflag || sbookflag) { + Sx -= 160; + } + if(chrflag || questlog) { + Sx += 160; + } + + for(i = 0; i <= Len + 1; i++) { + Px = Sx; + Py = Sy; + for(j = 0; j < Len; j++) { + Tile = GetAutomapType(j + MapX, MapY - j, TRUE); + if(Tile != 0) { + DrawAutomapTile(Px, Py, Tile); + } + Px += AmLine64; + } + MapY++; + Px = Sx - AmLine32; + Py = Sy + AmLine16; + for(j = 0; j <= Len; j++) { + Tile = GetAutomapType(j + MapX, MapY - j, TRUE); + if(Tile != 0) { + DrawAutomapTile(Px, Py, Tile); + } + Px += AmLine64; + } + MapX++; + Sy += AmLine32; + } + + DrawAutomapPlr(); + DrawAutomapText(); +} + +void DrawAutomapTile(int sx, int sy, WORD tile) +{ + int x1, y1, x2, y2; + BYTE f; + BOOL AMLWallFlag, AMRWallFlag, AMLLWallFlag, AMLRWallFlag; + + f = tile >> 8; + + if(f & AFLAG_DIRT) { + ENG_set_pixel(sx, sy, 200); + ENG_set_pixel(sx - AmLine8, sy - AmLine4, 200); + ENG_set_pixel(sx - AmLine8, sy + AmLine4, 200); + ENG_set_pixel(sx + AmLine8, sy - AmLine4, 200); + ENG_set_pixel(sx + AmLine8, sy + AmLine4, 200); + ENG_set_pixel(sx - AmLine16, sy, 200); + ENG_set_pixel(sx + AmLine16, sy, 200); + ENG_set_pixel(sx, sy - AmLine8, 200); + ENG_set_pixel(sx, sy + AmLine8, 200); + ENG_set_pixel(sx + AmLine8 - AmLine32, sy + AmLine4, 200); + ENG_set_pixel(sx + AmLine32 - AmLine8, sy + AmLine4, 200); + ENG_set_pixel(sx - AmLine16, sy + AmLine8, 200); + ENG_set_pixel(sx + AmLine16, sy + AmLine8, 200); + ENG_set_pixel(sx - AmLine8, sy + AmLine16 - AmLine4, 200); + ENG_set_pixel(sx + AmLine8, sy + AmLine16 - AmLine4, 200); + ENG_set_pixel(sx, sy + AmLine16, 200); + } + if(f & AFLAG_STAIRS) { + DrawLine(sx - AmLine8, sy - AmLine8 - AmLine4, sx + AmLine8 + AmLine16, sy + AmLine4, 144); + DrawLine(sx - AmLine16, sy - AmLine8, sx + AmLine16, sy + AmLine8, 144); + DrawLine(sx - AmLine16 - AmLine8, sy - AmLine4, sx + AmLine8, sy + AmLine8 + AmLine4, 144); + DrawLine(sx - AmLine32, sy, sx, sy + AmLine16, 144); + } + + AMLWallFlag = FALSE; + AMRWallFlag = FALSE; + AMLLWallFlag = FALSE; + AMLRWallFlag = FALSE; + + switch(tile & 0xF) { + case 1: + x1 = sx - AmLine16; + y1 = sy - AmLine16; + x2 = x1 + AmLine32; + y2 = sy - AmLine8; + DrawLine(sx, y1, x1, y2, 200); + DrawLine(sx, y1, x2, y2, 200); + DrawLine(sx, sy, x1, y2, 200); + DrawLine(sx, sy, x2, y2, 200); + break; + case 2: + case 5: + AMLWallFlag = TRUE; + break; + case 3: + case 6: + AMRWallFlag = TRUE; + break; + case 4: + AMLWallFlag = TRUE; + AMRWallFlag = TRUE; + break; + case 8: + AMLWallFlag = TRUE; + AMLLWallFlag = TRUE; + break; + case 9: + AMRWallFlag = TRUE; + AMLRWallFlag = TRUE; + break; + case 0xA: + AMLLWallFlag = TRUE; + break; + case 0xB: + AMLRWallFlag = TRUE; + break; + case 0xC: + AMLLWallFlag = TRUE; + AMLRWallFlag = TRUE; + break; + } + + if(AMLWallFlag) { + if(f & AFLAG_VERTDOOR) { + x1 = sx - AmLine32; + x2 = sx - AmLine16; + y1 = sy - AmLine16; + y2 = sy - AmLine8; + DrawLine(sx, y1, sx - AmLine8, y1 + AmLine4, 200); + DrawLine(x1, sy, x1 + AmLine8, sy - AmLine4, 200); + DrawLine(x2, y1, x1, y2, 144); + DrawLine(x2, y1, sx, y2, 144); + DrawLine(x2, sy, x1, y2, 144); + DrawLine(x2, sy, sx, y2, 144); + } + if(f & AFLAG_VERTGRATE) { + DrawLine(sx - AmLine16, sy - AmLine8, sx - AmLine32, sy, 200); + f |= AFLAG_VERTARCH; + } + if(f & AFLAG_VERTARCH) { + x1 = sx - AmLine16; + y1 = sy - AmLine16; + x2 = x1 + AmLine32; + y2 = sy - AmLine8; + DrawLine(sx, y1, x1, y2, 200); + DrawLine(sx, y1, x2, y2, 200); + DrawLine(sx, sy, x1, y2, 200); + DrawLine(sx, sy, x2, y2, 200); + } + if(!(f & (AFLAG_VERTGRATE | AFLAG_VERTARCH | AFLAG_VERTDOOR))) { + DrawLine(sx, sy - AmLine16, sx - AmLine32, sy, 200); + } + } + if(AMRWallFlag) { + if(f & AFLAG_HORZDOOR) { + x1 = sx + AmLine16; + x2 = sx + AmLine32; + y1 = sy - AmLine16; + y2 = sy - AmLine8; + DrawLine(sx, y1, sx + AmLine8, y1 + AmLine4, 200); + DrawLine(x2, sy, x2 - AmLine8, sy - AmLine4, 200); + DrawLine(x1, y1, sx, y2, 144); + DrawLine(x1, y1, x2, y2, 144); + DrawLine(x1, sy, sx, y2, 144); + DrawLine(x1, sy, x2, y2, 144); + } + if(f & AFLAG_HORZGRATE) { + DrawLine(sx + AmLine16, sy - AmLine8, sx + AmLine32, sy, 200); + f |= AFLAG_HORZARCH; + } + if(f & AFLAG_HORZARCH) { + x1 = sx - AmLine16; + y1 = sy - AmLine16; + x2 = x1 + AmLine32; + y2 = sy - AmLine8; + DrawLine(sx, y1, x1, y2, 200); + DrawLine(sx, y1, x2, y2, 200); + DrawLine(sx, sy, x1, y2, 200); + DrawLine(sx, sy, x2, y2, 200); + } + if(!(f & (AFLAG_HORZGRATE | AFLAG_HORZARCH | AFLAG_HORZDOOR))) { + DrawLine(sx, sy - AmLine16, sx + AmLine32, sy, 200); + } + } + if(AMLLWallFlag) { + if(f & AFLAG_VERTDOOR) { + x1 = sx - AmLine32; + x2 = sx - AmLine16; + y1 = sy + AmLine16; + y2 = sy + AmLine8; + DrawLine(sx, y1, sx - AmLine8, y1 - AmLine4, 200); + DrawLine(x1, sy, x1 + AmLine8, sy + AmLine4, 200); + DrawLine(x2, y1, x1, y2, 144); + DrawLine(x2, y1, sx, y2, 144); + DrawLine(x2, sy, x1, y2, 144); + DrawLine(x2, sy, sx, y2, 144); + } else { + DrawLine(sx, sy + AmLine16, sx - AmLine32, sy, 200); + } + } + if(AMLRWallFlag) { + if(f & AFLAG_HORZDOOR) { + x1 = sx + AmLine16; + x2 = sx + AmLine32; + y1 = sy + AmLine16; + y2 = sy + AmLine8; + DrawLine(sx, y1, sx + AmLine8, y1 - AmLine4, 200); + DrawLine(x2, sy, x2 - AmLine8, sy + AmLine4, 200); + DrawLine(x1, y1, sx, y2, 144); + DrawLine(x1, y1, x2, y2, 144); + DrawLine(x1, sy, sx, y2, 144); + DrawLine(x1, sy, x2, y2, 144); + } else { + DrawLine(sx, sy + AmLine16, sx + AmLine32, sy, 200); + } + } +} + +void DrawAutomapPlr() +{ + int Px, Py, MapX, MapY, x, y; + + if(plr[myplr]._pmode == PM_WALK3) { + Px = plr[myplr]._px; + Py = plr[myplr]._py; + if(plr[myplr]._pdir == DIR_W) { + Px++; + } else { + Py++; + } + } else { + Px = plr[myplr].WorldX; + Py = plr[myplr].WorldY; + } + + MapX = Px - ViewX - 2 * AutoMapXOfs; + MapY = Py - ViewY - 2 * AutoMapYOfs; + x = 640 / 2 + SCREEN_X + MapX * AmLine16 - MapY * AmLine16; + y = 352 / 2 + SCREEN_Y + MapX * AmLine8 + MapY * AmLine8; + x += plr[myplr]._pxoff * AutoMapScale / 100 >> 1; + y += plr[myplr]._pyoff * AutoMapScale / 100 >> 1; + x += ScrollInfo._sxoff * AutoMapScale / 100 >> 1; + y += ScrollInfo._syoff * AutoMapScale / 100 >> 1; + + if(invflag || sbookflag) { + x -= 160; + } + if(chrflag || questlog) { + x += 160; + } + + y -= AmLine8; + + switch(plr[myplr]._pdir) { + case DIR_N: + DrawLine(x, y, x, y - AmLine16, 153); + DrawLine(x, y - AmLine16, x - AmLine4, y - AmLine8, 153); + DrawLine(x, y - AmLine16, x + AmLine4, y - AmLine8, 153); + break; + case DIR_NE: + DrawLine(x, y, x + AmLine16, y - AmLine8, 153); + DrawLine(x + AmLine16, y - AmLine8, x + AmLine8, y - AmLine8, 153); + DrawLine(x + AmLine16, y - AmLine8, x + AmLine8 + AmLine4, y, 153); + break; + case DIR_E: + DrawLine(x, y, x + AmLine16, y, 153); + DrawLine(x + AmLine16, y, x + AmLine8, y - AmLine4, 153); + DrawLine(x + AmLine16, y, x + AmLine8, y + AmLine4, 153); + break; + case DIR_SE: + DrawLine(x, y, x + AmLine16, y + AmLine8, 153); + DrawLine(x + AmLine16, y + AmLine8, x + AmLine8 + AmLine4, y, 153); + DrawLine(x + AmLine16, y + AmLine8, x + AmLine8, y + AmLine8, 153); + break; + case DIR_S: + DrawLine(x, y, x, y + AmLine16, 153); + DrawLine(x, y + AmLine16, x + AmLine4, y + AmLine8, 153); + DrawLine(x, y + AmLine16, x - AmLine4, y + AmLine8, 153); + break; + case DIR_SW: + DrawLine(x, y, x - AmLine16, y + AmLine8, 153); + DrawLine(x - AmLine16, y + AmLine8, x - AmLine4 - AmLine8, y, 153); + DrawLine(x - AmLine16, y + AmLine8, x - AmLine8, y + AmLine8, 153); + break; + case DIR_W: + DrawLine(x, y, x - AmLine16, y, 153); + DrawLine(x - AmLine16, y, x - AmLine8, y - AmLine4, 153); + DrawLine(x - AmLine16, y, x - AmLine8, y + AmLine4, 153); + break; + case DIR_NW: + DrawLine(x, y, x - AmLine16, y - AmLine8, 153); + DrawLine(x - AmLine16, y - AmLine8, x - AmLine8, y - AmLine8, 153); + DrawLine(x - AmLine16, y - AmLine8, x - AmLine4 - AmLine8, y, 153); + break; + } +} + +WORD GetAutomapType(int x, int y, BOOL view) +{ + WORD rv, f; + + if(view && x == -1 && y >= 0 && y < DMAXY && automapview[0][y]) { + if(GetAutomapType(0, y, FALSE) & 0x4000) { + return 0; + } else { + return 0x4000; + } + } + if(view && y == -1 && x >= 0 && x < DMAXX && automapview[x][0]) { + if(GetAutomapType(x, 0, FALSE) & 0x4000) { + return 0; + } else { + return 0x4000; + } + } + + if(x < 0 || x >= DMAXX) { + return 0; + } + if(y < 0 || y >= DMAXY) { + return 0; + } + if(!automapview[x][y] && view) { + return 0; + } + + rv = automaptype[dungeon[x][y]]; + if(rv == 7) { + f = GetAutomapType(x - 1, y, FALSE) >> 8; + if(f & AFLAG_HORZARCH) { + f = GetAutomapType(x, y - 1, FALSE) >> 8; + if(f & AFLAG_VERTARCH) { + rv = 1; + } + } + } + return rv; +} + +void DrawAutomapText() +{ + int y; + char gamestr[256]; + + y = 20; + if(gbMaxPlayers > 1) { + strcat(strcpy(gamestr, "game: "), szPlayerName); + PrintGameStr(8, y, gamestr, COL_GOLD); + y += 15; + if(szPlayerDescript[0] != '\0') { + strcat(strcpy(gamestr, "password: "), szPlayerDescript); + PrintGameStr(8, y, gamestr, COL_GOLD); + y += 15; + } + } + + if(setlevel) { + PrintGameStr(8, y, quest_level_names[setlvlnum], COL_GOLD); + } else if(currlevel != 0) { + sprintf(gamestr, "Level: %i", currlevel); + PrintGameStr(8, y, gamestr, COL_GOLD); + } +} + +void SetAutomapView(int x, int y) +{ + int xx, yy; + WORD s, d; + + xx = (x - 16) >> 1; + yy = (y - 16) >> 1; + + if(xx < 0 || xx >= DMAXX) { + return; + } + if(yy < 0 || yy >= DMAXY) { + return; + } + + automapview[xx][yy] = TRUE; + d = GetAutomapType(xx, yy, FALSE); + s = d & 0x4000; + d &= 0xF; + + switch(d) { + case 2: + if(s) { + if(GetAutomapType(xx, yy + 1, FALSE) == 0x4007) { + automapview[xx][yy + 1] = TRUE; + } + } else { + if(GetAutomapType(xx - 1, yy, FALSE) & 0x4000) { + automapview[xx - 1][yy] = TRUE; + } + } + break; + case 3: + if(s) { + if(GetAutomapType(xx + 1, yy, FALSE) == 0x4007) { + automapview[xx + 1][yy] = TRUE; + } + } else { + if(GetAutomapType(xx, yy - 1, FALSE) & 0x4000) { + automapview[xx][yy - 1] = TRUE; + } + } + break; + case 4: + if(s) { + if(GetAutomapType(xx, yy + 1, FALSE) == 0x4007) { + automapview[xx][yy + 1] = TRUE; + } + if(GetAutomapType(xx + 1, yy, FALSE) == 0x4007) { + automapview[xx + 1][yy] = TRUE; + } + } else { + if(GetAutomapType(xx - 1, yy, FALSE) & 0x4000) { + automapview[xx - 1][yy] = TRUE; + } + if(GetAutomapType(xx, yy - 1, FALSE) & 0x4000) { + automapview[xx][yy - 1] = TRUE; + } + if(GetAutomapType(xx - 1, yy - 1, FALSE) & 0x4000) { + automapview[xx - 1][yy - 1] = TRUE; + } + } + break; + case 5: + if(s) { + if(GetAutomapType(xx, yy - 1, FALSE) & 0x4000) { + automapview[xx][yy - 1] = TRUE; + } + if(GetAutomapType(xx, yy + 1, FALSE) == 0x4007) { + automapview[xx][yy + 1] = TRUE; + } + } else { + if(GetAutomapType(xx - 1, yy, FALSE) & 0x4000) { + automapview[xx - 1][yy] = TRUE; + } + } + break; + case 6: + if(s) { + if(GetAutomapType(xx - 1, yy, FALSE) & 0x4000) { + automapview[xx - 1][yy] = TRUE; + } + if(GetAutomapType(xx + 1, yy, FALSE) == 0x4007) { + automapview[xx + 1][yy] = TRUE; + } + } else { + if(GetAutomapType(xx, yy - 1, FALSE) & 0x4000) { + automapview[xx][yy - 1] = TRUE; + } + } + break; + } +} + +void AutomapZoomReset() +{ + AmLine64 = (AutoMapScale << 6) / 100; + AmLine32 = AmLine64 >> 1; + AmLine16 = AmLine32 >> 1; + AmLine8 = AmLine16 >> 1; + AmLine4 = AmLine8 >> 1; + AutoMapXOfs = 0; + AutoMapYOfs = 0; +} diff --git a/2020_03_31/Source/automap.h b/2020_03_31/Source/automap.h new file mode 100644 index 00000000..94bd66e3 --- /dev/null +++ b/2020_03_31/Source/automap.h @@ -0,0 +1,37 @@ +//HEADER_GOES_HERE +#ifndef __AUTOMAP_H__ +#define __AUTOMAP_H__ + +extern WORD automaptype[512]; +extern int AutoMapX; // weak +extern int AutoMapY; // weak +extern BOOL automapflag; // idb +extern char AmShiftTab[31]; +extern BOOLEAN automapview[40][40]; +extern int AutoMapScale; // idb +extern int AutoMapXOfs; // weak +extern int AutoMapYOfs; // weak +extern int AmLine64; // weak +extern int AmLine32; // weak +extern int AmLine16; // weak +extern int AmLine8; // weak +extern int AmLine4; // weak + +void InitAutomapOnce(); +void InitAutomap(); +void StartAutomap(); +void AutomapUp(); +void AutomapDown(); +void AutomapLeft(); +void AutomapRight(); +void AutomapZoomIn(); +void AutomapZoomOut(); +void DrawAutomap(); +void DrawAutomapTile(int sx, int sy, WORD tile); +void DrawAutomapPlr(); +WORD GetAutomapType(int x, int y, BOOL view); +void DrawAutomapText(); +void SetAutomapView(int x, int y); +void AutomapZoomReset(); + +#endif /* __AUTOMAP_H__ */ diff --git a/2020_03_31/Source/capture.cpp b/2020_03_31/Source/capture.cpp new file mode 100644 index 00000000..fb0d1a08 --- /dev/null +++ b/2020_03_31/Source/capture.cpp @@ -0,0 +1,171 @@ +#include "diablo.h" + +static _bool CaptureHdr(HANDLE hFile, short width, short height) +{ + PCXHEADER Buffer; + memset(&Buffer, 0, sizeof(Buffer)); + + Buffer.Manufacturer = 10; + Buffer.Version = 5; + Buffer.Encoding = 1; + Buffer.BitsPerPixel = 8; + Buffer.Xmax = width - 1; + Buffer.Ymax = height - 1; + Buffer.HDpi = width; + Buffer.VDpi = height; + Buffer.NPlanes = 1; + Buffer.BytesPerLine = width; + + DWORD lpNumBytes; + return WriteFile(hFile, &Buffer, sizeof(Buffer), &lpNumBytes, NULL) && lpNumBytes == sizeof(Buffer); +} + +static _bool CapturePal(HANDLE hFile, PALETTEENTRY *palette) +{ + char *v3; + char Buffer[769]; + + Buffer[0] = 12; + v3 = &Buffer[1]; + for (int i = 256; i != 0; --i) + { + v3[0] = palette->peRed; + v3[1] = palette->peGreen; + v3[2] = palette->peBlue; + + palette++; + v3 += 3; + } + + DWORD lpNumBytes; + return WriteFile(hFile, Buffer, sizeof(Buffer), &lpNumBytes, NULL) && lpNumBytes == sizeof(Buffer); +} + +static BYTE *CaptureEnc(BYTE *src, BYTE *dst, int width) +{ + do + { + BYTE rlePixel = *src++; + --width; + + int rleLength = 1; + while (rlePixel == *src) + { + if (rleLength >= 63) + break; + if (!width) + break; + ++rleLength; + + --width; + ++src; + } + + if (rlePixel > 0xBF || rleLength > 1) + { + *dst++ = rleLength | 0xC0; + } + *dst++ = rlePixel; + } while (width); + return dst; +} + +static _bool CapturePix(HANDLE hFile, WORD width, WORD height, WORD stride, BYTE *pixels) +{ + int writeSize; + DWORD lpNumBytes; + + BYTE *pBuffer = (BYTE *)DiabloAllocPtr(2 * width); + do + { + if ( !height ) + { + mem_free_dbg(pBuffer); + return 1; + } + height--; + BYTE *pBufferEnd = CaptureEnc(pixels, pBuffer, width); + pixels += stride; + writeSize = pBufferEnd - pBuffer; + } + while (WriteFile(hFile, pBuffer, writeSize, &lpNumBytes, 0) && lpNumBytes == writeSize); + return 0; +} + +static HANDLE CaptureFile(char *dst_path) +{ + _bool num_used[100] = { false }; + + _finddata_t finder; + int hFind = _findfirst("screen??.PCX", &finder); + if (hFind != -1) + { + do + { + if (isdigit(finder.name[6]) && isdigit(finder.name[7])) + { + num_used[10 * (finder.name[6] - '0') + (finder.name[7] - '0')] = true; + } + } + while (_findnext(hFind, &finder) == 0); + } + + int free_num = 0; + while (num_used[free_num]) + { + ++free_num; + if (free_num >= 100) + return INVALID_HANDLE_VALUE; + } + + sprintf(dst_path, "screen%02d.PCX", free_num); + return CreateFile(dst_path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); +} + +static void RedPalette(PALETTEENTRY *pal) +{ + PALETTEENTRY red[256]; + + for(int i = 0; i < 256; i++) + { + red[i].peRed = pal[i].peRed; + red[i].peGreen = 0; + red[i].peBlue = 0; + red[i].peFlags = 0; + } + + lpDDPalette->SetEntries(0, 0, 256, red); +} + +void CaptureScreen() +{ + PALETTEENTRY palette[256]; + char FileName[MAX_PATH]; + + HANDLE hObject = CaptureFile(FileName); + if ( hObject != INVALID_HANDLE_VALUE) + { + DrawAndBlit(); + lpDDPalette->GetEntries(0, 0, 256, palette); + RedPalette(palette); + + lock_buf(2); + _bool success = CaptureHdr(hObject, 640, 480); + if (success) + { + success = CapturePix(hObject, 640, 480, 768, &gpBuffer[SCREENXY(0, 0)]); + if (success) + { + success = CapturePal(hObject, palette); + } + } + unlock_buf(2); + CloseHandle(hObject); + + if (!success) + DeleteFile(FileName); + + Sleep(300); + lpDDPalette->SetEntries(0, 0, 256, palette); + } +} diff --git a/2020_03_31/Source/capture.h b/2020_03_31/Source/capture.h new file mode 100644 index 00000000..1c2967e7 --- /dev/null +++ b/2020_03_31/Source/capture.h @@ -0,0 +1,7 @@ +//HEADER_GOES_HERE +#ifndef __CAPTURE_H__ +#define __CAPTURE_H__ + +void CaptureScreen(); + +#endif /* __CAPTURE_H__ */ diff --git a/2020_03_31/Source/codec.cpp b/2020_03_31/Source/codec.cpp new file mode 100644 index 00000000..2c66dd6a --- /dev/null +++ b/2020_03_31/Source/codec.cpp @@ -0,0 +1,160 @@ +#include "diablo.h" + +DWORD codec_decode(BYTE *pbSrcDst, DWORD dwSrcBytes, char *pszPassword) +{ + int i, j; + CODECCHUNK *pChunk; + char buff[128]; + char dst[20]; + + /// ASSERT: assert(pbSrcDst); + /// ASSERT: assert(pszPassword); + codec_init_key(FALSE, pszPassword); + + if(dwSrcBytes <= 8) { + return 0; + } + + dwSrcBytes -= 8; + + if(dwSrcBytes & 0x3F) { + return 0; + } + + for(i = dwSrcBytes; i != 0; i -= 64) { + memcpy(buff, pbSrcDst, 64); + SHA1Result(0, dst); + for(j = 0; j < 64; j++) { + buff[j] ^= dst[j % 20]; + } + SHA1Calculate(0, buff, 0); + memset(dst, 0, sizeof(dst)); + memcpy(pbSrcDst, buff, 64); + pbSrcDst += 64; + } + + memset(buff, 0, sizeof(buff)); + pChunk = (CODECCHUNK *)pbSrcDst; + + if(pChunk->failed > 0) { + goto error; + } + + SHA1Result(0, dst); + + if(pChunk->checksum != ((DWORD *)dst)[0]) { + memset(dst, 0, sizeof(dst)); + goto error; + } + + dwSrcBytes -= 64 - pChunk->last_chunk_size; + SHA1Clear(); + return dwSrcBytes; +error: + SHA1Clear(); + return 0; +} + +void codec_init_key(BOOL unused, char *pszPassword) +{ + int i, j, k, l, cnt; + char *p, *p2; + char buff[136]; + char key[64]; + char dst[20]; + + srand(0x7058); + + p = buff; + cnt = sizeof(buff); + while(cnt--) { + *p = rand(); + p++; + } + + j = 0; + for(i = 0; i < 64; i++) { + if(pszPassword[j] == '\0') { + j = 0; + } + key[i] = pszPassword[j]; + j++; + } + + SHA1Reset(0); + SHA1Calculate(0, key, dst); + SHA1Clear(); + + p2 = buff; + for(k = 0; k < sizeof(buff); k++) { + p2[k] ^= dst[k % 20]; + } + + memset(key, 0, sizeof(key)); + memset(dst, 0, sizeof(dst)); + + for(l = 0; l < 3; l++) { + SHA1Reset(l); + SHA1Calculate(l, &buff[72], 0); + } + + memset(buff, 0, sizeof(buff)); +} + +DWORD codec_get_encoded_len(DWORD dwSrcBytes) +{ + /// ASSERT: assert(dwSrcBytes); + if(dwSrcBytes & 0x3F) { + dwSrcBytes += 64 - (dwSrcBytes & 0x3F); + } + + dwSrcBytes += 8; + return dwSrcBytes; +} + +void codec_encode(BYTE *pbSrcDst, DWORD dwSrcBytes, DWORD dwSize64, char *pszPassword) +{ + int i, last; + DWORD size; + CODECCHUNK *pChunk; + char buff[128]; + char dst[20]; + char dst2[20]; + + /// ASSERT: assert(pbSrcDst); + /// ASSERT: assert(pszPassword); + + if(dwSize64 != codec_get_encoded_len(dwSrcBytes)) { + app_fatal("Invalid encode parameters"); + } + + codec_init_key(TRUE, pszPassword); + + last = 0; + while(dwSrcBytes != 0) { + size = dwSrcBytes < 64 ? dwSrcBytes : 64; + memcpy(buff, pbSrcDst, size); + if(size < 64) { + memset(&buff[size], 0, 64 - size); + } + SHA1Result(0, dst); + SHA1Calculate(0, buff, 0); + for(i = 0; i < 64; i++) { + buff[i] ^= dst[i % 20]; + } + memset(dst, 0, sizeof(dst)); + memcpy(pbSrcDst, buff, 64); + pbSrcDst += 64; + dwSrcBytes -= size; + last = size; + } + + memset(buff, 0, sizeof(buff)); + pChunk = (CODECCHUNK *)pbSrcDst; + SHA1Result(0, dst2); + pChunk->checksum = ((DWORD *)dst2)[0]; + pChunk->failed = 0; + pChunk->last_chunk_size = last; + pChunk->unused = 0; + SHA1Clear(); +} diff --git a/2020_03_31/Source/codec.h b/2020_03_31/Source/codec.h new file mode 100644 index 00000000..f5605c1e --- /dev/null +++ b/2020_03_31/Source/codec.h @@ -0,0 +1,10 @@ +//HEADER_GOES_HERE +#ifndef __CODEC_H__ +#define __CODEC_H__ + +DWORD codec_decode(BYTE *pbSrcDst, DWORD dwSrcBytes, char *pszPassword); +void codec_init_key(BOOL unused, char *pszPassword); +DWORD codec_get_encoded_len(DWORD dwSrcBytes); +void codec_encode(BYTE *pbSrcDst, DWORD dwSrcBytes, DWORD dwSize64, char *pszPassword); + +#endif /* __CODEC_H__ */ diff --git a/2020_03_31/Source/control.cpp b/2020_03_31/Source/control.cpp new file mode 100644 index 00000000..e33a5cc6 --- /dev/null +++ b/2020_03_31/Source/control.cpp @@ -0,0 +1,2927 @@ +#include "diablo.h" + +BYTE sgbNextTalkSave; // weak +BYTE sgbTalkSavePos; // weak +void *pDurIcons; +void *pChrButtons; +int drawhpflag; // idb +int dropGoldFlag; // weak +int panbtn[8]; +int chrbtn[4]; +void *pMultiBtns; +void *pPanelButtons; +void *pChrPanel; +int lvlbtndown; // weak +char sgszTalkSave[8][80]; +int dropGoldValue; // idb +int drawmanaflag; // idb +int chrbtnactive; // weak +char sgszTalkMsg[80]; +BYTE *pPanelText; +int frame_4B8800; // idb +BYTE *pLifeBuff; +BYTE *pBtmBuff; +void *pTalkBtns; +int pstrjust[4]; +int pnumlines; // idb +int pinfoflag; // weak +int talkbtndown[3]; +int pSpell; // weak +BYTE *pManaBuff; +char infoclr; // weak +int sgbPlrTalkTbl; // weak // should be char [4] +void *pGBoxBuff; +void *pSBkBtnCel; +char tempstr[256]; +char byte_4B894C[4]; +int sbooktab; // weak +int pSplType; // weak +int frame; // idb +int initialDropGoldIndex; // idb +int talkflag; // weak +void *pSBkIconCels; +int sbookflag; // weak +int chrflag; +int drawbtnflag; // idb +void *pSpellBkCel; +char infostr[256]; +int numpanbtns; // weak +void *pStatusPanel; +char panelstr[4][64]; +int panelflag; // weak +BYTE SplTransTbl[256]; +int initialDropGoldValue; // idb +void *pSpellCels; +int panbtndown; // weak +void *pTalkPanel; // idb +int spselflag; // weak + +const unsigned char fontframe[128] = +{ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 54, 44, 57, 58, 56, 55, 47, 40, 41, 59, 39, 50, 37, 51, 52, + 36, 27, 28, 29, 30, 31, 32, 33, 34, 35, 48, 49, 60, 38, 61, 53, + 62, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 42, 63, 43, 64, 65, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 40, 66, 41, 67, 0 +}; +const unsigned char fontkern[68] = +{ + 8, 10, 7, 9, 8, 7, 6, 8, 8, 3, + 3, 8, 6, 11, 9, 10, 6, 9, 9, 6, + 9, 11, 10, 13, 10, 11, 7, 5, 7, 7, + 8, 7, 7, 7, 7, 7, 10, 4, 5, 6, + 3, 3, 4, 3, 6, 6, 3, 3, 3, 3, + 3, 2, 7, 6, 3, 10, 10, 6, 6, 7, + 4, 4, 9, 6, 6, 12, 3, 7 +}; +const int lineoffset[5][5] = +{ + { SCREENXY(177, 434), BUFFER_WIDTH * 32, BUFFER_WIDTH * 32, BUFFER_WIDTH * 32, 180 + BUFFER_WIDTH * 32 }, + { SCREENXY(177, 422), SCREENXY(177, 446), BUFFER_WIDTH * 32, BUFFER_WIDTH * 32, BUFFER_WIDTH * 32 }, + { SCREENXY(177, 416), SCREENXY(177, 434), SCREENXY(177, 452), BUFFER_WIDTH * 32, BUFFER_WIDTH * 32 }, + { SCREENXY(177, 412), SCREENXY(177, 427), SCREENXY(177, 441), SCREENXY(177, 456), BUFFER_WIDTH * 32 }, + { SCREENXY(177, 410), SCREENXY(177, 422), SCREENXY(177, 434), SCREENXY(177, 446), SCREENXY(177, 457) } +}; +const unsigned char gbFontTransTbl[256] = +{ + '\0', 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + ' ', '!', '\"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?', + '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', + 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^', '_', + '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', + 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~', 0x01, + 'C', 'u', 'e', 'a', 'a', 'a', 'a', 'c', 'e', 'e', 'e', 'i', 'i', 'i', 'A', 'A', + 'E', 'a', 'A', 'o', 'o', 'o', 'u', 'u', 'y', 'O', 'U', 'c', 'L', 'Y', 'P', 'f', + 'a', 'i', 'o', 'u', 'n', 'N', 'a', 'o', '?', 0x01, 0x01, 0x01, 0x01, '!', '<', '>', + 'o', '+', '2', '3', '\'', 'u', 'P', '.', ',', '1', '0', '>', 0x01, 0x01, 0x01, '?', + 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'C', 'E', 'E', 'E', 'E', 'I', 'I', 'I', 'I', + 'D', 'N', 'O', 'O', 'O', 'O', 'O', 'X', '0', 'U', 'U', 'U', 'U', 'Y', 'b', 'B', + 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'c', 'e', 'e', 'e', 'e', 'i', 'i', 'i', 'i', + 'o', 'n', 'o', 'o', 'o', 'o', 'o', '/', '0', 'u', 'u', 'u', 'u', 'y', 'b', 'y' +}; + +/* data */ + +char SpellITbl[37] = +{ + 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 28, 13, 12, 18, 16, 14, 18, 19, 11, 20, + 15, 21, 23, 24, 25, 22, 26, 29, 37, 38, + 39, 42, 41, 40, 10, 36, 30 +}; +int PanBtnPos[8][5] = +{ + { 9, 361, 71, 19, 1 }, + { 9, 387, 71, 19, 0 }, + { 9, 427, 71, 19, 1 }, + { 9, 453, 71, 19, 0 }, + { 560, 361, 71, 19, 1 }, + { 560, 387, 71, 19, 0 }, + { 87, 443, 33, 32, 1 }, + { 527, 443, 33, 32, 1 } +}; +char *PanBtnHotKey[8] = { "'c'", "'q'", "Tab", "Esc", "'i'", "'b'", "Enter", NULL }; +char *PanBtnStr[8] = +{ + "Character Information", + "Quests log", + "Automap", + "Main Menu", + "Inventory", + "Spell book", + "Send Message", + "Player Attack" +}; +int attribute_inc_rects[4][4] = +{ + { 137, 138, 41, 22 }, + { 137, 166, 41, 22 }, + { 137, 195, 41, 22 }, + { 137, 223, 41, 22 } +}; + +int SpellPages[6][7] = +{ + { SPL_NULL, SPL_FIREBOLT, SPL_CBOLT, SPL_HBOLT, SPL_HEAL, SPL_HEALOTHER, SPL_FLAME }, + { SPL_RESURRECT, SPL_FIREWALL, SPL_TELEKINESIS, SPL_LIGHTNING, SPL_TOWN, SPL_FLASH, SPL_STONE }, + { SPL_RNDTELEPORT, SPL_MANASHIELD, SPL_ELEMENT, SPL_FIREBALL, SPL_WAVE, SPL_CHAIN, SPL_GUARDIAN }, + { SPL_NOVA, SPL_GOLEM, SPL_TELEPORT, SPL_APOCA, SPL_BONESPIRIT, SPL_FLARE, SPL_ETHEREALIZE }, + { -1, -1, -1, -1, -1, -1, -1 }, + { -1, -1, -1, -1, -1, -1, -1 } +}; + +void DrawSpellCel(int xp, int yp, BYTE *pCelBuff, int nCel, int w) +{ + BYTE *dst, *tbl, *end; + + tbl = SplTransTbl; + /// ASSERT: assert(gpBuffer); + dst = &gpBuffer[xp + PitchTbl[yp]]; + +#ifdef USE_ASM + __asm { + mov ebx, pCelBuff + mov eax, nCel + shl eax, 2 + add ebx, eax + mov eax, [ebx+4] + sub eax, [ebx] + mov end, eax + mov esi, pCelBuff + add esi, [ebx] + mov edi, dst + mov eax, end + add eax, esi + mov end, eax + mov ebx, tbl + label1: + mov edx, w + label2: + xor eax, eax + lodsb + or al, al + js label6 + sub edx, eax + mov ecx, eax + shr ecx, 1 + jnb label3 + lodsb + xlat + stosb + jecxz label5 + label3: + shr ecx, 1 + jnb label4 + lodsw + xlat + ror ax, 8 + xlat + ror ax, 8 + stosw + jecxz label5 + label4: + lodsd + xlat + ror eax, 8 + xlat + ror eax, 8 + xlat + ror eax, 8 + xlat + ror eax, 8 + stosd + loop label4 + label5: + or edx, edx + jz label7 + jmp label2 + label6: + neg al + add edi, eax + sub edx, eax + jnz label2 + label7: + sub edi, 768 + sub edi, w + cmp esi, end + jnz label1 + } +#else + int i; + BYTE width; + BYTE *src; + DWORD *pFrameTable; + + pFrameTable = (DWORD *)pCelBuff; + src = &pCelBuff[pFrameTable[nCel]]; + end = &src[pFrameTable[nCel + 1] - pFrameTable[nCel]]; + + for(; src != end; dst -= 768 + w) { + for(i = w; i;) { + width = *src++; + if(!(width & 0x80)) { + i -= width; + if(width & 1) { + dst[0] = tbl[src[0]]; + src++; + dst++; + } + width >>= 1; + if(width & 1) { + dst[0] = tbl[src[0]]; + dst[1] = tbl[src[1]]; + src += 2; + dst += 2; + } + width >>= 1; + for(; width; width--) { + dst[0] = tbl[src[0]]; + dst[1] = tbl[src[1]]; + dst[2] = tbl[src[2]]; + dst[3] = tbl[src[3]]; + src += 4; + dst += 4; + } + } else { + width = -(char)width; + dst += width; + i -= width; + } + } + } +#endif +} + +void SetSpellTrans(char t) +{ + int i; + + if(t == RSPLTYPE_SKILL) { + for(i = 0; i < 128; i++) { + SplTransTbl[i] = i; + } + } + + for(i = 128; i < 256; i++) { + SplTransTbl[i] = i; + } + + SplTransTbl[255] = 0; + + switch(t) { + case RSPLTYPE_SPELL: + SplTransTbl[PAL8_YELLOW] = PAL16_BLUE + 1; + SplTransTbl[PAL8_YELLOW + 1] = PAL16_BLUE + 3; + SplTransTbl[PAL8_YELLOW + 2] = PAL16_BLUE + 5; + for(i = PAL16_BLUE; i < PAL16_BLUE + 16; i++) { + SplTransTbl[PAL16_BEIGE - PAL16_BLUE + i] = i; + SplTransTbl[PAL16_YELLOW - PAL16_BLUE + i] = i; + SplTransTbl[PAL16_ORANGE - PAL16_BLUE + i] = i; + } + break; + case RSPLTYPE_SCROLL: + SplTransTbl[PAL8_YELLOW] = PAL16_BEIGE + 1; + SplTransTbl[PAL8_YELLOW + 1] = PAL16_BEIGE + 3; + SplTransTbl[PAL8_YELLOW + 2] = PAL16_BEIGE + 5; + for(i = PAL16_BEIGE; i < PAL16_BEIGE + 16; i++) { + SplTransTbl[PAL16_YELLOW - PAL16_BEIGE + i] = i; + SplTransTbl[PAL16_ORANGE - PAL16_BEIGE + i] = i; + } + break; + case RSPLTYPE_CHARGES: + SplTransTbl[PAL8_YELLOW] = PAL16_ORANGE + 1; + SplTransTbl[PAL8_YELLOW + 1] = PAL16_ORANGE + 3; + SplTransTbl[PAL8_YELLOW + 2] = PAL16_ORANGE + 5; + for(i = PAL16_ORANGE; i < PAL16_ORANGE + 16; i++) { + SplTransTbl[PAL16_BEIGE - PAL16_ORANGE + i] = i; + SplTransTbl[PAL16_YELLOW - PAL16_ORANGE + i] = i; + } + break; + case RSPLTYPE_INVALID: + SplTransTbl[PAL8_YELLOW] = PAL16_GRAY + 1; + SplTransTbl[PAL8_YELLOW + 1] = PAL16_GRAY + 3; + SplTransTbl[PAL8_YELLOW + 2] = PAL16_GRAY + 5; + for(i = PAL16_GRAY; i < PAL16_GRAY + 15; i++) { + SplTransTbl[PAL16_BEIGE - PAL16_GRAY + i] = i; + SplTransTbl[PAL16_YELLOW - PAL16_GRAY + i] = i; + SplTransTbl[PAL16_ORANGE - PAL16_GRAY + i] = i; + } + SplTransTbl[PAL16_BEIGE + 15] = 0; + SplTransTbl[PAL16_YELLOW + 15] = 0; + SplTransTbl[PAL16_ORANGE + 15] = 0; + break; + } +} + +void DrawSpell() +{ + char st, sn; + int sl; + + st = plr[myplr]._pRSplType; + sn = plr[myplr]._pRSpell; + sl = plr[myplr]._pSplLvl[sn] + plr[myplr]._pISplLvlAdd; + + if(st == RSPLTYPE_SPELL && sn != -1) { + if(!CheckSpell(myplr, sn, st, TRUE)) { + st = RSPLTYPE_INVALID; + } + if(sl <= 0) { + st = RSPLTYPE_INVALID; + } + } + if(currlevel == 0 && st != RSPLTYPE_INVALID && !spelldata[sn].sTownSpell) { + st = RSPLTYPE_INVALID; + } + if(plr[myplr]._pRSpell < 0) { + st = RSPLTYPE_INVALID; + } + + SetSpellTrans(st); + + if(sn != -1) { + DrawSpellCel(629, 631, (BYTE *)pSpellCels, SpellITbl[sn], 56); + } else { + DrawSpellCel(629, 631, (BYTE *)pSpellCels, 27, 56); + } +} + +void DrawSpellList() +{ + int x, y, i, j, t, s, c, v, trans, lx, ly, nCel; + __int64 mask, spl; + + x = 636; + y = 495; + pSpell = -1; + infostr[0] = '\0'; + ClearPanel(); + + for(t = 0; t < 4; t++) { + switch(t) { + case RSPLTYPE_SKILL: + SetSpellTrans(RSPLTYPE_SKILL); + spl = plr[myplr]._pAblSpells64; + nCel = 46; + break; + case RSPLTYPE_SPELL: + spl = plr[myplr]._pMemSpells64; + nCel = 47; + break; + case RSPLTYPE_SCROLL: + SetSpellTrans(RSPLTYPE_SCROLL); + spl = plr[myplr]._pScrlSpells64; + nCel = 44; + break; + case RSPLTYPE_CHARGES: + SetSpellTrans(RSPLTYPE_CHARGES); + spl = plr[myplr]._pISpells64; + nCel = 45; + break; + } + mask = 1; + for(s = 1; s < 37; s++) { + if(spl & mask) { + if(t == RSPLTYPE_SPELL) { + v = plr[myplr]._pSplLvl[s] + plr[myplr]._pISplLvlAdd; + if(v < 0) { + v = 0; + } + if(v > 0) { + trans = RSPLTYPE_SPELL; + } else { + trans = RSPLTYPE_INVALID; + } + SetSpellTrans(trans); + } + if(currlevel == 0 && !spelldata[s].sTownSpell) { + SetSpellTrans(RSPLTYPE_INVALID); + } + DrawSpellCel(x, y, (BYTE *)pSpellCels, SpellITbl[s], 56); + lx = x - 64; + ly = y - 216; + if(MouseX >= lx && MouseX < lx + 56 && MouseY >= ly && MouseY < ly + 56) { + pSpell = s; + pSplType = t; + DrawSpellCel(x, y, (BYTE *)pSpellCels, nCel, 56); + switch(t) { + case RSPLTYPE_SKILL: + sprintf(infostr, "%s Skill", spelldata[pSpell].sSkillText); + break; + case RSPLTYPE_SPELL: + sprintf(infostr, "%s Spell", spelldata[pSpell].sNameText); + if(pSpell == SPL_HBOLT) { + sprintf(tempstr, "Damages undead only"); + AddPanelString(tempstr, TRUE); + } + if(v == 0) { + sprintf(tempstr, "Spell Level 0 - Unusable"); + } else { + sprintf(tempstr, "Spell Level %i", v); + } + AddPanelString(tempstr, TRUE); + break; + case RSPLTYPE_SCROLL: + sprintf(infostr, "Scroll of %s", spelldata[pSpell].sNameText); + c = 0; + for(i = 0; i < plr[myplr]._pNumInv; i++) { + if(plr[myplr].InvList[i]._itype != -1 + && (plr[myplr].InvList[i]._iMiscId == IMISC_SCROLL + || plr[myplr].InvList[i]._iMiscId == IMISC_SCROLLT) + && plr[myplr].InvList[i]._iSpell == pSpell) { + c++; + } + } + for(i = 0; i < 8; i++) { + if(plr[myplr].SpdList[i]._itype != -1 + && (plr[myplr].SpdList[i]._iMiscId == IMISC_SCROLL + || plr[myplr].SpdList[i]._iMiscId == IMISC_SCROLLT) + && plr[myplr].SpdList[i]._iSpell == pSpell) { + c++; + } + } + if(c == 1) { + strcpy(tempstr, "1 Scroll"); + } else { + sprintf(tempstr, "%i Scrolls", c); + } + AddPanelString(tempstr, TRUE); + break; + case RSPLTYPE_CHARGES: + sprintf(infostr, "Staff of %s", spelldata[pSpell].sNameText); + if(plr[myplr].InvBody[4]._iCharges == 1) { + strcpy(tempstr, "1 Charge"); + } else { + sprintf(tempstr, "%i Charges", plr[myplr].InvBody[4]._iCharges); + } + AddPanelString(tempstr, TRUE); + break; + } + for(j = 0; j < 4; j++) { + if(plr[myplr]._pSplHotKey[j] == pSpell && plr[myplr]._pSplTHotKey[j] == pSplType) { + DrawSpellCel(x, y, (BYTE *)pSpellCels, j + 48, 56); + sprintf(tempstr, "Spell Hot Key #F%i", j + 5); + AddPanelString(tempstr, TRUE); + } + } + } + x -= 56; + if(x == 20) { + x = 636; + y -= 56; + } + } + mask <<= 1; + } + if(spl != 0 && x != 636) { + x -= 56; + } + if(x == 20) { + x = 636; + y -= 56; + } + } +} + +void SetSpell() +{ + spselflag = 0; + + if(pSpell != -1) { + ClearPanel(); + force_redraw = 255; + plr[myplr]._pRSpell = pSpell; + plr[myplr]._pRSplType = pSplType; + } +} + +void SetSpeedSpell(int slot) +{ + int i; + + if(pSpell != -1) { + for(i = 0; i < 4; i++) { + if(plr[myplr]._pSplHotKey[i] == pSpell && plr[myplr]._pSplTHotKey[i] == pSplType) { + plr[myplr]._pSplHotKey[i] = -1; + } + } + plr[myplr]._pSplHotKey[slot] = pSpell; + plr[myplr]._pSplTHotKey[slot] = pSplType; + } +} + +void ToggleSpell(int slot) +{ + __int64 spl; + + if(plr[myplr]._pSplHotKey[slot] == -1) { + return; + } + + switch(plr[myplr]._pSplTHotKey[slot]) { + case RSPLTYPE_SKILL: + spl = plr[myplr]._pAblSpells64; + break; + case RSPLTYPE_SPELL: + spl = plr[myplr]._pMemSpells64; + break; + case RSPLTYPE_SCROLL: + spl = plr[myplr]._pScrlSpells64; + break; + case RSPLTYPE_CHARGES: + spl = plr[myplr]._pISpells64; + break; + } + + if(spl & (__int64)1 << (plr[myplr]._pSplHotKey[slot] - 1)) { + force_redraw = 255; + plr[myplr]._pRSpell = plr[myplr]._pSplHotKey[slot]; + plr[myplr]._pRSplType = plr[myplr]._pSplTHotKey[slot]; + } +} + +void PrintChar(int nOffset, int nCel, char col) +{ + /// ASSERT: assert(gpBuffer); + +#ifdef USE_ASM + __asm { + mov ebx, pPanelText + mov eax, nCel + shl eax, 2 + add ebx, eax + mov edx, [ebx+4] + sub edx, [ebx] + mov esi, pPanelText + add esi, [ebx] + mov edi, gpBuffer + add edi, nOffset + mov ebx, edx + add ebx, esi + xor edx, edx + mov dl, col + cmp edx, COL_WHITE + jz c0_label1 + cmp edx, COL_BLUE + jz c1_label1 + cmp edx, COL_RED + jz c2_label1 + jmp d_label1 + + // Case 0 + c0_label1: + mov edx, 13 + c0_label2: + xor eax, eax + lodsb + or al, al + js c0_label6 + sub edx, eax + mov ecx, eax + shr ecx, 1 + jnb c0_label3 + movsb + jecxz c0_label5 + c0_label3: + shr ecx, 1 + jnb c0_label4 + movsw + jecxz c0_label5 + c0_label4: + rep movsd + c0_label5: + or edx, edx + jz c0_label7 + jmp c0_label2 + c0_label6: + neg al + add edi, eax + sub edx, eax + jnz c0_label2 + c0_label7: + sub edi, 768 + 13 + cmp ebx, esi + jnz c0_label1 + jmp labret + + // Case 1 + c1_label1: + mov edx, 13 + c1_label2: + xor eax, eax + lodsb + or al, al + js c1_label6 + sub edx, eax + mov ecx, eax + c1_label3: + lodsb + cmp al, PAL16_GRAY + 13 + ja c1_label4 + cmp al, PAL16_GRAY + jb c1_label5 + sub al, PAL16_GRAY - (PAL16_BLUE + 2) + jmp c1_label5 + c1_label4: + mov al, PAL16_BLUE + 15 + c1_label5: + stosb + loop c1_label3 + or edx, edx + jz c1_label7 + jmp c1_label2 + c1_label6: + neg al + add edi, eax + sub edx, eax + jnz c1_label2 + c1_label7: + sub edi, 768 + 13 + cmp ebx, esi + jnz c1_label1 + jmp labret + + // Case 2 + c2_label1: + mov edx, 13 + c2_label2: + xor eax, eax + lodsb + or al, al + js c2_label5 + sub edx, eax + mov ecx, eax + c2_label3: + lodsb + cmp al, PAL16_GRAY + jb c2_label4 + sub al, PAL16_GRAY - PAL16_RED + c2_label4: + stosb + loop c2_label3 + or edx, edx + jz c2_label6 + jmp c2_label2 + c2_label5: + neg al + add edi, eax + sub edx, eax + jnz c2_label2 + c2_label6: + sub edi, 768 + 13 + cmp ebx, esi + jnz c2_label1 + jmp labret + + // Default + d_label1: + mov edx, 13 + d_label2: + xor eax, eax + lodsb + or al, al + js d_label6 + sub edx, eax + mov ecx, eax + d_label3: + lodsb + cmp al, PAL16_GRAY + jb d_label5 + cmp al, PAL16_GRAY + 14 + jnb d_label4 + sub al, PAL16_GRAY - (PAL16_YELLOW + 2) + jmp d_label5 + d_label4: + mov al, PAL16_YELLOW + 15 + d_label5: + stosb + loop d_label3 + or edx, edx + jz d_label7 + jmp d_label2 + d_label6: + neg al + add edi, eax + sub edx, eax + jnz d_label2 + d_label7: + sub edi, 768 + 13 + cmp ebx, esi + jnz d_label1 + + labret: + } +#else + int i; + BYTE width, pix; + BYTE *src, *dst, *end; + DWORD *pFrameTable; + + pFrameTable = (DWORD *)pPanelText; + src = &pPanelText[pFrameTable[nCel]]; + end = &src[pFrameTable[nCel + 1] - pFrameTable[nCel]]; + dst = &gpBuffer[nOffset]; + + switch(col) { + case COL_WHITE: + for(; src != end; dst -= 768 + 13) { + for(i = 13; i;) { + width = *src++; + if(!(width & 0x80)) { + i -= width; + if(width & 1) { + dst[0] = src[0]; + src++; + dst++; + } + width >>= 1; + if(width & 1) { + dst[0] = src[0]; + dst[1] = src[1]; + src += 2; + dst += 2; + } + width >>= 1; + while(width) { + dst[0] = src[0]; + dst[1] = src[1]; + dst[2] = src[2]; + dst[3] = src[3]; + src += 4; + dst += 4; + width--; + } + } else { + width = -(char)width; + dst += width; + i -= width; + } + } + } + break; + case COL_BLUE: + for(; src != end; dst -= 768 + 13) { + for(i = 13; i;) { + width = *src++; + if(!(width & 0x80)) { + i -= width; + while(width) { + pix = *src++; + if(pix > PAL16_GRAY + 13) { + pix = PAL16_BLUE + 15; + } else if(pix >= PAL16_GRAY) { + pix -= PAL16_GRAY - (PAL16_BLUE + 2); + } + *dst++ = pix; + width--; + } + } else { + width = -(char)width; + dst += width; + i -= width; + } + } + } + break; + case COL_RED: + for(; src != end; dst -= 768 + 13) { + for(i = 13; i;) { + width = *src++; + if(!(width & 0x80)) { + i -= width; + while(width) { + pix = *src++; + if(pix >= PAL16_GRAY) { + pix -= PAL16_GRAY - PAL16_RED; + } + *dst++ = pix; + width--; + } + } else { + width = -(char)width; + dst += width; + i -= width; + } + } + } + break; + default: + for(; src != end; dst -= 768 + 13) { + for(i = 13; i;) { + width = *src++; + if(!(width & 0x80)) { + i -= width; + while(width) { + pix = *src++; + if(pix >= PAL16_GRAY) { + if(pix >= PAL16_GRAY + 14) { + pix = PAL16_YELLOW + 15; + } else { + pix -= PAL16_GRAY - (PAL16_YELLOW + 2); + } + } + *dst++ = pix; + width--; + } + } else { + width = -(char)width; + dst += width; + i -= width; + } + } + } + break; + } +#endif +} + +void AddPanelString(const char *str, BOOL just) +{ + strcpy(panelstr[pnumlines], str); + pstrjust[pnumlines] = just; + + if(pnumlines < 4) { + pnumlines++; + } +} + +void ClearPanel() +{ + pnumlines = 0; + pinfoflag = 0; +} + +void DrawPanelBox(int x, int y, int w, int h, int sx, int sy) +{ + int nSrcOff, nDstOff; + + /// ASSERT: assert(gpBuffer); + + nSrcOff = x + 640 * y; + nDstOff = sx + 768 * sy; + +#ifdef USE_ASM + __asm { + mov esi, pBtmBuff + add esi, nSrcOff + mov edi, gpBuffer + add edi, nDstOff + xor ebx, ebx + mov bx, word ptr w + xor edx, edx + mov dx, word ptr h + label1: + mov ecx, ebx + shr ecx, 1 + jnb label2 + movsb + jecxz label4 + label2: + shr ecx, 1 + jnb label3 + movsw + jecxz label4 + label3: + rep movsd + label4: + add esi, 640 + sub esi, ebx + add edi, 768 + sub edi, ebx + dec edx + jnz label1 + } +#else + int wdt, hgt; + BYTE *src, *dst; + + src = &pBtmBuff[nSrcOff]; + dst = &gpBuffer[nDstOff]; + + for(hgt = h; hgt; hgt--, src += 640 - w, dst += 768 - w) { + wdt = w; + if(wdt & 1) { + dst[0] = src[0]; + src++; + dst++; + } + wdt >>= 1; + if(wdt & 1) { + dst[0] = src[0]; + dst[1] = src[1]; + src += 2; + dst += 2; + } + wdt >>= 1; + while(wdt) { + dst[0] = src[0]; + dst[1] = src[1]; + dst[2] = src[2]; + dst[3] = src[3]; + src += 4; + dst += 4; + wdt--; + } + } +#endif +} + +void SetFlaskHeight(BYTE *pCelBuff, int min, int max, int x, int y) +{ + int nSrcOff, nDstOff, w; + + /// ASSERT: assert(gpBuffer); + + nSrcOff = 88 * min; + nDstOff = x + 768 * y; + w = max - min; + +#ifdef USE_ASM + __asm { + mov esi, pCelBuff + add esi, nSrcOff + mov edi, gpBuffer + add edi, nDstOff + mov edx, w + label1: + mov ecx, 88 / 4 + rep movsd + add edi, 768 - 88 + dec edx + jnz label1 + } +#else + BYTE *src, *dst; + + src = &pCelBuff[nSrcOff]; + dst = &gpBuffer[nDstOff]; + + for(; w; w--, src += 88, dst += 768) { + memcpy(dst, src, 88); + } +#endif +} + +void DrawFlask(BYTE *pCelBuff, int w, int nSrcOff, BYTE *pBuff, int nDstOff, int h) +{ +#ifdef USE_ASM + __asm { + mov esi, pCelBuff + add esi, nSrcOff + mov edi, pBuff + add edi, nDstOff + mov edx, h + label1: + mov ecx, 59 + label2: + lodsb + or al, al + jz label3 + mov [edi], al + label3: + inc edi + loop label2 + add esi, w + sub esi, 59 + add edi, 768 - 59 + dec edx + jnz label1 + } +#else + int wdt, hgt; + BYTE *src, *dst; + + src = &pCelBuff[nSrcOff]; + dst = &pBuff[nDstOff]; + + for(hgt = h; hgt; hgt--, src += w - 59, dst += 768 - 59) { + for(wdt = 59; wdt; wdt--) { + if(*src != 0) { + *dst = *src; + } + src++; + dst++; + } + } +#endif +} + +void DrawLifeFlask() +{ + int p; + + p = (double)plr[myplr]._pHitPoints / (double)plr[myplr]._pMaxHP * 80.0; + plr[myplr]._pHPPer = p; + if(p > 80) { + p = 80; + } + p = 80 - p; + if(p > 11) { + p = 11; + } + p += 2; + + /// ASSERT: assert(gpBuffer); + DrawFlask(pLifeBuff, 88, 13 + 88 * 3, gpBuffer, SCREENXY(109, 339), p); + + if(p != 13) { + DrawFlask(pBtmBuff, 640, 109 + (p + 3) * 640, gpBuffer, SCREENXY(109, 339 + p), 13 - p); + } +} + +void UpdateLifeFlask() +{ + int p; + + p = (double)plr[myplr]._pHitPoints / (double)plr[myplr]._pMaxHP * 80.0; + plr[myplr]._pHPPer = p; + if(p > 69) { + p = 69; + } else if(p < 0) { + p = 0; + } + + if(p != 69) { + SetFlaskHeight(pLifeBuff, 16, 16 + 69 - p, 96 + SCREEN_X, 352 + SCREEN_Y); + } + if(p != 0) { + DrawPanelBox(96, 16 + 69 - p, 88, p, 96 + SCREEN_X, 352 + 69 - p + SCREEN_Y); + } +} + +void DrawManaFlask() +{ + int p; + + p = plr[myplr]._pManaPer; + if(p > 80) { + p = 80; + } + p = 80 - p; + if(p > 11) { + p = 11; + } + p += 2; + + /// ASSERT: assert(gpBuffer); + DrawFlask(pManaBuff, 88, 13 + 88 * 3, gpBuffer, SCREENXY(475, 339), p); + + if(p != 13) { + DrawFlask(pBtmBuff, 640, 475 + (p + 3) * 640, gpBuffer, SCREENXY(475, 339 + p), 13 - p); + } +} + +void control_update_life_mana() +{ + int cm, mm, p; + + mm = plr[myplr]._pMaxMana; + cm = plr[myplr]._pMana; + if(mm < 0) { + mm = 0; + } + if(cm < 0) { + cm = 0; + } + + if(mm == 0) { + p = 0; + } else { + p = (double)cm / (double)mm * 80.0; + } + + plr[myplr]._pManaPer = p; + p = (double)plr[myplr]._pHitPoints / (double)plr[myplr]._pMaxHP * 80.0; + plr[myplr]._pHPPer = p; +} + +void UpdateManaFlask() +{ + int cm, mm, p; + + mm = plr[myplr]._pMaxMana; + cm = plr[myplr]._pMana; + if(mm < 0) { + mm = 0; + } + if(cm < 0) { + cm = 0; + } + + if(mm == 0) { + p = 0; + } else { + p = (double)cm / (double)mm * 80.0; + } + plr[myplr]._pManaPer = p; + if(p > 69) { + p = 69; + } + + if(p != 69) { + SetFlaskHeight(pManaBuff, 16, 16 + 69 - p, 464 + SCREEN_X, 352 + SCREEN_Y); + } + if(p != 0) { + DrawPanelBox(464, 16 + 69 - p, 88, p, 464 + SCREEN_X, 352 + 69 - p + SCREEN_Y); + } + + DrawSpell(); +} + +void InitControlPan() +{ + int i; + + /// ASSERT: assert(! pBtmBuff); + if(gbMaxPlayers == 1) { + pBtmBuff = DiabloAllocPtr(0x16800); + memset(pBtmBuff, 0, 0x16800); + } else { + pBtmBuff = DiabloAllocPtr(0x2D000); + memset(pBtmBuff, 0, 0x2D000); + } + + pManaBuff = DiabloAllocPtr(88 * 88); + memset(pManaBuff, 0, 88 * 88); + pLifeBuff = DiabloAllocPtr(88 * 88); + memset(pLifeBuff, 0, 88 * 88); + pPanelText = DiabLoad("CtrlPan\\SmalText.CEL", NULL, 'CTRL'); + pChrPanel = DiabLoad("Data\\Char.CEL", NULL, 'CTRL'); + pSpellCels = DiabLoad("CtrlPan\\SpelIcon.CEL", NULL, 'CTRL'); + + SetSpellTrans(RSPLTYPE_SKILL); + + pStatusPanel = DiabLoad("CtrlPan\\Panel8.CEL", NULL, 'CTRL'); + CelDecodeRect((BYTE *)pBtmBuff, 0, 143, 640, (BYTE *)pStatusPanel, 1, 640); + MemFreeDbg(pStatusPanel); + pStatusPanel = DiabLoad("CtrlPan\\P8Bulbs.CEL", NULL, 'CTRL'); + CelDecodeRect((BYTE *)pLifeBuff, 0, 87, 88, (BYTE *)pStatusPanel, 1, 88); + CelDecodeRect((BYTE *)pManaBuff, 0, 87, 88, (BYTE *)pStatusPanel, 2, 88); + MemFreeDbg(pStatusPanel); + + talkflag = 0; + if(gbMaxPlayers != 1) { + pTalkPanel = DiabLoad("CtrlPan\\TalkPanl.CEL", NULL, 'CTRL'); + CelDecodeRect((BYTE *)pBtmBuff, 0, 287, 640, (BYTE *)pTalkPanel, 1, 640); + MemFreeDbg(pTalkPanel); + pMultiBtns = DiabLoad("CtrlPan\\P8But2.CEL", NULL, 'CTRL'); + pTalkBtns = DiabLoad("CtrlPan\\TalkButt.CEL", NULL, 'CTRL'); + sgbPlrTalkTbl = 0; + sgszTalkMsg[0] = '\0'; + for(i = 0; i < 4; i++) { + byte_4B894C[i] = 1; + } + for(i = 0; i < 3; i++) { + talkbtndown[i] = 0; + } + } + + panelflag = 0; + lvlbtndown = 0; + pPanelButtons = DiabLoad("CtrlPan\\Panel8bu.CEL", NULL, 'CTRL'); + for(i = 0; i < 8; i++) { + panbtn[i] = 0; + } + panbtndown = 0; + if(gbMaxPlayers == 1) { + numpanbtns = 6; + } else { + numpanbtns = 8; + } + + pChrButtons = DiabLoad("Data\\CharBut.CEL", NULL, 'CTRL'); + for(i = 0; i < 4; i++) { + chrbtn[i] = 0; + } + chrbtnactive = 0; + + pDurIcons = DiabLoad("Items\\DurIcons.CEL", NULL, 'CTRL'); + strcpy(infostr, ""); + ClearPanel(); + drawhpflag = 1; + drawmanaflag = 1; + chrflag = 0; + spselflag = 0; + pSpellBkCel = DiabLoad("Data\\SpellBk.CEL", NULL, 'CTRL'); + pSBkBtnCel = DiabLoad("Data\\SpellBkB.CEL", NULL, 'CTRL'); + pSBkIconCels = DiabLoad("Data\\SpellI2.CEL", NULL, 'CTRL'); + sbooktab = 0; + sbookflag = 0; + + if(plr[myplr]._pClass == PC_WARRIOR) { + SpellPages[0][0] = SPL_REPAIR; + } else if(plr[myplr]._pClass == PC_ROGUE) { + SpellPages[0][0] = SPL_DISARM; + } else if(plr[myplr]._pClass == PC_SORCERER) { + SpellPages[0][0] = SPL_RECHARGE; + } + + pQLogCel = DiabLoad("Data\\Quest.CEL", NULL, 'CTRL'); + pGBoxBuff = DiabLoad("CtrlPan\\Golddrop.cel", NULL, 'CTRL'); + dropGoldFlag = 0; + dropGoldValue = 0; + initialDropGoldValue = 0; + initialDropGoldIndex = 0; + frame_4B8800 = 1; +} + +void DrawCtrlPan() +{ + DrawPanelBox(0, sgbPlrTalkTbl + 16, 640, 128, 0 + SCREEN_X, 352 + SCREEN_Y); + DrawInfoBox(); +} + +void DrawCtrlBtns() +{ + int i; + + for(i = 0; i < 6; i++) { + if(!panbtn[i]) { + DrawPanelBox(PanBtnPos[i][0], PanBtnPos[i][1] - 336, 71, 20, PanBtnPos[i][0] + SCREEN_X, PanBtnPos[i][1] + SCREEN_Y); + } else { + CelDecodeOnly(PanBtnPos[i][0] + SCREEN_X, PanBtnPos[i][1] + 18 + SCREEN_Y, (BYTE *)pPanelButtons, i + 1, 71); + } + } + + if(numpanbtns == 8) { + CelDecodeOnly(87 + SCREEN_X, 474 + SCREEN_Y, (BYTE *)pMultiBtns, panbtn[6] + 1, 33); + if(FriendlyMode) { + CelDecodeOnly(527 + SCREEN_X, 474 + SCREEN_Y, (BYTE *)pMultiBtns, panbtn[7] + 3, 33); + } else { + CelDecodeOnly(527 + SCREEN_X, 474 + SCREEN_Y, (BYTE *)pMultiBtns, panbtn[7] + 5, 33); + } + } +} + +void DoSpeedBook() +{ + int x, y, cx, cy, t, s; + __int64 spl, mask; + + spselflag = 1; + x = 636; + y = 495; + cx = x - 36; + cy = y - 188; + + if(plr[myplr]._pRSpell != -1) { + for(t = 0; t < 4; t++) { + switch(t) { + case RSPLTYPE_SKILL: + spl = plr[myplr]._pAblSpells64; + break; + case RSPLTYPE_SPELL: + spl = plr[myplr]._pMemSpells64; + break; + case RSPLTYPE_SCROLL: + spl = plr[myplr]._pScrlSpells64; + break; + case RSPLTYPE_CHARGES: + spl = plr[myplr]._pISpells64; + break; + } + mask = 1; + for(s = 1; s < 37; s++) { + if(spl & mask) { + if(s == plr[myplr]._pRSpell && t == plr[myplr]._pRSplType) { + cx = x - 36; + cy = y - 188; + } + x -= 56; + if(x == 20) { + x = 636; + y -= 56; + } + } + mask <<= 1; + } + if(spl != 0 && x != 636) { + x -= 56; + } + if(x == 20) { + x = 636; + y -= 56; + } + } + } + + SetCursorPos(cx, cy); +} + +void DoPanBtn() +{ + int i, x2, y2; + + for(i = 0; i < numpanbtns; i++) { + x2 = PanBtnPos[i][0] + PanBtnPos[i][2]; + y2 = PanBtnPos[i][1] + PanBtnPos[i][3]; + if(MouseX >= PanBtnPos[i][0] && MouseX <= x2 && MouseY >= PanBtnPos[i][1] && MouseY <= y2) { + panbtn[i] = 1; + drawbtnflag = 1; + panbtndown = 1; + } + } + + if(!spselflag && MouseX >= 565 && MouseX < 565 + 56 && MouseY >= 416 && MouseY < 416 + 56) { + DoSpeedBook(); + gamemenu_off(); + } +} + +void control_set_button_down(int btn_id) +{ + panbtn[btn_id] = 1; + drawbtnflag = 1; + panbtndown = 1; +} + +void control_check_btn_press() +{ + int x2, y2; + + x2 = PanBtnPos[3][0] + PanBtnPos[3][2]; + y2 = PanBtnPos[3][1] + PanBtnPos[3][3]; + if(MouseX >= PanBtnPos[3][0] && MouseX <= x2 && MouseY >= PanBtnPos[3][1] && MouseY <= y2) { + control_set_button_down(3); + } + x2 = PanBtnPos[6][0] + PanBtnPos[6][2]; + y2 = PanBtnPos[6][1] + PanBtnPos[6][3]; + if(MouseX >= PanBtnPos[6][0] && MouseX <= x2 && MouseY >= PanBtnPos[6][1] && MouseY <= y2) { + control_set_button_down(6); + } +} + +void DoAutoMap() +{ + if(currlevel == 0 && gbMaxPlayers == 1) { + InitDiabloMsg(1); + return; + } + + if(!automapflag) { + StartAutomap(); + } else { + automapflag = 0; + } +} + +void CheckPanelInfo() +{ + int i, j, x2, y2, c, s, v; + + panelflag = 0; + ClearPanel(); + + for(i = 0; i < numpanbtns; i++) { + x2 = PanBtnPos[i][0] + PanBtnPos[i][2]; + y2 = PanBtnPos[i][1] + PanBtnPos[i][3]; + if(MouseX >= PanBtnPos[i][0] && MouseX <= x2 && MouseY >= PanBtnPos[i][1] && MouseY <= y2) { + if(i != 7) { + strcpy(infostr, PanBtnStr[i]); + } else if(FriendlyMode) { + strcpy(infostr, "Player friendly"); + } else { + strcpy(infostr, "Player attack"); + } + if(PanBtnHotKey[i] != 0) { + sprintf(tempstr, "Hotkey : %s", PanBtnHotKey[i]); + AddPanelString(tempstr, TRUE); + } + infoclr = COL_WHITE; + panelflag = 1; + pinfoflag = 1; + } + } + + if(!spselflag && MouseX >= 565 && MouseX < 565 + 56 && MouseY >= 416 && MouseY < 416 + 56) { + strcpy(infostr, "Select current spell button"); + infoclr = COL_WHITE; + panelflag = 1; + pinfoflag = 1; + strcpy(tempstr, "Hotkey : 's'"); + AddPanelString(tempstr, TRUE); + s = plr[myplr]._pRSpell; + if(s != -1) { + switch(plr[myplr]._pRSplType) { + case RSPLTYPE_SKILL: + sprintf(tempstr, "%s Skill", spelldata[s].sSkillText); + AddPanelString(tempstr, TRUE); + break; + case RSPLTYPE_SPELL: + sprintf(tempstr, "%s Spell", spelldata[s].sNameText); + AddPanelString(tempstr, TRUE); + v = plr[myplr]._pSplLvl[s] + plr[myplr]._pISplLvlAdd; + if(v < 0) { + v = 0; + } + if(v == 0) { + sprintf(tempstr, "Spell Level 0 - Unusable"); + } else { + sprintf(tempstr, "Spell Level %i", v); + } + AddPanelString(tempstr, TRUE); + break; + case RSPLTYPE_SCROLL: + sprintf(tempstr, "Scroll of %s", spelldata[s].sNameText); + AddPanelString(tempstr, TRUE); + c = 0; + for(j = 0; j < plr[myplr]._pNumInv; j++) { + if(plr[myplr].InvList[j]._itype != -1 + && (plr[myplr].InvList[j]._iMiscId == IMISC_SCROLL + || plr[myplr].InvList[j]._iMiscId == IMISC_SCROLLT) + && plr[myplr].InvList[j]._iSpell == s) { + c++; + } + } + for(j = 0; j < 8; j++) { + if(plr[myplr].SpdList[j]._itype != -1 + && (plr[myplr].SpdList[j]._iMiscId == IMISC_SCROLL + || plr[myplr].SpdList[j]._iMiscId == IMISC_SCROLLT) + && plr[myplr].SpdList[j]._iSpell == s) { + c++; + } + } + if(c == 1) { + strcpy(tempstr, "1 Scroll"); + } else { + sprintf(tempstr, "%i Scrolls", c); + } + AddPanelString(tempstr, TRUE); + break; + case RSPLTYPE_CHARGES: + sprintf(tempstr, "Staff of %s", spelldata[s].sNameText); + AddPanelString(tempstr, TRUE); + if(plr[myplr].InvBody[4]._iCharges == 1) { + strcpy(tempstr, "1 Charge"); + } else { + sprintf(tempstr, "%i Charges", plr[myplr].InvBody[4]._iCharges); + } + AddPanelString(tempstr, TRUE); + break; + } + } + } + if(MouseX > 190 && MouseX < 437 && MouseY > 356 && MouseY < 385) { + pcursinvitem = CheckInvHLight(); + } +} + +void CheckBtnUp() +{ + int i; + BOOLEAN menu; + + menu = TRUE; + drawbtnflag = 1; + panbtndown = 0; + + for(i = 0; i < 8; i++) { + if(!panbtn[i]) { + continue; + } + panbtn[i] = 0; + if(MouseX < PanBtnPos[i][0]) { + continue; + } + if(MouseX > PanBtnPos[i][0] + PanBtnPos[i][2]) { + continue; + } + if(MouseY < PanBtnPos[i][1]) { + continue; + } + if(MouseY > PanBtnPos[i][1] + PanBtnPos[i][3]) { + continue; + } + switch(i) { + case PANBTN_CHARINFO: + questlog = 0; + chrflag = !chrflag; + break; + case PANBTN_QLOG: + chrflag = 0; + if(!questlog) { + StartQuestlog(); + } else { + questlog = 0; + } + break; + case PANBTN_AUTOMAP: + DoAutoMap(); + break; + case PANBTN_MAINMENU: + qtextflag = 0; + gamemenu_handle_previous(); + menu = FALSE; + break; + case PANBTN_INVENTORY: + sbookflag = 0; + invflag = !invflag; + if(dropGoldFlag) { + dropGoldFlag = 0; + dropGoldValue = 0; + } + break; + case PANBTN_SPELLBOOK: + invflag = 0; + if(dropGoldFlag) { + dropGoldFlag = 0; + dropGoldValue = 0; + } + sbookflag = !sbookflag; + break; + case PANBTN_SENDMSG: + if(talkflag) { + control_reset_talk(); + } else { + control_type_message(); + } + break; + case PANBTN_FRIENDLY: + FriendlyMode = !FriendlyMode; + break; + } + } + + if(menu) { + gamemenu_off(); + } +} + +void FreeControlPan() +{ + MemFreeDbg(pBtmBuff); + MemFreeDbg(pManaBuff); + MemFreeDbg(pLifeBuff); + MemFreeDbg(pPanelText); + MemFreeDbg(pChrPanel); + MemFreeDbg(pSpellCels); + MemFreeDbg(pPanelButtons); + MemFreeDbg(pMultiBtns); + MemFreeDbg(pTalkBtns); + MemFreeDbg(pChrButtons); + MemFreeDbg(pDurIcons); + MemFreeDbg(pQLogCel); + MemFreeDbg(pSpellBkCel); + MemFreeDbg(pSBkBtnCel); + MemFreeDbg(pSBkIconCels); + MemFreeDbg(pGBoxBuff); +} + +BOOL control_WriteStringToBuffer(const char *str) +{ + int w; + BYTE c; + + w = 0; + while(*str != '\0') { + c = gbFontTransTbl[(BYTE)*str]; + str++; + w += fontkern[fontframe[c]]; + if(w >= 125) { + return FALSE; + } + } + + return TRUE; +} + +void DrawInfoBox() +{ + int nGold; + + DrawPanelBox(177, 62, 288, 60, 177 + SCREEN_X, 398 + SCREEN_Y); + + if(!panelflag && !trigflag && pcursinvitem == -1 && !spselflag) { + infostr[0] = '\0'; + infoclr = COL_WHITE; + ClearPanel(); + } + + if(spselflag || trigflag) { + infoclr = COL_WHITE; + } else if(pcurs >= CURSOR_FIRSTITEM) { + if(plr[myplr].HoldItem._itype == ITYPE_GOLD) { + nGold = plr[myplr].HoldItem._ivalue; + sprintf(infostr, "%i gold %s", nGold, get_pieces_str(nGold)); + } else if(!plr[myplr].HoldItem._iStatFlag) { + ClearPanel(); + AddPanelString("Requirements not met", TRUE); + pinfoflag = 1; + } else { + if(plr[myplr].HoldItem._iIdentified) { + strcpy(infostr, plr[myplr].HoldItem._iIName); + } else { + strcpy(infostr, plr[myplr].HoldItem._iName); + } + if(plr[myplr].HoldItem._iMagical == 1) { + infoclr = COL_BLUE; + } + if(plr[myplr].HoldItem._iMagical == 2) { + infoclr = COL_GOLD; + } + } + } else { + if(pcursitem != -1) { + GetItemStr(pcursitem); + } + if(pcursobj != -1) { + GetObjectStr(pcursobj); + } + if(pcursmonst != -1) { + if(leveltype != DTYPE_TOWN) { + infoclr = COL_WHITE; + strcpy(infostr, monster[pcursmonst].mName); + ClearPanel(); + if(monster[pcursmonst]._uniqtype != 0) { + infoclr = COL_GOLD; + PrintUniqueHistory(); + } else { + PrintMonstHistory(monster[pcursmonst].MType->mtype); + } + } else { + strcpy(infostr, towner[pcursmonst]._tName); + } + } + if(pcursplr != -1) { + infoclr = COL_GOLD; + strcpy(infostr, plr[pcursplr]._pName); + ClearPanel(); + sprintf(tempstr, "Level : %i", plr[pcursplr]._pLevel); + AddPanelString(tempstr, TRUE); + sprintf(tempstr, "Hit Points %i of %i", plr[pcursplr]._pHitPoints >> 6, plr[pcursplr]._pMaxHP >> 6); + AddPanelString(tempstr, TRUE); + } + } + + if(infostr[0] != '\0' || pnumlines != 0) { + PrintInfo(); + } +} + +void PrintInfo() +{ + int i, nOffset1, nlines; + + if(talkflag) { + return; + } + + nOffset1 = 0; + nlines = 1; + if(infostr[0] != '\0') { + CPrintString(0, infostr, TRUE, pnumlines); + nOffset1 = 1; + nlines = 0; + } + + for(i = 0; i < pnumlines; i++) { + CPrintString(i + nOffset1, panelstr[i], pstrjust[i], pnumlines - nlines); + } +} + +void CPrintString(int No, char *pszStr, BOOL Just, int lines) +{ + int nOffset, w, cw; + BYTE c; + char *s; + + nOffset = lineoffset[lines][No]; + w = 0; + + if(Just == TRUE) { + cw = 0; + s = pszStr; + while(*s != '\0') { + c = gbFontTransTbl[(BYTE)*s]; + s++; + c = fontframe[c]; + cw += fontkern[c] + 2; + } + if(cw < 288) { + w = (288 - cw) >> 1; + } + nOffset += w; + } + + while(*pszStr != '\0') { + c = gbFontTransTbl[(BYTE)*pszStr]; + pszStr++; + c = fontframe[c]; + w += fontkern[c] + 2; + if(c != 0 && w < 288) { + PrintChar(nOffset, c, infoclr); + } + nOffset += fontkern[c] + 2; + } +} + +void PrintGameStr(int x, int y, const char *pszStr, int col) +{ + int nOffset; + BYTE c; + + nOffset = x + SCREEN_X + PitchTbl[y + SCREEN_Y]; + + while(*pszStr != '\0') { + c = gbFontTransTbl[(BYTE)*pszStr]; + pszStr++; + c = fontframe[c]; + if(c != 0) { + PrintChar(nOffset, c, col); + } + nOffset += fontkern[c] + 1; + } +} + +void DrawChr() +{ + int hper, ac, pc; + long mind, maxd; + char c; + char chrstr[64]; + + CelDecodeOnly(64, 511, (BYTE *)pChrPanel, 1, 320); + ADD_PlrStringXY(20, 32, 151, plr[myplr]._pName, COL_WHITE); + + if(plr[myplr]._pClass == PC_WARRIOR) { + ADD_PlrStringXY(168, 32, 299, "Warrior", COL_WHITE); + } else if(plr[myplr]._pClass == PC_ROGUE) { + ADD_PlrStringXY(168, 32, 299, "Rogue", COL_WHITE); + } else if(plr[myplr]._pClass == PC_SORCERER) { + ADD_PlrStringXY(168, 32, 299, "Sorceror", COL_WHITE); + } + + sprintf(chrstr, "%i", plr[myplr]._pLevel); + ADD_PlrStringXY(66, 69, 109, chrstr, COL_WHITE); + sprintf(chrstr, "%li", plr[myplr]._pExperience); + ADD_PlrStringXY(216, 69, 300, chrstr, COL_WHITE); + if(plr[myplr]._pLevel == 50) { + strcpy(chrstr, "None"); + c = COL_GOLD; + } else { + sprintf(chrstr, "%li", plr[myplr]._pNextExper); + c = COL_WHITE; + } + ADD_PlrStringXY(216, 97, 300, chrstr, c); + + sprintf(chrstr, "%i", plr[myplr]._pGold); + ADD_PlrStringXY(216, 146, 300, chrstr, COL_WHITE); + + c = COL_WHITE; + if(plr[myplr]._pIBonusAC > 0) { + c = COL_BLUE; + } + if(plr[myplr]._pIBonusAC < 0) { + c = COL_RED; + } + ac = plr[myplr]._pIAC + plr[myplr]._pIBonusAC + plr[myplr]._pDexterity / 5; + sprintf(chrstr, "%i", ac); + ADD_PlrStringXY(258, 183, 301, chrstr, c); + + c = COL_WHITE; + if(plr[myplr]._pIBonusToHit > 0) { + c = COL_BLUE; + } + if(plr[myplr]._pIBonusToHit < 0) { + c = COL_RED; + } + hper = 50 + plr[myplr]._pIBonusToHit + (plr[myplr]._pDexterity >> 1); + sprintf(chrstr, "%i%%", hper); + ADD_PlrStringXY(258, 211, 301, chrstr, c); + + c = COL_WHITE; + if(plr[myplr]._pIBonusDam > 0) { + c = COL_BLUE; + } + if(plr[myplr]._pIBonusDam < 0) { + c = COL_RED; + } + mind = plr[myplr]._pIMinDam; + mind += mind * plr[myplr]._pIBonusDam / 100; + mind += plr[myplr]._pIBonusDamMod; + if(plr[myplr].InvBody[4]._itype == ITYPE_BOW) { + if(plr[myplr]._pClass == PC_ROGUE) { + mind += plr[myplr]._pDamageMod; + } else { + mind += plr[myplr]._pDamageMod >> 1; + } + } else { + mind += plr[myplr]._pDamageMod; + } + maxd = plr[myplr]._pIMaxDam; + maxd += maxd * plr[myplr]._pIBonusDam / 100; + maxd += plr[myplr]._pIBonusDamMod; + if(plr[myplr].InvBody[4]._itype == ITYPE_BOW) { + if(plr[myplr]._pClass == PC_ROGUE) { + maxd += plr[myplr]._pDamageMod; + } else { + maxd += plr[myplr]._pDamageMod >> 1; + } + } else { + maxd += plr[myplr]._pDamageMod; + } + sprintf(chrstr, "%i-%i", mind, maxd); + if(mind >= 100 || maxd >= 100) { + MY_PlrStringXY(254, 239, 305, chrstr, c, -1); + } else { + MY_PlrStringXY(258, 239, 301, chrstr, c, 0); + } + + if(plr[myplr]._pMagResist == 0) { + c = COL_WHITE; + } else { + c = COL_BLUE; + } + if(plr[myplr]._pMagResist < 75) { + sprintf(chrstr, "%i%%", plr[myplr]._pMagResist); + } else { + c = COL_GOLD; + sprintf(chrstr, "MAX"); + } + ADD_PlrStringXY(257, 276, 300, chrstr, c); + if(plr[myplr]._pFireResist == 0) { + c = COL_WHITE; + } else { + c = COL_BLUE; + } + if(plr[myplr]._pFireResist < 75) { + sprintf(chrstr, "%i%%", plr[myplr]._pFireResist); + } else { + c = COL_GOLD; + sprintf(chrstr, "MAX"); + } + ADD_PlrStringXY(257, 304, 300, chrstr, c); + if(plr[myplr]._pLghtResist == 0) { + c = COL_WHITE; + } else { + c = COL_BLUE; + } + if(plr[myplr]._pLghtResist < 75) { + sprintf(chrstr, "%i%%", plr[myplr]._pLghtResist); + } else { + c = COL_GOLD; + sprintf(chrstr, "MAX"); + } + ADD_PlrStringXY(257, 332, 300, chrstr, c); + + c = COL_WHITE; + sprintf(chrstr, "%i", plr[myplr]._pBaseStr); + if(MaxStats[plr[myplr]._pClass][0] == plr[myplr]._pBaseStr) { + c = COL_GOLD; + } + ADD_PlrStringXY(95, 155, 126, chrstr, c); + c = COL_WHITE; + sprintf(chrstr, "%i", plr[myplr]._pBaseMag); + if(MaxStats[plr[myplr]._pClass][1] == plr[myplr]._pBaseMag) { + c = COL_GOLD; + } + ADD_PlrStringXY(95, 183, 126, chrstr, c); + c = COL_WHITE; + sprintf(chrstr, "%i", plr[myplr]._pBaseDex); + if(MaxStats[plr[myplr]._pClass][2] == plr[myplr]._pBaseDex) { + c = COL_GOLD; + } + ADD_PlrStringXY(95, 211, 126, chrstr, c); + c = COL_WHITE; + sprintf(chrstr, "%i", plr[myplr]._pBaseVit); + if(MaxStats[plr[myplr]._pClass][3] == plr[myplr]._pBaseVit) { + c = COL_GOLD; + } + ADD_PlrStringXY(95, 239, 126, chrstr, c); + + c = COL_WHITE; + if(plr[myplr]._pStrength > plr[myplr]._pBaseStr) { + c = COL_BLUE; + } + if(plr[myplr]._pStrength < plr[myplr]._pBaseStr) { + c = COL_RED; + } + sprintf(chrstr, "%i", plr[myplr]._pStrength); + ADD_PlrStringXY(143, 155, 173, chrstr, c); + c = COL_WHITE; + if(plr[myplr]._pMagic > plr[myplr]._pBaseMag) { + c = COL_BLUE; + } + if(plr[myplr]._pMagic < plr[myplr]._pBaseMag) { + c = COL_RED; + } + sprintf(chrstr, "%i", plr[myplr]._pMagic); + ADD_PlrStringXY(143, 183, 173, chrstr, c); + c = COL_WHITE; + if(plr[myplr]._pDexterity > plr[myplr]._pBaseDex) { + c = COL_BLUE; + } + if(plr[myplr]._pDexterity < plr[myplr]._pBaseDex) { + c = COL_RED; + } + sprintf(chrstr, "%i", plr[myplr]._pDexterity); + ADD_PlrStringXY(143, 211, 173, chrstr, c); + c = COL_WHITE; + if(plr[myplr]._pVitality > plr[myplr]._pBaseVit) { + c = COL_BLUE; + } + if(plr[myplr]._pVitality < plr[myplr]._pBaseVit) { + c = COL_RED; + } + sprintf(chrstr, "%i", plr[myplr]._pVitality); + ADD_PlrStringXY(143, 239, 173, chrstr, c); + + if(plr[myplr]._pStatPts > 0 && CalcStatDiff(myplr) < plr[myplr]._pStatPts) { + plr[myplr]._pStatPts = CalcStatDiff(myplr); + } + if(plr[myplr]._pStatPts > 0) { + sprintf(chrstr, "%i", plr[myplr]._pStatPts); + ADD_PlrStringXY(95, 266, 126, chrstr, COL_RED); + pc = plr[myplr]._pClass; + if(plr[myplr]._pBaseStr < MaxStats[pc][0]) { + CelDecodeOnly(201, 319, (BYTE *)pChrButtons, chrbtn[0] + 2, 41); + } + if(plr[myplr]._pBaseMag < MaxStats[pc][1]) { + CelDecodeOnly(201, 347, (BYTE *)pChrButtons, chrbtn[1] + 4, 41); + } + if(plr[myplr]._pBaseDex < MaxStats[pc][2]) { + CelDecodeOnly(201, 376, (BYTE *)pChrButtons, chrbtn[2] + 6, 41); + } + if(plr[myplr]._pBaseVit < MaxStats[pc][3]) { + CelDecodeOnly(201, 404, (BYTE *)pChrButtons, chrbtn[3] + 8, 41); + } + } + + if(plr[myplr]._pMaxHP > plr[myplr]._pMaxHPBase) { + c = COL_BLUE; + } else { + c = COL_WHITE; + } + sprintf(chrstr, "%i", plr[myplr]._pMaxHP >> 6); + ADD_PlrStringXY(95, 304, 126, chrstr, c); + if(plr[myplr]._pHitPoints != plr[myplr]._pMaxHP) { + c = COL_RED; + } + sprintf(chrstr, "%i", plr[myplr]._pHitPoints >> 6); + ADD_PlrStringXY(143, 304, 174, chrstr, c); + + if(plr[myplr]._pMaxMana > plr[myplr]._pMaxManaBase) { + c = COL_BLUE; + } else { + c = COL_WHITE; + } + sprintf(chrstr, "%i", plr[myplr]._pMaxMana >> 6); + ADD_PlrStringXY(95, 332, 126, chrstr, c); + if(plr[myplr]._pMana != plr[myplr]._pMaxMana) { + c = COL_RED; + } + sprintf(chrstr, "%i", plr[myplr]._pMana >> 6); + ADD_PlrStringXY(143, 332, 174, chrstr, c); +} + +void ADD_PlrStringXY(int x, int y, int x2, const char *pszStr, char col) +{ + int nOffset, width, w, cw; + BYTE c; + const char *s; + + nOffset = x + SCREEN_X + PitchTbl[y + SCREEN_Y]; + width = x2 - x + 1; + w = 0; + cw = 0; + + s = pszStr; + while(*s != '\0') { + c = gbFontTransTbl[(BYTE)*s]; + s++; + c = fontframe[c]; + cw += fontkern[c] + 1; + } + if(cw < width) { + w = (width - cw) >> 1; + } + + nOffset += w; + while(*pszStr != '\0') { + c = gbFontTransTbl[(BYTE)*pszStr]; + pszStr++; + c = fontframe[c]; + w += fontkern[c] + 1; + if(c != 0 && w < width) { + PrintChar(nOffset, c, col); + } + nOffset += fontkern[c] + 1; + } +} + +void MY_PlrStringXY(int x, int y, int x2, const char *pszStr, char col, int base) +{ + int nOffset, width, w, cw; + BYTE c; + const char *s; + + nOffset = x + SCREEN_X + PitchTbl[y + SCREEN_Y]; + width = x2 - x + 1; + w = 0; + cw = 0; + + s = pszStr; + while(*s != '\0') { + c = gbFontTransTbl[(BYTE)*s]; + s++; + c = fontframe[c]; + cw += fontkern[c] + base; + } + if(cw < width) { + w = (width - cw) >> 1; + } + + nOffset += w; + while(*pszStr != '\0') { + c = gbFontTransTbl[(BYTE)*pszStr]; + pszStr++; + c = fontframe[c]; + w += fontkern[c] + base; + if(c != 0 && w < width) { + PrintChar(nOffset, c, col); + } + nOffset += fontkern[c] + base; + } +} + +void CheckLvlBtn() +{ + if(lvlbtndown) { + return; + } + + if(MouseX >= 40 && MouseX <= 81 && MouseY >= 313 && MouseY <= 335) { + lvlbtndown = 1; + } +} + +void ReleaseLvlBtn() +{ + if(MouseX >= 40 && MouseX <= 81 && MouseY >= 313 && MouseY <= 335) { + chrflag = 1; + } + + lvlbtndown = 0; +} + +void DrawLevelUpIcon() +{ + int nCel; + + if(stextflag) { + return; + } + + if(lvlbtndown) { + nCel = 3; + } else { + nCel = 2; + } + ADD_PlrStringXY(0, 303, 120, "Level Up", COL_WHITE); + CelDecodeOnly(104, 495, (BYTE *)pChrButtons, nCel, 41); +} + +void CheckChrBtns() +{ + int i, pc, x2, y2; + + if(chrbtnactive) { + return; + } + if(plr[myplr]._pStatPts == 0) { + return; + } + + pc = plr[myplr]._pClass; + for(i = 0; i < 4; i++) { + switch(i) { + case 0: + if(plr[myplr]._pBaseStr >= MaxStats[pc][0]) { + continue; + } + break; + case 1: + if(plr[myplr]._pBaseMag >= MaxStats[pc][1]) { + continue; + } + break; + case 2: + if(plr[myplr]._pBaseDex >= MaxStats[pc][2]) { + continue; + } + break; + case 3: + if(plr[myplr]._pBaseVit >= MaxStats[pc][3]) { + continue; + } + break; + default: + continue; + } + x2 = attribute_inc_rects[i][0] + attribute_inc_rects[i][2]; + y2 = attribute_inc_rects[i][1] + attribute_inc_rects[i][3]; + if(MouseX >= attribute_inc_rects[i][0] && MouseX <= x2 + && MouseY >= attribute_inc_rects[i][1] && MouseY <= y2) { + chrbtn[i] = 1; + chrbtnactive = 1; + } + } +} + +void ReleaseChrBtns() +{ + int i; + + chrbtnactive = 0; + + for(i = 0; i < 4; i++) { + if(!chrbtn[i]) { + continue; + } + chrbtn[i] = 0; + if(MouseX < attribute_inc_rects[i][0]) { + continue; + } + if(MouseX > attribute_inc_rects[i][0] + attribute_inc_rects[i][2]) { + continue; + } + if(MouseY < attribute_inc_rects[i][1]) { + continue; + } + if(MouseY > attribute_inc_rects[i][1] + attribute_inc_rects[i][3]) { + continue; + } + switch(i) { + case ATTRIB_STR: + NetSendCmdParam1(TRUE, CMD_ADDSTR, 1); + plr[myplr]._pStatPts--; + break; + case ATTRIB_MAG: + NetSendCmdParam1(TRUE, CMD_ADDMAG, 1); + plr[myplr]._pStatPts--; + break; + case ATTRIB_DEX: + NetSendCmdParam1(TRUE, CMD_ADDDEX, 1); + plr[myplr]._pStatPts--; + break; + case ATTRIB_VIT: + NetSendCmdParam1(TRUE, CMD_ADDVIT, 1); + plr[myplr]._pStatPts--; + break; + } + } +} + +void DrawDurIcon() +{ + int x; + PlayerStruct *p; + + if((chrflag || questlog) && (invflag || sbookflag)) { + return; + } + + x = 656; + if(invflag || sbookflag) { + x -= 320; + } + + p = &plr[myplr]; + x = DrawDurIcon4Item(&p->InvBody[0], x, 4); + x = DrawDurIcon4Item(&p->InvBody[6], x, 3); + x = DrawDurIcon4Item(&p->InvBody[4], x, 0); + x = DrawDurIcon4Item(&p->InvBody[5], x, 0); +} + +int DrawDurIcon4Item(const ItemStruct *pItem, int x, int c) +{ + if(pItem->_itype == -1) { + return x; + } + if(pItem->_iDurability > 5) { + return x; + } + + if(c == 0) { + if(pItem->_iClass == ICLASS_WEAPON) { + switch(pItem->_itype) { + case ITYPE_SWORD: + c = 2; + break; + case ITYPE_AXE: + c = 6; + break; + case ITYPE_BOW: + c = 7; + break; + case ITYPE_MACE: + c = 5; + break; + case ITYPE_STAFF: + c = 8; + break; + } + } else { + c = 1; + } + } + if(pItem->_iDurability > 2) { + c += 8; + } + + CelDecodeOnly(x, 495, (BYTE *)pDurIcons, c, 32); + return x - 40; +} + +void RedBack() +{ + int idx; + + if(light4flag) { + idx = 1536; + } else { + idx = 4608; + } + + /// ASSERT: assert(gpBuffer); + +#ifdef USE_ASM + if(leveltype != DTYPE_HELL) { + __asm { + mov edi, gpBuffer + add edi, SCREENXY(0, 0) + mov ebx, pLightTbl + add ebx, idx + mov edx, 352 + lx_label1: + mov ecx, 640 + lx_label2: + mov al, [edi] + xlat + stosb + loop lx_label2 + add edi, 768 - 640 + dec edx + jnz lx_label1 + } + } else { + __asm { + mov edi, gpBuffer + add edi, SCREENXY(0, 0) + mov ebx, pLightTbl + add ebx, idx + mov edx, 352 + l4_label1: + mov ecx, 640 + l4_label2: + mov al, [edi] + cmp al, 32 + jb l4_label3 + xlat + l4_label3: + stosb + loop l4_label2 + add edi, 768 - 640 + dec edx + jnz l4_label1 + } + } +#else + int w, h; + BYTE *dst, *tbl; + + if(leveltype != DTYPE_HELL) { + dst = &gpBuffer[SCREENXY(0, 0)]; + tbl = &pLightTbl[idx]; + for(h = 352; h != 0; h--, dst += 768 - 640) { + for(w = 640; w != 0; w--) { + *dst = tbl[*dst]; + dst++; + } + } + } else { + dst = &gpBuffer[SCREENXY(0, 0)]; + tbl = &pLightTbl[idx]; + for(h = 352; h != 0; h--, dst += 768 - 640) { + for(w = 640; w != 0; w--) { + if(*dst >= 32) { + *dst = tbl[*dst]; + } + dst++; + } + } + } +#endif +} + +char GetSBookTrans(int ii, BOOL townok) +{ + char st, sl; + + st = RSPLTYPE_SPELL; + if(plr[myplr]._pISpells64 & (__int64)1 << (ii - 1)) { + st = RSPLTYPE_CHARGES; + } + if(plr[myplr]._pAblSpells64 & 1 << (ii - 1)) { /// BUGFIX: missing (__int64) + st = RSPLTYPE_SKILL; + } + if(st == RSPLTYPE_SPELL) { + if(!CheckSpell(myplr, ii, RSPLTYPE_SPELL, TRUE)) { + st = RSPLTYPE_INVALID; + } + sl = plr[myplr]._pSplLvl[ii] + plr[myplr]._pISplLvlAdd; + if(sl <= 0) { + st = RSPLTYPE_INVALID; + } + } + if(townok && currlevel == 0 && st != RSPLTYPE_INVALID && !spelldata[ii].sTownSpell) { + st = RSPLTYPE_INVALID; + } + + return st; +} + +void DrawSpellBook() +{ + int i, ii, x, y, mind, maxd, c, v; + char st; + __int64 tspls; + + CelDecodeOnly(384, 511, (BYTE *)pSpellBkCel, 1, 320); + x = 76 * sbooktab + 391; + CelDecodeOnly(x, 508, (BYTE *)pSBkBtnCel, sbooktab + 1, 76); + + y = 215; + tspls = plr[myplr]._pMemSpells64 | plr[myplr]._pISpells64 | plr[myplr]._pAblSpells64; + + for(i = 1; i < 8; i++) { /* redundant, use 'i = 0; i < 7' */ + ii = SpellPages[sbooktab][i - 1]; + if(ii != -1 && tspls & (__int64)1 << (ii - 1)) { + st = GetSBookTrans(ii, TRUE); + SetSpellTrans(st); + DrawSpellCel(395, y, (BYTE *)pSBkIconCels, SpellITbl[ii], 37); + if(ii == plr[myplr]._pRSpell && st == plr[myplr]._pRSplType) { + SetSpellTrans(RSPLTYPE_SKILL); + DrawSpellCel(395, y, (BYTE *)pSBkIconCels, 43, 37); + } + PrintSBookStr(10, y - 23, FALSE, spelldata[ii].sNameText, COL_WHITE); + st = GetSBookTrans(ii, FALSE); + switch(st) { + case RSPLTYPE_SKILL: + strcpy(tempstr, "Skill"); + break; + case RSPLTYPE_CHARGES: + sprintf(tempstr, "Staff (%i charges)", plr[myplr].InvBody[4]._iCharges); + break; + default: + c = GetManaAmount(myplr, ii) >> 6; + GetDamageAmt(ii, &mind, &maxd); + if(mind != -1) { + sprintf(tempstr, "Mana: %i Dam: %i - %i", c, mind, maxd); + } else { + sprintf(tempstr, "Mana: %i Dam: n/a", c); + } + if(ii == SPL_BONESPIRIT) { + sprintf(tempstr, "Mana: %i Dam: 1/3 tgt hp", c); + } + PrintSBookStr(10, y - 1, FALSE, tempstr, COL_WHITE); + v = plr[myplr]._pSplLvl[ii] + plr[myplr]._pISplLvlAdd; + if(v < 0) { + v = 0; + } + if(v == 0) { + sprintf(tempstr, "Spell Level 0 - Unusable"); + } else { + sprintf(tempstr, "Spell Level %i", v); + } + break; + } + PrintSBookStr(10, y - 12, FALSE, tempstr, COL_WHITE); + } + y += 43; + } +} + +void PrintSBookStr(int x, int y, BOOL cjustflag, const char *pszStr, char col) +{ + int nOffset, w, cw; + BYTE c; + const char *s; + + nOffset = x + PitchTbl[y] + 440; + w = 0; + + if(cjustflag) { + cw = 0; + s = pszStr; + while(*s != '\0') { + c = gbFontTransTbl[(BYTE)*s]; + s++; + c = fontframe[c]; + cw += fontkern[c] + 1; + } + if(cw < 222) { + w = (222 - cw) >> 1; + } + nOffset += w; + } + + while(*pszStr != '\0') { + c = gbFontTransTbl[(BYTE)*pszStr]; + pszStr++; + c = fontframe[c]; + w += fontkern[c] + 1; + if(c != 0 && w <= 222) { + PrintChar(nOffset, c, col); + } + nOffset += fontkern[c] + 1; + } +} + +void CheckSBook() +{ + int ii; + char st; + __int64 tspls; + + if(MouseX >= 331 && MouseX < 368 && MouseY >= 18 && MouseY < 314) { + ii = (MouseY - 18) / 43; + ii = SpellPages[sbooktab][ii]; + tspls = plr[myplr]._pMemSpells64 | plr[myplr]._pISpells64 | plr[myplr]._pAblSpells64; + if(ii != -1 && tspls & (__int64)1 << (ii - 1)) { + st = RSPLTYPE_SPELL; + if(plr[myplr]._pISpells64 & (__int64)1 << (ii - 1)) { + st = RSPLTYPE_CHARGES; + } + if(plr[myplr]._pAblSpells64 & (__int64)1 << (ii - 1)) { + st = RSPLTYPE_SKILL; + } + plr[myplr]._pRSpell = ii; + plr[myplr]._pRSplType = st; + force_redraw = 255; + } + } + if(MouseX >= 327 && MouseX < 633 && MouseY >= 320 && MouseY < 349) { /// BUGFIX: change `< 633` to `< 631` + sbooktab = (MouseX - 327) / 76; + } +} + +const char *get_pieces_str(int nGold) +{ + if(nGold == 1) { + return "piece"; + } else { + return "pieces"; + } +} + +void DrawGoldSplit(int amount) +{ + int i, sx; + BYTE c; + + sx = 0; + + CelDecodeOnly(415, 338, (BYTE *)pGBoxBuff, 1, 261); + sprintf(tempstr, "You have %u gold", initialDropGoldValue); + ADD_PlrStringXY(366, 87, 600, tempstr, COL_GOLD); + sprintf(tempstr, "%s. How many do", get_pieces_str(initialDropGoldValue)); + ADD_PlrStringXY(366, 103, 600, tempstr, COL_GOLD); + ADD_PlrStringXY(366, 121, 600, "you want to remove?", COL_GOLD); + + if(amount > 0) { + sprintf(tempstr, "%u", amount); + PrintGameStr(388, 140, tempstr, COL_WHITE); + for(i = 0; i < tempstr[i]; i++) { + c = gbFontTransTbl[(BYTE)tempstr[i]]; + c = fontframe[c]; + sx += fontkern[c] + 1; + } + sx += 452; + } else { + sx = 450; + } + + CelDecodeOnly(sx, 300, (BYTE *)pSPentSpnCels, frame_4B8800, 12); + frame_4B8800 = (frame_4B8800 & 7) + 1; +} + +void control_drop_gold(char vkey) +{ + int l, l2; + char split[6]; + + if(plr[myplr]._pHitPoints >> 6 <= 0) { + dropGoldFlag = 0; + dropGoldValue = 0; + return; + } + + memset(split, 0, sizeof(split)); + _itoa(dropGoldValue, split, 10); + + if(vkey == VK_RETURN) { + if(dropGoldValue > 0) { + control_remove_gold(myplr, initialDropGoldIndex); + } + dropGoldFlag = 0; + return; + } + if(vkey == VK_ESCAPE) { + dropGoldFlag = 0; + dropGoldValue = 0; + return; + } + if(vkey == VK_BACK) { + l = strlen(split); + split[l - 1] = '\0'; + dropGoldValue = atoi(split); + return; + } + if(vkey - '0' >= 0 && vkey - '0' <= 9) { + if(dropGoldValue == 0 && atoi(split) > initialDropGoldValue) { + split[0] = vkey; + } else { + l2 = strlen(split); + split[l2] = vkey; + if(atoi(split) > initialDropGoldValue || strlen(split) > strlen(split)) { /// BUGFIX: 'strlen(split) > 5'? + return; + } + } + dropGoldValue = atoi(split); + return; + } +} + +void control_remove_gold(int pnum, int ii) +{ + int i; + + if(ii <= 46) { + i = ii - 7; + plr[pnum].InvList[i]._ivalue -= dropGoldValue; + if(plr[pnum].InvList[i]._ivalue > 0) { + SetGoldCurs(pnum, i); + } else { + RemoveInvItem(pnum, i); + } + } else { + i = ii - 47; + plr[pnum].SpdList[i]._ivalue -= dropGoldValue; + if(plr[pnum].SpdList[i]._ivalue > 0) { + SetSpdbarGoldCurs(pnum, i); + } else { + RemoveSpdBarItem(pnum, i); + } + } + + SetPlrHandItem(&plr[pnum].HoldItem, IDI_GOLD); + GetGoldSeed(pnum, &plr[pnum].HoldItem); + plr[pnum].HoldItem._ivalue = dropGoldValue; + plr[pnum].HoldItem._iStatFlag = 1; + control_set_gold_curs(pnum); + plr[pnum]._pGold = CalculateGold(pnum); + dropGoldValue = 0; +} + +void control_set_gold_curs(int pnum) +{ + if(plr[pnum].HoldItem._ivalue >= 2500) { + plr[pnum].HoldItem._iCurs = 6; + } else if(plr[pnum].HoldItem._ivalue <= 1000) { + plr[pnum].HoldItem._iCurs = 4; + } else { + plr[pnum].HoldItem._iCurs = 5; + } + + SetCursor_(plr[pnum].HoldItem._iCurs + 12); +} + +void DrawTalkPan() +{ + int i, x, nOffset, btn, col, nCel; + char *s; + + if(!talkflag) { + return; + } + + /// ASSERT: assert(gpBuffer); + + DrawPanelBox(175, sgbPlrTalkTbl + 20, 294, 5, 175 + SCREEN_X, 356 + SCREEN_Y); + for(i = 0; i < 10; i++) { + x = i >> 1; + DrawPanelBox(x + 175, sgbPlrTalkTbl + i + 25, 293 - i, 1, x + 175 + SCREEN_X, i + 361 + SCREEN_Y); + } + DrawPanelBox(185, sgbPlrTalkTbl + 35, 274, 30, 185 + SCREEN_X, 371 + SCREEN_Y); + DrawPanelBox(180, sgbPlrTalkTbl + 65, 284, 5, 180 + SCREEN_X, 401 + SCREEN_Y); + for(i = 0; i < 10; i++) { + DrawPanelBox(180, sgbPlrTalkTbl + i + 70, i + 284, 1, 180 + SCREEN_X, i + 406 + SCREEN_Y); + } + DrawPanelBox(170, sgbPlrTalkTbl + 80, 310, 55, 170 + SCREEN_X, 416 + SCREEN_Y); + + s = sgszTalkMsg; + for(i = 0; i < 39; i += 13) { + s = control_print_talk_msg(s, 0, i, &nOffset, COL_WHITE); + if(s == NULL) { + break; + } + } + if(s != NULL) { + s[0] = '\0'; + } + CelDecDatOnly(&gpBuffer[nOffset], (BYTE *)pSPentSpnCels, frame, 12); + frame = (frame & 7) + 1; + + btn = 0; + for(i = 0; i < MAX_PLRS; i++) { + if(i == myplr) { + continue; + } + if(byte_4B894C[i]) { + col = COL_GOLD; + if(talkbtndown[btn]) { + if(btn == 0) { + nCel = 3; + } else { + nCel = 4; + } + CelDecodeOnly(236, 18 * btn + 596, (BYTE *)pTalkBtns, nCel, 61); + } + } else { + col = COL_RED; + if(btn == 0) { + nCel = 1; + } else { + nCel = 2; + } + if(talkbtndown[btn]) { + nCel += 4; + } + CelDecodeOnly(236, 18 * btn + 596, (BYTE *)pTalkBtns, nCel, 61); + } + if(plr[i].plractive) { + control_print_talk_msg(plr[i]._pName, 46, 18 * btn + 60, &nOffset, col); + } + btn++; + } +} + +char *control_print_talk_msg(char *msg, int x, int y, int *pnOffset, int col) +{ + int w; + BYTE c; + + x += 264; + w = x; + *pnOffset = x + PitchTbl[y + 534]; + + while(*msg != '\0') { + c = gbFontTransTbl[(BYTE)*msg]; + c = fontframe[c]; + w += fontkern[c] + 1; + if(w > 514) { + return msg; + } + msg++; + if(c != 0) { + PrintChar(*pnOffset, c, col); + } + *pnOffset += fontkern[c] + 1; + } + + return NULL; +} + +BOOL control_check_talk_btn() +{ + int i; + + if(!talkflag) { + return FALSE; + } + if(MouseX < 172) { + return FALSE; + } + if(MouseY < 421) { + return FALSE; + } + if(MouseX > 233) { + return FALSE; + } + if(MouseY > 475) { + return FALSE; + } + + for(i = 0; i < 3; i++) { + talkbtndown[i] = 0; + } + + i = (MouseY - 421) / 18; + talkbtndown[i] = 1; + return TRUE; +} + +void control_release_talk_btn() +{ + int i, y; + + if(!talkflag) { + return; + } + + for(i = 0; i < 3; i++) { + talkbtndown[i] = 0; + } + + if(MouseX < 172) { + return; + } + if(MouseY < 421) { + return; + } + if(MouseX > 233) { + return; + } + if(MouseY > 475) { + return; + } + + y = (MouseY - 421) / 18; + for(i = 0; i < 4 && y != -1; i++) { + if(i != myplr) { + y--; + } + } + if(i <= 4) { + byte_4B894C[i - 1] = !byte_4B894C[i - 1]; + } +} + +void control_reset_talk_msg(char *msg) +{ + int i, msk; + + msk = 0; + for(i = 0; i < 4; i++) { + if(byte_4B894C[i]) { + msk |= 1 << i; + } + } + + if(!msgcmd_add_server_cmd_W(sgszTalkMsg)) { /// BUGFIX: supposed to use unused arg 'msg' here? + NetSendCmdString(msk, sgszTalkMsg); + } +} + +void control_type_message() +{ + int i; + + if(gbMaxPlayers == 1) { + return; + } + + talkflag = 1; + sgbPlrTalkTbl = 144; + sgszTalkMsg[0] = '\0'; + frame = 1; + + for(i = 0; i < 3; i++) { + talkbtndown[i] = 0; + } + + force_redraw = 255; + sgbTalkSavePos = sgbNextTalkSave; +} + +void control_reset_talk() +{ + talkflag = 0; + sgbPlrTalkTbl = 0; + force_redraw = 255; +} + +BOOL control_talk_last_key(int vkey) +{ + int l; + + if(gbMaxPlayers == 1) { + return FALSE; + } + if(!talkflag) { + return FALSE; + } + if((DWORD)vkey < VK_SPACE) { + return FALSE; + } + + l = strlen(sgszTalkMsg); + if(l < 78) { + sgszTalkMsg[l] = vkey; + sgszTalkMsg[l + 1] = '\0'; + } + + return TRUE; +} + +BOOL control_presskeys(int vkey) +{ + int l; + + if(gbMaxPlayers == 1) { + return FALSE; + } + if(!talkflag) { + return FALSE; + } + if(vkey == VK_SPACE) { + return TRUE; + } + + if(vkey == VK_ESCAPE) { + control_reset_talk(); + } else if(vkey == VK_RETURN) { + control_press_enter(); + } else if(vkey == VK_BACK) { + l = strlen(sgszTalkMsg); + if(l > 0) { + sgszTalkMsg[l - 1] = '\0'; + } + } else if(vkey == VK_DOWN) { + control_up_down(1); + } else if(vkey == VK_UP) { + control_up_down(-1); + } else { + return FALSE; + } + + return TRUE; +} + +void control_press_enter() +{ + int i; + BYTE save; + + if(sgszTalkMsg[0] != '\0') { + control_reset_talk_msg(sgszTalkMsg); + for(i = 0; i < 8; i++) { + if(strcmp(sgszTalkSave[i], sgszTalkMsg) == 0) { + break; + } + } + if(i >= 8) { + strcpy(sgszTalkSave[sgbNextTalkSave], sgszTalkMsg); + sgbNextTalkSave = (sgbNextTalkSave + 1) & 7; + } else { + save = (sgbNextTalkSave - 1) & 7; + if(i != save) { + strcpy(sgszTalkSave[i], sgszTalkSave[save]); + strcpy(sgszTalkSave[save], sgszTalkMsg); + } + } + sgbTalkSavePos = sgbNextTalkSave; + sgszTalkMsg[0] = '\0'; + } + + control_reset_talk(); +} + +void control_up_down(int v) +{ + int i; + + for(i = 0; i < 8; i++) { + sgbTalkSavePos = (sgbTalkSavePos + v) & 7; + if(sgszTalkSave[sgbTalkSavePos][0] != '\0') { + strcpy(sgszTalkMsg, sgszTalkSave[sgbTalkSavePos]); + return; + } + } +} diff --git a/2020_03_31/Source/control.h b/2020_03_31/Source/control.h new file mode 100644 index 00000000..adae98a4 --- /dev/null +++ b/2020_03_31/Source/control.h @@ -0,0 +1,143 @@ +//HEADER_GOES_HERE +#ifndef __CONTROL_H__ +#define __CONTROL_H__ + +extern BYTE sgbNextTalkSave; // weak +extern BYTE sgbTalkSavePos; // weak +extern void *pDurIcons; +extern void *pChrButtons; +extern int drawhpflag; // idb +extern int dropGoldFlag; // weak +extern int panbtn[8]; +extern int chrbtn[4]; +extern void *pMultiBtns; +extern void *pPanelButtons; +extern void *pChrPanel; +extern int lvlbtndown; // weak +extern char sgszTalkSave[8][80]; +extern int dropGoldValue; // idb +extern int drawmanaflag; // idb +extern int chrbtnactive; // weak +extern char sgszTalkMsg[80]; +extern BYTE *pPanelText; +extern int frame_4B8800; // idb +extern BYTE *pLifeBuff; +extern BYTE *pBtmBuff; +extern void *pTalkBtns; +extern int pstrjust[4]; +extern int pnumlines; // idb +extern int pinfoflag; // weak +extern int talkbtndown[3]; +extern int pSpell; // weak +extern BYTE *pManaBuff; +extern char infoclr; // weak +extern int sgbPlrTalkTbl; // weak // should be char [4] +extern void *pGBoxBuff; +extern void *pSBkBtnCel; +extern char tempstr[256]; +extern char byte_4B894C[4]; +extern int sbooktab; // weak +extern int pSplType; // weak +extern int frame; // idb +extern int initialDropGoldIndex; // idb +extern int talkflag; // weak +extern void *pSBkIconCels; +extern int sbookflag; // weak +extern int chrflag; +extern int drawbtnflag; // idb +extern void *pSpellBkCel; +extern char infostr[256]; +extern int numpanbtns; // weak +extern void *pStatusPanel; +extern char panelstr[4][64]; +extern int panelflag; // weak +extern BYTE SplTransTbl[256]; +extern int initialDropGoldValue; // idb +extern void *pSpellCels; +extern int panbtndown; // weak +extern void *pTalkPanel; // idb +extern int spselflag; // weak + +void DrawSpellCel(int xp, int yp, BYTE *pCelBuff, int nCel, int w); +void SetSpellTrans(char t); +void DrawSpell(); +void DrawSpellList(); +void SetSpell(); +void SetSpeedSpell(int slot); +void ToggleSpell(int slot); +void PrintChar(int nOffset, int nCel, char col); +void AddPanelString(const char *str, BOOL just); +void ClearPanel(); +void DrawPanelBox(int x, int y, int w, int h, int sx, int sy); +// void InitPanelStr(); +void SetFlaskHeight(BYTE *pCelBuff, int min, int max, int x, int y); +void DrawFlask(BYTE *pCelBuff, int w, int nSrcOff, BYTE *pBuff, int nDstOff, int h); +void DrawLifeFlask(); +void UpdateLifeFlask(); +void DrawManaFlask(); +void control_update_life_mana(); +void UpdateManaFlask(); +void InitControlPan(); +void DrawCtrlPan(); +void DrawCtrlBtns(); +void DoSpeedBook(); +void DoPanBtn(); +void control_set_button_down(int btn_id); +void control_check_btn_press(); +void DoAutoMap(); +void CheckPanelInfo(); +void CheckBtnUp(); +void FreeControlPan(); +BOOL control_WriteStringToBuffer(const char *str); +void DrawInfoBox(); +void PrintInfo(); +void CPrintString(int No, char *pszStr, BOOL Just, int lines); +void PrintGameStr(int x, int y, const char *pszStr, int col); +void DrawChr(); +void ADD_PlrStringXY(int x, int y, int x2, const char *pszStr, char col); +void MY_PlrStringXY(int x, int y, int x2, const char *pszStr, char col, int base); +void CheckLvlBtn(); +void ReleaseLvlBtn(); +void DrawLevelUpIcon(); +void CheckChrBtns(); +void ReleaseChrBtns(); +void DrawDurIcon(); +int DrawDurIcon4Item(const ItemStruct *pItem, int x, int c); +void RedBack(); +char GetSBookTrans(int ii, BOOL townok); +void DrawSpellBook(); +void PrintSBookStr(int x, int y, BOOL cjustflag, const char *pszStr, char col); +void CheckSBook(); +const char *get_pieces_str(int nGold); +void DrawGoldSplit(int amount); +void control_drop_gold(char vkey); +void control_remove_gold(int pnum, int ii); +void control_set_gold_curs(int pnum); +void DrawTalkPan(); +char *control_print_talk_msg(char *msg, int x, int y, int *pnOffset, int col); +BOOL control_check_talk_btn(); +void control_release_talk_btn(); +void control_reset_talk_msg(char *msg); +void control_type_message(); +void control_reset_talk(); +BOOL control_talk_last_key(int vkey); +BOOL control_presskeys(int vkey); +void control_press_enter(); +void control_up_down(int v); + +/* rdata */ +extern const unsigned char fontframe[128]; +extern const unsigned char fontkern[68]; +extern const int lineoffset[5][5]; +extern const unsigned char gbFontTransTbl[256]; + +/* data */ + +extern char SpellITbl[37]; +extern int PanBtnPos[8][5]; +extern char *PanBtnHotKey[8]; +extern char *PanBtnStr[8]; +extern int attribute_inc_rects[4][4]; +extern int SpellPages[6][7]; + +#endif /* __CONTROL_H__ */ diff --git a/2020_03_31/Source/cursor.cpp b/2020_03_31/Source/cursor.cpp new file mode 100644 index 00000000..793502ce --- /dev/null +++ b/2020_03_31/Source/cursor.cpp @@ -0,0 +1,920 @@ +#include "diablo.h" + +int cursH; // weak +int icursH28; // idb +int cursW; // idb +int pcursmonst; // idb +int icursW28; // idb +BYTE *pCursCels; +int icursH; // weak +char pcursinvitem; // weak +int icursW; // weak +char pcursitem; // weak +char pcursobj; // weak +char pcursplr; // weak +int cursmx; +int cursmy; +int pcurstemp; // weak +int pcurs; // idb + + +/* rdata */ +const int InvItemWidth[180] = +{ + 0, + 33, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 23, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56 +}; +const int InvItemHeight[180] = +{ + 0, + 29, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 35, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 56, + 56, + 56, + 56, + 56, + 56, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 56, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84, + 84 +}; + +void InitCursor() +{ + pCursCels = DiabLoad("Data\\Inv\\Objcurs.CEL", NULL, 'CRSR'); + ClearCursor(); +} + +void FreeCursor() +{ + void *v0; // ecx + + v0 = pCursCels; + pCursCels = 0; + mem_free_dbg(v0); + ClearCursor(); +} + +void SetICursor(int i) +{ + int v1; // ecx + + v1 = i; + icursW = InvItemWidth[v1]; + icursH = InvItemHeight[v1]; + icursW28 = icursW / 28; + icursH28 = icursH / 28; +} + +void SetCursor_(int i) +{ + int v1; // eax + + v1 = InvItemWidth[i]; + pcurs = i; + cursW = v1; + cursH = InvItemHeight[i]; + SetICursor(i); +} + +void InitLevelCursor() +{ + SetCursor_(CURSOR_HAND); + cursmx = ViewX; + cursmy = ViewY; + pcurstemp = -1; + pcursmonst = -1; + pcursobj = -1; + pcursitem = -1; + pcursplr = -1; + ClearCursor(); +} + +void CheckTown() +{ + int i, mx; + + for(i = 0; i < nummissiles; i++) { + mx = missileactive[i]; + if(missile[mx]._mitype == MIS_TOWN) { + if(cursmx == missile[mx]._mix - 1 && cursmy == missile[mx]._miy + || cursmx == missile[mx]._mix && cursmy == missile[mx]._miy - 1 + || cursmx == missile[mx]._mix - 1 && cursmy == missile[mx]._miy - 1 + || cursmx == missile[mx]._mix - 2 && cursmy == missile[mx]._miy - 1 + || cursmx == missile[mx]._mix - 2 && cursmy == missile[mx]._miy - 2 + || cursmx == missile[mx]._mix - 1 && cursmy == missile[mx]._miy - 2 + || cursmx == missile[mx]._mix && cursmy == missile[mx]._miy) { + trigflag = 1; + ClearPanel(); + strcpy(infostr, "Town Portal"); + sprintf(tempstr, "from %s", plr[missile[mx]._misource]._pName); + AddPanelString(tempstr, 1); + cursmx = missile[mx]._mix; + cursmy = missile[mx]._miy; + } + } + } +} + +void CheckRportal() +{ + int i, mx; + + for(i = 0; i < nummissiles; i++) { + mx = missileactive[i]; + if(missile[mx]._mitype == MIS_RPORTAL) { + if(cursmx == missile[mx]._mix - 1 && cursmy == missile[mx]._miy + || cursmx == missile[mx]._mix && cursmy == missile[mx]._miy - 1 + || cursmx == missile[mx]._mix - 1 && cursmy == missile[mx]._miy - 1 + || cursmx == missile[mx]._mix - 2 && cursmy == missile[mx]._miy - 1 + || cursmx == missile[mx]._mix - 2 && cursmy == missile[mx]._miy - 2 + || cursmx == missile[mx]._mix - 1 && cursmy == missile[mx]._miy - 2 + || cursmx == missile[mx]._mix && cursmy == missile[mx]._miy) { + trigflag = 1; + ClearPanel(); + strcpy(infostr, "Portal to"); + if(!setlevel) + strcpy(tempstr, "The Unholy Altar"); + else + strcpy(tempstr, "level 15"); + AddPanelString(tempstr, 1); + cursmx = missile[mx]._mix; + cursmy = missile[mx]._miy; + } + } + } +} + +void CheckCursMove() +{ + int i, sx, sy, mx, my, tx, ty, px, py, xx, yy, mi; + char bv; + BOOL flipflag, flipx, flipy; + + sx = MouseX; + sy = MouseY; + + if(chrflag || questlog) { + if(sx >= 160) { + sx -= 160; + } else { + sx = 0; + } + } else if(invflag || sbookflag) { + if(sx <= 320) { + sx += 160; + } else { + sx = 0; + } + } + if(sy > 351 && track_isscrolling()) { + sy = 351; + } + if(!zoomflag) { + sx >>= 1; + sy >>= 1; + } + + sx -= ScrollInfo._sxoff; + sy -= ScrollInfo._syoff; + + if(ScrollInfo._sdir != 0) { + sx += ((plr[myplr]._pVar6 + plr[myplr]._pxvel) >> 8) - (plr[myplr]._pVar6 >> 8); + sy += ((plr[myplr]._pVar7 + plr[myplr]._pyvel) >> 8) - (plr[myplr]._pVar7 >> 8); + } + + if(sx < 0) { + sx = 0; + } + if(sx >= 640) { + sx = 640; + } + if(sy < 0) { + sy = 0; + } + if(sy >= 480) { + sy = 480; + } + + tx = sx >> 6; + ty = sy >> 5; + px = sx & 0x3F; + py = sy & 0x1F; + mx = ViewX + tx + ty - (zoomflag ? 10 : 5); + my = ViewY + ty - tx; + + flipy = py < px >> 1; + if(flipy) { + my--; + } + flipx = py >= 32 - (px >> 1); + if(flipx) { + mx++; + } + + if(mx < 0) { + mx = 0; + } + if(mx >= MAXDUNX) { + mx = MAXDUNX - 1; + } + if(my < 0) { + my = 0; + } + if(my >= MAXDUNY) { + my = MAXDUNY - 1; + } + + flipflag = flipy && flipx || (flipy || flipx) && px < 32; + + pcurstemp = pcursmonst; + pcursmonst = -1; + pcursobj = -1; + pcursitem = -1; + if(pcursinvitem != -1) { + drawsbarflag = 1; + } + pcursinvitem = -1; + pcursplr = -1; + uitemflag = 0; + panelflag = 0; + trigflag = 0; + + if(plr[myplr]._pInvincible) { + return; + } + if(pcurs >= CURSOR_FIRSTITEM || spselflag) { + cursmx = mx; + cursmy = my; + return; + } + if(MouseY > 352) { + CheckPanelInfo(); + return; + } + if(doomflag) { + return; + } + if(invflag && MouseX > 320) { + pcursinvitem = CheckInvHLight(); + return; + } + if(sbookflag && MouseX > 320) { + return; + } + if((chrflag || questlog) && MouseX < 320) { + return; + } + + if(leveltype != DTYPE_TOWN) { + if(pcurstemp != -1) { + if(!flipflag && dMonster[mx + 2][my + 1] != 0 && dFlags[mx + 2][my + 1] & 0x40) { + mi = dMonster[mx + 2][my + 1] > 0 ? dMonster[mx + 2][my + 1] - 1 : -(dMonster[mx + 2][my + 1] + 1); + if(mi == pcurstemp && monster[mi]._mhitpoints >> 6 > 0 && monster[mi].MData->mSelFlag & 4) { + cursmx = mx + 1; /// BUGFIX: 'mx + 2' + cursmy = my + 2; /// BUGFIX: 'my + 1' + pcursmonst = mi; + } + } + if(flipflag && dMonster[mx + 1][my + 2] != 0 && dFlags[mx + 1][my + 2] & 0x40) { + mi = dMonster[mx + 1][my + 2] > 0 ? dMonster[mx + 1][my + 2] - 1 : -(dMonster[mx + 1][my + 2] + 1); + if(mi == pcurstemp && monster[mi]._mhitpoints >> 6 > 0 && monster[mi].MData->mSelFlag & 4) { + cursmx = mx + 1; + cursmy = my + 2; + pcursmonst = mi; + } + } + if(dMonster[mx + 2][my + 2] != 0 && dFlags[mx + 2][my + 2] & 0x40) { + mi = dMonster[mx + 2][my + 2] > 0 ? dMonster[mx + 2][my + 2] - 1 : -(dMonster[mx + 2][my + 2] + 1); + if(mi == pcurstemp && monster[mi]._mhitpoints >> 6 > 0 && monster[mi].MData->mSelFlag & 4) { + cursmx = mx + 2; + cursmy = my + 2; + pcursmonst = mi; + } + } + if(!flipflag && dMonster[mx + 1][my] != 0 && dFlags[mx + 1][my] & 0x40) { + mi = dMonster[mx + 1][my] > 0 ? dMonster[mx + 1][my] - 1 : -(dMonster[mx + 1][my] + 1); + if(mi == pcurstemp && monster[mi]._mhitpoints >> 6 > 0 && monster[mi].MData->mSelFlag & 2) { + cursmx = mx + 1; + cursmy = my; + pcursmonst = mi; + } + } + if(flipflag && dMonster[mx][my + 1] != 0 && dFlags[mx][my + 1] & 0x40) { + mi = dMonster[mx][my + 1] > 0 ? dMonster[mx][my + 1] - 1 : -(dMonster[mx][my + 1] + 1); + if(mi == pcurstemp && monster[mi]._mhitpoints >> 6 > 0 && monster[mi].MData->mSelFlag & 2) { + cursmx = mx; + cursmy = my + 1; + pcursmonst = mi; + } + } + if(dMonster[mx][my] != 0 && dFlags[mx][my] & 0x40) { + mi = dMonster[mx][my] > 0 ? dMonster[mx][my] - 1 : -(dMonster[mx][my] + 1); + if(mi == pcurstemp && monster[mi]._mhitpoints >> 6 > 0 && monster[mi].MData->mSelFlag & 1) { + cursmx = mx; + cursmy = my; + pcursmonst = mi; + } + } + if(dMonster[mx + 1][my + 1] != 0 && dFlags[mx + 1][my + 1] & 0x40) { + mi = dMonster[mx + 1][my + 1] > 0 ? dMonster[mx + 1][my + 1] - 1 : -(dMonster[mx + 1][my + 1] + 1); + if(mi == pcurstemp && monster[mi]._mhitpoints >> 6 > 0 && monster[mi].MData->mSelFlag & 2) { + cursmx = mx + 1; + cursmy = my + 1; + pcursmonst = mi; + } + } + if(pcursmonst != -1 && monster[pcursmonst]._mFlags & 1) { + pcursmonst = -1; + cursmx = mx; + cursmy = my; + } + if(pcursmonst != -1 && monster[pcursmonst]._mFlags & 0x20) { + pcursmonst = -1; + } + if(pcursmonst != -1) { + return; + } + } + if(!flipflag && dMonster[mx + 2][my + 1] != 0 && dFlags[mx + 2][my + 1] & 0x40) { + mi = dMonster[mx + 2][my + 1] > 0 ? dMonster[mx + 2][my + 1] - 1 : -(dMonster[mx + 2][my + 1] + 1); + if(monster[mi]._mhitpoints >> 6 > 0 && monster[mi].MData->mSelFlag & 4) { + cursmx = mx + 2; + cursmy = my + 1; + pcursmonst = mi; + } + } + if(flipflag && dMonster[mx + 1][my + 2] != 0 && dFlags[mx + 1][my + 2] & 0x40) { + mi = dMonster[mx + 1][my + 2] > 0 ? dMonster[mx + 1][my + 2] - 1 : -(dMonster[mx + 1][my + 2] + 1); + if(monster[mi]._mhitpoints >> 6 > 0 && monster[mi].MData->mSelFlag & 4) { + cursmx = mx + 1; + cursmy = my + 2; + pcursmonst = mi; + } + } + if(dMonster[mx + 2][my + 2] != 0 && dFlags[mx + 2][my + 2] & 0x40) { + mi = dMonster[mx + 2][my + 2] > 0 ? dMonster[mx + 2][my + 2] - 1 : -(dMonster[mx + 2][my + 2] + 1); + if(monster[mi]._mhitpoints >> 6 > 0 && monster[mi].MData->mSelFlag & 4) { + cursmx = mx + 2; + cursmy = my + 2; + pcursmonst = mi; + } + } + if(!flipflag && dMonster[mx + 1][my] != 0 && dFlags[mx + 1][my] & 0x40) { + mi = dMonster[mx + 1][my] > 0 ? dMonster[mx + 1][my] - 1 : -(dMonster[mx + 1][my] + 1); + if(monster[mi]._mhitpoints >> 6 > 0 && monster[mi].MData->mSelFlag & 2) { + cursmx = mx + 1; + cursmy = my; + pcursmonst = mi; + } + } + if(flipflag && dMonster[mx][my + 1] != 0 && dFlags[mx][my + 1] & 0x40) { + mi = dMonster[mx][my + 1] > 0 ? dMonster[mx][my + 1] - 1 : -(dMonster[mx][my + 1] + 1); + if(monster[mi]._mhitpoints >> 6 > 0 && monster[mi].MData->mSelFlag & 2) { + cursmx = mx; + cursmy = my + 1; + pcursmonst = mi; + } + } + if(dMonster[mx][my] != 0 && dFlags[mx][my] & 0x40) { + mi = dMonster[mx][my] > 0 ? dMonster[mx][my] - 1 : -(dMonster[mx][my] + 1); + if(monster[mi]._mhitpoints >> 6 > 0 && monster[mi].MData->mSelFlag & 1) { + cursmx = mx; + cursmy = my; + pcursmonst = mi; + } + } + if(dMonster[mx + 1][my + 1] != 0 && dFlags[mx + 1][my + 1] & 0x40) { + mi = dMonster[mx + 1][my + 1] > 0 ? dMonster[mx + 1][my + 1] - 1 : -(dMonster[mx + 1][my + 1] + 1); + if(monster[mi]._mhitpoints >> 6 > 0 && monster[mi].MData->mSelFlag & 2) { + cursmx = mx + 1; + cursmy = my + 1; + pcursmonst = mi; + } + } + if(pcursmonst != -1 && monster[pcursmonst]._mFlags & 1) { + pcursmonst = -1; + cursmx = mx; + cursmy = my; + } + if(pcursmonst != -1 && monster[pcursmonst]._mFlags & 0x20) { + pcursmonst = -1; + } + } else { + if(!flipflag && dMonster[mx + 1][my] > 0) { + pcursmonst = dMonster[mx + 1][my] - 1; + cursmx = mx + 1; + cursmy = my; + } + if(flipflag && dMonster[mx][my + 1] > 0) { + pcursmonst = dMonster[mx][my + 1] - 1; + cursmx = mx; + cursmy = my + 1; + } + if(dMonster[mx][my] > 0) { + pcursmonst = dMonster[mx][my] - 1; + cursmx = mx; + cursmy = my; + } + if(dMonster[mx + 1][my + 1] > 0) { + pcursmonst = dMonster[mx + 1][my + 1] - 1; + cursmx = mx + 1; + cursmy = my + 1; + } + if(!towner[pcursmonst]._tSelFlag) { /// BUGFIX: Add check 'pcursmonst != -1' + pcursmonst = -1; + } + } + + if(pcursmonst == -1) { + if(!flipflag && dPlayer[mx + 1][my] != 0) { + bv = dPlayer[mx + 1][my] > 0 ? dPlayer[mx + 1][my] - 1 : -(dPlayer[mx + 1][my] + 1); + if(bv != myplr && plr[bv]._pHitPoints != 0) { + cursmx = mx + 1; + cursmy = my; + pcursplr = bv; + } + } + if(flipflag && dPlayer[mx][my + 1] != 0) { + bv = dPlayer[mx][my + 1] > 0 ? dPlayer[mx][my + 1] - 1 : -(dPlayer[mx][my + 1] + 1); + if(bv != myplr && plr[bv]._pHitPoints != 0) { + cursmx = mx; + cursmy = my + 1; + pcursplr = bv; + } + } + if(dPlayer[mx][my] != 0) { + bv = dPlayer[mx][my] > 0 ? dPlayer[mx][my] - 1 : -(dPlayer[mx][my] + 1); + if(bv != myplr) { + cursmx = mx; + cursmy = my; + pcursplr = bv; + } + } + if(dFlags[mx][my] & 4) { + for(i = 0; i < MAX_PLRS; i++) { + if(plr[i].WorldX == mx && plr[i].WorldY == my && i != myplr) { + cursmx = mx; + cursmy = my; + pcursplr = i; + } + } + } + if(pcurs == CURSOR_RESURRECT) { + for(xx = -1; xx < 2; xx++) { + for(yy = -1; yy < 2; yy++) { + if(dFlags[mx + xx][my + yy] & 4) { + for(i = 0; i < MAX_PLRS; i++) { + if(plr[i].WorldX == mx + xx && plr[i].WorldY == my + yy && i != myplr) { + cursmx = mx + xx; + cursmy = my + yy; + pcursplr = i; + } + } + } + } + } + } + if(dPlayer[mx + 1][my + 1] != 0) { + bv = dPlayer[mx + 1][my + 1] > 0 ? dPlayer[mx + 1][my + 1] - 1 : -(dPlayer[mx + 1][my + 1] + 1); + if(bv != myplr && plr[bv]._pHitPoints != 0) { + cursmx = mx + 1; + cursmy = my + 1; + pcursplr = bv; + } + } + } + if(pcursmonst == -1 && pcursplr == -1) { + if(!flipflag && dObject[mx + 1][my] != 0) { + bv = dObject[mx + 1][my] > 0 ? dObject[mx + 1][my] - 1 : -(dObject[mx + 1][my] + 1); + if(object[bv]._oSelFlag >= 2) { + cursmx = mx + 1; + cursmy = my; + pcursobj = bv; + } + } + if(flipflag && dObject[mx][my + 1] != 0) { + bv = dObject[mx][my + 1] > 0 ? dObject[mx][my + 1] - 1 : -(dObject[mx][my + 1] + 1); + if(object[bv]._oSelFlag >= 2) { + cursmx = mx; + cursmy = my + 1; + pcursobj = bv; + } + } + if(dObject[mx][my] != 0) { + bv = dObject[mx][my] > 0 ? dObject[mx][my] - 1 : -(dObject[mx][my] + 1); + if(object[bv]._oSelFlag == 1 || object[bv]._oSelFlag == 3) { + cursmx = mx; + cursmy = my; + pcursobj = bv; + } + } + if(dObject[mx + 1][my + 1] != 0) { + bv = dObject[mx + 1][my + 1] > 0 ? dObject[mx + 1][my + 1] - 1 : -(dObject[mx + 1][my + 1] + 1); + if(object[bv]._oSelFlag >= 2) { + cursmx = mx + 1; + cursmy = my + 1; + pcursobj = bv; + } + } + } + if(pcursplr == -1 && pcursobj == -1 && pcursmonst == -1) { + if(!flipflag && dItem[mx + 1][my] > 0) { + bv = dItem[mx + 1][my] - 1; + if(item[bv]._iSelFlag >= 2) { + cursmx = mx + 1; + cursmy = my; + pcursitem = bv; + } + } + if(flipflag && dItem[mx][my + 1] > 0) { + bv = dItem[mx][my + 1] - 1; + if(item[bv]._iSelFlag >= 2) { + cursmx = mx; + cursmy = my + 1; + pcursitem = bv; + } + } + if(dItem[mx][my] > 0) { + bv = dItem[mx][my] - 1; + if(item[bv]._iSelFlag == 1 || item[bv]._iSelFlag == 3) { + cursmx = mx; + cursmy = my; + pcursitem = bv; + } + } + if(dItem[mx + 1][my + 1] > 0) { + bv = dItem[mx + 1][my + 1] - 1; + if(item[bv]._iSelFlag >= 2) { + cursmx = mx + 1; + cursmy = my + 1; + pcursitem = bv; + } + } + if(pcursitem == -1) { + cursmx = mx; + cursmy = my; + CheckTrigForce(); + CheckTown(); + CheckRportal(); + } + } + + if(pcurs == CURSOR_IDENTIFY) { + pcursobj = -1; + pcursmonst = -1; + pcursitem = -1; + cursmx = mx; + cursmy = my; + } + if(pcursmonst != -1 && monster[pcursmonst]._mFlags & 0x20) { + pcursmonst = -1; + } +} diff --git a/2020_03_31/Source/cursor.h b/2020_03_31/Source/cursor.h new file mode 100644 index 00000000..735e47c1 --- /dev/null +++ b/2020_03_31/Source/cursor.h @@ -0,0 +1,36 @@ +//HEADER_GOES_HERE +#ifndef __CURSOR_H__ +#define __CURSOR_H__ + +extern int cursH; // weak +extern int icursH28; // idb +extern int cursW; // idb +extern int pcursmonst; // idb +extern int icursW28; // idb +extern BYTE *pCursCels; +extern int icursH; // weak +extern char pcursinvitem; // weak +extern int icursW; // weak +extern char pcursitem; // weak +extern char pcursobj; // weak +extern char pcursplr; // weak +extern int cursmx; +extern int cursmy; +extern int pcurstemp; // weak +extern int pcurs; // idb + +void InitCursor(); +void FreeCursor(); +void SetICursor(int i); +void SetCursor_(int i); +void NewCursor(int i); +void InitLevelCursor(); +void CheckTown(); +void CheckRportal(); +void CheckCursMove(); + +/* rdata */ +extern const int InvItemWidth[180]; +extern const int InvItemHeight[180]; + +#endif /* __CURSOR_H__ */ diff --git a/2020_03_31/Source/dead.cpp b/2020_03_31/Source/dead.cpp new file mode 100644 index 00000000..6eb2fcc3 --- /dev/null +++ b/2020_03_31/Source/dead.cpp @@ -0,0 +1,91 @@ +#include "diablo.h" + +int spurtndx; +DeadStruct dead[MAXDEAD]; +int stonendx; + +void InitDead() +{ + int mtypes[MAXMONSTERS]; + int i; + int nd; + int mi; + int d; + + for(i = 0; i < MAXMONSTERS; i++) + mtypes[i] = 0; + + nd = 0; + + for(i = 0; i < nummtypes; i++) { + if(!mtypes[Monsters[i].mtype]) { + for(d = 0; d < 8; d++) + dead[nd]._deadData[d] = Monsters[i].Anims[4].Frames[d]; + dead[nd]._deadFrame = Monsters[i].Anims[4].Rate; + dead[nd]._deadWidth = Monsters[i].flags_1; + dead[nd]._deadWidth2 = Monsters[i].flags_2; + dead[nd]._deadtrans = 0; + Monsters[i].mdeadval = nd + 1; + mtypes[Monsters[i].mtype] = nd + 1; + nd++; + } + } + + for(d = 0; d < 8; d++) + dead[nd]._deadData[d] = misfiledata[MFILE_BLODBUR].mAnimData[0]; + dead[nd]._deadFrame = 8; + dead[nd]._deadWidth = 128; + dead[nd]._deadWidth2 = 32; + dead[nd]._deadtrans = 0; + spurtndx = nd + 1; + nd++; + + for(d = 0; d < 8; d++) + dead[nd]._deadData[d] = misfiledata[MFILE_SHATTER1].mAnimData[0]; + dead[nd]._deadFrame = 12; + dead[nd]._deadWidth = 128; + dead[nd]._deadWidth2 = 32; + dead[nd]._deadtrans = 0; + stonendx = nd + 1; + nd++; + + for(i = 0; i < nummonsters; i++) { + mi = monstactive[i]; + if(monster[mi]._uniqtype) { + for(d = 0; d < 8; d++) + dead[nd]._deadData[d] = monster[mi].MType->Anims[4].Frames[d]; + dead[nd]._deadFrame = monster[mi].MType->Anims[4].Rate; + dead[nd]._deadWidth = monster[mi].MType->flags_1; + dead[nd]._deadWidth2 = monster[mi].MType->flags_2; + dead[nd]._deadtrans = monster[mi]._uniqtrans + 4; + monster[mi]._udeadval = nd + 1; + nd++; + } + } + + /// ASSERT: assert(nd <= MAXDEAD); +} + +void AddDead(int dx, int dy, char dv, int ddir) +{ + dDead[dx][dy] = (dv & 0x1F) + 32 * ddir; +} + +void SetDead() +{ + int mi; + int i; + int dx, dy; + + for(i = 0; i < nummonsters; i++) { + mi = monstactive[i]; + if(monster[mi]._uniqtype) { + for(dx = 0; dx < MAXDUNX; dx++) { + for(dy = 0; dy < MAXDUNY; dy++) { + if((dDead[dx][dy] & 0x1F) == monster[mi]._udeadval) + ChangeLightXY((unsigned char)monster[mi].mlid, dx, dy); + } + } + } + } +} diff --git a/2020_03_31/Source/dead.h b/2020_03_31/Source/dead.h new file mode 100644 index 00000000..aeb95c18 --- /dev/null +++ b/2020_03_31/Source/dead.h @@ -0,0 +1,13 @@ +//HEADER_GOES_HERE +#ifndef __DEAD_H__ +#define __DEAD_H__ + +extern int spurtndx; +extern DeadStruct dead[MAXDEAD]; +extern int stonendx; + +void InitDead(); +void AddDead(int dx, int dy, char dv, int ddir); +void SetDead(); + +#endif /* __DEAD_H__ */ diff --git a/2020_03_31/Source/debug.cpp b/2020_03_31/Source/debug.cpp new file mode 100644 index 00000000..3fe49744 --- /dev/null +++ b/2020_03_31/Source/debug.cpp @@ -0,0 +1,302 @@ +#include "diablo.h" + +#ifdef _DEBUG +BOOL update_seed_check = FALSE; +#endif + +int seed_index; +int level_seeds[NUMLEVELS]; +int seed_table[4096]; + +void *pSquareCel; +char dMonsDbg[NUMLEVELS][MAXDUNX][MAXDUNY]; +char dFlagDbg[NUMLEVELS][MAXDUNX][MAXDUNY]; + +void LoadDebugGFX() +{ + if ( visiondebug ) + pSquareCel = DiabLoad("Data\\Square.CEL", NULL, 'DBGS'); +} + +void FreeDebugGFX() +{ + void *v0; // ecx + + v0 = pSquareCel; + pSquareCel = 0; + mem_free_dbg(v0); +} + +#ifdef _DEBUG +void init_seed_desync() +{ + int i; + + for(i = 0; i < 4096; i++) { + seed_table[i] = -1; + } + + seed_index = 0; + + for(i = 0; i < NUMLEVELS; i++) { + level_seeds[i] = 0; + } +} + +void seed_desync_index_get() +{ + if(currlevel == 0) { + return; + } + + update_seed_check = TRUE; + seed_index = level_seeds[currlevel]; +} + +void seed_desync_index_set() +{ + if(currlevel == 0) { + return; + } + + update_seed_check = FALSE; + level_seeds[currlevel + 1] = seed_index; +} + +void seed_desync_check(int seed) +{ + if(!update_seed_check || seed_index == 4096 || currlevel == 0) { + return; + } + + if(seed_table[seed_index] == -1) { + seed_table[seed_index] = seed; + } else if(seed != seed_table[seed_index]) { + app_fatal("Seeds desynced"); + } + + seed_index++; +} +#endif + +void CheckDungeonClear() +{ + int i; + int j; + + for(i = 0; i < MAXDUNX; i++) + { + for(j = 0; j < MAXDUNY; j++) + { + if ( dMonster[i][j] ) + app_fatal("Monsters not cleared"); + if ( dPlayer[i][j] ) + app_fatal("Players not cleared"); + + dMonsDbg[currlevel][i][j] = dFlags[i][j] & 2; + dFlagDbg[currlevel][i][j] = dFlags[i][j] & 8; + } + } +} + +#ifdef _DEBUG +void GiveGoldCheat() +{ + int i; // esi + int ni; // ebp + + for(i = 0; i < 40; i++) + { + if ( !plr[myplr].InvGrid[i] ) + { + ni = plr[myplr]._pNumInv++; + SetPlrHandItem(&plr[myplr].InvList[ni], IDI_GOLD); + GetPlrHandSeed(&plr[myplr].InvList[ni]); + plr[myplr].InvList[ni]._ivalue = 5000; + plr[myplr].InvList[ni]._iCurs = 6; + plr[myplr]._pGold += 5000; + plr[myplr].InvGrid[i] = plr[myplr]._pNumInv; + } + } +} + +void StoresCheat() +{ + int i; // eax + + numpremium = 0; + + for(i = 0; i < 6; i++) + premiumitem[i]._itype = -1; + + SpawnPremium(30); + + for(i = 0; i < 20; i++) + witchitem[i]._itype = -1; + + SpawnWitch(30); +} + +void TakeGoldCheat() +{ + int i; // esi + char ig; // cl + + for(i = 0; i < 40; i++) + { + ig = plr[myplr].InvGrid[i]; + if ( ig > 0 && plr[myplr].InvList[ig - 1]._itype == ITYPE_GOLD ) + RemoveInvItem(myplr, ig - 1); + } + + for(i = 0; i < 8; i++) + { + if ( plr[myplr].SpdList[i]._itype == ITYPE_GOLD ) + plr[myplr].SpdList[i]._itype = -1; + } + + plr[myplr]._pGold = 0; +} + +void MaxSpellsCheat() +{ + int i; // ebp + + for(i = 1; i < 37; i++) + { + if ( spelldata[i].sBookLvl != -1 ) + { + *(_QWORD *)plr[myplr]._pMemSpells |= (__int64)1 << (i - 1); + plr[myplr]._pSplLvl[i] = 10; + } + } +} + +void SetSpellLevelCheat(char spl, int spllvl) +{ + *(_QWORD *)plr[myplr]._pMemSpells |= (__int64)1 << (spl - 1); + plr[myplr]._pSplLvl[spl] = spllvl; +} + +void SetAllSpellsCheat() +{ + SetSpellLevelCheat(SPL_FIREBOLT, 8); + SetSpellLevelCheat(SPL_CBOLT, 11); + SetSpellLevelCheat(SPL_HBOLT, 10); + SetSpellLevelCheat(SPL_HEAL, 7); + SetSpellLevelCheat(SPL_HEALOTHER, 5); + SetSpellLevelCheat(SPL_LIGHTNING, 9); + SetSpellLevelCheat(SPL_FIREWALL, 5); + SetSpellLevelCheat(SPL_TELEKINESIS, 3); + SetSpellLevelCheat(SPL_TOWN, 3); + SetSpellLevelCheat(SPL_FLASH, 3); + SetSpellLevelCheat(SPL_RNDTELEPORT, 2); + SetSpellLevelCheat(SPL_MANASHIELD, 2); + SetSpellLevelCheat(SPL_WAVE, 4); + SetSpellLevelCheat(SPL_FIREBALL, 3); + SetSpellLevelCheat(SPL_STONE, 1); + SetSpellLevelCheat(SPL_CHAIN, 1); + SetSpellLevelCheat(SPL_GUARDIAN, 4); + SetSpellLevelCheat(SPL_ELEMENT, 3); + SetSpellLevelCheat(SPL_NOVA, 1); + SetSpellLevelCheat(SPL_GOLEM, 2); + SetSpellLevelCheat(SPL_FLARE, 1); + SetSpellLevelCheat(SPL_BONESPIRIT, 1); +} + +void PrintDebugPlayer(_bool bNextPlayer) +{ + char dstr[128]; // [esp+Ch] [ebp-80h] + + if ( bNextPlayer ) + dbgplr = ((_BYTE)dbgplr + 1) & 3; + + sprintf(dstr, "Plr %i : Active = %i", dbgplr, plr[dbgplr].plractive); + NetSendCmdString(1 << myplr, dstr); + + if ( plr[dbgplr].plractive ) + { + sprintf(dstr, " Plr %i is %s", dbgplr, plr[dbgplr]._pName); + NetSendCmdString(1 << myplr, dstr); + sprintf(dstr, " Lvl = %i : Change = %i", plr[dbgplr].plrlevel, plr[dbgplr]._pLvlChanging); + NetSendCmdString(1 << myplr, dstr); + sprintf(dstr, " x = %i, y = %i : tx = %i, ty = %i", plr[dbgplr].WorldX, plr[dbgplr].WorldY, plr[dbgplr]._ptargx, plr[dbgplr]._ptargy); + NetSendCmdString(1 << myplr, dstr); + sprintf(dstr, " mode = %i : daction = %i : walk[0] = %i", plr[dbgplr]._pmode, plr[dbgplr].destAction, plr[dbgplr].walkpath[0]); + NetSendCmdString(1 << myplr, dstr); + sprintf(dstr, " inv = %i : hp = %i", plr[dbgplr]._pInvincible, plr[dbgplr]._pHitPoints); + NetSendCmdString(1 << myplr, dstr); + } +} + +void PrintDebugQuest() +{ + char dstr[128]; // [esp+0h] [ebp-80h] + + sprintf(dstr, "Quest %i : Active = %i, Var1 = %i", dbgqst, quests[dbgqst]._qactive, quests[dbgqst]._qvar1); + NetSendCmdString(1 << myplr, dstr); + if ( ++dbgqst == MAXQUESTS ) + dbgqst = 0; +} + +void PrintDebugMonster(int m) +{ + _bool bActive; // ecx + int i; // eax + char dstr[128]; // [esp+Ch] [ebp-80h] + + sprintf(dstr, "Monster %i = %s", m, monster[m].mName); + NetSendCmdString(1 << myplr, dstr); + sprintf(dstr, "X = %i, Y = %i", monster[m]._mx, monster[m]._my); + NetSendCmdString(1 << myplr, dstr); + sprintf(dstr, "Enemy = %i, HP = %i", monster[m]._menemy, monster[m]._mhitpoints); + NetSendCmdString(1 << myplr, dstr); + sprintf(dstr, "Mode = %i, Var1 = %i", monster[m]._mmode, monster[m]._mVar1); + NetSendCmdString(1 << myplr, dstr); + + bActive = 0; + + for(i = 0; i < nummonsters; i++) + { + if ( monstactive[i] == m ) + bActive = 1; + } + + sprintf(dstr, "Active List = %i, Squelch = %i", bActive, monster[m]._msquelch); + NetSendCmdString(1 << myplr, dstr); +} + +void GetDebugMonster() +{ + int v0; // ecx + int v1; // eax + + v0 = pcursmonst; + if ( pcursmonst == -1 ) + { + v1 = dMonster[cursmx][cursmy]; + if ( v1 ) + { + v0 = v1 - 1; + if ( v1 <= 0 ) + v0 = -1 - v1; + } + else + { + v0 = dbgmon; + } + } + PrintDebugMonster(v0); +} + +void NextDebugMonster() +{ + char dstr[128]; // [esp+0h] [ebp-80h] + + if ( dbgmon++ == MAXMONSTERS ) + dbgmon = 0; + + sprintf(dstr, "Current debug monster = %i", dbgmon); + NetSendCmdString(1 << myplr, dstr); +} +#endif diff --git a/2020_03_31/Source/debug.h b/2020_03_31/Source/debug.h new file mode 100644 index 00000000..d444df37 --- /dev/null +++ b/2020_03_31/Source/debug.h @@ -0,0 +1,32 @@ +//HEADER_GOES_HERE +#ifndef __DEBUG_H__ +#define __DEBUG_H__ + +extern void *pSquareCel; +extern char dMonsDbg[NUMLEVELS][MAXDUNX][MAXDUNY]; +extern char dFlagDbg[NUMLEVELS][MAXDUNX][MAXDUNY]; + +void LoadDebugGFX(); +void FreeDebugGFX(); +#ifdef _DEBUG +void init_seed_desync(); +void seed_desync_index_get(); +void seed_desync_index_set(); +void seed_desync_check(int seed); +#endif +void CheckDungeonClear(); +#ifdef _DEBUG +void GiveGoldCheat(); +void StoresCheat(); +void TakeGoldCheat(); +void MaxSpellsCheat(); +void SetSpellLevelCheat(char spl, int spllvl); +void SetAllSpellsCheat(); +void PrintDebugPlayer(_bool bNextPlayer); +void PrintDebugQuest(); +void PrintDebugMonster(int m); +void GetDebugMonster(); +void NextDebugMonster(); +#endif + +#endif /* __DEBUG_H__ */ diff --git a/2020_03_31/Source/diablo.cpp b/2020_03_31/Source/diablo.cpp new file mode 100644 index 00000000..fb4c2fd3 --- /dev/null +++ b/2020_03_31/Source/diablo.cpp @@ -0,0 +1,1948 @@ +#include "diablo.h" +#include "../3rdParty/Storm/Source/storm.h" +#include "../DiabloUI/diabloui.h" + +HWND ghMainWnd; +int glMid1Seed[NUMLEVELS]; +int glMid2Seed[NUMLEVELS]; +int gnLevelTypeTbl[NUMLEVELS]; +int MouseY; // idb +int MouseX; // idb +BOOL gbGameLoopStartup; // idb +int glSeedTbl[NUMLEVELS]; +int gbRunGame; // weak +int glMid3Seed[NUMLEVELS]; +int gbRunGameResult; // weak +int zoomflag; // weak +int gbProcessPlayers; // weak +int glEndSeed[NUMLEVELS]; +int gbLoadGame; // weak +HINSTANCE ghInst; // idb +int DebugMonsters[10]; +char cineflag; // weak +int force_redraw; // weak +int visiondebug; // weak +int scrollflag; /* unused */ +int light4flag; // weak +int leveldebug; // weak +int monstdebug; // weak +int trigdebug; /* unused */ +int setseed; // weak +int debugmonsttypes; // weak +int PauseMode; // weak +int sgnTimeoutCurs; +char sgbMouseDown; // weak +int color_cycle_timer; // weak + +/* rdata */ + +int fullscreen = 1; // weak +#ifdef _DEBUG +int showintrodebug = 1; +int questdebug = -1; +int debug_mode_key_s; +int debug_mode_key_w; +int debug_mode_key_inverted_v; +int debug_mode_dollar_sign; +int debug_mode_key_d; +int debug_mode_key_i; +int dbgplr; +int dbgqst; +int dbgmon; +int arrowdebug; +int frameflag; +int frameend; +int framerate; +int framestart; +#endif +int FriendlyMode = 1; // weak +char *spszMsgTbl[4] = +{ + "I need help! Come Here!", + "Follow me.", + "Here's something for you.", + "Now you DIE!" +}; // weak +char *spszMsgKeyTbl[4] = { "F9", "F10", "F11", "F12" }; // weak + +void FreeGameMem() +{ + music_stop(); + + MemFreeDbg(pDungeonCels); + MemFreeDbg(pMegaTiles); + MemFreeDbg(pLevelPieces); + MemFreeDbg(pSpecialCels); + MemFreeDbg(pSpeedCels); + + FreeMissiles(); + FreeMonsters(); + FreeObjectGFX(); + FreeMonsterSnd(); + FreeTownerGFX(); +} + +BOOL StartGame(BOOL bNewGame, BOOL bSinglePlayer) +{ + BOOL fExitProgram; + unsigned int uMsg; + + gbSelectProvider = 1; + + do { + fExitProgram = FALSE; + gbLoadGame = 0; + + if(!NetInit(bSinglePlayer, &fExitProgram)) { + gbRunGameResult = fExitProgram == FALSE; + break; + } + + gbSelectProvider = 0; + + if(bNewGame || !gbValidSaveFile) { + InitLevels(); + InitQuests(); + InitPortals(); + InitDungMsgs(myplr); + } + if(!gbValidSaveFile || !gbLoadGame) + uMsg = WM_DIABNEWGAME; + else + uMsg = WM_DIABLOADGAME; + + run_game_loop(uMsg); + NetClose(); + pfile_create_player_description(0, 0); + } while(gbRunGameResult); + + SNetDestroy(); + return gbRunGameResult; +} + +void run_game_loop(unsigned int uMsg) +{ + BOOL bLoop; + WNDPROC saveProc; + MSG msg; + + nthread_ignore_mutex(TRUE); + start_game(uMsg); + /// ASSERT: assert(ghMainWnd); + saveProc = SetWindowProc(GM_Game); + control_update_life_mana(); + run_delta_info(); + gbRunGame = TRUE; + gbProcessPlayers = TRUE; + gbRunGameResult = TRUE; + force_redraw = 255; + DrawAndBlit(); + PaletteFadeIn(8); + force_redraw = 255; + gbGameLoopStartup = TRUE; + nthread_ignore_mutex(FALSE); + + while(gbRunGame) { + diablo_color_cyc_logic(); + if(PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) { + SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL); + while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { + if(msg.message == WM_QUIT) { + gbRunGameResult = FALSE; + gbRunGame = FALSE; + break; + } + TranslateMessage(&msg); + DispatchMessage(&msg); + } + bLoop = gbRunGame && nthread_has_500ms_passed(FALSE); + SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL); + if(!bLoop) { + continue; + } + } else if(!nthread_has_500ms_passed(FALSE)) { +#ifdef SLEEPFIX + Sleep(1); +#endif + continue; + } + multi_process_network_packets(); + game_loop(gbGameLoopStartup); + msgcmd_send_chat(); + gbGameLoopStartup = FALSE; + DrawAndBlit(); + } + + if(gbMaxPlayers > 1) { + pfile_write_hero(); + } + + pfile_flush_W(); + PaletteFadeOut(8); + SetCursor_(0); + ClearScreenBuffer(); + force_redraw = 255; + scrollrt_draw_game_screen(TRUE); + saveProc = SetWindowProc(saveProc); + /// ASSERT: assert(saveProc == GM_Game); + free_game(); + + if(cineflag) { + cineflag = FALSE; + DoEnding(); + } +} + +void start_game(unsigned int uMsg) +{ + zoomflag = 1; + cineflag = 0; + InitCursor(); + InitLightTable(); + LoadDebugGFX(); + /// ASSERT: assert(ghMainWnd); + music_stop(); + ShowProgress(uMsg); + gmenu_init_menu(); + InitLevelCursor(); + sgnTimeoutCurs = 0; + sgbMouseDown = 0; + track_repeat_walk(0); +} + +void free_game() +{ + int i; + + FreeControlPan(); + FreeInvGFX(); + FreeGMenu(); + FreeQuestText(); + FreeStoreMem(); + + for(i = 0; i < MAX_PLRS; i++) { + FreePlayerGFX(i); + } + + FreeItemGFX(); + FreeCursor(); + FreeLightTable(); + FreeDebugGFX(); + FreeGameMem(); +} + +BOOL diablo_get_not_running() +{ + SetLastError(0); + CreateEvent(NULL, FALSE, FALSE, "DiabloEvent"); + return GetLastError() != ERROR_ALREADY_EXISTS; +} + +int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) +{ + HINSTANCE hInst; + DWORD dwData; + char szFileName[MAX_PATH]; + + hInst = hInstance; +#ifndef DEBUGGER + diablo_reload_process(hInstance); +#endif + ghInst = hInst; + + if(RestrictedTest()) + ErrOkDlg(IDD_DIALOG10, 0, "C:\\Src\\Diablo\\Source\\DIABLO.CPP", 877); + if(ReadOnlyTest()) { + if(!GetModuleFileName(ghInst, szFileName, sizeof(szFileName))) + szFileName[0] = '\0'; + DirErrorDlg(szFileName); + } + + ShowCursor(FALSE); + srand(GetTickCount()); + InitHash(); + exception_get_filter(); + + BOOL bNoEvent = diablo_get_not_running(); + if(!diablo_find_window("DIABLO") && bNoEvent) { +#ifdef _DEBUG + SFileEnableDirectAccess(TRUE); +#endif + diablo_init_screen(); + diablo_parse_flags(lpCmdLine); + init_create_window(nCmdShow); + ui_sound_init(); + UiInitialize(); + +#ifdef _DEBUG + if(showintrodebug) +#endif + play_movie("gendata\\logo.smk", TRUE); + + char szValueName[] = "Intro"; + if(!SRegLoadValue("Diablo", szValueName, 0, &dwData)) + dwData = 1; + if(dwData) + play_movie("gendata\\diablo1.smk", TRUE); + SRegSaveValue("Diablo", szValueName, 0, 0); + +#ifdef _DEBUG + if(showintrodebug) { +#endif + UiTitleDialog(7); + BlackPalette(); +#ifdef _DEBUG + } +#endif + + mainmenu_loop(); + UiDestroy(); + SaveGamma(); + + if(ghMainWnd) { + Sleep(300); + DestroyWindow(ghMainWnd); + } + } + + return FALSE; +} + +void diablo_parse_flags(char *args) +{ + char c; +#ifdef _DEBUG + int i; +#endif + + while(*args != '\0') { + while(isspace(*args)) { + args++; + } + if(_strnicmp("dd_emulate", args, strlen("dd_emulate")) == 0) { + gbEmulate = 1; + args += strlen("dd_emulate"); + } else if(_strnicmp("dd_backbuf", args, strlen("dd_backbuf")) == 0) { + gbBackBuf = 1; + args += strlen("dd_backbuf"); + } else if(_strnicmp("ds_noduplicates", args, strlen("ds_noduplicates")) == 0) { + gbDupSounds = 0; + args += strlen("ds_noduplicates"); + } else { + c = tolower(*args); + args++; +#ifdef _DEBUG + switch(c) { + case '^': + debug_mode_key_inverted_v = 1; + break; + case '$': + debug_mode_dollar_sign = 1; + break; + case 'b': + /* + debug_mode_key_b = 1; + */ + break; + case 'd': + showintrodebug = 0; + debug_mode_key_d = 1; + break; + case 'f': + EnableFrameCount(); + break; + case 'i': + debug_mode_key_i = 1; + break; + case 'j': + /* + while(isspace(*args)) { + args++; + } + i = 0; + while(isdigit(*args)) { + i = *args + 10 * i - '0'; + args++; + } + debug_mode_key_J_trigger = i; + */ + break; + case 'l': + setlevel = 0; + leveldebug = 1; + while(isspace(*args)) { + args++; + } + i = 0; + while(isdigit(*args)) { + i = *args + 10 * i - '0'; + args++; + } + leveltype = i; + while(isspace(*args)) { + args++; + } + i = 0; + while(isdigit(*args)) { + i = *args + 10 * i - '0'; + args++; + } + currlevel = i; + plr[0].plrlevel = i; + break; + case 'm': + monstdebug = 1; + while(isspace(*args)) { + args++; + } + i = 0; + while(isdigit(*args)) { + i = *args + 10 * i - '0'; + args++; + } + DebugMonsters[debugmonsttypes++] = i; + break; + case 'n': + showintrodebug = 0; + break; + case 'q': + while(isspace(*args)) { + args++; + } + i = 0; + while(isdigit(*args)) { + i = *args + 10 * i - '0'; + args++; + } + questdebug = i; + break; + case 'r': + while(isspace(*args)) { + args++; + } + i = 0; + while(isdigit(*args)) { + i = *args + 10 * i - '0'; + args++; + } + setseed = i; + break; + case 's': + debug_mode_key_s = 1; + break; + case 't': + leveldebug = 1; + setlevel = 1; + while(isspace(*args)) { + args++; + } + i = 0; + while(isdigit(*args)) { + i = *args + 10 * i - '0'; + args++; + } + setlvlnum = i; + break; + case 'v': + visiondebug = 1; + break; + case 'w': + debug_mode_key_w = 1; + break; + case 'x': + fullscreen = 0; + break; + } +#endif + } + } +} + +void diablo_init_screen() +{ + int i; + + MouseX = SCREEN_WIDTH / 2; + MouseY = SCREEN_HEIGHT / 2; + ScrollInfo._sdx = 0; + ScrollInfo._sdy = 0; + ScrollInfo._sxoff = 0; + ScrollInfo._syoff = 0; + ScrollInfo._sdir = 0; + + for(i = 0; i < 1024; i++) { + PitchTbl[i] = i * BUFFER_WIDTH; + } + + ClrDiabloMsg(); +} + +BOOL diablo_find_window(LPCSTR lpClassName) +{ + HWND result; // eax + HWND v2; // esi + HWND v3; // eax + HWND v4; // edi + + result = FindWindow(lpClassName, 0); + v2 = result; + if ( !result ) + return 0; + + v3 = GetLastActivePopup(result); + if ( v3 ) + v2 = v3; + v4 = GetTopWindow(v2); + if ( !v4 ) + v4 = v2; + SetForegroundWindow(v2); + SetFocus(v4); + return 1; +} + +void diablo_reload_process(HINSTANCE hInstance) +{ + DWORD dwSize, dwProcessId; + BOOL bNoExist; + char *s; + long *plMap; + HWND hWnd, hPrev; + HANDLE hMap; + STARTUPINFO si; + SYSTEM_INFO sinf; + PROCESS_INFORMATION pi; + char szReload[MAX_PATH + 16]; + char szFileName[MAX_PATH] = ""; + + GetModuleFileName(hInstance, szFileName, sizeof(szFileName)); + wsprintf(szReload, "Reload-%s", szFileName); + for(s = szReload; *s != '\0'; s++) { + if(*s == '\\') { + *s = '/'; + } + } + + GetSystemInfo(&sinf); + dwSize = sinf.dwPageSize; + if(dwSize < 4096) { + dwSize = 4096; + } + + hMap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, SEC_COMMIT | PAGE_READWRITE, 0, dwSize, szReload); + bNoExist = GetLastError() != ERROR_ALREADY_EXISTS; + if(hMap == NULL) { + return; + } + plMap = (long *)MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, dwSize); + if(plMap == NULL) { + return; + } + + if(bNoExist) { + plMap[0] = -1; + plMap[1] = 0; + memset(&si, 0, sizeof(si)); + si.cb = sizeof(si); + CreateProcess(szFileName, NULL, NULL, NULL, FALSE, CREATE_NEW_PROCESS_GROUP, NULL, NULL, &si, &pi); + WaitForInputIdle(pi.hProcess, INFINITE); + CloseHandle(pi.hThread); + CloseHandle(pi.hProcess); + while(plMap[0] < 0) { + Sleep(1000); + } + UnmapViewOfFile(plMap); + CloseHandle(hMap); + ExitProcess(0); + } + + if(InterlockedIncrement(plMap) == 0) { + plMap[1] = GetCurrentProcessId(); + } else { + hPrev = GetForegroundWindow(); + hWnd = hPrev; + while(1) { + hPrev = GetWindow(hPrev, GW_HWNDPREV); + if(hPrev == NULL) { + break; + } + hWnd = hPrev; + } + while(1) { + GetWindowThreadProcessId(hWnd, &dwProcessId); + if(dwProcessId == plMap[1]) { + SetForegroundWindow(hWnd); + break; + } + hWnd = GetWindow(hWnd, GW_HWNDNEXT); + if(hWnd == NULL) { + break; + } + } + UnmapViewOfFile(plMap); + CloseHandle(hMap); + ExitProcess(0); + } +} + +BOOL PressEscKey() +{ + BOOL rv = FALSE; + + if(doomflag) { + doom_close(); + rv = TRUE; + } + if(helpflag) { + helpflag = 0; + rv = TRUE; + } + + if(qtextflag) { + qtextflag = 0; + stream_stop(); + rv = TRUE; + } else if(stextflag) { + STextESC(); + rv = TRUE; + } + + if(msgflag) { + msgdelay = 0; + rv = TRUE; + } + if(talkflag) { + control_reset_talk(); + rv = TRUE; + } + if(dropGoldFlag) { + control_drop_gold(VK_ESCAPE); + rv = TRUE; + } + if(spselflag) { + spselflag = 0; + rv = TRUE; + } + + return rv; +} + +LRESULT CALLBACK DisableInputWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + switch(uMsg) { + case WM_KEYDOWN: + case WM_KEYUP: + case WM_CHAR: + case WM_SYSKEYDOWN: + case WM_SYSCOMMAND: + case WM_MOUSEMOVE: + return 0; + case WM_LBUTTONDOWN: + if(sgbMouseDown == 0) { + sgbMouseDown = 1; + SetCapture(hWnd); + } + return 0; + case WM_LBUTTONUP: + if(sgbMouseDown == 1) { + sgbMouseDown = 0; + ReleaseCapture(); + } + return 0; + case WM_RBUTTONDOWN: + if(sgbMouseDown == 0) { + sgbMouseDown = 2; + SetCapture(hWnd); + } + return 0; + case WM_RBUTTONUP: + if(sgbMouseDown == 2) { + sgbMouseDown = 0; + ReleaseCapture(); + } + return 0; + case WM_CAPTURECHANGED: + if(hWnd != (HWND)lParam) + sgbMouseDown = 0; + return 0; + } + + return MainWndProc(hWnd, uMsg, wParam, lParam); +} + +LRESULT CALLBACK GM_Game(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + switch(uMsg) { + case WM_KEYDOWN: + PressKey(wParam); + return 0; + case WM_KEYUP: + ReleaseKey(wParam); + return 0; + case WM_CHAR: + PressChar(wParam); + return 0; + case WM_SYSKEYDOWN: + if(PressSysKey(wParam)) + return 0; + break; + case WM_SYSCOMMAND: + if(wParam == SC_CLOSE) { + gbRunGame = FALSE; + gbRunGameResult = FALSE; + return 0; + } + break; + case WM_MOUSEMOVE: + MouseX = LOWORD(lParam); + MouseY = HIWORD(lParam); + gmenu_on_mouse_move(); + return 0; + case WM_LBUTTONDOWN: + MouseX = LOWORD(lParam); + MouseY = HIWORD(lParam); + if(sgbMouseDown == 0) { + sgbMouseDown = 1; + SetCapture(hWnd); + track_repeat_walk(LeftMouseDown(wParam)); + } + return 0; + case WM_LBUTTONUP: + MouseX = LOWORD(lParam); + MouseY = HIWORD(lParam); + if(sgbMouseDown == 1) { + sgbMouseDown = 0; + LeftMouseUp(); + track_repeat_walk(FALSE); + ReleaseCapture(); + } + return 0; + case WM_RBUTTONDOWN: + MouseX = LOWORD(lParam); + MouseY = HIWORD(lParam); + if(sgbMouseDown == 0) { + sgbMouseDown = 2; + SetCapture(hWnd); + RightMouseDown(); + } + return 0; + case WM_RBUTTONUP: + MouseX = LOWORD(lParam); + MouseY = HIWORD(lParam); + if(sgbMouseDown == 2) { + sgbMouseDown = 0; + ReleaseCapture(); + } + return 0; + case WM_CAPTURECHANGED: + if(hWnd != (HWND)lParam) { + sgbMouseDown = 0; + track_repeat_walk(FALSE); + } + break; + case WM_DIABNEXTLVL: + case WM_DIABPREVLVL: + case WM_DIABRTNLVL: + case WM_DIABSETLVL: + case WM_DIABWARPLVL: + case WM_DIABTOWNWARP: + case WM_DIABTWARPUP: + case WM_DIABRETOWN: + if(gbMaxPlayers > 1) + pfile_write_hero(); + nthread_ignore_mutex(TRUE); + PaletteFadeOut(8); + sound_stop(); + music_stop(); + track_repeat_walk(FALSE); + sgbMouseDown = 0; + ReleaseCapture(); + ShowProgress(uMsg); + force_redraw = 255; + DrawAndBlit(); + if(gbRunGame) + PaletteFadeIn(8); + nthread_ignore_mutex(FALSE); + gbGameLoopStartup = TRUE; + return 0; + } + + return MainWndProc(hWnd, uMsg, wParam, lParam); +} + +BOOL LeftMouseDown(int wParam) +{ + if ( gmenu_left_mouse(1) || control_check_talk_btn() || sgnTimeoutCurs ) + return 0; + if ( deathflag ) + { + control_check_btn_press(); + return 0; + } + if ( PauseMode == 2 ) + return 0; + if ( doomflag ) + { + doom_close(); + return 0; + } + if ( spselflag ) + { + SetSpell(); + return 0; + } + if ( stextflag ) + { + CheckStoreBtn(); + return 0; + } + if ( MouseY >= 352 ) + { + if ( !talkflag && !dropGoldFlag ) + { + if ( !gmenu_is_active() ) + CheckInvScrn(); + } + DoPanBtn(); + if ( pcurs <= 1 || pcurs >= 12 ) + return 0; + goto LABEL_48; + } + if ( gmenu_is_active() || TryIconCurs() ) + return 0; + if ( questlog && MouseX > 32 && MouseX < 288 && MouseY > 32 && MouseY < 308 ) + { + QuestlogESC(); + return 0; + } + if ( qtextflag ) + { + qtextflag = 0; + stream_stop(); + return 0; + } + if ( chrflag && MouseX < 320 ) + { + CheckChrBtns(); + return 0; + } + if ( invflag && MouseX > 320 ) + { + if ( !dropGoldFlag ) + CheckInvItem(); + return 0; + } + if ( sbookflag && MouseX > 320 ) + { + CheckSBook(); + return 0; + } + if ( pcurs >= CURSOR_FIRSTITEM ) + { + if ( !TryInvPut() ) + return 0; + NetSendCmdPItem(1u, CMD_PUTITEM, cursmx, cursmy); +LABEL_48: + SetCursor_(CURSOR_HAND); + return 0; + } + if ( plr[myplr]._pStatPts && !spselflag ) + CheckLvlBtn(); + if ( !lvlbtndown ) + return LeftMouseCmd(wParam == MK_SHIFT+MK_LBUTTON); + return 0; +} + +BOOL LeftMouseCmd(BOOL bShift) +{ + BOOL bNear; + + /// ASSERT: assert(MouseY < 352); + + if(leveltype == DTYPE_TOWN) { + if(pcursitem != -1 && pcurs == CURSOR_HAND) { + NetSendCmdLocParam1(1, invflag ? CMD_GOTOGETITEM : CMD_GOTOAGETITEM, cursmx, cursmy, pcursitem); + } + if(pcursmonst != -1) { + NetSendCmdLocParam1(1, CMD_TALKXY, cursmx, cursmy, pcursmonst); + } + if(pcursitem == -1 && pcursmonst == -1 && pcursplr == -1) { + return TRUE; + } + } else { + bNear = abs(plr[myplr].WorldX - cursmx) < 2 && abs(plr[myplr].WorldY - cursmy) < 2; + if(pcursitem != -1 && pcurs == CURSOR_HAND && !bShift) { + NetSendCmdLocParam1(1, invflag ? CMD_GOTOGETITEM : CMD_GOTOAGETITEM, cursmx, cursmy, pcursitem); + } else if(pcursobj != -1 && (!bShift || bNear && object[pcursobj]._oBreak == 1)) { + NetSendCmdLocParam1(1, pcurs == CURSOR_DISARM ? CMD_DISARMXY : CMD_OPOBJXY, cursmx, cursmy, pcursobj); + } else if(plr[myplr]._pwtype == 1) { + if(bShift) { + NetSendCmdLoc(1, CMD_RATTACKXY, cursmx, cursmy); + } else if(pcursmonst != -1) { + if(CanTalkToMonst(pcursmonst)) { + NetSendCmdParam1(1, CMD_ATTACKID, pcursmonst); + } else { + NetSendCmdParam1(1, CMD_RATTACKID, pcursmonst); + } + } else if(pcursplr != -1 && !FriendlyMode) { + NetSendCmdParam1(1, CMD_RATTACKPID, pcursplr); + } + } else { + if(bShift) { + if(pcursmonst != -1) { + if(CanTalkToMonst(pcursmonst)) { + NetSendCmdParam1(1, CMD_ATTACKID, pcursmonst); + } else { + NetSendCmdLoc(1, CMD_SATTACKXY, cursmx, cursmy); + } + } else { + NetSendCmdLoc(1, CMD_SATTACKXY, cursmx, cursmy); + } + } else if(pcursmonst != -1) { + NetSendCmdParam1(1, CMD_ATTACKID, pcursmonst); + } else if(pcursplr != -1 && !FriendlyMode) { + NetSendCmdParam1(1, CMD_ATTACKPID, pcursplr); + } + } + if(!bShift && pcursitem == -1 && pcursobj == -1 && pcursmonst == -1 && pcursplr == -1) { + return TRUE; + } + } + + return FALSE; +} + +BOOL TryIconCurs() +{ + if(pcurs == CURSOR_RESURRECT) { + NetSendCmdParam1(TRUE, CMD_RESURRECT, pcursplr); + return TRUE; + } else if(pcurs == CURSOR_HEALOTHER) { + NetSendCmdParam1(TRUE, CMD_HEALOTHER, pcursplr); + return TRUE; + } else if(pcurs == CURSOR_TELEKINESIS) { + DoTelekinesis(); + return TRUE; + } else if(pcurs == CURSOR_IDENTIFY) { + if(pcursinvitem != -1) { + CheckIdentify(myplr, pcursinvitem); + } else { + SetCursor_(CURSOR_HAND); + } + return TRUE; + } else if(pcurs == CURSOR_REPAIR) { + if(pcursinvitem != -1) { + DoRepair(myplr, pcursinvitem); + } else { + SetCursor_(CURSOR_HAND); + } + return TRUE; + } else if(pcurs == CURSOR_RECHARGE) { + if(pcursinvitem != -1) { + DoRecharge(myplr, pcursinvitem); + } else { + SetCursor_(CURSOR_HAND); + } + return TRUE; + } else if(pcurs == CURSOR_TELEPORT) { + if(pcursmonst != -1) { + NetSendCmdParam3(TRUE, CMD_TSPELLID, pcursmonst, plr[myplr]._pTSpell, GetSpellLevel(myplr, plr[myplr]._pTSpell)); + } else if(pcursplr != -1) { + NetSendCmdParam3(TRUE, CMD_TSPELLPID, pcursplr, plr[myplr]._pTSpell, GetSpellLevel(myplr, plr[myplr]._pTSpell)); + } else { + NetSendCmdLocParam2(TRUE, CMD_TSPELLXY, cursmx, cursmy, plr[myplr]._pTSpell, GetSpellLevel(myplr, plr[myplr]._pTSpell)); + } + SetCursor_(CURSOR_HAND); + return TRUE; + } else if(pcurs == CURSOR_DISARM && pcursobj == -1) { + SetCursor_(CURSOR_HAND); + return TRUE; + } + + return FALSE; +} + +void LeftMouseUp() +{ + gmenu_left_mouse(0); + control_release_talk_btn(); + if ( panbtndown ) + CheckBtnUp(); + if ( chrbtnactive ) + ReleaseChrBtns(); + if ( lvlbtndown ) + ReleaseLvlBtn(); + if ( stextflag ) + ReleaseStoreBtn(); +} + +void RightMouseDown() +{ + if ( !gmenu_is_active() && sgnTimeoutCurs == CURSOR_NONE && PauseMode != 2 && !plr[myplr]._pInvincible ) + { + if ( doomflag ) + { + doom_close(); + } + else if ( !stextflag ) + { + if ( spselflag ) + { + SetSpell(); + } + else if ( MouseY >= 352 + || (!sbookflag || MouseX <= 320) + && !TryIconCurs() + && (pcursinvitem == -1 || !UseInvItem(myplr, pcursinvitem)) ) + { + if ( pcurs == 1 ) + { + if ( pcursinvitem == -1 || !UseInvItem(myplr, pcursinvitem) ) + CheckPlrSpell(); + } + else if ( pcurs > 1 && pcurs < 12 ) + { + SetCursor_(CURSOR_HAND); + } + } + } + } +} + +BOOL PressSysKey(int wParam) +{ + if ( gmenu_is_active() || wParam != VK_F10 ) + return FALSE; + diablo_hotkey_msg(1); + return TRUE; +} + +void diablo_hotkey_msg(DWORD dwMsg) +{ + char *s; + char szFileName[MAX_PATH]; + char szMsg[MAX_SEND_STR_LEN]; + + if(gbMaxPlayers == 1) { + return; + } + if(GetModuleFileName(ghInst, szFileName, sizeof(szFileName)) == 0) { + app_fatal("Can't get program name"); + } + + s = strrchr(szFileName, '\\'); + if(s != NULL) { + *s = '\0'; + } + + strcat(szFileName, "\\Diablo.ini"); + /// ASSERT: assert(dwMsg < sizeof(spszMsgTbl) / sizeof(spszMsgTbl[0])); + GetPrivateProfileString("NetMsg", spszMsgKeyTbl[dwMsg], spszMsgTbl[dwMsg], szMsg, sizeof(szMsg), szFileName); + NetSendCmdString(-1, szMsg); +} + +void ReleaseKey(int vkey) +{ + if ( vkey == VK_SNAPSHOT ) + CaptureScreen(); +} + +void PressKey(int vkey) +{ + if(gmenu_presskeys(vkey) || control_presskeys(vkey)) { + return; + } + + if(deathflag) { + if(sgnTimeoutCurs != 0) { + return; + } + if(vkey == VK_F9) { + diablo_hotkey_msg(0); + } + if(vkey == VK_F10) { + diablo_hotkey_msg(1); + } + if(vkey == VK_F11) { + diablo_hotkey_msg(2); + } + if(vkey == VK_F12) { + diablo_hotkey_msg(3); + } + if(vkey == VK_RETURN) { + control_type_message(); + } + if(vkey != VK_ESCAPE) { + return; + } + } + if(vkey == VK_ESCAPE) { + if(!PressEscKey()) { + track_repeat_walk(0); + gamemenu_on(); + } + return; + } + + if(sgnTimeoutCurs != 0 || dropGoldFlag) { + return; + } + if(vkey == VK_PAUSE) { + diablo_pause_game(); + return; + } + if(PauseMode == 2) { + return; + } + + if(vkey == VK_RETURN) { + if(stextflag) { + STextEnter(); + } else if(questlog) { + QuestlogEnter(); + } else { + control_type_message(); + } + } else if(vkey == VK_F1) { + if(helpflag) { + helpflag = 0; + } else if(stextflag) { + ClearPanel(); + AddPanelString("No help available", 1); /// BUGFIX: message isn't displayed + AddPanelString("while in stores", 1); + track_repeat_walk(0); + } else { + invflag = 0; + chrflag = 0; + sbookflag = 0; + spselflag = 0; + if(qtextflag && leveltype == DTYPE_TOWN) { + qtextflag = 0; + stream_stop(); + } + questlog = 0; + automapflag = 0; + msgdelay = 0; + gamemenu_off(); + DisplayHelp(); + doom_close(); + } + } +#ifdef _DEBUG + else if(vkey == VK_F2) { + } +#endif +#ifdef _DEBUG + else if(vkey == VK_F3) { + if(pcursitem != -1) { + sprintf( + tempstr, + "IDX = %i : Seed = %i : CF = %i", + item[pcursitem].IDidx, + item[pcursitem]._iSeed, + item[pcursitem]._iCreateInfo); + NetSendCmdString(1 << myplr, tempstr); + } + sprintf(tempstr, "Numitems : %i", numitems); + NetSendCmdString(1 << myplr, tempstr); + } +#endif +#ifdef _DEBUG + else if(vkey == VK_F4) { + PrintDebugQuest(); + } +#endif + else if(vkey == VK_F5) { + if(spselflag) { + SetSpeedSpell(0); + } else { + ToggleSpell(0); + } + } else if(vkey == VK_F6) { + if(spselflag) { + SetSpeedSpell(1); + } else { + ToggleSpell(1); + } + } else if(vkey == VK_F7) { + if(spselflag) { + SetSpeedSpell(2); + } else { + ToggleSpell(2); + } + } else if(vkey == VK_F8) { + if(spselflag) { + SetSpeedSpell(3); + } else { + ToggleSpell(3); + } + } else if(vkey == VK_F9) { + diablo_hotkey_msg(0); + } else if(vkey == VK_F10) { + diablo_hotkey_msg(1); + } else if(vkey == VK_F11) { + diablo_hotkey_msg(2); + } else if(vkey == VK_F12) { + diablo_hotkey_msg(3); + } else if(vkey == VK_UP) { + if(stextflag) { + STextUp(); + } else if(questlog) { + QuestlogUp(); + } else if(helpflag) { + HelpScrollUp(); + } else if(automapflag) { + AutomapUp(); + } + } else if(vkey == VK_DOWN) { + if(stextflag) { + STextDown(); + } else if(questlog) { + QuestlogDown(); + } else if(helpflag) { + HelpScrollDown(); + } else if(automapflag) { + AutomapDown(); + } + } else if(vkey == VK_PRIOR) { + if(stextflag) { + STextPrior(); + } + } else if(vkey == VK_NEXT) { + if(stextflag) { + STextNext(); + } + } else if(vkey == VK_LEFT) { + if(automapflag && !talkflag) { + AutomapLeft(); + } + } else if(vkey == VK_RIGHT) { + if(automapflag && !talkflag) { + AutomapRight(); + } + } else if(vkey == VK_TAB) { + DoAutoMap(); + } else if(vkey == VK_SPACE) { + if(!chrflag && invflag && MouseX < 480 && MouseY < 352) { + SetCursorPos(MouseX + 160, MouseY); + } + if(!invflag && chrflag && MouseX > 160 && MouseY < 352) { + SetCursorPos(MouseX - 160, MouseY); + } + helpflag = 0; + invflag = 0; + chrflag = 0; + sbookflag = 0; + spselflag = 0; + if(qtextflag && leveltype == DTYPE_TOWN) { + qtextflag = 0; + stream_stop(); + } + questlog = 0; + automapflag = 0; + msgdelay = 0; + gamemenu_off(); + doom_close(); + } +} + +void diablo_pause_game() +{ + if ( (unsigned char)gbMaxPlayers <= 1u ) + { + if ( PauseMode ) + { + PauseMode = 0; + } + else + { + PauseMode = 2; + sound_stop(); + track_repeat_walk(0); + } + force_redraw = 255; + } +} + +/* NOTE: `return` must be used instead of `break` to be bin exact as C++ */ +void PressChar(int vkey) +{ + if(gmenu_is_active() || control_talk_last_key(vkey) || sgnTimeoutCurs != 0 || deathflag) { + return; + } + if((char)vkey == 'p' || (char)vkey == 'P') { + diablo_pause_game(); + return; + } + if(PauseMode == 2) { + return; + } + if(doomflag) { + doom_close(); + return; + } + if(dropGoldFlag) { + control_drop_gold(vkey); + return; + } + + switch(vkey) { + case 'G': + case 'g': + DecreaseGamma(); + return; + case 'F': + case 'f': + IncreaseGamma(); + return; + case 'I': + case 'i': + if(!stextflag) { + sbookflag = 0; + invflag = invflag == 0; + if(!invflag || chrflag) { + if(MouseX < 480 && MouseY < 352) { + SetCursorPos(MouseX + 160, MouseY); + } + } else { + if(MouseX > 160 && MouseY < 352) { + SetCursorPos(MouseX - 160, MouseY); + } + } + } + return; + case 'C': + case 'c': + if(!stextflag) { + questlog = 0; + chrflag = chrflag == 0; + if(!chrflag || invflag) { + if(MouseX > 160 && MouseY < 352) { + SetCursorPos(MouseX - 160, MouseY); + } + } else { + if(MouseX < 480 && MouseY < 352) { + SetCursorPos(MouseX + 160, MouseY); + } + } + } + return; + case 'Q': + case 'q': + if(!stextflag) { + chrflag = 0; + if(!questlog) { + StartQuestlog(); + } else { + questlog = 0; + } + } + return; + case 'Z': + case 'z': + zoomflag = zoomflag == 0; + return; + case 'S': + case 's': + if(!stextflag) { + invflag = 0; + if(!spselflag) { + DoSpeedBook(); + } else { + spselflag = 0; + } + track_repeat_walk(0); + } + return; + case 'B': + case 'b': + if(!stextflag) { + invflag = 0; + sbookflag = sbookflag == 0; + } + return; + case '+': + case '=': + if(automapflag) { + AutomapZoomIn(); + } + return; + case '-': + case '_': + if(automapflag) { + AutomapZoomOut(); + } + return; + case 'v': + NetSendCmdString(1 << myplr, gszProductName); + return; + case 'V': + NetSendCmdString(1 << myplr, gszVersionNumber); + return; + case '!': + case '1': + if(plr[myplr].SpdList[0]._itype != -1 && plr[myplr].SpdList[0]._itype != 11) { + UseInvItem(myplr, 47); + } + return; + case '@': + case '2': + if(plr[myplr].SpdList[1]._itype != -1 && plr[myplr].SpdList[1]._itype != 11) { + UseInvItem(myplr, 48); + } + return; + case '#': + case '3': + if(plr[myplr].SpdList[2]._itype != -1 && plr[myplr].SpdList[2]._itype != 11) { + UseInvItem(myplr, 49); + } + return; + case '$': + case '4': + if(plr[myplr].SpdList[3]._itype != -1 && plr[myplr].SpdList[3]._itype != 11) { + UseInvItem(myplr, 50); + } + return; + case '%': + case '5': + if(plr[myplr].SpdList[4]._itype != -1 && plr[myplr].SpdList[4]._itype != 11) { + UseInvItem(myplr, 51); + } + return; + case '^': + case '6': + if(plr[myplr].SpdList[5]._itype != -1 && plr[myplr].SpdList[5]._itype != 11) { + UseInvItem(myplr, 52); + } + return; + case '&': + case '7': + if(plr[myplr].SpdList[6]._itype != -1 && plr[myplr].SpdList[6]._itype != 11) { + UseInvItem(myplr, 53); + } + return; + case '*': + case '8': +#ifdef _DEBUG + if(debug_mode_key_inverted_v || debug_mode_key_w) { + NetSendCmd(TRUE, CMD_CHEAT_EXPERIENCE); + return; + } +#endif + if(plr[myplr].SpdList[7]._itype != -1 && plr[myplr].SpdList[7]._itype != 11) { + UseInvItem(myplr, 54); + } + return; +#ifdef _DEBUG + case ')': + case '0': + if(debug_mode_key_inverted_v) { + if(arrowdebug > 2) { + arrowdebug = 0; + } + if(arrowdebug == 0) { + plr[myplr]._pIFlags &= ~ISPL_FIRE_ARROWS; + plr[myplr]._pIFlags &= ~ISPL_LIGHT_ARROWS; + } + if(arrowdebug == 1) { + plr[myplr]._pIFlags |= ISPL_FIRE_ARROWS; + } + if(arrowdebug == 2) { + plr[myplr]._pIFlags |= ISPL_LIGHT_ARROWS; + } + arrowdebug++; + } + return; + case ':': + if(currlevel == 0 && debug_mode_key_w) { + SetAllSpellsCheat(); + } + return; + case '[': + if(currlevel == 0 && debug_mode_key_w) { + TakeGoldCheat(); + } + return; + case ']': + if(currlevel == 0 && debug_mode_key_w) { + MaxSpellsCheat(); + } + return; + case 'a': + if(debug_mode_key_inverted_v) { + spelldata[SPL_TELEPORT].sTownSpell = 1; + plr[myplr]._pSplLvl[plr[myplr]._pSpell]++; + } + return; + case 'D': + PrintDebugPlayer(1); + return; + case 'd': + PrintDebugPlayer(0); + return; + case 'e': + if(debug_mode_key_d) { + sprintf(tempstr, "EFlag = %i", plr[myplr]._peflag); + NetSendCmdString(1 << myplr, tempstr); + } + return; + case 'L': + case 'l': + if(debug_mode_key_inverted_v) { + ToggleLighting(); + } + return; + case 'M': + NextDebugMonster(); + return; + case 'm': + GetDebugMonster(); + return; + case 'R': + case 'r': + sprintf(tempstr, "seed = %i", glSeedTbl[currlevel]); + NetSendCmdString(1 << myplr, tempstr); + sprintf(tempstr, "Mid1 = %i : Mid2 = %i : Mid3 = %i", glMid1Seed[currlevel], glMid2Seed[currlevel], glMid3Seed[currlevel]); + NetSendCmdString(1 << myplr, tempstr); + sprintf(tempstr, "End = %i", glEndSeed[currlevel]); + NetSendCmdString(1 << myplr, tempstr); + return; + case 'T': + case 't': + if(debug_mode_key_inverted_v) { + sprintf(tempstr, "PX = %i PY = %i", plr[myplr].WorldX, plr[myplr].WorldY); + NetSendCmdString(1 << myplr, tempstr); + sprintf(tempstr, "CX = %i CY = %i DP = %i", cursmx, cursmy, dungeon[cursmx][cursmy]); + NetSendCmdString(1 << myplr, tempstr); + } + return; + case '|': + if(currlevel == 0 && debug_mode_key_w) { + GiveGoldCheat(); + } + return; + case '~': + if(currlevel == 0 && debug_mode_key_w) { + StoresCheat(); + } + return; +#endif + } +} + +void LoadLvlGFX() +{ + /// ASSERT: assert(! pDungeonCels); + + switch((unsigned char)leveltype) { + case DTYPE_TOWN: + pDungeonCels = DiabLoad("Levels\\TownData\\Town.CEL", NULL, 'TILE'); + pMegaTiles = DiabLoad("Levels\\TownData\\Town.TIL", NULL, 'TILE'); + pLevelPieces = DiabLoad("Levels\\TownData\\Town.MIN", NULL, 'TILE'); + pSpecialCels = DiabLoad("Levels\\TownData\\TownS.CEL", NULL, 'TILE'); + break; + case DTYPE_CATHEDRAL: + pDungeonCels = DiabLoad("Levels\\L1Data\\L1.CEL", NULL, 'TILE'); + pMegaTiles = DiabLoad("Levels\\L1Data\\L1.TIL", NULL, 'TILE'); + pLevelPieces = DiabLoad("Levels\\L1Data\\L1.MIN", NULL, 'TILE'); + pSpecialCels = DiabLoad("Levels\\L1Data\\L1S.CEL", NULL, 'TILE'); + break; + case DTYPE_CATACOMBS: + pDungeonCels = DiabLoad("Levels\\L2Data\\L2.CEL", NULL, 'TILE'); + pMegaTiles = DiabLoad("Levels\\L2Data\\L2.TIL", NULL, 'TILE'); + pLevelPieces = DiabLoad("Levels\\L2Data\\L2.MIN", NULL, 'TILE'); + pSpecialCels = DiabLoad("Levels\\L2Data\\L2S.CEL", NULL, 'TILE'); + break; + case DTYPE_CAVES: + pDungeonCels = DiabLoad("Levels\\L3Data\\L3.CEL", NULL, 'TILE'); + pMegaTiles = DiabLoad("Levels\\L3Data\\L3.TIL", NULL, 'TILE'); + pLevelPieces = DiabLoad("Levels\\L3Data\\L3.MIN", NULL, 'TILE'); + pSpecialCels = DiabLoad("Levels\\L1Data\\L1S.CEL", NULL, 'TILE'); + break; + case DTYPE_HELL: + pDungeonCels = DiabLoad("Levels\\L4Data\\L4.CEL", NULL, 'TILE'); + pMegaTiles = DiabLoad("Levels\\L4Data\\L4.TIL", NULL, 'TILE'); + pLevelPieces = DiabLoad("Levels\\L4Data\\L4.MIN", NULL, 'TILE'); + pSpecialCels = DiabLoad("Levels\\L2Data\\L2S.CEL", NULL, 'TILE'); + break; + default: + app_fatal("LoadLvlGFX"); + break; + } +} + +void LoadAllGFX() +{ + /// ASSERT: assert(! pSpeedCels); + pSpeedCels = DiabloAllocPtr(0x100000); + IncProgress(); + IncProgress(); + InitObjectGFX(); + IncProgress(); + InitMissileGFX(); + IncProgress(); +} + +void CreateLevel(int lvldir) +{ + switch((unsigned char)leveltype) { + case DTYPE_TOWN: + CreateTown(lvldir); + InitTownTriggers(); + LoadRndLvlPal(0); + break; + case DTYPE_CATHEDRAL: + CreateL5Dungeon(glSeedTbl[currlevel], lvldir); + InitL1Triggers(); + Freeupstairs(); + LoadRndLvlPal(1); + break; + case DTYPE_CATACOMBS: + CreateL2Dungeon(glSeedTbl[currlevel], lvldir); + InitL2Triggers(); + Freeupstairs(); + LoadRndLvlPal(2); + break; + case DTYPE_CAVES: + CreateL3Dungeon(glSeedTbl[currlevel], lvldir); + InitL3Triggers(); + Freeupstairs(); + LoadRndLvlPal(3); + break; + case DTYPE_HELL: + CreateL4Dungeon(glSeedTbl[currlevel], lvldir); + InitL4Triggers(); + Freeupstairs(); + LoadRndLvlPal(4); + break; + default: + app_fatal("CreateLevel"); + break; + } +} + +void LoadGameLevel(BOOL firstflag, int lvldir) +{ + int i, j; + BOOL visited; + + if(setseed) + glSeedTbl[currlevel] = setseed; + + music_stop(); + SetCursor_(CURSOR_HAND); + SetRndSeed(glSeedTbl[currlevel]); + IncProgress(); + MakeLightTable(); + LoadLvlGFX(); + IncProgress(); + + if(firstflag) { + InitInv(); + InitItemGFX(); + InitQuestText(); + + for(i = 0; i < gbMaxPlayers; i++) + InitPlrGFXMem(i); + + InitStores(); + InitAutomapOnce(); + InitHelp(); + } + + SetRndSeed(glSeedTbl[currlevel]); + + if(leveltype == DTYPE_TOWN) + SetupTownStores(); + + IncProgress(); + InitAutomap(); + + if(leveltype != DTYPE_TOWN && lvldir != 4) { + InitLighting(); + InitVision(); + } + + InitLevelMonsters(); + IncProgress(); + + if(!setlevel) { + CreateLevel(lvldir); + IncProgress(); + FillSolidBlockTbls(); + SetRndSeed(glSeedTbl[currlevel]); + + if(leveltype != DTYPE_TOWN) { + GetLevelMTypes(); + InitThemes(); + LoadAllGFX(); + } else { + InitMissileGFX(); + } + + IncProgress(); + + if(lvldir == 3) + GetReturnLvlPos(); + if(lvldir == 5) + GetPortalLvlPos(); + + IncProgress(); + + for(i = 0; i < MAX_PLRS; i++) { + if(plr[i].plractive && currlevel == plr[i].plrlevel) { + InitPlayerGFX(i); + if(lvldir != 4) + InitPlayer(i, firstflag); + } + } + + PlayDungMsgs(); + InitMultiView(); + IncProgress(); + + visited = FALSE; + for(i = 0; i < gbMaxPlayers; i++) { + if(plr[i].plractive) + visited = visited || plr[i]._pLvlVisited[currlevel]; + } + + SetRndSeed(glSeedTbl[currlevel]); + + if(leveltype != DTYPE_TOWN) { + if(firstflag || lvldir == 4 || !plr[myplr]._pLvlVisited[currlevel] || gbMaxPlayers != 1) { + HoldThemeRooms(); + glMid1Seed[currlevel] = GetRndSeed(); + InitMonsters(); + glMid2Seed[currlevel] = GetRndSeed(); + InitObjects(); + InitItems(); + CreateThemeRooms(); + glMid3Seed[currlevel] = GetRndSeed(); + InitMissiles(); + InitDead(); + glEndSeed[currlevel] = GetRndSeed(); + + if(gbMaxPlayers != 1) + DeltaLoadLevel(); + + IncProgress(); + SavePreLighting(); + } else { + InitMonsters(); + InitMissiles(); + InitDead(); + IncProgress(); + LoadLevel(); + IncProgress(); + } + } else { + for(i = 0; i < MAXDUNX; i++) { + for(j = 0; j < MAXDUNY; j++) + dFlags[i][j] |= 0x40; + } + + InitTowners(); + InitItems(); + InitMissiles(); + IncProgress(); + + if(!firstflag && lvldir != 4 && plr[myplr]._pLvlVisited[currlevel] && gbMaxPlayers == 1) + LoadLevel(); + if(gbMaxPlayers != 1) + DeltaLoadLevel(); + + IncProgress(); + } + if(gbMaxPlayers == 1) + ResyncQuests(); + else + ResyncMPQuests(); + } else { + /// ASSERT: assert(! pSpeedCels); + pSpeedCels = DiabloAllocPtr(0x100000); + LoadSetMap(); + IncProgress(); + GetLevelMTypes(); + InitMonsters(); + InitMissileGFX(); + InitDead(); + FillSolidBlockTbls(); + IncProgress(); + + if(lvldir == 5) + GetPortalLvlPos(); + + for(i = 0; i < MAX_PLRS; i++) { + if(plr[i].plractive && currlevel == plr[i].plrlevel) { + InitPlayerGFX(i); + if(lvldir != 4) + InitPlayer(i, firstflag); + } + } + + InitMultiView(); + IncProgress(); + + if(firstflag || lvldir == 4 || !plr[myplr]._pSLvlVisited[(unsigned char)setlvlnum]) { + InitItems(); + SavePreLighting(); + } else { + LoadLevel(); + } + + InitMissiles(); + IncProgress(); + } + + SyncPortals(); + + for(i = 0; i < MAX_PLRS; i++) { + if(plr[i].plractive && plr[i].plrlevel == currlevel && (!plr[i]._pLvlChanging || i == myplr)) { + if(plr[i]._pHitPoints > 0) { + if(gbMaxPlayers == 1) + dPlayer[plr[i].WorldX][plr[i].WorldY] = i + 1; + else + SyncInitPlrPos(i); + } else { + dFlags[plr[i].WorldX][plr[i].WorldY] |= 4; + } + } + } + + if(leveltype != DTYPE_TOWN) + SetDungeonMicros(); + + InitLightMax(); + IncProgress(); + IncProgress(); + + if(firstflag) { + InitControlPan(); + IncProgress(); + } + if(leveltype != DTYPE_TOWN) { + ProcessLightList(); + ProcessVisionList(); + } + + music_start((unsigned char)leveltype); + + while(!IncProgress()); + + if(setlevel && setlvlnum == SL_SKELKING && quests[12]._qactive == 2) + PlaySFX(USFX_SKING1); +} + +void game_loop(BOOL bStartup) +{ + int i; + + i = bStartup ? 60 : 3; + + while(i--) { + if(!multi_handle_delta()) { + timeout_cursor(1); + break; + } else { + timeout_cursor(0); + game_logic(); + } + if(!gbRunGame || gbMaxPlayers == 1 || !nthread_has_500ms_passed(1)) + break; + } +} + +void game_logic() +{ + if(PauseMode == 2) { + return; + } + if(PauseMode == 1) { + PauseMode = 2; + } + if(gbMaxPlayers == 1 && gmenu_is_active()) { + force_redraw |= 1; + return; + } + + if(!gmenu_is_active() && sgnTimeoutCurs == 0) { + CheckCursMove(); + track_process(); + } + if(gbProcessPlayers) { + ProcessPlayers(); + } + if(leveltype != DTYPE_TOWN) { + ProcessMonsters(); + ProcessObjects(); + ProcessMissiles(); + ProcessItems(); + ProcessLightList(); + ProcessVisionList(); + } else { + ProcessTowners(); + ProcessItems(); + ProcessMissiles(); + } + +#ifdef _DEBUG + if(debug_mode_key_inverted_v && GetAsyncKeyState(VK_SHIFT) & 0x8000) { + ScrollView(); + } +#endif + + sound_update(); + ClearPlrMsg(); + CheckTriggers(); + CheckQuests(); + force_redraw |= 1; + pfile_update(FALSE); +} + +void timeout_cursor(BOOL bTimeout) +{ + if ( bTimeout ) + { + if ( sgnTimeoutCurs == CURSOR_NONE && !sgbMouseDown ) + { + sgnTimeoutCurs = pcurs; + multi_net_ping(); + ClearPanel(); + AddPanelString("-- Network timeout --", 1); + AddPanelString("-- Waiting for players --", 1); + SetCursor_(CURSOR_HOURGLASS); + force_redraw = 255; + } + scrollrt_draw_game_screen(1); + } + else if ( sgnTimeoutCurs ) + { + SetCursor_(sgnTimeoutCurs); + sgnTimeoutCurs = 0; + ClearPanel(); + force_redraw = 255; + } +} + +void diablo_color_cyc_logic() +{ + DWORD v0; // eax + + v0 = GetTickCount(); + if ( v0 - color_cycle_timer >= 0x32 ) + { + color_cycle_timer = v0; + if ( palette_get_colour_cycling() ) + { + if ( leveltype == DTYPE_HELL ) + { + lighting_color_cycling(); + } + else if ( leveltype == DTYPE_CAVES ) + { + if ( fullscreen ) + palette_update_caves(); + } + } + } +} diff --git a/2020_03_31/Source/diablo.h b/2020_03_31/Source/diablo.h new file mode 100644 index 00000000..f747eecc --- /dev/null +++ b/2020_03_31/Source/diablo.h @@ -0,0 +1,173 @@ +//HEADER_GOES_HERE +#ifndef __DIABLO_H__ +#define __DIABLO_H__ + +#include "../types.h" + +#include "appfat.h" +#include "automap.h" +#include "capture.h" +#include "codec.h" +#include "control.h" +#include "cursor.h" +#include "dead.h" +#include "debug.h" +#include "doom.h" +#include "drlg_l1.h" +#include "drlg_l2.h" +#include "drlg_l3.h" +#include "drlg_l4.h" +#include "dthread.h" +#include "dx.h" +#include "effects.h" +#include "encrypt.h" +#include "engine.h" +#include "error.h" +#include "fault.h" +#include "gamemenu.h" +#include "gendung.h" +#include "gmenu.h" +#include "help.h" +#include "init.h" +#include "interfac.h" +#include "inv.h" +#include "itemdat.h" +#include "items.h" +#include "lighting.h" +#include "loadsave.h" +#include "logging.h" +#include "mainmenu.h" +#include "minitext.h" +#include "misdat.h" +#include "missiles.h" +#include "monstdat.h" +#include "monster.h" +#include "movie.h" +#include "mpqapi.h" +#include "msg.h" +#include "msgcmd.h" +#include "multi.h" +#include "nthread.h" +#include "objdat.h" +#include "objects.h" +#include "pack.h" +#include "palette.h" +#include "path.h" +#include "pfile.h" +#include "player.h" +#include "plrmsg.h" +#include "portal.h" +#include "quests.h" +#include "restrict.h" +#include "scrollrt.h" +#include "setmaps.h" +#include "sha.h" +#include "sound.h" +#include "spelldat.h" +#include "spells.h" +#include "stores.h" +#include "sync.h" +#include "textdat.h" // check file name +#include "themes.h" +#include "tmsg.h" +#include "town.h" +#include "towners.h" +#include "track.h" +#include "trigs.h" +#include "wave.h" +#include "render.h" // linked last, likely .s/.asm + + +extern HWND ghMainWnd; +extern int glMid1Seed[NUMLEVELS]; +extern int glMid2Seed[NUMLEVELS]; +extern int gnLevelTypeTbl[NUMLEVELS]; +extern int MouseY; // idb +extern int MouseX; // idb +extern BOOL gbGameLoopStartup; // idb +extern int glSeedTbl[NUMLEVELS]; +extern int gbRunGame; // weak +extern int glMid3Seed[NUMLEVELS]; +extern int gbRunGameResult; // weak +extern int zoomflag; // weak +extern int gbProcessPlayers; // weak +extern int glEndSeed[NUMLEVELS]; +extern int gbLoadGame; // weak +extern HINSTANCE ghInst; // idb +extern int DebugMonsters[10]; +extern char cineflag; // weak +extern int force_redraw; // weak +extern int visiondebug; // weak +extern int scrollflag; /* unused */ +extern int light4flag; // weak +extern int leveldebug; // weak +extern int monstdebug; // weak +extern int trigdebug; /* unused */ +extern int setseed; // weak +extern int debugmonsttypes; // weak +extern int PauseMode; // weak +extern int sgnTimeoutCurs; +extern char sgbMouseDown; // weak +extern int color_cycle_timer; // weak + +void FreeGameMem(); +BOOL StartGame(BOOL bNewGame, BOOL bSinglePlayer); +void run_game_loop(unsigned int uMsg); +void start_game(unsigned int uMsg); +void free_game(); +BOOL diablo_get_not_running(); +int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow); +void diablo_parse_flags(char *args); +void diablo_init_screen(); +BOOL diablo_find_window(LPCSTR lpClassName); +void diablo_reload_process(HINSTANCE hInstance); +BOOL PressEscKey(); +LRESULT CALLBACK DisableInputWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); +LRESULT CALLBACK GM_Game(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); +BOOL LeftMouseDown(int wParam); +BOOL LeftMouseCmd(BOOL bShift); +BOOL TryIconCurs(); +void LeftMouseUp(); +void RightMouseDown(); +void j_gmenu_on_mouse_move(LPARAM lParam); +BOOL PressSysKey(int wParam); +void diablo_hotkey_msg(DWORD dwMsg); +void ReleaseKey(int vkey); +void PressKey(int vkey); +void diablo_pause_game(); +void PressChar(int vkey); +void LoadLvlGFX(); +void LoadAllGFX(); +void CreateLevel(int lvldir); +void LoadGameLevel(BOOL firstflag, int lvldir); +void game_loop(BOOL bStartup); +void game_logic(); +void timeout_cursor(BOOL bTimeout); +void diablo_color_cyc_logic(); + +/* rdata */ + +extern int fullscreen; // weak +#ifdef _DEBUG +extern int showintrodebug; +extern int questdebug; +extern int debug_mode_key_s; +extern int debug_mode_key_w; +extern int debug_mode_key_inverted_v; +extern int debug_mode_dollar_sign; +extern int debug_mode_key_d; +extern int debug_mode_key_i; +extern int dbgplr; +extern int dbgqst; +extern int dbgmon; +extern int arrowdebug; +extern int frameflag; +extern int frameend; +extern int framerate; +extern int framestart; +#endif +extern int FriendlyMode; // weak +extern char *spszMsgTbl[4]; // weak +extern char *spszMsgKeyTbl[4]; // weak + +#endif /* __DIABLO_H__ */ diff --git a/2020_03_31/Source/doom.cpp b/2020_03_31/Source/doom.cpp new file mode 100644 index 00000000..42c568dc --- /dev/null +++ b/2020_03_31/Source/doom.cpp @@ -0,0 +1,85 @@ +#include "diablo.h" + +int doom_quest_time; // weak +int doom_stars_drawn; // weak +void *pDoomCel; +int doomflag; // weak +int DoomQuestState; // idb + +int doom_get_frame_from_time() +{ + int result; // eax + + if ( DoomQuestState == 36001 ) + result = 31; + else + result = DoomQuestState / 1200; + return result; +} + +void doom_alloc_cel() +{ + pDoomCel = DiabloAllocPtr(229376); +} + +void doom_cleanup() +{ + void *v0; // ecx + + v0 = pDoomCel; + pDoomCel = 0; + mem_free_dbg(v0); +} + +void doom_load_graphics() +{ + if ( doom_quest_time == 31 ) + { + strcpy(tempstr, "Items\\Map\\MapZDoom.CEL"); + } + else if ( doom_quest_time >= 10 ) + { + sprintf(tempstr, "Items\\Map\\MapZ00%i.CEL", doom_quest_time); + } + else + { + sprintf(tempstr, "Items\\Map\\MapZ000%i.CEL", doom_quest_time); + } + LoadFileWithMem(tempstr, pDoomCel); +} + +void doom_init() +{ + int v0; // eax + + doomflag = 1; + doom_alloc_cel(); + v0 = -(doom_get_frame_from_time() != 31); + _LOBYTE(v0) = v0 & 0xE1; + doom_quest_time = v0 + 31; + doom_load_graphics(); +} + +void doom_close() +{ + if ( doomflag ) + { + doomflag = 0; + doom_cleanup(); + } +} + +void doom_draw() +{ + if ( doomflag ) + { + if ( doom_quest_time != 31 && ++doom_stars_drawn >= 5 ) + { + doom_stars_drawn = 0; + if ( ++doom_quest_time > doom_get_frame_from_time() ) + doom_quest_time = 0; + doom_load_graphics(); + } + CelDecodeOnly(64, 511, (BYTE *)pDoomCel, 1, 640); + } +} diff --git a/2020_03_31/Source/doom.h b/2020_03_31/Source/doom.h new file mode 100644 index 00000000..7bd0a6c1 --- /dev/null +++ b/2020_03_31/Source/doom.h @@ -0,0 +1,19 @@ +//HEADER_GOES_HERE +#ifndef __DOOM_H__ +#define __DOOM_H__ + +extern int doom_quest_time; // weak +extern int doom_stars_drawn; // weak +extern void *pDoomCel; +extern int doomflag; // weak +extern int DoomQuestState; // idb + +int doom_get_frame_from_time(); +void doom_alloc_cel(); +void doom_cleanup(); +void doom_load_graphics(); +void doom_init(); +void doom_close(); +void doom_draw(); + +#endif /* __DOOM_H__ */ diff --git a/2020_03_31/Source/drlg_l1.cpp b/2020_03_31/Source/drlg_l1.cpp new file mode 100644 index 00000000..9d8f0fe3 --- /dev/null +++ b/2020_03_31/Source/drlg_l1.cpp @@ -0,0 +1,1747 @@ +#include "diablo.h" + +char L5dungeon[80][80]; +unsigned char L5dflags[40][40]; +int setloadflag; // weak +int HR1; +int HR2; +int HR3; +int VR1; +int VR2; +int VR3; +void *pSetPiece; // idb + +const ShadowStruct SPATS[37] = +{ + { 7, 13, 0, 13, 144, 0, 142 }, + { 16, 13, 0, 13, 144, 0, 142 }, + { 15, 13, 0, 13, 145, 0, 142 }, + { 5, 13, 13, 13, 152, 140, 139 }, + { 5, 13, 1, 13, 143, 146, 139 }, + { 5, 13, 13, 2, 143, 140, 148 }, + { 5, 0, 1, 2, 0, 146, 148 }, + { 5, 13, 11, 13, 143, 147, 139 }, + { 5, 13, 13, 12, 143, 140, 149 }, + { 5, 13, 11, 12, 150, 147, 149 }, + { 5, 13, 1, 12, 143, 146, 149 }, + { 5, 13, 11, 2, 143, 147, 148 }, + { 9, 13, 13, 13, 144, 140, 142 }, + { 9, 13, 1, 13, 144, 146, 142 }, + { 9, 13, 11, 13, 151, 147, 142 }, + { 8, 13, 0, 13, 144, 0, 139 }, + { 8, 13, 0, 12, 143, 0, 149 }, + { 8, 0, 0, 2, 0, 0, 148 }, + { 11, 0, 0, 13, 0, 0, 139 }, + { 11, 13, 0, 13, 139, 0, 139 }, + { 11, 2, 0, 13, 148, 0, 139 }, + { 11, 12, 0, 13, 149, 0, 139 }, + { 11, 13, 11, 12, 139, 0, 149 }, + { 14, 0, 0, 13, 0, 0, 139 }, + { 14, 13, 0, 13, 139, 0, 139 }, + { 14, 2, 0, 13, 148, 0, 139 }, + { 14, 12, 0, 13, 149, 0, 139 }, + { 14, 13, 11, 12, 139, 0, 149 }, + { 10, 0, 13, 0, 0, 140, 0 }, + { 10, 13, 13, 0, 140, 140, 0 }, + { 10, 0, 1, 0, 0, 146, 0 }, + { 10, 13, 11, 0, 140, 147, 0 }, + { 12, 0, 13, 0, 0, 140, 0 }, + { 12, 13, 13, 0, 140, 140, 0 }, + { 12, 0, 1, 0, 0, 146, 0 }, + { 12, 13, 11, 0, 140, 147, 0 }, + { 3, 13, 11, 12, 150, 0, 0 } +}; +const unsigned char BSTYPES[206] = +{ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 0, 0, + 0, 0, 0, 0, 0, 1, 2, 10, 4, 5, + 6, 7, 8, 9, 10, 11, 12, 14, 5, 14, + 10, 4, 14, 4, 5, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 2, 3, 4, 1, 6, 7, 16, 17, 2, 1, + 1, 2, 2, 1, 1, 2, 2, 2, 2, 2, + 1, 1, 11, 1, 13, 13, 13, 1, 2, 1, + 2, 1, 2, 1, 2, 2, 2, 2, 12, 0, + 0, 11, 1, 11, 1, 13, 0, 0, 0, 0, + 0, 0, 0, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 1, 11, 2, 12, + 13, 13, 13, 12, 2, 1, 2, 2, 4, 14, + 4, 10, 13, 13, 4, 4, 1, 1, 4, 2, + 2, 13, 13, 13, 13, 25, 26, 28, 30, 31, + 41, 43, 40, 41, 42, 43, 25, 41, 43, 28, + 28, 1, 2, 25, 26, 22, 22, 25, 26, 0, + 0, 0, 0, 0, 0, 0 +}; +const unsigned char L5BTYPES[206] = +{ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 0, 0, + 0, 0, 0, 0, 0, 25, 26, 0, 28, 0, + 30, 31, 0, 0, 0, 0, 0, 0, 0, 0, + 40, 41, 42, 43, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 79, + 80, 0, 82, 0, 0, 0, 0, 0, 0, 79, + 0, 80, 0, 0, 79, 80, 0, 2, 2, 2, + 1, 1, 11, 25, 13, 13, 13, 1, 2, 1, + 2, 1, 2, 1, 2, 2, 2, 2, 12, 0, + 0, 11, 1, 11, 1, 13, 0, 0, 0, 0, + 0, 0, 0, 13, 13, 13, 13, 13, 13, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 +}; +const unsigned char STAIRSUP[] = { 4, 4, 13, 13, 13, 13, 2, 2, 2, 2, 13, 13, 13, 13, 13, 13, 13, 13, 0, 66, 6, 0, 63, 64, 65, 0, 0, 67, 68, 0, 0, 0, 0, 0 }; +const unsigned char L5STAIRSUP[] = { 4, 4, 22, 22, 22, 22, 2, 2, 2, 2, 13, 13, 13, 13, 13, 13, 13, 13, 0, 66, 23, 0, 63, 64, 65, 0, 0, 67, 68, 0, 0, 0, 0, 0 }; +const unsigned char STAIRSDOWN[] = { 4, 3, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 62, 57, 58, 0, 61, 59, 60, 0, 0, 0, 0, 0 }; +const unsigned char LAMPS[] = { 2, 2, 13, 0, 13, 13, 129, 0, 130, 128 }; +const unsigned char PWATERIN[] = { 6, 6, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 0, 0, 0, 0, 0, 0, 0, 202, 200, 200, 84, 0, 0, 199, 203, 203, 83, 0, 0, 85, 206, 80, 81, 0, 0, 0, 134, 135, 0, 0, 0, 0, 0, 0, 0, 0 }; + +/* data */ +unsigned char L5ConvTbl[16] = +{ + 22u, 13u, + 1u, 13u, + 2u, 13u, + 13u, 13u, + 4u, 13u, + 1u, 13u, + 2u, 13u, + 16u, 13u +}; + +static void DRLG_PlaceDoor(int x, int y) +{ + if((L5dflags[x][y] & 0x80) == 0) { /* todo: unsigned */ + unsigned char df = L5dflags[x][y] & 0x7F; + unsigned char c = dungeon[x][y]; + + if(df == 1) { + if(y != 1 && c == 2) + dungeon[x][y] = 26; + if(y != 1 && c == 7) + dungeon[x][y] = 31; + if(y != 1 && c == 14) + dungeon[x][y] = 42; + if(y != 1 && c == 4) + dungeon[x][y] = 43; + if(x != 1 && c == 1) + dungeon[x][y] = 25; + if(x != 1 && c == 10) + dungeon[x][y] = 40; + if(x != 1 && c == 6) + dungeon[x][y] = 30; + } + if(df == 2) { + if(x != 1 && c == 1) + dungeon[x][y] = 25; + if(x != 1 && c == 6) + dungeon[x][y] = 30; + if(x != 1 && c == 10) + dungeon[x][y] = 40; + if(x != 1 && c == 4) + dungeon[x][y] = 41; + if(y != 1 && c == 2) + dungeon[x][y] = 26; + if(y != 1 && c == 14) + dungeon[x][y] = 42; + if(y != 1 && c == 7) + dungeon[x][y] = 31; + } + if(df == 3) { + if(x != 1 && y != 1 && c == 4) + dungeon[x][y] = 28; + if(x != 1 && c == 10) + dungeon[x][y] = 40; + if(y != 1 && c == 14) + dungeon[x][y] = 42; + if(y != 1 && c == 2) + dungeon[x][y] = 26; + if(x != 1 && c == 1) + dungeon[x][y] = 25; + if(y != 1 && c == 7) + dungeon[x][y] = 31; + if(x != 1 && c == 6) + dungeon[x][y] = 30; + } + } + + L5dflags[x][y] = 0x80; +} + +static void DRLG_L1Shadows() +{ + int x, y; + unsigned char sd[2][2]; + unsigned char tnv3; + + for(y = 1; y < DMAXY; y++) { + for(x = 1; x < DMAXX; x++) { + sd[0][0] = BSTYPES[(unsigned char)dungeon[x][y]]; + sd[1][0] = BSTYPES[(unsigned char)dungeon[x-1][y]]; + sd[0][1] = BSTYPES[(unsigned char)dungeon[x][y-1]]; + sd[1][1] = BSTYPES[(unsigned char)dungeon[x-1][y-1]]; + + for(int i = 0; i < 37; i++) { + if(SPATS[i].strig == sd[0][0]) { + BOOL patflag = TRUE; + if(SPATS[i].s1 && SPATS[i].s1 != sd[1][1]) + patflag = FALSE; + if(SPATS[i].s2 && SPATS[i].s2 != sd[0][1]) + patflag = FALSE; + if(SPATS[i].s3 && SPATS[i].s3 != sd[1][0]) + patflag = FALSE; + if(patflag == TRUE) { + if(SPATS[i].nv1 && !L5dflags[x-1][y-1]) + dungeon[x-1][y-1] = SPATS[i].nv1; + if(SPATS[i].nv2 && !L5dflags[x][y-1]) + dungeon[x][y-1] = SPATS[i].nv2; + if(SPATS[i].nv3) { + if(!L5dflags[x-1][y]) + dungeon[x-1][y] = SPATS[i].nv3; + } + } + } + } + } + } + + for(y = 1; y < DMAXY; y++) { + for(x = 1; x < DMAXX; x++) { + if((unsigned char)dungeon[x-1][y] == 139 && !L5dflags[x-1][y]) { + tnv3 = 139; + if(dungeon[x][y] == 29) + tnv3 = 141; + if(dungeon[x][y] == 32) + tnv3 = 141; + if(dungeon[x][y] == 35) + tnv3 = 141; + if(dungeon[x][y] == 37) + tnv3 = 141; + if(dungeon[x][y] == 38) + tnv3 = 141; + if(dungeon[x][y] == 39) + tnv3 = 141; + dungeon[x-1][y] = tnv3; + } + if((unsigned char)dungeon[x-1][y] == 149 && !L5dflags[x-1][y]) { + tnv3 = 149; + if(dungeon[x][y] == 29) + tnv3 = 153; + if(dungeon[x][y] == 32) + tnv3 = 153; + if(dungeon[x][y] == 35) + tnv3 = 153; + if(dungeon[x][y] == 37) + tnv3 = 153; + if(dungeon[x][y] == 38) + tnv3 = 153; + if(dungeon[x][y] == 39) + tnv3 = 153; + dungeon[x-1][y] = tnv3; + } + if((unsigned char)dungeon[x-1][y] == 148 && !L5dflags[x-1][y]) { + tnv3 = 148; + if(dungeon[x][y] == 29) + tnv3 = 154; + if(dungeon[x][y] == 32) + tnv3 = 154; + if(dungeon[x][y] == 35) + tnv3 = 154; + if(dungeon[x][y] == 37) + tnv3 = 154; + if(dungeon[x][y] == 38) + tnv3 = 154; + if(dungeon[x][y] == 39) + tnv3 = 154; + dungeon[x-1][y] = tnv3; + } + } + } +} + +static int DRLG_PlaceMiniSet(const unsigned char *miniset, int tmin, int tmax, int cx, int cy, BOOL setview, int noquad, int ldir) +{ + int xx, yy, sx, sy; + int ii; + int numt; + + int sw = miniset[0]; + int sh = miniset[1]; + + if(tmax - tmin == 0) + numt = 1; + else + numt = random(0, tmax - tmin) + tmin; + + for(int i = 0; i < numt; i++) { + sx = random(0, 40 - sw); + sy = random(0, 40 - sh); + BOOL abort = FALSE; + int found = 0; + + while(abort == FALSE) { + abort = TRUE; + if(cx != -1 && sx >= cx - sw && sx <= cx + 12) { + sx++; + abort = FALSE; + } + if(cy != -1 && sy >= cy - sh && sy <= cy + 12) { + sy++; + abort = FALSE; + } + + switch(noquad) { + case 0: + if(sx < cx && sy < cy) + abort = FALSE; + break; + case 1: + if(sx > cx && sy < cy) + abort = FALSE; + break; + case 2: + if(sx < cx && sy > cy) + abort = FALSE; + break; + case 3: + if(sx > cx && sy > cy) + abort = FALSE; + break; + default: + break; + } + + ii = 2; + + for(yy = 0; yy < sh && abort == TRUE; yy++) { + for(xx = 0; xx < sw && abort == TRUE; xx++) { + if(miniset[ii] && (unsigned char)dungeon[xx + sx][sy + yy] != miniset[ii]) + abort = FALSE; + if(L5dflags[xx + sx][sy + yy]) + abort = FALSE; + ii++; + } + } + + if(abort == FALSE) { + if(++sx == 40 - sw) { + sx = 0; + if(++sy == 40 - sh) + sy = 0; + } + if(++found > 4000) + return -1; + } + } + + ii = sw * sh + 2; + + for(yy = 0; yy < sh; yy++) { + for(xx = 0; xx < sw; xx++) { + if(miniset[ii]) + dungeon[xx + sx][sy + yy] = miniset[ii]; + ii++; + } + } + } + + if(miniset == PWATERIN) { + int t = TransVal; + TransVal = 0; + DRLG_MRectTrans(sx, sy + 2, sx + 5, sy + 4); + TransVal = t; + + quests[13]._qtx = 2 * sx + 21; + quests[13]._qty = 2 * sy + 22; + } + + if(setview == TRUE) { + ViewX = 2 * sx + 19; + ViewY = 2 * sy + 20; + } + + if(ldir == 0) { + LvlViewX = 2 * sx + 19; + LvlViewY = 2 * sy + 20; + } + + if(sx < cx && sy < cy) + return 0; + if(sx > cx && sy < cy) + return 1; + if(sx < cx && sy > cy) + return 2; + else + return 3; +} + +static void DRLG_L1Floor() +{ + for(int j = 0; j < DMAXY; j++) { + for(int i = 0; i < DMAXX; i++) { + if(L5dflags[i][j] == 0 && dungeon[i][j] == 13) + { + long rv = random(0, 3); + + if(rv == 1) + dungeon[i][j] = 162; + if(rv == 2) + dungeon[i][j] = 163; + } + } + } +} + +static void DRLG_L1Pass3() +{ + int i, j, xx, yy; + long v1, v2, v3, v4, lv; + + lv = 22-1; + +#ifdef USE_ASM + __asm { + mov esi, pMegaTiles + mov eax, lv + shl eax, 3 + add esi, eax + xor eax, eax + lodsw + inc eax + mov v1, eax + lodsw + inc eax + mov v2, eax + lodsw + inc eax + mov v3, eax + lodsw + inc eax + mov v4, eax + } +#else + v1 = ((WORD *)&pMegaTiles[lv << 3])[0] + 1; + v2 = ((WORD *)&pMegaTiles[lv << 3])[1] + 1; + v3 = ((WORD *)&pMegaTiles[lv << 3])[2] + 1; + v4 = ((WORD *)&pMegaTiles[lv << 3])[3] + 1; +#endif + + for(j = 0; j < MAXDUNY; j += 2) { + for(i = 0; i < MAXDUNX; i += 2) { + dPiece[i][j] = v1; + dPiece[i+1][j] = v2; + dPiece[i][j+1] = v3; + dPiece[i+1][j+1] = v4; + } + } + + yy = 16; + for(j = 0; j < DMAXY; j++) { + xx = 16; + for(i = 0; i < DMAXX; i++) { + lv = (unsigned char)dungeon[i][j]-1; + /// ASSERT: assert(lv >= 0); +#ifdef USE_ASM + __asm { + mov esi, pMegaTiles + mov eax, lv + shl eax, 3 + add esi, eax + xor eax, eax + lodsw + inc eax + mov v1, eax + lodsw + inc eax + mov v2, eax + lodsw + inc eax + mov v3, eax + lodsw + inc eax + mov v4, eax + } +#else + v1 = ((WORD *)&pMegaTiles[lv << 3])[0] + 1; + v2 = ((WORD *)&pMegaTiles[lv << 3])[1] + 1; + v3 = ((WORD *)&pMegaTiles[lv << 3])[2] + 1; + v4 = ((WORD *)&pMegaTiles[lv << 3])[3] + 1; +#endif + dPiece[xx][yy] = v1; + dPiece[xx+1][yy] = v2; + dPiece[xx][yy+1] = v3; + dPiece[xx+1][yy+1] = v4; + xx += 2; + } + yy += 2; + } +} + +static void DRLG_LoadL1SP() +{ + setloadflag = 0; + if ( QuestStatus(6) ) + { + pSetPiece = DiabLoad("Levels\\L1Data\\rnd6.DUN", NULL, 'STPC'); + setloadflag = 1; + } + if ( QuestStatus(12) && gbMaxPlayers == 1 ) + { + pSetPiece = DiabLoad("Levels\\L1Data\\SKngDO.DUN", NULL, 'STPC'); + setloadflag = 1; + } + if ( QuestStatus(7) ) + { + pSetPiece = DiabLoad("Levels\\L1Data\\Banner2.DUN", NULL, 'STPC'); + setloadflag = 1; + } +} + +static void DRLG_FreeL1SP() +{ + MemFreeDbg(pSetPiece); +} + +void DRLG_Init_Globals() +{ + char c; + + memset(dFlags, 0, sizeof(dFlags)); + memset(dPlayer, 0, sizeof(dPlayer)); + memset(dMonster, 0, sizeof(dMonster)); + memset(dDead, 0, sizeof(dDead)); + memset(dObject, 0, sizeof(dObject)); + memset(dItem, 0, sizeof(dItem)); + memset(dMissile, 0, sizeof(dMissile)); + memset(dSpecial, 0, sizeof(dSpecial)); + + if(!lightflag) { + if(light4flag) { + c = 3; + } else { + c = 15; + } + } else { + c = 0; + } + + memset(dLight, c, sizeof(dLight)); +} + +static void DRLG_InitL1Vals() +{ + int i, j, pc; + + for(j = 0; j < MAXDUNY; j++) { + for(i = 0; i < MAXDUNX; i++) { + if(dPiece[i][j] == 12) { + pc = 1; + } else if(dPiece[i][j] == 11) { + pc = 2; + } else if(dPiece[i][j] == 71) { + pc = 1; + } else if(dPiece[i][j] == 259) { + pc = 5; + } else if(dPiece[i][j] == 249) { + pc = 2; + } else if(dPiece[i][j] == 325) { + pc = 2; + } else if(dPiece[i][j] == 321) { + pc = 1; + } else if(dPiece[i][j] == 255) { + pc = 4; + } else if(dPiece[i][j] == 211) { + pc = 1; + } else if(dPiece[i][j] == 344) { + pc = 2; + } else if(dPiece[i][j] == 341) { + pc = 1; + } else if(dPiece[i][j] == 331) { + pc = 2; + } else if(dPiece[i][j] == 418) { + pc = 1; + } else if(dPiece[i][j] == 421) { + pc = 2; + } else { + continue; + } + dSpecial[i][j] = pc; + } + } +} + +void LoadL1Dungeon(char *sFileName, int vx, int vy) +{ + int i, j, rw, rh; + BYTE *pLevelMap, *lm; + + dminx = 16; + dminy = 16; + dmaxx = 96; + dmaxy = 96; + + DRLG_InitTrans(); + pLevelMap = DiabLoad(sFileName, NULL, 'LMPt'); + + for(j = 0; j < DMAXY; j++) { + for(i = 0; i < DMAXX; i++) { + dungeon[i][j] = 22; + L5dflags[i][j] = 0; + } + } + + lm = pLevelMap; + rw = *lm; + lm += 2; + rh = *lm; + lm += 2; + + for(j = 0; j < rh; j++) { + for(i = 0; i < rw; i++) { + if(*lm != 0) { + dungeon[i][j] = *lm; + L5dflags[i][j] |= 0x80; + } else { + dungeon[i][j] = 13; + } + lm += 2; + } + } + + DRLG_L1Floor(); + ViewX = vx; + ViewY = vy; + DRLG_L1Pass3(); + DRLG_Init_Globals(); + DRLG_InitL1Vals(); + SetMapMonsters(pLevelMap, 0, 0); + SetMapObjects(pLevelMap, 0, 0); + mem_free_dbg(pLevelMap); +} + +void LoadPreL1Dungeon(char *sFileName, int vx, int vy) +{ + int i, j, rw, rh; + BYTE *pLevelMap, *lm; + + dminx = 16; + dminy = 16; + dmaxx = 96; + dmaxy = 96; + + pLevelMap = DiabLoad(sFileName, NULL, 'LMPt'); + + for(j = 0; j < DMAXY; j++) { + for(i = 0; i < DMAXX; i++) { + dungeon[i][j] = 22; + L5dflags[i][j] = 0; + } + } + + lm = pLevelMap; + rw = *lm; + lm += 2; + rh = *lm; + lm += 2; + + for(j = 0; j < rh; j++) { + for(i = 0; i < rw; i++) { + if(*lm != 0) { + dungeon[i][j] = *lm; + L5dflags[i][j] |= 0x80; + } else { + dungeon[i][j] = 13; + } + lm += 2; + } + } + + DRLG_L1Floor(); + + for(j = 0; j < DMAXY; j++) { + for(i = 0; i < DMAXX; i++) { + pdungeon[i][j] = dungeon[i][j]; + } + } + + mem_free_dbg(pLevelMap); +} + +static void InitL5Dungeon() +{ + for(int j = 0; j < DMAXY; j++) { + for(int i = 0; i < DMAXX; i++) { + dungeon[i][j] = 0; + L5dflags[i][j] = 0; + } + } +} + +static void L5ClearFlags() +{ + for(int j = 0; j < DMAXY; j++) { + for(int i = 0; i < DMAXX; i++) { + L5dflags[i][j] &= 0xBF; + } + } +} + +static void L5drawRoom(int x, int y, int w, int h) +{ + for(int j = 0; j < h; j++) { + for(int i = 0; i < w; i++) { + dungeon[x+i][y+j] = 1; + } + } +} + +static BOOL L5checkRoom(int x, int y, int width, int height) +{ + for(int j = 0; j < height; j++) { + for(int i = 0; i < width; i++) { + if(i+x < 0 || i+x >= DMAXX || j+y < 0 || j+y >= DMAXY) + return FALSE; + if(dungeon[i+x][j+y]) + return FALSE; + } + } + + return TRUE; +} + +static void L5roomGen(int x, int y, int w, int h, int dir) +{ + int num; + BOOL ran, ran2; + int width, height, rx, ry, ry2; + int cw, ch, cx1, cy1, cx2; + + int dirProb = random(0, 4); + + switch(dir == 1 ? dirProb != 0 : dirProb == 0) { + case FALSE: + num = 0; + do { + cw = (random(0, 5) + 2) & 0xFFFFFFFE; + ch = (random(0, 5) + 2) & 0xFFFFFFFE; + cy1 = h/2 + y - ch/2; + cx1 = x-cw; + ran = L5checkRoom(cx1-1, cy1-1, ch+2, cw+1); /// BUGFIX: swap args 3 and 4 ("ch+2" and "cw+1") + num++; + } while(ran == FALSE && num < 20); + + if(ran == TRUE) + L5drawRoom(cx1, cy1, cw, ch); + cx2 = x+w; + ran2 = L5checkRoom(cx2, cy1-1, cw+1, ch+2); + if(ran2 == TRUE) + L5drawRoom(cx2, cy1, cw, ch); + if(ran == TRUE) + L5roomGen(cx1, cy1, cw, ch, 1); + if(ran2 == TRUE) + L5roomGen(cx2, cy1, cw, ch, 1); + break; + case TRUE: + num = 0; + do { + width = (random(0, 5) + 2) & 0xFFFFFFFE; + height = (random(0, 5) + 2) & 0xFFFFFFFE; + rx = w/2 + x - width/2; + ry = y-height; + ran = L5checkRoom(rx-1, ry-1, width+2, height+1); + num++; + } while(ran == FALSE && num < 20); + + if(ran == TRUE) + L5drawRoom(rx, ry, width, height); + ry2 = y+h; + ran2 = L5checkRoom(rx-1, ry2, width+2, height+1); + if(ran2 == TRUE) + L5drawRoom(rx, ry2, width, height); + if(ran == TRUE) + L5roomGen(rx, ry, width, height, 0); + if(ran2 == TRUE) + L5roomGen(rx, ry2, width, height, 0); + break; + } +} + +static void L5firstRoom() +{ + if(random(0, 2) == 0) { + int ys = 1; + int ye = 39; + + VR1 = random(0, 2); + VR2 = random(0, 2); + VR3 = random(0, 2); + + if(VR1 + VR3 <= 1) + VR2 = 1; + if(VR1) + L5drawRoom(15, 1, 10, 10); + else + ys = 18; + + if(VR2) + L5drawRoom(15, 15, 10, 10); + if(VR3) + L5drawRoom(15, 29, 10, 10); + else + ye = 22; + + for(int y = ys; y < ye; y++) { + dungeon[17][y] = 1; + dungeon[18][y] = 1; + dungeon[19][y] = 1; + dungeon[20][y] = 1; + dungeon[21][y] = 1; + dungeon[22][y] = 1; + } + + if(VR1) + L5roomGen(15, 1, 10, 10, 0); + if(VR2) + L5roomGen(15, 15, 10, 10, 0); + if(VR3) + L5roomGen(15, 29, 10, 10, 0); + + HR3 = 0; + HR2 = 0; + HR1 = 0; + } + else { + int xs = 1; + int xe = 39; + + HR1 = random(0, 2); + HR2 = random(0, 2); + HR3 = random(0, 2); + + if(HR1 + HR3 <= 1) + HR2 = 1; + if(HR1) + L5drawRoom(1, 15, 10, 10); + else + xs = 18; + + if(HR2) + L5drawRoom(15, 15, 10, 10); + if(HR3) + L5drawRoom(29, 15, 10, 10); + else + xe = 22; + + for(int x = xs; x < xe; x++) { + dungeon[x][17] = 1; + dungeon[x][18] = 1; + dungeon[x][19] = 1; + dungeon[x][20] = 1; + dungeon[x][21] = 1; + dungeon[x][22] = 1; + } + + if(HR1) + L5roomGen(1, 15, 10, 10, 1); + if(HR2) + L5roomGen(15, 15, 10, 10, 1); + if(HR3) + L5roomGen(29, 15, 10, 10, 1); + + VR3 = 0; + VR2 = 0; + VR1 = 0; + } +} + +static int L5GetArea() +{ + int rv = 0; + + for(int j = 0; j < DMAXY; j++) { + for(int i = 0; i < DMAXX; i++) { + if(dungeon[i][j] == 1) + rv++; + } + } + + return rv; +} + +static void L5makeDungeon() +{ + int i, j, k, l; + + for(j = 0; j < DMAXY; j++) { + for(i = 0; i < DMAXX; i++) { + k = i << 1; + l = j << 1; + L5dungeon[k][l] = dungeon[i][j]; + L5dungeon[k][l + 1] = dungeon[i][j]; + L5dungeon[k + 1][l] = dungeon[i][j]; + L5dungeon[k + 1][l + 1] = dungeon[i][j]; + } + } +} + +static void L5makeDmt() +{ + int i, j, dmtx, dmty; + + for(j = 0; j < DMAXY; j++) { + for(i = 0; i < DMAXX; i++) { + dungeon[i][j] = 22; + } + } + + for(j = 0, dmty = 1; dmty <= 77; j++, dmty += 2) { + for(i = 0, dmtx = 1; dmtx <= 77; i++, dmtx += 2) { + int val = (unsigned char)L5dungeon[dmtx+1][dmty+1]; /* todo: unsigned */ + val = 2 * val + (unsigned char)L5dungeon[dmtx][dmty+1]; + val = 2 * val + (unsigned char)L5dungeon[dmtx+1][dmty]; + val = 2 * val + (unsigned char)L5dungeon[dmtx][dmty]; + dungeon[i][j] = L5ConvTbl[val]; + } + } +} + +static int L5HWallOk(int i, int j) +{ + int x; + + for(x = 1; dungeon[i+x][j] == 13; x++) { + if(dungeon[i+x][j-1] != 13 || dungeon[i+x][j+1] != 13 || L5dflags[i+x][j]) + break; + } + + BOOL wallok = FALSE; + if((unsigned char)dungeon[i+x][j] >= 3 && (unsigned char)dungeon[i+x][j] <= 7) /* todo: unsigned */ + wallok = TRUE; + if((unsigned char)dungeon[i+x][j] >= 16 && (unsigned char)dungeon[i+x][j] <= 24) + wallok = TRUE; + if(dungeon[i+x][j] == 22) + wallok = FALSE; + if(x == 1) + wallok = FALSE; + + if(wallok) + return x; + else + return -1; +} + +static int L5VWallOk(int i, int j) +{ + int y; + + for(y = 1; dungeon[i][j+y] == 13; y++) { + if(dungeon[i-1][j+y] != 13 || dungeon[i+1][j+y] != 13 || L5dflags[i][j+y]) + break; + } + + BOOL wallok = FALSE; + if((unsigned char)dungeon[i][j+y] >= 3 && (unsigned char)dungeon[i][j+y] <= 7) /* todo: unsigned */ + wallok = TRUE; + if((unsigned char)dungeon[i][j+y] >= 16 && (unsigned char)dungeon[i][j+y] <= 24) + wallok = TRUE; + if(dungeon[i][j+y] == 22) + wallok = FALSE; + if(y == 1) + wallok = FALSE; + + if(wallok) + return y; + else + return -1; +} + +static void L5HorizWall(int i, int j, char p, int dx) +{ + int xx; + char wt, dt; + + switch(random(0, 4)) { + case 0: + case 1: + dt = 2; + break; + case 2: + dt = 12; + if(p == 2) + p = 12; + if(p == 4) + p = 10; + break; + case 3: + dt = 36; + if(p == 2) + p = 36; + if(p == 4) + p = 27; + break; + default: + break; + } + + if(random(0, 6) == 5) + wt = 12; + else + wt = 26; + if(dt == 12) + wt = 12; + + dungeon[i][j] = p; + + for(xx = 1; xx < dx; xx++) { + dungeon[i+xx][j] = dt; + } + + xx = random(0, dx-1) + 1; + + if(wt == 12) { + dungeon[i+xx][j] = wt; + } + else { + dungeon[i+xx][j] = 2; + L5dflags[i+xx][j] |= 1; + } +} + +static void L5VertWall(int i, int j, char p, int dy) +{ + int yy; + char wt, dt; + + switch(random(0, 4)) { + case 0: + case 1: + dt = 1; + break; + case 2: + dt = 11; + if(p == 1) + p = 11; + if(p == 4) + p = 14; + break; + case 3: + dt = 35; + if(p == 1) + p = 35; + if(p == 4) + p = 37; + break; + default: + break; + } + + if(random(0, 6) == 5) + wt = 11; + else + wt = 25; + if(dt == 11) + wt = 11; + + dungeon[i][j] = p; + + for(yy = 1; yy < dy; yy++) { + dungeon[i][j+yy] = dt; + } + + yy = random(0, dy-1) + 1; + + if(wt == 11) { + dungeon[i][j+yy] = wt; + } + else { + dungeon[i][j+yy] = 1; + L5dflags[i][j+yy] |= 2; + } +} + +static void L5AddWall() +{ + for(int j = 0; j < DMAXY; j++) { + for(int i = 0; i < DMAXX; i++) { + if(!L5dflags[i][j]) { + if(dungeon[i][j] == 3 && random(0, 100) < 100) { + int x = L5HWallOk(i, j); + if(x != -1) + L5HorizWall(i, j, 2, x); + } + if(dungeon[i][j] == 3 && random(0, 100) < 100) { + int y = L5VWallOk(i, j); + if(y != -1) + L5VertWall(i, j, 1, y); + } + if(dungeon[i][j] == 6 && random(0, 100) < 100) { + int x = L5HWallOk(i, j); + if(x != -1) + L5HorizWall(i, j, 4, x); + } + if(dungeon[i][j] == 7 && random(0, 100) < 100) { + int y = L5VWallOk(i, j); + if(y != -1) + L5VertWall(i, j, 4, y); + } + if(dungeon[i][j] == 2 && random(0, 100) < 100) { + int x = L5HWallOk(i, j); + if(x != -1) + L5HorizWall(i, j, 2, x); + } + if(dungeon[i][j] == 1 && random(0, 100) < 100) { + int y = L5VWallOk(i, j); + if(y != -1) + L5VertWall(i, j, 1, y); + } + } + } + } +} + +static void DRLG_L5GChamber(int sx, int sy, BOOL topflag, BOOL bottomflag, BOOL leftflag, BOOL rightflag) +{ + int i, j; + + if(topflag == TRUE) { + dungeon[sx + 2][sy] = 12; + dungeon[sx + 3][sy] = 12; + dungeon[sx + 4][sy] = 3; + dungeon[sx + 7][sy] = 9; + dungeon[sx + 8][sy] = 12; + dungeon[sx + 9][sy] = 2; + } + if(bottomflag == TRUE) { + sy += 11; + dungeon[sx + 2][sy] = 10; + dungeon[sx + 3][sy] = 12; + dungeon[sx + 4][sy] = 8; + dungeon[sx + 7][sy] = 5; + dungeon[sx + 8][sy] = 12; + if(dungeon[sx + 9][sy] != 4) { + dungeon[sx + 9][sy] = 21; + } + sy -= 11; + } + if(leftflag == TRUE) { + dungeon[sx][sy + 2] = 11; + dungeon[sx][sy + 3] = 11; + dungeon[sx][sy + 4] = 3; + dungeon[sx][sy + 7] = 8; + dungeon[sx][sy + 8] = 11; + dungeon[sx][sy + 9] = 1; + } + if(rightflag == TRUE) { + sx += 11; + dungeon[sx][sy + 2] = 14; + dungeon[sx][sy + 3] = 11; + dungeon[sx][sy + 4] = 9; + dungeon[sx][sy + 7] = 5; + dungeon[sx][sy + 8] = 11; + if(dungeon[sx][sy + 9] != 4) { + dungeon[sx][sy + 9] = 21; + } + sx -= 11; + } + + for(j = 1; j < 11; j++) { + for(i = 1; i < 11; i++) { + dungeon[i + sx][j + sy] = 13; + L5dflags[i + sx][j + sy] |= 0x40; + } + } + + dungeon[sx + 4][sy + 4] = 15; + dungeon[sx + 7][sy + 4] = 15; + dungeon[sx + 4][sy + 7] = 15; + dungeon[sx + 7][sy + 7] = 15; +} + +static void DRLG_L5GHall(int x1, int y1, int x2, int y2) +{ + int i; + + if(y1 == y2) + { + for(i = x1; i < x2; i++) { + dungeon[i][y1] = 12; + dungeon[i][y1+3] = 12; + } + } + else + { + for(i = y1; i < y2; i++) { + dungeon[x1][i] = 11; + dungeon[x1+3][i] = 11; + } + } +} + +static void L5tileFix() +{ + int i, j; + + for(j = 0; j < DMAXY; j++) { + for(i = 0; i < DMAXX; i++) { + if(dungeon[i][j] == 2 && dungeon[i+1][j] == 22) + dungeon[i+1][j] = 23; + if(dungeon[i][j] == 13 && dungeon[i+1][j] == 22) + dungeon[i+1][j] = 18; + if(dungeon[i][j] == 13 && dungeon[i+1][j] == 2) + dungeon[i+1][j] = 7; + if(dungeon[i][j] == 6 && dungeon[i+1][j] == 22) + dungeon[i+1][j] = 24; + if(dungeon[i][j] == 1 && dungeon[i][j+1] == 22) + dungeon[i][j+1] = 24; + if(dungeon[i][j] == 13 && dungeon[i][j+1] == 1) + dungeon[i][j+1] = 6; + if(dungeon[i][j] == 13 && dungeon[i][j+1] == 22) + dungeon[i][j+1] = 19; + } + } + + for(j = 0; j < DMAXY; j++) { + for(i = 0; i < DMAXX; i++) { + if(dungeon[i][j] == 13 && dungeon[i+1][j] == 19) + dungeon[i+1][j] = 21; + if(dungeon[i][j] == 13 && dungeon[i+1][j] == 22) + dungeon[i+1][j] = 20; + if(dungeon[i][j] == 7 && dungeon[i+1][j] == 22) + dungeon[i+1][j] = 23; + if(dungeon[i][j] == 13 && dungeon[i+1][j] == 24) + dungeon[i+1][j] = 21; + if(dungeon[i][j] == 19 && dungeon[i+1][j] == 22) + dungeon[i+1][j] = 20; + if(dungeon[i][j] == 2 && dungeon[i+1][j] == 19) + dungeon[i+1][j] = 21; + if(dungeon[i][j] == 19 && dungeon[i+1][j] == 1) + dungeon[i+1][j] = 6; + if(dungeon[i][j] == 7 && dungeon[i+1][j] == 19) + dungeon[i+1][j] = 21; + if(dungeon[i][j] == 2 && dungeon[i+1][j] == 1) + dungeon[i+1][j] = 6; + if(dungeon[i][j] == 3 && dungeon[i+1][j] == 22) + dungeon[i+1][j] = 24; + if(dungeon[i][j] == 21 && dungeon[i+1][j] == 1) + dungeon[i+1][j] = 6; + if(dungeon[i][j] == 7 && dungeon[i+1][j] == 1) + dungeon[i+1][j] = 6; + if(dungeon[i][j] == 7 && dungeon[i+1][j] == 24) + dungeon[i+1][j] = 21; + if(dungeon[i][j] == 4 && dungeon[i+1][j] == 16) + dungeon[i+1][j] = 17; + if(dungeon[i][j] == 7 && dungeon[i+1][j] == 13) + dungeon[i+1][j] = 17; + if(dungeon[i][j] == 2 && dungeon[i+1][j] == 24) + dungeon[i+1][j] = 21; + if(dungeon[i][j] == 2 && dungeon[i+1][j] == 13) + dungeon[i+1][j] = 17; + if(dungeon[i][j] == 23 && dungeon[i-1][j] == 22) + dungeon[i-1][j] = 19; + if(dungeon[i][j] == 19 && dungeon[i-1][j] == 23) + dungeon[i-1][j] = 21; + if(dungeon[i][j] == 6 && dungeon[i-1][j] == 22) + dungeon[i-1][j] = 24; + if(dungeon[i][j] == 6 && dungeon[i-1][j] == 23) + dungeon[i-1][j] = 21; + if(dungeon[i][j] == 1 && dungeon[i][j+1] == 2) + dungeon[i][j+1] = 7; + if(dungeon[i][j] == 6 && dungeon[i][j+1] == 18) + dungeon[i][j+1] = 21; + if(dungeon[i][j] == 18 && dungeon[i][j+1] == 2) + dungeon[i][j+1] = 7; + if(dungeon[i][j] == 6 && dungeon[i][j+1] == 2) + dungeon[i][j+1] = 7; + if(dungeon[i][j] == 21 && dungeon[i][j+1] == 2) + dungeon[i][j+1] = 7; + if(dungeon[i][j] == 6 && dungeon[i][j+1] == 22) + dungeon[i][j+1] = 24; + if(dungeon[i][j] == 6 && dungeon[i][j+1] == 13) + dungeon[i][j+1] = 16; + if(dungeon[i][j] == 1 && dungeon[i][j+1] == 13) + dungeon[i][j+1] = 16; + if(dungeon[i][j] == 13 && dungeon[i][j+1] == 16) + dungeon[i][j+1] = 17; + if(dungeon[i][j] == 6 && dungeon[i][j-1] == 22) + dungeon[i][j-1] = 7; + if(dungeon[i][j] == 6 && dungeon[i][j-1] == 22) + dungeon[i][j-1] = 24; + if(dungeon[i][j] == 7 && dungeon[i][j-1] == 24) + dungeon[i][j-1] = 21; + if(dungeon[i][j] == 18 && dungeon[i][j-1] == 24) + dungeon[i][j-1] = 21; + } + } + + for(j = 0; j < DMAXY; j++) { + for(i = 0; i < DMAXX; i++) { + if(dungeon[i][j] == 4 && dungeon[i][j+1] == 2) + dungeon[i][j+1] = 7; + if(dungeon[i][j] == 2 && dungeon[i+1][j] == 19) + dungeon[i+1][j] = 21; + if(dungeon[i][j] == 18 && dungeon[i][j+1] == 22) + dungeon[i][j+1] = 20; + } + } +} + +static void DRLG_L5Subs() +{ + for(int y = 0; y < DMAXY; y++) { + for(int x = 0; x < DMAXX; x++) { + if(!random(0, 4)) + { + unsigned char c = L5BTYPES[(unsigned char)dungeon[x][y]]; /* todo: changed to unsigned */ + + if(c && !L5dflags[x][y]) + { + int rv = random(0, 16); + int i = -1; + + while(rv >= 0) { + if(++i == sizeof(L5BTYPES)) + i = 0; + if(c == L5BTYPES[i]) + rv--; + } + + if(i == 89) { + if(L5BTYPES[(unsigned char)dungeon[x][y-1]] != 79 || L5dflags[x][y-1]) + i = 79; + else + dungeon[x][y-1] = 90; + } + if(i == 91) { + if(L5BTYPES[(unsigned char)dungeon[x+1][y]] != 80 || L5dflags[x+1][y]) + i = 80; + else + dungeon[x+1][y] = 92; + } + dungeon[x][y] = i; + } + } + } + } +} + +static void DRLG_L5SetRoom(int rx1, int ry1) +{ + int rw = *(unsigned char *)pSetPiece; /* todo: BYTE */ + int rh = *((unsigned char *)pSetPiece+2); + + setpc_x = rx1; + setpc_y = ry1; + setpc_w = rw; + setpc_h = rh; + + unsigned char *sp = (unsigned char *)pSetPiece+4; + + for(int j = 0; j < rh; j++) { + for(int i = 0; i < rw; i++) { + if(*sp) { + dungeon[rx1+i][ry1+j] = *sp; + L5dflags[rx1+i][ry1+j] |= 0x80; + } + else { + dungeon[rx1+i][ry1+j] = 13; + } + sp += 2; + } + } +} + +static void L5FillChambers() +{ + int c; + + if(HR1) + DRLG_L5GChamber(0, 14, 0, 0, 0, 1); + + if(HR2) { + if(HR1 && !HR3) + DRLG_L5GChamber(14, 14, 0, 0, 1, 0); + if(!HR1 && HR3) + DRLG_L5GChamber(14, 14, 0, 0, 0, 1); + if(HR1 && HR3) + DRLG_L5GChamber(14, 14, 0, 0, 1, 1); + if(!HR1 && !HR3) + DRLG_L5GChamber(14, 14, 0, 0, 0, 0); + } + + if(HR3) + DRLG_L5GChamber(28, 14, 0, 0, 1, 0); + if(HR1 && HR2) + DRLG_L5GHall(12, 18, 14, 18); + if(HR2 && HR3) + DRLG_L5GHall(26, 18, 28, 18); + if(HR1 && !HR2 && HR3) + DRLG_L5GHall(12, 18, 28, 18); + if(VR1) + DRLG_L5GChamber(14, 0, 0, 1, 0, 0); + + if(VR2) { + if(VR1 && !VR3) + DRLG_L5GChamber(14, 14, 1, 0, 0, 0); + if(!VR1 && VR3) + DRLG_L5GChamber(14, 14, 0, 1, 0, 0); + if(VR1 && VR3) + DRLG_L5GChamber(14, 14, 1, 1, 0, 0); + if(!VR1 && !VR3) + DRLG_L5GChamber(14, 14, 0, 0, 0, 0); + } + + if(VR3) + DRLG_L5GChamber(14, 28, 1, 0, 0, 0); + if(VR1 && VR2) + DRLG_L5GHall(18, 12, 18, 14); + if(VR2 && VR3) + DRLG_L5GHall(18, 26, 18, 28); + if(VR1 && !VR2 && VR3) + DRLG_L5GHall(18, 12, 18, 28); + + if(setloadflag) { + if(VR1 || VR2 || VR3) { + c = 1; + if(!VR1 && VR2 && VR3 && random(0, 2)) + c = 2; + if(VR1 && VR2 && !VR3 && random(0, 2)) + c = 0; + + if(VR1 && !VR2 && VR3) { + if(random(0, 2)) + c = 0; + else + c = 2; + } + + if(VR1 && VR2 && VR3) + c = random(0, 3); + + switch(c) { + case 0: + DRLG_L5SetRoom(16, 2); + break; + case 1: + DRLG_L5SetRoom(16, 16); + break; + case 2: + DRLG_L5SetRoom(16, 30); + break; + } + } + else { + c = 1; + if(!HR1 && HR2 && HR3 && random(0, 2)) + c = 2; + if(HR1 && HR2 && !HR3 && random(0, 2)) + c = 0; + + if(HR1 && !HR2 && HR3) { + if(random(0, 2)) + c = 0; + else + c = 2; + } + + if(HR1 && HR2 && HR3) + c = random(0, 3); + + switch(c) { + case 0: + DRLG_L5SetRoom(2, 16); + break; + case 1: + DRLG_L5SetRoom(16, 16); + break; + case 2: + DRLG_L5SetRoom(30, 16); + break; + } + } + } +} + +static void DRLG_L5FTVR(int i, int j, int x, int y, int d) +{ + if(dTransVal[x][y] || dungeon[i][j] != 13) { + if(d == 1) { + dTransVal[x][y] = TransVal; + dTransVal[x][y+1] = TransVal; + } + if(d == 2) { + dTransVal[x+1][y] = TransVal; + dTransVal[x+1][y+1] = TransVal; + } + if(d == 3) { + dTransVal[x][y] = TransVal; + dTransVal[x+1][y] = TransVal; + } + if(d == 4) { + dTransVal[x][y+1] = TransVal; + dTransVal[x+1][y+1] = TransVal; + } + if(d == 5) + dTransVal[x+1][y+1] = TransVal; + if(d == 6) + dTransVal[x][y+1] = TransVal; + if(d == 7) + dTransVal[x+1][y] = TransVal; + if(d == 8) + dTransVal[x][y] = TransVal; + } + else { + dTransVal[x][y] = TransVal; + dTransVal[x+1][y] = TransVal; + dTransVal[x][y+1] = TransVal; + dTransVal[x+1][y+1] = TransVal; + DRLG_L5FTVR(i+1, j, x+2, y, 1); + DRLG_L5FTVR(i-1, j, x-2, y, 2); + DRLG_L5FTVR(i, j+1, x, y+2, 3); + DRLG_L5FTVR(i, j-1, x, y-2, 4); + DRLG_L5FTVR(i-1, j-1, x-2, y-2, 5); + DRLG_L5FTVR(i+1, j-1, x+2, y-2, 6); + DRLG_L5FTVR(i-1, j+1, x-2, y+2, 7); + DRLG_L5FTVR(i+1, j+1, x+2, y+2, 8); + } +} + +static void DRLG_L5FloodTVal() +{ + int yy = 16; + + for(int j = 0; j < DMAXY; j++) + { + int xx = 16; + + for(int i = 0; i < DMAXX; i++) + { + if(dungeon[i][j] == 13 && !dTransVal[xx][yy]) { + DRLG_L5FTVR(i, j, xx, yy, 0); + TransVal++; + } + xx += 2; + } + yy += 2; + } +} + +static void DRLG_L5TransFix() +{ + int yy = 16; + + for(int j = 0; j < DMAXY; j++) + { + int xx = 16; + + for(int i = 0; i < DMAXX; i++) + { + if(dungeon[i][j] == 23 && dungeon[i][j-1] == 18) { + dTransVal[xx+1][yy] = dTransVal[xx][yy]; + dTransVal[xx+1][yy+1] = dTransVal[xx][yy]; + } + if(dungeon[i][j] == 24 && dungeon[i+1][j] == 19) { + dTransVal[xx][yy+1] = dTransVal[xx][yy]; + dTransVal[xx+1][yy+1] = dTransVal[xx][yy]; + } + if(dungeon[i][j] == 18) { + dTransVal[xx+1][yy] = dTransVal[xx][yy]; + dTransVal[xx+1][yy+1] = dTransVal[xx][yy]; + } + if(dungeon[i][j] == 19) { + dTransVal[xx][yy+1] = dTransVal[xx][yy]; + dTransVal[xx+1][yy+1] = dTransVal[xx][yy]; + } + if(dungeon[i][j] == 20) { + dTransVal[xx+1][yy] = dTransVal[xx][yy]; + dTransVal[xx][yy+1] = dTransVal[xx][yy]; + dTransVal[xx+1][yy+1] = dTransVal[xx][yy]; + } + xx += 2; + } + yy += 2; + } +} + +static void DRLG_L5DirtFix() +{ + for(int j = 0; j < DMAXY; j++) { + for(int i = 0; i < DMAXX; i++) { + if(dungeon[i][j] == 21 && dungeon[i+1][j] != 19) + dungeon[i][j] = 202; + if(dungeon[i][j] == 19 && dungeon[i+1][j] != 19) + dungeon[i][j] = 200; + if(dungeon[i][j] == 24 && dungeon[i+1][j] != 19) + dungeon[i][j] = 205; + if(dungeon[i][j] == 18 && dungeon[i][j+1] != 18) + dungeon[i][j] = 199; + if(dungeon[i][j] == 21 && dungeon[i][j+1] != 18) + dungeon[i][j] = 202; + if(dungeon[i][j] == 23 && dungeon[i][j+1] != 18) + dungeon[i][j] = 204; + } + } +} + +static void DRLG_L5CornerFix() +{ + int i, j; + + for(j = 1; j < DMAXY - 1; j++) { + for(i = 1; i < DMAXX - 1; i++) { + if(!(L5dflags[i][j] & 0x80) && dungeon[i][j] == 17 && dungeon[i - 1][j] == 13 && dungeon[i][j - 1] == 1) { + dungeon[i][j] = 16; + L5dflags[i][j - 1] &= 0x80; + } + if(dungeon[i][j] == 202 && dungeon[i + 1][j] == 13 && dungeon[i][j + 1] == 1) { + dungeon[i][j] = 8; + } + } + } +} + +static void DRLG_L5(int entry) +{ + int i, j; + long minarea; + BOOL doneflag; + + switch(currlevel) { + case 1: + minarea = 533; + break; + case 2: + minarea = 693; + break; + case 3: + case 4: + minarea = 761; + break; + default: + break; + } + + do { + DRLG_InitTrans(); + + do { + InitL5Dungeon(); + L5firstRoom(); + } while(L5GetArea() < minarea); + + L5makeDungeon(); + L5makeDmt(); + L5FillChambers(); + L5tileFix(); + L5AddWall(); + L5ClearFlags(); + DRLG_L5FloodTVal(); + + doneflag = TRUE; + + if(QuestStatus(13)) { + if(entry == 0) { + if(DRLG_PlaceMiniSet(PWATERIN, 1, 1, 0, 0, 1, -1, 0) < 0) + doneflag = FALSE; + } + else { + if(DRLG_PlaceMiniSet(PWATERIN, 1, 1, 0, 0, 0, -1, 0) < 0) + doneflag = FALSE; + ViewY--; + } + } + if(QuestStatus(7)) { + if(entry == 0) { + if(DRLG_PlaceMiniSet(STAIRSUP, 1, 1, 0, 0, 1, -1, 0) < 0) + doneflag = FALSE; + } + else { + if(DRLG_PlaceMiniSet(STAIRSUP, 1, 1, 0, 0, 0, -1, 0) < 0) + doneflag = FALSE; + if(entry == 1) { + ViewX = 2 * setpc_x + 20; + ViewY = 2 * setpc_y + 28; + } + else { + ViewY--; + } + } + } + else if(entry == 0) { + if(DRLG_PlaceMiniSet(L5STAIRSUP, 1, 1, 0, 0, 1, -1, 0) < 0) + doneflag = FALSE; + else if(DRLG_PlaceMiniSet(STAIRSDOWN, 1, 1, 0, 0, 0, -1, 1) < 0) + doneflag = FALSE; + } + else { + if(DRLG_PlaceMiniSet(L5STAIRSUP, 1, 1, 0, 0, 0, -1, 0) < 0) + doneflag = FALSE; + else if(DRLG_PlaceMiniSet(STAIRSDOWN, 1, 1, 0, 0, 1, -1, 1) < 0) + doneflag = FALSE; + ViewY--; + } + } while(doneflag == FALSE); + + for(j = 0; j < DMAXY; j++) { + for(i = 0; i < DMAXX; i++) { + if(dungeon[i][j] == 64) { + int xx = 2 * i + 16; /* todo: fix loop */ + int yy = 2 * j + 16; + DRLG_CopyTrans(xx, yy+1, xx, yy); + DRLG_CopyTrans(xx+1, yy+1, xx+1, yy); + } + } + } + + DRLG_L5TransFix(); + DRLG_L5DirtFix(); + DRLG_L5CornerFix(); + + for(j = 0; j < DMAXY; j++) { + for(i = 0; i < DMAXX; i++) { + if(L5dflags[i][j] & 0x7F) + DRLG_PlaceDoor(i, j); + } + } + + DRLG_L5Subs(); + DRLG_L1Shadows(); + DRLG_PlaceMiniSet(LAMPS, 5, 10, 0, 0, 0, -1, 4); + DRLG_L1Floor(); + + for(j = 0; j < DMAXY; j++) { + for(i = 0; i < DMAXX; i++) { + pdungeon[i][j] = dungeon[i][j]; + } + } + + DRLG_Init_Globals(); + DRLG_CheckQuests(setpc_x, setpc_y); +} + +void CreateL5Dungeon(int rseed, int entry) +{ + SetRndSeed(rseed); + + dminx = 16; + dminy = 16; + dmaxx = 96; + dmaxy = 96; + + DRLG_InitTrans(); + DRLG_InitSetPC(); + DRLG_LoadL1SP(); + DRLG_L5(entry); + DRLG_L1Pass3(); + DRLG_FreeL1SP(); + DRLG_InitL1Vals(); + DRLG_SetPC(); +} diff --git a/2020_03_31/Source/drlg_l1.h b/2020_03_31/Source/drlg_l1.h new file mode 100644 index 00000000..64695df8 --- /dev/null +++ b/2020_03_31/Source/drlg_l1.h @@ -0,0 +1,34 @@ +//HEADER_GOES_HERE +#ifndef __DRLG_L1_H__ +#define __DRLG_L1_H__ + +extern char L5dungeon[80][80]; +extern unsigned char L5dflags[40][40]; +extern int setloadflag; // weak +extern int HR1; +extern int HR2; +extern int HR3; +extern int VR1; +extern int VR2; +extern int VR3; +extern void *pSetPiece; // idb + +void DRLG_Init_Globals(); +void LoadL1Dungeon(char *sFileName, int vx, int vy); +void LoadPreL1Dungeon(char *sFileName, int vx, int vy); +void CreateL5Dungeon(int rseed, int entry); + +/* rdata */ +extern const ShadowStruct SPATS[37]; +extern const unsigned char BSTYPES[206]; +extern const unsigned char L5BTYPES[206]; +extern const unsigned char STAIRSUP[]; +extern const unsigned char L5STAIRSUP[]; +extern const unsigned char STAIRSDOWN[]; +extern const unsigned char LAMPS[]; +extern const unsigned char PWATERIN[]; + +/* data */ +extern unsigned char L5ConvTbl[16]; + +#endif /* __DRLG_L1_H__ */ diff --git a/2020_03_31/Source/drlg_l2.cpp b/2020_03_31/Source/drlg_l2.cpp new file mode 100644 index 00000000..5a70b98c --- /dev/null +++ b/2020_03_31/Source/drlg_l2.cpp @@ -0,0 +1,2140 @@ +#include "diablo.h" + +int nSx1; +int nSx2; // weak +int nSy1; +int nSy2; // weak +int nRoomCnt; +unsigned char predungeon[40][40]; +ROOMNODE RoomList[81]; +HALLNODE *pHallList; + +int Area_Min = 2; // weak +int Room_Max = 10; // weak +int Room_Min = 4; // weak +int Dir_Xadd[5] = { 0, 0, 1, 0, -1 }; +int Dir_Yadd[5] = { 0, -1, 0, 1, 0 }; +ShadowStruct SPATSL2[2] = { { 6u, 3u, 0u, 3u, 48u, 0u, 50u }, { 9u, 3u, 0u, 3u, 48u, 0u, 50u } }; +//short word_48489A = 0; // weak +unsigned char BTYPESL2[161] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 17, 18, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 2, 2, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 0, 3, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; +unsigned char BSTYPESL2[161] = { 0, 1, 2, 3, 0, 0, 6, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 6, 6, 6, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 2, 2, 2, 0, 0, 0, 1, 1, 1, 1, 6, 2, 2, 2, 0, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 2, 2, 3, 3, 3, 3, 1, 1, 2, 2, 3, 3, 3, 3, 1, 1, 3, 3, 2, 2, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; +unsigned char VARCH1[] = { 2, 4, 3, 0, 3, 1, 3, 4, 0, 7, 48, 0, 51, 39, 47, 44, 0, 0 }; +unsigned char VARCH2[] = { 2, 4, 3, 0, 3, 1, 3, 4, 0, 8, 48, 0, 51, 39, 47, 44, 0, 0 }; +unsigned char VARCH3[] = { 2, 4, 3, 0, 3, 1, 3, 4, 0, 6, 48, 0, 51, 39, 47, 44, 0, 0 }; +unsigned char VARCH4[] = { 2, 4, 3, 0, 3, 1, 3, 4, 0, 9, 48, 0, 51, 39, 47, 44, 0, 0 }; +unsigned char VARCH5[] = { 2, 4, 3, 0, 3, 1, 3, 4, 0, 14, 48, 0, 51, 39, 47, 44, 0, 0 }; +unsigned char VARCH6[] = { 2, 4, 3, 0, 3, 1, 3, 4, 0, 13, 48, 0, 51, 39, 47, 44, 0, 0 }; +unsigned char VARCH7[] = { 2, 4, 3, 0, 3, 1, 3, 4, 0, 16, 48, 0, 51, 39, 47, 44, 0, 0 }; +unsigned char VARCH8[] = { 2, 4, 3, 0, 3, 1, 3, 4, 0, 15, 48, 0, 51, 39, 47, 44, 0, 0 }; +unsigned char VARCH9[] = { 2, 4, 3, 0, 3, 8, 3, 4, 0, 7, 48, 0, 51, 42, 47, 44, 0, 0 }; +unsigned char VARCH10[] = { 2, 4, 3, 0, 3, 8, 3, 4, 0, 8, 48, 0, 51, 42, 47, 44, 0, 0 }; +unsigned char VARCH11[] = { 2, 4, 3, 0, 3, 8, 3, 4, 0, 6, 48, 0, 51, 42, 47, 44, 0, 0 }; +unsigned char VARCH12[] = { 2, 4, 3, 0, 3, 8, 3, 4, 0, 9, 48, 0, 51, 42, 47, 44, 0, 0 }; +unsigned char VARCH13[] = { 2, 4, 3, 0, 3, 8, 3, 4, 0, 14, 48, 0, 51, 42, 47, 44, 0, 0 }; +unsigned char VARCH14[] = { 2, 4, 3, 0, 3, 8, 3, 4, 0, 13, 48, 0, 51, 42, 47, 44, 0, 0 }; +unsigned char VARCH15[] = { 2, 4, 3, 0, 3, 8, 3, 4, 0, 16, 48, 0, 51, 42, 47, 44, 0, 0 }; +unsigned char VARCH16[] = { 2, 4, 3, 0, 3, 8, 3, 4, 0, 15, 48, 0, 51, 42, 47, 44, 0, 0 }; +unsigned char VARCH17[] = { 2, 3, 2, 7, 3, 4, 0, 7, 141, 39, 47, 44, 0, 0 }; +unsigned char VARCH18[] = { 2, 3, 2, 7, 3, 4, 0, 8, 141, 39, 47, 44, 0, 0 }; +unsigned char VARCH19[] = { 2, 3, 2, 7, 3, 4, 0, 6, 141, 39, 47, 44, 0, 0 }; +unsigned char VARCH20[] = { 2, 3, 2, 7, 3, 4, 0, 9, 141, 39, 47, 44, 0, 0 }; +unsigned char VARCH21[] = { 2, 3, 2, 7, 3, 4, 0, 14, 141, 39, 47, 44, 0, 0 }; +unsigned char VARCH22[] = { 2, 3, 2, 7, 3, 4, 0, 13, 141, 39, 47, 44, 0, 0 }; +unsigned char VARCH23[] = { 2, 3, 2, 7, 3, 4, 0, 16, 141, 39, 47, 44, 0, 0 }; +unsigned char VARCH24[] = { 2, 3, 2, 7, 3, 4, 0, 15, 141, 39, 47, 44, 0, 0 }; +unsigned char VARCH25[] = { 2, 4, 3, 0, 3, 4, 3, 1, 0, 7, 48, 0, 51, 39, 47, 44, 0, 0 }; +unsigned char VARCH26[] = { 2, 4, 3, 0, 3, 4, 3, 1, 0, 8, 48, 0, 51, 39, 47, 44, 0, 0 }; +unsigned char VARCH27[] = { 2, 4, 3, 0, 3, 4, 3, 1, 0, 6, 48, 0, 51, 39, 47, 44, 0, 0 }; +unsigned char VARCH28[] = { 2, 4, 3, 0, 3, 4, 3, 1, 0, 9, 48, 0, 51, 39, 47, 44, 0, 0 }; +unsigned char VARCH29[] = { 2, 4, 3, 0, 3, 4, 3, 1, 0, 14, 48, 0, 51, 39, 47, 44, 0, 0 }; +unsigned char VARCH30[] = { 2, 4, 3, 0, 3, 4, 3, 1, 0, 13, 48, 0, 51, 39, 47, 44, 0, 0 }; +unsigned char VARCH31[] = { 2, 4, 3, 0, 3, 4, 3, 1, 0, 16, 48, 0, 51, 39, 47, 44, 0, 0 }; +unsigned char VARCH32[] = { 2, 4, 3, 0, 3, 4, 3, 1, 0, 15, 48, 0, 51, 39, 47, 44, 0, 0 }; +unsigned char VARCH33[] = { 2, 4, 2, 0, 3, 8, 3, 4, 0, 7, 142, 0, 51, 42, 47, 44, 0, 0 }; +unsigned char VARCH34[] = { 2, 4, 2, 0, 3, 8, 3, 4, 0, 8, 142, 0, 51, 42, 47, 44, 0, 0 }; +unsigned char VARCH35[] = { 2, 4, 2, 0, 3, 8, 3, 4, 0, 6, 142, 0, 51, 42, 47, 44, 0, 0 }; +unsigned char VARCH36[] = { 2, 4, 2, 0, 3, 8, 3, 4, 0, 9, 142, 0, 51, 42, 47, 44, 0, 0 }; +unsigned char VARCH37[] = { 2, 4, 2, 0, 3, 8, 3, 4, 0, 14, 142, 0, 51, 42, 47, 44, 0, 0 }; +unsigned char VARCH38[] = { 2, 4, 2, 0, 3, 8, 3, 4, 0, 13, 142, 0, 51, 42, 47, 44, 0, 0 }; +unsigned char VARCH39[] = { 2, 4, 2, 0, 3, 8, 3, 4, 0, 16, 142, 0, 51, 42, 47, 44, 0, 0 }; +unsigned char VARCH40[] = { 2, 4, 2, 0, 3, 8, 3, 4, 0, 15, 142, 0, 51, 42, 47, 44, 0, 0 }; +unsigned char HARCH1[] = { 3, 2, 3, 3, 0, 2, 5, 9, 49, 46, 0, 40, 45, 0 }; +unsigned char HARCH2[] = { 3, 2, 3, 3, 0, 2, 5, 6, 49, 46, 0, 40, 45, 0 }; +unsigned char HARCH3[] = { 3, 2, 3, 3, 0, 2, 5, 8, 49, 46, 0, 40, 45, 0 }; +unsigned char HARCH4[] = { 3, 2, 3, 3, 0, 2, 5, 7, 49, 46, 0, 40, 45, 0 }; +unsigned char HARCH5[] = { 3, 2, 3, 3, 0, 2, 5, 15, 49, 46, 0, 40, 45, 0 }; +unsigned char HARCH6[] = { 3, 2, 3, 3, 0, 2, 5, 16, 49, 46, 0, 40, 45, 0 }; +unsigned char HARCH7[] = { 3, 2, 3, 3, 0, 2, 5, 13, 49, 46, 0, 40, 45, 0 }; +unsigned char HARCH8[] = { 3, 2, 3, 3, 0, 2, 5, 14, 49, 46, 0, 40, 45, 0 }; +unsigned char HARCH9[] = { 3, 2, 3, 3, 0, 8, 5, 9, 49, 46, 0, 43, 45, 0 }; +unsigned char HARCH10[] = { 3, 2, 3, 3, 0, 8, 5, 6, 49, 46, 0, 43, 45, 0 }; +unsigned char HARCH11[] = { 3, 2, 3, 3, 0, 8, 5, 8, 49, 46, 0, 43, 45, 0 }; +unsigned char HARCH12[] = { 3, 2, 3, 3, 0, 8, 5, 7, 49, 46, 0, 43, 45, 0 }; +unsigned char HARCH13[] = { 3, 2, 3, 3, 0, 8, 5, 15, 49, 46, 0, 43, 45, 0 }; +unsigned char HARCH14[] = { 3, 2, 3, 3, 0, 8, 5, 16, 49, 46, 0, 43, 45, 0 }; +unsigned char HARCH15[] = { 3, 2, 3, 3, 0, 8, 5, 13, 49, 46, 0, 43, 45, 0 }; +unsigned char HARCH16[] = { 3, 2, 3, 3, 0, 8, 5, 14, 49, 46, 0, 43, 45, 0 }; +unsigned char HARCH17[] = { 3, 2, 1, 3, 0, 8, 5, 9, 140, 46, 0, 43, 45, 0 }; +unsigned char HARCH18[] = { 3, 2, 1, 3, 0, 8, 5, 6, 140, 46, 0, 43, 45, 0 }; +unsigned char HARCH19[] = { 3, 2, 1, 3, 0, 8, 5, 8, 140, 46, 0, 43, 45, 0 }; +unsigned char HARCH20[] = { 3, 2, 1, 3, 0, 8, 5, 7, 140, 46, 0, 43, 45, 0 }; +unsigned char HARCH21[] = { 3, 2, 1, 3, 0, 8, 5, 15, 140, 46, 0, 43, 45, 0 }; +unsigned char HARCH22[] = { 3, 2, 1, 3, 0, 8, 5, 16, 140, 46, 0, 43, 45, 0 }; +unsigned char HARCH23[] = { 3, 2, 1, 3, 0, 8, 5, 13, 140, 46, 0, 43, 45, 0 }; +unsigned char HARCH24[] = { 3, 2, 1, 3, 0, 8, 5, 14, 140, 46, 0, 43, 45, 0 }; +unsigned char HARCH25[] = { 3, 2, 3, 3, 0, 5, 2, 9, 49, 46, 0, 40, 45, 0 }; +unsigned char HARCH26[] = { 3, 2, 3, 3, 0, 5, 2, 6, 49, 46, 0, 40, 45, 0 }; +unsigned char HARCH27[] = { 3, 2, 3, 3, 0, 5, 2, 8, 49, 46, 0, 40, 45, 0 }; +unsigned char HARCH28[] = { 3, 2, 3, 3, 0, 5, 2, 7, 49, 46, 0, 40, 45, 0 }; +unsigned char HARCH29[] = { 3, 2, 3, 3, 0, 5, 2, 15, 49, 46, 0, 40, 45, 0 }; +unsigned char HARCH30[] = { 3, 2, 3, 3, 0, 5, 2, 16, 49, 46, 0, 40, 45, 0 }; +unsigned char HARCH31[] = { 3, 2, 3, 3, 0, 5, 2, 13, 49, 46, 0, 40, 45, 0 }; +unsigned char HARCH32[] = { 3, 2, 3, 3, 0, 5, 2, 14, 49, 46, 0, 40, 45, 0 }; +unsigned char HARCH33[] = { 3, 2, 1, 3, 0, 9, 5, 9, 140, 46, 0, 40, 45, 0 }; +unsigned char HARCH34[] = { 3, 2, 1, 3, 0, 9, 5, 6, 140, 46, 0, 40, 45, 0 }; +unsigned char HARCH35[] = { 3, 2, 1, 3, 0, 9, 5, 8, 140, 46, 0, 40, 45, 0 }; +unsigned char HARCH36[] = { 3, 2, 1, 3, 0, 9, 5, 7, 140, 46, 0, 40, 45, 0 }; +unsigned char HARCH37[] = { 3, 2, 1, 3, 0, 9, 5, 15, 140, 46, 0, 40, 45, 0 }; +unsigned char HARCH38[] = { 3, 2, 1, 3, 0, 9, 5, 16, 140, 46, 0, 40, 45, 0 }; +unsigned char HARCH39[] = { 3, 2, 1, 3, 0, 9, 5, 13, 140, 46, 0, 40, 45, 0 }; +unsigned char HARCH40[] = { 3, 2, 1, 3, 0, 9, 5, 14, 140, 46, 0, 40, 45, 0 }; +unsigned char USTAIRS[] = { 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 72, 77, 0, 0, 76, 0, 0, 0, 0, 0, 0 }; +unsigned char DSTAIRS[] = { 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 48, 71, 0, 0, 50, 78, 0, 0, 0, 0, 0 }; +unsigned char WARPSTAIRS[] = { 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 158, 160, 0, 0, 159, 0, 0, 0, 0, 0, 0 }; +unsigned char CRUSHCOL[] = { 3, 3, 3, 1, 3, 2, 6, 3, 3, 3, 3, 0, 0, 0, 0, 83, 0, 0, 0, 0 }; +unsigned char BIG1[] = { 2, 2, 3, 3, 3, 3, 113, 0, 112, 0 }; +unsigned char BIG2[] = { 2, 2, 3, 3, 3, 3, 114, 115, 0, 0 }; +unsigned char BIG3[] = { 1, 2, 1, 1, 117, 116 }; +unsigned char BIG4[] = { 2, 1, 2, 2, 118, 119 }; +unsigned char BIG5[] = { 2, 2, 3, 3, 3, 3, 120, 122, 121, 123 }; +unsigned char BIG6[] = { 1, 2, 1, 1, 125, 124 }; +unsigned char BIG7[] = { 2, 1, 2, 2, 126, 127 }; +unsigned char BIG8[] = { 2, 2, 3, 3, 3, 3, 128, 130, 129, 131 }; +unsigned char BIG9[] = { 2, 2, 1, 3, 1, 3, 133, 135, 132, 134 }; +unsigned char BIG10[] = { 2, 2, 2, 2, 3, 3, 136, 137, 3, 3 }; +unsigned char RUINS1[] = { 1, 1, 1, 80 }; +unsigned char RUINS2[] = { 1, 1, 1, 81 }; +unsigned char RUINS3[] = { 1, 1, 1, 82 }; +unsigned char RUINS4[] = { 1, 1, 2, 84 }; +unsigned char RUINS5[] = { 1, 1, 2, 85 }; +unsigned char RUINS6[] = { 1, 1, 2, 86 }; +unsigned char RUINS7[] = { 1, 1, 8, 87 }; +unsigned char PANCREAS1[] = { 5, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 108, 0, 0, 0, 0, 0, 0, 0 }; +unsigned char PANCREAS2[] = { 5, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 110, 0, 0, 0, 0, 0, 0, 0 }; +unsigned char CTRDOOR1[] = { 3, 3, 3, 1, 3, 0, 4, 0, 0, 9, 0, 0, 4, 0, 0, 1, 0, 0, 0, 0 }; +unsigned char CTRDOOR2[] = { 3, 3, 3, 1, 3, 0, 4, 0, 0, 8, 0, 0, 4, 0, 0, 1, 0, 0, 0, 0 }; +unsigned char CTRDOOR3[] = { 3, 3, 3, 1, 3, 0, 4, 0, 0, 6, 0, 0, 4, 0, 0, 1, 0, 0, 0, 0 }; +unsigned char CTRDOOR4[] = { 3, 3, 3, 1, 3, 0, 4, 0, 0, 7, 0, 0, 4, 0, 0, 1, 0, 0, 0, 0 }; +unsigned char CTRDOOR5[] = { 3, 3, 3, 1, 3, 0, 4, 0, 0, 15, 0, 0, 4, 0, 0, 1, 0, 0, 0, 0 }; +unsigned char CTRDOOR6[] = { 3, 3, 3, 1, 3, 0, 4, 0, 0, 13, 0, 0, 4, 0, 0, 1, 0, 0, 0, 0 }; +unsigned char CTRDOOR7[] = { 3, 3, 3, 1, 3, 0, 4, 0, 0, 16, 0, 0, 4, 0, 0, 1, 0, 0, 0, 0 }; +unsigned char CTRDOOR8[] = { 3, 3, 3, 1, 3, 0, 4, 0, 0, 14, 0, 0, 4, 0, 0, 1, 0, 0, 0, 0 }; +int Patterns[100][10] = +{ + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 3 }, + { 0, 0, 0, 0, 2, 0, 0, 0, 0, 3 }, + { 0, 7, 0, 0, 1, 0, 0, 5, 0, 2 }, + { 0, 5, 0, 0, 1, 0, 0, 7, 0, 2 }, + { 0, 0, 0, 7, 1, 5, 0, 0, 0, 1 }, + { 0, 0, 0, 5, 1, 7, 0, 0, 0, 1 }, + { 0, 1, 0, 0, 3, 0, 0, 1, 0, 4 }, + { 0, 0, 0, 1, 3, 1, 0, 0, 0, 5 }, + { 0, 6, 0, 6, 1, 0, 0, 0, 0, 6 }, + { 0, 6, 0, 0, 1, 6, 0, 0, 0, 9 }, + { 0, 0, 0, 6, 1, 0, 0, 6, 0, 7 }, + { 0, 0, 0, 0, 1, 6, 0, 6, 0, 8 }, + { 0, 6, 0, 6, 6, 0, 8, 6, 0, 7 }, + { 0, 6, 8, 6, 6, 6, 0, 0, 0, 9 }, + { 0, 6, 0, 0, 6, 6, 0, 6, 8, 8 }, + { 6, 6, 6, 6, 6, 6, 0, 6, 0, 8 }, + { 2, 6, 6, 6, 6, 6, 0, 6, 0, 8 }, + { 7, 7, 7, 6, 6, 6, 0, 6, 0, 8 }, + { 6, 6, 2, 6, 6, 6, 0, 6, 0, 8 }, + { 6, 2, 6, 6, 6, 6, 0, 6, 0, 8 }, + { 2, 6, 6, 6, 6, 6, 0, 6, 0, 8 }, + { 6, 7, 7, 6, 6, 6, 0, 6, 0, 8 }, + { 4, 4, 6, 6, 6, 6, 2, 6, 2, 8 }, + { 2, 2, 2, 2, 6, 2, 2, 6, 2, 7 }, + { 2, 2, 2, 2, 6, 2, 6, 6, 6, 7 }, + { 2, 2, 6, 2, 6, 6, 2, 2, 6, 9 }, + { 2, 6, 2, 2, 6, 2, 2, 2, 2, 6 }, + { 2, 2, 2, 2, 6, 6, 2, 2, 2, 9 }, + { 2, 2, 2, 6, 6, 2, 2, 2, 2, 6 }, + { 2, 2, 0, 2, 6, 6, 2, 2, 0, 9 }, + { 0, 0, 0, 0, 4, 0, 0, 0, 0, 12 }, + { 0, 1, 0, 0, 1, 4, 0, 1, 0, 10 }, + { 0, 0, 0, 1, 1, 1, 0, 4, 0, 11 }, + { 0, 0, 0, 6, 1, 4, 0, 1, 0, 14 }, + { 0, 6, 0, 1, 1, 0, 0, 4, 0, 16 }, + { 0, 6, 0, 0, 1, 1, 0, 4, 0, 15 }, + { 0, 0, 0, 0, 1, 1, 0, 1, 4, 13 }, + { 8, 8, 8, 8, 1, 1, 0, 1, 1, 13 }, + { 8, 8, 4, 8, 1, 1, 0, 1, 1, 10 }, + { 0, 0, 0, 1, 1, 1, 1, 1, 1, 11 }, + { 1, 1, 1, 1, 1, 1, 2, 2, 8, 2 }, + { 0, 1, 0, 1, 1, 4, 1, 1, 0, 16 }, + { 0, 0, 0, 1, 1, 1, 1, 1, 4, 11 }, + { 1, 1, 4, 1, 1, 1, 0, 2, 2, 2 }, + { 1, 1, 1, 1, 1, 1, 6, 2, 6, 2 }, + { 4, 1, 1, 1, 1, 1, 6, 2, 6, 2 }, + { 2, 2, 2, 1, 1, 1, 4, 1, 1, 11 }, + { 4, 1, 1, 1, 1, 1, 2, 2, 2, 2 }, + { 1, 1, 4, 1, 1, 1, 2, 2, 1, 2 }, + { 4, 1, 1, 1, 1, 1, 1, 2, 2, 2 }, + { 2, 2, 6, 1, 1, 1, 4, 1, 1, 11 }, + { 4, 1, 1, 1, 1, 1, 2, 2, 6, 2 }, + { 1, 2, 2, 1, 1, 1, 4, 1, 1, 11 }, + { 0, 1, 1, 0, 1, 1, 0, 1, 1, 10 }, + { 2, 1, 1, 3, 1, 1, 2, 1, 1, 14 }, + { 1, 1, 0, 1, 1, 2, 1, 1, 0, 1 }, + { 0, 4, 0, 1, 1, 1, 0, 1, 1, 14 }, + { 4, 1, 0, 1, 1, 0, 1, 1, 0, 1 }, + { 0, 1, 0, 4, 1, 1, 0, 1, 1, 15 }, + { 1, 1, 1, 1, 1, 1, 0, 2, 2, 2 }, + { 0, 1, 1, 2, 1, 1, 2, 1, 4, 10 }, + { 2, 1, 1, 1, 1, 1, 0, 4, 0, 16 }, + { 1, 1, 4, 1, 1, 2, 0, 1, 2, 1 }, + { 2, 1, 1, 2, 1, 1, 1, 1, 4, 10 }, + { 1, 1, 2, 1, 1, 2, 4, 1, 8, 1 }, + { 2, 1, 4, 1, 1, 1, 4, 4, 1, 16 }, + { 2, 1, 1, 1, 1, 1, 1, 1, 1, 16 }, + { 1, 1, 2, 1, 1, 1, 1, 1, 1, 15 }, + { 1, 1, 1, 1, 1, 1, 2, 1, 1, 14 }, + { 4, 1, 1, 1, 1, 1, 2, 1, 1, 14 }, + { 1, 1, 1, 1, 1, 1, 1, 1, 2, 8 }, + { 0, 0, 0, 0, 255, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } +}; + +static BOOL DRLG_L2PlaceMiniSet(unsigned char *miniset, int tmin, int tmax, int cx, int cy, BOOL setview, int ldir) +{ + int sx, sy, sw, sh, xx, yy, i, ii, numt, bailcnt; + BOOL found; + + sw = miniset[0]; + sh = miniset[1]; + + if(tmax - tmin == 0) { + numt = 1; + } else { + numt = random(0, tmax - tmin) + tmin; + } + + for(i = 0; i < numt; i++) { + sx = random(0, 40 - sw); + sy = random(0, 40 - sh); + found = FALSE; + for(bailcnt = 0; !found && bailcnt < 200; bailcnt++) { + found = TRUE; + if(sx >= nSx1 && sx <= nSx2 && sy >= nSy1 && sy <= nSy2) { + found = FALSE; + } + if(cx != -1 && sx >= cx - sw && sx <= cx + 12) { + sx = random(0, 40 - sw); + sy = random(0, 40 - sh); + found = FALSE; + } + if(cy != -1 && sy >= cy - sh && sy <= cy + 12) { + sx = random(0, 40 - sw); + sy = random(0, 40 - sh); + found = FALSE; + } + ii = 2; + for(yy = 0; yy < sh && found == TRUE; yy++) { + for(xx = 0; xx < sw && found == TRUE; xx++) { + if(miniset[ii] != 0 && dungeon[xx + sx][yy + sy] != miniset[ii]) { + found = FALSE; + } + if(dflags[xx + sx][yy + sy] != 0) { + found = FALSE; + } + ii++; + } + } + if(!found) { + sx++; + if(sx == 40 - sw) { + sx = 0; + sy++; + if(sy == 40 - sh) { + sy = 0; + } + } + } + } + if(bailcnt >= 200) { + return FALSE; + } + ii = sw * sh + 2; + for(yy = 0; yy < sh; yy++) { + for(xx = 0; xx < sw; xx++) { + if(miniset[ii] != 0) { + dungeon[xx + sx][yy + sy] = miniset[ii]; + } + ii++; + } + } + } + + if(setview == TRUE) { + ViewX = 2 * sx + 21; + ViewY = 2 * sy + 22; + } + if(ldir == 0) { + LvlViewX = 2 * sx + 21; + LvlViewY = 2 * sy + 22; + } + if(ldir == 6) { + LvlViewX = 2 * sx + 21; + LvlViewY = 2 * sy + 22; + } + + return TRUE; +} + +static void DRLG_L2PlaceRndSet(unsigned char *miniset, int rndper) +{ + int sx, sy, sw, sh, xx, yy, ii, kk; + BOOL found; + + sw = miniset[0]; + sh = miniset[1]; + + for(sy = 0; sy < 40 - sh; sy++) { + for(sx = 0; sx < 40 - sw; sx++) { + found = TRUE; + ii = 2; + if(sx >= nSx1 && sx <= nSx2 && sy >= nSy1 && sy <= nSy2) { + found = FALSE; + } + for(yy = 0; yy < sh && found == TRUE; yy++) { + for(xx = 0; xx < sw && found == TRUE; xx++) { + if(miniset[ii] != 0 && dungeon[xx + sx][yy + sy] != miniset[ii]) { + found = FALSE; + } + if(dflags[xx + sx][yy + sy] != 0) { + found = FALSE; + } + ii++; + } + } + kk = sw * sh + 2; + if(found == TRUE) { + for(yy = sy - sh; yy < sy + 2 * sh && found == TRUE; yy++) { + for(xx = sx - sw; xx < sx + 2 * sw; xx++) { + if(dungeon[xx][yy] == miniset[kk]) { + found = FALSE; + } + } + } + } + if(found == TRUE && random(0, 100) < rndper) { + for(yy = 0; yy < sh; yy++) { + for(xx = 0; xx < sw; xx++) { + if(miniset[kk] != 0) { + dungeon[xx + sx][yy + sy] = miniset[kk]; + } + kk++; + } + } + } + } + } +} + +static void DRLG_L2Subs() +{ + int x, y, i, j, k, rv; + unsigned char c; + + for(y = 0; y < 40; y++) { + for(x = 0; x < 40; x++) { + if((x < nSx1 || x > nSx2) && (y < nSy1 || y > nSy2) && random(0, 4) == 0) { + c = BTYPESL2[dungeon[x][y]]; + if(c != 0) { + rv = random(0, 16); + k = -1; + while(rv >= 0) { + k++; + if(k == sizeof(BTYPESL2)) { + k = 0; + } + if(c == BTYPESL2[k]) { + rv--; + } + } + for(j = y - 2; j < y + 2; j++) { + for(i = x - 2; i < x + 2; i++) { + if(dungeon[i][j] == k) { + j = y + 3; + i = x + 2; + } + } + } + if(j < y + 3) { + dungeon[x][y] = k; + } + } + } + } + } +} + +static void DRLG_L2Shadows() +{ + int x, y, i; + BOOL patflag; + unsigned char sd[2][2]; + + for(y = 1; y < 40; y++) { + for(x = 1; x < 40; x++) { + sd[0][0] = BSTYPESL2[dungeon[x][y]]; + sd[1][0] = BSTYPESL2[dungeon[x - 1][y]]; + sd[0][1] = BSTYPESL2[dungeon[x][y - 1]]; + sd[1][1] = BSTYPESL2[dungeon[x - 1][y - 1]]; + for(i = 0; i < 2; i++) { + if(SPATSL2[i].strig == sd[0][0]) { + patflag = TRUE; + if(SPATSL2[i].s1 != 0 && SPATSL2[i].s1 != sd[1][1]) { + patflag = FALSE; + } + if(SPATSL2[i].s2 != 0 && SPATSL2[i].s2 != sd[0][1]) { + patflag = FALSE; + } + if(SPATSL2[i].s3 != 0 && SPATSL2[i].s3 != sd[1][0]) { + patflag = FALSE; + } + if(patflag == TRUE) { + if(SPATSL2[i].nv1 != 0) { + dungeon[x - 1][y - 1] = SPATSL2[i].nv1; + } + if(SPATSL2[i].nv2 != 0) { + dungeon[x][y - 1] = SPATSL2[i].nv2; + } + if(SPATSL2[i].nv3 != 0) { + dungeon[x - 1][y] = SPATSL2[i].nv3; + } + } + } + } + } + } +} + +void InitDungeon() +{ + int i, j; + + for(j = 0; j < DMAXY; j++) { + for(i = 0; i < DMAXX; i++) { + predungeon[i][j] = 32; + dflags[i][j] = 0; + } + } +} + +static void DRLG_LoadL2SP() +{ + setloadflag_2 = 0; + + if(QuestStatus(Q_BLIND)) { + pSetPiece_2 = (char *)DiabLoad("Levels\\L2Data\\Blind2.DUN", NULL, 'STPC'); + setloadflag_2 = 1; + } else if(QuestStatus(Q_BLOOD)) { + pSetPiece_2 = (char *)DiabLoad("Levels\\L2Data\\Blood1.DUN", NULL, 'STPC'); + setloadflag_2 = 1; + } else if(QuestStatus(Q_SCHAMB)) { + pSetPiece_2 = (char *)DiabLoad("Levels\\L2Data\\Bonestr2.DUN", NULL, 'STPC'); + setloadflag_2 = 1; + } +} + +static void DRLG_FreeL2SP() +{ + MemFreeDbg(pSetPiece_2); +} + +static void DRLG_L2SetRoom(int rx1, int ry1) +{ + int rw, rh, i, j; + unsigned char *sp; + + rw = (unsigned char)pSetPiece_2[0]; + rh = (unsigned char)pSetPiece_2[2]; + + setpc_x = rx1; + setpc_y = ry1; + setpc_w = rw; + setpc_h = rh; + + sp = (unsigned char *)&pSetPiece_2[4]; + + for(j = 0; j < rh; j++) { + for(i = 0; i < rw; i++) { + if(*sp != 0) { + dungeon[i + rx1][j + ry1] = *sp; + dflags[i + rx1][j + ry1] |= 0x80; + } else { + dungeon[i + rx1][j + ry1] = 3; + } + sp += 2; + } + } +} + +static void DefineRoom(int nX1, int nY1, int nX2, int nY2, BOOL ForceHW) +{ + int i, j; + + predungeon[nX1][nY1] = 67; + predungeon[nX1][nY2] = 69; + predungeon[nX2][nY1] = 66; + predungeon[nX2][nY2] = 65; + + nRoomCnt++; + RoomList[nRoomCnt].nRoomx1 = nX1; + RoomList[nRoomCnt].nRoomx2 = nX2; + RoomList[nRoomCnt].nRoomy1 = nY1; + RoomList[nRoomCnt].nRoomy2 = nY2; + + if(ForceHW == TRUE) { + for(i = nX1; i < nX2; i++) { + while(i < nY2) { + dflags[i][nY1] |= 0x80; + i++; + } + } + } + for(i = nX1 + 1; i <= nX2 - 1; i++) { + predungeon[i][nY1] = 35; + predungeon[i][nY2] = 35; + } + nY2--; + for(j = nY1 + 1; j <= nY2; j++) { + predungeon[nX1][j] = 35; + predungeon[nX2][j] = 35; + for(i = nX1 + 1; i < nX2; i++) { + predungeon[i][j] = 46; + } + } +} + +static void CreateDoorType(int nX, int nY) +{ + BOOL fDoneflag; + + fDoneflag = FALSE; + + if(predungeon[nX - 1][nY] == 68) { + fDoneflag = TRUE; + } + if(predungeon[nX + 1][nY] == 68) { + fDoneflag = TRUE; + } + if(predungeon[nX][nY - 1] == 68) { + fDoneflag = TRUE; + } + if(predungeon[nX][nY + 1] == 68) { + fDoneflag = TRUE; + } + if(predungeon[nX][nY] == 66 || predungeon[nX][nY] == 67 || predungeon[nX][nY] == 65 || predungeon[nX][nY] == 69) { + fDoneflag = TRUE; + } + + if(!fDoneflag) { + predungeon[nX][nY] = 68; + } +} + +static void PlaceHallExt(int nX, int nY) +{ + if(predungeon[nX][nY] == 32) { + predungeon[nX][nY] = 44; + } +} + +static void AddHall(int nX1, int nY1, int nX2, int nY2, int nHd) +{ + HALLNODE *p1, *p2; + + if(pHallList == NULL) { + pHallList = (HALLNODE *)DiabloAllocPtr(sizeof(*pHallList)); + pHallList->nHallx1 = nX1; + pHallList->nHally1 = nY1; + pHallList->nHallx2 = nX2; + pHallList->nHally2 = nY2; + pHallList->nHalldir = nHd; + pHallList->pNext = NULL; + } else { + p1 = (HALLNODE *)DiabloAllocPtr(sizeof(*pHallList)); + p1->nHallx1 = nX1; + p1->nHally1 = nY1; + p1->nHallx2 = nX2; + p1->nHally2 = nY2; + p1->nHalldir = nHd; + p1->pNext = NULL; + p2 = pHallList; + while(p2->pNext != NULL) { + p2 = p2->pNext; + } + p2->pNext = p1; + } +} + +static void CreateRoom(int nX1, int nY1, int nX2, int nY2, int nRDest, int nHDir, BOOL ForceHW, int nH, int nW) +{ + int nAw, nAh, nRw, nRh, nRx1, nRy1, nRx2, nRy2, nHw, nHh, nHx1, nHy1, nHx2, nHy2, nRid; + + if(nRoomCnt >= 80) { + return; + } + + nAw = nX2 - nX1; + nAh = nY2 - nY1; + if(nAw < Area_Min || nAh < Area_Min) { + return; + } + + if(nAw > Room_Max) { + nRw = random(0, Room_Max - Room_Min) + Room_Min; + } else if(nAw > Room_Min) { + nRw = random(0, nAw - Room_Min) + Room_Min; + } else { + nRw = nAw; + } + if(nAh > Room_Max) { + nRh = random(0, Room_Max - Room_Min) + Room_Min; + } else if(nAh > Room_Min) { + nRh = random(0, nAh - Room_Min) + Room_Min; + } else { + nRh = nAh; + } + + if(ForceHW == TRUE) { + nRw = nW; + nRh = nH; + } + + nRx1 = random(0, nX2 - nX1) + nX1; + nRy1 = random(0, nY2 - nY1) + nY1; + nRx2 = nRw + nRx1; + nRy2 = nRh + nRy1; + if(nRx2 > nX2) { + nRx2 = nX2; + nRx1 = nX2 - nRw; + } + if(nRy2 > nY2) { + nRy2 = nY2; + nRy1 = nY2 - nRh; + } + + if(nRx1 >= 38) { + nRx1 = 38; + } + if(nRy1 >= 38) { + nRy1 = 38; + } + if(nRx1 <= 1) { + nRx1 = 1; + } + if(nRy1 <= 1) { + nRy1 = 1; + } + if(nRx2 >= 38) { + nRx2 = 38; + } + if(nRy2 >= 38) { + nRy2 = 38; + } + if(nRx2 <= 1) { + nRx2 = 1; + } + if(nRy2 <= 1) { + nRy2 = 1; + } + DefineRoom(nRx1, nRy1, nRx2, nRy2, ForceHW); + + if(ForceHW == TRUE) { + nSx1 = nRx1 + 2; + nSy1 = nRy1 + 2; + nSx2 = nRx2; + nSy2 = nRy2; + } + + nRid = nRoomCnt; + RoomList[nRid].nRoomDest = nRDest; + + if(nRDest != 0) { + if(nHDir == 1) { + nHx1 = random(0, nRx2 - nRx1 - 2) + nRx1 + 1; + nHy1 = nRy1; + nHw = RoomList[nRDest].nRoomx2 - RoomList[nRDest].nRoomx1 - 2; + nHx2 = random(0, nHw) + RoomList[nRDest].nRoomx1 + 1; + nHy2 = RoomList[nRDest].nRoomy2; + } + if(nHDir == 3) { + nHx1 = random(0, nRx2 - nRx1 - 2) + nRx1 + 1; + nHy1 = nRy2; + nHw = RoomList[nRDest].nRoomx2 - RoomList[nRDest].nRoomx1 - 2; + nHx2 = random(0, nHw) + RoomList[nRDest].nRoomx1 + 1; + nHy2 = RoomList[nRDest].nRoomy1; + } + if(nHDir == 2) { + nHx1 = nRx2; + nHy1 = random(0, nRy2 - nRy1 - 2) + nRy1 + 1; + nHx2 = RoomList[nRDest].nRoomx1; + nHh = RoomList[nRDest].nRoomy2 - RoomList[nRDest].nRoomy1 - 2; + nHy2 = random(0, nHh) + RoomList[nRDest].nRoomy1 + 1; + } + if(nHDir == 4) { + nHx1 = nRx1; + nHy1 = random(0, nRy2 - nRy1 - 2) + nRy1 + 1; + nHx2 = RoomList[nRDest].nRoomx2; + nHh = RoomList[nRDest].nRoomy2 - RoomList[nRDest].nRoomy1 - 2; + nHy2 = random(0, nHh) + RoomList[nRDest].nRoomy1 + 1; + } + AddHall(nHx1, nHy1, nHx2, nHy2, nHDir); + } + + if(nRh > nRw) { + CreateRoom(nX1 + 2, nY1 + 2, nRx1 - 2, nRy2 - 2, nRid, 2, 0, 0, 0); + CreateRoom(nRx2 + 2, nRy1 + 2, nX2 - 2, nY2 - 2, nRid, 4, 0, 0, 0); + CreateRoom(nX1 + 2, nRy2 + 2, nRx2 - 2, nY2 - 2, nRid, 1, 0, 0, 0); + CreateRoom(nRx1 + 2, nY1 + 2, nX2 - 2, nRy1 - 2, nRid, 3, 0, 0, 0); + } else { + CreateRoom(nX1 + 2, nY1 + 2, nRx2 - 2, nRy1 - 2, nRid, 3, 0, 0, 0); + CreateRoom(nRx1 + 2, nRy2 + 2, nX2 - 2, nY2 - 2, nRid, 1, 0, 0, 0); + CreateRoom(nX1 + 2, nRy1 + 2, nRx1 - 2, nY2 - 2, nRid, 2, 0, 0, 0); + CreateRoom(nRx2 + 2, nY1 + 2, nX2 - 2, nRy2 - 2, nRid, 4, 0, 0, 0); + } +} + +static void GetHall(int *nX1, int *nY1, int *nX2, int *nY2, int *nHd) +{ + HALLNODE *p1; + + p1 = pHallList->pNext; + *nX1 = pHallList->nHallx1; + *nY1 = pHallList->nHally1; + *nX2 = pHallList->nHallx2; + *nY2 = pHallList->nHally2; + *nHd = pHallList->nHalldir; + MemFreeDbg(pHallList); + pHallList = p1; +} + +static void ConnectHall(int nX1, int nY1, int nX2, int nY2, int nHd) +{ + int nCurrd, nDx, nDy, nRp, nOrigX1, nOrigY1, fMinusFlag, fPlusFlag; + BOOL fDoneflag, fInroom; + + fDoneflag = FALSE; + fMinusFlag = random(0, 100); + fPlusFlag = random(0, 100); + nOrigX1 = nX1; + nOrigY1 = nY1; + CreateDoorType(nX1, nY1); + CreateDoorType(nX2, nY2); + nDx = abs(nX2 - nX1); /* unused */ + nDy = abs(nY2 - nY1); /* unused */ + nCurrd = nHd; + nX2 -= Dir_Xadd[nCurrd]; + nY2 -= Dir_Yadd[nCurrd]; + predungeon[nX2][nY2] = 44; + fInroom = FALSE; + + while(!fDoneflag) { + if(nX1 >= 38 && nCurrd == 2) { + nCurrd = 4; + } + if(nY1 >= 38 && nCurrd == 3) { + nCurrd = 1; + } + if(nX1 <= 1 && nCurrd == 4) { + nCurrd = 2; + } + if(nY1 <= 1 && nCurrd == 1) { + nCurrd = 3; + } + if(predungeon[nX1][nY1] == 67 && (nCurrd == 1 || nCurrd == 4)) { + nCurrd = 2; + } + if(predungeon[nX1][nY1] == 66 && (nCurrd == 1 || nCurrd == 2)) { + nCurrd = 3; + } + if(predungeon[nX1][nY1] == 69 && (nCurrd == 4 || nCurrd == 3)) { + nCurrd = 1; + } + if(predungeon[nX1][nY1] == 65 && (nCurrd == 2 || nCurrd == 3)) { + nCurrd = 4; + } + nX1 += Dir_Xadd[nCurrd]; + nY1 += Dir_Yadd[nCurrd]; + if(predungeon[nX1][nY1] == 32) { + if(fInroom) { + CreateDoorType(nX1 - Dir_Xadd[nCurrd], nY1 - Dir_Yadd[nCurrd]); + } else { + if(fMinusFlag < 50) { + if(nCurrd != 1 && nCurrd != 3) { + PlaceHallExt(nX1, nY1 - 1); + } else { + PlaceHallExt(nX1 - 1, nY1); + } + } + if(fPlusFlag < 50) { + if(nCurrd != 1 && nCurrd != 3) { + PlaceHallExt(nX1, nY1 + 1); + } else { + PlaceHallExt(nX1 + 1, nY1); + } + } + } + predungeon[nX1][nY1] = 44; + fInroom = FALSE; + } else { + if(!fInroom && predungeon[nX1][nY1] == 35) { + CreateDoorType(nX1, nY1); + } + if(predungeon[nX1][nY1] != 44) { + fInroom = TRUE; + } + } + nDx = abs(nX2 - nX1); + nDy = abs(nY2 - nY1); + if(nDx > nDy) { + nRp = 2 * nDx; + if(nRp > 30) { + nRp = 30; + } + if(random(0, 100) < nRp) { + if(nX2 <= nX1 || nX1 >= 40) { + nCurrd = 4; + } else { + nCurrd = 2; + } + } + } else { + nRp = 5 * nDy; + if(nRp > 80) { + nRp = 80; + } + if(random(0, 100) < nRp) { + if(nY2 <= nY1 || nY1 >= 40) { + nCurrd = 1; + } else { + nCurrd = 3; + } + } + } + if(nDy < 10 && nX1 == nX2 && (nCurrd == 2 || nCurrd == 4)) { + if(nY2 <= nY1 || nY1 >= 40) { + nCurrd = 1; + } else { + nCurrd = 3; + } + } + if(nDx < 10 && nY1 == nY2 && (nCurrd == 1 || nCurrd == 3)) { + if(nX2 <= nX1 || nX1 >= 40) { + nCurrd = 4; + } else { + nCurrd = 2; + } + } + if(nDy == 1 && nDx > 1 && (nCurrd == 1 || nCurrd == 3)) { + if(nX2 <= nX1 || nX1 >= 40) { + nCurrd = 4; + } else { + nCurrd = 2; + } + } + if(nDx == 1 && nDy > 1 && (nCurrd == 2 || nCurrd == 4)) { + if(nY2 <= nY1 || nX1 >= 40) { + nCurrd = 1; + } else { + nCurrd = 3; + } + } + if(nDx == 0 && predungeon[nX1][nY1] != 32 && (nCurrd == 2 || nCurrd == 4)) { + if(nX2 <= nOrigX1 || nX1 >= 40) { + nCurrd = 1; + } else { + nCurrd = 3; + } + } + if(nDy == 0 && predungeon[nX1][nY1] != 32 && (nCurrd == 1 || nCurrd == 3)) { + if(nY2 <= nOrigY1 || nY1 >= 40) { + nCurrd = 4; + } else { + nCurrd = 2; + } + } + if(nX1 == nX2 && nY1 == nY2) { + fDoneflag = TRUE; + } + } +} + +static void DoPatternCheck(int i, int j) +{ + int k, l, x, y, nOk; + + for(k = 0; Patterns[k][4] != 255; k++) { + x = i - 1; + y = j - 1; + nOk = 254; + for(l = 0; l < 9 && nOk == 254; l++) { + nOk = 255; + if(l == 3 || l == 6) { + y++; + x = i - 1; + } + if(x >= 0 && x < 40 && y >= 0 && y < 40) { + switch(Patterns[k][l]) { + case 0: + nOk = 254; + break; + case 1: + if(predungeon[x][y] == 35) { + nOk = 254; + } + break; + case 2: + if(predungeon[x][y] == 46) { + nOk = 254; + } + break; + case 4: + if(predungeon[x][y] == 32) { + nOk = 254; + } + break; + case 3: + if(predungeon[x][y] == 68) { + nOk = 254; + } + break; + case 5: + if(predungeon[x][y] == 68 || predungeon[x][y] == 46) { + nOk = 254; + } + break; + case 6: + if(predungeon[x][y] == 68 || predungeon[x][y] == 35) { + nOk = 254; + } + break; + case 7: + if(predungeon[x][y] == 32 || predungeon[x][y] == 46) { + nOk = 254; + } + break; + case 8: + if(predungeon[x][y] == 68 || predungeon[x][y] == 35 || predungeon[x][y] == 46) { + nOk = 254; + } + break; + } + } else { + nOk = 254; + } + x++; + } + if(nOk == 254) { + dungeon[i][j] = Patterns[k][9]; + } + } +} + +static void L2TileFix() +{ + int i, j; + + for(j = 0; j < 40; j++) { + for(i = 0; i < 40; i++) { + if(dungeon[i][j] == 1 && dungeon[i][j + 1] == 3) { + dungeon[i][j + 1] = 1; + } + if(dungeon[i][j] == 3 && dungeon[i][j + 1] == 1) { + dungeon[i][j + 1] = 3; + } + if(dungeon[i][j] == 3 && dungeon[i + 1][j] == 7) { + dungeon[i + 1][j] = 3; + } + if(dungeon[i][j] == 2 && dungeon[i + 1][j] == 3) { + dungeon[i + 1][j] = 2; + } + if(dungeon[i][j] == 11 && dungeon[i + 1][j] == 14) { + dungeon[i + 1][j] = 16; + } + } + } +} + +static BOOL DL2_Cont(BOOL x1f, BOOL y1f, BOOL x2f, BOOL y2f) +{ + if(x1f && x2f && y1f && y2f) { + return FALSE; + } + if(x1f && x2f && (y1f || y2f)) { + return TRUE; + } + if(y1f && y2f && (x1f || x2f)) { + return TRUE; + } + + return FALSE; +} + +static int DL2_NumNoChar() +{ + int t, ii, jj; + + t = 0; + for(jj = 0; jj < 40; jj++) { + for(ii = 0; ii < 40; ii++) { + if(predungeon[ii][jj] == 32) { + t++; + } + } + } + + return t; +} + +static void DL2_DrawRoom(int x1, int y1, int x2, int y2) +{ + int ii, jj; + + for(jj = y1; jj <= y2; jj++) { + for(ii = x1; ii <= x2; ii++) { + predungeon[ii][jj] = 46; + } + } + for(jj = y1; jj <= y2; jj++) { + predungeon[x1][jj] = 35; + predungeon[x2][jj] = 35; + } + for(ii = x1; ii <= x2; ii++) { + predungeon[ii][y1] = 35; + predungeon[ii][y2] = 35; + } +} + +static void DL2_KnockWalls(int x1, int y1, int x2, int y2) +{ + int ii, jj; + + for(ii = x1 + 1; ii < x2; ii++) { + if(predungeon[ii][y1 - 1] == 46 && predungeon[ii][y1 + 1] == 46) { + predungeon[ii][y1] = 46; + } + if(predungeon[ii][y2 - 1] == 46 && predungeon[ii][y2 + 1] == 46) { + predungeon[ii][y2] = 46; + } + if(predungeon[ii][y1 - 1] == 68) { + predungeon[ii][y1 - 1] = 46; + } + if(predungeon[ii][y2 + 1] == 68) { + predungeon[ii][y2 + 1] = 46; + } + } + for(jj = y1 + 1; jj < y2; jj++) { + if(predungeon[x1 - 1][jj] == 46 && predungeon[x1 + 1][jj] == 46) { + predungeon[x1][jj] = 46; + } + if(predungeon[x2 - 1][jj] == 46 && predungeon[x2 + 1][jj] == 46) { + predungeon[x2][jj] = 46; + } + if(predungeon[x1 - 1][jj] == 68) { + predungeon[x1 - 1][jj] = 46; + } + if(predungeon[x2 + 1][jj] == 68) { + predungeon[x2 + 1][jj] = 46; + } + } +} + +static BOOL DL2_FillVoids() +{ + int ii, jj, xx, yy, x1, x2, y1, y2; + BOOL xf1, xf2, yf1, yf2; + int to; + + to = 0; + while(DL2_NumNoChar() > 700 && to < 100) { + xx = random(0, 38) + 1; + yy = random(0, 38) + 1; + if(predungeon[xx][yy] != 35) { + continue; + } + xf1 = xf2 = yf1 = yf2 = FALSE; + if(predungeon[xx - 1][yy] == 32 && predungeon[xx + 1][yy] == 46) { + if(predungeon[xx + 1][yy - 1] == 46 + && predungeon[xx + 1][yy + 1] == 46 + && predungeon[xx - 1][yy - 1] == 32 + && predungeon[xx - 1][yy + 1] == 32) { + xf1 = yf1 = yf2 = TRUE; + } + } else if(predungeon[xx + 1][yy] == 32 && predungeon[xx - 1][yy] == 46) { + if(predungeon[xx - 1][yy - 1] == 46 + && predungeon[xx - 1][yy + 1] == 46 + && predungeon[xx + 1][yy - 1] == 32 + && predungeon[xx + 1][yy + 1] == 32) { + xf2 = yf1 = yf2 = TRUE; + } + } else if(predungeon[xx][yy - 1] == 32 && predungeon[xx][yy + 1] == 46) { + if(predungeon[xx - 1][yy + 1] == 46 + && predungeon[xx + 1][yy + 1] == 46 + && predungeon[xx - 1][yy - 1] == 32 + && predungeon[xx + 1][yy - 1] == 32) { + yf1 = xf1 = xf2 = TRUE; + } + } else if(predungeon[xx][yy + 1] == 32 && predungeon[xx][yy - 1] == 46) { + if(predungeon[xx - 1][yy - 1] == 46 + && predungeon[xx + 1][yy - 1] == 46 + && predungeon[xx - 1][yy + 1] == 32 + && predungeon[xx + 1][yy + 1] == 32) { + yf2 = xf1 = xf2 = TRUE; + } + } + if(DL2_Cont(xf1, yf1, xf2, yf2)) { + if(xf1) { + x1 = xx - 1; + } else { + x1 = xx; + } + if(xf2) { + x2 = xx + 1; + } else { + x2 = xx; + } + if(yf1) { + y1 = yy - 1; + } else { + y1 = yy; + } + if(yf2) { + y2 = yy + 1; + } else { + y2 = yy; + } + if(!xf1) { + while(yf1 || yf2) { + if(y1 == 0) { + yf1 = FALSE; + } + if(y2 == 39) { + yf2 = FALSE; + } + if(y2 - y1 >= 14) { + yf1 = FALSE; + yf2 = FALSE; + } + if(yf1) { + y1--; + } + if(yf2) { + y2++; + } + if(predungeon[x2][y1] != 32) { + yf1 = FALSE; + } + if(predungeon[x2][y2] != 32) { + yf2 = FALSE; + } + } + y1 += 2; + y2 -= 2; + if(y2 - y1 > 5) { + while(xf2) { + if(x2 == 39) { + xf2 = FALSE; + } + if(x2 - x1 >= 12) { + xf2 = FALSE; + } + for(jj = y1; jj <= y2; jj++) { + if(predungeon[x2][jj] != 32) { + xf2 = FALSE; + } + } + if(xf2) { + x2++; + } + } + x2 -= 2; + if(x2 - x1 > 5) { + DL2_DrawRoom(x1, y1, x2, y2); + DL2_KnockWalls(x1, y1, x2, y2); + } + } + } else if(!xf2) { + while(yf1 || yf2) { + if(y1 == 0) { + yf1 = FALSE; + } + if(y2 == 39) { + yf2 = FALSE; + } + if(y2 - y1 >= 14) { + yf1 = FALSE; + yf2 = FALSE; + } + if(yf1) { + y1--; + } + if(yf2) { + y2++; + } + if(predungeon[x1][y1] != 32) { + yf1 = FALSE; + } + if(predungeon[x1][y2] != 32) { + yf2 = FALSE; + } + } + y1 += 2; + y2 -= 2; + if(y2 - y1 > 5) { + while(xf1) { + if(x1 == 0) { + xf1 = FALSE; + } + if(x2 - x1 >= 12) { + xf1 = FALSE; + } + for(jj = y1; jj <= y2; jj++) { + if(predungeon[x1][jj] != 32) { + xf1 = FALSE; + } + } + if(xf1) { + x1--; + } + } + x1 += 2; + if(x2 - x1 > 5) { + DL2_DrawRoom(x1, y1, x2, y2); + DL2_KnockWalls(x1, y1, x2, y2); + } + } + } else if(!yf1) { + while(xf1 || xf2) { + if(x1 == 0) { + xf1 = FALSE; + } + if(x2 == 39) { + xf2 = FALSE; + } + if(x2 - x1 >= 14) { + xf1 = FALSE; + xf2 = FALSE; + } + if(xf1) { + x1--; + } + if(xf2) { + x2++; + } + if(predungeon[x1][y2] != 32) { + xf1 = FALSE; + } + if(predungeon[x2][y2] != 32) { + xf2 = FALSE; + } + } + x1 += 2; + x2 -= 2; + if(x2 - x1 > 5) { + while(yf2) { + if(y2 == 39) { + yf2 = FALSE; + } + if(y2 - y1 >= 12) { + yf2 = FALSE; + } + for(ii = x1; ii <= x2; ii++) { + if(predungeon[ii][y2] != 32) { + yf2 = FALSE; + } + } + if(yf2) { + y2++; + } + } + y2 -= 2; + if(y2 - y1 > 5) { + DL2_DrawRoom(x1, y1, x2, y2); + DL2_KnockWalls(x1, y1, x2, y2); + } + } + } else if(!yf2) { + while(xf1 || xf2) { + if(x1 == 0) { + xf1 = FALSE; + } + if(x2 == 39) { + xf2 = FALSE; + } + if(x2 - x1 >= 14) { + xf1 = FALSE; + xf2 = FALSE; + } + if(xf1) { + x1--; + } + if(xf2) { + x2++; + } + if(predungeon[x1][y1] != 32) { + xf1 = FALSE; + } + if(predungeon[x2][y1] != 32) { + xf2 = FALSE; + } + } + x1 += 2; + x2 -= 2; + if(x2 - x1 > 5) { + while(yf1) { + if(y1 == 0) { + yf1 = FALSE; + } + if(y2 - y1 >= 12) { + yf1 = FALSE; + } + for(ii = x1; ii <= x2; ii++) { + if(predungeon[ii][y1] != 32) { + yf1 = FALSE; + } + } + if(yf1) { + y1--; + } + } + y1 += 2; + if(y2 - y1 > 5) { + DL2_DrawRoom(x1, y1, x2, y2); + DL2_KnockWalls(x1, y1, x2, y2); + } + } + } + } + to++; + } + + return DL2_NumNoChar() <= 700; +} + +static BOOL CreateDungeon() +{ + int i, j, nHx1, nHy1, nHx2, nHy2, nHd, ForceH, ForceW; + BOOL ForceHW; + + ForceW = 0; + ForceH = 0; + ForceHW = FALSE; + + switch(currlevel) { + case 5: + if(quests[Q_BLOOD]._qactive) { + ForceHW = TRUE; + ForceH = 20; + ForceW = 14; + } + break; + case 6: + if(quests[Q_SCHAMB]._qactive) { + ForceHW = TRUE; + ForceW = 10; + ForceH = 10; + } + break; + case 7: + if(quests[Q_BLIND]._qactive) { + ForceHW = TRUE; + ForceW = 15; + ForceH = 15; + } + break; + case 8: + break; + } + + CreateRoom(2, 2, 39, 39, 0, 0, ForceHW, ForceH, ForceW); + + while(pHallList != NULL) { + GetHall(&nHx1, &nHy1, &nHx2, &nHy2, &nHd); + ConnectHall(nHx1, nHy1, nHx2, nHy2, nHd); + } + + for(j = 0; j <= DMAXY; j++) { /// BUGFIX: change '<=' to '<' + for(i = 0; i <= DMAXX; i++) { /// BUGFIX: change '<=' to '<' + if(predungeon[i][j] == 67) { + predungeon[i][j] = 35; + } + if(predungeon[i][j] == 66) { + predungeon[i][j] = 35; + } + if(predungeon[i][j] == 69) { + predungeon[i][j] = 35; + } + if(predungeon[i][j] == 65) { + predungeon[i][j] = 35; + } + if(predungeon[i][j] == 44) { + predungeon[i][j] = 46; + if(predungeon[i - 1][j - 1] == 32) { + predungeon[i - 1][j - 1] = 35; + } + if(predungeon[i - 1][j] == 32) { + predungeon[i - 1][j] = 35; + } + if(predungeon[i - 1][1 + j] == 32) { + predungeon[i - 1][1 + j] = 35; + } + if(predungeon[i + 1][j - 1] == 32) { + predungeon[i + 1][j - 1] = 35; + } + if(predungeon[i + 1][j] == 32) { + predungeon[i + 1][j] = 35; + } + if(predungeon[i + 1][1 + j] == 32) { + predungeon[i + 1][1 + j] = 35; + } + if(predungeon[i][j - 1] == 32) { + predungeon[i][j - 1] = 35; + } + if(predungeon[i][j + 1] == 32) { + predungeon[i][j + 1] = 35; + } + } + } + } + + if(!DL2_FillVoids()) { + return FALSE; + } + + for(j = 0; j < DMAXY; j++) { + for(i = 0; i < DMAXX; i++) { + DoPatternCheck(i, j); + } + } + + return TRUE; +} + +static void DRLG_L2Pass3() +{ + int i, j, xx, yy; + long v1, v2, v3, v4, lv; + + lv = 12-1; + +#ifdef USE_ASM + __asm { + mov esi, pMegaTiles + mov eax, lv + shl eax, 3 + add esi, eax + xor eax, eax + lodsw + inc eax + mov v1, eax + lodsw + inc eax + mov v2, eax + lodsw + inc eax + mov v3, eax + lodsw + inc eax + mov v4, eax + } +#else + v1 = ((WORD *)&pMegaTiles[lv << 3])[0] + 1; + v2 = ((WORD *)&pMegaTiles[lv << 3])[1] + 1; + v3 = ((WORD *)&pMegaTiles[lv << 3])[2] + 1; + v4 = ((WORD *)&pMegaTiles[lv << 3])[3] + 1; +#endif + + for(j = 0; j < MAXDUNY; j += 2) { + for(i = 0; i < MAXDUNX; i += 2) { + dPiece[i][j] = v1; + dPiece[i+1][j] = v2; + dPiece[i][j+1] = v3; + dPiece[i+1][j+1] = v4; + } + } + + yy = 16; + for(j = 0; j < DMAXY; j++) { + xx = 16; + for(i = 0; i < DMAXX; i++) { + lv = (unsigned char)dungeon[i][j]-1; +#ifdef USE_ASM + __asm { + mov esi, pMegaTiles + mov eax, lv + shl eax, 3 + add esi, eax + xor eax, eax + lodsw + inc eax + mov v1, eax + lodsw + inc eax + mov v2, eax + lodsw + inc eax + mov v3, eax + lodsw + inc eax + mov v4, eax + } +#else + v1 = ((WORD *)&pMegaTiles[lv << 3])[0] + 1; + v2 = ((WORD *)&pMegaTiles[lv << 3])[1] + 1; + v3 = ((WORD *)&pMegaTiles[lv << 3])[2] + 1; + v4 = ((WORD *)&pMegaTiles[lv << 3])[3] + 1; +#endif + dPiece[xx][yy] = v1; + dPiece[xx+1][yy] = v2; + dPiece[xx][yy+1] = v3; + dPiece[xx+1][yy+1] = v4; + xx += 2; + } + yy += 2; + } +} + +static void DRLG_L2FTVR(int i, int j, int x, int y, int d) +{ + if(dTransVal[x][y] != 0 || dungeon[i][j] != 3) { + if(d == 1) { + dTransVal[x][y] = TransVal; + dTransVal[x][y + 1] = TransVal; + } + if(d == 2) { + dTransVal[x + 1][y] = TransVal; + dTransVal[x + 1][y + 1] = TransVal; + } + if(d == 3) { + dTransVal[x][y] = TransVal; + dTransVal[x + 1][y] = TransVal; + } + if(d == 4) { + dTransVal[x][y + 1] = TransVal; + dTransVal[x + 1][y + 1] = TransVal; + } + if(d == 5) { + dTransVal[x + 1][y + 1] = TransVal; + } + if(d == 6) { + dTransVal[x][y + 1] = TransVal; + } + if(d == 7) { + dTransVal[x + 1][y] = TransVal; + } + if(d == 8) { + dTransVal[x][y] = TransVal; + } + } else { + dTransVal[x][y] = TransVal; + dTransVal[x + 1][y] = TransVal; + dTransVal[x][y + 1] = TransVal; + dTransVal[x + 1][y + 1] = TransVal; + DRLG_L2FTVR(i + 1, j, x + 2, y, 1); + DRLG_L2FTVR(i - 1, j, x - 2, y, 2); + DRLG_L2FTVR(i, j + 1, x, y + 2, 3); + DRLG_L2FTVR(i, j - 1, x, y - 2, 4); + DRLG_L2FTVR(i - 1, j - 1, x - 2, y - 2, 5); + DRLG_L2FTVR(i + 1, j - 1, x + 2, y - 2, 6); + DRLG_L2FTVR(i - 1, j + 1, x - 2, y + 2, 7); + DRLG_L2FTVR(i + 1, j + 1, x + 2, y + 2, 8); + } +} + +static void DRLG_L2FloodTVal() +{ + int i, j, xx, yy; + + yy = 16; + for(j = 0; j < 40; j++) { + xx = 16; + for(i = 0; i < 40; i++) { + if(dungeon[i][j] == 3 && dTransVal[xx][yy] == 0) { + DRLG_L2FTVR(i, j, xx, yy, 0); + TransVal++; + } + xx += 2; + } + yy += 2; + } +} + +static void DRLG_L2TransFix() +{ + int i, j, xx, yy; + + yy = 16; + for(j = 0; j < 40; j++) { + xx = 16; + for(i = 0; i < 40; i++) { + if(dungeon[i][j] == 14 && dungeon[i][j - 1] == 10) { + dTransVal[xx + 1][yy] = dTransVal[xx][yy]; + dTransVal[xx + 1][yy + 1] = dTransVal[xx][yy]; + } + if(dungeon[i][j] == 15 && dungeon[i + 1][j] == 11) { + dTransVal[xx][yy + 1] = dTransVal[xx][yy]; + dTransVal[xx + 1][yy + 1] = dTransVal[xx][yy]; + } + if(dungeon[i][j] == 10) { + dTransVal[xx + 1][yy] = dTransVal[xx][yy]; + dTransVal[xx + 1][yy + 1] = dTransVal[xx][yy]; + } + if(dungeon[i][j] == 11) { + dTransVal[xx][yy + 1] = dTransVal[xx][yy]; + dTransVal[xx + 1][yy + 1] = dTransVal[xx][yy]; + } + if(dungeon[i][j] == 16) { + dTransVal[xx + 1][yy] = dTransVal[xx][yy]; + dTransVal[xx][yy + 1] = dTransVal[xx][yy]; + dTransVal[xx + 1][yy + 1] = dTransVal[xx][yy]; + } + xx += 2; + } + yy += 2; + } +} + +static void L2DirtFix() +{ + int i, j; + + for(j = 0; j < 40; j++) { + for(i = 0; i < 40; i++) { + if(dungeon[i][j] == 13 && dungeon[i + 1][j] != 11) { + dungeon[i][j] = 146; + } + if(dungeon[i][j] == 11 && dungeon[i + 1][j] != 11) { + dungeon[i][j] = 144; + } + if(dungeon[i][j] == 15 && dungeon[i + 1][j] != 11) { + dungeon[i][j] = 148; + } + if(dungeon[i][j] == 10 && dungeon[i][j + 1] != 10) { + dungeon[i][j] = 143; + } + if(dungeon[i][j] == 13 && dungeon[i][j + 1] != 10) { + dungeon[i][j] = 146; + } + if(dungeon[i][j] == 14 && dungeon[i][j + 1] != 15) { + dungeon[i][j] = 147; + } + } + } +} + +void L2LockoutFix() +{ + int i, j; + BOOL doorok; + + for(j = 0; j < DMAXY; j++) { + for(i = 0; i < DMAXX; i++) { + if(dungeon[i][j] == 4 && dungeon[i - 1][j] != 3) { + dungeon[i][j] = 1; + } + if(dungeon[i][j] == 5 && dungeon[i][j - 1] != 3) { + dungeon[i][j] = 2; + } + } + } + for(j = 1; j < DMAXY - 1; j++) { + for(i = 1; i < DMAXX - 1; i++) { + if(dflags[i][j] & 0x80) { + continue; + } + if((dungeon[i][j] == 2 || dungeon[i][j] == 5) && dungeon[i][j - 1] == 3 && dungeon[i][j + 1] == 3) { + doorok = FALSE; + while(1) { + if(dungeon[i][j] != 2 && dungeon[i][j] != 5) { + break; + } + if(dungeon[i][j - 1] != 3 || dungeon[i][j + 1] != 3) { + break; + } + if(dungeon[i][j] == 5) { + doorok = TRUE; + } + i++; + } + if(!doorok && !(dflags[i - 1][j] & 0x80)) { + dungeon[i - 1][j] = 5; + } + } + } + } + for(j = 1; j < DMAXX - 1; j++) { /* check: might be flipped */ + for(i = 1; i < DMAXY - 1; i++) { + if(dflags[j][i] & 0x80) { + continue; + } + if((dungeon[j][i] == 1 || dungeon[j][i] == 4) && dungeon[j - 1][i] == 3 && dungeon[j + 1][i] == 3) { + doorok = FALSE; + while(1) { + if(dungeon[j][i] != 1 && dungeon[j][i] != 4) { + break; + } + if(dungeon[j - 1][i] != 3 || dungeon[j + 1][i] != 3) { + break; + } + if(dungeon[j][i] == 4) { + doorok = TRUE; + } + i++; + } + if(!doorok && !(dflags[j][i - 1] & 0x80)) { + dungeon[j][i - 1] = 4; + } + } + } + } +} + +void L2DoorFix() +{ + int i, j; + + for(j = 1; j < 40; j++) { + for(i = 1; i < 40; i++) { + if(dungeon[i][j] == 4 && dungeon[i][j - 1] == 3) { + dungeon[i][j] = 7; + } + if(dungeon[i][j] == 5 && dungeon[i - 1][j] == 3) { + dungeon[i][j] = 9; + } + } + } +} + +static void DRLG_L2(int entry) +{ + int i, j; + BOOL doneflag; + + doneflag = FALSE; + while(!doneflag) { + nRoomCnt = 0; + InitDungeon(); + DRLG_InitTrans(); + if(!CreateDungeon()) { + continue; + } + L2TileFix(); + if(setloadflag_2) { + DRLG_L2SetRoom(nSx1, nSy1); + } + DRLG_L2FloodTVal(); + DRLG_L2TransFix(); + if(entry == 0) { + doneflag = DRLG_L2PlaceMiniSet(USTAIRS, 1, 1, -1, -1, 1, 0); + if(doneflag) { + doneflag = DRLG_L2PlaceMiniSet(DSTAIRS, 1, 1, -1, -1, 0, 1); + if(doneflag && currlevel == 5) { + doneflag = DRLG_L2PlaceMiniSet(WARPSTAIRS, 1, 1, -1, -1, 0, 6); + } + } + ViewY -= 2; + } else if(entry == 1) { + doneflag = DRLG_L2PlaceMiniSet(USTAIRS, 1, 1, -1, -1, 0, 0); + if(doneflag) { + doneflag = DRLG_L2PlaceMiniSet(DSTAIRS, 1, 1, -1, -1, 1, 1); + if(doneflag && currlevel == 5) { + doneflag = DRLG_L2PlaceMiniSet(WARPSTAIRS, 1, 1, -1, -1, 0, 6); + } + } + ViewX--; + } else { + doneflag = DRLG_L2PlaceMiniSet(USTAIRS, 1, 1, -1, -1, 0, 0); + if(doneflag) { + doneflag = DRLG_L2PlaceMiniSet(DSTAIRS, 1, 1, -1, -1, 0, 1); + if(doneflag && currlevel == 5) { + doneflag = DRLG_L2PlaceMiniSet(WARPSTAIRS, 1, 1, -1, -1, 1, 6); + } + } + ViewY -= 2; + } + } + + L2LockoutFix(); + L2DoorFix(); + L2DirtFix(); + + DRLG_PlaceThemeRooms(6, 10, 3, 0, 0); + DRLG_L2PlaceRndSet(CTRDOOR1, 100); + DRLG_L2PlaceRndSet(CTRDOOR2, 100); + DRLG_L2PlaceRndSet(CTRDOOR3, 100); + DRLG_L2PlaceRndSet(CTRDOOR4, 100); + DRLG_L2PlaceRndSet(CTRDOOR5, 100); + DRLG_L2PlaceRndSet(CTRDOOR6, 100); + DRLG_L2PlaceRndSet(CTRDOOR7, 100); + DRLG_L2PlaceRndSet(CTRDOOR8, 100); + DRLG_L2PlaceRndSet(VARCH33, 100); + DRLG_L2PlaceRndSet(VARCH34, 100); + DRLG_L2PlaceRndSet(VARCH35, 100); + DRLG_L2PlaceRndSet(VARCH36, 100); + DRLG_L2PlaceRndSet(VARCH37, 100); + DRLG_L2PlaceRndSet(VARCH38, 100); + DRLG_L2PlaceRndSet(VARCH39, 100); + DRLG_L2PlaceRndSet(VARCH40, 100); + DRLG_L2PlaceRndSet(VARCH1, 100); + DRLG_L2PlaceRndSet(VARCH2, 100); + DRLG_L2PlaceRndSet(VARCH3, 100); + DRLG_L2PlaceRndSet(VARCH4, 100); + DRLG_L2PlaceRndSet(VARCH5, 100); + DRLG_L2PlaceRndSet(VARCH6, 100); + DRLG_L2PlaceRndSet(VARCH7, 100); + DRLG_L2PlaceRndSet(VARCH8, 100); + DRLG_L2PlaceRndSet(VARCH9, 100); + DRLG_L2PlaceRndSet(VARCH10, 100); + DRLG_L2PlaceRndSet(VARCH11, 100); + DRLG_L2PlaceRndSet(VARCH12, 100); + DRLG_L2PlaceRndSet(VARCH13, 100); + DRLG_L2PlaceRndSet(VARCH14, 100); + DRLG_L2PlaceRndSet(VARCH15, 100); + DRLG_L2PlaceRndSet(VARCH16, 100); + DRLG_L2PlaceRndSet(VARCH17, 100); + DRLG_L2PlaceRndSet(VARCH18, 100); + DRLG_L2PlaceRndSet(VARCH19, 100); + DRLG_L2PlaceRndSet(VARCH20, 100); + DRLG_L2PlaceRndSet(VARCH21, 100); + DRLG_L2PlaceRndSet(VARCH22, 100); + DRLG_L2PlaceRndSet(VARCH23, 100); + DRLG_L2PlaceRndSet(VARCH24, 100); + DRLG_L2PlaceRndSet(VARCH25, 100); + DRLG_L2PlaceRndSet(VARCH26, 100); + DRLG_L2PlaceRndSet(VARCH27, 100); + DRLG_L2PlaceRndSet(VARCH28, 100); + DRLG_L2PlaceRndSet(VARCH29, 100); + DRLG_L2PlaceRndSet(VARCH30, 100); + DRLG_L2PlaceRndSet(VARCH31, 100); + DRLG_L2PlaceRndSet(VARCH32, 100); + DRLG_L2PlaceRndSet(HARCH1, 100); + DRLG_L2PlaceRndSet(HARCH2, 100); + DRLG_L2PlaceRndSet(HARCH3, 100); + DRLG_L2PlaceRndSet(HARCH4, 100); + DRLG_L2PlaceRndSet(HARCH5, 100); + DRLG_L2PlaceRndSet(HARCH6, 100); + DRLG_L2PlaceRndSet(HARCH7, 100); + DRLG_L2PlaceRndSet(HARCH8, 100); + DRLG_L2PlaceRndSet(HARCH9, 100); + DRLG_L2PlaceRndSet(HARCH10, 100); + DRLG_L2PlaceRndSet(HARCH11, 100); + DRLG_L2PlaceRndSet(HARCH12, 100); + DRLG_L2PlaceRndSet(HARCH13, 100); + DRLG_L2PlaceRndSet(HARCH14, 100); + DRLG_L2PlaceRndSet(HARCH15, 100); + DRLG_L2PlaceRndSet(HARCH16, 100); + DRLG_L2PlaceRndSet(HARCH17, 100); + DRLG_L2PlaceRndSet(HARCH18, 100); + DRLG_L2PlaceRndSet(HARCH19, 100); + DRLG_L2PlaceRndSet(HARCH20, 100); + DRLG_L2PlaceRndSet(HARCH21, 100); + DRLG_L2PlaceRndSet(HARCH22, 100); + DRLG_L2PlaceRndSet(HARCH23, 100); + DRLG_L2PlaceRndSet(HARCH24, 100); + DRLG_L2PlaceRndSet(HARCH25, 100); + DRLG_L2PlaceRndSet(HARCH26, 100); + DRLG_L2PlaceRndSet(HARCH27, 100); + DRLG_L2PlaceRndSet(HARCH28, 100); + DRLG_L2PlaceRndSet(HARCH29, 100); + DRLG_L2PlaceRndSet(HARCH30, 100); + DRLG_L2PlaceRndSet(HARCH31, 100); + DRLG_L2PlaceRndSet(HARCH32, 100); + DRLG_L2PlaceRndSet(HARCH33, 100); + DRLG_L2PlaceRndSet(HARCH34, 100); + DRLG_L2PlaceRndSet(HARCH35, 100); + DRLG_L2PlaceRndSet(HARCH36, 100); + DRLG_L2PlaceRndSet(HARCH37, 100); + DRLG_L2PlaceRndSet(HARCH38, 100); + DRLG_L2PlaceRndSet(HARCH39, 100); + DRLG_L2PlaceRndSet(HARCH40, 100); + DRLG_L2PlaceRndSet(CRUSHCOL, 99); + DRLG_L2PlaceRndSet(RUINS1, 10); + DRLG_L2PlaceRndSet(RUINS2, 10); + DRLG_L2PlaceRndSet(RUINS3, 10); + DRLG_L2PlaceRndSet(RUINS4, 10); + DRLG_L2PlaceRndSet(RUINS5, 10); + DRLG_L2PlaceRndSet(RUINS6, 10); + DRLG_L2PlaceRndSet(RUINS7, 50); + DRLG_L2PlaceRndSet(PANCREAS1, 1); + DRLG_L2PlaceRndSet(PANCREAS2, 1); + DRLG_L2PlaceRndSet(BIG1, 3); + DRLG_L2PlaceRndSet(BIG2, 3); + DRLG_L2PlaceRndSet(BIG3, 3); + DRLG_L2PlaceRndSet(BIG4, 3); + DRLG_L2PlaceRndSet(BIG5, 3); + DRLG_L2PlaceRndSet(BIG6, 20); + DRLG_L2PlaceRndSet(BIG7, 20); + DRLG_L2PlaceRndSet(BIG8, 3); + DRLG_L2PlaceRndSet(BIG9, 20); + DRLG_L2PlaceRndSet(BIG10, 20); + DRLG_L2Subs(); + DRLG_L2Shadows(); + + for(j = 0; j < 40; j++) { + for(i = 0; i < 40; i++) { + pdungeon[i][j] = dungeon[i][j]; + } + } + + DRLG_Init_Globals(); + DRLG_CheckQuests(nSx1, nSy1); +} + +static void DRLG_InitL2Vals() +{ + int i, j, pc; + + for(j = 0; j < 112; j++) { + for(i = 0; i < 112; i++) { + if(dPiece[i][j] == 541) { + pc = 5; + } else if(dPiece[i][j] == 178) { + pc = 5; + } else if(dPiece[i][j] == 551) { + pc = 5; + } else if(dPiece[i][j] == 542) { + pc = 6; + } else if(dPiece[i][j] == 553) { + pc = 6; + } else if(dPiece[i][j] == 13) { + pc = 5; + } else if(dPiece[i][j] == 17) { + pc = 6; + } else { + continue; + } + dSpecial[i][j] = pc; + } + } + for(j = 0; j < 112; j++) { + for(i = 0; i < 112; i++) { + if(dPiece[i][j] == 132) { + dSpecial[i][j + 1] = 2; + dSpecial[i][j + 2] = 1; + } else if(dPiece[i][j] == 135 || dPiece[i][j] == 139) { + dSpecial[i + 1][j] = 3; + dSpecial[i + 2][j] = 4; + } + } + } +} + +void LoadL2Dungeon(char *sFileName, int vx, int vy) +{ + int i, j, rw, rh, pc; + BYTE *pLevelMap, *lm; + + InitDungeon(); + DRLG_InitTrans(); + pLevelMap = DiabLoad(sFileName, NULL, 'LMPt'); + + for(j = 0; j < DMAXY; j++) { + for(i = 0; i < DMAXX; i++) { + dungeon[i][j] = 12; + dflags[i][j] = 0; + } + } + + lm = pLevelMap; + rw = *lm; + lm += 2; + rh = *lm; + lm += 2; + + for(j = 0; j < rh; j++) { + for(i = 0; i < rw; i++) { + if(*lm != 0) { + dungeon[i][j] = *lm; + dflags[i][j] |= 0x80; + } else { + dungeon[i][j] = 3; + } + lm += 2; + } + } + for(j = 0; j < DMAXY; j++) { + for(i = 0; i < DMAXX; i++) { + if(dungeon[i][j] == 0) { + dungeon[i][j] = 12; + } + } + } + + DRLG_L2Pass3(); + DRLG_Init_Globals(); + + for(j = 0; j < MAXDUNY; j++) { + for(i = 0; i < MAXDUNX; i++) { + pc = 0; + if(dPiece[i][j] == 541) { + pc = 5; + } + if(dPiece[i][j] == 178) { + pc = 5; + } + if(dPiece[i][j] == 551) { + pc = 5; + } + if(dPiece[i][j] == 542) { + pc = 6; + } + if(dPiece[i][j] == 553) { + pc = 6; + } + if(dPiece[i][j] == 13) { + pc = 5; + } + if(dPiece[i][j] == 17) { + pc = 6; + } + dSpecial[i][j] = pc; + } + } + for(j = 0; j < MAXDUNY; j++) { + for(i = 0; i < MAXDUNX; i++) { + if(dPiece[i][j] == 132) { + dSpecial[i][j + 1] = 2; + dSpecial[i][j + 2] = 1; + } else if(dPiece[i][j] == 135 || dPiece[i][j] == 139) { + dSpecial[i + 1][j] = 3; + dSpecial[i + 2][j] = 4; + } + } + } + + ViewX = vx; + ViewY = vy; + SetMapMonsters(pLevelMap, 0, 0); + SetMapObjects(pLevelMap, 0, 0); + mem_free_dbg(pLevelMap); +} + +void LoadPreL2Dungeon(char *sFileName, int vx, int vy) +{ + int i, j, rw, rh; + BYTE *pLevelMap, *lm; + + InitDungeon(); + DRLG_InitTrans(); + pLevelMap = DiabLoad(sFileName, NULL, 'LMPt'); + + for(j = 0; j < DMAXY; j++) { + for(i = 0; i < DMAXX; i++) { + dungeon[i][j] = 12; + dflags[i][j] = 0; + } + } + + lm = pLevelMap; + rw = *lm; + lm += 2; + rh = *lm; + lm += 2; + + for(j = 0; j < rh; j++) { + for(i = 0; i < rw; i++) { + if(*lm != 0) { + dungeon[i][j] = *lm; + dflags[i][j] |= 0x80; + } else { + dungeon[i][j] = 3; + } + lm += 2; + } + } + for(j = 0; j < DMAXY; j++) { + for(i = 0; i < DMAXX; i++) { + if(dungeon[i][j] == 0) { + dungeon[i][j] = 12; + } + } + } + for(j = 0; j < DMAXY; j++) { + for(i = 0; i < DMAXX; i++) { + pdungeon[i][j] = dungeon[i][j]; + } + } + + mem_free_dbg(pLevelMap); +} + +void CreateL2Dungeon(unsigned int rseed, int entry) +{ + if(gbMaxPlayers == 1) { + if(currlevel == 7 && !quests[8]._qactive) { + currlevel = 6; + CreateL2Dungeon(glSeedTbl[6], 4); + currlevel = 7; + } + if(currlevel == 8) { + if(!quests[8]._qactive) { + currlevel = 6; + CreateL2Dungeon(glSeedTbl[6], 4); + currlevel = 8; + } else { + currlevel = 7; + CreateL2Dungeon(glSeedTbl[7], 4); + currlevel = 8; + + } + } + } + + SetRndSeed(rseed); + + dminx = 16; + dminy = 16; + dmaxx = 96; + dmaxy = 96; + + DRLG_InitTrans(); + DRLG_InitSetPC(); + DRLG_LoadL2SP(); + DRLG_L2(entry); + DRLG_L2Pass3(); + DRLG_FreeL2SP(); + DRLG_InitL2Vals(); + DRLG_SetPC(); +} diff --git a/2020_03_31/Source/drlg_l2.h b/2020_03_31/Source/drlg_l2.h new file mode 100644 index 00000000..f7d68852 --- /dev/null +++ b/2020_03_31/Source/drlg_l2.h @@ -0,0 +1,144 @@ +//HEADER_GOES_HERE +#ifndef __DRLG_L2_H__ +#define __DRLG_L2_H__ + +extern int nSx1; +extern int nSx2; // weak +extern int nSy1; +extern int nSy2; // weak +extern int nRoomCnt; +extern unsigned char predungeon[40][40]; +extern ROOMNODE RoomList[81]; +extern HALLNODE *pHallList; + +void InitDungeon(); +void L2LockoutFix(); +void L2DoorFix(); +void LoadL2Dungeon(char *sFileName, int vx, int vy); +void LoadPreL2Dungeon(char *sFileName, int vx, int vy); +void CreateL2Dungeon(unsigned int rseed, int entry); + +/* rdata */ +extern int Area_Min; // weak +extern int Room_Max; // weak +extern int Room_Min; // weak +extern int Dir_Xadd[5]; +extern int Dir_Yadd[5]; +extern ShadowStruct SPATSL2[2]; +//short word_48489A; +extern unsigned char BTYPESL2[161]; +extern unsigned char BSTYPESL2[161]; +extern unsigned char VARCH1[]; +extern unsigned char VARCH2[]; +extern unsigned char VARCH3[]; +extern unsigned char VARCH4[]; +extern unsigned char VARCH5[]; +extern unsigned char VARCH6[]; +extern unsigned char VARCH7[]; +extern unsigned char VARCH8[]; +extern unsigned char VARCH9[]; +extern unsigned char VARCH10[]; +extern unsigned char VARCH11[]; +extern unsigned char VARCH12[]; +extern unsigned char VARCH13[]; +extern unsigned char VARCH14[]; +extern unsigned char VARCH15[]; +extern unsigned char VARCH16[]; +extern unsigned char VARCH17[]; +extern unsigned char VARCH18[]; +extern unsigned char VARCH19[]; +extern unsigned char VARCH20[]; +extern unsigned char VARCH21[]; +extern unsigned char VARCH22[]; +extern unsigned char VARCH23[]; +extern unsigned char VARCH24[]; +extern unsigned char VARCH25[]; +extern unsigned char VARCH26[]; +extern unsigned char VARCH27[]; +extern unsigned char VARCH28[]; +extern unsigned char VARCH29[]; +extern unsigned char VARCH30[]; +extern unsigned char VARCH31[]; +extern unsigned char VARCH32[]; +extern unsigned char VARCH33[]; +extern unsigned char VARCH34[]; +extern unsigned char VARCH35[]; +extern unsigned char VARCH36[]; +extern unsigned char VARCH37[]; +extern unsigned char VARCH38[]; +extern unsigned char VARCH39[]; +extern unsigned char VARCH40[]; +extern unsigned char HARCH1[]; +extern unsigned char HARCH2[]; +extern unsigned char HARCH3[]; +extern unsigned char HARCH4[]; +extern unsigned char HARCH5[]; +extern unsigned char HARCH6[]; +extern unsigned char HARCH7[]; +extern unsigned char HARCH8[]; +extern unsigned char HARCH9[]; +extern unsigned char HARCH10[]; +extern unsigned char HARCH11[]; +extern unsigned char HARCH12[]; +extern unsigned char HARCH13[]; +extern unsigned char HARCH14[]; +extern unsigned char HARCH15[]; +extern unsigned char HARCH16[]; +extern unsigned char HARCH17[]; +extern unsigned char HARCH18[]; +extern unsigned char HARCH19[]; +extern unsigned char HARCH20[]; +extern unsigned char HARCH21[]; +extern unsigned char HARCH22[]; +extern unsigned char HARCH23[]; +extern unsigned char HARCH24[]; +extern unsigned char HARCH25[]; +extern unsigned char HARCH26[]; +extern unsigned char HARCH27[]; +extern unsigned char HARCH28[]; +extern unsigned char HARCH29[]; +extern unsigned char HARCH30[]; +extern unsigned char HARCH31[]; +extern unsigned char HARCH32[]; +extern unsigned char HARCH33[]; +extern unsigned char HARCH34[]; +extern unsigned char HARCH35[]; +extern unsigned char HARCH36[]; +extern unsigned char HARCH37[]; +extern unsigned char HARCH38[]; +extern unsigned char HARCH39[]; +extern unsigned char HARCH40[]; +extern unsigned char USTAIRS[]; +extern unsigned char DSTAIRS[]; +extern unsigned char WARPSTAIRS[]; +extern unsigned char CRUSHCOL[]; +extern unsigned char BIG1[]; +extern unsigned char BIG2[]; +extern unsigned char BIG3[]; +extern unsigned char BIG4[]; +extern unsigned char BIG5[]; +extern unsigned char BIG6[]; +extern unsigned char BIG7[]; +extern unsigned char BIG8[]; +extern unsigned char BIG9[]; +extern unsigned char BIG10[]; +extern unsigned char RUINS1[]; +extern unsigned char RUINS2[]; +extern unsigned char RUINS3[]; +extern unsigned char RUINS4[]; +extern unsigned char RUINS5[]; +extern unsigned char RUINS6[]; +extern unsigned char RUINS7[]; +extern unsigned char PANCREAS1[]; +extern unsigned char PANCREAS2[]; +extern unsigned char CTRDOOR1[]; +extern unsigned char CTRDOOR2[]; +extern unsigned char CTRDOOR3[]; +extern unsigned char CTRDOOR4[]; +extern unsigned char CTRDOOR5[]; +extern unsigned char CTRDOOR6[]; +extern unsigned char CTRDOOR7[]; +extern unsigned char CTRDOOR8[]; +extern int Patterns[100][10]; + +#endif /* __DRLG_L2_H__ */ diff --git a/2020_03_31/Source/drlg_l3.cpp b/2020_03_31/Source/drlg_l3.cpp new file mode 100644 index 00000000..cb55f423 --- /dev/null +++ b/2020_03_31/Source/drlg_l3.cpp @@ -0,0 +1,1812 @@ +#include "diablo.h" + +char lavapool; // weak +int abyssx; // weak +int lockoutcnt; // weak +BOOLEAN lockout[40][40]; + +const unsigned char L3ConvTbl[16] = { 8, 11, 3, 10, 1, 9, 12, 12, 6, 13, 4, 13, 2, 14, 5, 7 }; +const unsigned char L3UP[20] = { 3, 3, 8, 8, 0, 10, 10, 0, 7, 7, 0, 51, 50, 0, 48, 49, 0, 0, 0, 0 }; +const unsigned char L3DOWN[20] = { 3, 3, 8, 9, 7, 8, 9, 7, 0, 0, 0, 0, 47, 0, 0, 46, 0, 0, 0, 0 }; +const unsigned char L3HOLDWARP[20] = { 3, 3, 8, 8, 0, 10, 10, 0, 7, 7, 0, 125, 125, 0, 125, 125, 0, 0, 0, 0 }; +const unsigned char L3TITE1[34] = { 4, 4, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 57, 58, 0, 0, 56, 55, 0, 0, 0, 0, 0 }; +const unsigned char L3TITE2[34] = { 4, 4, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 61, 62, 0, 0, 60, 59, 0, 0, 0, 0, 0 }; +const unsigned char L3TITE3[34] = { 4, 4, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 65, 66, 0, 0, 64, 63, 0, 0, 0, 0, 0 }; +const unsigned char L3TITE6[42] = { 5, 4, 7, 7, 7, 7, 7, 7, 7, 7, 0, 7, 7, 7, 7, 0, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 77, 78, 0, 0, 0, 76, 74, 75, 0, 0, 0, 0, 0, 0 }; +const unsigned char L3TITE7[42] = { 4, 5, 7, 7, 7, 7, 7, 7, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 83, 0, 0, 0, 82, 80, 0, 0, 81, 79, 0, 0, 0, 0, 0 }; +const unsigned char L3TITE8[20] = { 3, 3, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 52, 0, 0, 0, 0 }; +const unsigned char L3TITE9[20] = { 3, 3, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 53, 0, 0, 0, 0 }; +const unsigned char L3TITE10[20] = { 3, 3, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 54, 0, 0, 0, 0 }; +const unsigned char L3TITE11[20] = { 3, 3, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 67, 0, 0, 0, 0 }; +const unsigned char L3TITE12[6] = { 2u, 1u, 9u, 7u, 68u, 0u }; +const unsigned char L3TITE13[6] = { 1u, 2u, 10u, 7u, 69u, 0u }; +const unsigned char L3CREV1[6] = { 2u, 1u, 8u, 7u, 84u, 85u }; +const unsigned char L3CREV2[6] = { 2u, 1u, 8u, 11u, 86u, 87u }; +const unsigned char L3CREV3[6] = { 1u, 2u, 8u, 10u, 89u, 88u }; +const unsigned char L3CREV4[6] = { 2u, 1u, 8u, 7u, 90u, 91u }; +const unsigned char L3CREV5[6] = { 1u, 2u, 8u, 11u, 92u, 93u }; +const unsigned char L3CREV6[6] = { 1u, 2u, 8u, 10u, 95u, 94u }; +const unsigned char L3CREV7[6] = { 2u, 1u, 8u, 7u, 96u, 101u }; +const unsigned char L3CREV8[6] = { 1u, 2u, 2u, 8u, 102u, 97u }; +const unsigned char L3CREV9[6] = { 2u, 1u, 3u, 8u, 103u, 98u }; +const unsigned char L3CREV10[6] = { 2u, 1u, 4u, 8u, 104u, 99u }; +const unsigned char L3CREV11[6] = { 1u, 2u, 6u, 8u, 105u, 100u }; +const unsigned char L3ISLE1[14] = { 2u, 3u, 5u, 14u, 4u, 9u, 13u, 12u, 7u, 7u, 7u, 7u, 7u, 7u }; +const unsigned char L3ISLE2[14] = { 3u, 2u, 5u, 2u, 14u, 13u, 10u, 12u, 7u, 7u, 7u, 7u, 7u, 7u }; +const unsigned char L3ISLE3[14] = { 2u, 3u, 5u, 14u, 4u, 9u, 13u, 12u, 29u, 30u, 25u, 28u, 31u, 32u }; +const unsigned char L3ISLE4[14] = { 3u, 2u, 5u, 2u, 14u, 13u, 10u, 12u, 29u, 26u, 30u, 31u, 27u, 32u }; +const unsigned char L3ISLE5[10] = { 2u, 2u, 5u, 14u, 13u, 12u, 7u, 7u, 7u, 7u }; +const unsigned char L3XTRA1[4] = { 1u, 1u, 7u, 106u }; +const unsigned char L3XTRA2[4] = { 1u, 1u, 7u, 107u }; +const unsigned char L3XTRA3[4] = { 1u, 1u, 7u, 108u }; +const unsigned char L3XTRA4[4] = { 1u, 1u, 9u, 109u }; +const unsigned char L3XTRA5[4] = { 1u, 1u, 10u, 110u }; +const unsigned char L3ANVIL[244] = +{ + 11, 11, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 29, 26, 26, 26, + 26, 26, 30, 0, 0, 0, 29, 34, 33, 33, + 37, 36, 33, 35, 30, 0, 0, 25, 33, 37, + 27, 32, 31, 36, 33, 28, 0, 0, 25, 37, + 32, 7, 7, 7, 31, 27, 32, 0, 0, 25, + 28, 7, 7, 7, 7, 2, 2, 2, 0, 0, + 25, 35, 30, 7, 7, 7, 29, 26, 30, 0, + 0, 25, 33, 35, 26, 30, 29, 34, 33, 28, + 0, 0, 31, 36, 33, 33, 35, 34, 33, 37, + 32, 0, 0, 0, 31, 27, 27, 27, 27, 27, + 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0 +}; + +static void InitL3Dungeon() +{ + int i, j; + + memset(dungeon, 0, sizeof(dungeon)); + + for(j = 0; j < 40; j++) { + for(i = 0; i < 40; i++) { + dungeon[i][j] = 0; + dflags[i][j] = 0; + } + } +} + +static BOOL DRLG_L3FillRoom(int x1, int y1, int x2, int y2) +{ + int i, j, v; + + if(x1 <= 1 || x2 >= 34 || y1 <= 1 || y2 >= 38) { + return FALSE; + } + + v = 0; + for(j = y1; j <= y2; j++) { + for(i = x1; i <= x2; i++) { + v += dungeon[i][j]; + } + } + + if(v != 0) { + return FALSE; + } + + for(j = y1 + 1; j < y2; j++) { + for(i = x1 + 1; i < x2; i++) { + dungeon[i][j] = 1; + } + } + for(j = y1; j <= y2; j++) { + if(random(0, 2) != 0) { + dungeon[x1][j] = 1; + } + if(random(0, 2) != 0) { + dungeon[x2][j] = 1; + } + } + for(i = x1; i <= x2; i++) { + if(random(0, 2) != 0) { + dungeon[i][y1] = 1; + } + if(random(0, 2) != 0) { + dungeon[i][y2] = 1; + } + } + + return TRUE; +} + +static void DRLG_L3CreateBlock(int x, int y, int obs, int dir) +{ + int blksizex, blksizey, x1, y1, x2, y2; + BOOL contflag; + + blksizex = random(0, 2) + 3; + blksizey = random(0, 2) + 3; + + if(dir == 0) { + y2 = y - 1; + y1 = y2 - blksizey; + if(blksizex < obs) { + x1 = random(0, blksizex) + x; + } + if(blksizex == obs) { + x1 = x; + } + if(blksizex > obs) { + x1 = x - random(0, blksizex); + } + x2 = blksizex + x1; + } + if(dir == 3) { + x2 = x - 1; + x1 = x2 - blksizex; + if(blksizey < obs) { + y1 = random(0, blksizey) + y; + } + if(blksizey == obs) { + y1 = y; + } + if(blksizey > obs) { + y1 = y - random(0, blksizey); + } + y2 = y1 + blksizey; + } + if(dir == 2) { + y1 = y + 1; + y2 = y1 + blksizey; + if(blksizex < obs) { + x1 = random(0, blksizex) + x; + } + if(blksizex == obs) { + x1 = x; + } + if(blksizex > obs) { + x1 = x - random(0, blksizex); + } + x2 = blksizex + x1; + } + if(dir == 1) { + x1 = x + 1; + x2 = x1 + blksizex; + if(blksizey < obs) { + y1 = random(0, blksizey) + y; + } + if(blksizey == obs) { + y1 = y; + } + if(blksizey > obs) { + y1 = y - random(0, blksizey); + } + y2 = y1 + blksizey; + } + + if(DRLG_L3FillRoom(x1, y1, x2, y2) == TRUE) { + contflag = random(0, 4); + if(contflag && dir != 2) { + DRLG_L3CreateBlock(x1, y1, blksizey, 0); + } + if(contflag && dir != 3) { + DRLG_L3CreateBlock(x2, y1, blksizex, 1); + } + if(contflag && dir != 0) { + DRLG_L3CreateBlock(x1, y2, blksizey, 2); + } + if(contflag && dir != 1) { + DRLG_L3CreateBlock(x1, y1, blksizex, 3); + } + } +} + +static void DRLG_L3FloorArea(int x1, int y1, int x2, int y2) +{ + int i, j; + + for(j = y1; j <= y2; j++) { + for(i = x1; i <= x2; i++) { + dungeon[i][j] = 1; + } + } +} + +static void DRLG_L3FillDiags() +{ + int i, j, v; + + for(j = 0; j < 39; j++) { + for(i = 0; i < 39; i++) { + v = dungeon[i + 1][j + 1] + 2 * dungeon[i][j + 1] + 4 * dungeon[i + 1][j] + 8 * dungeon[i][j]; + if(v == 6) { + if(random(0, 2) == 0) { + dungeon[i][j] = 1; + } else { + dungeon[i + 1][j + 1] = 1; + } + } + if(v == 9) { + if(random(0, 2) == 0) { + dungeon[i + 1][j] = 1; + } else { + dungeon[i][j + 1] = 1; + } + } + } + } +} + +static void DRLG_L3FillSingles() +{ + int i, j; + + for(j = 1; j < 39; j++) { + for(i = 1; i < 39; i++) { + if(dungeon[i][j] == 0 + && dungeon[i][j - 1] + dungeon[i - 1][j - 1] + dungeon[i + 1][j - 1] == 3 + && dungeon[i + 1][j] + dungeon[i - 1][j] == 2 + && dungeon[i][j + 1] + dungeon[i - 1][j + 1] + dungeon[i + 1][j + 1] == 3) { + dungeon[i][j] = 1; + } + } + } +} + +static void DRLG_L3FillStraights() +{ + int i, j, xc, xs, yc, ys, k; + + for(j = 0; j < 39; j++) { + xs = 0; + for(i = 0; i < 37; i++) { + if(dungeon[i][j] == 0 && dungeon[i][j + 1] == 1) { + if(xs == 0) { + xc = i; + } + xs++; + } else { + if(xs > 3 && random(0, 2) != 0) { + for(k = xc; k < i; k++) { + dungeon[k][j] = random(0, 2); + } + } + xs = 0; + } + } + } + for(j = 0; j < 39; j++) { + xs = 0; + for(i = 0; i < 37; i++) { + if(dungeon[i][j] == 1 && dungeon[i][j + 1] == 0) { + if(xs == 0) { + xc = i; + } + xs++; + } else { + if(xs > 3 && random(0, 2) != 0) { + for(k = xc; k < i; k++) { + dungeon[k][j + 1] = random(0, 2); + } + } + xs = 0; + } + } + } + for(i = 0; i < 39; i++) { + ys = 0; + for(j = 0; j < 37; j++) { + if(dungeon[i][j] == 0 && dungeon[i + 1][j] == 1) { + if(ys == 0) { + yc = j; + } + ys++; + } else { + if(ys > 3 && random(0, 2) != 0) { + for(k = yc; k < j; k++) { + dungeon[i][k] = random(0, 2); + } + } + ys = 0; + } + } + } + for(i = 0; i < 39; i++) { + ys = 0; + for(j = 0; j < 37; j++) { + if(dungeon[i][j] == 1 && dungeon[i + 1][j] == 0) { + if(ys == 0) { + yc = j; + } + ys++; + } else { + if(ys > 3 && random(0, 2) != 0) { + for(k = yc; k < j; k++) { + dungeon[i + 1][k] = random(0, 2); + } + } + ys = 0; + } + } + } +} + +static void DRLG_L3Edges() +{ + int i, j; + + for(j = 0; j < 40; j++) { + dungeon[39][j] = 0; + } + for(i = 0; i < 40; i++) { + dungeon[i][39] = 0; + } +} + +static int DRLG_L3GetFloorArea() +{ + int i, j, gfa; + + gfa = 0; + + for(j = 0; j < 40; j++) { + for(i = 0; i < 40; i++) { + gfa += dungeon[i][j]; + } + } + + return gfa; +} + +static void DRLG_L3MakeMegas() +{ + int i, j, v; + + for(j = 0; j < 39; j++) { + for(i = 0; i < 39; i++) { + v = dungeon[i + 1][j + 1] + 2 * dungeon[i][j + 1] + 4 * dungeon[i + 1][j] + 8 * dungeon[i][j]; + if(v == 6) { + if(random(0, 2) == 0) { + v = 12; + } else { + v = 5; + } + } + if(v == 9) { + if(random(0, 2) == 0) { + v = 13; + } else { + v = 14; + } + } + dungeon[i][j] = L3ConvTbl[v]; + } + dungeon[39][j] = 8; + } + for(i = 0; i < 40; i++) { + dungeon[i][39] = 8; + } +} + +static void DRLG_L3River() +{ + int rx, ry, px, py, dir, pdir, nodir, nodir2, dircheck; + int river[3][100]; + int rivercnt, riveramt; + int i, trys, found, bridge, lpcnt; + BOOL bail; + + rivercnt = 0; + bail = FALSE; + trys = 0; + + while(trys < 200 && rivercnt < 4) { + bail = FALSE; + while(!bail && trys < 200) { + trys++; + rx = 0; + ry = 0; + i = 0; + while((dungeon[rx][ry] < 25 || dungeon[rx][ry] > 28) && i < 100) { + rx = random(0, 40); + ry = random(0, 40); + i++; + while((dungeon[rx][ry] < 25 || dungeon[rx][ry] > 28) && ry < 40) { + rx++; + if(rx >= 40) { + rx = 0; + ry++; + } + } + } + if(i >= 100) { + return; + } + switch(dungeon[rx][ry]) { + case 25: + dir = 3; + nodir = 2; + river[2][0] = 40; + break; + case 26: + dir = 0; + nodir = 1; + river[2][0] = 38; + break; + case 27: + dir = 1; + nodir = 0; + river[2][0] = 41; + break; + case 28: + dir = 2; + nodir = 3; + river[2][0] = 39; + break; + } + river[0][0] = rx; + river[1][0] = ry; + riveramt = 1; + nodir2 = 4; + dircheck = 0; + while(dircheck < 4 && riveramt < 100) { + px = rx; + py = ry; + if(dircheck == 0) { + dir = random(0, 4); + } else { + dir = (dir + 1) & 3; + } + dircheck++; + while(dir == nodir || dir == nodir2) { + dir = (dir + 1) & 3; + dircheck++; + } + if(dir == 0 && ry > 0) { + ry--; + } + if(dir == 1 && ry < 40) { + ry++; + } + if(dir == 2 && rx < 40) { + rx++; + } + if(dir == 3 && rx > 0) { + rx--; + } + if(dungeon[rx][ry] == 7) { + dircheck = 0; + if(dir < 2) { + river[2][riveramt] = (BYTE)random(0, 2) + 17; + } + if(dir > 1) { + river[2][riveramt] = (BYTE)random(0, 2) + 15; + } + river[0][riveramt] = rx; + river[1][riveramt] = ry; + riveramt++; + if(dir == 0 && pdir == 2 || dir == 3 && pdir == 1) { + if(riveramt > 2) { + river[2][riveramt - 2] = 22; + } + if(dir == 0) { + nodir2 = 1; + } else { + nodir2 = 2; + } + } + if(dir == 0 && pdir == 3 || dir == 2 && pdir == 1) { + if(riveramt > 2) { + river[2][riveramt - 2] = 21; + } + if(dir == 0) { + nodir2 = 1; + } else { + nodir2 = 3; + } + } + if(dir == 1 && pdir == 2 || dir == 3 && pdir == 0) { + if(riveramt > 2) { + river[2][riveramt - 2] = 20; + } + if(dir == 1) { + nodir2 = 0; + } else { + nodir2 = 2; + } + } + if(dir == 1 && pdir == 3 || dir == 2 && pdir == 0) { + if(riveramt > 2) { + river[2][riveramt - 2] = 19; + } + if(dir == 1) { + nodir2 = 0; + } else { + nodir2 = 3; + } + } + pdir = dir; + } else { + rx = px; + ry = py; + } + } + if(dir == 0 && dungeon[rx][ry - 1] == 10 && dungeon[rx][ry - 2] == 8) { + river[0][riveramt] = rx; + river[1][riveramt] = ry - 1; + river[2][riveramt] = 24; + if(pdir == 2) { + river[2][riveramt - 1] = 22; + } + if(pdir == 3) { + river[2][riveramt - 1] = 21; + } + bail = TRUE; + } + if(dir == 1 && dungeon[rx][ry + 1] == 2 && dungeon[rx][ry + 2] == 8) { + river[0][riveramt] = rx; + river[1][riveramt] = ry + 1; + river[2][riveramt] = 42; + if(pdir == 2) { + river[2][riveramt - 1] = 20; + } + if(pdir == 3) { + river[2][riveramt - 1] = 19; + } + bail = TRUE; + } + if(dir == 2 && dungeon[rx + 1][ry] == 4 && dungeon[rx + 2][ry] == 8) { + river[0][riveramt] = rx + 1; + river[1][riveramt] = ry; + river[2][riveramt] = 43; + if(pdir == 0) { + river[2][riveramt - 1] = 19; + } + if(pdir == 1) { + river[2][riveramt - 1] = 21; + } + bail = TRUE; + } + if(dir == 3 && dungeon[rx - 1][ry] == 9 && dungeon[rx - 2][ry] == 8) { + river[0][riveramt] = rx - 1; + river[1][riveramt] = ry; + river[2][riveramt] = 23; + if(pdir == 0) { + river[2][riveramt - 1] = 20; + } + if(pdir == 1) { + river[2][riveramt - 1] = 22; + } + bail = TRUE; + } + } + if(bail == TRUE && riveramt < 7) { + bail = FALSE; + } + if(bail == TRUE) { + found = 0; + lpcnt = 0; + while(found == 0 && lpcnt < 30) { + lpcnt++; + bridge = random(0, riveramt); + if((river[2][bridge] == 15 || river[2][bridge] == 16) + && dungeon[river[0][bridge]][river[1][bridge] - 1] == 7 + && dungeon[river[0][bridge]][river[1][bridge] + 1] == 7) { + found = 1; + } + if((river[2][bridge] == 17 || river[2][bridge] == 18) + && dungeon[river[0][bridge] - 1][river[1][bridge]] == 7 + && dungeon[river[0][bridge] + 1][river[1][bridge]] == 7) { + found = 2; + } + for(i = 0; i < riveramt && found != 0; i++) { + if(found == 1 + && (river[1][bridge] - 1 == river[1][i] || river[1][bridge] + 1 == river[1][i]) + && river[0][bridge] == river[0][i]) { + found = 0; + } + if(found == 2 + && (river[0][bridge] - 1 == river[0][i] || river[0][bridge] + 1 == river[0][i]) + && river[1][bridge] == river[1][i]) { + found = 0; + } + } + } + if(found != 0) { + if(found == 1) { + river[2][bridge] = 44; + } else { + river[2][bridge] = 45; + } + rivercnt++; + for(bridge = 0; bridge <= riveramt; bridge++) { + dungeon[river[0][bridge]][river[1][bridge]] = river[2][bridge]; + } + } else { + bail = FALSE; + } + } + } +} + +static BOOL DRLG_L3Spawn(int x, int y, int *totarea); + +static BOOL DRLG_L3SpawnEdge(int x, int y, int *totarea) +{ + unsigned char i; + static unsigned char spawntable[15] = { 0, 10, 67, 5, 44, 6, 9, 0, 0, 28, 131, 6, 9, 10, 5 }; + + if(*totarea > 40) { + return TRUE; + } + if(x < 0 || y < 0 || x >= 40 || y >= 40) { + return TRUE; + } + if(dungeon[x][y] & 0x80) { + return FALSE; + } + if(dungeon[x][y] > 15) { + return TRUE; + } + + i = dungeon[x][y]; + dungeon[x][y] |= 0x80; + (*totarea)++; + + if(spawntable[i] & 8 && DRLG_L3SpawnEdge(x, y - 1, totarea) == TRUE) { + return TRUE; + } + if(spawntable[i] & 4 && DRLG_L3SpawnEdge(x, y + 1, totarea) == TRUE) { + return TRUE; + } + if(spawntable[i] & 2 && DRLG_L3SpawnEdge(x + 1, y, totarea) == TRUE) { + return TRUE; + } + if(spawntable[i] & 1 && DRLG_L3SpawnEdge(x - 1, y, totarea) == TRUE) { + return TRUE; + } + if(spawntable[i] & 0x80 && DRLG_L3Spawn(x, y - 1, totarea) == TRUE) { + return TRUE; + } + if(spawntable[i] & 0x40 && DRLG_L3Spawn(x, y + 1, totarea) == TRUE) { + return TRUE; + } + if(spawntable[i] & 0x20 && DRLG_L3Spawn(x + 1, y, totarea) == TRUE) { + return TRUE; + } + if(spawntable[i] & 0x10 && DRLG_L3Spawn(x - 1, y, totarea) == TRUE) { + return TRUE; + } + + return FALSE; +} + +static BOOL DRLG_L3Spawn(int x, int y, int *totarea) +{ + unsigned char i; + static unsigned char spawntable[15] = { 0, 10, 3, 5, 12, 6, 9, 0, 0, 12, 3, 6, 9, 10, 5 }; + + if(*totarea > 40) { + return TRUE; + } + if(x < 0 || y < 0 || x >= 40 || y >= 40) { + return TRUE; + } + if(dungeon[x][y] & 0x80) { + return FALSE; + } + if(dungeon[x][y] > 15) { + return TRUE; + } + + i = dungeon[x][y]; + dungeon[x][y] |= 0x80; + (*totarea)++; + + if(i != 8) { + if(spawntable[i] & 8 && DRLG_L3SpawnEdge(x, y - 1, totarea) == TRUE) { + return TRUE; + } + if(spawntable[i] & 4 && DRLG_L3SpawnEdge(x, y + 1, totarea) == TRUE) { + return TRUE; + } + if(spawntable[i] & 2 && DRLG_L3SpawnEdge(x + 1, y, totarea) == TRUE) { + return TRUE; + } + if(spawntable[i] & 1 && DRLG_L3SpawnEdge(x - 1, y, totarea) == TRUE) { + return TRUE; + } + } else { + if(DRLG_L3Spawn(x + 1, y, totarea) == TRUE) { + return TRUE; + } + if(DRLG_L3Spawn(x - 1, y, totarea) == TRUE) { + return TRUE; + } + if(DRLG_L3Spawn(x, y + 1, totarea) == TRUE) { + return TRUE; + } + if(DRLG_L3Spawn(x, y - 1, totarea) == TRUE) { + return TRUE; + } + } + + return FALSE; +} + +static void DRLG_L3Pool() +{ + int i, j, dunx, duny, totarea, poolchance; + BOOL found; + unsigned char k; + static unsigned char poolsub[15] = { 0, 35, 26, 36, 25, 29, 34, 7, 33, 28, 27, 37, 32, 31, 30 }; + + for(duny = 0; duny < 40; duny++) { + for(dunx = 0; dunx < 40; dunx++) { + if(dungeon[dunx][duny] != 8) { + continue; + } + dungeon[dunx][duny] |= 0x80; + totarea = 1; + if(dunx + 1 < 40) { + found = DRLG_L3Spawn(dunx + 1, duny, &totarea); + } else { + found = TRUE; + } + if(dunx - 1 > 0 && !found) { + found = DRLG_L3Spawn(dunx - 1, duny, &totarea); + } else { + found = TRUE; + } + if(duny + 1 < 40 && !found) { + found = DRLG_L3Spawn(dunx, duny + 1, &totarea); + } else { + found = TRUE; + } + if(duny - 1 > 0 && !found) { + found = DRLG_L3Spawn(dunx, duny - 1, &totarea); + } else { + found = TRUE; + } + poolchance = random(0, 100); + for(j = duny - totarea; j < duny + totarea; j++) { + for(i = dunx - totarea; i < dunx + totarea; i++) { + if(dungeon[i][j] & 0x80 && j >= 0 && j < 40 && i >= 0 && i < 40) { + dungeon[i][j] &= ~0x80; + if(totarea > 4 && poolchance < 25 && !found) { + k = poolsub[dungeon[i][j]]; + if(k != 0 && k <= 37) { + dungeon[i][j] = k; + } + lavapool = 1; + } + } + } + } + } + } +} + +static void DRLG_L3PoolFix() +{ + int dunx, duny; + + for(duny = 0; duny < DMAXY; duny++) { + for(dunx = 0; dunx < DMAXX; dunx++) { + if(dungeon[dunx][duny] == 8) { + if(dungeon[dunx - 1][duny - 1] >= 25 && dungeon[dunx - 1][duny - 1] <= 41 + && dungeon[dunx - 1][duny] >= 25 && dungeon[dunx - 1][duny] <= 41 + && dungeon[dunx - 1][duny + 1] >= 25 && dungeon[dunx - 1][duny + 1] <= 41 + && dungeon[dunx][duny - 1] >= 25 && dungeon[dunx][duny - 1] <= 41 + && dungeon[dunx][duny + 1] >= 25 && dungeon[dunx][duny + 1] <= 41 + && dungeon[dunx + 1][duny - 1] >= 25 && dungeon[dunx + 1][duny - 1] <= 41 + && dungeon[dunx + 1][duny] >= 25 && dungeon[dunx + 1][duny] <= 41 + && dungeon[dunx + 1][duny + 1] >= 25 && dungeon[dunx + 1][duny + 1] <= 41) { + dungeon[dunx][duny] = 33; + } + } + } + } +} + +static BOOL DRLG_L3PlaceMiniSet(const unsigned char *miniset, int tmin, int tmax, int cx, int cy, BOOL setview, int ldir) +{ + int sx, sy, sw, sh, xx, yy, i, ii, numt, trys; + BOOL found; + + sw = miniset[0]; + sh = miniset[1]; + + if(tmax - tmin == 0) { + numt = 1; + } else { + numt = random(0, tmax - tmin) + tmin; + } + + for(i = 0; i < numt; i++) { + sx = random(0, 40 - sw); + sy = random(0, 40 - sh); + found = FALSE; + trys = 0; + while(!found && trys < 200) { + trys++; + found = TRUE; + if(cx != -1 && sx >= cx - sw && sx <= cx + 12) { + sx = random(0, 40 - sw); + sy = random(0, 40 - sh); + found = FALSE; + } + if(cy != -1 && sy >= cy - sh && sy <= cy + 12) { + sx = random(0, 40 - sw); + sy = random(0, 40 - sh); + found = FALSE; + } + ii = 2; + for(yy = 0; yy < sh && found == TRUE; yy++) { + for(xx = 0; xx < sw && found == TRUE; xx++) { + if(miniset[ii] != 0 && dungeon[xx + sx][yy + sy] != miniset[ii]) { + found = FALSE; + } + if(dflags[xx + sx][yy + sy] != 0) { + found = FALSE; + } + ii++; + } + } + if(!found) { + sx++; + if(sx == 40 - sw) { + sx = 0; + sy++; + if(sy == 40 - sh) { + sy = 0; + } + } + } + } + if(trys >= 200) { + return TRUE; + } + ii = sw * sh + 2; + for(yy = 0; yy < sh; yy++) { + for(xx = 0; xx < sw; xx++) { + if(miniset[ii] != 0) { + dungeon[xx + sx][yy + sy] = miniset[ii]; + } + ii++; + } + } + } + + if(setview == TRUE) { + ViewX = 2 * sx + 17; + ViewY = 2 * sy + 19; + } + if(ldir == 0) { + LvlViewX = 2 * sx + 17; + LvlViewY = 2 * sy + 19; + } + + return FALSE; +} + +static void DRLG_L3PlaceRndSet(const unsigned char *miniset, int rndper) +{ + int sx, sy, sw, sh, xx, yy, ii, kk; + BOOL found; + + sw = miniset[0]; + sh = miniset[1]; + + for(sy = 0; sy < 40 - sh; sy++) { + for(sx = 0; sx < 40 - sw; sx++) { + found = TRUE; + ii = 2; + for(yy = 0; yy < sh && found == TRUE; yy++) { + for(xx = 0; xx < sw && found == TRUE; xx++) { + if(miniset[ii] != 0 && dungeon[xx + sx][yy + sy] != miniset[ii]) { + found = FALSE; + } + if(dflags[xx + sx][yy + sy] != 0) { + found = FALSE; + } + ii++; + } + } + kk = sw * sh + 2; + if(miniset[kk] >= 84 && miniset[kk] <= 100 && found == TRUE) { + if(dungeon[sx - 1][sy] >= 84 && dungeon[sx - 1][sy] <= 100) { + found = FALSE; + } + if(dungeon[sx + 1][sy] >= 84 && dungeon[sx - 1][sy] <= 100) { + found = FALSE; + } + if(dungeon[sx][sy + 1] >= 84 && dungeon[sx - 1][sy] <= 100) { + found = FALSE; + } + if(dungeon[sx][sy - 1] >= 84 && dungeon[sx - 1][sy] <= 100) { + found = FALSE; + } + } + if(found == TRUE && random(0, 100) < rndper) { + for(yy = 0; yy < sh; yy++) { + for(xx = 0; xx < sw; xx++) { + if(miniset[kk] != 0) { + dungeon[xx + sx][yy + sy] = miniset[kk]; + } + kk++; + } + } + } + } + } +} + +static BOOL WoodVertU(int i, int y) +{ + if((dungeon[i + 1][y] > 152 || dungeon[i + 1][y] < 130) + && (dungeon[i - 1][y] > 152 || dungeon[i - 1][y] < 130)) { + if(dungeon[i][y] == 7) { + return TRUE; + } + if(dungeon[i][y] == 10) { + return TRUE; + } + if(dungeon[i][y] == 126) { + return TRUE; + } + if(dungeon[i][y] == 129) { + return TRUE; + } + if(dungeon[i][y] == 134) { + return TRUE; + } + if(dungeon[i][y] == 136) { + return TRUE; + } + } + + return FALSE; +} + +static BOOL WoodVertD(int i, int y) +{ + if((dungeon[i + 1][y] > 152 || dungeon[i + 1][y] < 130) + && (dungeon[i - 1][y] > 152 || dungeon[i - 1][y] < 130)) { + if(dungeon[i][y] == 7) { + return TRUE; + } + if(dungeon[i][y] == 2) { + return TRUE; + } + if(dungeon[i][y] == 134) { + return TRUE; + } + if(dungeon[i][y] == 136) { + return TRUE; + } + } + + return FALSE; +} + +static BOOL WoodHorizL(int x, int j) +{ + if((dungeon[x][j + 1] > 152 || dungeon[x][j + 1] < 130) + && (dungeon[x][j - 1] > 152 || dungeon[x][j - 1] < 130)) { + if(dungeon[x][j] == 7) { + return TRUE; + } + if(dungeon[x][j] == 9) { + return TRUE; + } + if(dungeon[x][j] == 121) { + return TRUE; + } + if(dungeon[x][j] == 124) { + return TRUE; + } + if(dungeon[x][j] == 135) { + return TRUE; + } + if(dungeon[x][j] == 137) { + return TRUE; + } + } + + return FALSE; +} + +static BOOL WoodHorizR(int x, int j) +{ + if((dungeon[x][j + 1] > 152 || dungeon[x][j + 1] < 130) + && (dungeon[x][j - 1] > 152 || dungeon[x][j - 1] < 130)) { + if(dungeon[x][j] == 7) { + return TRUE; + } + if(dungeon[x][j] == 4) { + return TRUE; + } + if(dungeon[x][j] == 135) { + return TRUE; + } + if(dungeon[x][j] == 137) { + return TRUE; + } + } + + return FALSE; +} + +void AddFenceDoors() +{ + int i, j; + + for(j = 0; j < DMAXY; j++) { + for(i = 0; i < DMAXX; i++) { + if(dungeon[i][j] == 7) { + if(dungeon[i - 1][j] <= 152 && dungeon[i - 1][j] >= 130 + && dungeon[i + 1][j] <= 152 && dungeon[i + 1][j] >= 130) { + dungeon[i][j] = 146; + continue; + } + } + if(dungeon[i][j] == 7) { + if(dungeon[i][j - 1] <= 152 && dungeon[i][j - 1] >= 130 + && dungeon[i][j + 1] <= 152 && dungeon[i][j + 1] >= 130) { + dungeon[i][j] = 147; + continue; + } + } + } + } +} + +void FenceDoorFix() +{ + int i, j; + + for(j = 0; j < DMAXY; j++) { + for(i = 0; i < DMAXX; i++) { + if(dungeon[i][j] == 146) { + if(dungeon[i + 1][j] > 152 || dungeon[i + 1][j] < 130 + || dungeon[i - 1][j] > 152 || dungeon[i - 1][j] < 130) { + dungeon[i][j] = 7; + continue; + } + } + if(dungeon[i][j] == 146) { + if(dungeon[i + 1][j] != 130 && dungeon[i - 1][j] != 130 + && dungeon[i + 1][j] != 132 && dungeon[i - 1][j] != 132 + && dungeon[i + 1][j] != 133 && dungeon[i - 1][j] != 133 + && dungeon[i + 1][j] != 134 && dungeon[i - 1][j] != 134 + && dungeon[i + 1][j] != 136 && dungeon[i - 1][j] != 136 + && dungeon[i + 1][j] != 138 && dungeon[i - 1][j] != 138 + && dungeon[i + 1][j] != 140 && dungeon[i - 1][j] != 140) { + dungeon[i][j] = 7; + continue; + } + } + if(dungeon[i][j] == 147) { + if(dungeon[i][j + 1] > 152 || dungeon[i][j + 1] < 130 + || dungeon[i][j - 1] > 152 || dungeon[i][j - 1] < 130) { + dungeon[i][j] = 7; + continue; + } + } + if(dungeon[i][j] == 147) { + if(dungeon[i][j + 1] != 131 && dungeon[i][j - 1] != 131 + && dungeon[i][j + 1] != 132 && dungeon[i][j - 1] != 132 + && dungeon[i][j + 1] != 133 && dungeon[i][j - 1] != 133 + && dungeon[i][j + 1] != 135 && dungeon[i][j - 1] != 135 + && dungeon[i][j + 1] != 137 && dungeon[i][j - 1] != 137 + && dungeon[i][j + 1] != 138 && dungeon[i][j - 1] != 138 + && dungeon[i][j + 1] != 139 && dungeon[i][j - 1] != 139) { + dungeon[i][j] = 7; + continue; + } + } + } + } +} + +static void DRLG_L3Wood() +{ + int i, j, x, y, xx, yy, rt, rp, x1, y1, x2, y2; + BOOL skip; + + for(j = 0; j < DMAXY - 1; j++) { + for(i = 0; i < DMAXX - 1; i++) { + if(dungeon[i][j] == 10 && random(0, 2) != 0) { + x = i; + while(dungeon[x][j] == 10) { + x++; + } + x--; + if(x - i > 0) { + dungeon[i][j] = 127; + for(xx = i + 1; xx < x; xx++) { + if(random(0, 2) != 0) { + dungeon[xx][j] = 126; + } else { + dungeon[xx][j] = 129; + } + } + dungeon[x][j] = 128; + } + } + if(dungeon[i][j] == 9 && random(0, 2) != 0) { + y = j; + while(dungeon[i][y] == 9) { + y++; + } + y--; + if(y - j > 0) { + dungeon[i][j] = 123; + for(yy = j + 1; yy < y; yy++) { + if(random(0, 2) != 0) { + dungeon[i][yy] = 121; + } else { + dungeon[i][yy] = 124; + } + } + dungeon[i][y] = 122; + } + } + if(dungeon[i][j] == 11 && dungeon[i + 1][j] == 10 && dungeon[i][j + 1] == 9 && random(0, 2) != 0) { + dungeon[i][j] = 125; + x = i + 1; + while(dungeon[x][j] == 10) { + x++; + } + x--; + for(xx = i + 1; xx < x; xx++) { + if(random(0, 2) != 0) { + dungeon[xx][j] = 126; + } else { + dungeon[xx][j] = 129; + } + } + dungeon[x][j] = 128; + y = j + 1; + while(dungeon[i][y] == 9) { + y++; + } + y--; + for(yy = j + 1; yy < y; yy++) { + if(random(0, 2) != 0) { + dungeon[i][yy] = 121; + } else { + dungeon[i][yy] = 124; + } + } + dungeon[i][y] = 122; + } + } + } + + for(j = 0; j < DMAXY; j++) { + for(i = 0; i < DMAXX; i++) { + if(dungeon[i][j] != 7 || random(0, 1) != 0 || !SkipThemeRoom(i, j)) { + continue; + } + rt = random(0, 2); + if(rt == 0) { + y1 = j; + while(WoodVertU(i, y1)) { + y1--; + } + y1++; + y2 = j; + while(WoodVertD(i, y2)) { + y2++; + } + y2--; + skip = TRUE; + if(dungeon[i][y1] == 7) { + skip = FALSE; + } + if(dungeon[i][y2] == 7) { + skip = FALSE; + } + if(y2 - y1 > 1 && skip) { + rp = random(0, y2 - y1 - 1) + y1 + 1; + for(y = y1; y <= y2; y++) { + if(y == rp) { + continue; + } + if(dungeon[i][y] == 7) { + if(random(0, 2) != 0) { + dungeon[i][y] = 135; + } else { + dungeon[i][y] = 137; + } + } + if(dungeon[i][y] == 10) { + dungeon[i][y] = 131; + } + if(dungeon[i][y] == 126) { + dungeon[i][y] = 133; + } + if(dungeon[i][y] == 129) { + dungeon[i][y] = 133; + } + if(dungeon[i][y] == 2) { + dungeon[i][y] = 139; + } + if(dungeon[i][y] == 134) { + dungeon[i][y] = 138; + } + if(dungeon[i][y] == 136) { + dungeon[i][y] = 138; + } + } + } + } + if(rt == 1) { + x1 = i; + while(WoodHorizL(x1, j)) { + x1--; + } + x1++; + x2 = i; + while(WoodHorizR(x2, j)) { + x2++; + } + x2--; + skip = TRUE; + if(dungeon[x1][j] == 7) { + skip = FALSE; + } + if(dungeon[x2][j] == 7) { + skip = FALSE; + } + if(x2 - x1 > 1 && skip) { + rp = random(0, x2 - x1 - 1) + x1 + 1; + for(x = x1; x <= x2; x++) { + if(x == rp) { + continue; + } + if(dungeon[x][j] == 7) { + if(random(0, 2) != 0) { + dungeon[x][j] = 134; + } else { + dungeon[x][j] = 136; + } + } + if(dungeon[x][j] == 9) { + dungeon[x][j] = 130; + } + if(dungeon[x][j] == 121) { + dungeon[x][j] = 132; + } + if(dungeon[x][j] == 124) { + dungeon[x][j] = 132; + } + if(dungeon[x][j] == 4) { + dungeon[x][j] = 140; + } + if(dungeon[x][j] == 135) { + dungeon[x][j] = 138; + } + if(dungeon[x][j] == 137) { + dungeon[x][j] = 138; + } + } + } + } + } + } + + AddFenceDoors(); + FenceDoorFix(); +} + +BOOL DRLG_L3Anvil() +{ + int sx, sy, sw, sh, xx, yy, ii, trys; + BOOL found; + + sx = random(0, 29); + sy = random(0, 29); + sw = 11; + sh = 11; + + found = FALSE; + trys = 0; + while(!found && trys < 200) { + trys++; + found = TRUE; + ii = 2; + for(yy = 0; yy < sh && found == TRUE; yy++) { + for(xx = 0; xx < sw && found == TRUE; xx++) { + if(L3ANVIL[ii] != 0 && dungeon[xx + sx][yy + sy] != L3ANVIL[ii]) { + found = FALSE; + } + if(dflags[xx + sx][yy + sy] != 0) { + found = FALSE; + } + ii++; + } + } + if(!found) { + sx++; + if(sx == 29) { + sx = 0; + sy++; + if(sy == 29) { + sy = 0; + } + } + } + } + if(trys >= 200) { + return TRUE; + } + + ii = 123; + for(yy = 0; yy < sh; yy++) { + for(xx = 0; xx < sw; xx++) { + if(L3ANVIL[ii] != 0) { + dungeon[xx + sx][yy + sy] = L3ANVIL[ii]; + } + dflags[xx + sx][yy + sy] |= 0x80; + ii++; + } + } + + setpc_x = sx; + setpc_y = sy; + setpc_w = sw; + setpc_h = sh; + + return FALSE; +} + +void FixL3Warp() +{ + int i, j; + + for(j = 0; j < 40; j++) { + for(i = 0; i < 40; i++) { + if(dungeon[i][j] == 125 && dungeon[i + 1][j] == 125 && dungeon[i][j + 1] == 125 && dungeon[i + 1][j + 1] == 125) { + dungeon[i][j] = 156; + dungeon[i + 1][j] = 155; + dungeon[i][j + 1] = 153; + dungeon[i + 1][j + 1] = 154; + return; + } + if(dungeon[i][j] == 5 && dungeon[i + 1][j + 1] == 7) { + dungeon[i][j] = 7; + } + } + } +} + +void FixL3HallofHeroes() +{ + int i, j; + + for(j = 0; j < 40; j++) { + for(i = 0; i < 40; i++) { + if(dungeon[i][j] == 5 && dungeon[i + 1][j + 1] == 7) { + dungeon[i][j] = 7; + } + } + } + for(j = 0; j < 40; j++) { + for(i = 0; i < 40; i++) { + if(dungeon[i][j] == 5 && dungeon[i + 1][j + 1] == 12 && dungeon[i + 1][j] == 7) { + dungeon[i][j] = 7; + dungeon[i][j + 1] = 7; + dungeon[i + 1][j + 1] = 7; + } + if(dungeon[i][j] == 5 && dungeon[i + 1][j + 1] == 12 && dungeon[i][j + 1] == 7) { + dungeon[i][j] = 7; + dungeon[i + 1][j] = 7; + dungeon[i + 1][j + 1] = 7; + } + } + } +} + +void DRLG_L3LockRec(int x, int y) +{ + if(!lockout[x][y]) { + return; + } + + lockout[x][y] = FALSE; + lockoutcnt++; + DRLG_L3LockRec(x, y - 1); + DRLG_L3LockRec(x, y + 1); + DRLG_L3LockRec(x - 1, y); + DRLG_L3LockRec(x + 1, y); +} + +BOOL DRLG_L3Lockout() +{ + int i, j, t, fx, fy; + + t = 0; + for(j = 0; j < DMAXY; j++) { + for(i = 0; i < DMAXX; i++) { + if(dungeon[i][j] != 0) { + lockout[i][j] = TRUE; + fx = i; + fy = j; + t++; + } else { + lockout[i][j] = FALSE; + } + } + } + + lockoutcnt = 0; + DRLG_L3LockRec(fx, fy); + + return t == lockoutcnt; +} + +static void DRLG_L3(int entry) +{ + int x1, y1, x2, y2, i, j; + BOOL found, genok; + + lavapool = FALSE; + + do { + do { + do { + InitL3Dungeon(); + x1 = random(0, 20) + 10; + y1 = random(0, 20) + 10; + x2 = x1 + 2; + y2 = y1 + 2; + DRLG_L3FillRoom(x1, y1, x2, y2); + DRLG_L3CreateBlock(x1, y1, 2, 0); + DRLG_L3CreateBlock(x2, y1, 2, 1); + DRLG_L3CreateBlock(x1, y2, 2, 2); + DRLG_L3CreateBlock(x1, y1, 2, 3); + if(QuestStatus(Q_ANVIL)) { + x1 = random(0, 10) + 10; + y1 = random(0, 10) + 10; + x2 = x1 + 12; + y2 = y1 + 12; + DRLG_L3FloorArea(x1, y1, x2, y2); + } + DRLG_L3FillDiags(); + DRLG_L3FillSingles(); + DRLG_L3FillStraights(); + DRLG_L3FillDiags(); + DRLG_L3Edges(); + if(DRLG_L3GetFloorArea() >= 600) { + found = DRLG_L3Lockout(); + } else { + found = FALSE; + } + } while(!found); + DRLG_L3MakeMegas(); + if(entry == 0) { + genok = DRLG_L3PlaceMiniSet(L3UP, 1, 1, -1, -1, 1, 0); + if(!genok) { + genok = DRLG_L3PlaceMiniSet(L3DOWN, 1, 1, -1, -1, 0, 1); + if(!genok && currlevel == 9) { + genok = DRLG_L3PlaceMiniSet(L3HOLDWARP, 1, 1, -1, -1, 0, 6); + } + } + } else if(entry == 1) { + genok = DRLG_L3PlaceMiniSet(L3UP, 1, 1, -1, -1, 0, 0); + if(!genok) { + genok = DRLG_L3PlaceMiniSet(L3DOWN, 1, 1, -1, -1, 1, 1); + ViewX += 2; + ViewY -= 2; + if(!genok && currlevel == 9) { + genok = DRLG_L3PlaceMiniSet(L3HOLDWARP, 1, 1, -1, -1, 0, 6); + } + } + } else { + genok = DRLG_L3PlaceMiniSet(L3UP, 1, 1, -1, -1, 0, 0); + if(!genok) { + genok = DRLG_L3PlaceMiniSet(L3DOWN, 1, 1, -1, -1, 0, 1); + if(!genok && currlevel == 9) { + genok = DRLG_L3PlaceMiniSet(L3HOLDWARP, 1, 1, -1, -1, 1, 6); + } + } + } + if(!genok && QuestStatus(Q_ANVIL)) { + genok = DRLG_L3Anvil(); + } + } while(genok == TRUE); + DRLG_L3Pool(); + } while(!lavapool); + + DRLG_L3PoolFix(); + FixL3Warp(); + DRLG_L3PlaceRndSet(L3ISLE1, 70); + DRLG_L3PlaceRndSet(L3ISLE2, 70); + DRLG_L3PlaceRndSet(L3ISLE3, 30); + DRLG_L3PlaceRndSet(L3ISLE4, 30); + DRLG_L3PlaceRndSet(L3ISLE1, 100); + DRLG_L3PlaceRndSet(L3ISLE2, 100); + DRLG_L3PlaceRndSet(L3ISLE5, 90); + FixL3HallofHeroes(); + DRLG_L3River(); + + if(QuestStatus(Q_ANVIL)) { + dungeon[setpc_x + 7][setpc_y + 5] = 7; + dungeon[setpc_x + 8][setpc_y + 5] = 7; + dungeon[setpc_x + 9][setpc_y + 5] = 7; + if(dungeon[setpc_x + 10][setpc_y + 5] == 17 || dungeon[setpc_x + 10][setpc_y + 5] == 18) { + dungeon[setpc_x + 10][setpc_y + 5] = 45; + } + } + + DRLG_PlaceThemeRooms(5, 10, 7, 0, 0); + DRLG_L3Wood(); + DRLG_L3PlaceRndSet(L3TITE1, 10); + DRLG_L3PlaceRndSet(L3TITE2, 10); + DRLG_L3PlaceRndSet(L3TITE3, 10); + DRLG_L3PlaceRndSet(L3TITE6, 20); + DRLG_L3PlaceRndSet(L3TITE7, 20); + DRLG_L3PlaceRndSet(L3TITE8, 20); + DRLG_L3PlaceRndSet(L3TITE9, 20); + DRLG_L3PlaceRndSet(L3TITE10, 20); + DRLG_L3PlaceRndSet(L3TITE11, 30); + DRLG_L3PlaceRndSet(L3TITE12, 20); + DRLG_L3PlaceRndSet(L3TITE13, 20); + DRLG_L3PlaceRndSet(L3CREV1, 30); + DRLG_L3PlaceRndSet(L3CREV2, 30); + DRLG_L3PlaceRndSet(L3CREV3, 30); + DRLG_L3PlaceRndSet(L3CREV4, 30); + DRLG_L3PlaceRndSet(L3CREV5, 30); + DRLG_L3PlaceRndSet(L3CREV6, 30); + DRLG_L3PlaceRndSet(L3CREV7, 30); + DRLG_L3PlaceRndSet(L3CREV8, 30); + DRLG_L3PlaceRndSet(L3CREV9, 30); + DRLG_L3PlaceRndSet(L3CREV10, 30); + DRLG_L3PlaceRndSet(L3CREV11, 30); + DRLG_L3PlaceRndSet(L3XTRA1, 25); + DRLG_L3PlaceRndSet(L3XTRA2, 25); + DRLG_L3PlaceRndSet(L3XTRA3, 25); + DRLG_L3PlaceRndSet(L3XTRA4, 25); + DRLG_L3PlaceRndSet(L3XTRA5, 25); + + for(j = 0; j < DMAXY; j++) { + for(i = 0; i < DMAXX; i++) { + pdungeon[i][j] = dungeon[i][j]; + } + } + + DRLG_Init_Globals(); +} + +static void DRLG_L3Pass3() +{ + int i, j, xx, yy; + long v1, v2, v3, v4, lv; + + lv = 8-1; + +#ifdef USE_ASM + __asm { + mov esi, pMegaTiles + mov eax, lv + shl eax, 3 + add esi, eax + xor eax, eax + lodsw + inc eax + mov v1, eax + lodsw + inc eax + mov v2, eax + lodsw + inc eax + mov v3, eax + lodsw + inc eax + mov v4, eax + } +#else + v1 = ((WORD *)&pMegaTiles[lv << 3])[0] + 1; + v2 = ((WORD *)&pMegaTiles[lv << 3])[1] + 1; + v3 = ((WORD *)&pMegaTiles[lv << 3])[2] + 1; + v4 = ((WORD *)&pMegaTiles[lv << 3])[3] + 1; +#endif + + for(j = 0; j < MAXDUNY; j += 2) { + for(i = 0; i < MAXDUNX; i += 2) { + dPiece[i][j] = v1; + dPiece[i+1][j] = v2; + dPiece[i][j+1] = v3; + dPiece[i+1][j+1] = v4; + } + } + + yy = 16; + for(j = 0; j < DMAXY; j++) { + xx = 16; + for(i = 0; i < DMAXX; i++) { + lv = (unsigned char)dungeon[i][j]-1; + if(lv >= 0) { +#ifdef USE_ASM + __asm { + mov esi, pMegaTiles + mov eax, lv + shl eax, 3 + add esi, eax + xor eax, eax + lodsw + inc eax + mov v1, eax + lodsw + inc eax + mov v2, eax + lodsw + inc eax + mov v3, eax + lodsw + inc eax + mov v4, eax + } +#else + v1 = ((WORD *)&pMegaTiles[lv << 3])[0] + 1; + v2 = ((WORD *)&pMegaTiles[lv << 3])[1] + 1; + v3 = ((WORD *)&pMegaTiles[lv << 3])[2] + 1; + v4 = ((WORD *)&pMegaTiles[lv << 3])[3] + 1; +#endif + } else { + v1 = 0; + v2 = 0; + v3 = 0; + v4 = 0; + } + dPiece[xx][yy] = v1; + dPiece[xx+1][yy] = v2; + dPiece[xx][yy+1] = v3; + dPiece[xx+1][yy+1] = v4; + xx += 2; + } + yy += 2; + } +} + +void CreateL3Dungeon(unsigned int rseed, int entry) +{ + int i, j; + + SetRndSeed(rseed); + dminx = 16; + dminy = 16; + dmaxx = 96; + dmaxy = 96; + DRLG_InitTrans(); + DRLG_InitSetPC(); + DRLG_L3(entry); + DRLG_L3Pass3(); + + for(j = 0; j < 112; j++) { + for(i = 0; i < 112; i++) { + if(dPiece[i][j] >= 56 && dPiece[i][j] <= 147) { + DoLighting(i, j, 7, -1); + } else if(dPiece[i][j] >= 154 && dPiece[i][j] <= 161) { + DoLighting(i, j, 7, -1); + } else if(dPiece[i][j] == 150) { + DoLighting(i, j, 7, -1); + } else if(dPiece[i][j] == 152) { + DoLighting(i, j, 7, -1); + } + } + } + + DRLG_SetPC(); +} + +void LoadL3Dungeon(char *sFileName, int vx, int vy) +{ + int i, j, rw, rh; + BYTE *pLevelMap, *lm; + + InitL3Dungeon(); + dminx = 16; + dminy = 16; + dmaxx = 96; + dmaxy = 96; + DRLG_InitTrans(); + pLevelMap = DiabLoad(sFileName, NULL, 'LMPt'); + + lm = pLevelMap; + rw = *lm; + lm += 2; + rh = *lm; + lm += 2; + + for(j = 0; j < rh; j++) { + for(i = 0; i < rw; i++) { + if(*lm != 0) { + dungeon[i][j] = *lm; + } else { + dungeon[i][j] = 7; + } + lm += 2; + } + } + for(j = 0; j < 40; j++) { + for(i = 0; i < 40; i++) { + if(dungeon[i][j] == 0) { + dungeon[i][j] = 8; + } + } + } + + abyssx = 112; + DRLG_L3Pass3(); + DRLG_Init_Globals(); + ViewX = 31; + ViewY = 83; + SetMapMonsters(pLevelMap, 0, 0); + SetMapObjects(pLevelMap, 0, 0); + + for(j = 0; j < 112; j++) { + for(i = 0; i < 112; i++) { + if(dPiece[i][j] >= 56 && dPiece[i][j] <= 147) { + DoLighting(i, j, 7, -1); + } else if(dPiece[i][j] >= 154 && dPiece[i][j] <= 161) { + DoLighting(i, j, 7, -1); + } else if(dPiece[i][j] == 150) { + DoLighting(i, j, 7, -1); + } else if(dPiece[i][j] == 152) { + DoLighting(i, j, 7, -1); + } + } + } + + mem_free_dbg(pLevelMap); +} + +void LoadPreL3Dungeon(char *sFileName, int vx, int vy) +{ + int i, j, rw, rh; + BYTE *pLevelMap, *lm; + + InitL3Dungeon(); + DRLG_InitTrans(); + pLevelMap = DiabLoad(sFileName, NULL, 'LMPt'); + + lm = pLevelMap; + rw = *lm; + lm += 2; + rh = *lm; + lm += 2; + + for(j = 0; j < rh; j++) { + for(i = 0; i < rw; i++) { + if(*lm != 0) { + dungeon[i][j] = *lm; + } else { + dungeon[i][j] = 7; + } + lm += 2; + } + } + for(j = 0; j < 40; j++) { + for(i = 0; i < 40; i++) { + if(dungeon[i][j] == 0) { + dungeon[i][j] = 8; + } + } + } + + memcpy(pdungeon, dungeon, sizeof(pdungeon)); + mem_free_dbg(pLevelMap); +} diff --git a/2020_03_31/Source/drlg_l3.h b/2020_03_31/Source/drlg_l3.h new file mode 100644 index 00000000..7f454f1b --- /dev/null +++ b/2020_03_31/Source/drlg_l3.h @@ -0,0 +1,60 @@ +//HEADER_GOES_HERE +#ifndef __DRLG_L3_H__ +#define __DRLG_L3_H__ + +extern char lavapool; // weak +extern int abyssx; // weak +extern int lockoutcnt; // weak +extern BOOLEAN lockout[40][40]; + +void AddFenceDoors(); +void FenceDoorFix(); +BOOL DRLG_L3Anvil(); +void FixL3Warp(); +void FixL3HallofHeroes(); +void DRLG_L3LockRec(int x, int y); +BOOL DRLG_L3Lockout(); +void CreateL3Dungeon(unsigned int rseed, int entry); +void LoadL3Dungeon(char *sFileName, int vx, int vy); +void LoadPreL3Dungeon(char *sFileName, int vx, int vy); + +/* rdata */ +extern const unsigned char L3ConvTbl[16]; +extern const unsigned char L3UP[20]; +extern const unsigned char L3DOWN[20]; +extern const unsigned char L3HOLDWARP[20]; +extern const unsigned char L3TITE1[34]; +extern const unsigned char L3TITE2[34]; +extern const unsigned char L3TITE3[34]; +extern const unsigned char L3TITE6[42]; +extern const unsigned char L3TITE7[42]; +extern const unsigned char L3TITE8[20]; +extern const unsigned char L3TITE9[20]; +extern const unsigned char L3TITE10[20]; +extern const unsigned char L3TITE11[20]; +extern const unsigned char L3TITE12[6]; +extern const unsigned char L3TITE13[6]; +extern const unsigned char L3CREV1[6]; +extern const unsigned char L3CREV2[6]; +extern const unsigned char L3CREV3[6]; +extern const unsigned char L3CREV4[6]; +extern const unsigned char L3CREV5[6]; +extern const unsigned char L3CREV6[6]; +extern const unsigned char L3CREV7[6]; +extern const unsigned char L3CREV8[6]; +extern const unsigned char L3CREV9[6]; +extern const unsigned char L3CREV10[6]; +extern const unsigned char L3CREV11[6]; +extern const unsigned char L3ISLE1[14]; +extern const unsigned char L3ISLE2[14]; +extern const unsigned char L3ISLE3[14]; +extern const unsigned char L3ISLE4[14]; +extern const unsigned char L3ISLE5[10]; +extern const unsigned char L3XTRA1[4]; +extern const unsigned char L3XTRA2[4]; +extern const unsigned char L3XTRA3[4]; +extern const unsigned char L3XTRA4[4]; +extern const unsigned char L3XTRA5[4]; +extern const unsigned char L3ANVIL[244]; + +#endif /* __DRLG_L3_H__ */ diff --git a/2020_03_31/Source/drlg_l4.cpp b/2020_03_31/Source/drlg_l4.cpp new file mode 100644 index 00000000..4059537e --- /dev/null +++ b/2020_03_31/Source/drlg_l4.cpp @@ -0,0 +1,1987 @@ +#include "diablo.h" + +int diabquad1x; // weak +int diabquad1y; // weak +int diabquad3x; // idb +int diabquad3y; // idb +int diabquad2x; // idb +int diabquad2y; // idb +int diabquad4x; // idb +int diabquad4y; // idb +BOOL hallok[20]; +int l4holdx; // weak +int l4holdy; // weak +int SP4x1; // idb +int SP4x2; // weak +int SP4y1; // idb +int SP4y2; // weak +unsigned char L4dungeon[80][80]; +unsigned char dung[20][20]; +//int dword_52A4DC; // weak + +const unsigned char L4ConvTbl[16] = { 30u, 6u, 1u, 6u, 2u, 6u, 6u, 6u, 9u, 6u, 1u, 6u, 2u, 6u, 3u, 6u }; +const unsigned char L4USTAIRS[42] = +{ + 4u, + 5u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 0u, + 0u, + 0u, + 0u, + 36u, + 38u, + 35u, + 0u, + 37u, + 34u, + 33u, + 32u, + 0u, + 0u, + 31u, + 0u, + 0u, + 0u, + 0u, + 0u +}; +const unsigned char L4TWARP[42] = +{ + 4u, + 5u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 0u, + 0u, + 0u, + 0u, + 134u, + 136u, + 133u, + 0u, + 135u, + 132u, + 131u, + 130u, + 0u, + 0u, + 129u, + 0u, + 0u, + 0u, + 0u, + 0u +}; +const unsigned char L4DSTAIRS[52] = +{ + 5u, + 5u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 45u, + 41u, + 0u, + 0u, + 44u, + 43u, + 40u, + 0u, + 0u, + 46u, + 42u, + 39u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u +}; +const unsigned char L4PENTA[52] = +{ + 5u, + 5u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 98u, + 100u, + 103u, + 0u, + 0u, + 99u, + 102u, + 105u, + 0u, + 0u, + 101u, + 104u, + 106u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u +}; +const unsigned char L4PENTA2[52] = +{ + 5u, + 5u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 6u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u, + 107u, + 109u, + 112u, + 0u, + 0u, + 108u, + 111u, + 114u, + 0u, + 0u, + 110u, + 113u, + 115u, + 0u, + 0u, + 0u, + 0u, + 0u, + 0u +}; +const unsigned char L4BTYPES[140] = +{ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, + 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 2, 1, 2, 1, 2, 1, 1, 2, + 2, 0, 0, 0, 0, 0, 0, 15, 16, 9, + 12, 4, 5, 7, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +static void DRLG_L4Shadows() +{ + int x, y; + BOOL okflag; + + for(y = 1; y < 40; y++) { + for(x = 1; x < 40; x++) { + okflag = FALSE; + if(dungeon[x][y] == 3) { + okflag = TRUE; + } + if(dungeon[x][y] == 4) { + okflag = TRUE; + } + if(dungeon[x][y] == 8) { + okflag = TRUE; + } + if(dungeon[x][y] == 15) { + okflag = TRUE; + } + if(!okflag) { + continue; + } + if(dungeon[x - 1][y] == 6) { + dungeon[x - 1][y] = 47; + } + if(dungeon[x - 1][y - 1] == 6) { + dungeon[x - 1][y - 1] = 48; + } + } + } +} + +static void InitL4Dungeon() +{ + int i, j; + + memset(dung, 0, sizeof(dung)); + memset(L4dungeon, 0, sizeof(L4dungeon)); + + for(j = 0; j < 40; j++) { + for(i = 0; i < 40; i++) { + dungeon[i][j] = 30; + dflags[i][j] = 0; + } + } +} + +void DRLG_LoadL4SP() +{ + setloadflag_2 = 0; + + if(QuestStatus(Q_WARLORD)) { + pSetPiece_2 = (char *)DiabLoad("Levels\\L4Data\\Warlord.DUN", NULL, 'STPC'); + setloadflag_2 = 1; + } + if(currlevel == 15 && gbMaxPlayers != 1) { + pSetPiece_2 = (char *)DiabLoad("Levels\\L4Data\\Vile1.DUN", NULL, 'STPC'); + setloadflag_2 = 1; + } +} + +void DRLG_FreeL4SP() +{ + MemFreeDbg(pSetPiece_2); +} + +void DRLG_L4SetSPRoom(int rx1, int ry1) +{ + int rw, rh, i, j; + unsigned char *sp; + + rw = (unsigned char)pSetPiece_2[0]; + rh = (unsigned char)pSetPiece_2[2]; + + setpc_x = rx1; + setpc_y = ry1; + setpc_w = rw; + setpc_h = rh; + + sp = (unsigned char *)&pSetPiece_2[4]; + + for(j = 0; j < rh; j++) { + for(i = 0; i < rw; i++) { + if(*sp != 0) { + dungeon[i + rx1][j + ry1] = *sp; + dflags[i + rx1][j + ry1] |= 0x80; + } else { + dungeon[i + rx1][j + ry1] = 6; + } + sp += 2; + } + } +} + +static void L4makeDmt() +{ + int i, j, val, dmtx, dmty; + + for(j = 0, dmty = 1; dmty <= 77; j++, dmty += 2) { + for(i = 0, dmtx = 1; dmtx <= 77; i++, dmtx += 2) { + val = L4dungeon[dmtx+1][dmty+1]; + val = 2 * val + L4dungeon[dmtx][dmty+1]; + val = 2 * val + L4dungeon[dmtx+1][dmty]; + val = 2 * val + L4dungeon[dmtx][dmty]; + dungeon[i][j] = L4ConvTbl[val]; + } + } +} + +static int L4HWallOk(int i, int j) +{ + int x; + BOOL wallok; + + for(x = 1; dungeon[i + x][j] == 6; x++) { + if(dflags[i + x][j] != 0) { + break; + } + if(dungeon[i + x][j - 1] != 6) { + break; + } + if(dungeon[i + x][j + 1] != 6) { + break; + } + } + + wallok = FALSE; + + if(dungeon[i + x][j] == 10) { + wallok = TRUE; + } + if(dungeon[i + x][j] == 12) { + wallok = TRUE; + } + if(dungeon[i + x][j] == 13) { + wallok = TRUE; + } + if(dungeon[i + x][j] == 15) { + wallok = TRUE; + } + if(dungeon[i + x][j] == 16) { + wallok = TRUE; + } + if(dungeon[i + x][j] == 21) { + wallok = TRUE; + } + if(dungeon[i + x][j] == 22) { + wallok = TRUE; + } + if(x <= 3) { + wallok = FALSE; + } + + if(wallok) { + return x; + } else { + return -1; + } +} + +static int L4VWallOk(int i, int j) +{ + int y; + BOOL wallok; + + for(y = 1; dungeon[i][j + y] == 6; y++) { + if(dflags[i][j + y] != 0) { + break; + } + if(dungeon[i - 1][j + y] != 6) { + break; + } + if(dungeon[i + 1][j + y] != 6) { + break; + } + } + + wallok = FALSE; + + if(dungeon[i][j + y] == 8) { + wallok = TRUE; + } + if(dungeon[i][j + y] == 9) { + wallok = TRUE; + } + if(dungeon[i][j + y] == 11) { + wallok = TRUE; + } + if(dungeon[i][j + y] == 14) { + wallok = TRUE; + } + if(dungeon[i][j + y] == 15) { + wallok = TRUE; + } + if(dungeon[i][j + y] == 16) { + wallok = TRUE; + } + if(dungeon[i][j + y] == 21) { + wallok = TRUE; + } + if(dungeon[i][j + y] == 23) { + wallok = TRUE; + } + if(y <= 3) { + wallok = FALSE; + } + + if(wallok) { + return y; + } else { + return -1; + } +} + +static void L4HorizWall(int i, int j, int dx) +{ + int xx; + + if(dungeon[i][j] == 13) { + dungeon[i][j] = 17; + } + if(dungeon[i][j] == 16) { + dungeon[i][j] = 11; + } + if(dungeon[i][j] == 12) { + dungeon[i][j] = 14; + } + + for(xx = 1; xx < dx; xx++) { + dungeon[i + xx][j] = 2; + } + + if(dungeon[i + dx][j] == 15) { + dungeon[i + dx][j] = 14; + } + if(dungeon[i + dx][j] == 10) { + dungeon[i + dx][j] = 17; + } + if(dungeon[i + dx][j] == 21) { + dungeon[i + dx][j] = 23; + } + if(dungeon[i + dx][j] == 22) { + dungeon[i + dx][j] = 29; + } + + xx = random(0, dx - 3) + 1; + dungeon[i + xx][j] = 57; + dungeon[i + xx + 2][j] = 56; + dungeon[i + xx + 1][j] = 60; + + if(dungeon[i + xx][j - 1] == 6) { + dungeon[i + xx][j - 1] = 58; + } + if(dungeon[i + xx + 1][j - 1] == 6) { + dungeon[i + xx + 1][j - 1] = 59; + } +} + +static void L4VertWall(int i, int j, int dy) +{ + int yy; + + if(dungeon[i][j] == 14) { + dungeon[i][j] = 17; + } + if(dungeon[i][j] == 8) { + dungeon[i][j] = 9; + } + if(dungeon[i][j] == 15) { + dungeon[i][j] = 10; + } + + for(yy = 1; yy < dy; yy++) { + dungeon[i][j + yy] = 1; + } + + if(dungeon[i][j + dy] == 11) { + dungeon[i][j + dy] = 17; + } + if(dungeon[i][j + dy] == 9) { + dungeon[i][j + dy] = 10; + } + if(dungeon[i][j + dy] == 16) { + dungeon[i][j + dy] = 13; + } + if(dungeon[i][j + dy] == 21) { + dungeon[i][j + dy] = 22; + } + if(dungeon[i][j + dy] == 23) { + dungeon[i][j + dy] = 29; + } + + yy = random(0, dy - 3) + 1; + dungeon[i][j + yy] = 53; + dungeon[i][j + yy + 2] = 52; + dungeon[i][j + yy + 1] = 6; + + if(dungeon[i - 1][j + yy] == 6) { + dungeon[i - 1][j + yy] = 54; + } + if(dungeon[i - 1][j + yy - 1] == 6) { + dungeon[i - 1][j + yy - 1] = 55; + } +} + +static void L4AddWall() +{ + int i, j, x, y; + + for(j = 0; j < 40; j++) { + for(i = 0; i < 40; i++) { + if(dflags[i][j] != 0) { + continue; + } + if(dungeon[i][j] == 10 && random(0, 100) < 100) { + x = L4HWallOk(i, j); + if(x != -1) { + L4HorizWall(i, j, x); + } + } + if(dungeon[i][j] == 12 && random(0, 100) < 100) { + x = L4HWallOk(i, j); + if(x != -1) { + L4HorizWall(i, j, x); + } + } + if(dungeon[i][j] == 13 && random(0, 100) < 100) { + x = L4HWallOk(i, j); + if(x != -1) { + L4HorizWall(i, j, x); + } + } + if(dungeon[i][j] == 15 && random(0, 100) < 100) { + x = L4HWallOk(i, j); + if(x != -1) { + L4HorizWall(i, j, x); + } + } + if(dungeon[i][j] == 16 && random(0, 100) < 100) { + x = L4HWallOk(i, j); + if(x != -1) { + L4HorizWall(i, j, x); + } + } + if(dungeon[i][j] == 21 && random(0, 100) < 100) { + x = L4HWallOk(i, j); + if(x != -1) { + L4HorizWall(i, j, x); + } + } + if(dungeon[i][j] == 22 && random(0, 100) < 100) { + x = L4HWallOk(i, j); + if(x != -1) { + L4HorizWall(i, j, x); + } + } + if(dungeon[i][j] == 8 && random(0, 100) < 100) { + y = L4VWallOk(i, j); + if(y != -1) { + L4VertWall(i, j, y); + } + } + if(dungeon[i][j] == 9 && random(0, 100) < 100) { + y = L4VWallOk(i, j); + if(y != -1) { + L4VertWall(i, j, y); + } + } + if(dungeon[i][j] == 11 && random(0, 100) < 100) { + y = L4VWallOk(i, j); + if(y != -1) { + L4VertWall(i, j, y); + } + } + if(dungeon[i][j] == 14 && random(0, 100) < 100) { + y = L4VWallOk(i, j); + if(y != -1) { + L4VertWall(i, j, y); + } + } + if(dungeon[i][j] == 15 && random(0, 100) < 100) { + y = L4VWallOk(i, j); + if(y != -1) { + L4VertWall(i, j, y); + } + } + if(dungeon[i][j] == 16 && random(0, 100) < 100) { + y = L4VWallOk(i, j); + if(y != -1) { + L4VertWall(i, j, y); + } + } + if(dungeon[i][j] == 21 && random(0, 100) < 100) { + y = L4VWallOk(i, j); + if(y != -1) { + L4VertWall(i, j, y); + } + } + if(dungeon[i][j] == 23 && random(0, 100) < 100) { + y = L4VWallOk(i, j); + if(y != -1) { + L4VertWall(i, j, y); + } + } + } + } +} + +static void L4tileFix() +{ + int i, j; + + for(j = 0; j < DMAXY; j++) { + for(i = 0; i < DMAXX; i++) { + if(dungeon[i][j] == 2 && dungeon[i + 1][j] == 6) + dungeon[i + 1][j] = 5; + if(dungeon[i][j] == 2 && dungeon[i + 1][j] == 1) + dungeon[i + 1][j] = 13; + if(dungeon[i][j] == 1 && dungeon[i][j + 1] == 2) + dungeon[i][j + 1] = 14; + } + } + for(j = 0; j < DMAXY; j++) { + for(i = 0; i < DMAXX; i++) { + if(dungeon[i][j] == 2 && dungeon[i + 1][j] == 6) + dungeon[i + 1][j] = 2; + if(dungeon[i][j] == 2 && dungeon[i + 1][j] == 9) + dungeon[i + 1][j] = 11; + if(dungeon[i][j] == 9 && dungeon[i + 1][j] == 6) + dungeon[i + 1][j] = 12; + if(dungeon[i][j] == 14 && dungeon[i + 1][j] == 1) + dungeon[i + 1][j] = 13; + if(dungeon[i][j] == 6 && dungeon[i + 1][j] == 14) + dungeon[i + 1][j] = 15; + if(dungeon[i][j] == 6 && dungeon[i][j + 1] == 13) + dungeon[i][j + 1] = 16; + if(dungeon[i][j] == 1 && dungeon[i][j + 1] == 9) + dungeon[i][j + 1] = 10; + if(dungeon[i][j] == 6 && dungeon[i][j - 1] == 1) + dungeon[i][j - 1] = 1; + } + } + for(j = 0; j < DMAXY; j++) { + for(i = 0; i < DMAXX; i++) { + if(dungeon[i][j] == 13 && dungeon[i][j + 1] == 30) + dungeon[i][j + 1] = 27; + if(dungeon[i][j] == 27 && dungeon[i + 1][j] == 30) + dungeon[i + 1][j] = 19; + if(dungeon[i][j] == 1 && dungeon[i][j + 1] == 30) + dungeon[i][j + 1] = 27; + if(dungeon[i][j] == 27 && dungeon[i + 1][j] == 1) + dungeon[i + 1][j] = 16; + if(dungeon[i][j] == 19 && dungeon[i + 1][j] == 27) + dungeon[i + 1][j] = 26; + if(dungeon[i][j] == 27 && dungeon[i + 1][j] == 30) + dungeon[i + 1][j] = 19; + if(dungeon[i][j] == 2 && dungeon[i + 1][j] == 15) + dungeon[i + 1][j] = 14; + if(dungeon[i][j] == 14 && dungeon[i + 1][j] == 15) + dungeon[i + 1][j] = 14; + if(dungeon[i][j] == 22 && dungeon[i + 1][j] == 1) + dungeon[i + 1][j] = 16; + if(dungeon[i][j] == 27 && dungeon[i + 1][j] == 1) + dungeon[i + 1][j] = 16; + if(dungeon[i][j] == 6 && dungeon[i + 1][j] == 27 && dungeon[i + 1][j + 1] != 0) /* check */ + dungeon[i + 1][j] = 22; + if(dungeon[i][j] == 22 && dungeon[i + 1][j] == 30) + dungeon[i + 1][j] = 19; + if(dungeon[i][j] == 21 && dungeon[i + 1][j] == 1 && dungeon[i + 1][j - 1] == 1) + dungeon[i + 1][j] = 13; + if(dungeon[i][j] == 14 && dungeon[i + 1][j] == 30 && dungeon[i][j + 1] == 6) + dungeon[i + 1][j] = 28; + if(dungeon[i][j] == 16 && dungeon[i + 1][j] == 6 && dungeon[i][j + 1] == 30) + dungeon[i][j + 1] = 27; + if(dungeon[i][j] == 16 && dungeon[i][j + 1] == 30 && dungeon[i + 1][j + 1] == 30) + dungeon[i][j + 1] = 27; + if(dungeon[i][j] == 6 && dungeon[i + 1][j] == 30 && dungeon[i + 1][j - 1] == 6) + dungeon[i + 1][j] = 21; + if(dungeon[i][j] == 2 && dungeon[i + 1][j] == 27 && dungeon[i + 1][j + 1] == 9) + dungeon[i + 1][j] = 29; + if(dungeon[i][j] == 9 && dungeon[i + 1][j] == 15) + dungeon[i + 1][j] = 14; + if(dungeon[i][j] == 15 && dungeon[i + 1][j] == 27 && dungeon[i + 1][j + 1] == 2) + dungeon[i + 1][j] = 29; + if(dungeon[i][j] == 19 && dungeon[i + 1][j] == 18) + dungeon[i + 1][j] = 24; + if(dungeon[i][j] == 9 && dungeon[i + 1][j] == 15) + dungeon[i + 1][j] = 14; + if(dungeon[i][j] == 19 && dungeon[i + 1][j] == 19 && dungeon[i + 1][j - 1] == 30) + dungeon[i + 1][j] = 24; + if(dungeon[i][j] == 24 && dungeon[i][j - 1] == 30 && dungeon[i][j - 2] == 6) + dungeon[i][j - 1] = 21; + if(dungeon[i][j] == 2 && dungeon[i + 1][j] == 30) + dungeon[i + 1][j] = 28; + if(dungeon[i][j] == 15 && dungeon[i + 1][j] == 30) + dungeon[i + 1][j] = 28; + if(dungeon[i][j] == 28 && dungeon[i][j + 1] == 30) + dungeon[i][j + 1] = 18; + if(dungeon[i][j] == 28 && dungeon[i][j + 1] == 2) + dungeon[i][j + 1] = 15; + if(dungeon[i][j] == 19 && dungeon[i + 2][j] == 2 && dungeon[i + 1][j - 1] == 18 && dungeon[i + 1][j + 1] == 1) + dungeon[i + 1][j] = 17; + if(dungeon[i][j] == 19 && dungeon[i + 2][j] == 2 && dungeon[i + 1][j - 1] == 22 && dungeon[i + 1][j + 1] == 1) + dungeon[i + 1][j] = 17; + if(dungeon[i][j] == 19 && dungeon[i + 2][j] == 2 && dungeon[i + 1][j - 1] == 18 && dungeon[i + 1][j + 1] == 13) + dungeon[i + 1][j] = 17; + if(dungeon[i][j] == 21 && dungeon[i + 2][j] == 2 && dungeon[i + 1][j - 1] == 18 && dungeon[i + 1][j + 1] == 1) + dungeon[i + 1][j] = 17; + if(dungeon[i][j] == 21 && dungeon[i + 1][j + 1] == 1 && dungeon[i + 1][j - 1] == 22 && dungeon[i + 2][j] == 3) + dungeon[i + 1][j] = 17; + if(dungeon[i][j] == 15 && dungeon[i + 1][j] == 28 && dungeon[i + 2][j] == 30 && dungeon[i + 1][j - 1] == 6) + dungeon[i + 1][j] = 23; + if(dungeon[i][j] == 14 && dungeon[i + 1][j] == 28 && dungeon[i + 2][j] == 1) + dungeon[i + 1][j] = 23; + if(dungeon[i][j] == 15 && dungeon[i + 1][j] == 27 && dungeon[i + 1][j + 1] == 30) + dungeon[i + 1][j] = 29; + if(dungeon[i][j] == 28 && dungeon[i][j + 1] == 9) + dungeon[i][j + 1] = 15; + if(dungeon[i][j] == 21 && dungeon[i + 1][j - 1] == 21) + dungeon[i + 1][j] = 24; + if(dungeon[i][j] == 2 && dungeon[i + 1][j] == 27 && dungeon[i + 1][j + 1] == 30) + dungeon[i + 1][j] = 29; + if(dungeon[i][j] == 2 && dungeon[i + 1][j] == 18) + dungeon[i + 1][j] = 25; + if(dungeon[i][j] == 21 && dungeon[i + 1][j] == 9 && dungeon[i + 2][j] == 2) + dungeon[i + 1][j] = 11; + if(dungeon[i][j] == 19 && dungeon[i + 1][j] == 10) + dungeon[i + 1][j] = 17; + if(dungeon[i][j] == 15 && dungeon[i][j + 1] == 3) + dungeon[i][j + 1] = 4; + if(dungeon[i][j] == 22 && dungeon[i][j + 1] == 9) + dungeon[i][j + 1] = 15; + if(dungeon[i][j] == 18 && dungeon[i][j + 1] == 30) + dungeon[i][j + 1] = 18; + if(dungeon[i][j] == 24 && dungeon[i - 1][j] == 30) + dungeon[i - 1][j] = 19; + if(dungeon[i][j] == 21 && dungeon[i][j + 1] == 2) + dungeon[i][j + 1] = 15; + if(dungeon[i][j] == 21 && dungeon[i][j + 1] == 9) + dungeon[i][j + 1] = 10; + if(dungeon[i][j] == 22 && dungeon[i][j + 1] == 30) + dungeon[i][j + 1] = 18; + if(dungeon[i][j] == 21 && dungeon[i][j + 1] == 30) + dungeon[i][j + 1] = 18; + if(dungeon[i][j] == 16 && dungeon[i][j + 1] == 2) + dungeon[i][j + 1] = 15; + if(dungeon[i][j] == 13 && dungeon[i][j + 1] == 2) + dungeon[i][j + 1] = 15; + if(dungeon[i][j] == 22 && dungeon[i][j + 1] == 2) + dungeon[i][j + 1] = 15; + if(dungeon[i][j] == 21 && dungeon[i + 1][j] == 18 && dungeon[i + 2][j] == 30) + dungeon[i + 1][j] = 24; + if(dungeon[i][j] == 21 && dungeon[i + 1][j] == 9 && dungeon[i + 1][j + 1] == 1) + dungeon[i + 1][j] = 16; + if(dungeon[i][j] == 2 && dungeon[i + 1][j] == 27 && dungeon[i + 1][j + 1] == 2) + dungeon[i + 1][j] = 29; + if(dungeon[i][j] == 23 && dungeon[i][j + 1] == 2) + dungeon[i][j + 1] = 15; + if(dungeon[i][j] == 23 && dungeon[i][j + 1] == 9) + dungeon[i][j + 1] = 15; + if(dungeon[i][j] == 25 && dungeon[i][j + 1] == 2) + dungeon[i][j + 1] = 15; + if(dungeon[i][j] == 22 && dungeon[i + 1][j] == 9) + dungeon[i + 1][j] = 11; + if(dungeon[i][j] == 23 && dungeon[i + 1][j] == 9) + dungeon[i + 1][j] = 11; + if(dungeon[i][j] == 15 && dungeon[i + 1][j] == 1) + dungeon[i + 1][j] = 16; + if(dungeon[i][j] == 11 && dungeon[i + 1][j] == 15) + dungeon[i + 1][j] = 14; + if(dungeon[i][j] == 23 && dungeon[i + 1][j] == 1) + dungeon[i + 1][j] = 16; + if(dungeon[i][j] == 21 && dungeon[i + 1][j] == 27) + dungeon[i + 1][j] = 26; + if(dungeon[i][j] == 21 && dungeon[i + 1][j] == 18) + dungeon[i + 1][j] = 24; + if(dungeon[i][j] == 26 && dungeon[i + 1][j] == 1) + dungeon[i + 1][j] = 16; + if(dungeon[i][j] == 29 && dungeon[i + 1][j] == 1) + dungeon[i + 1][j] = 16; + if(dungeon[i][j] == 29 && dungeon[i][j + 1] == 2) + dungeon[i][j + 1] = 15; + if(dungeon[i][j] == 1 && dungeon[i][j - 1] == 15) + dungeon[i][j - 1] = 10; + if(dungeon[i][j] == 18 && dungeon[i][j + 1] == 2) + dungeon[i][j + 1] = 15; + if(dungeon[i][j] == 23 && dungeon[i][j + 1] == 30) + dungeon[i][j + 1] = 18; + if(dungeon[i][j] == 18 && dungeon[i][j + 1] == 9) + dungeon[i][j + 1] = 10; + if(dungeon[i][j] == 14 && dungeon[i + 1][j] == 30 && dungeon[i + 1][j + 1] == 30) + dungeon[i + 1][j] = 23; + if(dungeon[i][j] == 2 && dungeon[i + 1][j] == 28 && dungeon[i + 1][j - 1] == 6) + dungeon[i + 1][j] = 23; + if(dungeon[i][j] == 23 && dungeon[i + 1][j] == 18 && dungeon[i][j - 1] == 6) + dungeon[i + 1][j] = 24; + if(dungeon[i][j] == 14 && dungeon[i + 1][j] == 23 && dungeon[i + 2][j] == 30) + dungeon[i + 1][j] = 28; + if(dungeon[i][j] == 14 && dungeon[i + 1][j] == 28 && dungeon[i + 2][j] == 30 && dungeon[i + 1][j - 1] == 6) + dungeon[i + 1][j] = 23; + if(dungeon[i][j] == 23 && dungeon[i + 1][j] == 30) + dungeon[i + 1][j] = 19; + if(dungeon[i][j] == 29 && dungeon[i + 1][j] == 30) + dungeon[i + 1][j] = 19; + if(dungeon[i][j] == 29 && dungeon[i][j + 1] == 30) + dungeon[i][j + 1] = 18; + if(dungeon[i][j] == 19 && dungeon[i + 1][j] == 30) + dungeon[i + 1][j] = 19; + if(dungeon[i][j] == 21 && dungeon[i + 1][j] == 30) + dungeon[i + 1][j] = 19; + if(dungeon[i][j] == 26 && dungeon[i + 1][j] == 30) + dungeon[i + 1][j] = 19; + if(dungeon[i][j] == 16 && dungeon[i][j + 1] == 30) + dungeon[i][j + 1] = 18; + if(dungeon[i][j] == 13 && dungeon[i][j + 1] == 9) + dungeon[i][j + 1] = 10; + if(dungeon[i][j] == 25 && dungeon[i][j + 1] == 30) + dungeon[i][j + 1] = 18; + if(dungeon[i][j] == 18 && dungeon[i][j + 1] == 2) + dungeon[i][j + 1] = 15; + if(dungeon[i][j] == 11 && dungeon[i + 1][j] == 3) + dungeon[i + 1][j] = 5; + if(dungeon[i][j] == 19 && dungeon[i + 1][j] == 9) + dungeon[i + 1][j] = 11; + if(dungeon[i][j] == 19 && dungeon[i + 1][j] == 1) + dungeon[i + 1][j] = 13; + if(dungeon[i][j] == 19 && dungeon[i + 1][j] == 13 && dungeon[i + 1][j - 1] == 6) + dungeon[i + 1][j] = 16; + } + } + for(j = 0; j < DMAXY; j++) { + for(i = 0; i < DMAXX; i++) { + if(dungeon[i][j] == 21 && dungeon[i][j + 1] == 24 && dungeon[i][j + 2] == 1) + dungeon[i][j + 1] = 17; + if(dungeon[i][j] == 15 && dungeon[i + 1][j + 1] == 9 && dungeon[i + 1][j - 1] == 1 && dungeon[i + 2][j] == 16) + dungeon[i + 1][j] = 29; + if(dungeon[i][j] == 2 && dungeon[i - 1][j] == 6) + dungeon[i - 1][j] = 8; + if(dungeon[i][j] == 1 && dungeon[i][j - 1] == 6) + dungeon[i][j - 1] = 7; + if(dungeon[i][j] == 6 && dungeon[i + 1][j] == 15 && dungeon[i + 1][j + 1] == 4) + dungeon[i + 1][j] = 10; + if(dungeon[i][j] == 1 && dungeon[i][j + 1] == 3) + dungeon[i][j + 1] = 4; + if(dungeon[i][j] == 1 && dungeon[i][j + 1] == 6) + dungeon[i][j + 1] = 4; + if(dungeon[i][j] == 9 && dungeon[i][j + 1] == 3) + dungeon[i][j + 1] = 4; + if(dungeon[i][j] == 10 && dungeon[i][j + 1] == 3) + dungeon[i][j + 1] = 4; + if(dungeon[i][j] == 13 && dungeon[i][j + 1] == 3) + dungeon[i][j + 1] = 4; + if(dungeon[i][j] == 1 && dungeon[i][j + 1] == 5) + dungeon[i][j + 1] = 12; + if(dungeon[i][j] == 1 && dungeon[i][j + 1] == 16) + dungeon[i][j + 1] = 13; + if(dungeon[i][j] == 6 && dungeon[i][j + 1] == 13) + dungeon[i][j + 1] = 16; + if(dungeon[i][j] == 25 && dungeon[i][j + 1] == 9) + dungeon[i][j + 1] = 10; + if(dungeon[i][j] == 13 && dungeon[i][j + 1] == 5) + dungeon[i][j + 1] = 12; + if(dungeon[i][j] == 28 && dungeon[i][j - 1] == 6 && dungeon[i + 1][j] == 1) + dungeon[i + 1][j] = 23; + if(dungeon[i][j] == 19 && dungeon[i + 1][j] == 10) + dungeon[i + 1][j] = 17; + if(dungeon[i][j] == 21 && dungeon[i + 1][j] == 9) + dungeon[i + 1][j] = 11; + if(dungeon[i][j] == 11 && dungeon[i + 1][j] == 3) + dungeon[i + 1][j] = 5; + if(dungeon[i][j] == 10 && dungeon[i + 1][j] == 4) + dungeon[i + 1][j] = 12; + if(dungeon[i][j] == 14 && dungeon[i + 1][j] == 4) + dungeon[i + 1][j] = 12; + if(dungeon[i][j] == 27 && dungeon[i + 1][j] == 9) + dungeon[i + 1][j] = 11; + if(dungeon[i][j] == 15 && dungeon[i + 1][j] == 4) + dungeon[i + 1][j] = 12; + if(dungeon[i][j] == 21 && dungeon[i + 1][j] == 1) + dungeon[i + 1][j] = 16; + if(dungeon[i][j] == 11 && dungeon[i + 1][j] == 4) + dungeon[i + 1][j] = 12; + if(dungeon[i][j] == 2 && dungeon[i + 1][j] == 3) + dungeon[i + 1][j] = 5; + if(dungeon[i][j] == 9 && dungeon[i + 1][j] == 3) + dungeon[i + 1][j] = 5; + if(dungeon[i][j] == 14 && dungeon[i + 1][j] == 3) + dungeon[i + 1][j] = 5; + if(dungeon[i][j] == 15 && dungeon[i + 1][j] == 3) + dungeon[i + 1][j] = 5; + if(dungeon[i][j] == 2 && dungeon[i + 1][j] == 5 && dungeon[i + 1][j - 1] == 16) + dungeon[i + 1][j] = 12; + if(dungeon[i][j] == 2 && dungeon[i + 1][j] == 4) + dungeon[i + 1][j] = 12; + if(dungeon[i][j] == 9 && dungeon[i + 1][j] == 4) + dungeon[i + 1][j] = 12; + if(dungeon[i][j] == 1 && dungeon[i][j - 1] == 8) + dungeon[i][j - 1] = 9; + if(dungeon[i][j] == 28 && dungeon[i + 1][j] == 23 && dungeon[i + 1][j + 1] == 3) + dungeon[i + 1][j] = 16; + } + } + for(j = 0; j < DMAXY; j++) { + for(i = 0; i < DMAXX; i++) { + if(dungeon[i][j] == 21 && dungeon[i + 1][j] == 10) + dungeon[i + 1][j] = 17; + if(dungeon[i][j] == 17 && dungeon[i + 1][j] == 4) + dungeon[i + 1][j] = 12; + if(dungeon[i][j] == 10 && dungeon[i + 1][j] == 4) + dungeon[i + 1][j] = 12; + if(dungeon[i][j] == 17 && dungeon[i][j + 1] == 5) + dungeon[i][j + 1] = 12; + if(dungeon[i][j] == 29 && dungeon[i][j + 1] == 9) + dungeon[i][j + 1] = 10; + if(dungeon[i][j] == 13 && dungeon[i][j + 1] == 5) + dungeon[i][j + 1] = 12; + if(dungeon[i][j] == 9 && dungeon[i][j + 1] == 16) + dungeon[i][j + 1] = 13; + if(dungeon[i][j] == 10 && dungeon[i][j + 1] == 16) + dungeon[i][j + 1] = 13; + if(dungeon[i][j] == 16 && dungeon[i][j + 1] == 3) + dungeon[i][j + 1] = 4; + if(dungeon[i][j] == 11 && dungeon[i][j + 1] == 5) + dungeon[i][j + 1] = 12; + if(dungeon[i][j] == 10 && dungeon[i + 1][j] == 3 && dungeon[i + 1][j - 1] == 16) + dungeon[i + 1][j] = 12; + if(dungeon[i][j] == 16 && dungeon[i][j + 1] == 5) + dungeon[i][j + 1] = 12; + if(dungeon[i][j] == 1 && dungeon[i][j + 1] == 6) + dungeon[i][j + 1] = 4; + if(dungeon[i][j] == 21 && dungeon[i + 1][j] == 13 && dungeon[i][j + 1] == 10) + dungeon[i + 1][j + 1] = 12; + if(dungeon[i][j] == 15 && dungeon[i + 1][j] == 10) + dungeon[i + 1][j] = 17; + if(dungeon[i][j] == 22 && dungeon[i][j + 1] == 11) + dungeon[i][j + 1] = 17; + if(dungeon[i][j] == 15 && dungeon[i + 1][j] == 28 && dungeon[i + 2][j] == 16) + dungeon[i + 1][j] = 23; + if(dungeon[i][j] == 28 && dungeon[i + 1][j] == 23 && dungeon[i + 1][j + 1] == 1 && dungeon[i + 2][j] == 6) + dungeon[i + 1][j] = 16; + } + } + for(j = 0; j < DMAXY; j++) { + for(i = 0; i < DMAXX; i++) { + if(dungeon[i][j] == 15 && dungeon[i + 1][j] == 28 && dungeon[i + 2][j] == 16) + dungeon[i + 1][j] = 23; + if(dungeon[i][j] == 21 && dungeon[i + 1][j - 1] == 21 && dungeon[i + 1][j + 1] == 13 && dungeon[i + 2][j] == 2) + dungeon[i + 1][j] = 17; + if(dungeon[i][j] == 19 && dungeon[i + 1][j] == 15 && dungeon[i + 1][j + 1] == 12) + dungeon[i + 1][j] = 17; + } + } +} + +static void DRLG_L4Subs() +{ + int x, y, i, rv; + unsigned char c; + + for(y = 0; y < 40; y++) { + for(x = 0; x < 40; x++) { + if(random(0, 3) == 0) { + c = L4BTYPES[dungeon[x][y]]; + if(c != 0 && dflags[x][y] == 0) { + rv = random(0, 16); + i = -1; + while(rv >= 0) { + i++; + if(i == sizeof(L4BTYPES)) { + i = 0; + } + if(c == L4BTYPES[i]) { + rv--; + } + } + dungeon[x][y] = i; + } + } + } + } + for(y = 0; y < 40; y++) { + for(x = 0; x < 40; x++) { + if(random(0, 10) == 0) { + if(L4BTYPES[dungeon[x][y]] == 6 && dflags[x][y] == 0) { + dungeon[x][y] = random(0, 3) + 95; + } + } + } + } +} + +static void L4makeDungeon() +{ + int i, j, k, l; + + for(j = 0; j < 20; j++) { + for(i = 0; i < 20; i++) { + k = i << 1; + l = j << 1; + L4dungeon[k][l] = dung[i][j]; + L4dungeon[k][l + 1] = dung[i][j]; + L4dungeon[k + 1][l] = dung[i][j]; + L4dungeon[k + 1][l + 1] = dung[i][j]; + } + } + for(j = 0; j < 20; j++) { + for(i = 0; i < 20; i++) { + k = i << 1; + l = j << 1; + L4dungeon[k][l + 40] = dung[i][19 - j]; + L4dungeon[k][l + 41] = dung[i][19 - j]; + L4dungeon[k + 1][l + 40] = dung[i][19 - j]; + L4dungeon[k + 1][l + 41] = dung[i][19 - j]; + } + } + for(j = 0; j < 20; j++) { + for(i = 0; i < 20; i++) { + k = i << 1; + l = j << 1; + L4dungeon[k + 40][l] = dung[19 - i][j]; + L4dungeon[k + 40][l + 1] = dung[19 - i][j]; + L4dungeon[k + 41][l] = dung[19 - i][j]; + L4dungeon[k + 41][l + 1] = dung[19 - i][j]; + } + } + for(j = 0; j < 20; j++) { + for(i = 0; i < 20; i++) { + k = i << 1; + l = j << 1; + L4dungeon[k + 40][l + 40] = dung[19 - i][19 - j]; + L4dungeon[k + 40][l + 41] = dung[19 - i][19 - j]; + L4dungeon[k + 41][l + 40] = dung[19 - i][19 - j]; + L4dungeon[k + 41][l + 41] = dung[19 - i][19 - j]; + } + } +} + +static void uShape() +{ + int j, i, rv; + + for(j = 19; j >= 0; j--) { + for(i = 19; i >= 0; i--) { + if(dung[i][j] != 1) { + hallok[j] = FALSE; + } + if(dung[i][j] == 1) { + if(dung[i][j + 1] == 1 && dung[i + 1][j + 1] == 0) { + hallok[j] = TRUE; + } else { + hallok[j] = FALSE; + } + i = 0; + } + } + } + + rv = random(0, 19) + 1; + do { + if(hallok[rv]) { + for(i = 19; i >= 0; i--) { + if(dung[i][rv] == 1) { + i = -1; + rv = 0; + } else { + dung[i][rv] = 1; + dung[i][rv + 1] = 1; + } + } + } else { + rv++; + if(rv == 20) { + rv = 1; + } + } + } while(rv != 0); + + for(i = 19; i >= 0; i--) { + for(j = 19; j >= 0; j--) { + if(dung[i][j] != 1) { + hallok[i] = FALSE; + } + if(dung[i][j] == 1) { + if(dung[i + 1][j] == 1 && dung[i + 1][j + 1] == 0) { + hallok[i] = TRUE; + } else { + hallok[i] = FALSE; + } + j = 0; + } + } + } + + rv = random(0, 19) + 1; + do { + if(hallok[rv]) { + for(j = 19; j >= 0; j--) { + if(dung[rv][j] == 1) { + j = -1; + rv = 0; + } else { + dung[rv][j] = 1; + dung[rv + 1][j] = 1; + } + } + } else { + rv++; + if(rv == 20) { + rv = 1; + } + } + } while(rv != 0); +} + +static long GetArea() +{ + int i, j; + long rv; + + rv = 0; + + for(j = 0; j < 20; j++) { + for(i = 0; i < 20; i++) { + if(dung[i][j] == 1) { + rv++; + } + } + } + + return rv; +} + +static void L4drawRoom(int x, int y, int width, int height) +{ + int i, j; + + for(j = 0; j < height; j++) { + for(i = 0; i < width; i++) { + dung[i + x][j + y] = 1; + } + } +} + +static BOOL L4checkRoom(int x, int y, int width, int height) +{ + int i, j; + + if(x <= 0 || y <= 0) { + return FALSE; + } + + for(j = 0; j < height; j++) { + for(i = 0; i < width; i++) { + if(i + x < 0 || i + x >= 20 || j + y < 0 || j + y >= 20) { + return FALSE; + } + if(dung[i + x][j + y] != 0) { + return FALSE; + } + } + } + + return TRUE; +} + +static void L4roomGen(int x, int y, int w, int h, int dir) +{ + int num; + BOOL ran, ran2; + int width, height, rx, ry, ry2; + int cw, ch, cx1, cy1, cx2; + + int dirProb = random(0, 4); + + switch(dir == 1 ? dirProb != 0 : dirProb == 0) { + case FALSE: + num = 0; + do { + cw = (random(0, 5) + 2) & ~1; + ch = (random(0, 5) + 2) & ~1; + cy1 = h/2 + y - ch/2; + cx1 = x-cw; + ran = L4checkRoom(cx1-1, cy1-1, ch+2, cw+1); /// BUGFIX: swap args 3 and 4 ("ch+2" and "cw+1") + num++; + } while(ran == FALSE && num < 20); + + if(ran == TRUE) + L4drawRoom(cx1, cy1, cw, ch); + cx2 = x+w; + ran2 = L4checkRoom(cx2, cy1-1, cw+1, ch+2); + if(ran2 == TRUE) + L4drawRoom(cx2, cy1, cw, ch); + if(ran == TRUE) + L4roomGen(cx1, cy1, cw, ch, 1); + if(ran2 == TRUE) + L4roomGen(cx2, cy1, cw, ch, 1); + break; + case TRUE: + num = 0; + do { + width = (random(0, 5) + 2) & ~1; + height = (random(0, 5) + 2) & ~1; + rx = w/2 + x - width/2; + ry = y-height; + ran = L4checkRoom(rx-1, ry-1, width+2, height+1); + num++; + } while(ran == FALSE && num < 20); + + if(ran == TRUE) + L4drawRoom(rx, ry, width, height); + ry2 = y+h; + ran2 = L4checkRoom(rx-1, ry2, width+2, height+1); + if(ran2 == TRUE) + L4drawRoom(rx, ry2, width, height); + if(ran == TRUE) + L4roomGen(rx, ry, width, height, 0); + if(ran2 == TRUE) + L4roomGen(rx, ry2, width, height, 0); + break; + } +} + +static void L4firstRoom() +{ + int x, y, w, h, rndx, rndy, xmin, xmax, ymin, ymax; + + if(currlevel != 16) { + if(currlevel == quests[Q_WARLORD]._qlevel && quests[Q_WARLORD]._qactive) { + /// ASSERT: assert(gbMaxPlayers == 1); + w = 11; + h = 11; + } else if(currlevel == quests[Q_BETRAYER]._qlevel && gbMaxPlayers != 1) { + w = 11; + h = 11; + } else { + w = random(0, 5) + 2; + h = random(0, 5) + 2; + } + } else { + w = 14; + h = 14; + } + + xmin = (20 - w) >> 1; + xmax = 19 - w; + rndx = random(0, xmax - xmin + 1) + xmin; + if(rndx + w > 19) { + x = 19 - w + 1; + } else { + x = rndx; + } + ymin = (20 - h) >> 1; + ymax = 19 - h; + rndy = random(0, ymax - ymin + 1) + ymin; + if(rndy + h > 19) { + y = 19 - h + 1; + } else { + y = rndy; + } + + if(currlevel == 16) { + l4holdx = x; + l4holdy = y; + } + if(QuestStatus(Q_WARLORD) || currlevel == quests[Q_BETRAYER]._qlevel && gbMaxPlayers != 1) { + SP4x1 = x + 1; + SP4y1 = y + 1; + SP4x2 = SP4x1 + w; + SP4y2 = SP4y1 + h; + } else { + SP4x1 = 0; + SP4y1 = 0; + SP4x2 = 0; + SP4y2 = 0; + } + + L4drawRoom(x, y, w, h); + L4roomGen(x, y, w, h, random(0, 2)); +} + +void L4SaveQuads() +{ + int i, j, x, y; + + y = 0; + for(j = 0; j < 14; j++) { + x = 0; + for(i = 0; i < 14; i++) { + dflags[i + l4holdx][j + l4holdy] = 1; + dflags[39 - x - l4holdx][j + l4holdy] = 1; + dflags[i + l4holdx][39 - y - l4holdy] = 1; + dflags[39 - x - l4holdx][39 - y - l4holdy] = 1; + x++; + } + y++; + } +} + +void DRLG_L4SetRoom(unsigned char *pSetPiece, int rx1, int ry1) +{ + int rw, rh, i, j; + unsigned char *sp; + + rw = pSetPiece[0]; + rh = pSetPiece[2]; + sp = &pSetPiece[4]; + + for(j = 0; j < rh; j++) { + for(i = 0; i < rw; i++) { + if(*sp != 0) { + dungeon[i + rx1][j + ry1] = *sp; + dflags[i + rx1][j + ry1] |= 0x80; + } else { + dungeon[i + rx1][j + ry1] = 6; + } + sp += 2; + } + } +} + +void DRLG_LoadDiabQuads(BOOL preflag) +{ + BYTE *lpSetPiece; + + lpSetPiece = DiabLoad("Levels\\L4Data\\diab1.DUN", NULL, 'STPC'); + diabquad1x = 4 + l4holdx; + diabquad1y = 4 + l4holdy; + DRLG_L4SetRoom(lpSetPiece, diabquad1x, diabquad1y); + mem_free_dbg(lpSetPiece); + + if(preflag) { + lpSetPiece = DiabLoad("Levels\\L4Data\\diab2b.DUN", NULL, 'STPC'); + } else { + lpSetPiece = DiabLoad("Levels\\L4Data\\diab2a.DUN", NULL, 'STPC'); + } + diabquad2x = 27 - l4holdx; + diabquad2y = 1 + l4holdy; + DRLG_L4SetRoom(lpSetPiece, diabquad2x, diabquad2y); + mem_free_dbg(lpSetPiece); + + if(preflag) { + lpSetPiece = DiabLoad("Levels\\L4Data\\diab3b.DUN", NULL, 'STPC'); + } else { + lpSetPiece = DiabLoad("Levels\\L4Data\\diab3a.DUN", NULL, 'STPC'); + } + diabquad3x = 1 + l4holdx; + diabquad3y = 27 - l4holdy; + DRLG_L4SetRoom(lpSetPiece, diabquad3x, diabquad3y); + mem_free_dbg(lpSetPiece); + + if(preflag) { + lpSetPiece = DiabLoad("Levels\\L4Data\\diab4b.DUN", NULL, 'STPC'); + } else { + lpSetPiece = DiabLoad("Levels\\L4Data\\diab4a.DUN", NULL, 'STPC'); + } + diabquad4x = 28 - l4holdx; + diabquad4y = 28 - l4holdy; + DRLG_L4SetRoom(lpSetPiece, diabquad4x, diabquad4y); + mem_free_dbg(lpSetPiece); +} + +static BOOL DRLG_L4PlaceMiniSet(const unsigned char *miniset, int tmin, int tmax, int cx, int cy, BOOL setview, int ldir) +{ + int sx, sy, sw, sh, xx, yy, i, ii, numt, bailcnt; + BOOL found; + + sw = miniset[0]; + sh = miniset[1]; + + if(tmax - tmin == 0) { + numt = 1; + } else { + numt = random(0, tmax - tmin) + tmin; + } + + for(i = 0; i < numt; i++) { + sx = random(0, 40 - sw); + sy = random(0, 40 - sh); + found = FALSE; + for(bailcnt = 0; !found && bailcnt < 200; bailcnt++) { + found = TRUE; + if(sx >= SP4x1 && sx <= SP4x2 && sy >= SP4y1 && sy <= SP4y2) { + found = FALSE; + } + if(cx != -1 && sx >= cx - sw && sx <= cx + 12) { + sx = random(0, 40 - sw); + sy = random(0, 40 - sh); + found = FALSE; + } + if(cy != -1 && sy >= cy - sh && sy <= cy + 12) { + sx = random(0, 40 - sw); + sy = random(0, 40 - sh); + found = FALSE; + } + ii = 2; + for(yy = 0; yy < sh && found == TRUE; yy++) { + for(xx = 0; xx < sw && found == TRUE; xx++) { + if(miniset[ii] != 0 && dungeon[xx + sx][yy + sy] != miniset[ii]) { + found = FALSE; + } + if(dflags[xx + sx][yy + sy] != 0) { + found = FALSE; + } + ii++; + } + } + if(!found) { + sx++; + if(sx == 40 - sw) { + sx = 0; + sy++; + if(sy == 40 - sh) { + sy = 0; + } + } + } + } + if(bailcnt >= 200) { + return FALSE; + } + ii = sw * sh + 2; + for(yy = 0; yy < sh; yy++) { + for(xx = 0; xx < sw; xx++) { + if(miniset[ii] != 0) { + dungeon[xx + sx][yy + sy] = miniset[ii]; + dflags[xx + sx][yy + sy] |= 8; + } + ii++; + } + } + } + + if(currlevel == 15) { + quests[15]._qtx = sx + 1; + quests[15]._qty = sy + 1; + } + if(setview == TRUE) { + ViewX = 2 * sx + 21; + ViewY = 2 * sy + 22; + } + if(ldir == 0) { + LvlViewX = 2 * sx + 21; + LvlViewY = 2 * sy + 22; + } + + return TRUE; +} + +static void DRLG_L4FTVR(int i, int j, int x, int y, int d) +{ + if(dTransVal[x][y] != 0 || dungeon[i][j] != 6) { + if(d == 1) { + dTransVal[x][y] = TransVal; + dTransVal[x][y + 1] = TransVal; + } + if(d == 2) { + dTransVal[x + 1][y] = TransVal; + dTransVal[x + 1][y + 1] = TransVal; + } + if(d == 3) { + dTransVal[x][y] = TransVal; + dTransVal[x + 1][y] = TransVal; + } + if(d == 4) { + dTransVal[x][y + 1] = TransVal; + dTransVal[x + 1][y + 1] = TransVal; + } + if(d == 5) { + dTransVal[x + 1][y + 1] = TransVal; + } + if(d == 6) { + dTransVal[x][y + 1] = TransVal; + } + if(d == 7) { + dTransVal[x + 1][y] = TransVal; + } + if(d == 8) { + dTransVal[x][y] = TransVal; + } + } else { + dTransVal[x][y] = TransVal; + dTransVal[x + 1][y] = TransVal; + dTransVal[x][y + 1] = TransVal; + dTransVal[x + 1][y + 1] = TransVal; + DRLG_L4FTVR(i + 1, j, x + 2, y, 1); + DRLG_L4FTVR(i - 1, j, x - 2, y, 2); + DRLG_L4FTVR(i, j + 1, x, y + 2, 3); + DRLG_L4FTVR(i, j - 1, x, y - 2, 4); + DRLG_L4FTVR(i - 1, j - 1, x - 2, y - 2, 5); + DRLG_L4FTVR(i + 1, j - 1, x + 2, y - 2, 6); + DRLG_L4FTVR(i - 1, j + 1, x - 2, y + 2, 7); + DRLG_L4FTVR(i + 1, j + 1, x + 2, y + 2, 8); + } +} + +static void DRLG_L4FloodTVal() +{ + int i, j, xx, yy; + + yy = 16; + for(j = 0; j < DMAXY; j++) { + xx = 16; + for(i = 0; i < DMAXX; i++) { + if(dungeon[i][j] == 6 && dTransVal[xx][yy] == 0) { + DRLG_L4FTVR(i, j, xx, yy, 0); + TransVal++; + } + xx += 2; + } + yy += 2; + } +} + +BOOL IsDURWall(char d) +{ + if(d == 25) { + return TRUE; + } + if(d == 28) { + return TRUE; + } + if(d == 23) { + return TRUE; + } + + return FALSE; +} + +BOOL IsDLLWall(char dd) +{ + if(dd == 27) { + return TRUE; + } + if(dd == 26) { + return TRUE; + } + if(dd == 22) { + return TRUE; + } + + return FALSE; +} + +static void DRLG_L4TransFix() +{ + int i, j, xx, yy; + + yy = 16; + for(j = 0; j < DMAXY; j++) { + xx = 16; + for(i = 0; i < DMAXX; i++) { + if(IsDURWall(dungeon[i][j]) && dungeon[i][j - 1] == 18) { + dTransVal[xx + 1][yy] = dTransVal[xx][yy]; + dTransVal[xx + 1][yy + 1] = dTransVal[xx][yy]; + } + if(IsDLLWall(dungeon[i][j]) && dungeon[i + 1][j] == 19) { + dTransVal[xx][yy + 1] = dTransVal[xx][yy]; + dTransVal[xx + 1][yy + 1] = dTransVal[xx][yy]; + } + if(dungeon[i][j] == 18) { + dTransVal[xx + 1][yy] = dTransVal[xx][yy]; + dTransVal[xx + 1][yy + 1] = dTransVal[xx][yy]; + } + if(dungeon[i][j] == 19) { + dTransVal[xx][yy + 1] = dTransVal[xx][yy]; + dTransVal[xx + 1][yy + 1] = dTransVal[xx][yy]; + } + if(dungeon[i][j] == 24) { + dTransVal[xx + 1][yy] = dTransVal[xx][yy]; + dTransVal[xx][yy + 1] = dTransVal[xx][yy]; + dTransVal[xx + 1][yy + 1] = dTransVal[xx][yy]; + } + if(dungeon[i][j] == 57) { + dTransVal[xx - 1][yy] = dTransVal[xx][yy + 1]; + dTransVal[xx][yy] = dTransVal[xx][yy + 1]; + } + if(dungeon[i][j] == 53) { + dTransVal[xx][yy - 1] = dTransVal[xx + 1][yy]; + dTransVal[xx][yy] = dTransVal[xx + 1][yy]; + } + xx += 2; + } + yy += 2; + } +} + +static void DRLG_L4Corners() +{ + int i, j; + + for(j = 1; j < DMAXY - 1; j++) { + for(i = 1; i < DMAXX - 1; i++) { + if(dungeon[i][j] >= 18 && dungeon[i][j] <= 30) { + if(dungeon[i + 1][j] < 18) { + dungeon[i][j] += 98; + } else if(dungeon[i][j + 1] < 18) { + dungeon[i][j] += 98; + } + } + } + } +} + +void L4FixRim() +{ + int i, j; + + for(i = 0; i < 20; i++) { + dung[i][0] = 0; + } + for(j = 0; j < 20; j++) { + dung[0][j] = 0; + } +} + +void DRLG_L4GeneralFix() +{ + int i, j; + + for(j = 0; j < 39; j++) { + for(i = 0; i < 39; i++) { + if((dungeon[i][j] == 24 || dungeon[i][j] == 122) && dungeon[i + 1][j] == 2 && dungeon[i][j + 1] == 5) { + dungeon[i][j] = 17; + } + } + } +} + +static void DRLG_L4(int entry) +{ + int i, j, spi, spj; + BOOL doneflag; + + do { + DRLG_InitTrans(); + do { + InitL4Dungeon(); + L4firstRoom(); + L4FixRim(); + } while(GetArea() < 173); + uShape(); + L4makeDungeon(); + L4makeDmt(); + L4tileFix(); + if(currlevel == 16) { + L4SaveQuads(); + } + if(QuestStatus(Q_WARLORD) || currlevel == quests[Q_BETRAYER]._qlevel && gbMaxPlayers != 1) { + for(spi = SP4x1; spi < SP4x2; spi++) { + for(spj = SP4y1; spj < SP4y2; spj++) { + dflags[spi][spj] = 1; + } + } + } + L4AddWall(); + DRLG_L4FloodTVal(); + DRLG_L4TransFix(); + if(setloadflag_2) { + DRLG_L4SetSPRoom(SP4x1, SP4y1); + } + if(currlevel == 16) { + DRLG_LoadDiabQuads(TRUE); + } + if(QuestStatus(Q_WARLORD)) { + if(entry == 0) { + doneflag = DRLG_L4PlaceMiniSet(L4USTAIRS, 1, 1, -1, -1, 1, 0); + if(doneflag && currlevel == 13) { + doneflag = DRLG_L4PlaceMiniSet(L4TWARP, 1, 1, -1, -1, 0, 6); + } + ViewX++; + } else if(entry == 1) { + doneflag = DRLG_L4PlaceMiniSet(L4USTAIRS, 1, 1, -1, -1, 0, 0); + if(doneflag && currlevel == 13) { + doneflag = DRLG_L4PlaceMiniSet(L4TWARP, 1, 1, -1, -1, 0, 6); + } + ViewX = 2 * setpc_x + 22; + ViewY = 2 * setpc_y + 22; + } else { + doneflag = DRLG_L4PlaceMiniSet(L4USTAIRS, 1, 1, -1, -1, 0, 0); + if(doneflag && currlevel == 13) { + doneflag = DRLG_L4PlaceMiniSet(L4TWARP, 1, 1, -1, -1, 1, 6); + } + ViewX++; + } + } else if(currlevel != 15) { + if(entry == 0) { + doneflag = DRLG_L4PlaceMiniSet(L4USTAIRS, 1, 1, -1, -1, 1, 0); + if(doneflag && currlevel != 16) { + doneflag = DRLG_L4PlaceMiniSet(L4DSTAIRS, 1, 1, -1, -1, 0, 1); + } + if(doneflag && currlevel == 13) { + doneflag = DRLG_L4PlaceMiniSet(L4TWARP, 1, 1, -1, -1, 0, 6); + } + ViewX++; + } else if(entry == 1) { + doneflag = DRLG_L4PlaceMiniSet(L4USTAIRS, 1, 1, -1, -1, 0, 0); + if(doneflag && currlevel != 16) { + doneflag = DRLG_L4PlaceMiniSet(L4DSTAIRS, 1, 1, -1, -1, 1, 1); + } + if(doneflag && currlevel == 13) { + doneflag = DRLG_L4PlaceMiniSet(L4TWARP, 1, 1, -1, -1, 0, 6); + } + ViewY++; + } else { + doneflag = DRLG_L4PlaceMiniSet(L4USTAIRS, 1, 1, -1, -1, 0, 0); + if(doneflag && currlevel != 16) { + doneflag = DRLG_L4PlaceMiniSet(L4DSTAIRS, 1, 1, -1, -1, 0, 1); + } + if(doneflag && currlevel == 13) { + doneflag = DRLG_L4PlaceMiniSet(L4TWARP, 1, 1, -1, -1, 1, 6); + } + ViewX++; + } + } else { + if(entry == 0) { + doneflag = DRLG_L4PlaceMiniSet(L4USTAIRS, 1, 1, -1, -1, 1, 0); + if(doneflag) { + if(gbMaxPlayers == 1 && quests[Q_DIABLO]._qactive != 2) { + doneflag = DRLG_L4PlaceMiniSet(L4PENTA, 1, 1, -1, -1, 0, 1); + } else { + doneflag = DRLG_L4PlaceMiniSet(L4PENTA2, 1, 1, -1, -1, 0, 1); + } + } + ViewX++; + } else { + doneflag = DRLG_L4PlaceMiniSet(L4USTAIRS, 1, 1, -1, -1, 0, 0); + if(doneflag) { + if(gbMaxPlayers == 1 && quests[Q_DIABLO]._qactive != 2) { + doneflag = DRLG_L4PlaceMiniSet(L4PENTA, 1, 1, -1, -1, 1, 1); + } else { + doneflag = DRLG_L4PlaceMiniSet(L4PENTA2, 1, 1, -1, -1, 1, 1); + } + } + ViewY++; + } + } + } while(!doneflag); + + DRLG_L4GeneralFix(); + + if(currlevel != 16) { + DRLG_PlaceThemeRooms(7, 10, 6, 8, 1); + } + + DRLG_L4Shadows(); + DRLG_L4Corners(); + DRLG_L4Subs(); + DRLG_Init_Globals(); + + if(QuestStatus(Q_WARLORD)) { + for(j = 0; j < DMAXY; j++) { + for(i = 0; i < DMAXX; i++) { + pdungeon[i][j] = dungeon[i][j]; + } + } + } + + DRLG_CheckQuests(SP4x1, SP4y1); + + if(currlevel == 15) { + for(j = 0; j < DMAXY; j++) { + for(i = 0; i < DMAXX; i++) { + if(dungeon[i][j] == 98) { + Make_SetPC(i - 1, j - 1, 5, 5); + } + if(dungeon[i][j] == 107) { + Make_SetPC(i - 1, j - 1, 5, 5); + } + } + } + } + if(currlevel == 16) { + for(j = 0; j < DMAXY; j++) { + for(i = 0; i < DMAXX; i++) { + pdungeon[i][j] = dungeon[i][j]; + } + } + DRLG_LoadDiabQuads(FALSE); + } +} + +static void DRLG_L4Pass3() +{ + int i, j, xx, yy; + long v1, v2, v3, v4, lv; + + lv = 30-1; + +#ifdef USE_ASM + __asm { + mov esi, pMegaTiles + mov eax, lv + shl eax, 3 + add esi, eax + xor eax, eax + lodsw + inc eax + mov v1, eax + lodsw + inc eax + mov v2, eax + lodsw + inc eax + mov v3, eax + lodsw + inc eax + mov v4, eax + } +#else + v1 = ((WORD *)&pMegaTiles[lv << 3])[0] + 1; + v2 = ((WORD *)&pMegaTiles[lv << 3])[1] + 1; + v3 = ((WORD *)&pMegaTiles[lv << 3])[2] + 1; + v4 = ((WORD *)&pMegaTiles[lv << 3])[3] + 1; +#endif + + for(j = 0; j < MAXDUNY; j += 2) { + for(i = 0; i < MAXDUNX; i += 2) { + dPiece[i][j] = v1; + dPiece[i+1][j] = v2; + dPiece[i][j+1] = v3; + dPiece[i+1][j+1] = v4; + } + } + + yy = 16; + for(j = 0; j < DMAXY; j++) { + xx = 16; + for(i = 0; i < DMAXX; i++) { + lv = (unsigned char)dungeon[i][j]-1; + if(lv >= 0) { +#ifdef USE_ASM + __asm { + mov esi, pMegaTiles + mov eax, lv + shl eax, 3 + add esi, eax + xor eax, eax + lodsw + inc eax + mov v1, eax + lodsw + inc eax + mov v2, eax + lodsw + inc eax + mov v3, eax + lodsw + inc eax + mov v4, eax + } +#else + v1 = ((WORD *)&pMegaTiles[lv << 3])[0] + 1; + v2 = ((WORD *)&pMegaTiles[lv << 3])[1] + 1; + v3 = ((WORD *)&pMegaTiles[lv << 3])[2] + 1; + v4 = ((WORD *)&pMegaTiles[lv << 3])[3] + 1; +#endif + } else { + v1 = 0; + v2 = 0; + v3 = 0; + v4 = 0; + } + dPiece[xx][yy] = v1; + dPiece[xx+1][yy] = v2; + dPiece[xx][yy+1] = v3; + dPiece[xx+1][yy+1] = v4; + xx += 2; + } + yy += 2; + } +} + +void CreateL4Dungeon(unsigned int rseed, int entry) +{ + SetRndSeed(rseed); + + dminx = 16; + dminy = 16; + dmaxx = 96; + dmaxy = 96; + + ViewX = 40; + ViewY = 40; + + DRLG_InitSetPC(); + DRLG_LoadL4SP(); + DRLG_L4(entry); + DRLG_L4Pass3(); + DRLG_FreeL4SP(); + DRLG_SetPC(); +} diff --git a/2020_03_31/Source/drlg_l4.h b/2020_03_31/Source/drlg_l4.h new file mode 100644 index 00000000..50f096e9 --- /dev/null +++ b/2020_03_31/Source/drlg_l4.h @@ -0,0 +1,45 @@ +//HEADER_GOES_HERE +#ifndef __DRLG_L4_H__ +#define __DRLG_L4_H__ + +extern int diabquad1x; // weak +extern int diabquad1y; // weak +extern int diabquad3x; // idb +extern int diabquad3y; // idb +extern int diabquad2x; // idb +extern int diabquad2y; // idb +extern int diabquad4x; // idb +extern int diabquad4y; // idb +extern BOOL hallok[20]; +extern int l4holdx; // weak +extern int l4holdy; // weak +extern int SP4x1; // idb +extern int SP4x2; // weak +extern int SP4y1; // idb +extern int SP4y2; // weak +extern unsigned char L4dungeon[80][80]; +extern unsigned char dung[20][20]; +//int dword_52A4DC; // weak + +void DRLG_LoadL4SP(); +void DRLG_FreeL4SP(); +void DRLG_L4SetSPRoom(int rx1, int ry1); +void L4SaveQuads(); +void DRLG_L4SetRoom(unsigned char *pSetPiece, int rx1, int ry1); +void DRLG_LoadDiabQuads(BOOL preflag); +BOOL IsDURWall(char d); +BOOL IsDLLWall(char dd); +void L4FixRim(); +void DRLG_L4GeneralFix(); +void CreateL4Dungeon(unsigned int rseed, int entry); + +/* rdata */ +extern const unsigned char L4ConvTbl[16]; +extern const unsigned char L4USTAIRS[42]; +extern const unsigned char L4TWARP[42]; +extern const unsigned char L4DSTAIRS[52]; +extern const unsigned char L4PENTA[52]; +extern const unsigned char L4PENTA2[52]; +extern const unsigned char L4BTYPES[140]; + +#endif /* __DRLG_L4_H__ */ diff --git a/2020_03_31/Source/dthread.cpp b/2020_03_31/Source/dthread.cpp new file mode 100644 index 00000000..edfbfc8c --- /dev/null +++ b/2020_03_31/Source/dthread.cpp @@ -0,0 +1,148 @@ +#include "diablo.h" +#include "../3rdParty/Storm/Source/storm.h" + +static CCritSect sgMemCrit; // idb +static unsigned int sgnThreadId; // idb +TDeltaInfo *sgpInfoHead; +static BOOLEAN sgbThreadIsActive; // weak +HANDLE sghWorkToDoEvent; // idb + +/* rdata */ +static HANDLE sghThread = INVALID_HANDLE_VALUE; // idb + +void dthread_remove_player(int pnum) +{ + TDeltaInfo *p; + + sgMemCrit.Enter(); + + for(p = sgpInfoHead; p != NULL; p = p->pNext) { + if(p->pnum == pnum) { + p->pnum = 4; + } + } + + sgMemCrit.Leave(); +} + +void dthread_send_delta(int pnum, BYTE cmd, const BYTE *pbSrc, DWORD dwLen) +{ + TDeltaInfo *pCurr, *p; + + /// ASSERT: assert((DWORD) pnum < MAX_PLRS); + /// ASSERT: assert(pnum != myplr); + /// ASSERT: assert(pbSrc); + /// ASSERT: assert(dwLen); + + if(gbMaxPlayers == 1) { + return; + } + + pCurr = (TDeltaInfo *)DiabloAllocPtr(sizeof(*pCurr) + dwLen); + pCurr->pNext = NULL; + pCurr->pnum = pnum; + pCurr->cmd = cmd; + pCurr->size = dwLen; + memcpy(pCurr->data, pbSrc, dwLen); + + sgMemCrit.Enter(); + + p = (TDeltaInfo *)&sgpInfoHead; + while(p->pNext != NULL) { + p = p->pNext; + } + p->pNext = pCurr; + + SetEvent(sghWorkToDoEvent); + + sgMemCrit.Leave(); +} + +void dthread_start() +{ + /// ASSERT: assert(sghThread == INVALID_HANDLE_VALUE); + + if(gbMaxPlayers == 1) { + return; + } + + /// ASSERT: assert(! sgpInfoHead); + /// ASSERT: assert(! sghWorkToDoEvent); + sghWorkToDoEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + if(sghWorkToDoEvent == NULL) { + app_fatal("dthread:1\n%s", TraceLastError()); + } + + sgbThreadIsActive = TRUE; + + /// ASSERT: assert(sghThread == INVALID_HANDLE_VALUE); + sghThread = (HANDLE)_beginthreadex(NULL, 0, dthread_handler, NULL, 0, &sgnThreadId); + if(sghThread == INVALID_HANDLE_VALUE) { + app_fatal("dthread2:\n%s", TraceLastError()); + } +} + +unsigned int __stdcall dthread_handler(void *dummy) +{ + DWORD dwTime; + TDeltaInfo *p; + + while(sgbThreadIsActive) { + if(sgpInfoHead == NULL && WaitForSingleObject(sghWorkToDoEvent, INFINITE) == WAIT_FAILED) { + app_fatal("dthread4:\n%s", TraceLastError()); + } + sgMemCrit.Enter(); + p = sgpInfoHead; + if(p != NULL) { + sgpInfoHead = p->pNext; + } else { + ResetEvent(sghWorkToDoEvent); + } + sgMemCrit.Leave(); + if(p != NULL) { + if(p->pnum != 4) { + multi_send_zero_packet(p->pnum, p->cmd, p->data, p->size); + } + /// ASSERT: assert(gdwDeltaBytesSec); + dwTime = 1000 * p->size / gdwDeltaBytesSec; + if(dwTime >= 1) { + dwTime = 1; + } + MemFreeDbg(p); + if(dwTime != 0) { + Sleep(dwTime); + } + } + } + + return 0; +} + +void dthread_cleanup() +{ + TDeltaInfo *p; + + if(sghWorkToDoEvent == NULL) { + return; + } + + sgbThreadIsActive = FALSE; + SetEvent(sghWorkToDoEvent); + + if(sghThread != INVALID_HANDLE_VALUE && sgnThreadId != GetCurrentThreadId()) { + if(WaitForSingleObject(sghThread, INFINITE) == WAIT_FAILED) { + app_fatal("dthread3:\n(%s)", TraceLastError()); + } + CloseHandle(sghThread); + sghThread = INVALID_HANDLE_VALUE; + } + + CloseHandle(sghWorkToDoEvent); + sghWorkToDoEvent = NULL; + + while(sgpInfoHead != NULL) { + p = sgpInfoHead->pNext; + MemFreeDbg(sgpInfoHead); + sgpInfoHead = p; + } +} diff --git a/2020_03_31/Source/dthread.h b/2020_03_31/Source/dthread.h new file mode 100644 index 00000000..9557fcc9 --- /dev/null +++ b/2020_03_31/Source/dthread.h @@ -0,0 +1,14 @@ +//HEADER_GOES_HERE +#ifndef __DTHREAD_H__ +#define __DTHREAD_H__ + +extern TDeltaInfo *sgpInfoHead; +extern HANDLE sghWorkToDoEvent; // idb + +void dthread_remove_player(int pnum); +void dthread_send_delta(int pnum, BYTE cmd, const BYTE *pbSrc, DWORD dwLen); +void dthread_start(); +unsigned int __stdcall dthread_handler(void *dummy); +void dthread_cleanup(); + +#endif /* __DTHREAD_H__ */ diff --git a/2020_03_31/Source/dx.cpp b/2020_03_31/Source/dx.cpp new file mode 100644 index 00000000..9ecdd401 --- /dev/null +++ b/2020_03_31/Source/dx.cpp @@ -0,0 +1,310 @@ +#include "diablo.h" +#include "../3rdParty/Storm/Source/storm.h" + +void *sgpBackBuf; +IDirectDraw *lpDDInterface; +IDirectDrawPalette *lpDDPalette; // idb +int sgdwLockCount; +BYTE *gpBuffer; +IDirectDrawSurface *lpDDSBackBuf; +IDirectDrawSurface *lpDDSPrimary; +#ifdef _DEBUG +int locktbl[256]; +#endif +static CCritSect sgMemCrit; +char gbBackBuf; // weak +char gbEmulate; // weak +HINSTANCE sghInstDD; // idb + +static void dx_create_back_buffer() +{ + HRESULT hDDVal; + DDSURFACEDESC ddsd; + DDSCAPS caps; + + /// ASSERT: assert(! gpBuffer); + /// ASSERT: assert(! sgdwLockCount); + /// ASSERT: assert(! sgpBackBuf); + /// ASSERT: assert(lpDDSPrimary); + + hDDVal = lpDDSPrimary->GetCaps(&caps); + if(hDDVal != DD_OK) { + DDErrMsg(hDDVal, 59, "C:\\Src\\Diablo\\Source\\dx.cpp"); + } + /// ASSERT: assert(caps.dwCaps & DDSCAPS_PRIMARYSURFACE); + + if(!gbBackBuf) { + ddsd.dwSize = sizeof(ddsd); + hDDVal = lpDDSPrimary->Lock(NULL, &ddsd, DDLOCK_WRITEONLY | DDLOCK_WAIT, NULL); + if(hDDVal == DD_OK) { + hDDVal = lpDDSPrimary->Unlock(NULL); +#ifdef _DEBUG + if(hDDVal != DD_OK) { + DDErrMsg(hDDVal, 69, "C:\\Diablo\\Direct\\dx.cpp"); + } +#endif + sgpBackBuf = DiabloAllocPtr(BUFFER_WIDTH * BUFFER_HEIGHT); + return; + } + if(hDDVal != DDERR_CANTLOCKSURFACE) { + ErrDlg(IDD_DIALOG1, hDDVal, "C:\\Src\\Diablo\\Source\\dx.cpp", 81); + } + } + + memset(&ddsd, 0, sizeof(ddsd)); + ddsd.dwSize = sizeof(ddsd); + ddsd.dwFlags = DDSD_PIXELFORMAT | DDSD_PITCH | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS; + ddsd.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN; + ddsd.dwWidth = BUFFER_WIDTH; + ddsd.dwHeight = BUFFER_HEIGHT; + ddsd.lPitch = BUFFER_WIDTH; + ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat); + + hDDVal = lpDDSPrimary->GetPixelFormat(&ddsd.ddpfPixelFormat); + if(hDDVal != DD_OK) { + ErrDlg(IDD_DIALOG1, hDDVal, "C:\\Src\\Diablo\\Source\\dx.cpp", 94); + } + hDDVal = lpDDInterface->CreateSurface(&ddsd, &lpDDSBackBuf, NULL); + if(hDDVal != DD_OK) { + ErrDlg(IDD_DIALOG1, hDDVal, "C:\\Src\\Diablo\\Source\\dx.cpp", 96); + } +} + +static void dx_create_primary_surface() +{ + HRESULT hDDVal; + DDSURFACEDESC ddsd; + + memset(&ddsd, 0, sizeof(ddsd)); + ddsd.dwSize = sizeof(ddsd); + ddsd.dwFlags = DDSD_CAPS; + ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; + + hDDVal = lpDDInterface->CreateSurface(&ddsd, &lpDDSPrimary, NULL); + if(hDDVal != DD_OK) { + ErrDlg(IDD_DIALOG1, hDDVal, "C:\\Src\\Diablo\\Source\\dx.cpp", 109); + } +} + +static HRESULT dx_DirectDrawCreate(GUID FAR *lpGUID, LPDIRECTDRAW FAR *lplpDD, IUnknown FAR *pUnkOuter) +{ + DDCREATEPROC ddcp; + + if(sghInstDD == NULL) { + sghInstDD = LoadLibrary("ddraw.dll"); + if(sghInstDD == NULL) { + ErrDlg(IDD_DIALOG4, GetLastError(), "C:\\Src\\Diablo\\Source\\dx.cpp", 122); + } + } + ddcp = (DDCREATEPROC)GetProcAddress(sghInstDD, "DirectDrawCreate"); + if(ddcp == NULL) { + ErrDlg(IDD_DIALOG4, GetLastError(), "C:\\Src\\Diablo\\Source\\dx.cpp", 127); + } + + return ddcp(lpGUID, lplpDD, pUnkOuter); +} + +void dx_init(HWND hWnd) +{ + HRESULT hDDVal; + int winw, winh; + BOOL bSuccess; + GUID *lpGUID; + + /// ASSERT: assert(! gpBuffer); + /// ASSERT: assert(! sgdwLockCount); + /// ASSERT: assert(! sgpBackBuf); + + SetFocus(hWnd); + ShowWindow(hWnd, SW_SHOWNORMAL); + + lpGUID = NULL; + if(gbEmulate) { + lpGUID = (GUID *)DDCREATE_EMULATIONONLY; + } + hDDVal = dx_DirectDrawCreate(lpGUID, &lpDDInterface, NULL); + if(hDDVal != DD_OK) { + ErrDlg(IDD_DIALOG1, hDDVal, "C:\\Src\\Diablo\\Source\\dx.cpp", 149); + } + +#ifdef COLORFIX +#ifdef __DDRAWI_INCLUDED__ + ((LPDDRAWI_DIRECTDRAW_INT)lpDDInterface)->lpLcl->dwAppHackFlags |= 0x800; +#else + ((DWORD **)lpDDInterface)[1][18] |= 0x800; +#endif +#endif + +#ifndef _DEBUG + fullscreen = TRUE; +#endif + if(!fullscreen) { + hDDVal = lpDDInterface->SetCooperativeLevel(hWnd, DDSCL_NORMAL | DDSCL_ALLOWREBOOT); + if(hDDVal == DDERR_EXCLUSIVEMODEALREADYSET) { + TriggerBreak(); + } else if(hDDVal != DD_OK) { + ErrDlg(IDD_DIALOG1, hDDVal, "C:\\Diablo\\Direct\\dx.cpp", 155); + } + SetWindowPos(hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE); + } else { + hDDVal = lpDDInterface->SetCooperativeLevel(hWnd, DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT | DDSCL_FULLSCREEN); + if(hDDVal == DDERR_EXCLUSIVEMODEALREADYSET) { + TriggerBreak(); + } else if(hDDVal != DD_OK) { + ErrDlg(IDD_DIALOG1, hDDVal, "C:\\Src\\Diablo\\Source\\dx.cpp", 170); + } + hDDVal = lpDDInterface->SetDisplayMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP); + if(hDDVal != DD_OK) { + winw = GetSystemMetrics(SM_CXSCREEN); + winh = GetSystemMetrics(SM_CYSCREEN); + hDDVal = lpDDInterface->SetDisplayMode(winw, winh, SCREEN_BPP); + } + if(hDDVal != DD_OK) { + ErrDlg(IDD_DIALOG1, hDDVal, "C:\\Src\\Diablo\\Source\\dx.cpp", 183); + } + } + + dx_create_primary_surface(); + palette_init(); + GdiSetBatchLimit(1); + dx_create_back_buffer(); + bSuccess = SDrawManualInitialize(hWnd, lpDDInterface, lpDDSPrimary, NULL, NULL, lpDDSBackBuf, lpDDPalette, NULL); + /// ASSERT: assert(bSuccess); +} + +static void lock_buf_priv() +{ + HRESULT hDDVal; + DDSURFACEDESC ddsd; + + sgMemCrit.Enter(); + + if(sgpBackBuf != NULL) { + gpBuffer = (BYTE *)sgpBackBuf; + } else if(lpDDSBackBuf == NULL) { + Sleep(20000); + app_fatal("lock_buf_priv"); + } else if(sgdwLockCount == 0) { + ddsd.dwSize = sizeof(ddsd); + hDDVal = lpDDSBackBuf->Lock(NULL, &ddsd, DDLOCK_WAIT, NULL); + if(hDDVal != DD_OK) { + DDErrMsg(hDDVal, 235, "C:\\Src\\Diablo\\Source\\dx.cpp"); + } + gpBuffer = (BYTE *)ddsd.lpSurface; + /// ASSERT: assert(gpBuffer); + gpBufEnd += (DWORD)gpBuffer; + } + + sgdwLockCount++; +} + +void lock_buf(BYTE idx) +{ +#ifdef _DEBUG + locktbl[idx]++; +#endif + lock_buf_priv(); +} + +static void unlock_buf_priv() +{ + HRESULT hDDVal; + + if(sgdwLockCount == 0) { + app_fatal("draw main unlock error"); + } + if(gpBuffer == NULL) { + app_fatal("draw consistency error"); + } + if(sgpBackBuf == NULL) { + /// ASSERT: assert(lpDDSBackBuf); + } + + sgdwLockCount--; + + if(sgdwLockCount == 0) { + gpBufEnd -= (DWORD)gpBuffer; + gpBuffer = NULL; + if(sgpBackBuf == NULL) { + hDDVal = lpDDSBackBuf->Unlock(NULL); + if(hDDVal != DD_OK) { + DDErrMsg(hDDVal, 273, "C:\\Src\\Diablo\\Source\\dx.cpp"); + } + } + } + + sgMemCrit.Leave(); +} + +void unlock_buf(BYTE idx) +{ +#ifdef _DEBUG + if(locktbl[idx] == 0) { + app_fatal("Draw lock underflow: 0x%x", idx); + } + locktbl[idx]--; +#endif + unlock_buf_priv(); +} + +void dx_cleanup() +{ + if(ghMainWnd != NULL) { + ShowWindow(ghMainWnd, SW_HIDE); + } + + SDrawDestroy(); + sgMemCrit.Enter(); + + if(sgpBackBuf != NULL) { + /// ASSERT: assert(! lpDDSBackBuf); + MemFreeDbg(sgpBackBuf); + } else if(lpDDSBackBuf != NULL) { + lpDDSBackBuf->Release(); + lpDDSBackBuf = NULL; + } + + sgdwLockCount = 0; + gpBuffer = NULL; + + sgMemCrit.Leave(); + + if(lpDDSPrimary != NULL) { + lpDDSPrimary->Release(); + lpDDSPrimary = NULL; + } + if(lpDDPalette != NULL) { + lpDDPalette->Release(); + lpDDPalette = NULL; + } + if(lpDDInterface != NULL) { + lpDDInterface->Release(); + lpDDInterface = NULL; + } +} + +void dx_reinit() +{ + DWORD lock; + + sgMemCrit.Enter(); + + /// ASSERT: assert(ghMainWnd); + ClearCursor(); + + lock = sgdwLockCount; + while(sgdwLockCount != 0) { + unlock_buf_priv(); + } + + dx_cleanup(); + force_redraw = 255; + dx_init(ghMainWnd); + + while(lock != 0) { + lock_buf_priv(); + lock--; + } + + sgMemCrit.Leave(); +} diff --git a/2020_03_31/Source/dx.h b/2020_03_31/Source/dx.h new file mode 100644 index 00000000..282090fc --- /dev/null +++ b/2020_03_31/Source/dx.h @@ -0,0 +1,23 @@ +//HEADER_GOES_HERE +#ifndef __DX_H__ +#define __DX_H__ + +extern void *sgpBackBuf; +extern IDirectDraw *lpDDInterface; +extern IDirectDrawPalette *lpDDPalette; // idb +extern int sgdwLockCount; +extern BYTE *gpBuffer; +extern IDirectDrawSurface *lpDDSBackBuf; +extern IDirectDrawSurface *lpDDSPrimary; +extern char gbBackBuf; // weak +extern char gbEmulate; // weak +extern HINSTANCE sghInstDD; // idb + +void dx_init(HWND hWnd); +void lock_buf(BYTE idx); +void unlock_buf(BYTE idx); +void dx_cleanup(); +void dx_reinit(); +void j_dx_reinit(); + +#endif /* __DX_H__ */ diff --git a/2020_03_31/Source/effects.cpp b/2020_03_31/Source/effects.cpp new file mode 100644 index 00000000..4a48b8a3 --- /dev/null +++ b/2020_03_31/Source/effects.cpp @@ -0,0 +1,431 @@ +#include "diablo.h" +#include "../3rdParty/Storm/Source/storm.h" + +int sfxdelay; // weak +int sfxdnum; +HANDLE sghStream; +TSFX *sgpStreamSFX; + +const char monster_action_sounds[] = { 'a', 'h', 'd', 's' }; // idb + +/* data */ + +TSFX sgSFX[NUM_SFX] = +{ +#include "Data/xl_sfx.cpp" +}; + +BOOL effect_is_playing(int nSFX) +{ + TSFX *pSFX; + + /// ASSERT: assert(nSFX < NUM_SFX); + pSFX = &sgSFX[nSFX]; + + if(pSFX->pSnd != NULL) { + return snd_playing(pSFX->pSnd); + } + if(pSFX->bFlags & 1) { + return pSFX == sgpStreamSFX; + } + + return FALSE; +} + +void stream_stop() +{ + if(sghStream != NULL) { + SFileDdaEnd(sghStream); + SFileCloseFile(sghStream); + sghStream = NULL; + sgpStreamSFX = NULL; + } +} + +static void stream_play(TSFX *pSFX, long lVolume, long lPan) +{ + BOOL bSuccess; + + /// ASSERT: assert(pSFX); + /// ASSERT: assert(pSFX->bFlags & sfx_STREAM); + + stream_stop(); + + lVolume += sound_get_or_set_sound_volume(1); + if(lVolume < VOLUME_MIN) { + return; + } + if(lVolume > VOLUME_MAX) { + lVolume = VOLUME_MAX; + } + +#ifdef _DEBUG + SFileEnableDirectAccess(FALSE); +#endif + bSuccess = SFileOpenFile(pSFX->pszName, &sghStream); +#ifdef _DEBUG + SFileEnableDirectAccess(TRUE); +#endif + + if(!bSuccess) { + sghStream = NULL; + return; + } + if(!SFileDdaBeginEx(sghStream, 0x40000, 0, 0, lVolume, lPan, 0)) { + stream_stop(); + return; + } + + sgpStreamSFX = pSFX; +} + +static void stream_update() +{ + DWORD dwStart, dwEnd; + + if(sghStream == NULL) { + return; + } + if(!SFileDdaGetPos(sghStream, &dwStart, &dwEnd)) { + return; + } + if(dwStart < dwEnd) { + return; + } + + stream_stop(); +} + +static void sfx_stop() +{ + int i; + TSFX *pSFX; + + pSFX = sgSFX; + i = NUM_SFX; + while(i--) { + if(pSFX->pSnd != NULL) { + snd_stop_snd(pSFX->pSnd); + } + pSFX++; + } +} + +void InitMonsterSND(int monst) +{ + int mtype, mode, nr; + TSnd *pSnd; + char *pszFile; + char szName[MAX_PATH]; + + if(!gbSndInited) { + return; + } + + mtype = Monsters[monst].mtype; + + for(mode = 0; mode < 4; mode++) { + if(monster_action_sounds[mode] == 's' && !monsterdata[mtype].snd_special) { + continue; + } + for(nr = 0; nr < 2; nr++) { + sprintf(szName, monsterdata[mtype].sndfile, monster_action_sounds[mode], nr + 1); + pszFile = (char *)DiabloAllocPtr(strlen(szName) + 1); + strcpy(pszFile, szName); + pSnd = sound_file_load(pszFile); + Monsters[monst].Snds[mode][nr] = pSnd; + if(pSnd == NULL) { + MemFreeDbg(pszFile); + } + } + } +} + +void FreeMonsterSnd() +{ + int mi, mode, nr; + TSnd *pSnd; + char *pszFile; + + for(mi = 0; mi < nummtypes; mi++) { + for(mode = 0; mode < 4; mode++) { + for(nr = 0; nr < 2; nr++) { + pSnd = Monsters[mi].Snds[mode][nr]; + if(pSnd == NULL) { + continue; + } + Monsters[mi].Snds[mode][nr] = NULL; + pszFile = pSnd->sound_path; + pSnd->sound_path = NULL; + sound_file_cleanup(pSnd); + MemFreeDbg(pszFile); + } + } + } +} + +static BOOL calc_snd_position(int x, int y, long *plVolume, long *plPan) +{ + long volume, pan; + + x -= plr[myplr].WorldX; + y -= plr[myplr].WorldY; + + pan = x - y; + *plPan = pan << 8; + if(abs(*plPan) > 6400) { + return FALSE; + } + + volume = abs(x) > abs(y) ? abs(x) : abs(y); + *plVolume = volume << 6; + if(*plVolume >= 6400) { + return FALSE; + } + + *plVolume = -*plVolume; + return TRUE; +} + +static void PlaySFX_priv(TSFX *pSFX, BOOL loc, int x, int y) +{ + long lPan, lVolume; + + if(plr[myplr].pLvlLoad != 0 && gbMaxPlayers != 1) { + return; + } + if(!gbSndInited || !gbSoundOn) { + return; + } + if(gbBufferMsgs != 0) { + return; + } + if(!(pSFX->bFlags & 3) && pSFX->pSnd != NULL && snd_playing(pSFX->pSnd)) { + return; + } + + lPan = 0; + lVolume = 0; + if(loc && !calc_snd_position(x, y, &lVolume, &lPan)) { + return; + } + + if(pSFX->bFlags & 1) { + stream_play(pSFX, lVolume, lPan); + } else { + if(pSFX->pSnd == NULL) { + pSFX->pSnd = sound_file_load(pSFX->pszName); + } + if(pSFX->pSnd != NULL) { + snd_play_snd(pSFX->pSnd, lVolume, lPan); + } + } +} + +void PlayEffect(int i, int mode) +{ + int mi, nr; + long lPan, lVolume; + TSnd *pSnd; + + if(plr[myplr].pLvlLoad != 0) { + return; + } + + nr = random(164, 2); + + if(!gbSndInited || !gbSoundOn) { + return; + } + if(gbBufferMsgs != 0) { + return; + } + + mi = monster[i]._mMTidx; + pSnd = Monsters[mi].Snds[mode][nr]; + if(pSnd == NULL) { +#ifdef _DEBUG + app_fatal("Monster sound problem\n:%s playing %i", Monsters[mi].MData->mName, mode); +#endif + return; + } + if(snd_playing(pSnd)) { + return; + } + if(!calc_snd_position(monster[i]._mx, monster[i]._my, &lVolume, &lPan)) { + return; + } + + snd_play_snd(pSnd, lVolume, lPan); +} + +static int RndSFX(int psfx) +{ + int nRand; + + if(psfx == PS_WARR69) { + nRand = 2; + } else if(psfx == PS_WARR14) { + nRand = 3; + } else if(psfx == PS_WARR15) { + nRand = 3; + } else if(psfx == PS_WARR16) { + nRand = 3; + } else if(psfx == PS_MAGE69) { + nRand = 2; + } else if(psfx == PS_ROGUE69) { + nRand = 2; + } else if(psfx == PS_SWING) { + nRand = 2; + } else if(psfx == LS_ACID) { + nRand = 2; + } else if(psfx == IS_FMAG) { + nRand = 2; + } else if(psfx == IS_MAGIC) { + nRand = 2; + } else if(psfx == IS_BHIT) { + nRand = 2; + } else if(psfx == PS_WARR2) { + nRand = 3; + } else { + return psfx; + } + + return random(165, nRand) + psfx; +} + +void PlaySFX(int psfx) +{ + psfx = RndSFX(psfx); + /// ASSERT: assert(psfx < NUM_SFX); + PlaySFX_priv(&sgSFX[psfx], FALSE, 0, 0); +} + +void PlaySfxLoc(int psfx, int x, int y) +{ + psfx = RndSFX(psfx); + /// ASSERT: assert(psfx < NUM_SFX); + + if(psfx >= PS_WALK1 && psfx <= PS_WALK4 && sgSFX[psfx].pSnd != NULL) { + sgSFX[psfx].pSnd->start_tc = 0; + } + + PlaySFX_priv(&sgSFX[psfx], TRUE, x, y); +} + +void sound_stop() +{ + int mi, mode, nr; + + snd_update(TRUE); + stream_stop(); + sfx_stop(); + + for(mi = 0; mi < nummtypes; mi++) { + for(mode = 0; mode < 4; mode++) { + for(nr = 0; nr < 2; nr++) { + snd_stop_snd(Monsters[mi].Snds[mode][nr]); + } + } + } +} + +void sound_update() +{ + if(!gbSndInited) { + return; + } + + snd_update(FALSE); + stream_update(); +} + +void effects_cleanup_sfx() +{ + int i; + + sound_stop(); + + for(i = 0; (DWORD)i < NUM_SFX; i++) { + if(sgSFX[i].pSnd == NULL) { + continue; + } + sound_file_cleanup(sgSFX[i].pSnd); + sgSFX[i].pSnd = NULL; + } +} + +static void priv_sound_init(BYTE bLoadMask) +{ + BYTE pc; + int i; + + if(!gbSndInited) { + return; + } + + pc = bLoadMask & (0x20 | 0x10 | 0x40); + bLoadMask ^= pc; + + for(i = 0; (DWORD)i < NUM_SFX; i++) { + if(sgSFX[i].pSnd != NULL) { + continue; + } + if(sgSFX[i].bFlags & 1) { + continue; + } + if(bLoadMask != 0 && !(sgSFX[i].bFlags & bLoadMask)) { + continue; + } + if(sgSFX[i].bFlags & (0x20 | 0x10 | 0x40) && !(sgSFX[i].bFlags & pc)) { + continue; + } + sgSFX[i].pSnd = sound_file_load(sgSFX[i].pszName); + } +} + +void sound_init() +{ + BYTE bLoadMask; + + bLoadMask = 0; + + if(gbMaxPlayers > 1) { + bLoadMask = 0x20 | 0x10 | 0x40; + } else { + if(plr[myplr]._pClass == PC_WARRIOR) { + bLoadMask = 0x20; + } else if(plr[myplr]._pClass == PC_ROGUE) { + bLoadMask = 0x10; + } else if(plr[myplr]._pClass == PC_SORCERER) { + bLoadMask = 0x40; + } else { + app_fatal("effects:1"); + } + } + + priv_sound_init(bLoadMask); +} + +void ui_sound_init() +{ + priv_sound_init(4); +} + +void __stdcall effects_play_sound(const char *pszFile) +{ + int i; + + if(!gbSndInited || !gbSoundOn) { + return; + } + + for(i = 0; (DWORD)i < NUM_SFX; i++) { + if(_strcmpi(sgSFX[i].pszName, pszFile) == 0 && sgSFX[i].pSnd != NULL) { + if(!snd_playing(sgSFX[i].pSnd)) { + snd_play_snd(sgSFX[i].pSnd, 0, 0); + } + return; + } + } +} diff --git a/2020_03_31/Source/effects.h b/2020_03_31/Source/effects.h new file mode 100644 index 00000000..1e3ac62c --- /dev/null +++ b/2020_03_31/Source/effects.h @@ -0,0 +1,32 @@ +//HEADER_GOES_HERE +#ifndef __EFFECTS_H__ +#define __EFFECTS_H__ + +extern int sfxdelay; // weak +extern int sfxdnum; +extern HANDLE sghStream; +extern TSFX *sgpStreamSFX; + +BOOL effect_is_playing(int nSFX); +void stream_stop(); +void InitMonsterSND(int monst); +void FreeMonsterSnd(); +void PlayEffect(int i, int mode); +void PlaySFX(int psfx); +void PlaySfxLoc(int psfx, int x, int y); +void sound_stop(); +void sound_update(); +void effects_cleanup_sfx(); +void sound_init(); +void ui_sound_init(); +void __stdcall effects_play_sound(const char *pszFile); + +/* rdata */ + +extern const char monster_action_sounds[]; // idb + +/* data */ + +extern TSFX sgSFX[NUM_SFX]; + +#endif /* __EFFECTS_H__ */ diff --git a/2020_03_31/Source/encrypt.cpp b/2020_03_31/Source/encrypt.cpp new file mode 100644 index 00000000..985ad284 --- /dev/null +++ b/2020_03_31/Source/encrypt.cpp @@ -0,0 +1,207 @@ +#include "diablo.h" +#include "../3rdParty/Pkware/implode.h" + +int hashtable[1280]; + +void Decrypt(void *block, int size, int key) +{ + unsigned int v3; // edx + int v4; // eax + unsigned int v5; // edi + unsigned int v6; // edx + int v7; // eax + int v8; // esi + + v3 = (unsigned int)size >> 2; + v4 = 0xEEEEEEEE; + if ( v3 ) + { + v5 = v3; + v6 = key; + do + { + v7 = hashtable[(unsigned char)v6 + 1024] + v4; + *(_DWORD *)block ^= v7 + v6; + v8 = *(_DWORD *)block; + block = (char *)block + 4; + v4 = 33 * v7 + v8 + 3; + v6 = ((~v6 << 21) + 0x11111111) | (v6 >> 11); + --v5; + } + while ( v5 ); + } +} + +void Encrypt(void *block, int size, int key) +{ + unsigned int v3; // edx + int v4; // eax + unsigned int v5; // edi + unsigned int v6; // edx + int v7; // eax + int v8; // ebx + + v3 = (unsigned int)size >> 2; + v4 = 0xEEEEEEEE; + if ( v3 ) + { + v5 = v3; + v6 = key; + do + { + v7 = hashtable[(unsigned char)v6 + 1024] + v4; + v8 = *(_DWORD *)block ^ (v7 + v6); + v4 = 33 * v7 + *(_DWORD *)block + 3; + *(_DWORD *)block = v8; + block = (char *)block + 4; + v6 = ((~v6 << 21) + 0x11111111) | (v6 >> 11); + --v5; + } + while ( v5 ); + } +} + +int Hash(char *s, int type) +{ + int v2; // ebp + char *v3; // ebx + signed int v4; // esi + int v5; // edi + int v6; // ST00_4 + char v7; // al + + v2 = type; + v3 = s; + v4 = 0x7FED7FED; + v5 = 0xEEEEEEEE; + while ( v3 && *v3 ) + { + v6 = *v3++; + v7 = toupper(v6); + v4 = (v5 + v4) ^ hashtable[v7 + (v2 << 8)]; + v5 = v7 + 33 * v5 + v4 + 3; + } + return v4; +} + +void InitHash() +{ + unsigned int v0; // eax + int *v1; // edi + unsigned int v2; // eax + int v3; // ecx + signed int v4; // [esp+Ch] [ebp-8h] + int *v5; // [esp+10h] [ebp-4h] + + v0 = 0x100001; + v5 = hashtable; + do + { + v1 = v5; + v4 = 5; + do + { + v2 = (125 * v0 + 3) % 0x2AAAAB; + v3 = (unsigned short)v2 << 16; + v0 = (125 * v2 + 3) % 0x2AAAAB; + *v1 = (unsigned short)v0 | v3; + v1 += 256; + --v4; + } + while ( v4 ); + ++v5; + } + while ( (signed int)v5 < (signed int)&hashtable[256] ); +} + +int PkwareCompress(void *buf, int size) +{ + unsigned char *v2; // ebx + unsigned char *v3; // esi + int v4; // ecx + unsigned char *v5; // edi + TDataInfo param; // [esp+Ch] [ebp-20h] + unsigned int type; // [esp+20h] [ebp-Ch] + unsigned int dsize; // [esp+24h] [ebp-8h] + char *ptr; // [esp+28h] [ebp-4h] + + v2 = (unsigned char *)buf; + v3 = (unsigned char *)size; + ptr = (char *)DiabloAllocPtr(CMP_BUFFER_SIZE); // 36312 + v4 = 2 * (_DWORD)v3; + if ( (unsigned int)(2 * (_DWORD)v3) < 0x2000 ) + v4 = 0x2000; + v5 = (unsigned char *)DiabloAllocPtr(v4); + param.pbInBuffEnd = 0; + param.pbOutBuffEnd = 0; + type = 0; + param.pbInBuff = v2; + param.pbOutBuff = v5; + param.pbSize = v3; + dsize = 4096; + implode( + PkwareBufferRead, + PkwareBufferWrite, + ptr, + ¶m, + &type, + &dsize); + if ( param.pbOutBuffEnd < v3 ) + { + memcpy(v2, v5, (size_t)param.pbOutBuffEnd); + v3 = param.pbOutBuffEnd; + } + mem_free_dbg(ptr); + mem_free_dbg(v5); + return (int)v3; +} + +unsigned int __cdecl PkwareBufferRead(char *buf, unsigned int *size, void *param) +{ + TDataInfo * pInfo = (TDataInfo *)param; + int v3; // edi + unsigned char *v4; // ecx + + v3 = *size; + v4 = pInfo->pbInBuffEnd; + if ( *size >= (unsigned int)(pInfo->pbSize - v4) ) + v3 = pInfo->pbSize - v4; + memcpy(buf, &v4[(unsigned int)pInfo->pbInBuff], v3); + pInfo->pbInBuffEnd += v3; + return v3; +} + +void __cdecl PkwareBufferWrite(char *buf, unsigned int *size, void *param) +{ + TDataInfo * pInfo = (TDataInfo *)param; + + memcpy(&pInfo->pbOutBuffEnd[(unsigned int)pInfo->pbOutBuff], buf, *size); + pInfo->pbOutBuffEnd += *size; +} + +void PkwareDecompress(void *param, int recv_size, int dwMaxBytes) +{ + unsigned char *v3; // edi + unsigned char *v4; // ebx + unsigned char *v5; // esi + TDataInfo info; // [esp+Ch] [ebp-18h] + char *ptr; // [esp+20h] [ebp-4h] + + v3 = (unsigned char *)param; + v4 = (unsigned char *)recv_size; + ptr = (char *)DiabloAllocPtr(CMP_BUFFER_SIZE); // 36312 + v5 = (unsigned char *)DiabloAllocPtr(dwMaxBytes); + info.pbInBuffEnd = 0; + info.pbOutBuffEnd = 0; + info.pbInBuff = v3; + info.pbOutBuff = v5; + info.pbSize = v4; + explode( + PkwareBufferRead, + PkwareBufferWrite, + ptr, + &info); + memcpy(v3, v5, (size_t)info.pbOutBuffEnd); + mem_free_dbg(ptr); + mem_free_dbg(v5); +} diff --git a/2020_03_31/Source/encrypt.h b/2020_03_31/Source/encrypt.h new file mode 100644 index 00000000..b78245f8 --- /dev/null +++ b/2020_03_31/Source/encrypt.h @@ -0,0 +1,16 @@ +//HEADER_GOES_HERE +#ifndef __ENCRYPT_H__ +#define __ENCRYPT_H__ + +extern int hashtable[1280]; + +void Decrypt(void *block, int size, int key); +void Encrypt(void *block, int size, int key); +int Hash(char *s, int type); +void InitHash(); +int PkwareCompress(void *buf, int size); +unsigned int __cdecl PkwareBufferRead(char *buf, unsigned int *size, void *param); +void __cdecl PkwareBufferWrite(char *buf, unsigned int *size, void *param); +void PkwareDecompress(void *param, int recv_size, int dwMaxBytes); + +#endif /* __ENCRYPT_H__ */ diff --git a/2020_03_31/Source/engine.cpp b/2020_03_31/Source/engine.cpp new file mode 100644 index 00000000..36510b25 --- /dev/null +++ b/2020_03_31/Source/engine.cpp @@ -0,0 +1,3859 @@ +#include "diablo.h" +#include "../3rdParty/Storm/Source/storm.h" + +#ifdef USE_ASM +#pragma warning (disable : 4731) // frame pointer register 'ebp' modified by inline assembly code +#endif + +char gbPixelCol; // automap pixel color 8-bit (palette entry) +int gbRotateMap; // _bool flip - if y < x +int orgseed; // weak +int sgnWidth; +int sglGameSeed; // weak +static CCritSect sgMemCrit; +int SeedCount; // weak +int gbNotInView; // _bool valid - if x/y are in bounds + +const int rand_increment = 1; +const int rand_multiplier = 0x015A4E35; + +void CelDrawDatOnly(BYTE *pDecodeTo, BYTE *pRLEBytes, int nDataSize, int nWidth) +{ + int w; + + /// ASSERT: assert(pDecodeTo != NULL); + if(!pDecodeTo) + return; + /// ASSERT: assert(pRLEBytes != NULL); + if(!pRLEBytes) + return; + +#ifdef USE_ASM + __asm { + mov esi, pRLEBytes + mov edi, pDecodeTo + mov eax, 768 + add eax, nWidth + mov w, eax + mov ebx, nDataSize + add ebx, esi + label1: + mov edx, nWidth + label2: + xor eax, eax + lodsb + or al, al + js label6 + sub edx, eax + mov ecx, eax + shr ecx, 1 + jnb label3 + movsb + jecxz label5 + label3: + shr ecx, 1 + jnb label4 + movsw + jecxz label5 + label4: + rep movsd + label5: + or edx, edx + jz label7 + jmp label2 + label6: + neg al + add edi, eax + sub edx, eax + jnz label2 + label7: + sub edi, w + cmp ebx, esi + jnz label1 + } +#else + int i; + BYTE width; + BYTE *src, *dst; + + src = pRLEBytes; + dst = pDecodeTo; + w = nWidth; + + for(; src != &pRLEBytes[nDataSize]; dst -= 768 + w) { + for(i = w; i;) { + width = *src++; + if(!(width & 0x80)) { + i -= width; + if(width & 1) { + dst[0] = src[0]; + src++; + dst++; + } + width >>= 1; + if(width & 1) { + dst[0] = src[0]; + dst[1] = src[1]; + src += 2; + dst += 2; + } + width >>= 1; + for(; width; width--) { + dst[0] = src[0]; + dst[1] = src[1]; + dst[2] = src[2]; + dst[3] = src[3]; + src += 4; + dst += 4; + } + } else { + width = -(char)width; + dst += width; + i -= width; + } + } + } +#endif +} + +void CelDecodeOnly(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth) +{ + int nDataSize; + BYTE *pDecodeTo, *pRLEBytes; + DWORD *pFrameTable; + + /// ASSERT: assert(gpBuffer); + if(gpBuffer == NULL) { + return; + } + /// ASSERT: assert(pCelBuff != NULL); + if(pCelBuff == NULL) { + return; + } + + pFrameTable = (DWORD *)pCelBuff; + nDataSize = pFrameTable[nCel + 1] - pFrameTable[nCel]; + pRLEBytes = &pCelBuff[pFrameTable[nCel]]; + pDecodeTo = &gpBuffer[sx + PitchTbl[sy]]; + + CelDrawDatOnly(pDecodeTo, pRLEBytes, nDataSize, nWidth); +} + +void CelDecDatOnly(BYTE *pBuff, BYTE *pCelBuff, int nCel, int nWidth) +{ + int nDataSize; + BYTE *pRLEBytes; + DWORD *pFrameTable; + + /// ASSERT: assert(pCelBuff != NULL); + if(pCelBuff == NULL) { + return; + } + /// ASSERT: assert(pBuff != NULL); + if(pBuff == NULL) { + return; + } + + pFrameTable = (DWORD *)pCelBuff; + nDataSize = pFrameTable[nCel + 1] - pFrameTable[nCel]; + pRLEBytes = &pCelBuff[pFrameTable[nCel]]; + + CelDrawDatOnly(pBuff, pRLEBytes, nDataSize, nWidth); +} + +void CelDrawHdrOnly(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth, int always_0, int dir) +{ + int hdr, v2, nDataSize; + BYTE *pDecodeTo, *pRLEBytes; + DWORD *pFrameTable; + + /// ASSERT: assert(gpBuffer); + if(gpBuffer == NULL) { + return; + } + /// ASSERT: assert(pCelBuff != NULL); + if(pCelBuff == NULL) { + return; + } + + pFrameTable = (DWORD *)pCelBuff; + pRLEBytes = &pCelBuff[pFrameTable[nCel]]; + hdr = ((WORD *)&pRLEBytes[always_0])[0]; + + if(hdr == 0) { + return; + } + + nDataSize = pFrameTable[nCel + 1] - pFrameTable[nCel]; + + if(dir == 8) { + v2 = 0; + } else { + v2 = ((WORD *)&pRLEBytes[dir])[0]; + } + if(v2 != 0) { + nDataSize = v2 - hdr; + } else { + nDataSize -= hdr; + } + + pRLEBytes += hdr; + pDecodeTo = &gpBuffer[sx + PitchTbl[sy - 16 * always_0]]; + + CelDrawDatOnly(pDecodeTo, pRLEBytes, nDataSize, nWidth); +} + +void CelDecodeHdrOnly(BYTE *pBuff, BYTE *pCelBuff, int nCel, int nWidth, int always_0, int dir) +{ + int hdr, v2, nDataSize; + BYTE *pRLEBytes; + DWORD *pFrameTable; + + /// ASSERT: assert(pCelBuff != NULL); + if(pCelBuff == NULL) { + return; + } + /// ASSERT: assert(pBuff != NULL); + if(pBuff == NULL) { + return; + } + + pFrameTable = (DWORD *)pCelBuff; + pRLEBytes = &pCelBuff[pFrameTable[nCel]]; + hdr = ((WORD *)&pRLEBytes[always_0])[0]; + + if(hdr == 0) { + return; + } + + nDataSize = pFrameTable[nCel + 1] - pFrameTable[nCel]; + + if(dir == 8) { + v2 = 0; + } else { + v2 = ((WORD *)&pRLEBytes[dir])[0]; + } + if(v2 != 0) { + nDataSize = v2 - hdr; + } else { + nDataSize -= hdr; + } + + pRLEBytes += hdr; + + CelDrawDatOnly(pBuff, pRLEBytes, nDataSize, nWidth); +} + +void CelDecDatLightOnly(BYTE *pDecodeTo, BYTE *pRLEBytes, int nDataSize, int nWidth) +{ + int w; + BYTE *tbl; + + /// ASSERT: assert(pDecodeTo != NULL); + if(!pDecodeTo) + return; + /// ASSERT: assert(pRLEBytes != NULL); + if(!pRLEBytes) + return; + +#ifdef USE_ASM + __asm { + mov eax, light_table_index + shl eax, 8 + add eax, pLightTbl + mov tbl, eax + mov esi, pRLEBytes + mov edi, pDecodeTo + mov eax, 768 + add eax, nWidth + mov w, eax + mov ebx, nDataSize + add ebx, esi + label1: + mov edx, nWidth + label2: + xor eax, eax + lodsb + or al, al + js label3 + push ebx + mov ebx, tbl + sub edx, eax + mov ecx, eax + push edx + call CelDecDatLightEntry + pop edx + pop ebx + or edx, edx + jnz label2 + jmp label4 + label3: + neg al + add edi, eax + sub edx, eax + jnz label2 + label4: + sub edi, w + cmp ebx, esi + jnz label1 + jmp labexit + } + + /* Assembly Macro */ + __asm { + CelDecDatLightEntry: + shr cl, 1 + jnb label5 + mov dl, [esi] + mov dl, [ebx+edx] + mov [edi], dl + add esi, 1 + add edi, 1 + label5: + shr cl, 1 + jnb label6 + mov dl, [esi] + mov ch, [ebx+edx] + mov [edi], ch + mov dl, [esi+1] + mov ch, [ebx+edx] + mov [edi+1], ch + add esi, 2 + add edi, 2 + label6: + test cl, cl + jz labret + label7: + mov eax, [esi] + add esi, 4 + mov dl, al + mov ch, [ebx+edx] + mov dl, ah + ror eax, 10h + mov [edi], ch + mov ch, [ebx+edx] + mov dl, al + mov [edi+1], ch + mov ch, [ebx+edx] + mov dl, ah + mov [edi+2], ch + mov ch, [ebx+edx] + mov [edi+3], ch + add edi, 4 + dec cl + jnz label7 + labret: + retn + } + + __asm { + labexit: + } +#else + int i; + BYTE width; + BYTE *src, *dst; + + src = pRLEBytes; + dst = pDecodeTo; + tbl = &pLightTbl[light_table_index * 256]; + w = nWidth; + + for(; src != &pRLEBytes[nDataSize]; dst -= 768 + w) { + for(i = w; i;) { + width = *src++; + if(!(width & 0x80)) { + i -= width; + if(width & 1) { + dst[0] = tbl[src[0]]; + src++; + dst++; + } + width >>= 1; + if(width & 1) { + dst[0] = tbl[src[0]]; + dst[1] = tbl[src[1]]; + src += 2; + dst += 2; + } + width >>= 1; + for(; width; width--) { + dst[0] = tbl[src[0]]; + dst[1] = tbl[src[1]]; + dst[2] = tbl[src[2]]; + dst[3] = tbl[src[3]]; + src += 4; + dst += 4; + } + } else { + width = -(char)width; + dst += width; + i -= width; + } + } + } +#endif +} + +void CelDecDatLightTrans(BYTE *pDecodeTo, BYTE *pRLEBytes, int nDataSize, int nWidth) +{ + int w; + BOOL shift; + BYTE *tbl; + + /// ASSERT: assert(pDecodeTo != NULL); + if(!pDecodeTo) + return; + /// ASSERT: assert(pRLEBytes != NULL); + if(!pRLEBytes) + return; + +#ifdef USE_ASM + __asm { + mov eax, light_table_index + shl eax, 8 + add eax, pLightTbl + mov tbl, eax + mov esi, pRLEBytes + mov edi, pDecodeTo + mov eax, 768 + add eax, nWidth + mov w, eax + mov ebx, nDataSize + add ebx, esi + mov eax, edi + and eax, 1 + mov shift, eax + label1: + mov edx, nWidth + label2: + xor eax, eax + lodsb + or al, al + js label9 + push ebx + mov ebx, tbl + sub edx, eax + mov ecx, eax + mov eax, edi + and eax, 1 + cmp eax, shift + jnz label5 + shr ecx, 1 + jnb label3 + inc esi + inc edi + jecxz label8 + jmp label6 + label3: + shr ecx, 1 + jnb label4 + inc esi + inc edi + lodsb + xlat + stosb + jecxz label8 + label4: + lodsd + inc edi + ror eax, 8 + xlat + stosb + ror eax, 10h + inc edi + xlat + stosb + loop label4 + jmp label8 + label5: + shr ecx, 1 + jnb label6 + lodsb + xlat + stosb + jecxz label8 + jmp label3 + label6: + shr ecx, 1 + jnb label7 + lodsb + xlat + stosb + inc esi + inc edi + jecxz label8 + label7: + lodsd + xlat + stosb + inc edi + ror eax, 10h + xlat + stosb + inc edi + loop label7 + label8: + pop ebx + or edx, edx + jz label10 + jmp label2 + label9: + neg al + add edi, eax + sub edx, eax + jnz label2 + label10: + sub edi, w + mov eax, shift + inc eax + and eax, 1 + mov shift, eax + cmp ebx, esi + jnz label1 + } +#else + int i; + BYTE width; + BYTE *src, *dst; + + src = pRLEBytes; + dst = pDecodeTo; + tbl = &pLightTbl[light_table_index * 256]; + w = nWidth; + shift = (BYTE)dst & 1; + + for(; src != &pRLEBytes[nDataSize]; dst -= 768 + w, shift = (shift + 1) & 1) { + for(i = w; i;) { + width = *src++; + if(!(width & 0x80)) { + i -= width; + if(((BYTE)dst & 1) == shift) { + if(!(width & 1)) { + goto L_ODD; + } else { + src++; + dst++; +L_EVEN: + width >>= 1; + if(width & 1) { + dst[0] = tbl[src[0]]; + src += 2; + dst += 2; + } + width >>= 1; + for(; width; width--) { + dst[0] = tbl[src[0]]; + dst[2] = tbl[src[2]]; + src += 4; + dst += 4; + } + } + } else { + if(!(width & 1)) { + goto L_EVEN; + } else { + dst[0] = tbl[src[0]]; + src++; + dst++; +L_ODD: + width >>= 1; + if(width & 1) { + dst[1] = tbl[src[1]]; + src += 2; + dst += 2; + } + width >>= 1; + for(; width; width--) { + dst[1] = tbl[src[1]]; + dst[3] = tbl[src[3]]; + src += 4; + dst += 4; + } + } + } + } else { + width = -(char)width; + dst += width; + i -= width; + } + } + } +#endif +} + +void CelDecodeLightOnly(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth) +{ + int nDataSize; + BYTE *pDecodeTo, *pRLEBytes; + DWORD *pFrameTable; + + /// ASSERT: assert(gpBuffer); + if(gpBuffer == NULL) { + return; + } + /// ASSERT: assert(pCelBuff != NULL); + if(pCelBuff == NULL) { + return; + } + + pFrameTable = (DWORD *)pCelBuff; + nDataSize = pFrameTable[nCel + 1] - pFrameTable[nCel]; + pRLEBytes = &pCelBuff[pFrameTable[nCel]]; + pDecodeTo = &gpBuffer[sx + PitchTbl[sy]]; + + if(light_table_index != 0) { + CelDecDatLightOnly(pDecodeTo, pRLEBytes, nDataSize, nWidth); + } else { + CelDrawDatOnly(pDecodeTo, pRLEBytes, nDataSize, nWidth); + } +} + +void CelDecodeHdrLightOnly(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth, int always_0, int dir) +{ + int hdr, v2, nDataSize; + BYTE *pDecodeTo, *pRLEBytes; + DWORD *pFrameTable; + + /// ASSERT: assert(gpBuffer); + if(gpBuffer == NULL) { + return; + } + /// ASSERT: assert(pCelBuff != NULL); + if(pCelBuff == NULL) { + return; + } + + pFrameTable = (DWORD *)pCelBuff; + pRLEBytes = &pCelBuff[pFrameTable[nCel]]; + hdr = ((WORD *)&pRLEBytes[always_0])[0]; + + if(hdr == 0) { + return; + } + + nDataSize = pFrameTable[nCel + 1] - pFrameTable[nCel]; + + if(dir == 8) { + v2 = 0; + } else { + v2 = ((WORD *)&pRLEBytes[dir])[0]; + } + if(v2 != 0) { + nDataSize = v2 - hdr; + } else { + nDataSize -= hdr; + } + + pRLEBytes += hdr; + pDecodeTo = &gpBuffer[sx + PitchTbl[sy - 16 * always_0]]; + + if(light_table_index != 0) { + CelDecDatLightOnly(pDecodeTo, pRLEBytes, nDataSize, nWidth); + } else { + CelDrawDatOnly(pDecodeTo, pRLEBytes, nDataSize, nWidth); + } +} + +void CelDecodeHdrLightTrans(BYTE *pBuff, BYTE *pCelBuff, int nCel, int nWidth, int always_0, int dir) +{ + int hdr, v2, nDataSize; + BYTE *pRLEBytes; + DWORD *pFrameTable; + + /// ASSERT: assert(pCelBuff != NULL); + if(pCelBuff == NULL) { + return; + } + /// ASSERT: assert(pBuff != NULL); + if(pBuff == NULL) { + return; + } + + pFrameTable = (DWORD *)pCelBuff; + pRLEBytes = &pCelBuff[pFrameTable[nCel]]; + hdr = ((WORD *)&pRLEBytes[always_0])[0]; + + if(hdr == 0) { + return; + } + + nDataSize = pFrameTable[nCel + 1] - pFrameTable[nCel]; + + if(dir == 8) { + v2 = 0; + } else { + v2 = ((WORD *)&pRLEBytes[dir])[0]; + } + if(v2 != 0) { + nDataSize = v2 - hdr; + } else { + nDataSize -= hdr; + } + + pRLEBytes += hdr; + + if(cel_transparency_active) { + CelDecDatLightTrans(pBuff, pRLEBytes, nDataSize, nWidth); + } else if(light_table_index != 0) { + CelDecDatLightOnly(pBuff, pRLEBytes, nDataSize, nWidth); + } else { + CelDrawDatOnly(pBuff, pRLEBytes, nDataSize, nWidth); + } +} + +void CelDrawHdrLightRed(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth, int always_0, int dir, char light) +{ + int w, idx, hdr, v2, nDataSize; + BYTE *src, *dst, *tbl; + DWORD *pFrameTable; + + /// ASSERT: assert(gpBuffer); + if(gpBuffer == NULL) { + return; + } + /// ASSERT: assert(pCelBuff != NULL); + if(pCelBuff == NULL) { + return; + } + + pFrameTable = (DWORD *)pCelBuff; + src = &pCelBuff[pFrameTable[nCel]]; + hdr = ((WORD *)&src[always_0])[0]; + + if(hdr == 0) { + return; + } + + nDataSize = pFrameTable[nCel + 1] - pFrameTable[nCel]; + + if(dir == 8) { + v2 = 0; + } else { + v2 = ((WORD *)&src[dir])[0]; + } + if(v2 != 0) { + nDataSize = v2 - hdr; + } else { + nDataSize -= hdr; + } + + src += hdr; + dst = &gpBuffer[sx + PitchTbl[sy - 16 * always_0]]; + + idx = light4flag ? 1024 : 4096; + if(light == 2) { + idx += 256; + } + if(light >= 4) { + idx += (light - 1) << 8; + } + +#ifdef USE_ASM + __asm { + mov eax, pLightTbl + add eax, idx + mov tbl, eax + mov esi, src + mov edi, dst + mov eax, 768 + add eax, nWidth + mov w, eax + mov ebx, nDataSize + add ebx, esi + label1: + mov edx, nWidth + label2: + xor eax, eax + mov al, [esi] + inc esi + test al, al + js label4 + push ebx + mov ebx, tbl + sub edx, eax + mov ecx, eax + label3: + mov al, [esi] + inc esi + mov al, [ebx+eax] + mov [edi], al + dec ecx + lea edi, [edi+1] + jnz label3 + pop ebx + test edx, edx + jz label5 + jmp label2 + label4: + neg al + add edi, eax + sub edx, eax + jnz label2 + label5: + sub edi, w + cmp ebx, esi + jnz label1 + } +#else + BYTE width; + BYTE *end; + + tbl = &pLightTbl[idx]; + end = &src[nDataSize]; + + for(; src != end; dst -= 768 + nWidth) { + for(w = nWidth; w;) { + width = *src++; + if(!(width & 0x80)) { + w -= width; + while(width) { + *dst = tbl[*src]; + src++; + dst++; + width--; + } + } else { + width = -(char)width; + dst += width; + w -= width; + } + } + } +#endif +} + +void Cel2DecDatOnly(BYTE *pDecodeTo, BYTE *pRLEBytes, int nDataSize, int nWidth) +{ + int w; + + /// ASSERT: assert(pDecodeTo != NULL); + if(!pDecodeTo) + return; + /// ASSERT: assert(pRLEBytes != NULL); + if(!pRLEBytes) + return; + /// ASSERT: assert(gpBuffer); + if(!gpBuffer) + return; + +#ifdef USE_ASM + __asm { + mov esi, pRLEBytes + mov edi, pDecodeTo + mov eax, 768 + add eax, nWidth + mov w, eax + mov ebx, nDataSize + add ebx, esi + label1: + mov edx, nWidth + label2: + xor eax, eax + lodsb + or al, al + js label7 + sub edx, eax + cmp edi, gpBufEnd + jb label3 + add esi, eax + add edi, eax + jmp label6 + label3: + mov ecx, eax + shr ecx, 1 + jnb label4 + movsb + jecxz label6 + label4: + shr ecx, 1 + jnb label5 + movsw + jecxz label6 + label5: + rep movsd + label6: + or edx, edx + jz label8 + jmp label2 + label7: + neg al + add edi, eax + sub edx, eax + jnz label2 + label8: + sub edi, w + cmp ebx, esi + jnz label1 + } +#else + int i; + BYTE width; + BYTE *src, *dst; + + src = pRLEBytes; + dst = pDecodeTo; + w = nWidth; + + for(; src != &pRLEBytes[nDataSize]; dst -= 768 + w) { + for(i = w; i;) { + width = *src++; + if(!(width & 0x80)) { + i -= width; + if(dst < gpBufEnd) { + if(width & 1) { + dst[0] = src[0]; + src++; + dst++; + } + width >>= 1; + if(width & 1) { + dst[0] = src[0]; + dst[1] = src[1]; + src += 2; + dst += 2; + } + width >>= 1; + for(; width; width--) { + dst[0] = src[0]; + dst[1] = src[1]; + dst[2] = src[2]; + dst[3] = src[3]; + src += 4; + dst += 4; + } + } else { + src += width; + dst += width; + } + } else { + width = -(char)width; + dst += width; + i -= width; + } + } + } +#endif +} + +void Cel2DrawHdrOnly(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth, int always_0, int dir) +{ + int hdr, v2, nDataSize; + BYTE *pDecodeTo, *pRLEBytes; + DWORD *pFrameTable; + + /// ASSERT: assert(gpBuffer); + if(gpBuffer == NULL) { + return; + } + /// ASSERT: assert(pCelBuff != NULL); + if(pCelBuff == NULL) { + return; + } + + pFrameTable = (DWORD *)pCelBuff; + pRLEBytes = &pCelBuff[pFrameTable[nCel]]; + hdr = ((WORD *)&pRLEBytes[always_0])[0]; + + if(hdr == 0) { + return; + } + + nDataSize = pFrameTable[nCel + 1] - pFrameTable[nCel]; + + if(dir == 8) { + v2 = 0; + } else { + v2 = ((WORD *)&pRLEBytes[dir])[0]; + } + if(v2 != 0) { + nDataSize = v2 - hdr; + } else { + nDataSize -= hdr; + } + + pRLEBytes += hdr; + pDecodeTo = &gpBuffer[sx + PitchTbl[sy - 16 * always_0]]; + + Cel2DecDatOnly(pDecodeTo, pRLEBytes, nDataSize, nWidth); +} + +void Cel2DecodeHdrOnly(BYTE *pBuff, BYTE *pCelBuff, int nCel, int nWidth, int always_0, int dir) +{ + int hdr, v2, nDataSize; + BYTE *pRLEBytes; + DWORD *pFrameTable; + + /// ASSERT: assert(pCelBuff != NULL); + if(pCelBuff == NULL) { + return; + } + /// ASSERT: assert(pBuff != NULL); + if(pBuff == NULL) { + return; + } + + pFrameTable = (DWORD *)pCelBuff; + pRLEBytes = &pCelBuff[pFrameTable[nCel]]; + hdr = ((WORD *)&pRLEBytes[always_0])[0]; + + if(hdr == 0) { + return; + } + + nDataSize = pFrameTable[nCel + 1] - pFrameTable[nCel]; + + v2 = ((WORD *)&pRLEBytes[dir])[0]; + if(dir == 8) { + v2 = 0; + } + if(v2 != 0) { + nDataSize = v2 - hdr; + } else { + nDataSize -= hdr; + } + + pRLEBytes += hdr; + + Cel2DecDatOnly(pBuff, pRLEBytes, nDataSize, nWidth); +} + +void Cel2DecDatLightOnly(BYTE *pDecodeTo, BYTE *pRLEBytes, int nDataSize, int nWidth) +{ + int w; + BYTE *tbl; + + /// ASSERT: assert(pDecodeTo != NULL); + if(!pDecodeTo) + return; + /// ASSERT: assert(pRLEBytes != NULL); + if(!pRLEBytes) + return; + /// ASSERT: assert(gpBuffer); + if(!gpBuffer) + return; + +#ifdef USE_ASM + __asm { + mov eax, light_table_index + shl eax, 8 + add eax, pLightTbl + mov tbl, eax + mov esi, pRLEBytes + mov edi, pDecodeTo + mov eax, 768 + add eax, nWidth + mov w, eax + mov ebx, nDataSize + add ebx, esi + label1: + mov edx, nWidth + label2: + xor eax, eax + lodsb + or al, al + js label5 + push ebx + mov ebx, tbl + sub edx, eax + cmp edi, gpBufEnd + jb label3 + add esi, eax + add edi, eax + jmp label4 + label3: + mov ecx, eax + push edx + call Cel2DecDatLightEntry + pop edx + label4: + pop ebx + or edx, edx + jz label6 + jmp label2 + label5: + neg al + add edi, eax + sub edx, eax + jnz label2 + label6: + sub edi, w + cmp ebx, esi + jnz label1 + jmp labexit + } + + /* Assembly Macro */ + __asm { + Cel2DecDatLightEntry: + shr cl, 1 + jnb label7 + mov dl, [esi] + mov dl, [ebx+edx] + mov [edi], dl + add esi, 1 + add edi, 1 + label7: + shr cl, 1 + jnb label8 + mov dl, [esi] + mov ch, [ebx+edx] + mov [edi], ch + mov dl, [esi+1] + mov ch, [ebx+edx] + mov [edi+1], ch + add esi, 2 + add edi, 2 + label8: + test cl, cl + jz labret + label9: + mov eax, [esi] + add esi, 4 + mov dl, al + mov ch, [ebx+edx] + mov dl, ah + ror eax, 10h + mov [edi], ch + mov ch, [ebx+edx] + mov dl, al + mov [edi+1], ch + mov ch, [ebx+edx] + mov dl, ah + mov [edi+2], ch + mov ch, [ebx+edx] + mov [edi+3], ch + add edi, 4 + dec cl + jnz label9 + labret: + retn + } + + __asm { + labexit: + } +#else + int i; + BYTE width; + BYTE *src, *dst; + + src = pRLEBytes; + dst = pDecodeTo; + tbl = &pLightTbl[light_table_index * 256]; + w = nWidth; + + for(; src != &pRLEBytes[nDataSize]; dst -= 768 + w) { + for(i = w; i;) { + width = *src++; + if(!(width & 0x80)) { + i -= width; + if(dst < gpBufEnd) { + if(width & 1) { + dst[0] = tbl[src[0]]; + src++; + dst++; + } + width >>= 1; + if(width & 1) { + dst[0] = tbl[src[0]]; + dst[1] = tbl[src[1]]; + src += 2; + dst += 2; + } + width >>= 1; + for(; width; width--) { + dst[0] = tbl[src[0]]; + dst[1] = tbl[src[1]]; + dst[2] = tbl[src[2]]; + dst[3] = tbl[src[3]]; + src += 4; + dst += 4; + } + } else { + src += width; + dst += width; + } + } else { + width = -(char)width; + dst += width; + i -= width; + } + } + } +#endif +} + +void Cel2DecDatLightTrans(BYTE *pDecodeTo, BYTE *pRLEBytes, int nDataSize, int nWidth) +{ + int w; + BOOL shift; + BYTE *tbl; + + /// ASSERT: assert(pDecodeTo != NULL); + if(!pDecodeTo) + return; + /// ASSERT: assert(pRLEBytes != NULL); + if(!pRLEBytes) + return; + /// ASSERT: assert(gpBuffer); + if(!gpBuffer) + return; + +#ifdef USE_ASM + __asm { + mov eax, light_table_index + shl eax, 8 + add eax, pLightTbl + mov tbl, eax + mov esi, pRLEBytes + mov edi, pDecodeTo + mov eax, 768 + add eax, nWidth + mov w, eax + mov ebx, nDataSize + add ebx, esi + mov eax, edi + and eax, 1 + mov shift, eax + label1: + mov edx, nWidth + label2: + xor eax, eax + lodsb + or al, al + js label10 + push ebx + mov ebx, tbl + sub edx, eax + cmp edi, gpBufEnd + jb label3 + add esi, eax + add edi, eax + jmp label9 + label3: + mov ecx, eax + mov eax, edi + and eax, 1 + cmp eax, shift + jnz label6 + shr ecx, 1 + jnb label4 + inc esi + inc edi + jecxz label9 + jmp label7 + label4: + shr ecx, 1 + jnb label5 + inc esi + inc edi + lodsb + xlat + stosb + jecxz label9 + label5: + lodsd + inc edi + ror eax, 8 + xlat + stosb + ror eax, 10h + inc edi + xlat + stosb + loop label5 + jmp label9 + label6: + shr ecx, 1 + jnb label7 + lodsb + xlat + stosb + jecxz label9 + jmp label4 + label7: + shr ecx, 1 + jnb label8 + lodsb + xlat + stosb + inc esi + inc edi + jecxz label9 + label8: + lodsd + xlat + stosb + inc edi + ror eax, 10h + xlat + stosb + inc edi + loop label8 + label9: + pop ebx + or edx, edx + jz label11 + jmp label2 + label10: + neg al + add edi, eax + sub edx, eax + jnz label2 + label11: + sub edi, w + mov eax, shift + inc eax + and eax, 1 + mov shift, eax + cmp ebx, esi + jnz label1 + } +#else + int i; + BYTE width; + BYTE *src, *dst; + + src = pRLEBytes; + dst = pDecodeTo; + tbl = &pLightTbl[light_table_index * 256]; + w = nWidth; + shift = (BYTE)dst & 1; + + for(; src != &pRLEBytes[nDataSize]; dst -= 768 + w, shift = (shift + 1) & 1) { + for(i = w; i;) { + width = *src++; + if(!(width & 0x80)) { + i -= width; + if(dst < gpBufEnd) { + if(((BYTE)dst & 1) == shift) { + if(!(width & 1)) { + goto L_ODD; + } else { + src++; + dst++; +L_EVEN: + width >>= 1; + if(width & 1) { + dst[0] = tbl[src[0]]; + src += 2; + dst += 2; + } + width >>= 1; + for(; width; width--) { + dst[0] = tbl[src[0]]; + dst[2] = tbl[src[2]]; + src += 4; + dst += 4; + } + } + } else { + if(!(width & 1)) { + goto L_EVEN; + } else { + dst[0] = tbl[src[0]]; + src++; + dst++; +L_ODD: + width >>= 1; + if(width & 1) { + dst[1] = tbl[src[1]]; + src += 2; + dst += 2; + } + width >>= 1; + for(; width; width--) { + dst[1] = tbl[src[1]]; + dst[3] = tbl[src[3]]; + src += 4; + dst += 4; + } + } + } + } else { + src += width; + dst += width; + } + } else { + width = -(char)width; + dst += width; + i -= width; + } + } + } +#endif +} + +void Cel2DecodeHdrLight(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth, int always_0, int dir) +{ + int hdr, v2, nDataSize; + BYTE *pDecodeTo, *pRLEBytes; + DWORD *pFrameTable; + + /// ASSERT: assert(gpBuffer); + if(gpBuffer == NULL) { + return; + } + /// ASSERT: assert(pCelBuff != NULL); + if(pCelBuff == NULL) { + return; + } + + pFrameTable = (DWORD *)pCelBuff; + pRLEBytes = &pCelBuff[pFrameTable[nCel]]; + hdr = ((WORD *)&pRLEBytes[always_0])[0]; + + if(hdr == 0) { + return; + } + + nDataSize = pFrameTable[nCel + 1] - pFrameTable[nCel]; + + v2 = ((WORD *)&pRLEBytes[dir])[0]; + if(dir == 8) { + v2 = 0; + } + if(v2 != 0) { + nDataSize = v2 - hdr; + } else { + nDataSize -= hdr; + } + + pRLEBytes += hdr; + pDecodeTo = &gpBuffer[sx + PitchTbl[sy - 16 * always_0]]; + + if(light_table_index != 0) { + Cel2DecDatLightOnly(pDecodeTo, pRLEBytes, nDataSize, nWidth); + } else { + Cel2DecDatOnly(pDecodeTo, pRLEBytes, nDataSize, nWidth); + } +} + +void Cel2DecodeLightTrans(BYTE *pBuff, BYTE *pCelBuff, int nCel, int nWidth, int always_0, int dir) +{ + int hdr, v2, nDataSize; + BYTE *pRLEBytes; + DWORD *pFrameTable; + + /// ASSERT: assert(pCelBuff != NULL); + if(pCelBuff == NULL) { + return; + } + + pFrameTable = (DWORD *)pCelBuff; + pRLEBytes = &pCelBuff[pFrameTable[nCel]]; + hdr = ((WORD *)&pRLEBytes[always_0])[0]; + + if(hdr == 0) { + return; + } + + nDataSize = pFrameTable[nCel + 1] - pFrameTable[nCel]; + + v2 = ((WORD *)&pRLEBytes[dir])[0]; + if(dir == 8) { + v2 = 0; + } + if(v2 != 0) { + nDataSize = v2 - hdr; + } else { + nDataSize -= hdr; + } + + pRLEBytes += hdr; + + if(cel_transparency_active) { + Cel2DecDatLightTrans(pBuff, pRLEBytes, nDataSize, nWidth); + } else if(light_table_index != 0) { + Cel2DecDatLightOnly(pBuff, pRLEBytes, nDataSize, nWidth); + } else { + Cel2DecDatOnly(pBuff, pRLEBytes, nDataSize, nWidth); + } +} + +void Cel2DrawHdrLightRed(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth, int always_0, int dir, char light) +{ + int w, hdr, idx, nDataSize, v1; + BYTE *src, *dst, *tbl; + DWORD *pFrameTable; + + /// ASSERT: assert(gpBuffer); + if(!gpBuffer) + return; + /// ASSERT: assert(pCelBuff != NULL); + if(!pCelBuff) + return; + + pFrameTable = (DWORD *)pCelBuff; + src = &pCelBuff[pFrameTable[nCel]]; + hdr = *(WORD *)&src[always_0]; + if(!hdr) + return; + + nDataSize = pFrameTable[nCel + 1] - pFrameTable[nCel]; + if(dir == 8) + v1 = 0; + else + v1 = *(WORD *)&src[dir]; + if(v1) + nDataSize = v1 - hdr; + else + nDataSize -= hdr; + + src += hdr; + dst = &gpBuffer[sx + PitchTbl[sy - 16 * always_0]]; + + idx = light4flag ? 1024 : 4096; + if(light == 2) + idx += 256; + if(light >= 4) + idx += (light - 1) << 8; + + tbl = &pLightTbl[idx]; + +#ifdef USE_ASM + w = 768 + nWidth; + + __asm { + mov esi, src + mov edi, dst + mov ecx, nDataSize + add ecx, esi + label1: + push ecx + mov edx, nWidth + xor ecx, ecx + label2: + xor eax, eax + mov al, [esi] + inc esi + test al, al + js label5 + mov ebx, tbl + sub edx, eax + cmp edi, gpBufEnd + jb label3 + add esi, eax + add edi, eax + jmp label4 + label3: + mov cl, [esi] + inc esi + mov cl, [ebx+ecx] + mov [edi], cl + dec eax + lea edi, [edi+1] + jnz label3 + label4: + test edx, edx + jz label6 + jmp label2 + label5: + neg al + add edi, eax + sub edx, eax + jnz label2 + label6: + pop ecx + sub edi, w + cmp ecx, esi + jnz label1 + } +#else + BYTE width; + BYTE *end; + + end = &src[nDataSize]; + + for(; src != end; dst -= 768 + nWidth) { + for(w = nWidth; w;) { + width = *src++; + if(!(width & 0x80)) { + w -= width; + if(dst < gpBufEnd) { + while(width) { + *dst = tbl[*src]; + src++; + dst++; + width--; + } + } else { + src += width; + dst += width; + } + } else { + width = -(char)width; + dst += width; + w -= width; + } + } + } +#endif +} + +void CelDecodeRect(BYTE *pBuff, int always_0, int hgt, int wdt, BYTE *pCelBuff, int nCel, int nWidth) +{ + BYTE *src, *dst, *end; + + /// ASSERT: assert(pCelBuff != NULL); + if(!pCelBuff) + return; + /// ASSERT: assert(pBuff != NULL); + if(!pBuff) + return; + +#ifdef USE_ASM + __asm { + mov ebx, pCelBuff + mov eax, nCel + shl eax, 2 + add ebx, eax + mov eax, [ebx+4] + sub eax, [ebx] + mov end, eax + mov eax, pCelBuff + add eax, [ebx] + mov src, eax + } + + dst = &pBuff[hgt * wdt + always_0]; + + __asm { + mov esi, src + mov edi, dst + mov eax, wdt + add eax, nWidth + mov wdt, eax + mov ebx, end + add ebx, esi + label1: + mov edx, nWidth + label2: + xor eax, eax + lodsb + or al, al + js label6 + sub edx, eax + mov ecx, eax + shr ecx, 1 + jnb label3 + movsb + jecxz label5 + label3: + shr ecx, 1 + jnb label4 + movsw + jecxz label5 + label4: + rep movsd + label5: + or edx, edx + jz label7 + jmp label2 + label6: + neg al + add edi, eax + sub edx, eax + jnz label2 + label7: + sub edi, wdt + cmp ebx, esi + jnz label1 + } +#else + int i; + BYTE width; + DWORD *pFrameTable; + + pFrameTable = (DWORD *)&pCelBuff[4 * nCel]; + src = &pCelBuff[pFrameTable[0]]; + end = &src[pFrameTable[1] - pFrameTable[0]]; + dst = &pBuff[hgt * wdt + always_0]; + + for(; src != end; dst -= wdt + nWidth) { + for(i = nWidth; i;) { + width = *src++; + if(!(width & 0x80)) { + i -= width; + if(width & 1) { + dst[0] = src[0]; + src++; + dst++; + } + width >>= 1; + if(width & 1) { + dst[0] = src[0]; + dst[1] = src[1]; + src += 2; + dst += 2; + } + width >>= 1; + while(width) { + dst[0] = src[0]; + dst[1] = src[1]; + dst[2] = src[2]; + dst[3] = src[3]; + src += 4; + dst += 4; + width--; + } + } else { + width = -(char)width; + dst += width; + i -= width; + } + } + } +#endif +} + +void CelDecodeClr(char col, int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth, int always_0, int dir) +{ + int w, hdr, nDataSize, v1; + BYTE *src, *dst; + + /// ASSERT: assert(pCelBuff != NULL); + if(!pCelBuff) + return; + /// ASSERT: assert(gpBuffer); + if(!gpBuffer) + return; + +#ifdef USE_ASM + __asm { + mov ebx, pCelBuff + mov eax, nCel + shl eax, 2 + add ebx, eax + mov eax, [ebx+4] + sub eax, [ebx] + mov nDataSize, eax + mov edx, pCelBuff + add edx, [ebx] + mov src, edx + add edx, always_0 + xor eax, eax + mov ax, [edx] + mov hdr, eax + mov edx, src + add edx, dir + mov ax, [edx] + mov v1, eax + } + + if(!hdr) + return; + + if(dir == 8) + v1 = 0; + if(v1) + nDataSize = v1 - hdr; + else + nDataSize -= hdr; + + src += hdr; + dst = &gpBuffer[sx + PitchTbl[sy - 16 * always_0]]; + + __asm { + mov esi, src + mov edi, dst + mov eax, 768 + add eax, nWidth + mov w, eax + mov ebx, nDataSize + add ebx, esi + label1: + mov edx, nWidth + label2: + xor eax, eax + lodsb + or al, al + js label5 + sub edx, eax + mov ecx, eax + mov ah, col + label3: + lodsb + or al, al + jz label4 + mov [edi-768], ah + mov [edi-1], ah + mov [edi+1], ah + mov [edi+768], ah + label4: + inc edi + loop label3 + or edx, edx + jz label6 + jmp label2 + label5: + neg al + add edi, eax + sub edx, eax + jnz label2 + label6: + sub edi, w + cmp ebx, esi + jnz label1 + } +#else + BYTE width; + BYTE *end, *pRLEBytes; + DWORD *pFrameTable; + + pFrameTable = (DWORD *)&pCelBuff[4 * nCel]; + pRLEBytes = &pCelBuff[pFrameTable[0]]; + hdr = *(WORD *)&pRLEBytes[always_0]; + if(!hdr) + return; + + v1 = *(WORD *)&pRLEBytes[dir]; + if(dir == 8) + v1 = 0; + if(v1) + nDataSize = v1 - hdr; + else + nDataSize = pFrameTable[1] - pFrameTable[0] - hdr; + + src = &pRLEBytes[hdr]; + end = &src[nDataSize]; + dst = &gpBuffer[sx + PitchTbl[sy - 16 * always_0]]; + + for(; src != end; dst -= 768 + nWidth) { + for(w = nWidth; w;) { + width = *src++; + if(!(width & 0x80)) { + w -= width; + while(width) { + if(*src++) { + dst[-768] = col; + dst[-1] = col; + dst[1] = col; + dst[768] = col; + } + dst++; + width--; + } + } else { + width = -(char)width; + dst += width; + w -= width; + } + } + } +#endif +} + +void CelDrawHdrClrHL(char col, int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth, int always_0, int dir) +{ + int w, hdr, nDataSize, v1; + BYTE *src, *dst; + + /// ASSERT: assert(pCelBuff != NULL); + if(!pCelBuff) + return; + /// ASSERT: assert(gpBuffer); + if(!gpBuffer) + return; + +#ifdef USE_ASM + __asm { + mov ebx, pCelBuff + mov eax, nCel + shl eax, 2 + add ebx, eax + mov eax, [ebx+4] + sub eax, [ebx] + mov nDataSize, eax + mov edx, pCelBuff + add edx, [ebx] + mov src, edx + add edx, always_0 + xor eax, eax + mov ax, [edx] + mov hdr, eax + mov edx, src + add edx, dir + mov ax, [edx] + mov v1, eax + } + + if(!hdr) + return; + + if(dir == 8) + v1 = 0; + if(v1) + nDataSize = v1 - hdr; + else + nDataSize -= hdr; + + src += hdr; + dst = &gpBuffer[sx + PitchTbl[sy - 16 * always_0]]; + + __asm { + mov esi, src + mov edi, dst + mov eax, 768 + add eax, nWidth + mov w, eax + mov ebx, nDataSize + add ebx, esi + label1: + mov edx, nWidth + label2: + xor eax, eax + lodsb + or al, al + js label10 + sub edx, eax + mov ecx, gpBufEnd + cmp edi, ecx + jb label3 + add esi, eax + add edi, eax + jmp label9 + label3: + sub ecx, 768 + cmp edi, ecx + jnb label6 + mov ecx, eax + mov ah, col + label4: + lodsb + or al, al + jz label5 + mov [edi-768], ah + mov [edi-1], ah + mov [edi+1], ah + mov [edi+768], ah + label5: + inc edi + loop label4 + jmp label9 + label6: + mov ecx, eax + mov ah, col + label7: + lodsb + or al, al + jz label8 + mov [edi-768], ah + mov [edi-1], ah + mov [edi+1], ah + label8: + inc edi + loop label7 + label9: + or edx, edx + jz label11 + jmp label2 + label10: + neg al + add edi, eax + sub edx, eax + jnz label2 + label11: + sub edi, w + cmp ebx, esi + jnz label1 + } +#else + BYTE width; + BYTE *end, *pRLEBytes; + DWORD *pFrameTable; + + pFrameTable = (DWORD *)&pCelBuff[4 * nCel]; + pRLEBytes = &pCelBuff[pFrameTable[0]]; + hdr = *(WORD *)&pRLEBytes[always_0]; + if(!hdr) + return; + + v1 = *(WORD *)&pRLEBytes[dir]; + if(dir == 8) + v1 = 0; + if(v1) + nDataSize = v1 - hdr; + else + nDataSize = pFrameTable[1] - pFrameTable[0] - hdr; + + src = &pRLEBytes[hdr]; + end = &src[nDataSize]; + dst = &gpBuffer[sx + PitchTbl[sy - 16 * always_0]]; + + for(; src != end; dst -= 768 + nWidth) { + for(w = nWidth; w;) { + width = *src++; + if(!(width & 0x80)) { + w -= width; + if(dst < gpBufEnd) { + if(dst >= gpBufEnd - 768) { + while(width) { + if(*src++) { + dst[-768] = col; + dst[-1] = col; + dst[1] = col; + } + dst++; + width--; + } + } else { + while(width) { + if(*src++) { + dst[-768] = col; + dst[-1] = col; + dst[1] = col; + dst[768] = col; + } + dst++; + width--; + } + } + } else { + src += width; + dst += width; + } + } else { + width = -(char)width; + dst += width; + w -= width; + } + } + } +#endif +} + +void ENG_set_pixel(int sx, int sy, BYTE col) +{ + BYTE *dst; + + /// ASSERT: assert(gpBuffer); + + if(sy < 0 || sy >= 640 || sx < 64 || sx >= 704) + return; + + dst = &gpBuffer[sx + PitchTbl[sy]]; + +#ifdef USE_ASM + __asm { + mov edi, dst + cmp edi, gpBufEnd + jnb label1 + mov al, col + mov [edi], al + label1: + } +#else + if(dst < gpBufEnd) + *dst = col; +#endif +} + +void engine_draw_pixel(int sx, int sy) +{ + BYTE *dst; + + /// ASSERT: assert(gpBuffer); + + if(gbRotateMap) { + if(gbNotInView && (sx < 0 || sx >= 640 || sy < 64 || sy >= 704)) + return; + dst = &gpBuffer[sy + PitchTbl[sx]]; + } else { + if(gbNotInView && (sy < 0 || sy >= 640 || sx < 64 || sx >= 704)) + return; + dst = &gpBuffer[sx + PitchTbl[sy]]; + } + +#ifdef USE_ASM + __asm { + mov edi, dst + cmp edi, gpBufEnd + jnb label1 + mov al, gbPixelCol + mov [edi], al + label1: + } +#else + if(dst < gpBufEnd) + *dst = gbPixelCol; +#endif +} + +/* + * Xiaolin Wu's anti-aliased line algorithm + */ +void DrawLine(int x0, int y0, int x1, int y1, BYTE col) +{ + int i, sx, sy, dx, dy, nx, ny, xlen, ylen, pixels, remain, xy_same, line_dir, mult_2, mult_4; + + gbPixelCol = col; + + gbNotInView = FALSE; + if(x0 < 0 + 64 || x0 >= 640 + 64) { + gbNotInView = TRUE; + } + if(x1 < 0 + 64 || x1 >= 640 + 64) { + gbNotInView = TRUE; + } + if(y0 < 0 + 160 || y0 >= 352 + 160) { + gbNotInView = TRUE; + } + if(y1 < 0 + 160 || y1 >= 352 + 160) { + gbNotInView = TRUE; + } + + if(x1 - x0 < 0) { + nx = -1; + } else { + nx = 1; + } + xlen = nx * (x1 - x0); + + if(y1 - y0 < 0) { + ny = -1; + } else { + ny = 1; + } + ylen = ny * (y1 - y0); + + if(ny == nx) { + xy_same = 1; + } else { + xy_same = -1; + } + + if(ylen > xlen) { + x0 ^= y0 ^= x0 ^= y0; + x1 ^= y1 ^= x1 ^= y1; + xlen ^= ylen ^= xlen ^= ylen; + gbRotateMap = TRUE; + } else { + gbRotateMap = FALSE; + } + + if(x0 > x1) { + sx = x1; + sy = y1; + dx = x0; + dy = y0; + } else { + sx = x0; + sy = y0; + dx = x1; + dy = y1; + } + + pixels = (xlen - 1) / 4; + remain = (xlen - 1) % 4; + engine_draw_pixel(sx, sy); + engine_draw_pixel(dx, dy); + + line_dir = (ylen << 2) - xlen - xlen; + if(line_dir < 0) { + mult_2 = ylen << 1; + mult_4 = (mult_2 << 1) - xlen; + for(i = 0; i < pixels; i++) { + sx++; + dx--; + if(mult_4 < 0) { + engine_draw_pixel(sx, sy); + sx++; + engine_draw_pixel(sx, sy); + engine_draw_pixel(dx, dy); + dx--; + engine_draw_pixel(dx, dy); + mult_4 += mult_2 + mult_2; + } else if(mult_4 < mult_2) { + engine_draw_pixel(sx, sy); + sy += xy_same; + sx++; + engine_draw_pixel(sx, sy); + engine_draw_pixel(dx, dy); + dy -= xy_same; + dx--; + engine_draw_pixel(dx, dy); + mult_4 += line_dir; + } else { + sy += xy_same; + engine_draw_pixel(sx, sy); + sx++; + engine_draw_pixel(sx, sy); + dy -= xy_same; + engine_draw_pixel(dx, dy); + dx--; + engine_draw_pixel(dx, dy); + mult_4 += line_dir; + } + } + if(remain != 0) { + if(mult_4 < 0) { + sx++; + engine_draw_pixel(sx, sy); + if(remain > 1) { + sx++; + engine_draw_pixel(sx, sy); + } + if(remain > 2) { + dx--; + engine_draw_pixel(dx, dy); + } + } else if(mult_4 < mult_2) { + sx++; + engine_draw_pixel(sx, sy); + if(remain > 1) { + sy += xy_same; + sx++; + engine_draw_pixel(sx, sy); + } + if(remain > 2) { + dx--; + engine_draw_pixel(dx, dy); + } + } else { + sy += xy_same; + sx++; + engine_draw_pixel(sx, sy); + if(remain > 1) { + sx++; + engine_draw_pixel(sx, sy); + } + if(remain > 2) { + dy -= xy_same; + dx--; + engine_draw_pixel(dx, dy); + } + } + } + } else { + mult_2 = (ylen - xlen) << 1; + mult_4 = (mult_2 << 1) + xlen; + for(i = 0; i < pixels; i++) { + sx++; + dx--; + if(mult_4 > 0) { + sy += xy_same; + engine_draw_pixel(sx, sy); + sy += xy_same; + sx++; + engine_draw_pixel(sx, sy); + dy -= xy_same; + engine_draw_pixel(dx, dy); + dy -= xy_same; + dx--; + engine_draw_pixel(dx, dy); + mult_4 += mult_2 + mult_2; + } else if(mult_4 < mult_2) { + engine_draw_pixel(sx, sy); + sy += xy_same; + sx++; + engine_draw_pixel(sx, sy); + engine_draw_pixel(dx, dy); + dy -= xy_same; + dx--; + engine_draw_pixel(dx, dy); + mult_4 += line_dir; + } else { + sy += xy_same; + engine_draw_pixel(sx, sy); + sx++; + engine_draw_pixel(sx, sy); + dy -= xy_same; + engine_draw_pixel(dx, dy); + dx--; + engine_draw_pixel(dx, dy); + mult_4 += line_dir; + } + } + if(remain != 0) { + if(mult_4 > 0) { + sy += xy_same; + sx++; + engine_draw_pixel(sx, sy); + if(remain > 1) { + sy += xy_same; + sx++; + engine_draw_pixel(sx, sy); + } + if(remain > 2) { + dy -= xy_same; + dx--; + engine_draw_pixel(dx, dy); + } + } else if(mult_4 < mult_2) { + sx++; + engine_draw_pixel(sx, sy); + if(remain > 1) { + sy += xy_same; + sx++; + engine_draw_pixel(sx, sy); + } + if(remain > 2) { + dx--; + engine_draw_pixel(dx, dy); + } + } else { + sy += xy_same; + sx++; + engine_draw_pixel(sx, sy); + if(remain > 1) { + sx++; + engine_draw_pixel(sx, sy); + } + if(remain > 2) { + if(mult_4 > mult_2) { + dy -= xy_same; + dx--; + engine_draw_pixel(dx, dy); + } else { + dx--; + engine_draw_pixel(dx, dy); + } + } + } + } + } +} + +int GetDirection(int x1, int y1, int x2, int y2) +{ + int mx, my, md; + + mx = x2 - x1; + my = y2 - y1; + + if(mx >= 0) { + if(my >= 0) { + md = 0; + if(2 * mx < my) { + md = 1; + } + if(2 * my < mx) { + md = 7; + } + } else { + md = 6; + my = -my; + if(2 * mx < my) { + md = 5; + } + if(2 * my < mx) { + md = 7; + } + } + } else { + if(my >= 0) { + md = 2; + mx = -mx; + if(2 * mx < my) { + md = 1; + } + if(2 * my < mx) { + md = 3; + } + } else { + md = 4; + mx = -mx; + my = -my; + if(2 * mx < my) { + md = 5; + } + if(2 * my < mx) { + md = 3; + } + } + } + + return md; +} + +void SetRndSeed(long s) +{ + sglGameSeed = s; + orgseed = s; + SeedCount = 0; +} + +long GetRndSeed() +{ + SeedCount++; + sglGameSeed = rand_multiplier * sglGameSeed + rand_increment; + return abs(sglGameSeed); +} + +long random(BYTE idx, long v) +{ + if(v <= 0) { + return 0; + } + if(v >= 0xFFFF) { + return GetRndSeed() % v; + } + + return (GetRndSeed() >> 16) % v; +} + +void engine_debug_trap(BOOL show_cursor) +{ +/* + TMemBlock *pCurr; + + sgMemCrit.Enter(); + while(sgpMemBlock != NULL) { + pCurr = sgpMemBlock->pNext; + SMemFree(sgpMemBlock, "C:\\Diablo\\Direct\\ENGINE.CPP", 1970); + sgpMemBlock = pCurr; + } + sgMemCrit.Leave(); +*/ +} + +BYTE *DiabloAllocPtr(DWORD dwBytes) +{ + BYTE *p; + + sgMemCrit.Enter(); + p = (BYTE *)SMemAlloc(dwBytes, "C:\\Src\\Diablo\\Source\\ENGINE.CPP", 2236, 0); + sgMemCrit.Leave(); + + if(p == NULL) { + ErrDlg(IDD_DIALOG2, GetLastError(), "C:\\Src\\Diablo\\Source\\ENGINE.CPP", 2269); + } + + return p; +} + +void mem_free_dbg(void *p) +{ + if(p == NULL) { + return; + } + + sgMemCrit.Enter(); + SMemFree(p, "C:\\Src\\Diablo\\Source\\ENGINE.CPP", 2317, 0); + sgMemCrit.Leave(); +} + +BYTE *LoadFileInMem(const char *pszName, DWORD *pdwFileLen) +{ + DWORD dwFileLen; + HANDLE hsFile; + BYTE *p; + +#if 0 + if(pszName == NULL) { + app_fatal("LoadFileInMem: %s:%d", pszFile, nLineNo); + } +#endif + + WOpenFile((char *)pszName, &hsFile, 0); + + dwFileLen = WGetFileSize(hsFile, 0); + if(pdwFileLen != NULL) { + *pdwFileLen = dwFileLen; + } + if(dwFileLen == 0) { + app_fatal("Zero length SFILE:\n%s", pszName); + } + + p = DiabloAllocPtr(dwFileLen); + WReadFile(hsFile, (char *)p, dwFileLen); + WCloseFile(hsFile); + + return p; +} + +DWORD LoadFileWithMem(const char *pszName, void *p) +{ + DWORD dwFileLen; + HANDLE hsFile; + + /// ASSERT: assert(pszName); + if(p == NULL) { + app_fatal("LoadFileWithMem(NULL):\n%s", pszName); + } + + WOpenFile((char *)pszName, &hsFile, 0); + + dwFileLen = WGetFileSize(hsFile, 0); + if(dwFileLen == 0) { + app_fatal("Zero length SFILE:\n%s", pszName); + } + + WReadFile(hsFile, (char *)p, dwFileLen); + WCloseFile(hsFile); + + return dwFileLen; +} + +void Cl2ApplyTrans(BYTE *p, BYTE *ttbl, int nCel) +{ + int i, nDataSize; + char width; + BYTE *dst; + DWORD *pFrameTable; + + /// ASSERT: assert(p != NULL); + /// ASSERT: assert(ttbl != NULL); + + for(i = 1; i <= nCel; i++) { + pFrameTable = (DWORD *)p; + dst = &p[pFrameTable[i] + 10]; + nDataSize = pFrameTable[i + 1] - pFrameTable[i] - 10; + while(nDataSize != 0) { + width = *dst++; + nDataSize--; + /// ASSERT: assert(nDataSize >= 0); + if(width < 0) { + width = -width; + if(width > 65) { + nDataSize--; + /// ASSERT: assert(nDataSize >= 0); + *dst = ttbl[*dst]; + dst++; + } else { + nDataSize -= width; + /// ASSERT: assert(nDataSize >= 0); + while(width != 0) { + *dst = ttbl[*dst]; + dst++; + width--; + } + } + } + } + } +} + +static void Cl2DecDatFrm1(BYTE *pDecodeTo, BYTE *pRLEBytes, int nDataSize, int nWidth) +{ +#ifdef USE_ASM + __asm { + push ebx + push esi + push edi + mov esi, edx /// UNSAFE: use 'mov esi, pRLEBytes' + mov edi, ecx /// UNSAFE: use 'mov edi, pDecodeTo' + xor eax, eax + mov ebx, nWidth + mov ecx, nDataSize + label1: + mov al, [esi] + inc esi + dec ecx + test al, al + jns label6 + neg al + cmp al, 41h + jle label3 + sub al, 41h + dec ecx + mov dl, [esi] + inc esi + sub ebx, eax + label2: + mov [edi], dl + dec eax + lea edi, [edi+1] + jnz label2 + jmp label5 + label3: + sub ecx, eax + sub ebx, eax + label4: + mov dl, [esi] + inc esi + mov [edi], dl + dec eax + lea edi, [edi+1] + jnz label4 + label5: + test ebx, ebx + jnz label10 + mov ebx, nWidth + sub edi, 768 + sub edi, ebx + jmp label10 + label6: + cmp eax, ebx + jle label7 + mov edx, ebx + add edi, ebx + sub eax, ebx + jmp label8 + label7: + mov edx, eax + add edi, eax + xor eax, eax + label8: + sub ebx, edx + jnz label9 + mov ebx, nWidth + sub edi, 768 + sub edi, ebx + label9: + test eax, eax + jnz label6 + label10: + test ecx, ecx + jnz label1 + pop edi + pop esi + pop ebx + } +#else + int w; + char width; + BYTE fill; + BYTE *src, *dst; + + src = pRLEBytes; + dst = pDecodeTo; + w = nWidth; + + while(nDataSize) { + width = *src++; + nDataSize--; + if(width < 0) { + width = -width; + if(width > 65) { + width -= 65; + nDataSize--; + fill = *src++; + w -= width; + while(width) { + *dst = fill; + dst++; + width--; + } + if(!w) { + w = nWidth; + dst -= 768 + w; + } + continue; + } else { + nDataSize -= width; + w -= width; + while(width) { + *dst = *src; + src++; + dst++; + width--; + } + if(!w) { + w = nWidth; + dst -= 768 + w; + } + continue; + } + } + while(width) { + if(width > w) { + dst += w; + width -= w; + w = 0; + } else { + dst += width; + w -= width; + width = 0; + } + if(!w) { + w = nWidth; + dst -= 768 + w; + } + } + } +#endif +} + +static void Cl2DecDatFrm2(BYTE *pDecodeTo, BYTE *pRLEBytes, int nDataSize, int nWidth, char col) +{ +#ifdef USE_ASM + __asm { + push ebx + push esi + push edi + mov esi, edx /// UNSAFE: use 'mov esi, pRLEBytes' + mov edi, ecx /// UNSAFE: use 'mov edi, pDecodeTo' + xor eax, eax + mov ebx, nWidth + xor edx, edx + mov ecx, nDataSize + mov dl, col + label1: + mov al, [esi] + inc esi + dec ecx + test al, al + jns label7 + neg al + cmp al, 41h + jle label3 + sub al, 41h + dec ecx + mov dh, [esi] + inc esi + test dh, dh + jz label7 + mov [edi-1], dl + sub ebx, eax + mov [edi+eax], dl + label2: + mov [edi-768], dl + mov [edi+768], dl + dec eax + lea edi, [edi+1] + jnz label2 + jmp label6 + label3: + sub ecx, eax + sub ebx, eax + label4: + mov dh, [esi] + inc esi + test dh, dh + jz label5 + mov [edi-1], dl + mov [edi+1], dl + mov [edi-768], dl + mov [edi+768], dl + label5: + dec eax + lea edi, [edi+1] + jnz label4 + label6: + test ebx, ebx + jnz label11 + mov ebx, nWidth + sub edi, 768 + sub edi, ebx + jmp label11 + label7: + cmp eax, ebx + jle label8 + mov edx, ebx + add edi, ebx + sub eax, ebx + jmp label9 + label8: + mov edx, eax + add edi, eax + xor eax, eax + label9: + sub ebx, edx + jnz label10 + mov ebx, nWidth + sub edi, 768 + sub edi, ebx + label10: + test eax, eax + jnz label7 + mov dl, col + label11: + test ecx, ecx + jnz label1 + pop edi + pop esi + pop ebx + } +#else + int w; + char width; + BYTE *src, *dst; + + src = pRLEBytes; + dst = pDecodeTo; + w = nWidth; + + while(nDataSize) { + width = *src++; + nDataSize--; + if(width < 0) { + width = -width; + if(width > 65) { + width -= 65; + nDataSize--; + if(*src++) { + w -= width; + dst[-1] = col; + dst[width] = col; + while(width) { + dst[-768] = col; + dst[768] = col; + dst++; + width--; + } + if(!w) { + w = nWidth; + dst -= 768 + w; + } + continue; + } + } else { + nDataSize -= width; + w -= width; + while(width) { + if(*src++) { + dst[-1] = col; + dst[1] = col; + dst[-768] = col; + dst[768] = col; + } + dst++; + width--; + } + if(!w) { + w = nWidth; + dst -= 768 + w; + } + continue; + } + } + while(width) { + if(width > w) { + dst += w; + width -= w; + w = 0; + } else { + dst += width; + w -= width; + width = 0; + } + if(!w) { + w = nWidth; + dst -= 768 + w; + } + } + } +#endif +} + +static void Cl2DecDatLightTbl1(BYTE *pDecodeTo, BYTE *pRLEBytes, int nDataSize, int nWidth, BYTE *pTable) +{ +#ifdef USE_ASM + __asm { + push ebx + push esi + push edi + mov esi, edx /// UNSAFE: use 'mov esi, pRLEBytes' + mov edi, ecx /// UNSAFE: use 'mov edi, pDecodeTo' + mov ebx, nWidth + mov ecx, nDataSize + mov edx, pTable + push ebp + mov sgnWidth, ebx + mov ebp, edx + xor eax, eax + xor edx, edx + label1: + mov al, [esi] + inc esi + dec ecx + test al, al + jns label6 + neg al + cmp al, 41h + jle label3 + sub al, 41h + dec ecx + sub ebx, eax + mov dl, [esi] + inc esi + mov dl, [ebp+edx] + label2: + mov [edi], dl + dec eax + lea edi, [edi+1] + jnz label2 + jmp label5 + label3: + sub ecx, eax + sub ebx, eax + label4: + mov dl, [esi] + inc esi + mov dl, [ebp+edx] + mov [edi], dl + dec eax + lea edi, [edi+1] + jnz label4 + label5: + test ebx, ebx + jnz label10 + mov ebx, sgnWidth + sub edi, 768 + sub edi, ebx + jmp label10 + label6: + cmp eax, ebx + jle label7 + mov edx, ebx + add edi, ebx + sub eax, ebx + jmp label8 + label7: + mov edx, eax + add edi, eax + xor eax, eax + label8: + sub ebx, edx + jnz label9 + mov ebx, sgnWidth + sub edi, 768 + sub edi, ebx + label9: + test eax, eax + jnz label6 + label10: + test ecx, ecx + jnz label1 + pop ebp + pop edi + pop esi + pop ebx + } +#else + int w; + char width; + BYTE fill; + BYTE *src, *dst; + + src = pRLEBytes; + dst = pDecodeTo; + w = nWidth; + sgnWidth = nWidth; + + while(nDataSize) { + width = *src++; + nDataSize--; + if(width < 0) { + width = -width; + if(width > 65) { + width -= 65; + nDataSize--; + fill = pTable[*src++]; + w -= width; + while(width) { + *dst = fill; + dst++; + width--; + } + if(!w) { + w = sgnWidth; + dst -= 768 + w; + } + continue; + } else { + nDataSize -= width; + w -= width; + while(width) { + *dst = pTable[*src]; + src++; + dst++; + width--; + } + if(!w) { + w = sgnWidth; + dst -= 768 + w; + } + continue; + } + } + while(width) { + if(width > w) { + dst += w; + width -= w; + w = 0; + } else { + dst += width; + w -= width; + width = 0; + } + if(!w) { + w = sgnWidth; + dst -= 768 + w; + } + } + } +#endif +} + +static void Cl2DecDatFrm4(BYTE *pDecodeTo, BYTE *pRLEBytes, int nDataSize, int nWidth) +{ +#ifdef USE_ASM + __asm { + push ebx + push esi + push edi + mov esi, edx /// UNSAFE: use 'mov esi, pRLEBytes' + mov edi, ecx /// UNSAFE: use 'mov edi, pDecodeTo' + xor eax, eax + mov ebx, nWidth + mov ecx, nDataSize + label1: + mov al, [esi] + inc esi + dec ecx + test al, al + jns label7 + neg al + cmp al, 41h + jle label3 + sub al, 41h + dec ecx + mov dl, [esi] + inc esi + cmp edi, gpBufEnd + jge label7 + sub ebx, eax + label2: + mov [edi], dl + dec eax + lea edi, [edi+1] + jnz label2 + jmp label6 + label3: + sub ecx, eax + cmp edi, gpBufEnd + jl label4 + add esi, eax + jmp label7 + label4: + sub ebx, eax + label5: + mov dl, [esi] + inc esi + mov [edi], dl + dec eax + lea edi, [edi+1] + jnz label5 + label6: + test ebx, ebx + jnz label11 + mov ebx, nWidth + sub edi, 768 + sub edi, ebx + jmp label11 + label7: + cmp eax, ebx + jle label8 + mov edx, ebx + add edi, ebx + sub eax, ebx + jmp label9 + label8: + mov edx, eax + add edi, eax + xor eax, eax + label9: + sub ebx, edx + jnz label10 + mov ebx, nWidth + sub edi, 768 + sub edi, ebx + label10: + test eax, eax + jnz label7 + label11: + test ecx, ecx + jnz label1 + pop edi + pop esi + pop ebx + } +#else + int w; + char width; + BYTE fill; + BYTE *src, *dst; + + src = pRLEBytes; + dst = pDecodeTo; + w = nWidth; + + while(nDataSize) { + width = *src++; + nDataSize--; + if(width < 0) { + width = -width; + if(width > 65) { + width -= 65; + nDataSize--; + fill = *src++; + if(dst < gpBufEnd) { + w -= width; + while(width) { + *dst = fill; + dst++; + width--; + } + if(!w) { + w = nWidth; + dst -= 768 + w; + } + continue; + } + } else { + nDataSize -= width; + if(dst < gpBufEnd) { + w -= width; + while(width) { + *dst = *src; + src++; + dst++; + width--; + } + if(!w) { + w = nWidth; + dst -= 768 + w; + } + continue; + } else { + src += width; + } + } + } + while(width) { + if(width > w) { + dst += w; + width -= w; + w = 0; + } else { + dst += width; + w -= width; + width = 0; + } + if(!w) { + w = nWidth; + dst -= 768 + w; + } + } + } +#endif +} + +static void Cl2DecDatClrHL(BYTE *pDecodeTo, BYTE *pRLEBytes, int nDataSize, int nWidth, char col) +{ +#ifdef USE_ASM + __asm { + push ebx + push esi + push edi + mov esi, edx /// UNSAFE: use 'mov esi, pRLEBytes' + mov edi, ecx /// UNSAFE: use 'mov edi, pDecodeTo' + xor eax, eax + mov ebx, nWidth + xor edx, edx + mov ecx, nDataSize + mov dl, col + label1: + mov al, [esi] + inc esi + dec ecx + test al, al + jns label9 + neg al + cmp al, 41h + jle label3 + sub al, 41h + dec ecx + mov dh, [esi] + inc esi + test dh, dh + jz label9 + cmp edi, gpBufEnd + jge label9 + mov [edi-1], dl + sub ebx, eax + mov [edi+eax], dl + label2: + mov [edi-768], dl + mov [edi+768], dl + dec eax + lea edi, [edi+1] + jnz label2 + jmp label7 + label3: + sub ecx, eax + cmp edi, gpBufEnd + jl label4 + add esi, eax + jmp label9 + label4: + sub ebx, eax + label5: + mov dh, [esi] + inc esi + test dh, dh + jz label6 + mov [edi-1], dl + mov [edi+1], dl + mov [edi-768], dl + mov [edi+768], dl + label6: + dec eax + lea edi, [edi+1] + jnz label5 + label7: + test ebx, ebx + jnz label13 + mov ebx, nWidth + sub edi, 768 + sub edi, ebx + jmp label13 + label9: + cmp eax, ebx + jle label10 + mov edx, ebx + add edi, ebx + sub eax, ebx + jmp label11 + label10: + mov edx, eax + add edi, eax + xor eax, eax + label11: + sub ebx, edx + jnz label12 + mov ebx, nWidth + sub edi, 768 + sub edi, ebx + label12: + test eax, eax + jnz label9 + mov dl, col + label13: + test ecx, ecx + jnz label1 + pop edi + pop esi + pop ebx + } +#else + int w; + char width; + BYTE *src, *dst; + + src = pRLEBytes; + dst = pDecodeTo; + w = nWidth; + + while(nDataSize) { + width = *src++; + nDataSize--; + if(width < 0) { + width = -width; + if(width > 65) { + width -= 65; + nDataSize--; + if(*src++ && dst < gpBufEnd) { + w -= width; + dst[-1] = col; + dst[width] = col; + while(width) { + dst[-768] = col; + dst[768] = col; + dst++; + width--; + } + if(!w) { + w = nWidth; + dst -= 768 + w; + } + continue; + } + } else { + nDataSize -= width; + if(dst < gpBufEnd) { + w -= width; + while(width) { + if(*src++) { + dst[-1] = col; + dst[1] = col; + dst[-768] = col; + dst[768] = col; + } + dst++; + width--; + } + if(!w) { + w = nWidth; + dst -= 768 + w; + } + continue; + } else { + src += width; + } + } + } + while(width) { + if(width > w) { + dst += w; + width -= w; + w = 0; + } else { + dst += width; + w -= width; + width = 0; + } + if(!w) { + w = nWidth; + dst -= 768 + w; + } + } + } +#endif +} + +static void Cl2DecDatLightTbl2(BYTE *pDecodeTo, BYTE *pRLEBytes, int nDataSize, int nWidth, BYTE *pTable) +{ +#ifdef USE_ASM + __asm { + push ebx + push esi + push edi + mov esi, edx /// UNSAFE: use 'mov esi, pRLEBytes' + mov edi, ecx /// UNSAFE: use 'mov edi, pDecodeTo' + mov ebx, nWidth + mov ecx, nDataSize + mov edx, pTable + push ebp + mov sgnWidth, ebx + mov ebp, edx + xor eax, eax + xor edx, edx + label1: + mov al, [esi] + inc esi + dec ecx + test al, al + jns label7 + neg al + cmp al, 41h + jle label3 + sub al, 41h + dec ecx + mov dl, [esi] + inc esi + mov dl, [ebp+edx] + cmp edi, gpBufEnd + jge label7 + sub ebx, eax + label2: + mov [edi], dl + dec eax + lea edi, [edi+1] + jnz label2 + jmp label6 + label3: + sub ecx, eax + cmp edi, gpBufEnd + jl label4 + add esi, eax + jmp label7 + label4: + sub ebx, eax + label5: + mov dl, [esi] + inc esi + mov dl, [ebp+edx] + mov [edi], dl + dec eax + lea edi, [edi+1] + jnz label5 + label6: + test ebx, ebx + jnz label11 + mov ebx, sgnWidth + sub edi, 768 + sub edi, ebx + jmp label11 + label7: + cmp eax, ebx + jle label8 + mov edx, ebx + add edi, ebx + sub eax, ebx + jmp label9 + label8: + mov edx, eax + add edi, eax + xor eax, eax + label9: + sub ebx, edx + jnz label10 + mov ebx, sgnWidth + sub edi, 768 + sub edi, ebx + label10: + test eax, eax + jnz label7 + label11: + test ecx, ecx + jnz label1 + pop ebp + pop edi + pop esi + pop ebx + } +#else + int w; + char width; + BYTE fill; + BYTE *src, *dst; + + src = pRLEBytes; + dst = pDecodeTo; + w = nWidth; + sgnWidth = nWidth; + + while(nDataSize) { + width = *src++; + nDataSize--; + if(width < 0) { + width = -width; + if(width > 65) { + width -= 65; + nDataSize--; + fill = pTable[*src++]; + if(dst < gpBufEnd) { + w -= width; + while(width) { + *dst = fill; + dst++; + width--; + } + if(!w) { + w = sgnWidth; + dst -= 768 + w; + } + continue; + } + } else { + nDataSize -= width; + if(dst < gpBufEnd) { + w -= width; + while(width) { + *dst = pTable[*src]; + src++; + dst++; + width--; + } + if(!w) { + w = sgnWidth; + dst -= 768 + w; + } + continue; + } else { + src += width; + } + } + } + while(width) { + if(width > w) { + dst += w; + width -= w; + w = 0; + } else { + dst += width; + w -= width; + width = 0; + } + if(!w) { + w = sgnWidth; + dst -= 768 + w; + } + } + } +#endif +} + +void Cl2DecodeFrm1(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth, int always_0, int dir) +{ + int hdr, v2, nDataSize; + BYTE *pDecodeTo, *pRLEBytes; + DWORD *pFrameTable; + + /// ASSERT: assert(gpBuffer != NULL); + if(gpBuffer == NULL) { + return; + } + /// ASSERT: assert(pCelBuff != NULL); + if(pCelBuff == NULL) { + return; + } + /// ASSERT: assert(nCel > 0); + if(nCel <= 0) { + return; + } + + pFrameTable = (DWORD *)pCelBuff; + /// ASSERT: assert(nCel <= (int) pFrameTable[0]); + pRLEBytes = &pCelBuff[pFrameTable[nCel]]; + hdr = ((WORD *)&pRLEBytes[always_0])[0]; + + if(hdr == 0) { + return; + } + + if(dir == 8) { + v2 = 0; + } else { + v2 = ((WORD *)&pRLEBytes[dir])[0]; + } + if(v2 == 0) { + v2 = pFrameTable[nCel + 1] - pFrameTable[nCel]; + } + + nDataSize = v2 - hdr; + pRLEBytes += hdr; + pDecodeTo = &gpBuffer[sx + PitchTbl[sy - 16 * always_0]]; + + Cl2DecDatFrm1(pDecodeTo, pRLEBytes, nDataSize, nWidth); +} + +void Cl2DecodeFrm2(char col, int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth, int always_0, int dir) +{ + int hdr, v2, nDataSize; + BYTE *pDecodeTo, *pRLEBytes; + DWORD *pFrameTable; + + /// ASSERT: assert(gpBuffer != NULL); + if(gpBuffer == NULL) { + return; + } + /// ASSERT: assert(pCelBuff != NULL); + if(pCelBuff == NULL) { + return; + } + /// ASSERT: assert(nCel > 0); + if(nCel <= 0) { + return; + } + + pFrameTable = (DWORD *)pCelBuff; + /// ASSERT: assert(nCel <= (int) pFrameTable[0]); + pRLEBytes = &pCelBuff[pFrameTable[nCel]]; + hdr = ((WORD *)&pRLEBytes[always_0])[0]; + + if(hdr == 0) { + return; + } + + if(dir == 8) { + v2 = 0; + } else { + v2 = ((WORD *)&pRLEBytes[dir])[0]; + } + if(v2 == 0) { + v2 = pFrameTable[nCel + 1] - pFrameTable[nCel]; + } + + nDataSize = v2 - hdr; + pRLEBytes += hdr; + pDecodeTo = &gpBuffer[sx + PitchTbl[sy - 16 * always_0]]; + + Cl2DecDatFrm2(pDecodeTo, pRLEBytes, nDataSize, nWidth, col); +} + +void Cl2DecodeFrm3(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth, int always_0, int dir, char light) +{ + int idx, hdr, v2, nDataSize; + BYTE *pDecodeTo, *pRLEBytes; + DWORD *pFrameTable; + + /// ASSERT: assert(gpBuffer != NULL); + if(gpBuffer == NULL) { + return; + } + /// ASSERT: assert(pCelBuff != NULL); + if(pCelBuff == NULL) { + return; + } + /// ASSERT: assert(nCel > 0); + if(nCel <= 0) { + return; + } + + pFrameTable = (DWORD *)pCelBuff; + /// ASSERT: assert(nCel <= (int) pFrameTable[0]); + pRLEBytes = &pCelBuff[pFrameTable[nCel]]; + hdr = ((WORD *)&pRLEBytes[always_0])[0]; + + if(hdr == 0) { + return; + } + + if(dir == 8) { + v2 = 0; + } else { + v2 = ((WORD *)&pRLEBytes[dir])[0]; + } + if(v2 == 0) { + v2 = pFrameTable[nCel + 1] - pFrameTable[nCel]; + } + + nDataSize = v2 - hdr; + pRLEBytes += hdr; + pDecodeTo = &gpBuffer[sx + PitchTbl[sy - 16 * always_0]]; + + idx = light4flag ? 1024 : 4096; + if(light == 2) { + idx += 256; + } + if(light >= 4) { + idx += (light - 1) << 8; + } + + Cl2DecDatLightTbl1(pDecodeTo, pRLEBytes, nDataSize, nWidth, &pLightTbl[idx]); +} + +void Cl2DecodeLightTbl(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth, int always_0, int dir) +{ + int hdr, v2, nDataSize; + BYTE *pDecodeTo, *pRLEBytes; + DWORD *pFrameTable; + + /// ASSERT: assert(gpBuffer != NULL); + if(gpBuffer == NULL) { + return; + } + /// ASSERT: assert(pCelBuff != NULL); + if(pCelBuff == NULL) { + return; + } + /// ASSERT: assert(nCel > 0); + if(nCel <= 0) { + return; + } + + pFrameTable = (DWORD *)pCelBuff; + /// ASSERT: assert(nCel <= (int) pFrameTable[0]); + pRLEBytes = &pCelBuff[pFrameTable[nCel]]; + hdr = ((WORD *)&pRLEBytes[always_0])[0]; + + if(hdr == 0) { + return; + } + + if(dir == 8) { + v2 = 0; + } else { + v2 = ((WORD *)&pRLEBytes[dir])[0]; + } + if(v2 == 0) { + v2 = pFrameTable[nCel + 1] - pFrameTable[nCel]; + } + + nDataSize = v2 - hdr; + pRLEBytes += hdr; + pDecodeTo = &gpBuffer[sx + PitchTbl[sy - 16 * always_0]]; + + if(light_table_index != 0) { + Cl2DecDatLightTbl1(pDecodeTo, pRLEBytes, nDataSize, nWidth, &pLightTbl[light_table_index * 256]); + } else { + Cl2DecDatFrm1(pDecodeTo, pRLEBytes, nDataSize, nWidth); + } +} + +void Cl2DecodeFrm4(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth, int always_0, int dir) +{ + int hdr, v2, nDataSize; + BYTE *pDecodeTo, *pRLEBytes; + DWORD *pFrameTable; + + /// ASSERT: assert(gpBuffer != NULL); + if(gpBuffer == NULL) { + return; + } + /// ASSERT: assert(pCelBuff != NULL); + if(pCelBuff == NULL) { + return; + } + /// ASSERT: assert(nCel > 0); + if(nCel <= 0) { + return; + } + + pFrameTable = (DWORD *)pCelBuff; + /// ASSERT: assert(nCel <= (int) pFrameTable[0]); + pRLEBytes = &pCelBuff[pFrameTable[nCel]]; + hdr = ((WORD *)&pRLEBytes[always_0])[0]; + + if(hdr == 0) { + return; + } + + if(dir == 8) { + v2 = 0; + } else { + v2 = ((WORD *)&pRLEBytes[dir])[0]; + } + if(v2 == 0) { + v2 = pFrameTable[nCel + 1] - pFrameTable[nCel]; + } + + nDataSize = v2 - hdr; + pRLEBytes += hdr; + pDecodeTo = &gpBuffer[sx + PitchTbl[sy - 16 * always_0]]; + + Cl2DecDatFrm4(pDecodeTo, pRLEBytes, nDataSize, nWidth); +} + +void Cl2DecodeClrHL(char col, int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth, int always_0, int dir) +{ + int hdr, v2, nDataSize; + BYTE *pDecodeTo, *pRLEBytes; + DWORD *pFrameTable; + + /// ASSERT: assert(gpBuffer != NULL); + if(gpBuffer == NULL) { + return; + } + /// ASSERT: assert(pCelBuff != NULL); + if(pCelBuff == NULL) { + return; + } + /// ASSERT: assert(nCel > 0); + if(nCel <= 0) { + return; + } + + pFrameTable = (DWORD *)pCelBuff; + /// ASSERT: assert(nCel <= (int) pFrameTable[0]); + pRLEBytes = &pCelBuff[pFrameTable[nCel]]; + hdr = ((WORD *)&pRLEBytes[always_0])[0]; + + if(hdr == 0) { + return; + } + + if(dir == 8) { + v2 = 0; + } else { + v2 = ((WORD *)&pRLEBytes[dir])[0]; + } + if(v2 == 0) { + v2 = pFrameTable[nCel + 1] - pFrameTable[nCel]; + } + + nDataSize = v2 - hdr; + pRLEBytes += hdr; + pDecodeTo = &gpBuffer[sx + PitchTbl[sy - 16 * always_0]]; + + gpBufEnd -= 768; + Cl2DecDatClrHL(pDecodeTo, pRLEBytes, nDataSize, nWidth, col); + gpBufEnd += 768; +} + +void Cl2DecodeFrm5(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth, int always_0, int dir, char light) +{ + int idx, hdr, v2, nDataSize; + BYTE *pDecodeTo, *pRLEBytes; + DWORD *pFrameTable; + + /// ASSERT: assert(gpBuffer != NULL); + if(gpBuffer == NULL) { + return; + } + /// ASSERT: assert(pCelBuff != NULL); + if(pCelBuff == NULL) { + return; + } + /// ASSERT: assert(nCel > 0); + if(nCel <= 0) { + return; + } + + pFrameTable = (DWORD *)pCelBuff; + /// ASSERT: assert(nCel <= (int) pFrameTable[0]); + pRLEBytes = &pCelBuff[pFrameTable[nCel]]; + hdr = ((WORD *)&pRLEBytes[always_0])[0]; + + if(hdr == 0) { + return; + } + + if(dir == 8) { + v2 = 0; + } else { + v2 = ((WORD *)&pRLEBytes[dir])[0]; + } + if(v2 == 0) { + v2 = pFrameTable[nCel + 1] - pFrameTable[nCel]; + } + + nDataSize = v2 - hdr; + pRLEBytes += hdr; + pDecodeTo = &gpBuffer[sx + PitchTbl[sy - 16 * always_0]]; + + idx = light4flag ? 1024 : 4096; + if(light == 2) { + idx += 256; + } + if(light >= 4) { + idx += (light - 1) << 8; + } + + Cl2DecDatLightTbl2(pDecodeTo, pRLEBytes, nDataSize, nWidth, &pLightTbl[idx]); +} + +void Cl2DecodeFrm6(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth, int always_0, int dir) +{ + int hdr, v2, nDataSize; + BYTE *pDecodeTo, *pRLEBytes; + DWORD *pFrameTable; + + /// ASSERT: assert(gpBuffer != NULL); + if(gpBuffer == NULL) { + return; + } + /// ASSERT: assert(pCelBuff != NULL); + if(pCelBuff == NULL) { + return; + } + /// ASSERT: assert(nCel > 0); + if(nCel <= 0) { + return; + } + + pFrameTable = (DWORD *)pCelBuff; + /// ASSERT: assert(nCel <= (int) pFrameTable[0]); + pRLEBytes = &pCelBuff[pFrameTable[nCel]]; + hdr = ((WORD *)&pRLEBytes[always_0])[0]; + + if(hdr == 0) { + return; + } + + if(dir == 8) { + v2 = 0; + } else { + v2 = ((WORD *)&pRLEBytes[dir])[0]; + } + if(v2 == 0) { + v2 = pFrameTable[nCel + 1] - pFrameTable[nCel]; + } + + nDataSize = v2 - hdr; + pRLEBytes += hdr; + pDecodeTo = &gpBuffer[sx + PitchTbl[sy - 16 * always_0]]; + + if(light_table_index != 0) { + Cl2DecDatLightTbl2(pDecodeTo, pRLEBytes, nDataSize, nWidth, &pLightTbl[light_table_index * 256]); + } else { + Cl2DecDatFrm4(pDecodeTo, pRLEBytes, nDataSize, nWidth); + } +} + +void PlayInGameMovie(const char *pszMovie) +{ + PaletteFadeOut(8); + play_movie(pszMovie, FALSE); + ClearScreenBuffer(); + force_redraw = 255; + scrollrt_draw_game_screen(TRUE); + PaletteFadeIn(8); + force_redraw = 255; +} diff --git a/2020_03_31/Source/engine.h b/2020_03_31/Source/engine.h new file mode 100644 index 00000000..2a344848 --- /dev/null +++ b/2020_03_31/Source/engine.h @@ -0,0 +1,66 @@ +//HEADER_GOES_HERE +#ifndef __ENGINE_H__ +#define __ENGINE_H__ + +//offset 0 +//pCelBuff->pFrameTable[0] + +extern char gbPixelCol; // automap pixel color 8-bit (palette entry) +extern int gbRotateMap; // _bool flip - if y < x +extern int orgseed; // weak +extern int sgnWidth; +extern int sglGameSeed; // weak +extern int SeedCount; // weak +extern int gbNotInView; // _bool valid - if x/y are in bounds + +void CelDrawDatOnly(BYTE *pDecodeTo, BYTE *pRLEBytes, int nDataSize, int nWidth); +void CelDecodeOnly(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth); +void CelDecDatOnly(BYTE *pBuff, BYTE *pCelBuff, int nCel, int nWidth); +void CelDrawHdrOnly(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth, int always_0, int dir); +void CelDecodeHdrOnly(BYTE *pBuff, BYTE *pCelBuff, int nCel, int nWidth, int always_0, int dir); +void CelDecDatLightOnly(BYTE *pDecodeTo, BYTE *pRLEBytes, int nDataSize, int nWidth); +void CelDecDatLightTrans(BYTE *pDecodeTo, BYTE *pRLEBytes, int nDataSize, int nWidth); +void CelDecodeLightOnly(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth); +void CelDecodeHdrLightOnly(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth, int always_0, int dir); +void CelDecodeHdrLightTrans(BYTE *pBuff, BYTE *pCelBuff, int nCel, int nWidth, int always_0, int dir); +void CelDrawHdrLightRed(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth, int always_0, int dir, char light); +void Cel2DecDatOnly(BYTE *pDecodeTo, BYTE *pRLEBytes, int nDataSize, int nWidth); +void Cel2DrawHdrOnly(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth, int always_0, int dir); +void Cel2DecodeHdrOnly(BYTE *pBuff, BYTE *pCelBuff, int nCel, int nWidth, int always_0, int dir); +void Cel2DecDatLightOnly(BYTE *pDecodeTo, BYTE *pRLEBytes, int nDataSize, int nWidth); +void Cel2DecDatLightTrans(BYTE *pDecodeTo, BYTE *pRLEBytes, int nDataSize, int nWidth); +void Cel2DecodeHdrLight(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth, int always_0, int dir); +void Cel2DecodeLightTrans(BYTE *pBuff, BYTE *pCelBuff, int nCel, int nWidth, int always_0, int dir); +void Cel2DrawHdrLightRed(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth, int always_0, int dir, char light); +void CelDecodeRect(BYTE *pBuff, int always_0, int hgt, int wdt, BYTE *pCelBuff, int nCel, int nWidth); +void CelDecodeClr(char col, int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth, int always_0, int dir); +void CelDrawHdrClrHL(char col, int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth, int always_0, int dir); +void ENG_set_pixel(int sx, int sy, BYTE col); +void engine_draw_pixel(int sx, int sy); +void DrawLine(int x0, int y0, int x1, int y1, BYTE col); +int GetDirection(int x1, int y1, int x2, int y2); +void SetRndSeed(long s); +long GetRndSeed(); +long random(BYTE idx, long v); +void engine_debug_trap(BOOL show_cursor); +BYTE *DiabloAllocPtr(DWORD dwBytes); +void mem_free_dbg(void *p); +BYTE *LoadFileInMem(const char *pszName, DWORD *pdwFileLen); +DWORD LoadFileWithMem(const char *pszName, void *p); +void Cl2ApplyTrans(BYTE *p, BYTE *ttbl, int nCel); +void Cl2DecodeFrm1(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth, int always_0, int dir); +void Cl2DecodeFrm2(char col, int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth, int always_0, int dir); +void Cl2DecodeFrm3(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth, int always_0, int dir, char light); +void Cl2DecodeLightTbl(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth, int always_0, int dir); +void Cl2DecodeFrm4(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth, int always_0, int dir); +void Cl2DecodeClrHL(char col, int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth, int always_0, int dir); +void Cl2DecodeFrm5(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth, int always_0, int dir, char light); +void Cl2DecodeFrm6(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth, int always_0, int dir); +void PlayInGameMovie(const char *pszMovie); + +/* rdata */ + +extern const int rand_increment; // unused +extern const int rand_multiplier; // unused + +#endif /* __ENGINE_H__ */ diff --git a/2020_03_31/Source/error.cpp b/2020_03_31/Source/error.cpp new file mode 100644 index 00000000..b74190e3 --- /dev/null +++ b/2020_03_31/Source/error.cpp @@ -0,0 +1,188 @@ +#include "diablo.h" + +char msgtable[80]; +char msgdelay; // weak +char msgflag; // weak +char msgcnt; // weak + +char *MsgStrings[44] = +{ + "", + "No automap available in town", + "No multiplayer functions in demo", + "Direct Sound Creation Failed", + "Not available in shareware version", + "Not enough space to save", + "No Pause in town", + "Copying to a hard disk is recommended", + "Multiplayer sync problem", + "No pause in multiplayer", + "Loading...", + "Saving...", + "Some are weakened as one grows strong", + "New strength is forged through destruction", + "Those who defend seldom attack", + "The sword of justice is swift and sharp", + "While the spirit is vigilant the body thrives", + "The powers of mana refocused renews", + "Time cannot diminish the power of steel", + "Magic is not always what it seems to be", + "What once was opened now is closed", + "Intensity comes at the cost of wisdom", + "Arcane power brings destruction", + "That which cannot be held cannot be harmed", + "Crimson and Azure become as the sun", + "Knowledge and wisdom at the cost of self", + "Drink and be refreshed", + "Wherever you go, there you are", + "Energy comes at the cost of wisdom", + "Riches abound when least expected", + "Where avarice fails, patience gains reward", + "Blessed by a benevolent companion!", + "The hands of men may be guided by fate", + "Strength is bolstered by heavenly faith", + "The essence of life flows from within", + "The way is made clear when viewed from above", + "Salvation comes at the cost of wisdom", + "Mysteries are revealed in the light of reason", + "Those who are last may yet be first", + "Generosity brings its own rewards", + "You must be at least level 8 to use this.", + "You must be at least level 13 to use this.", + "You must be at least level 17 to use this.", + "Arcane knowledge gained!" +}; + +void InitDiabloMsg(char e) +{ + int i; + + for(i = 0; i < msgcnt; i++) { + if(msgtable[i] == e) { + return; + } + } + + msgtable[msgcnt] = e; + + if(msgcnt < 80) { + msgcnt++; + } + + msgflag = msgtable[0]; + msgdelay = 70; +} + +void ClrDiabloMsg() +{ + int i; + + for(i = 0; i < 80; i++) { + msgtable[i] = 0; + } + + msgflag = 0; + msgcnt = 0; +} + +void DrawDiabloMsg() +{ + int i, len, off, width, sx, sy; + BYTE c; + + CelDecodeOnly(165, 318, (BYTE *)pSTextSlidCels, 1, 12); + CelDecodeOnly(591, 318, (BYTE *)pSTextSlidCels, 4, 12); + CelDecodeOnly(165, 366, (BYTE *)pSTextSlidCels, 2, 12); + CelDecodeOnly(591, 366, (BYTE *)pSTextSlidCels, 3, 12); + + sx = 173; + for(i = 0; i < 35; i++) { + CelDecodeOnly(sx, 318, (BYTE *)pSTextSlidCels, 5, 12); + CelDecodeOnly(sx, 366, (BYTE *)pSTextSlidCels, 7, 12); + sx += 12; + } + sy = 330; + for(i = 0; i < 3; i++) { + CelDecodeOnly(165, sy, (BYTE *)pSTextSlidCels, 6, 12); + CelDecodeOnly(591, sy, (BYTE *)pSTextSlidCels, 8, 12); + sy += 12; + } + + /// ASSERT: assert(gpBuffer); + +#ifdef USE_ASM + __asm { + mov edi, gpBuffer + add edi, SCREENXY(104, 203) + xor eax, eax + mov edx, 54 / 2 + label1: + mov ecx, 432 / 2 + label2: + stosb + inc edi + loop label2 + sub edi, BUFFER_WIDTH + 432 + mov ecx, 432 / 2 + label3: + inc edi + stosb + loop label3 + sub edi, BUFFER_WIDTH + 432 + dec edx + jnz label1 + } +#else + int wdt, hgt; + BYTE *dst; + + dst = &gpBuffer[SCREENXY(104, 203)]; + + for(hgt = 54 / 2; hgt != 0; hgt--) { + for(wdt = 432 / 2; wdt != 0; wdt--) { + dst[0] = 0; + dst += 2; + } + dst -= BUFFER_WIDTH + 432; + for(wdt = 432 / 2; wdt != 0; wdt--) { + dst[1] = 0; + dst += 2; + } + dst -= BUFFER_WIDTH + 432; + } +#endif + + strcpy(tempstr, MsgStrings[msgflag]); + off = 165 + PitchTbl[342]; + len = strlen(tempstr); + width = 0; + + for(i = 0; i < len; i++) { + width += fontkern[fontframe[gbFontTransTbl[(BYTE)tempstr[i]]]] + 1; + } + + if(width < 442) { + off += (442 - width) >> 1; + } + + for(i = 0; i < len; i++) { + c = fontframe[gbFontTransTbl[(BYTE)tempstr[i]]]; + if(c != '\0') { + PrintChar(off, c, COL_GOLD); + } + off += fontkern[c] + 1; + } + + if(msgdelay > 0) { + msgdelay--; + } + if(msgdelay == 0) { + msgcnt--; + msgdelay = 70; + if(msgcnt == 0) { + msgflag = 0; + } else { + msgflag = msgtable[msgcnt]; + } + } +} diff --git a/2020_03_31/Source/error.h b/2020_03_31/Source/error.h new file mode 100644 index 00000000..724b2201 --- /dev/null +++ b/2020_03_31/Source/error.h @@ -0,0 +1,17 @@ +//HEADER_GOES_HERE +#ifndef __ERROR_H__ +#define __ERROR_H__ + +extern char msgtable[80]; +extern char msgdelay; // weak +extern char msgflag; // weak +extern char msgcnt; // weak + +void InitDiabloMsg(char e); +void ClrDiabloMsg(); +void DrawDiabloMsg(); + +/* data */ +extern char *MsgStrings[44]; + +#endif /* __ERROR_H__ */ diff --git a/2020_03_31/Source/fault.cpp b/2020_03_31/Source/fault.cpp new file mode 100644 index 00000000..8b24b4bf --- /dev/null +++ b/2020_03_31/Source/fault.cpp @@ -0,0 +1,250 @@ +#include "diablo.h" + +LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter; // idb + +#ifndef _MSC_VER +__attribute__((constructor)) +#endif +static void +exception_c_init(void) +{ + exception_install_filter(); + j_exception_init_filter(); +} + +SEG_ALLOCATE(SEGMENT_C_INIT) +_PVFV exception_c_init_funcs[] = { &exception_c_init }; + +void exception_install_filter() +{ + exception_set_filter(); +} + +void j_exception_init_filter() +{ + atexit(exception_init_filter); +} + +void __cdecl exception_init_filter() +{ + exception_set_filter_ptr(); +} + +LONG __stdcall TopLevelExceptionFilter(PEXCEPTION_POINTERS ExceptionInfo) +{ + log_dump_computer_info(); + PEXCEPTION_RECORD xcpt = ExceptionInfo->ExceptionRecord; + + char szExceptionNameBuf[MAX_PATH]; // [esp+Ch] [ebp-210h] + char *pszExceptionName = exception_get_error_type(ExceptionInfo->ExceptionRecord->ExceptionCode, szExceptionNameBuf, sizeof(szExceptionNameBuf)); + log_printf("Exception code: %08X %s\r\n", xcpt->ExceptionCode, pszExceptionName); + + char szModuleName[MAX_PATH]; + int sectionNumber, sectionOffset; + exception_unknown_module(xcpt->ExceptionAddress, szModuleName, MAX_PATH, §ionNumber, §ionOffset); + log_printf("Fault address:\t%08X %02X:%08X %s\r\n", xcpt->ExceptionAddress, sectionNumber, sectionOffset, szModuleName); + + PCONTEXT ctx = ExceptionInfo->ContextRecord; + + log_printf("\r\nRegisters:\r\n"); + log_printf( + "EAX:%08X\r\nEBX:%08X\r\nECX:%08X\r\nEDX:%08X\r\nESI:%08X\r\nEDI:%08X\r\n", + ctx->Eax, + ctx->Ebx, + ctx->Ecx, + ctx->Edx, + ctx->Esi, + ctx->Edi); + log_printf("CS:EIP:%04X:%08X\r\n", ctx->SegCs, ctx->Eip); + log_printf("SS:ESP:%04X:%08X EBP:%08X\r\n", ctx->SegSs, ctx->Esp, ctx->Ebp); + log_printf("DS:%04X ES:%04X FS:%04X GS:%04X\r\n", ctx->SegDs, ctx->SegEs, ctx->SegFs, ctx->SegGs); + + log_printf("Flags:%08X\r\n", ctx->EFlags); + exception_call_stack((void *)ctx->Eip, (STACK_FRAME*)ctx->Ebp); + + log_printf("Stack bytes:\r\n"); + exception_hex_format((BYTE *)ctx->Esp, 0); + + log_printf("Code bytes:\r\n"); + exception_hex_format((BYTE *)ctx->Eip, 16); + + log_printf("\r\n"); + log_flush(1); + + if ( lpTopLevelExceptionFilter ) + return lpTopLevelExceptionFilter(ExceptionInfo); + return EXCEPTION_CONTINUE_SEARCH; +} + +void exception_hex_format(BYTE *ptr, unsigned int numBytes) +{ + int i; + + while (numBytes > 0) + { + unsigned int bytesRead = 16; + if (numBytes < 16 ) + bytesRead = numBytes; + + if ( IsBadReadPtr(ptr, bytesRead) ) + break; + + log_printf("0x%08x: ", ptr); + + for (i = 0; i < 16; ++i) + { + const char *fmt = "%02x "; + if (i >= bytesRead) + fmt = " "; + log_printf(fmt, ptr[i]); + if (i % 4 == 3) + log_printf(" "); + } + + for (i = 0; i < bytesRead; ++i) + { + char c; + if (isprint(ptr[i])) + c = ptr[i]; + else + c = '.'; + log_printf("%c", c); + } + + log_printf("\r\n"); + ptr += bytesRead; + numBytes -= bytesRead; + } + log_printf("\r\n"); +} + +void exception_unknown_module(LPCVOID lpAddress, LPSTR lpModuleName, int iMaxLength, int *sectionNum, int *sectionOffset) +{ + lstrcpyn(lpModuleName, "*unknown*", iMaxLength); + *sectionNum = 0; + *sectionOffset = 0; + + MEMORY_BASIC_INFORMATION memInfo; // [esp+Ch] [ebp-24h] + if (!VirtualQuery(lpAddress, &memInfo, sizeof(memInfo))) + return; + + PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)memInfo.AllocationBase; + if ( !memInfo.AllocationBase ) + dosHeader = (PIMAGE_DOS_HEADER)GetModuleHandle(0); + + if (!GetModuleFileName((HMODULE)dosHeader, lpModuleName, iMaxLength)) + { + lstrcpyn(lpModuleName, "*unknown*", iMaxLength); + return; + } + + if (dosHeader && dosHeader->e_magic == IMAGE_DOS_SIGNATURE) + { + LONG ntOffset = dosHeader->e_lfanew; + if (ntOffset) + { + PIMAGE_NT_HEADERS ntHeader = (PIMAGE_NT_HEADERS)((DWORD)dosHeader + ntOffset); + if (ntHeader->Signature == IMAGE_NT_SIGNATURE) + { + DWORD numSections = ntHeader->FileHeader.NumberOfSections; + DWORD moduleOffset = (_BYTE *)lpAddress - (_BYTE *)dosHeader; + PIMAGE_SECTION_HEADER section = IMAGE_FIRST_SECTION(ntHeader); + for (int i = 0; i < numSections; ++i, ++section) + { + DWORD sectionSize = section->SizeOfRawData; + DWORD sectionAddress = section->VirtualAddress; + if (section->SizeOfRawData <= section->Misc.VirtualSize) + sectionSize = section->Misc.VirtualSize; + + if (moduleOffset >= sectionAddress && moduleOffset <= sectionAddress + sectionSize) + { + *sectionNum = i + 1; + *sectionOffset = moduleOffset - sectionAddress; + return; + } + } + } + } + } +} + +void exception_call_stack(void *instr, STACK_FRAME *stackFrame) +{ + STACK_FRAME *oldStackFrame; + + log_printf("Call stack:\r\nAddress Frame Logical addr Module\r\n"); + do + { + char szModuleName[MAX_PATH]; + int sectionNumber, sectionOffset; + exception_unknown_module(instr, szModuleName, MAX_PATH, §ionNumber, §ionOffset); + log_printf("%08X %08X %04X:%08X %s\r\n", instr, stackFrame, sectionNumber, sectionOffset, szModuleName); + + if ( IsBadWritePtr(stackFrame, 8u) ) + break; + + instr = stackFrame->pCallRet; + oldStackFrame = stackFrame; + stackFrame = stackFrame->pNext; + + if ((int)stackFrame % 4 != 0) + break; + } + while (stackFrame > oldStackFrame && !IsBadWritePtr(stackFrame, 8u) ); + + log_printf("\r\n"); +} + +#define CASE_EXCEPTION(v, errName) case EXCEPTION_ ## errName: v = #errName; break; +char *exception_get_error_type(DWORD dwMessageId, LPSTR lpString1, DWORD nSize) +{ + const char *v4; // eax + + switch (dwMessageId) { + CASE_EXCEPTION(v4, STACK_OVERFLOW); + CASE_EXCEPTION(v4, FLT_DIVIDE_BY_ZERO); + CASE_EXCEPTION(v4, FLT_INEXACT_RESULT); + CASE_EXCEPTION(v4, FLT_INVALID_OPERATION); + CASE_EXCEPTION(v4, FLT_OVERFLOW); + CASE_EXCEPTION(v4, FLT_STACK_CHECK); + CASE_EXCEPTION(v4, FLT_UNDERFLOW); + CASE_EXCEPTION(v4, INT_DIVIDE_BY_ZERO); + CASE_EXCEPTION(v4, INT_OVERFLOW); + CASE_EXCEPTION(v4, PRIV_INSTRUCTION); + CASE_EXCEPTION(v4, FLT_DENORMAL_OPERAND); + CASE_EXCEPTION(v4, INVALID_HANDLE); + CASE_EXCEPTION(v4, ILLEGAL_INSTRUCTION); + CASE_EXCEPTION(v4, NONCONTINUABLE_EXCEPTION); + CASE_EXCEPTION(v4, INVALID_DISPOSITION); + CASE_EXCEPTION(v4, ARRAY_BOUNDS_EXCEEDED); + CASE_EXCEPTION(v4, IN_PAGE_ERROR); + CASE_EXCEPTION(v4, GUARD_PAGE); + CASE_EXCEPTION(v4, DATATYPE_MISALIGNMENT); + CASE_EXCEPTION(v4, BREAKPOINT); + CASE_EXCEPTION(v4, SINGLE_STEP); + CASE_EXCEPTION(v4, ACCESS_VIOLATION); + default: + HMODULE ntdll = GetModuleHandle("NTDLL.DLL"); + if (!FormatMessage(FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_IGNORE_INSERTS, ntdll, dwMessageId, 0, lpString1, nSize, NULL)) + { + v4 = "*unknown*"; + } + } + lstrcpyn(lpString1, v4, nSize); + return lpString1; +} + +void exception_set_filter() +{ + lpTopLevelExceptionFilter = SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)TopLevelExceptionFilter); +} + +LPTOP_LEVEL_EXCEPTION_FILTER exception_set_filter_ptr() +{ + return SetUnhandledExceptionFilter(lpTopLevelExceptionFilter); +} + +LPTOP_LEVEL_EXCEPTION_FILTER exception_get_filter() +{ + return lpTopLevelExceptionFilter; +} diff --git a/2020_03_31/Source/fault.h b/2020_03_31/Source/fault.h new file mode 100644 index 00000000..29abcdf6 --- /dev/null +++ b/2020_03_31/Source/fault.h @@ -0,0 +1,26 @@ +//HEADER_GOES_HERE +#ifndef __FAULT_H__ +#define __FAULT_H__ + +typedef struct STACK_FRAME { + struct STACK_FRAME *pNext; + void *pCallRet; +} STACK_FRAME; + +//int dword_52B9F4; +extern LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter; // idb + +// void exception_cpp_init(); +void exception_install_filter(); +void j_exception_init_filter(); +void __cdecl exception_init_filter(); +LONG __stdcall TopLevelExceptionFilter(PEXCEPTION_POINTERS ExceptionInfo); +void exception_hex_format(BYTE *ptr, unsigned int numBytes); +void exception_unknown_module(LPCVOID lpAddress, LPSTR lpModuleName, int iMaxLength, int *sectionNum, int *sectionOffset); +void exception_call_stack(void *instr, STACK_FRAME *stackAddr); +char *exception_get_error_type(DWORD dwMessageId, LPSTR lpString1, DWORD nSize); +void exception_set_filter(); +LPTOP_LEVEL_EXCEPTION_FILTER exception_set_filter_ptr(); +LPTOP_LEVEL_EXCEPTION_FILTER exception_get_filter(); + +#endif /* __FAULT_H__ */ diff --git a/2020_03_31/Source/gamemenu.cpp b/2020_03_31/Source/gamemenu.cpp new file mode 100644 index 00000000..cf8048bb --- /dev/null +++ b/2020_03_31/Source/gamemenu.cpp @@ -0,0 +1,313 @@ +#include "diablo.h" + +TMenuItem sgSingleMenu[6] = +{ + { 0x80000000, "Save Game", &gamemenu_save_game }, + { 0x80000000, "Options", &gamemenu_options }, + { 0x80000000, "New Game", &gamemenu_new_game }, + { 0x80000000, "Load Game", &gamemenu_load_game }, + { 0x80000000, "Quit Diablo", &gamemenu_quit_game }, + { 0x80000000, NULL, NULL } +}; +TMenuItem sgMultiMenu[5] = +{ + { 0x80000000, "Options", &gamemenu_options }, + { 0x80000000, "New Game", &gamemenu_new_game }, + { 0x80000000, "Restart In Town", &gamemenu_restart_town }, + { 0x80000000, "Quit Diablo", &gamemenu_quit_game }, + { 0x80000000, NULL, NULL } +}; +TMenuItem sgOptionMenu[6] = +{ + { 0xC0000000, NULL, &gamemenu_music_volume }, + { 0xC0000000, NULL, &gamemenu_sound_volume }, + { 0xC0000000, "Gamma", &gamemenu_gamma }, + { 0x80000000, NULL, &gamemenu_color_cycling }, + { 0x80000000, "Previous Menu", &gamemenu_previous }, + { 0x80000000, NULL, NULL } +}; +char *music_toggle_names[] = { "Music", "Music Disabled" }; +char *sound_toggle_names[] = { "Sound", "Sound Disabled" }; +char *color_cycling_toggle_names[] = { "Color Cycling Off", "Color Cycling On" }; + +void gamemenu_on() +{ + if(gbMaxPlayers == 1) { + gmenu_set_items(sgSingleMenu, gamemenu_update_single); + } else { + gmenu_set_items(sgMultiMenu, gamemenu_update_multi); + } + + PressEscKey(); +} + +void gamemenu_update_single(TMenuItem *pMenuItems) +{ + /// ASSERT: assert(pMenuItems == sgSingleMenu); + gmenu_enable(&sgSingleMenu[3], gbValidSaveFile); + gmenu_enable(&sgSingleMenu[0], plr[myplr]._pmode != PM_DEATH && !deathflag); +} + +void gamemenu_update_multi(TMenuItem *pMenuItems) +{ + /// ASSERT: assert(pMenuItems == sgMultiMenu); + gmenu_enable(&sgMultiMenu[2], deathflag); +} + +void gamemenu_off() +{ + gmenu_set_items(NULL, NULL); +} + +void gamemenu_handle_previous() +{ + if(gmenu_is_active()) { + gamemenu_off(); + } else { + gamemenu_on(); + } +} + +void gamemenu_previous(BOOL bActivate) +{ + /// ASSERT: assert(bActivate); + gamemenu_on(); +} + +void gamemenu_new_game(BOOL bActivate) +{ + int i; + + /// ASSERT: assert(bActivate); + + for(i = 0; i < MAX_PLRS; i++) { + plr[i]._pmode = PM_QUIT; + plr[i]._pInvincible = 1; + } + + deathflag = 0; + force_redraw = 255; + scrollrt_draw_game_screen(TRUE); + gbRunGame = 0; + gamemenu_off(); +} + +void gamemenu_quit_game(BOOL bActivate) +{ + /// ASSERT: assert(bActivate); + gamemenu_new_game(bActivate); + gbRunGameResult = 0; +} + +void gamemenu_load_game(BOOL bActivate) +{ + WNDPROC saveProc; + + /// ASSERT: assert(bActivate); + /// ASSERT: assert(gbMaxPlayers == 1); + /// ASSERT: assert(gbValidSaveFile); + + /// ASSERT: assert(ghMainWnd); + saveProc = SetWindowProc(DisableInputWndProc); + gamemenu_off(); + SetCursor_(0); + InitDiabloMsg(10); + force_redraw = 255; + DrawAndBlit(); + LoadGame(FALSE); + ClrDiabloMsg(); + PaletteFadeOut(8); + deathflag = 0; + force_redraw = 255; + DrawAndBlit(); + PaletteFadeIn(8); + SetCursor_(CURSOR_HAND); + interface_msg_pump(); + saveProc = SetWindowProc(saveProc); + /// ASSERT: assert(saveProc == DisableInputWndProc); +} + +void gamemenu_save_game(BOOL bActivate) +{ + WNDPROC saveProc; + + /// ASSERT: assert(bActivate); + /// ASSERT: assert(gbMaxPlayers == 1); + + if(pcurs != CURSOR_HAND) { + return; + } + if(plr[myplr]._pmode == PM_DEATH || deathflag) { + gamemenu_off(); + return; + } + + /// ASSERT: assert(ghMainWnd); + saveProc = SetWindowProc(DisableInputWndProc); + SetCursor_(0); + gamemenu_off(); + InitDiabloMsg(11); + force_redraw = 255; + DrawAndBlit(); + SaveGame(); + ClrDiabloMsg(); + force_redraw = 255; + SetCursor_(CURSOR_HAND); + interface_msg_pump(); + saveProc = SetWindowProc(saveProc); + /// ASSERT: assert(saveProc == DisableInputWndProc); +} + +void gamemenu_restart_town(BOOL bActivate) +{ + /// ASSERT: assert(bActivate); + NetSendCmd(TRUE, CMD_RETOWN); +} + +void gamemenu_options(BOOL bActivate) +{ + /// ASSERT: assert(bActivate); + gamemenu_get_music(); + gamemenu_get_sound(); + gamemenu_get_gamma(); + gamemenu_get_color_cycling(); + gmenu_set_items(sgOptionMenu, NULL); +} + +void gamemenu_get_music() +{ + gamemenu_sound_music_toggle(music_toggle_names, &sgOptionMenu[0], sound_get_or_set_music_volume(1)); +} + +void gamemenu_sound_music_toggle(char **names, TMenuItem *pItem, int ticks) +{ + if(gbSndInited) { + pItem->dwFlags |= 0xC0000000; + pItem->pszStr = names[0]; + gmenu_set_max_ticks(pItem, 17); + gmenu_set_slider_ticks(pItem, -1600, 0, ticks); + } else { + pItem->dwFlags &= ~0xC0000000; + pItem->pszStr = names[1]; + } +} + +void gamemenu_get_sound() +{ + gamemenu_sound_music_toggle(sound_toggle_names, &sgOptionMenu[1], sound_get_or_set_sound_volume(1)); +} + +void gamemenu_get_color_cycling() +{ + BOOL bCycle; + + bCycle = palette_get_colour_cycling(); + sgOptionMenu[3].pszStr = color_cycling_toggle_names[bCycle & 1]; +} + +void gamemenu_get_gamma() +{ + gmenu_set_max_ticks(&sgOptionMenu[2], 15); + gmenu_set_slider_ticks(&sgOptionMenu[2], 30, 100, UpdateGamma(0)); +} + +void gamemenu_music_volume(BOOL bActivate) +{ + int volume; + + if(bActivate) { + if(gbMusicOn) { + gbMusicOn = 0; + music_stop(); + sound_get_or_set_music_volume(-1600); + } else { + gbMusicOn = 1; + sound_get_or_set_music_volume(0); + music_start(leveltype); + } + } else { + volume = gamemenu_slider_music_sound(&sgOptionMenu[0]); + sound_get_or_set_music_volume(volume); + if(volume == -1600) { + if(gbMusicOn) { + gbMusicOn = 0; + music_stop(); + } + } else { + if(!gbMusicOn) { + gbMusicOn = 1; + music_start(leveltype); + } + } + } + + gamemenu_get_music(); +} + +int gamemenu_slider_music_sound(TMenuItem *pItem) +{ + return gmenu_get_slider_ticks(pItem, -1600, 0); +} + +void gamemenu_sound_volume(BOOL bActivate) +{ + int volume; + + if(bActivate) { + if(gbSoundOn) { + gbSoundOn = 0; + sound_stop(); + sound_get_or_set_sound_volume(-1600); + } else { + gbSoundOn = 1; + sound_get_or_set_sound_volume(0); + } + } else { + volume = gamemenu_slider_music_sound(&sgOptionMenu[1]); + sound_get_or_set_sound_volume(volume); + if(volume == -1600) { + if(gbSoundOn) { + gbSoundOn = 0; + sound_stop(); + } + } else { + if(!gbSoundOn) { + gbSoundOn = 1; + } + } + } + + PlaySFX(IS_TITLEMOV); + gamemenu_get_sound(); +} + +void gamemenu_gamma(BOOL bActivate) +{ + int gamma; + + if(bActivate) { + if(UpdateGamma(0) == 30) { + gamma = 100; + } else { + gamma = 30; + } + } else { + gamma = gamemenu_slider_gamma(); + } + + UpdateGamma(gamma); + gamemenu_get_gamma(); +} + +int gamemenu_slider_gamma() +{ + return gmenu_get_slider_ticks(&sgOptionMenu[2], 30, 100); +} + +void gamemenu_color_cycling(BOOL bActivate) +{ + BOOL bCycle; + + bCycle = palette_set_color_cycling(!palette_get_colour_cycling()); + sgOptionMenu[3].pszStr = color_cycling_toggle_names[bCycle & 1]; +} diff --git a/2020_03_31/Source/gamemenu.h b/2020_03_31/Source/gamemenu.h new file mode 100644 index 00000000..c89c5977 --- /dev/null +++ b/2020_03_31/Source/gamemenu.h @@ -0,0 +1,37 @@ +//HEADER_GOES_HERE +#ifndef __GAMEMENU_H__ +#define __GAMEMENU_H__ + +void gamemenu_on(); +void gamemenu_update_single(TMenuItem *pMenuItems); +void gamemenu_update_multi(TMenuItem *pMenuItems); +void gamemenu_off(); +void gamemenu_handle_previous(); +void gamemenu_previous(BOOL bActivate); +void gamemenu_new_game(BOOL bActivate); +void gamemenu_quit_game(BOOL bActivate); +void gamemenu_load_game(BOOL bActivate); +void gamemenu_save_game(BOOL bActivate); +void gamemenu_restart_town(BOOL bActivate); +void gamemenu_options(BOOL bActivate); +void gamemenu_get_music(); +void gamemenu_sound_music_toggle(char **names, TMenuItem *pItem, int ticks); +void gamemenu_get_sound(); +void gamemenu_get_color_cycling(); +void gamemenu_get_gamma(); +void gamemenu_music_volume(BOOL bActivate); +int gamemenu_slider_music_sound(TMenuItem *pItem); +void gamemenu_sound_volume(BOOL bActivate); +void gamemenu_gamma(BOOL bActivate); +int gamemenu_slider_gamma(); +void gamemenu_color_cycling(BOOL bActivate); + +/* rdata */ +extern TMenuItem sgSingleMenu[6]; +extern TMenuItem sgMultiMenu[5]; +extern TMenuItem sgOptionMenu[6]; +extern char *music_toggle_names[]; +extern char *sound_toggle_names[]; +extern char *color_cycling_toggle_names[]; + +#endif /* __GAMEMENU_H__ */ diff --git a/2020_03_31/Source/gendung.cpp b/2020_03_31/Source/gendung.cpp new file mode 100644 index 00000000..0b0fdc83 --- /dev/null +++ b/2020_03_31/Source/gendung.cpp @@ -0,0 +1,1056 @@ +#include "diablo.h" + +unsigned char dungeon[40][40]; +BYTE pdungeon[40][40]; +char dflags[40][40]; +int setpc_x; // idb +int setpc_y; // idb +int setpc_w; // weak +int setpc_h; // weak +char *pSetPiece_2; +int setloadflag_2; // weak +BYTE *pSpecialCels; +BYTE *pMegaTiles; +BYTE *pLevelPieces; +BYTE *pDungeonCels; +BYTE *pSpeedCels; +int SpeedFrameTbl[128][16]; /* MICROS */ +char block_lvid[2049]; +int level_frame_count[MAXTILES]; +int tile_defs[MAXTILES]; +WORD level_frame_types[MAXTILES]; +int level_frame_sizes[MAXTILES]; +int nlevel_frames; // weak +BOOLEAN nBlockTable[2049]; +BOOLEAN nSolidTable[2049]; +BOOLEAN nTransTable[2049]; +BOOLEAN nMissileTable[2049]; +BOOLEAN nTrapTable[2049]; +int dminx; // weak +int dminy; // weak +int dmaxx; // weak +int dmaxy; // weak +int gnDifficulty; // idb +unsigned char leveltype; // weak +unsigned char currlevel; // idb +char setlevel; // weak +BYTE setlvlnum; // weak +char setlvltype; // weak +int ViewX; // idb +int ViewY; // idb +int ViewDX; // weak +int ViewDY; // weak +int ViewBX; // weak +int ViewBY; // weak +ScrollStruct ScrollInfo; +int LvlViewX; // weak +int LvlViewY; // weak +int MicroTileLen; +char TransVal; // weak +char TransList[256]; +int dPiece[MAXDUNX][MAXDUNY]; +MICROS dpiece_defs_map_2[MAXDUNX][MAXDUNY]; +MICROS dpiece_defs_map_1[MAXDUNX * MAXDUNY]; +char dTransVal[MAXDUNX][MAXDUNY]; +char dLight[MAXDUNX][MAXDUNY]; +char dPreLight[MAXDUNX][MAXDUNY]; +char dFlags[MAXDUNX][MAXDUNY]; +char dPlayer[MAXDUNX][MAXDUNY]; +int dMonster[MAXDUNX][MAXDUNY]; +char dDead[MAXDUNX][MAXDUNY]; +char dObject[MAXDUNX][MAXDUNY]; +char dItem[MAXDUNX][MAXDUNY]; +char dMissile[MAXDUNX][MAXDUNY]; +char dSpecial[MAXDUNX][MAXDUNY]; +int themeCount; +THEME_LOC themeLoc[MAXTHEMES]; + +void FillSolidBlockTbls() +{ + unsigned char bv; + DWORD dwTiles; + unsigned char *pSBFile, *pTmp; + int i; + + memset(nBlockTable, 0, sizeof(nBlockTable)); + memset(nSolidTable, 0, sizeof(nSolidTable)); + memset(nTransTable, 0, sizeof(nTransTable)); + memset(nMissileTable, 0, sizeof(nMissileTable)); + memset(nTrapTable, 0, sizeof(nTrapTable)); + + switch((unsigned char)leveltype) { + case DTYPE_TOWN: + pSBFile = DiabLoad("Levels\\TownData\\Town.SOL", &dwTiles, 'SOL '); + break; + case DTYPE_CATHEDRAL: + pSBFile = DiabLoad("Levels\\L1Data\\L1.SOL", &dwTiles, 'SOL '); + break; + case DTYPE_CATACOMBS: + pSBFile = DiabLoad("Levels\\L2Data\\L2.SOL", &dwTiles, 'SOL '); + break; + case DTYPE_CAVES: + pSBFile = DiabLoad("Levels\\L3Data\\L3.SOL", &dwTiles, 'SOL '); + break; + case DTYPE_HELL: + pSBFile = DiabLoad("Levels\\L4Data\\L4.SOL", &dwTiles, 'SOL '); + break; + default: + app_fatal("FillSolidBlockTbls"); + } + + pTmp = pSBFile; + + for(i = 1; i <= dwTiles; i++) { + bv = *pTmp++; + if(bv & 1) + nSolidTable[i] = 1; + if(bv & 2) + nBlockTable[i] = 1; + if(bv & 4) + nMissileTable[i] = 1; + if(bv & 8) + nTransTable[i] = 1; + if(bv & 0x80) + nTrapTable[i] = 1; + block_lvid[i] = (bv & 0x70) >> 4; /* beta: (bv >> 4) & 7 */ + } + + mem_free_dbg(pSBFile); +} + +static void SwapTile(int f1, int f2) +{ + int swap; + + swap = level_frame_count[f1]; + level_frame_count[f1] = level_frame_count[f2]; + level_frame_count[f2] = swap; + swap = tile_defs[f1]; + tile_defs[f1] = tile_defs[f2]; + tile_defs[f2] = swap; + swap = level_frame_types[f1]; + level_frame_types[f1] = level_frame_types[f2]; + level_frame_types[f2] = swap; + swap = level_frame_sizes[f1]; + level_frame_sizes[f1] = level_frame_sizes[f2]; + level_frame_sizes[f2] = swap; +} + +static void SortTiles(int frames) +{ + int i; + BOOL doneflag; + + doneflag = FALSE; + while(frames > 0 && !doneflag) { + doneflag = TRUE; + for(i = 0; i < frames; i++) { + if(level_frame_count[i] < level_frame_count[i + 1]) { + SwapTile(i, i + 1); + doneflag = FALSE; + } + } + frames--; + } +} + +void MakeSpeedCels() +{ + int i, j, x, y; + int tile, total_frames, blocks, total_size, frameidx, lfs_adder, blk_cnt, currtile, nDataSize; + WORD m; + BOOL blood_flag; + DWORD *pFrameTable; + MICROS *pMap; +#ifndef USE_ASM + int k, l; + BYTE width, pix; + BYTE *src, *dst, *tbl; +#endif + + for(i = 0; i < MAXTILES; i++) { + tile_defs[i] = i; + level_frame_count[i] = 0; + level_frame_types[i] = 0; + } + + if(leveltype != DTYPE_HELL) + blocks = 10; + else + blocks = 12; + + for(y = 0; y < MAXDUNY; y++) { + for(x = 0; x < MAXDUNX; x++) { + pMap = &dpiece_defs_map_2[x][y]; + for(i = 0; i < blocks; i++) { + tile = pMap->mt[i]; + if(tile) { + level_frame_count[tile & 0xFFF]++; + level_frame_types[tile & 0xFFF] = tile & 0x7000; + } + } + } + } + + pFrameTable = (DWORD *)pDungeonCels; + nDataSize = pFrameTable[0]; + nlevel_frames = nDataSize & 0xFFFF; + + for(i = 1; i < nlevel_frames; i++) { + currtile = i; +#ifdef USE_ASM + __asm { + mov ebx, pDungeonCels + mov eax, currtile + shl eax, 2 + add ebx, eax + mov eax, [ebx+4] + sub eax, [ebx] + mov nDataSize, eax + } +#else + nDataSize = pFrameTable[currtile + 1] - pFrameTable[currtile]; +#endif + level_frame_sizes[i] = nDataSize & 0xFFFF; + } + + level_frame_sizes[0] = 0; + + if(leveltype == DTYPE_HELL) { + for(i = 0; i < nlevel_frames; i++) { + if(!i) + level_frame_count[0] = 0; + currtile = i; + blood_flag = TRUE; + if(level_frame_count[i]) { + if(level_frame_types[i] != 0x1000) { +#ifdef USE_ASM + lfs_adder = level_frame_sizes[i]; + __asm { + mov ebx, pDungeonCels + mov eax, currtile + shl eax, 2 + add ebx, eax + mov esi, pDungeonCels + add esi, [ebx] + xor ebx, ebx + mov ecx, lfs_adder + jecxz l1_label3 + l1_label1: + lodsb + cmp al, 0 + jz l1_label2 + cmp al, 32 + jnb l1_label2 + mov blood_flag, ebx + l1_label2: + loop l1_label1 + l1_label3: + nop + } +#else + src = &pDungeonCels[pFrameTable[currtile]]; + for(lfs_adder = level_frame_sizes[i]; lfs_adder; lfs_adder--) { + pix = *src++; + if(pix && pix < 32) + blood_flag = FALSE; + } +#endif + } else { +#ifdef USE_ASM + __asm { + mov ebx, pDungeonCels + mov eax, currtile + shl eax, 2 + add ebx, eax + mov esi, pDungeonCels + add esi, [ebx] + xor ebx, ebx + mov ecx, 32 + l2_label1: + push ecx + mov edx, 32 + l2_label2: + xor eax, eax + lodsb + or al, al + js l2_label5 + sub edx, eax + mov ecx, eax + l2_label3: + lodsb + cmp al, 0 + jz l2_label4 + cmp al, 32 + jnb l2_label4 + mov blood_flag, ebx + l2_label4: + loop l2_label3 + or edx, edx + jz l2_label6 + jmp l2_label2 + l2_label5: + neg al + sub edx, eax + jnz l2_label2 + l2_label6: + pop ecx + loop l2_label1 + } +#else + src = &pDungeonCels[pFrameTable[currtile]]; + for(k = 32; k; k--) { + for(l = 32; l;) { + width = *src++; + if(!(width & 0x80)) { + l -= width; + while(width) { + pix = *src++; + if(pix && pix < 32) + blood_flag = FALSE; + width--; + } + } else { + width = -(char)width; + l -= width; + } + } + } +#endif + } + if(!blood_flag) + level_frame_count[i] = 0; + } + } + } + + SortTiles(MAXTILES - 1); + total_size = 0; + total_frames = 0; + + if(light4flag) { + while(total_size < 0x100000) { + total_size += level_frame_sizes[total_frames] << 1; + total_frames++; + } + } else { + while(total_size < 0x100000) { + total_size += (level_frame_sizes[total_frames] << 4) - (level_frame_sizes[total_frames] << 1); + total_frames++; + } + } + + total_frames--; + if(total_frames > 128) + total_frames = 128; + + frameidx = 0; /* move into loop ? */ + + if(light4flag) + blk_cnt = 3; + else + blk_cnt = 15; + + for(i = 0; i < total_frames; i++) { + currtile = tile_defs[i]; + SpeedFrameTbl[i][0] = currtile; + if(level_frame_types[i] != 0x1000) { + lfs_adder = level_frame_sizes[i]; + for(j = 1; j < blk_cnt; j++) { + SpeedFrameTbl[i][j] = frameidx; +#ifdef USE_ASM + __asm { + mov ebx, pDungeonCels + mov eax, currtile + shl eax, 2 + add ebx, eax + mov esi, pDungeonCels + add esi, [ebx] + mov edi, pSpeedCels + add edi, frameidx + mov ebx, j + shl ebx, 8 + add ebx, pLightTbl + mov ecx, lfs_adder + jecxz l3_label2 + l3_label1: + lodsb + xlat + stosb + loop l3_label1 + l3_label2: + nop + } +#else + src = &pDungeonCels[pFrameTable[currtile]]; + dst = &pSpeedCels[frameidx]; + tbl = &pLightTbl[256 * j]; + for(k = lfs_adder; k; k--) { + *dst++ = tbl[*src++]; + } +#endif + frameidx += lfs_adder; + } + } else { + for(j = 1; j < blk_cnt; j++) { + SpeedFrameTbl[i][j] = frameidx; +#ifdef USE_ASM + __asm { + mov ebx, pDungeonCels + mov eax, currtile + shl eax, 2 + add ebx, eax + mov esi, pDungeonCels + add esi, [ebx] + mov edi, pSpeedCels + add edi, frameidx + mov ebx, j + shl ebx, 8 + add ebx, pLightTbl + mov ecx, 32 + l4_label1: + push ecx + mov edx, 32 + l4_label2: + xor eax, eax + lodsb + stosb + or al, al + js l4_label4 + sub edx, eax + mov ecx, eax + l4_label3: + lodsb + xlat + stosb + loop l4_label3 + or edx, edx + jz l4_label5 + jmp l4_label2 + l4_label4: + neg al + sub edx, eax + jnz l4_label2 + l4_label5: + pop ecx + loop l4_label1 + } +#else + src = &pDungeonCels[pFrameTable[currtile]]; + dst = &pSpeedCels[frameidx]; + tbl = &pLightTbl[256 * j]; + for(k = 32; k; k--) { + for(l = 32; l;) { + width = *src++; + *dst++ = width; + if(!(width & 0x80)) { + l -= width; + while(width) { + *dst++ = tbl[*src++]; + width--; + } + } else { + width = -(char)width; + l -= width; + } + } + } +#endif + frameidx += level_frame_sizes[i]; + } + } + } + + for(y = 0; y < MAXDUNY; y++) { + for(x = 0; x < MAXDUNX; x++) { + if(dPiece[x][y]) { + pMap = &dpiece_defs_map_2[x][y]; + for(i = 0; i < blocks; i++) { + if(pMap->mt[i]) { + for(m = 0; m < total_frames; m++) { + if((pMap->mt[i] & 0xFFF) == tile_defs[m]) { + pMap->mt[i] = m + level_frame_types[m] + 0x8000; + m = total_frames; + } + } + } + } + } + } + } +} + +int IsometricCoord(int x, int y) +{ + if(x < MAXDUNY - y) + return (y + y * y + x * (x + 2 * y + 3)) / 2; + + x = MAXDUNX - x - 1; + y = MAXDUNY - y - 1; + return MAXDUNX * MAXDUNY - ((y + y * y + x * (x + 2 * y + 3)) / 2) - 1; +} + +void SetSpeedCels() +{ + int x, y; + + for(x = 0; x < MAXDUNX; x++) { + for(y = 0; y < MAXDUNY; y++) { + dpiece_defs_map_1[IsometricCoord(x, y)] = dpiece_defs_map_2[x][y]; + } + } +} + +void SetDungeonMicros() +{ + int i, x, y, lv, blocks; + WORD *pPiece; + MICROS *pMap; + + if(leveltype != DTYPE_HELL) { + MicroTileLen = 10; + blocks = 10; + } else { + MicroTileLen = 12; + blocks = 16; + } + + for(y = 0; y < MAXDUNY; y++) { + for(x = 0; x < MAXDUNX; x++) { + lv = dPiece[x][y]; + pMap = &dpiece_defs_map_2[x][y]; + if(lv) { + lv--; + if(leveltype != DTYPE_HELL) + pPiece = (WORD *)&pLevelPieces[20 * lv]; + else + pPiece = (WORD *)&pLevelPieces[32 * lv]; + for(i = 0; i < blocks; i++) + pMap->mt[i] = pPiece[(i & 1) + blocks - 2 - (i & 0xE)]; + } else { + for(i = 0; i < blocks; i++) + pMap->mt[i] = 0; + } + } + } + + MakeSpeedCels(); + SetSpeedCels(); + + if(zoomflag) { + ViewDX = 640; + ViewDY = 352; + ViewBX = 10; + ViewBY = 11; + } else { + ViewDX = 384; + ViewDY = 224; + ViewBX = 6; + ViewBY = 7; + } +} + +void DRLG_InitTrans() +{ + memset(dTransVal, 0, 0x3100u); + memset(TransList, 0, 0x100u); + TransVal = 1; +} + +void DRLG_MRectTrans(int x1, int y1, int x2, int y2) +{ + int i, j; + + x1 = 2 * x1 + 17; + y1 = 2 * y1 + 17; + x2 = 2 * x2 + 16; + y2 = 2 * y2 + 16; + + for(j = y1; j <= y2; j++) { + for(i = x1; i <= x2; i++) { + dTransVal[i][j] = TransVal; + } + } + + TransVal++; +} + +void DRLG_RectTrans(int x1, int y1, int x2, int y2) +{ + int i; // esi + char *v5; // edx + int j; // eax + + for ( i = y1; i <= y2; ++i ) + { + if ( x1 <= x2 ) + { + v5 = &dTransVal[x1][i]; + j = x2 - x1 + 1; + do + { + *v5 = TransVal; + v5 += 112; + --j; + } + while ( j ); + } + } + ++TransVal; +} + +void DRLG_CopyTrans(int sx, int sy, int dx, int dy) +{ + dTransVal[dx][dy] = dTransVal[sx][sy]; +} + +void DRLG_ListTrans(int num, unsigned char *List) +{ + unsigned char *v2; // esi + int v3; // edi + unsigned char v4; // al + unsigned char *v5; // esi + unsigned char v6; // cl + unsigned char v7; // dl + unsigned char v8; // bl + + v2 = List; + if ( num > 0 ) + { + v3 = num; + do + { + v4 = *v2; + v5 = v2 + 1; + v6 = *v5++; + v7 = *v5++; + v8 = *v5; + v2 = v5 + 1; + DRLG_RectTrans(v4, v6, v7, v8); + --v3; + } + while ( v3 ); + } +} + +void DRLG_AreaTrans(int num, unsigned char *List) +{ + unsigned char *v2; // esi + int v3; // edi + unsigned char v4; // al + unsigned char *v5; // esi + unsigned char v6; // cl + unsigned char v7; // dl + unsigned char v8; // bl + + v2 = List; + if ( num > 0 ) + { + v3 = num; + do + { + v4 = *v2; + v5 = v2 + 1; + v6 = *v5++; + v7 = *v5++; + v8 = *v5; + v2 = v5 + 1; + DRLG_RectTrans(v4, v6, v7, v8); + --TransVal; + --v3; + } + while ( v3 ); + } + ++TransVal; +} + +void DRLG_InitSetPC() +{ + setpc_x = 0; + setpc_y = 0; + setpc_w = 0; + setpc_h = 0; +} + +void DRLG_SetPC() +{ + int i, j, x, y, w, h; + + w = 2 * setpc_w; + h = 2 * setpc_h; + x = 2 * setpc_x + 16; + y = 2 * setpc_y + 16; + + for(j = 0; j < h; j++) { + for(i = 0; i < w; i++) { + dFlags[i + x][j + y] |= 8; + } + } +} + +void Make_SetPC(int x, int y, int w, int h) +{ + int i, j, dx, dy, dh, dw; + + dw = 2 * w; + dh = 2 * h; + dx = 2 * x + 16; + dy = 2 * y + 16; + + for(j = 0; j < dh; j++) { + for(i = 0; i < dw; i++) { + dFlags[i + dx][j + dy] |= 8; + } + } +} + +BOOL DRLG_WillThemeRoomFit(int floor, int x, int y, int minSize, int maxSize, int *width, int *height) +{ + int ii, xx, yy; + int xSmallest, ySmallest; + int xArray[20], yArray[20]; + int xCount, yCount; + BOOL yFlag, xFlag; + + yFlag = TRUE; + xFlag = TRUE; + xCount = 0; + yCount = 0; + + if(x > DMAXX - maxSize && y > DMAXY - maxSize) { + return FALSE; + } + if(!SkipThemeRoom(x, y)) { + return FALSE; + } + + memset(xArray, 0, sizeof(xArray)); + memset(yArray, 0, sizeof(yArray)); + + for(ii = 0; ii < maxSize; ii++) { + if(xFlag) { + for(xx = x; xx < x + maxSize; xx++) { + if((unsigned char)dungeon[xx][y + ii] != floor) { + if(xx >= minSize) { + break; + } + xFlag = FALSE; + } else { + xCount++; + } + } + if(xFlag) { + xArray[ii] = xCount; + xCount = 0; + } + } + if(yFlag) { + for(yy = y; yy < y + maxSize; yy++) { + if((unsigned char)dungeon[x + ii][yy] != floor) { + if(yy >= minSize) { + break; + } + yFlag = FALSE; + } else { + yCount++; + } + } + if(yFlag) { + yArray[ii] = yCount; + yCount = 0; + } + } + } + + for(ii = 0; ii < minSize; ii++) { + if(xArray[ii] < minSize || yArray[ii] < minSize) { + return FALSE; + } + } + + xSmallest = xArray[0]; + ySmallest = yArray[0]; + + for(ii = 0; ii < maxSize; ii++) { + if(xArray[ii] < minSize || yArray[ii] < minSize) { + break; + } + if(xArray[ii] < xSmallest) { + xSmallest = xArray[ii]; + } + if(yArray[ii] < ySmallest) { + ySmallest = yArray[ii]; + } + } + + *width = xSmallest - 2; + *height = ySmallest - 2; + return TRUE; +} + +void DRLG_CreateThemeRoom(int themeIndex) +{ + int xx, yy; + + for(yy = themeLoc[themeIndex].y; yy < themeLoc[themeIndex].y + themeLoc[themeIndex].height; yy++) { + for(xx = themeLoc[themeIndex].x; xx < themeLoc[themeIndex].x + themeLoc[themeIndex].width; xx++) { + if(leveltype == DTYPE_CATACOMBS) { + if(yy == themeLoc[themeIndex].y + && xx >= themeLoc[themeIndex].x + && xx <= themeLoc[themeIndex].x + themeLoc[themeIndex].width + || yy == themeLoc[themeIndex].y + themeLoc[themeIndex].height - 1 + && xx >= themeLoc[themeIndex].x + && xx <= themeLoc[themeIndex].x + themeLoc[themeIndex].width) { + dungeon[xx][yy] = 2; + } else if(xx == themeLoc[themeIndex].x + && yy >= themeLoc[themeIndex].y + && yy <= themeLoc[themeIndex].y + themeLoc[themeIndex].height + || xx == themeLoc[themeIndex].x + themeLoc[themeIndex].width - 1 + && yy >= themeLoc[themeIndex].y + && yy <= themeLoc[themeIndex].y + themeLoc[themeIndex].height) { + dungeon[xx][yy] = 1; + } else { + dungeon[xx][yy] = 3; + } + } + if(leveltype == DTYPE_CAVES) { + if(yy == themeLoc[themeIndex].y + && xx >= themeLoc[themeIndex].x + && xx <= themeLoc[themeIndex].x + themeLoc[themeIndex].width + || yy == themeLoc[themeIndex].y + themeLoc[themeIndex].height - 1 + && xx >= themeLoc[themeIndex].x + && xx <= themeLoc[themeIndex].x + themeLoc[themeIndex].width) { + dungeon[xx][yy] = 134; + } else if(xx == themeLoc[themeIndex].x + && yy >= themeLoc[themeIndex].y + && yy <= themeLoc[themeIndex].y + themeLoc[themeIndex].height + || xx == themeLoc[themeIndex].x + themeLoc[themeIndex].width - 1 + && yy >= themeLoc[themeIndex].y + && yy <= themeLoc[themeIndex].y + themeLoc[themeIndex].height) { + dungeon[xx][yy] = 137; + } else { + dungeon[xx][yy] = 7; + } + } + if(leveltype == DTYPE_HELL) { + if(yy == themeLoc[themeIndex].y + && xx >= themeLoc[themeIndex].x + && xx <= themeLoc[themeIndex].x + themeLoc[themeIndex].width + || yy == themeLoc[themeIndex].y + themeLoc[themeIndex].height - 1 + && xx >= themeLoc[themeIndex].x + && xx <= themeLoc[themeIndex].x + themeLoc[themeIndex].width) { + dungeon[xx][yy] = 2; + } else if(xx == themeLoc[themeIndex].x + && yy >= themeLoc[themeIndex].y + && yy <= themeLoc[themeIndex].y + themeLoc[themeIndex].height + || xx == themeLoc[themeIndex].x + themeLoc[themeIndex].width - 1 + && yy >= themeLoc[themeIndex].y + && yy <= themeLoc[themeIndex].y + themeLoc[themeIndex].height) { + dungeon[xx][yy] = 1; + } else { + dungeon[xx][yy] = 6; + } + } + } + } + + if(leveltype == DTYPE_CATACOMBS) { + dungeon[themeLoc[themeIndex].x][themeLoc[themeIndex].y] = 8; + dungeon[themeLoc[themeIndex].x + themeLoc[themeIndex].width - 1][themeLoc[themeIndex].y] = 7; + dungeon[themeLoc[themeIndex].x][themeLoc[themeIndex].y + themeLoc[themeIndex].height - 1] = 9; + dungeon[themeLoc[themeIndex].x + themeLoc[themeIndex].width - 1][themeLoc[themeIndex].y + themeLoc[themeIndex].height - 1] = 6; + } + if(leveltype == DTYPE_CAVES) { + dungeon[themeLoc[themeIndex].x][themeLoc[themeIndex].y] = 150; + dungeon[themeLoc[themeIndex].x + themeLoc[themeIndex].width - 1][themeLoc[themeIndex].y] = 151; + dungeon[themeLoc[themeIndex].x][themeLoc[themeIndex].y + themeLoc[themeIndex].height - 1] = 152; + dungeon[themeLoc[themeIndex].x + themeLoc[themeIndex].width - 1][themeLoc[themeIndex].y + themeLoc[themeIndex].height - 1] = 138; + } + if(leveltype == DTYPE_HELL) { + dungeon[themeLoc[themeIndex].x][themeLoc[themeIndex].y] = 9; + dungeon[themeLoc[themeIndex].x + themeLoc[themeIndex].width - 1][themeLoc[themeIndex].y] = 16; + dungeon[themeLoc[themeIndex].x][themeLoc[themeIndex].y + themeLoc[themeIndex].height - 1] = 15; + dungeon[themeLoc[themeIndex].x + themeLoc[themeIndex].width - 1][themeLoc[themeIndex].y + themeLoc[themeIndex].height - 1] = 12; + } + + if(leveltype == DTYPE_CATACOMBS) { + switch(random(0, 2)) { + case 0: + dungeon[themeLoc[themeIndex].x + themeLoc[themeIndex].width - 1][themeLoc[themeIndex].y + themeLoc[themeIndex].height / 2] = 4; + break; + case 1: + dungeon[themeLoc[themeIndex].x + themeLoc[themeIndex].width / 2][themeLoc[themeIndex].y + themeLoc[themeIndex].height - 1] = 5; + break; + } + } + if(leveltype == DTYPE_CAVES) { + switch(random(0, 2)) { + case 0: + dungeon[themeLoc[themeIndex].x + themeLoc[themeIndex].width - 1][themeLoc[themeIndex].y + themeLoc[themeIndex].height / 2] = 147; + break; + case 1: + dungeon[themeLoc[themeIndex].x + themeLoc[themeIndex].width / 2][themeLoc[themeIndex].y + themeLoc[themeIndex].height - 1] = 146; + break; + } + } + if(leveltype == DTYPE_HELL) { + switch(random(0, 2)) { + case 0: + dungeon[themeLoc[themeIndex].x + themeLoc[themeIndex].width - 1][themeLoc[themeIndex].y + themeLoc[themeIndex].height / 2 - 1] = 53; + dungeon[themeLoc[themeIndex].x + themeLoc[themeIndex].width - 1][themeLoc[themeIndex].y + themeLoc[themeIndex].height / 2] = 6; + dungeon[themeLoc[themeIndex].x + themeLoc[themeIndex].width - 1][themeLoc[themeIndex].y + themeLoc[themeIndex].height / 2 + 1] = 52; + dungeon[themeLoc[themeIndex].x + themeLoc[themeIndex].width - 2][themeLoc[themeIndex].y + themeLoc[themeIndex].height / 2 - 1] = 54; + break; + case 1: + dungeon[themeLoc[themeIndex].x + themeLoc[themeIndex].width / 2 - 1][themeLoc[themeIndex].y + themeLoc[themeIndex].height - 1] = 57; + dungeon[themeLoc[themeIndex].x + themeLoc[themeIndex].width / 2][themeLoc[themeIndex].y + themeLoc[themeIndex].height - 1] = 6; + dungeon[themeLoc[themeIndex].x + themeLoc[themeIndex].width / 2 + 1][themeLoc[themeIndex].y + themeLoc[themeIndex].height - 1] = 56; + dungeon[themeLoc[themeIndex].x + themeLoc[themeIndex].width / 2][themeLoc[themeIndex].y + themeLoc[themeIndex].height - 2] = 59; + dungeon[themeLoc[themeIndex].x + themeLoc[themeIndex].width / 2 - 1][themeLoc[themeIndex].y + themeLoc[themeIndex].height - 2] = 58; + break; + } + } +} + +void DRLG_PlaceThemeRooms(int minSize, int maxSize, int floor, int freq, int rndSize) +{ + int v5; // ebx + //int v7; // eax + int v8; // esi + int v9; // edi + int v10; // eax + int v12; // eax + int v14; // eax + int v16; // eax + int v17; // edi + int v18; // esi + int v19; // ecx + int v20; // ecx + int v21; // eax + int minSize2; // [esp+10h] [ebp-1Ch] + int maxSize2; // [esp+14h] [ebp-18h] + unsigned char *v24; // [esp+18h] [ebp-14h] + signed int x_start; // [esp+1Ch] [ebp-10h] + int x; // [esp+20h] [ebp-Ch] + int width; // [esp+24h] [ebp-8h] + int height; // [esp+28h] [ebp-4h] + + v5 = 0; + maxSize2 = maxSize; + minSize2 = minSize; + themeCount = 0; + memset(themeLoc, 0, 0x14u); + do + { + x = 0; + x_start = 20; + v24 = (unsigned char *)dungeon + v5; + do + { + if ( *v24 == floor ) + { + if ( !random(0, freq) ) + { + //_LOBYTE(v7) = DRLG_WillThemeRoomFit(floor, x, v5, minSize2, maxSize2, &width, &height); + if ( DRLG_WillThemeRoomFit(floor, x, v5, minSize2, maxSize2, &width, &height) ) + { + if ( rndSize ) + { + v8 = minSize2 - 2; + v9 = maxSize2 - 2; + v10 = random(0, width - (minSize2 - 2) + 1); + v12 = minSize2 - 2 + random(0, v10); + if ( v12 < minSize2 - 2 || (width = v12, v12 > v9) ) + width = minSize2 - 2; + v14 = random(0, height - v8 + 1); + v16 = v8 + random(0, v14); + if ( v16 < v8 || v16 > v9 ) + v16 = minSize2 - 2; + height = v16; + } + else + { + v16 = height; + } + v17 = themeCount; + v18 = themeCount; + themeLoc[v18].x = x + 1; + themeLoc[v18].y = v5 + 1; + v19 = width; + themeLoc[v18].width = width; + themeLoc[v18].height = v16; + v20 = x + v19; + v21 = v5 + v16; + if ( leveltype == DTYPE_CAVES ) + DRLG_RectTrans(x_start, 2 * v5 + 20, 2 * v20 + 15, 2 * v21 + 15); + else + DRLG_MRectTrans(x + 1, v5 + 1, v20, v21); + themeLoc[v18].ttval = TransVal - 1; + DRLG_CreateThemeRoom(v17); + ++themeCount; + } + } + } + x_start += 2; + ++x; + v24 += 40; + } + while ( x_start < 100 ); + ++v5; + } + while ( v5 < 40 ); +} + +void DRLG_HoldThemeRooms() +{ + int i, x, y, xx, yy; + + for(i = 0; i < themeCount; i++) { + for(y = themeLoc[i].y; y < themeLoc[i].y + themeLoc[i].height - 1; y++) { + for(x = themeLoc[i].x; x < themeLoc[i].x + themeLoc[i].width - 1; x++) { + xx = 2 * x + 16; + yy = 2 * y + 16; + dFlags[xx][yy] |= 8; + dFlags[xx + 1][yy] |= 8; + dFlags[xx][yy + 1] |= 8; + dFlags[xx + 1][yy + 1] |= 8; + } + } + } +} + +BOOL SkipThemeRoom(int x, int y) +{ + int i; // ebx + THEME_LOC *v3; // eax + int v4; // esi + + i = 0; + if ( themeCount <= 0 ) + return 1; + v3 = themeLoc; + while ( 1 ) + { + if ( x >= v3->x - 2 && x <= v3->x + v3->width + 2 ) + { + v4 = v3->y; + if ( y >= v4 - 2 && y <= v4 + v3->height + 2 ) + break; + } + ++i; + ++v3; + if ( i >= themeCount ) + return 1; + } + return 0; +} + +void InitLevels() +{ + if ( !leveldebug ) + { + currlevel = 0; + leveltype = 0; + setlevel = 0; + } +} diff --git a/2020_03_31/Source/gendung.h b/2020_03_31/Source/gendung.h new file mode 100644 index 00000000..181f0252 --- /dev/null +++ b/2020_03_31/Source/gendung.h @@ -0,0 +1,91 @@ +//HEADER_GOES_HERE +#ifndef __GENDUNG_H__ +#define __GENDUNG_H__ + +extern unsigned char dungeon[40][40]; +extern BYTE pdungeon[40][40]; +extern char dflags[40][40]; +extern int setpc_x; // idb +extern int setpc_y; // idb +extern int setpc_w; // weak +extern int setpc_h; // weak +extern char *pSetPiece_2; +extern int setloadflag_2; // weak +extern BYTE *pSpecialCels; +extern BYTE *pMegaTiles; +extern BYTE *pLevelPieces; +extern BYTE *pDungeonCels; +extern BYTE *pSpeedCels; +extern int SpeedFrameTbl[128][16]; +extern char block_lvid[2049]; +extern int level_frame_count[MAXTILES]; +extern int tile_defs[MAXTILES]; +extern WORD level_frame_types[MAXTILES]; +extern int level_frame_sizes[MAXTILES]; +extern int nlevel_frames; // weak +extern BOOLEAN nBlockTable[2049]; +extern BOOLEAN nSolidTable[2049]; +extern BOOLEAN nTransTable[2049]; +extern BOOLEAN nMissileTable[2049]; +extern BOOLEAN nTrapTable[2049]; +extern int dminx; // weak +extern int dminy; // weak +extern int dmaxx; // weak +extern int dmaxy; // weak +extern int gnDifficulty; // idb +extern unsigned char leveltype; // weak +extern unsigned char currlevel; // idb +extern char setlevel; // weak +extern BYTE setlvlnum; // weak +extern char setlvltype; // weak +extern int ViewX; // idb +extern int ViewY; // idb +extern int ViewDX; // weak +extern int ViewDY; // weak +extern int ViewBX; // weak +extern int ViewBY; // weak +extern ScrollStruct ScrollInfo; +extern int LvlViewX; // weak +extern int LvlViewY; // weak +extern int MicroTileLen; +extern char TransVal; // weak +extern char TransList[256]; +extern int dPiece[MAXDUNX][MAXDUNY]; +extern MICROS dpiece_defs_map_2[MAXDUNX][MAXDUNY]; +extern MICROS dpiece_defs_map_1[MAXDUNX * MAXDUNY]; +extern char dTransVal[MAXDUNX][MAXDUNY]; +extern char dLight[MAXDUNX][MAXDUNY]; +extern char dPreLight[MAXDUNX][MAXDUNY]; +extern char dFlags[MAXDUNX][MAXDUNY]; +extern char dPlayer[MAXDUNX][MAXDUNY]; +extern int dMonster[MAXDUNX][MAXDUNY]; +extern char dDead[MAXDUNX][MAXDUNY]; +extern char dObject[MAXDUNX][MAXDUNY]; +extern char dItem[MAXDUNX][MAXDUNY]; +extern char dMissile[MAXDUNX][MAXDUNY]; +extern char dSpecial[MAXDUNX][MAXDUNY]; +extern int themeCount; +extern THEME_LOC themeLoc[MAXTHEMES]; + +void FillSolidBlockTbls(); +void MakeSpeedCels(); +int IsometricCoord(int x, int y); +void SetSpeedCels(); +void SetDungeonMicros(); +void DRLG_InitTrans(); +void DRLG_MRectTrans(int x1, int y1, int x2, int y2); +void DRLG_RectTrans(int x1, int y1, int x2, int y2); +void DRLG_CopyTrans(int sx, int sy, int dx, int dy); +void DRLG_ListTrans(int num, unsigned char *List); +void DRLG_AreaTrans(int num, unsigned char *List); +void DRLG_InitSetPC(); +void DRLG_SetPC(); +void Make_SetPC(int x, int y, int w, int h); +BOOL DRLG_WillThemeRoomFit(int floor, int x, int y, int minSize, int maxSize, int *width, int *height); +void DRLG_CreateThemeRoom(int themeIndex); +void DRLG_PlaceThemeRooms(int minSize, int maxSize, int floor, int freq, int rndSize); +void DRLG_HoldThemeRooms(); +BOOL SkipThemeRoom(int x, int y); +void InitLevels(); + +#endif /* __GENDUNG_H__ */ diff --git a/2020_03_31/Source/gmenu.cpp b/2020_03_31/Source/gmenu.cpp new file mode 100644 index 00000000..e3b34e0e --- /dev/null +++ b/2020_03_31/Source/gmenu.cpp @@ -0,0 +1,484 @@ +#include "diablo.h" + +void *optbar_cel; +BOOLEAN mouse_in_slider; // weak +void *PentSpin_cel; +TMenuItem *sgpCurrItem; +void *BigTGold_cel; +int menu_draw_ticks; // weak +char menu_spinner_frame; // weak +void (*sgpUpdateFunc)(TMenuItem *); +TMenuItem *sgpMenuItems; // idb +void *option_cel; +void *sgpLogo; +int num_menu_items; // weak + +const unsigned char lfontframe[127] = +{ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 37, 49, 38, 0, 39, 40, 47, + 42, 43, 41, 45, 52, 44, 53, 55, 36, 27, + 28, 29, 30, 31, 32, 33, 34, 35, 51, 50, + 0, 46, 0, 54, 0, 1, 2, 3, 4, 5, + 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 26, 42, 0, 43, 0, 0, 0, 1, 2, 3, + 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 20, 0, 21, 0 +}; +const unsigned char lfontkern[56] = +{ + 18, 33, 21, 26, 28, 19, 19, 26, 25, 11, + 12, 25, 19, 34, 28, 32, 20, 32, 28, 20, + 28, 36, 35, 46, 33, 33, 24, 11, 23, 22, + 22, 21, 22, 21, 21, 21, 32, 10, 20, 36, + 31, 17, 13, 12, 13, 18, 16, 11, 20, 21, + 11, 10, 12, 11, 21, 23 +}; + +void gmenu_draw_pause() +{ + if(currlevel != 0) { + RedBack(); + } + if(sgpMenuItems == NULL) { + light_table_index = 0; + gmenu_print_text(316, 336, "Pause"); + } +} + +void gmenu_print_text(int x, int y, char *pszStr) +{ + BYTE c; + + /// ASSERT: assert(pszStr); + while(*pszStr != '\0') { + c = gbFontTransTbl[(BYTE)*pszStr]; + pszStr++; + c = lfontframe[c]; + if(c != 0) { + CelDecodeLightOnly(x, y, (BYTE *)BigTGold_cel, c, 46); + } + x += lfontkern[c] + 2; + } +} + +void FreeGMenu() +{ + MemFreeDbg(sgpLogo); + MemFreeDbg(BigTGold_cel); + MemFreeDbg(PentSpin_cel); + MemFreeDbg(option_cel); + MemFreeDbg(optbar_cel); +} + +void gmenu_init_menu() +{ + menu_spinner_frame = 1; + sgpMenuItems = NULL; + sgpCurrItem = NULL; + sgpUpdateFunc = NULL; + num_menu_items = 0; + mouse_in_slider = FALSE; + + /// ASSERT: assert(! sgpLogo); + sgpLogo = DiabLoad("Data\\Diabsmal.CEL", NULL, 'MENU'); + BigTGold_cel = DiabLoad("Data\\BigTGold.CEL", NULL, 'MENU'); + PentSpin_cel = DiabLoad("Data\\PentSpin.CEL", NULL, 'MENU'); + option_cel = DiabLoad("Data\\option.CEL", NULL, 'MENU'); + optbar_cel = DiabLoad("Data\\optbar.CEL", NULL, 'MENU'); +} + +BOOL gmenu_is_active() +{ + return sgpMenuItems != NULL; +} + +void gmenu_set_items(TMenuItem *pMenuItems, void (*fnUpdate)(TMenuItem *)) +{ + TMenuItem *p; + + PauseMode = 0; + sgpMenuItems = pMenuItems; + mouse_in_slider = FALSE; + + sgpUpdateFunc = fnUpdate; + if(sgpUpdateFunc != NULL) { + sgpUpdateFunc(sgpMenuItems); + } + + num_menu_items = 0; + if(sgpMenuItems != NULL) { + for(p = sgpMenuItems; p->fnMenu != NULL; p++) { + num_menu_items++; + } + } + + sgpCurrItem = &sgpMenuItems[num_menu_items - 1]; + gmenu_up_down(TRUE); +} + +void gmenu_up_down(BOOL down) +{ + int i; + + if(sgpCurrItem == NULL) { + return; + } + + mouse_in_slider = FALSE; + i = num_menu_items; + if(num_menu_items != 0) { + while(i--) { + if(down) { + sgpCurrItem++; + if(sgpCurrItem->fnMenu == NULL) { + sgpCurrItem = sgpMenuItems; + } + } else { + if(sgpCurrItem == &sgpMenuItems[0]) { + sgpCurrItem = &sgpMenuItems[num_menu_items]; + } + sgpCurrItem--; + } + if(sgpCurrItem->dwFlags & 0x80000000) { + if(i != 0) { + PlaySFX(IS_TITLEMOV); + } + break; + } + } + } +} + +void gmenu_draw() +{ + int y, nTicks; + TMenuItem *p; + + if(sgpMenuItems == NULL) { + return; + } + + if(sgpUpdateFunc != NULL) { + sgpUpdateFunc(sgpMenuItems); + } + + CelDecodeOnly(236, 262, (BYTE *)sgpLogo, 1, 296); + + y = 320; + p = sgpMenuItems; + if(sgpMenuItems->fnMenu != NULL) { + while(p->fnMenu != NULL) { + gmenu_draw_menu_item(p, y); + y += 45; + p++; + } + } + + nTicks = GetTickCount(); + if(nTicks - menu_draw_ticks > 25) { + menu_spinner_frame++; + if(menu_spinner_frame == 9) { + menu_spinner_frame = 1; + } + menu_draw_ticks = nTicks; + } +} + +void gmenu_draw_menu_item(TMenuItem *pItem, int y) +{ + int x, sx, yy; + DWORD ticks, maxt, w; + + yy = y - 2; /* workaround, should be fixed */ + w = gmenu_get_lfont(pItem); + + if(pItem->dwFlags & 0x40000000) { + sx = (w >> 1) + 80; + CelDecodeOnly(sx, y - 10, (BYTE *)optbar_cel, 1, 287); + ticks = pItem->dwFlags & 0xFFF; + maxt = pItem->dwFlags & 0xFFF000; + maxt >>= 12; + if(maxt < 2) { + maxt = 2; + } + ticks <<= 8; + ticks /= maxt; + gmenu_clear_buffer(sx + 2, yy - 10, ticks + 13, 28); + sx += ticks; + CelDecodeOnly(sx + 2, y - 12, (BYTE *)option_cel, 1, 27); + } + + x = 320 - (w >> 1) + 64; + + if(pItem->dwFlags & 0x80000000) { + light_table_index = 0; + } else { + light_table_index = 15; + } + + gmenu_print_text(x, y, pItem->pszStr); + + if(pItem == sgpCurrItem) { + CelDecodeOnly(x - 54, y + 1, (BYTE *)PentSpin_cel, menu_spinner_frame, 48); + CelDecodeOnly(x + w + 4, y + 1, (BYTE *)PentSpin_cel, menu_spinner_frame, 48); + } +} + +void gmenu_clear_buffer(int x, int y, int width, int height) +{ + BYTE *p; + + /// ASSERT: assert(gpBuffer); + p = &gpBuffer[x + PitchTbl[y]]; + + while(height--) { + memset(p, 205, width); + p -= BUFFER_WIDTH; + } +} + +int gmenu_get_lfont(TMenuItem *pItem) +{ + BYTE c; + int len; + char *s; + + if(pItem->dwFlags & 0x40000000) { + return 490; + } + + len = 0; + s = pItem->pszStr; + while(*s != '\0') { + c = gbFontTransTbl[(BYTE)*s]; + s++; + len += lfontkern[lfontframe[c]] + 2; + } + + len -= 2; + return len; +} + +BOOL gmenu_presskeys(int vkey) +{ + if(sgpMenuItems == NULL) { + return FALSE; + } + + /// ASSERT: assert(sgpCurrItem); + + switch(vkey) { + case VK_SPACE: + return FALSE; + case VK_LEFT: + gmenu_left_right(FALSE); + break; + case VK_RIGHT: + gmenu_left_right(TRUE); + break; + case VK_UP: + gmenu_up_down(FALSE); + break; + case VK_DOWN: + gmenu_up_down(TRUE); + break; + case VK_RETURN: + /// ASSERT: assert(sgpCurrItem); + if(sgpCurrItem->dwFlags & 0x80000000) { + PlaySFX(IS_TITLEMOV); + sgpCurrItem->fnMenu(TRUE); + } + break; + case VK_ESCAPE: + PlaySFX(IS_TITLEMOV); + gmenu_set_items(NULL, NULL); + break; + } + + return TRUE; +} + +void gmenu_left_right(BOOL right) +{ + int ticks, maxt; + + if(!(sgpCurrItem->dwFlags & 0x40000000)) { + return; + } + + ticks = sgpCurrItem->dwFlags & 0xFFF; + maxt = sgpCurrItem->dwFlags & 0xFFF000; + maxt >>= 12; + + if(right) { + if(ticks == maxt) { + return; + } + ticks++; + } else { + if(ticks == 0) { + return; + } + ticks--; + } + + sgpCurrItem->dwFlags &= 0xFFFFF000; + sgpCurrItem->dwFlags |= ticks; + sgpCurrItem->fnMenu(FALSE); +} + +BOOL gmenu_on_mouse_move() +{ + int maxt; + long lOffset; + + if(!mouse_in_slider) { + return FALSE; + } + + /// ASSERT: assert(sgpCurrItem); + + gmenu_get_mouse_slider(&lOffset); + maxt = sgpCurrItem->dwFlags & 0xFFF000; + maxt >>= 12; + lOffset *= maxt; + lOffset /= 256; + sgpCurrItem->dwFlags &= 0xFFFFF000; + sgpCurrItem->dwFlags |= lOffset; + sgpCurrItem->fnMenu(FALSE); + return TRUE; +} + +BOOLEAN gmenu_get_mouse_slider(long *plOffset) +{ + /// ASSERT: assert(plOffset); + *plOffset = 282; + + if(MouseX < *plOffset) { + *plOffset = 0; + return FALSE; + } + if(MouseX > *plOffset + 256) { + *plOffset = 256; + return FALSE; + } + + *plOffset = MouseX - *plOffset; + return TRUE; +} + +BOOL gmenu_left_mouse(BOOL down) +{ + int my; + DWORD w; + long lOffset; + TMenuItem *pItem; + + if(!down) { + if(!mouse_in_slider) { + return FALSE; + } + mouse_in_slider = FALSE; + return TRUE; + } + + if(sgpMenuItems == NULL) { + return FALSE; + } + if(MouseY >= 352) { + return FALSE; + } + + my = MouseY - 117; + if(my < 0) { + return TRUE; + } + my /= 45; + if((DWORD)my >= num_menu_items) { + return TRUE; + } + + pItem = &sgpMenuItems[my]; + if(!(pItem->dwFlags & 0x80000000)) { + return TRUE; + } + + w = gmenu_get_lfont(pItem); + if(MouseX < 320 - (w >> 1)) { + return TRUE; + } + if(MouseX > 320 + (w >> 1)) { + return TRUE; + } + + sgpCurrItem = pItem; + PlaySFX(IS_TITLEMOV); + if(pItem->dwFlags & 0x40000000) { + mouse_in_slider = gmenu_get_mouse_slider(&lOffset); + gmenu_on_mouse_move(); + } else { + sgpCurrItem->fnMenu(TRUE); + } + + return TRUE; +} + +void gmenu_enable(TMenuItem *pMenuItem, BOOL enable) +{ + /// ASSERT: assert(pMenuItem); + + if(enable) { + pMenuItem->dwFlags |= 0x80000000; + } else { + pMenuItem->dwFlags &= ~0x80000000; + } +} + +void gmenu_set_slider_ticks(TMenuItem *pItem, int min, int max, int ticks) +{ + int maxt; + + /// ASSERT: assert(pItem); + maxt = pItem->dwFlags & 0xFFF000; + maxt >>= 12; + if(maxt < 2) { + maxt = 2; + } + ticks -= min; + ticks *= maxt; + ticks += (max - min - 1) / 2; + ticks /= max - min; + pItem->dwFlags &= 0xFFFFF000; + pItem->dwFlags |= ticks; +} + +int gmenu_get_slider_ticks(TMenuItem *pItem, int min, int max) +{ + int ticks, maxt; + + /// ASSERT: assert(pItem); + ticks = pItem->dwFlags & 0xFFF; + maxt = pItem->dwFlags & 0xFFF000; + maxt >>= 12; + if(maxt < 2) { + maxt = 2; + } + ticks *= max - min; + ticks += (maxt - 1) / 2; + ticks /= maxt; + ticks += min; + return ticks; +} + +void gmenu_set_max_ticks(TMenuItem *pItem, DWORD dwTicks) +{ + /// ASSERT: assert(pItem); + /// ASSERT: assert(dwTicks >= MIN_SLIDER_TICKS && dwTicks <= MAX_SLIDER_TICKS); + pItem->dwFlags &= 0xFF000FFF; + pItem->dwFlags |= (dwTicks << 12) & 0xFFF000; +} diff --git a/2020_03_31/Source/gmenu.h b/2020_03_31/Source/gmenu.h new file mode 100644 index 00000000..a90375a3 --- /dev/null +++ b/2020_03_31/Source/gmenu.h @@ -0,0 +1,44 @@ +//HEADER_GOES_HERE +#ifndef __GMENU_H__ +#define __GMENU_H__ + +extern void *optbar_cel; +extern BOOLEAN mouse_in_slider; // weak +extern void *PentSpin_cel; +extern TMenuItem *sgpCurrItem; +extern void *BigTGold_cel; +extern int menu_draw_ticks; // weak +extern char menu_spinner_frame; // weak +extern void (*sgpUpdateFunc)(TMenuItem *); +extern TMenuItem *sgpMenuItems; // idb +extern void *option_cel; +extern void *sgpLogo; +extern int num_menu_items; // weak + +void gmenu_draw_pause(); +void gmenu_print_text(int x, int y, char *pszStr); +void FreeGMenu(); +void gmenu_init_menu(); +BOOL gmenu_is_active(); +void gmenu_set_items(TMenuItem *pMenuItems, void (*fnUpdate)(TMenuItem *)); +void gmenu_up_down(BOOL down); +void gmenu_draw(); +void gmenu_draw_menu_item(TMenuItem *pItem, int y); +void gmenu_clear_buffer(int x, int y, int width, int height); +int gmenu_get_lfont(TMenuItem *pItem); +BOOL gmenu_presskeys(int vkey); +void gmenu_left_right(BOOL right); +BOOL gmenu_on_mouse_move(); +BOOLEAN gmenu_get_mouse_slider(long *plOffset); +BOOL gmenu_left_mouse(BOOL down); +void gmenu_enable(TMenuItem *pMenuItem, BOOL enable); +void gmenu_set_slider_ticks(TMenuItem *pItem, int min, int max, int ticks); +int gmenu_get_slider_ticks(TMenuItem *pItem, int min, int max); +void gmenu_set_max_ticks(TMenuItem *pItem, DWORD dwTicks); + +/* rdata */ + +extern const unsigned char lfontframe[127]; +extern const unsigned char lfontkern[56]; + +#endif /* __GMENU_H__ */ diff --git a/2020_03_31/Source/help.cpp b/2020_03_31/Source/help.cpp new file mode 100644 index 00000000..a910c4e8 --- /dev/null +++ b/2020_03_31/Source/help.cpp @@ -0,0 +1,217 @@ +#include "diablo.h" + +int help_select_line; // weak +int dword_634494; // weak +int helpflag; +int displayinghelp[22]; /* check, does nothing? */ +int HelpTop; // weak + +const char gszHelpText[] = +{ + "$Keyboard Shortcuts:|" + "F1: Open Help Screen|" + "Esc: Display Main Menu|" + "Tab: Display Auto-map|" + "Space: Hide all info screens|" + "S: Open Speedbook|" + "B: Open Spellbook|" + "I: Open Inventory screen|" + "C: Open Character screen|" + "Q: Open Quest log|" + "F: Reduce screen brightness|" + "G: Increase screen brightness|" + "Z: Zoom Game Screen|" + "+ / -: Zoom Automap|" + "1 - 8: Use Belt item|" + "F5, F6, F7, F8: Set hot key for skill or spell|" + "Shift + Left Click: Attack without moving|" + "|" + "$Movement:|" + "If you hold the mouse button down while moving, the character " + "will continue to move in that direction.|" + "|" + "$Combat:|" + "Holding down the shift key and then left-clicking allows the " + "character to attack without moving.|" + "|" + "$Auto-map:|" + "To access the auto-map, click the 'MAP' button on the " + "Information Bar or press 'TAB' on the keyboard. Zooming in and " + "out of the map is done with the + and - keys. Scrolling the map " + "uses the arrow keys.|" + "|" + "$Picking up Objects:|" + "Useable items that are small in size, such as potions or scrolls, " + "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 pressing " + "the corresponding number or right-clicking on the item.|" + "|" + "$Gold|" + "You can select a specific amount of gold to drop by right " + "clicking on a pile of gold in your inventory.|" + "|" + "$Skills & Spells:|" + "You can access your list of skills and spells by left-clicking on " + "the 'SPELLS' button in the interface bar. Memorized spells and " + "those available through staffs are listed here. Left-clicking on " + "the spell you wish to cast will ready the spell. A readied spell " + "may be cast by simply right-clicking in the play area.|" + "|" + "$Using the Speedbook for Spells|" + "Left-clicking on the 'readied spell' button will open the 'Speedbook' " + "which allows you to select a skill or spell for immediate use. " + "To use a readied skill or spell, simply right-click in the main play " + "area.|" + "|" + "$Setting Spell Hotkeys|" + "You can assign up to four Hot Keys for skills, spells or scrolls. " + "Start by opening the 'speedbook' as described in the section above. " + "Press the F5, F6, F7 or F8 keys after highlighting the spell you " + "wish to assign.|" + "|" + "$Spell Books|" + "Reading more than one book increases your knowledge of that " + "spell, allowing you to cast the spell more effectively.|" + "&" +}; + +void InitHelp() +{ + helpflag = 0; + dword_634494 = 0; + displayinghelp[0] = 0; +} + +void DrawHelp() +{ + int i, c, w; + char col; + const char *s; + + DrawSTextHelp(); + DrawQTextBack(); + PrintSString(0, 2, 1, "Diablo Help", COL_GOLD, 0); + DrawSLine(5); + + s = gszHelpText; + + for(i = 0; i < help_select_line; i++) { + c = 0; + w = 0; + while(*s == '\0') { + s++; + } + if(*s == '$') { + s++; + } + if(*s == '&') { + continue; + } + while(*s != '|' && w < 577) { + while(*s == '\0') { + s++; + } + tempstr[c] = *s; + w += fontkern[fontframe[gbFontTransTbl[(BYTE)tempstr[c]]]] + 1; + c++; + s++; + } + if(w >= 577) { + c--; + while(tempstr[c] != ' ') { + s--; + c--; + } + } + if(*s == '|') { + s++; + } + } + for(i = 7; i < 22; i++) { + c = 0; + w = 0; + while(*s == '\0') { + s++; + } + if(*s == '$') { + s++; + col = COL_RED; + } else { + col = COL_WHITE; + } + if(*s == '&') { + HelpTop = help_select_line; + continue; + } + while(*s != '|' && w < 577) { + while(*s == '\0') { + s++; + } + tempstr[c] = *s; + w += fontkern[fontframe[gbFontTransTbl[(BYTE)tempstr[c]]]] + 1; + c++; + s++; + } + if(w >= 577) { + c--; + while(tempstr[c] != ' ') { + s--; + c--; + } + } + if(c != 0) { + tempstr[c] = '\0'; + DrawHelpLine(0, i, tempstr, col); + } + if(*s == '|') { + s++; + } + } + + PrintSString(0, 23, 1, "Press ESC to end or the arrow keys to scroll.", COL_GOLD, 0); +} + +void DrawHelpLine(int always_0, int help_line_nr, char *text, char color) +{ + signed int v4; // ebx + int v5; // edi + unsigned char i; // al + unsigned char v7; // al + int v8; // esi + + v4 = 0; + v5 = PitchTbl[SStringY[help_line_nr] + 204] + always_0 + 96; + for ( i = *text; *text; i = *text ) + { + ++text; + v7 = fontframe[gbFontTransTbl[i]]; + v8 = v7; + v4 += fontkern[v7] + 1; + if ( v7 ) + { + if ( v4 <= 577 ) + PrintChar(v5, v7, color); + } + v5 += fontkern[v8] + 1; + } +} + +void DisplayHelp() +{ + help_select_line = 0; + helpflag = 1; + HelpTop = 5000; +} + +void HelpScrollUp() +{ + if ( help_select_line > 0 ) + --help_select_line; +} + +void HelpScrollDown() +{ + if ( help_select_line < HelpTop ) + ++help_select_line; +} diff --git a/2020_03_31/Source/help.h b/2020_03_31/Source/help.h new file mode 100644 index 00000000..84865ca2 --- /dev/null +++ b/2020_03_31/Source/help.h @@ -0,0 +1,21 @@ +//HEADER_GOES_HERE +#ifndef __HELP_H__ +#define __HELP_H__ + +extern int help_select_line; // weak +extern int dword_634494; // weak +extern int helpflag; +extern int displayinghelp[22]; +extern int HelpTop; // weak + +void InitHelp(); +void DrawHelp(); +void DrawHelpLine(int always_0, int help_line_nr, char *text, char color); +void DisplayHelp(); +void HelpScrollUp(); +void HelpScrollDown(); + +/* rdata */ +extern const char gszHelpText[]; + +#endif /* __HELP_H__ */ diff --git a/2020_03_31/Source/init.cpp b/2020_03_31/Source/init.cpp new file mode 100644 index 00000000..5a2faab9 --- /dev/null +++ b/2020_03_31/Source/init.cpp @@ -0,0 +1,486 @@ +#include "diablo.h" +#include "../3rdParty/Storm/Source/storm.h" +#include "../DiabloUI/diabloui.h" + +_SNETVERSIONDATA fileinfo; +int gbActive; // weak +char diablo_exe_path[260]; +void *unused_mpq; +char patch_rt_mpq_path[260]; +WNDPROC CurrentProc; +void *diabdat_mpq; +char diabdat_mpq_path[260]; +void *patch_rt_mpq; +BOOL killed_mom_parent; // weak +_bool screensaver_enabled_prev; + +/* data */ + +char gszVersionNumber[260] = "internal version unknown"; +char gszProductName[260] = "Diablo v1.09"; + +void init_cleanup(BOOL show_cursor) +{ + int v1; // edi + + v1 = show_cursor; + pfile_flush_W(); + init_disable_screensaver(0); + init_run_office_from_start_menu(); + if ( diabdat_mpq ) + { + SFileCloseArchive(diabdat_mpq); + diabdat_mpq = 0; + } + if ( patch_rt_mpq ) + { + SFileCloseArchive(patch_rt_mpq); + patch_rt_mpq = 0; + } + if ( unused_mpq ) + { + SFileCloseArchive(unused_mpq); + unused_mpq = 0; + } + UiDestroy(); + effects_cleanup_sfx(); + sound_cleanup(); + NetClose(); + dx_cleanup(); + engine_debug_trap(v1); + StormDestroy(); + if ( v1 ) + ShowCursor(1); +} + +void init_run_office_from_start_menu() +{ + LPITEMIDLIST idl; + + if(!killed_mom_parent) { + return; + } + + killed_mom_parent = FALSE; + char szPath[256] = ""; /// BUGFIX: size should be at least 'MAX_PATH' + idl = NULL; + + if(SHGetSpecialFolderLocation(GetDesktopWindow(), CSIDL_STARTMENU, &idl) == NOERROR) { + SHGetPathFromIDList(idl, szPath); + init_run_office(szPath); + } +} + +void init_run_office(char *dir) +{ + HANDLE hSearch; + WIN32_FIND_DATA find; + char szFirst[MAX_PATH]; + + strcpy(szFirst, dir); + if(szFirst[0] != '\0' && szFirst[strlen(szFirst) - 1] == '\\') { + strcat(szFirst, "*"); + } else { + strcat(szFirst, "\\*"); + } + hSearch = FindFirstFile(szFirst, &find); + if(hSearch == INVALID_HANDLE_VALUE) { + return; + } + + while(1) { + if(find.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { + if(strcmp(find.cFileName, ".") != 0 && strcmp(find.cFileName, "..") != 0) { + char szNext[MAX_PATH] = ""; + if(dir[0] != '\0' && dir[strlen(dir) - 1] == '\\') { + sprintf(szNext, "%s%s\\", dir, find.cFileName); + } else { + sprintf(szNext, "%s\\%s\\", dir, find.cFileName); + } + init_run_office(szNext); + } + } else if(_strcmpi(find.cFileName, "Microsoft Office Shortcut Bar.lnk") == 0) { + ShellExecute(GetDesktopWindow(), "open", find.cFileName, "", dir, SW_SHOWNORMAL); + } + if(!FindNextFile(hSearch, &find)) { + break; + } + } + + FindClose(hSearch); +} + +void init_disable_screensaver(_bool disable) +{ + _bool v1; // al + char Data[16]; // [esp+4h] [ebp-20h] + DWORD Type; // [esp+14h] [ebp-10h] + DWORD cbData; // [esp+18h] [ebp-Ch] + HKEY phkResult; // [esp+1Ch] [ebp-8h] + _bool v6; // [esp+20h] [ebp-4h] + + v6 = disable; + if ( !RegOpenKeyEx(HKEY_CURRENT_USER, "Control Panel\\Desktop", 0, KEY_READ|KEY_WRITE, &phkResult) ) + { + if ( v6 ) + { + cbData = 16; + if ( !RegQueryValueEx(phkResult, "ScreenSaveActive", 0, &Type, (LPBYTE)Data, &cbData) ) + screensaver_enabled_prev = Data[0] != '0'; + v1 = 0; + } + else + { + v1 = screensaver_enabled_prev; + } + Data[1] = 0; + Data[0] = (v1 != 0) + '0'; + RegSetValueEx(phkResult, "ScreenSaveActive", 0, REG_SZ, (const BYTE *)Data, 2u); + RegCloseKey(phkResult); + } +} + +void init_create_window(int nCmdShow) +{ + int nHeight; // eax + HWND hWnd; // esi + WNDCLASSEXA wcex; // [esp+8h] [ebp-34h] + int nWidth; // [esp+38h] [ebp-4h] + + init_kill_mom_parent(); + pfile_init_save_directory(); + memset(&wcex, 0, sizeof(wcex)); + wcex.cbSize = sizeof(wcex); + wcex.style = CS_HREDRAW|CS_VREDRAW; + wcex.lpfnWndProc = WindowProc; + wcex.hInstance = ghInst; + wcex.hIcon = LoadIcon(ghInst, MAKEINTRESOURCE(IDI_ICON1)); + wcex.hCursor = LoadCursor(0, IDC_ARROW); + wcex.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); + wcex.lpszMenuName = "DIABLO"; + wcex.lpszClassName = "DIABLO"; + wcex.hIconSm = (HICON)LoadImage(ghInst, MAKEINTRESOURCE(IDI_ICON1), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR); + if ( !RegisterClassEx(&wcex) ) + app_fatal("Unable to register window class"); + if ( GetSystemMetrics(SM_CXSCREEN) >= 640 ) + nWidth = GetSystemMetrics(SM_CXSCREEN); + else + nWidth = 640; + if ( GetSystemMetrics(SM_CYSCREEN) >= 480 ) + nHeight = GetSystemMetrics(SM_CYSCREEN); + else + nHeight = 480; + hWnd = CreateWindowEx(0, "DIABLO", "DIABLO", WS_POPUP, 0, 0, nWidth, nHeight, NULL, NULL, ghInst, NULL); + if ( !hWnd ) + app_fatal("Unable to create main window"); + ShowWindow(hWnd, SW_SHOWNORMAL); // nCmdShow used only in beta: ShowWindow(hWnd, nCmdShow) + UpdateWindow(hWnd); + init_await_mom_parent_exit(); + dx_init(hWnd); + BlackPalette(); + snd_init(hWnd); + init_archives(); + init_disable_screensaver(1); +} + +void init_kill_mom_parent() +{ + HWND v0; // eax + + v0 = init_find_mom_parent(); + if ( v0 ) + { + PostMessage(v0, WM_CLOSE, 0, 0); + killed_mom_parent = TRUE; + } +} + +HWND init_find_mom_parent() +{ + HWND i; // eax + HWND v1; // esi + char ClassName[256]; // [esp+4h] [ebp-100h] + + for ( i = GetForegroundWindow(); ; i = GetWindow(v1, GW_HWNDNEXT) ) + { + v1 = i; + if ( !i ) + break; + GetClassName(i, ClassName, 255); + if ( !_strcmpi(ClassName, "MOM Parent") ) + break; + } + return v1; +} + +void init_await_mom_parent_exit() +{ + DWORD v0; // edi + + v0 = GetTickCount(); + do + { + if ( !init_find_mom_parent() ) + break; + Sleep(250); + } + while ( GetTickCount() - v0 <= 4000 ); +} + +void init_archives() +{ + void *a1; // [esp+8h] [ebp-8h] +#ifdef COPYPROT + int v1; // [esp+Ch] [ebp-4h] +#endif + + fileinfo.size = 20; + fileinfo.versionstring = gszVersionNumber; + fileinfo.executablefile = diablo_exe_path; + fileinfo.originalarchivefile = diabdat_mpq_path; + fileinfo.patcharchivefile = patch_rt_mpq_path; + init_get_file_info(); +#ifdef COPYPROT + while ( 1 ) + { +#endif + diabdat_mpq = init_test_access(diabdat_mpq_path, "\\diabdat.mpq", "DiabloCD", 1000, 1); +#ifdef COPYPROT + if ( diabdat_mpq ) + break; + UiCopyProtError(&v1); + if ( v1 == COPYPROT_CANCEL ) + FileErrDlg("diabdat.mpq"); + } +#endif + if ( !WOpenFile("ui_art\\title.pcx", &a1, 1) ) + FileErrDlg("Main program archive: diabdat.mpq"); + WCloseFile(a1); + patch_rt_mpq = init_test_access(patch_rt_mpq_path, "\\patch_rt.mpq", "DiabloInstall", 2000, 0); +} + +void *init_test_access(char *mpq_path, char *mpq_name, char *reg_loc, int flags, _bool on_cd) +{ + char *v5; // esi + char *v7; // eax + char Filename[260]; // [esp+Ch] [ebp-314h] + char Buffer[260]; // [esp+110h] [ebp-210h] + char v15[260]; // [esp+214h] [ebp-10Ch] + char *mpq_namea; // [esp+318h] [ebp-8h] + void *archive; // [esp+31Ch] [ebp-4h] + + mpq_namea = mpq_name; + v5 = mpq_path; + if ( !GetCurrentDirectory(0x104u, Buffer) ) + app_fatal("Can't get program path"); + init_strip_trailing_slash(Buffer); + if ( !SFileSetBasePath(Buffer) ) + app_fatal("SFileSetBasePath"); + if ( !GetModuleFileName(ghInst, Filename, 0x104u) ) + app_fatal("Can't get program name"); + v7 = strrchr(Filename, '\\'); + if ( v7 ) + *v7 = 0; + init_strip_trailing_slash(Filename); + strcpy(v5, Buffer); + strcat(v5, mpq_namea); +#ifdef COPYPROT + if ( SFileOpenArchive(v5, flags, on_cd, &archive) ) +#else + if ( SFileOpenArchive(v5, flags, 0, &archive) ) +#endif + return archive; + if ( strcmp(Filename, Buffer) ) + { + strcpy(v5, Filename); + strcat(v5, mpq_namea); +#ifdef COPYPROT + if ( SFileOpenArchive(v5, flags, on_cd, &archive) ) +#else + if ( SFileOpenArchive(v5, flags, 0, &archive) ) +#endif + return archive; + } + v15[0] = 0; + if ( reg_loc ) + { + if ( SRegLoadString("Archives", (const char *)reg_loc, 0, v15, 260) ) + { + init_strip_trailing_slash(v15); + strcpy(v5, v15); + strcat(v5, mpq_namea); +#ifdef COPYPROT + if ( SFileOpenArchive(v5, flags, on_cd, &archive) ) +#else + if ( SFileOpenArchive(v5, flags, 0, &archive) ) +#endif + return archive; + } + } + if ( on_cd && init_read_test_file(v15, mpq_namea, flags, &archive) ) + { + strcpy(v5, v15); + return archive; + } + return 0; +} + +char *init_strip_trailing_slash(char *path) +{ + char *result; // eax + + result = strrchr(path, '\\'); + if ( result ) + { + if ( !result[1] ) + *result = 0; + } + return result; +} + +BOOL init_read_test_file(char *pszPath, char *pszArchive, int flags, HANDLE *phArchive) +{ + DWORD dwSize; + char *pszDrive, *pszRoot; + char szDrive[MAX_PATH]; + + dwSize = GetLogicalDriveStrings(sizeof(szDrive), szDrive); + if(dwSize == 0 || dwSize > sizeof(szDrive)) { + return FALSE; + } + + while(*pszArchive == '\\') { + pszArchive++; + } + + pszDrive = szDrive; + while(*pszDrive != '\0') { + pszRoot = pszDrive; + while(*pszDrive++ != '\0'); + if(GetDriveType(pszRoot) == DRIVE_CDROM) { + strcpy(pszPath, pszRoot); + strcat(pszPath, pszArchive); + if(SFileOpenArchive(pszPath, flags, 1, phArchive)) { + return TRUE; + } + } + } + + return FALSE; +} + +void init_get_file_info() +{ + int v0; // eax + DWORD v1; // edi + void *v2; // ebx + unsigned int uBytes; // [esp+8h] [ebp-Ch] + DWORD dwHandle; // [esp+Ch] [ebp-8h] + VS_FIXEDFILEINFO *lpBuffer; // [esp+10h] [ebp-4h] + + if ( GetModuleFileName(ghInst, diablo_exe_path, 0x104u) ) + { + v0 = GetFileVersionInfoSize(diablo_exe_path, &dwHandle); + v1 = v0; + if ( v0 ) + { + v2 = DiabloAllocPtr(v0); + if ( GetFileVersionInfo(diablo_exe_path, 0, v1, v2) ) + { + if ( VerQueryValue(v2, "\\", (LPVOID *)&lpBuffer, &uBytes) ) + sprintf( + gszVersionNumber, + "version %d.%d.%d.%d", + lpBuffer->dwProductVersionMS >> 16, + lpBuffer->dwProductVersionMS & 0xFFFF, + lpBuffer->dwProductVersionLS >> 16, + lpBuffer->dwProductVersionLS & 0xFFFF); + } + mem_free_dbg(v2); + } + } +} + +LRESULT CALLBACK MainWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + switch(uMsg) { + case WM_CREATE: + ghMainWnd = hWnd; + break; + case WM_DESTROY: + init_cleanup(TRUE); + ghMainWnd = NULL; + PostQuitMessage(0); + break; + case WM_PAINT: + force_redraw = 255; + break; + case WM_CLOSE: + case WM_ERASEBKGND: + return 0; + case WM_ACTIVATEAPP: + init_activate_window(hWnd, wParam); + break; +#ifdef _DEBUG + case WM_SYSKEYUP: + if(wParam == VK_RETURN) { + fullscreen = !fullscreen; + dx_reinit(); + return 0; + } + break; +#endif + case WM_QUERYNEWPALETTE: + SDrawRealizePalette(); + return 1; + case WM_PALETTECHANGED: + if((HWND)wParam != hWnd) { + SDrawRealizePalette(); + } + break; + } + + return DefWindowProc(hWnd, uMsg, wParam, lParam); +} + +void init_activate_window(HWND hWnd, BOOL bActive) +{ + LONG dwNewLong; // eax + + gbActive = bActive; + UiAppActivate(bActive); + dwNewLong = GetWindowLong(hWnd, GWL_STYLE); + + if ( gbActive && fullscreen ) + dwNewLong &= ~WS_SYSMENU; + else + dwNewLong |= WS_SYSMENU; + + SetWindowLong(hWnd, GWL_STYLE, dwNewLong); + + if ( gbActive ) + { + force_redraw = 255; + ResetPal(); + } +} + +LRESULT __stdcall WindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) +{ + LRESULT result; // eax + + if ( CurrentProc ) + result = CurrentProc(hWnd, Msg, wParam, lParam); + else + result = MainWndProc(hWnd, Msg, wParam, lParam); + return result; +} + +WNDPROC SetWindowProc(WNDPROC NewProc) +{ + WNDPROC OldProc; // eax + + OldProc = CurrentProc; + CurrentProc = NewProc; + return OldProc; +} diff --git a/2020_03_31/Source/init.h b/2020_03_31/Source/init.h new file mode 100644 index 00000000..d87a2cf6 --- /dev/null +++ b/2020_03_31/Source/init.h @@ -0,0 +1,40 @@ +//HEADER_GOES_HERE +#ifndef __INIT_H__ +#define __INIT_H__ + +extern _SNETVERSIONDATA fileinfo; +extern int gbActive; // weak +extern char diablo_exe_path[260]; +extern void *unused_mpq; +extern char patch_rt_mpq_path[260]; +extern WNDPROC CurrentProc; +extern void *diabdat_mpq; +extern char diabdat_mpq_path[260]; +extern void *patch_rt_mpq; +extern BOOL killed_mom_parent; // weak +extern _bool screensaver_enabled_prev; + +void init_cleanup(BOOL show_cursor); +void init_run_office_from_start_menu(); +void init_run_office(char *dir); +void init_disable_screensaver(_bool disable); +void init_create_window(int nCmdShow); +void init_kill_mom_parent(); +HWND init_find_mom_parent(); +void init_await_mom_parent_exit(); +void init_archives(); +void *init_test_access(char *mpq_path, char *mpq_name, char *reg_loc, int flags, _bool on_cd); +char *init_strip_trailing_slash(char *path); +BOOL init_read_test_file(char *pszPath, char *pszArchive, int flags, HANDLE *phArchive); +void init_get_file_info(); +LRESULT CALLBACK MainWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); +void init_activate_window(HWND hWnd, BOOL bActive); +LRESULT __stdcall WindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); +WNDPROC SetWindowProc(WNDPROC NewProc); + +/* data */ + +extern char gszVersionNumber[260]; +extern char gszProductName[260]; + +#endif /* __INIT_H__ */ diff --git a/2020_03_31/Source/interfac.cpp b/2020_03_31/Source/interfac.cpp new file mode 100644 index 00000000..8ca57cfd --- /dev/null +++ b/2020_03_31/Source/interfac.cpp @@ -0,0 +1,420 @@ +#include "diablo.h" +#include "../3rdParty/Storm/Source/storm.h" + +void *sgpBackCel; +int sgdwProgress; +int progress_id; // idb + +const unsigned char progress_bar_colours[3] = { 138u, 43u, 254u }; +const int progress_bar_screen_pos[3][2] = { { 53, 37 }, { 53, 421 }, { 53, 37 } }; + +void interface_msg_pump() +{ + MSG Msg; // [esp+8h] [ebp-1Ch] + + while ( PeekMessage(&Msg, NULL, 0, 0, PM_REMOVE) ) + { + if ( Msg.message != WM_QUIT ) + { + TranslateMessage(&Msg); + DispatchMessage(&Msg); + } + } +} + +BOOL IncProgress() +{ + interface_msg_pump(); + sgdwProgress += 15; + if ( (unsigned int)sgdwProgress > 0x216 ) + sgdwProgress = 534; + if ( sgpBackCel ) + DrawCutscene(); + return (unsigned int)sgdwProgress >= 0x216; +} + +void DrawCutscene() +{ + unsigned int v0; // esi + + lock_buf(1); + CelDecodeOnly(64, 639, (BYTE *)sgpBackCel, 1, 640); + v0 = 0; + if ( sgdwProgress ) + { + do + DrawProgress( + progress_bar_screen_pos[progress_id][0] + v0++ + 64, + progress_bar_screen_pos[progress_id][1] + 160, + progress_id); + while ( v0 < sgdwProgress ); + } + unlock_buf(1); + force_redraw = 255; + scrollrt_draw_game_screen(0); +} + +void DrawProgress(int screen_x, int screen_y, int progress_id) +{ + _BYTE *v3; // eax + signed int v4; // ecx + + v3 = &gpBuffer[PitchTbl[screen_y] + screen_x]; + v4 = 22; + do + { + *v3 = progress_bar_colours[progress_id]; + v3 += 768; + --v4; + } + while ( v4 ); +} + +void ShowProgress(unsigned int uMsg) +{ + WNDPROC saveProc; + + gbSomebodyWonGameKludge = FALSE; + plrmsg_delay(TRUE); + + /// ASSERT: assert(ghMainWnd); + saveProc = SetWindowProc(DisableInputWndProc); + + interface_msg_pump(); + ClearScreenBuffer(); + scrollrt_draw_game_screen(TRUE); + InitCutscene(uMsg); + BlackPalette(); + DrawCutscene(); + PaletteFadeIn(8); + IncProgress(); + sound_init(); + IncProgress(); + + switch(uMsg) { + case WM_DIABLOADGAME: + IncProgress(); + LoadGame(TRUE); + IncProgress(); + break; + case WM_DIABNEWGAME: + IncProgress(); + FreeGameMem(); + IncProgress(); + pfile_remove_temp_files(); + LoadGameLevel(TRUE, 0); + IncProgress(); + break; + case WM_DIABNEXTLVL: + IncProgress(); + if(gbMaxPlayers == 1) { + SaveLevel(); + } else { + DeltaSaveLevel(); + } + FreeGameMem(); + currlevel++; + leveltype = gnLevelTypeTbl[currlevel]; + /// ASSERT: assert(plr[myplr].plrlevel == currlevel); + IncProgress(); + LoadGameLevel(FALSE, 0); + IncProgress(); + break; + case WM_DIABPREVLVL: + IncProgress(); + if(gbMaxPlayers == 1) { + SaveLevel(); + } else { + DeltaSaveLevel(); + } + IncProgress(); + FreeGameMem(); + currlevel--; + leveltype = gnLevelTypeTbl[currlevel]; + /// ASSERT: assert(plr[myplr].plrlevel == currlevel); + IncProgress(); + LoadGameLevel(FALSE, 1); + IncProgress(); + break; + case WM_DIABSETLVL: + SetReturnLvlPos(); + if(gbMaxPlayers == 1) { + SaveLevel(); + } else { + DeltaSaveLevel(); + } + setlevel = TRUE; + leveltype = setlvltype; + FreeGameMem(); + IncProgress(); + LoadGameLevel(FALSE, 2); + IncProgress(); + break; + case WM_DIABRTNLVL: + if(gbMaxPlayers == 1) { + SaveLevel(); + } else { + DeltaSaveLevel(); + } + setlevel = FALSE; + FreeGameMem(); + IncProgress(); + GetReturnLvlPos(); + LoadGameLevel(FALSE, 3); + IncProgress(); + break; + case WM_DIABWARPLVL: + IncProgress(); + if(gbMaxPlayers == 1) { + SaveLevel(); + } else { + DeltaSaveLevel(); + } + FreeGameMem(); + GetPortalLevel(); + IncProgress(); + LoadGameLevel(FALSE, 5); + IncProgress(); + break; + case WM_DIABTOWNWARP: + IncProgress(); + if(gbMaxPlayers == 1) { + SaveLevel(); + } else { + DeltaSaveLevel(); + } + FreeGameMem(); + currlevel = plr[myplr].plrlevel; + leveltype = gnLevelTypeTbl[currlevel]; + /// ASSERT: assert(plr[myplr].plrlevel == currlevel); + IncProgress(); + LoadGameLevel(FALSE, 6); + IncProgress(); + break; + case WM_DIABTWARPUP: + IncProgress(); + if(gbMaxPlayers == 1) { + SaveLevel(); + } else { + DeltaSaveLevel(); + } + FreeGameMem(); + currlevel = plr[myplr].plrlevel; + leveltype = gnLevelTypeTbl[currlevel]; + /// ASSERT: assert(plr[myplr].plrlevel == currlevel); + IncProgress(); + LoadGameLevel(FALSE, 7); + IncProgress(); + break; + case WM_DIABRETOWN: + IncProgress(); + if(gbMaxPlayers == 1) { + SaveLevel(); + } else { + DeltaSaveLevel(); + } + FreeGameMem(); + currlevel = plr[myplr].plrlevel; + leveltype = gnLevelTypeTbl[currlevel]; + /// ASSERT: assert(plr[myplr].plrlevel == currlevel); + IncProgress(); + LoadGameLevel(FALSE, 0); + IncProgress(); + break; + } + + /// ASSERT: assert(ghMainWnd); + + PaletteFadeOut(8); + FreeInterface(); + + saveProc = SetWindowProc(saveProc); + /// ASSERT: assert(saveProc == DisableInputWndProc); + + NetSendCmdLocParam1(TRUE, CMD_PLAYER_JOINLEVEL, plr[myplr].WorldX, plr[myplr].WorldY, plr[myplr].plrlevel); + plrmsg_delay(FALSE); + ResetPal(); + + if(gbSomebodyWonGameKludge && plr[myplr].plrlevel == 16) { + PrepDoEnding(); + } + + gbSomebodyWonGameKludge = FALSE; +} + +void FreeInterface() +{ + void *v0; // ecx + + v0 = sgpBackCel; + sgpBackCel = 0; + mem_free_dbg(v0); +} + +void InitCutscene(unsigned int uMsg) +{ + /// ASSERT: assert(! sgpBackCel); + + switch(uMsg) { + case WM_DIABNEXTLVL: + switch(gnLevelTypeTbl[currlevel]) { + case 0: + sgpBackCel = DiabLoad("Gendata\\Cuttt.CEL", NULL, 'PROG'); + LoadPalette("Gendata\\Cuttt.pal"); + progress_id = 1; + break; + case 1: + sgpBackCel = DiabLoad("Gendata\\Cutl1d.CEL", NULL, 'PROG'); + LoadPalette("Gendata\\Cutl1d.pal"); + progress_id = 0; + break; + case 2: + sgpBackCel = DiabLoad("Gendata\\Cut2.CEL", NULL, 'PROG'); + LoadPalette("Gendata\\Cut2.pal"); + progress_id = 2; + break; + case 3: + sgpBackCel = DiabLoad("Gendata\\Cut3.CEL", NULL, 'PROG'); + LoadPalette("Gendata\\Cut3.pal"); + progress_id = 1; + break; + case 4: + if(currlevel < 15) { + sgpBackCel = DiabLoad("Gendata\\Cut4.CEL", NULL, 'PROG'); + LoadPalette("Gendata\\Cut4.pal"); + progress_id = 1; + } else { + sgpBackCel = DiabLoad("Gendata\\Cutgate.CEL", NULL, 'PROG'); + LoadPalette("Gendata\\Cutgate.pal"); + progress_id = 1; + } + break; + default: + sgpBackCel = DiabLoad("Gendata\\Cutl1d.CEL", NULL, 'PROG'); + LoadPalette("Gendata\\Cutl1d.pal"); + progress_id = 0; + break; + } + break; + case WM_DIABPREVLVL: + if(gnLevelTypeTbl[currlevel - 1] == 0) { + sgpBackCel = DiabLoad("Gendata\\Cuttt.CEL", NULL, 'PROG'); + LoadPalette("Gendata\\Cuttt.pal"); + progress_id = 1; + } else { + switch(gnLevelTypeTbl[currlevel]) { + case 0: + sgpBackCel = DiabLoad("Gendata\\Cuttt.CEL", NULL, 'PROG'); + LoadPalette("Gendata\\Cuttt.pal"); + progress_id = 1; + break; + case 1: + sgpBackCel = DiabLoad("Gendata\\Cutl1d.CEL", NULL, 'PROG'); + LoadPalette("Gendata\\Cutl1d.pal"); + progress_id = 0; + break; + case 2: + sgpBackCel = DiabLoad("Gendata\\Cut2.CEL", NULL, 'PROG'); + LoadPalette("Gendata\\Cut2.pal"); + progress_id = 2; + break; + case 3: + sgpBackCel = DiabLoad("Gendata\\Cut3.CEL", NULL, 'PROG'); + LoadPalette("Gendata\\Cut3.pal"); + progress_id = 1; + break; + case 4: + sgpBackCel = DiabLoad("Gendata\\Cut4.CEL", NULL, 'PROG'); + LoadPalette("Gendata\\Cut4.pal"); + progress_id = 1; + break; + default: + sgpBackCel = DiabLoad("Gendata\\Cutl1d.CEL", NULL, 'PROG'); + LoadPalette("Gendata\\Cutl1d.pal"); + progress_id = 0; + break; + } + } + break; + case WM_DIABSETLVL: + if(setlvlnum == SL_BONECHAMB) { + sgpBackCel = DiabLoad("Gendata\\Cut2.CEL", NULL, 'PROG'); + LoadPalette("Gendata\\Cut2.pal"); + progress_id = 2; + } else if(setlvlnum == SL_VILEBETRAYER) { + sgpBackCel = DiabLoad("Gendata\\Cutportr.CEL", NULL, 'PROG'); + LoadPalette("Gendata\\Cutportr.pal"); + progress_id = 1; + } else { + sgpBackCel = DiabLoad("Gendata\\Cutl1d.CEL", NULL, 'PROG'); + LoadPalette("Gendata\\Cutl1d.pal"); + progress_id = 0; + } + break; + case WM_DIABRTNLVL: + if(setlvlnum == SL_BONECHAMB) { + sgpBackCel = DiabLoad("Gendata\\Cut2.CEL", NULL, 'PROG'); + LoadPalette("Gendata\\Cut2.pal"); + progress_id = 2; + } else if(setlvlnum == SL_VILEBETRAYER) { + sgpBackCel = DiabLoad("Gendata\\Cutportr.CEL", NULL, 'PROG'); + LoadPalette("Gendata\\Cutportr.pal"); + progress_id = 1; + } else { + sgpBackCel = DiabLoad("Gendata\\Cutl1d.CEL", NULL, 'PROG'); + LoadPalette("Gendata\\Cutl1d.pal"); + progress_id = 0; + } + break; + case WM_DIABWARPLVL: + sgpBackCel = DiabLoad("Gendata\\Cutportl.CEL", NULL, 'PROG'); + LoadPalette("Gendata\\Cutportl.pal"); + progress_id = 1; + break; + case WM_DIABLOADGAME: + sgpBackCel = DiabLoad("Gendata\\Cutstart.CEL", NULL, 'PROG'); + LoadPalette("Gendata\\Cutstart.pal"); + progress_id = 1; + break; + case WM_DIABNEWGAME: + sgpBackCel = DiabLoad("Gendata\\Cutstart.CEL", NULL, 'PROG'); + LoadPalette("Gendata\\Cutstart.pal"); + progress_id = 1; + break; + case WM_DIABTOWNWARP: + case WM_DIABTWARPUP: + switch(gnLevelTypeTbl[plr[myplr].plrlevel]) { + case 0: + sgpBackCel = DiabLoad("Gendata\\Cuttt.CEL", NULL, 'PROG'); + LoadPalette("Gendata\\Cuttt.pal"); + progress_id = 1; + break; + case 2: + sgpBackCel = DiabLoad("Gendata\\Cut2.CEL", NULL, 'PROG'); + LoadPalette("Gendata\\Cut2.pal"); + progress_id = 2; + break; + case 3: + sgpBackCel = DiabLoad("Gendata\\Cut3.CEL", NULL, 'PROG'); + LoadPalette("Gendata\\Cut3.pal"); + progress_id = 1; + break; + case 4: + sgpBackCel = DiabLoad("Gendata\\Cut4.CEL", NULL, 'PROG'); + LoadPalette("Gendata\\Cut4.pal"); + progress_id = 1; + break; + } + break; + case WM_DIABRETOWN: + sgpBackCel = DiabLoad("Gendata\\Cuttt.CEL", NULL, 'PROG'); + LoadPalette("Gendata\\Cuttt.pal"); + progress_id = 1; + break; + default: + app_fatal("Unknown progress mode"); + break; + } + + sgdwProgress = 0; +} diff --git a/2020_03_31/Source/interfac.h b/2020_03_31/Source/interfac.h new file mode 100644 index 00000000..029d0a9c --- /dev/null +++ b/2020_03_31/Source/interfac.h @@ -0,0 +1,22 @@ +//HEADER_GOES_HERE +#ifndef __INTERFAC_H__ +#define __INTERFAC_H__ + +extern void *sgpBackCel; +extern int sgdwProgress; +extern int progress_id; // idb + +void interface_msg_pump(); +BOOL IncProgress(); +void DrawCutscene(); +void DrawProgress(int screen_x, int screen_y, int progress_id); +void ShowProgress(unsigned int uMsg); +void FreeInterface(); +void InitCutscene(unsigned int uMsg); + +/* rdata */ + +extern const unsigned char progress_bar_colours[3]; +extern const int progress_bar_screen_pos[3][2]; + +#endif /* __INTERFAC_H__ */ diff --git a/2020_03_31/Source/inv.cpp b/2020_03_31/Source/inv.cpp new file mode 100644 index 00000000..0583dd67 --- /dev/null +++ b/2020_03_31/Source/inv.cpp @@ -0,0 +1,2262 @@ +#include "diablo.h" + +int invflag; +BYTE *pInvCels; +int drawsbarflag; // idb +int sgdwLastTime; // check name + +const InvXY InvRect[73] = +{ + { 452, 31 }, // helmet + { 480, 31 }, // helmet + { 452, 59 }, // helmet + { 480, 59 }, // helmet + { 365, 205 }, // left ring + { 567, 205 }, // right ring + { 524, 59 }, // amulet + { 337, 104 }, // left hand + { 366, 104 }, // left hand + { 337, 132 }, // left hand + { 366, 132 }, // left hand + { 337, 160 }, // left hand + { 366, 160 }, // left hand + { 567, 104 }, // right hand + { 596, 104 }, // right hand + { 567, 132 }, // right hand + { 596, 132 }, // right hand + { 567, 160 }, // right hand + { 596, 160 }, // right hand + { 452, 104 }, // chest + { 480, 104 }, // chest + { 452, 132 }, // chest + { 480, 132 }, // chest + { 452, 160 }, // chest + { 480, 160 }, // chest + { 337, 250 }, // inv row 1 + { 366, 250 }, // inv row 1 + { 394, 250 }, // inv row 1 + { 423, 250 }, // inv row 1 + { 451, 250 }, // inv row 1 + { 480, 250 }, // inv row 1 + { 509, 250 }, // inv row 1 + { 538, 250 }, // inv row 1 + { 567, 250 }, // inv row 1 + { 596, 250 }, // inv row 1 + { 337, 279 }, // inv row 2 + { 366, 279 }, // inv row 2 + { 394, 279 }, // inv row 2 + { 423, 279 }, // inv row 2 + { 451, 279 }, // inv row 2 + { 480, 279 }, // inv row 2 + { 509, 279 }, // inv row 2 + { 538, 279 }, // inv row 2 + { 567, 279 }, // inv row 2 + { 596, 279 }, // inv row 2 + { 337, 308 }, // inv row 3 + { 366, 308 }, // inv row 3 + { 394, 308 }, // inv row 3 + { 423, 308 }, // inv row 3 + { 451, 308 }, // inv row 3 + { 480, 308 }, // inv row 3 + { 509, 308 }, // inv row 3 + { 538, 308 }, // inv row 3 + { 567, 308 }, // inv row 3 + { 596, 308 }, // inv row 3 + { 337, 336 }, // inv row 4 + { 366, 336 }, // inv row 4 + { 394, 336 }, // inv row 4 + { 423, 336 }, // inv row 4 + { 451, 336 }, // inv row 4 + { 480, 336 }, // inv row 4 + { 509, 336 }, // inv row 4 + { 538, 336 }, // inv row 4 + { 567, 336 }, // inv row 4 + { 596, 336 }, // inv row 4 + { 205, 385 }, // belt + { 234, 385 }, // belt + { 263, 385 }, // belt + { 292, 385 }, // belt + { 321, 385 }, // belt + { 350, 385 }, // belt + { 379, 385 }, // belt + { 408, 385 } // belt +}; + +/* data */ + +int AP2x2Tbl[10] = { 8, 28, 6, 26, 4, 24, 2, 22, 0, 20 }; // weak + +void FreeInvGFX() +{ + MemFreeDbg(pInvCels); +} + +void InitInv() +{ + /// ASSERT: assert(! pInvCels); + + if(plr[myplr]._pClass == PC_WARRIOR) { + pInvCels = DiabLoad("Data\\Inv\\Inv.CEL", NULL, 'INVC'); + } else if(plr[myplr]._pClass == PC_ROGUE) { + pInvCels = DiabLoad("Data\\Inv\\Inv_rog.CEL", NULL, 'INVC'); + } else if(plr[myplr]._pClass == PC_SORCERER) { + pInvCels = DiabLoad("Data\\Inv\\Inv_Sor.CEL", NULL, 'INVC'); + } + + invflag = 0; + drawsbarflag = 0; +} + +void InvDrawSlotBack(int X, int Y, int W, int H) +{ + BYTE *dst; + + /// ASSERT: assert(gpBuffer); + + dst = &gpBuffer[X + PitchTbl[Y]]; + +#ifdef USE_ASM + __asm { + mov edi, dst + xor edx, edx + xor ebx, ebx + mov dx, word ptr H + mov bx, word ptr W + label1: + mov ecx, ebx + label2: + mov al, [edi] + cmp al, PAL16_BLUE + jb label5 + cmp al, PAL16_BLUE + 15 + ja label3 + sub al, PAL16_BLUE - PAL16_BEIGE + jmp label4 + label3: + cmp al, PAL16_GRAY + jb label5 + sub al, PAL16_GRAY - PAL16_BEIGE + label4: + mov [edi], al + label5: + inc edi + loop label2 + sub edi, 768 + sub edi, ebx + dec edx + jnz label1 + } +#else + int wdt, hgt; + BYTE pix; + + for(hgt = H; hgt; hgt--, dst -= 768 + W) { + for(wdt = W; wdt; wdt--) { + pix = *dst; + if(pix >= PAL16_BLUE) { + if(pix <= PAL16_BLUE + 15) + pix -= PAL16_BLUE - PAL16_BEIGE; + else if(pix >= PAL16_GRAY) + pix -= PAL16_GRAY - PAL16_BEIGE; + } + *dst++ = pix; + } + } +#endif +} + +void DrawInv() +{ + int i, ii, sx, sy, cn, w, col; + BYTE *pBuff; + BOOL invtest[40]; + + /// ASSERT: assert(gpBuffer); + + CelDecodeOnly(384, 511, pInvCels, 1, 320); + + if(plr[myplr].InvBody[0]._itype != -1) { + InvDrawSlotBack(517, 219, 56, 56); + cn = plr[myplr].InvBody[0]._iCurs + 12; + w = InvItemWidth[cn]; + if(pcursinvitem == 0) { + col = 197; + if(plr[myplr].InvBody[0]._iMagical != 0) { + col = 181; + } + if(!plr[myplr].InvBody[0]._iStatFlag) { + col = 229; + } + CelDecodeClr(col, 517, 219, pCursCels, cn, w, 0, 8); + } + if(plr[myplr].InvBody[0]._iStatFlag) { + /// ASSERT: assert(pCursCels); + CelDrawHdrOnly(517, 219, pCursCels, cn, w, 0, 8); + } else { + CelDrawHdrLightRed(517, 219, pCursCels, cn, w, 0, 8, 1); + } + } + if(plr[myplr].InvBody[1]._itype != -1) { + InvDrawSlotBack(432, 365, 28, 28); + cn = plr[myplr].InvBody[1]._iCurs + 12; + w = InvItemWidth[cn]; + if(pcursinvitem == 1) { + col = 197; + if(plr[myplr].InvBody[1]._iMagical != 0) { + col = 181; + } + if(!plr[myplr].InvBody[1]._iStatFlag) { + col = 229; + } + CelDecodeClr(col, 432, 365, pCursCels, cn, w, 0, 8); + } + if(plr[myplr].InvBody[1]._iStatFlag) { + /// ASSERT: assert(pCursCels); + CelDrawHdrOnly(432, 365, pCursCels, cn, w, 0, 8); + } else { + CelDrawHdrLightRed(432, 365, pCursCels, cn, w, 0, 8, 1); + } + } + if(plr[myplr].InvBody[2]._itype != -1) { + InvDrawSlotBack(633, 365, 28, 28); + cn = plr[myplr].InvBody[2]._iCurs + 12; + w = InvItemWidth[cn]; + if(pcursinvitem == 2) { + col = 197; + if(plr[myplr].InvBody[2]._iMagical != 0) { + col = 181; + } + if(!plr[myplr].InvBody[2]._iStatFlag) { + col = 229; + } + CelDecodeClr(col, 633, 365, pCursCels, cn, w, 0, 8); + } + if(plr[myplr].InvBody[2]._iStatFlag) { + /// ASSERT: assert(pCursCels); + CelDrawHdrOnly(633, 365, pCursCels, cn, w, 0, 8); + } else { + CelDrawHdrLightRed(633, 365, pCursCels, cn, w, 0, 8, 1); + } + } + if(plr[myplr].InvBody[3]._itype != -1) { + InvDrawSlotBack(589, 220, 28, 28); + cn = plr[myplr].InvBody[3]._iCurs + 12; + w = InvItemWidth[cn]; + if(pcursinvitem == 3) { + col = 197; + if(plr[myplr].InvBody[3]._iMagical != 0) { + col = 181; + } + if(!plr[myplr].InvBody[3]._iStatFlag) { + col = 229; + } + CelDecodeClr(col, 589, 220, pCursCels, cn, w, 0, 8); + } + if(plr[myplr].InvBody[3]._iStatFlag) { + /// ASSERT: assert(pCursCels); + CelDrawHdrOnly(589, 220, pCursCels, cn, w, 0, 8); + } else { + CelDrawHdrLightRed(589, 220, pCursCels, cn, w, 0, 8, 1); + } + } + if(plr[myplr].InvBody[4]._itype != -1) { + InvDrawSlotBack(401, 320, 56, 84); + cn = plr[myplr].InvBody[4]._iCurs + 12; + w = InvItemWidth[cn]; + if(w == 28) { + sx = 415; + } else { + sx = 401; + } + if(InvItemHeight[cn] == 84) { + sy = 320; + } else { + sy = 306; + } + if(pcursinvitem == 4) { + col = 197; + if(plr[myplr].InvBody[4]._iMagical != 0) { + col = 181; + } + if(!plr[myplr].InvBody[4]._iStatFlag) { + col = 229; + } + CelDecodeClr(col, sx, sy, pCursCels, cn, w, 0, 8); + } + if(plr[myplr].InvBody[4]._iStatFlag) { + /// ASSERT: assert(pCursCels); + CelDrawHdrOnly(sx, sy, pCursCels, cn, w, 0, 8); + } else { + CelDrawHdrLightRed(sx, sy, pCursCels, cn, w, 0, 8, 1); + } + if(plr[myplr].InvBody[4]._iLoc == ILOC_TWOHAND) { + InvDrawSlotBack(631, 320, 56, 84); + light_table_index = 0; + cel_transparency_active = 1; + if(w == 28) { + pBuff = &gpBuffer[SCREENXY(581, 160)]; + } else { + pBuff = &gpBuffer[SCREENXY(567, 160)]; + } + CelDecodeHdrLightTrans(pBuff, pCursCels, cn, w, 0, 8); + cel_transparency_active = 0; + } + } + if(plr[myplr].InvBody[5]._itype != -1) { + InvDrawSlotBack(631, 320, 56, 84); + cn = plr[myplr].InvBody[5]._iCurs + 12; + w = InvItemWidth[cn]; + if(w == 28) { + sx = 645; + } else { + sx = 633; + } + if(InvItemHeight[cn] == 84) { + sy = 320; + } else { + sy = 306; + } + if(pcursinvitem == 5) { + col = 197; + if(plr[myplr].InvBody[5]._iMagical != 0) { + col = 181; + } + if(!plr[myplr].InvBody[5]._iStatFlag) { + col = 229; + } + CelDecodeClr(col, sx, sy, pCursCels, cn, w, 0, 8); + } + if(plr[myplr].InvBody[5]._iStatFlag) { + /// ASSERT: assert(pCursCels); + CelDrawHdrOnly(sx, sy, pCursCels, cn, w, 0, 8); + } else { + CelDrawHdrLightRed(sx, sy, pCursCels, cn, w, 0, 8, 1); + } + } + if(plr[myplr].InvBody[6]._itype != -1) { + InvDrawSlotBack(517, 320, 56, 84); + cn = plr[myplr].InvBody[6]._iCurs + 12; + w = InvItemWidth[cn]; + if(pcursinvitem == 6) { + col = 197; + if(plr[myplr].InvBody[6]._iMagical != 0) { + col = 181; + } + if(!plr[myplr].InvBody[6]._iStatFlag) { + col = 229; + } + CelDecodeClr(col, 517, 320, pCursCels, cn, w, 0, 8); + } + if(plr[myplr].InvBody[6]._iStatFlag) { + /// ASSERT: assert(pCursCels); + CelDrawHdrOnly(517, 320, pCursCels, cn, w, 0, 8); + } else { + CelDrawHdrLightRed(517, 320, pCursCels, cn, w, 0, 8, 1); + } + } + + for(i = 0; i < 40; i++) { + invtest[i] = FALSE; + if(plr[myplr].InvGrid[i] != 0) { + InvDrawSlotBack(InvRect[i + 25].X + 64, InvRect[i + 25].Y + 160 - 1, 28, 28); + } + } + for(i = 0; i < 40; i++) { + if(plr[myplr].InvGrid[i] <= 0) { + continue; + } + /// ASSERT: assert(!invtest[i]); + invtest[i] = TRUE; + /// ASSERT: assert(plr[myplr].InvGrid[i] <= plr[myplr]._pNumInv); + ii = plr[myplr].InvGrid[i] - 1; + cn = plr[myplr].InvList[ii]._iCurs + 12; + w = InvItemWidth[cn]; + if(pcursinvitem == ii + 7) { + col = 197; + if(plr[myplr].InvList[ii]._iMagical != 0) { + col = 181; + } + if(!plr[myplr].InvList[ii]._iStatFlag) { + col = 229; + } + CelDecodeClr(col, InvRect[i + 25].X + 64, InvRect[i + 25].Y + 160 - 1, pCursCels, cn, w, 0, 8); + } + if(plr[myplr].InvList[ii]._iStatFlag) { + /// ASSERT: assert(pCursCels); + CelDrawHdrOnly(InvRect[i + 25].X + 64, InvRect[i + 25].Y + 160 - 1, pCursCels, cn, w, 0, 8); + } else { + CelDrawHdrLightRed(InvRect[i + 25].X + 64, InvRect[i + 25].Y + 160 - 1, pCursCels, cn, w, 0, 8, 1); + } + } +} + +void DrawInvBelt() +{ + int i, cn, w, col, idx, No; + BYTE c; + + if(talkflag) { + return; + } + + DrawPanelBox(205, 21, 232, 28, 269, 517); + + for(i = 0; i < 8; i++) { + if(plr[myplr].SpdList[i]._itype == -1) { + continue; + } + InvDrawSlotBack(InvRect[i + 65].X + 64, InvRect[i + 65].Y + 160 - 1, 28, 28); + cn = plr[myplr].SpdList[i]._iCurs + 12; + w = InvItemWidth[cn]; + if(pcursinvitem == i + 47) { + col = 197; + if(plr[myplr].SpdList[i]._iMagical != 0) { + col = 181; + } + if(!plr[myplr].SpdList[i]._iStatFlag) { + col = 229; + } + CelDecodeClr(col, InvRect[i + 65].X + 64, InvRect[i + 65].Y + 160 - 1, pCursCels, cn, w, 0, 8); + } + if(plr[myplr].SpdList[i]._iStatFlag) { + /// ASSERT: assert(pCursCels); + CelDrawHdrOnly(InvRect[i + 65].X + 64, InvRect[i + 65].Y + 160 - 1, pCursCels, cn, w, 0, 8); + } else { + CelDrawHdrLightRed(InvRect[i + 65].X + 64, InvRect[i + 65].Y + 160 - 1, pCursCels, cn, w, 0, 8, 1); + } + idx = plr[myplr].SpdList[i].IDidx; + if(AllItemsList[idx].iUsable && plr[myplr].SpdList[i]._iStatFlag && plr[myplr].SpdList[i]._itype != ITYPE_GOLD) { + c = fontframe[gbFontTransTbl[(BYTE)(i + 49)]]; + No = InvRect[i + 65].X + PitchTbl[InvRect[i + 65].Y + 160 - 1] + 28 + 64 - fontkern[c]; + PrintChar(No, c, COL_WHITE); + } + } +} + +BOOL AutoPlace(int pnum, int ii, int sx, int sy, BOOL saveflag) +{ + int i, j, xx, yy; + BOOL done; + + done = TRUE; + + yy = 10 * (ii / 10); + if(yy < 0) { + yy = 0; + } + for(j = 0; j < sy && done; j++) { + if(yy >= 40) { + done = FALSE; + } + xx = ii % 10; + if(xx < 0) { + xx = 0; + } + for(i = 0; i < sx && done; i++) { + if(xx >= 10) { + done = FALSE; + } else { + done = plr[pnum].InvGrid[xx + yy] == 0; + } + xx++; + } + yy += 10; + } + if(done && saveflag) { + plr[pnum].InvList[plr[pnum]._pNumInv] = plr[pnum].HoldItem; + plr[pnum]._pNumInv++; + yy = 10 * (ii / 10); + if(yy < 0) { + yy = 0; + } + for(j = 0; j < sy; j++) { + xx = ii % 10; + if(xx < 0) { + xx = 0; + } + for(i = 0; i < sx; i++) { + if(i == 0 && j == sy - 1) { + plr[pnum].InvGrid[xx + yy] = plr[pnum]._pNumInv; + } else { + plr[pnum].InvGrid[xx + yy] = -plr[pnum]._pNumInv; + } + xx++; + } + yy += 10; + } + CalcPlrScrolls(pnum); + } + + return done; +} + +BOOL SpecialAutoPlace(int pnum, int ii, int sx, int sy, BOOL saveflag) +{ + int i, j, xx, yy; + BOOL done; + + done = TRUE; + + yy = 10 * (ii / 10); + if(yy < 0) { + yy = 0; + } + for(j = 0; j < sy && done; j++) { + if(yy >= 40) { + done = FALSE; + } + xx = ii % 10; + if(xx < 0) { + xx = 0; + } + for(i = 0; i < sx && done; i++) { + if(xx >= 10) { + done = FALSE; + } else { + done = plr[pnum].InvGrid[xx + yy] == 0; + } + xx++; + } + yy += 10; + } + if(!done) { + if(sx > 1 || sy > 1) { + done = FALSE; + } else { + for(i = 0; i < 8; i++) { + if(plr[pnum].SpdList[i]._itype == -1) { + done = TRUE; + break; + } + } + } + } + if(done && saveflag) { + plr[pnum].InvList[plr[pnum]._pNumInv] = plr[pnum].HoldItem; + plr[pnum]._pNumInv++; + yy = 10 * (ii / 10); + if(yy < 0) { + yy = 0; + } + for(j = 0; j < sy; j++) { + xx = ii % 10; + if(xx < 0) { + xx = 0; + } + for(i = 0; i < sx; i++) { + if(i == 0 && j == sy - 1) { + plr[pnum].InvGrid[xx + yy] = plr[pnum]._pNumInv; + } else { + plr[pnum].InvGrid[xx + yy] = -plr[pnum]._pNumInv; + } + xx++; + } + yy += 10; + } + CalcPlrScrolls(pnum); + } + + return done; +} + +BOOL GoldAutoPlace(int pnum) +{ + int i, ii, xx, yy; + long gt; + BOOL done; + + done = FALSE; + + for(i = 0; i < plr[pnum]._pNumInv && !done; i++) { + if(plr[pnum].InvList[i]._itype == ITYPE_GOLD) { + gt = plr[pnum].InvList[i]._ivalue + plr[pnum].HoldItem._ivalue; + if(gt <= 5000) { + plr[pnum].InvList[i]._ivalue += plr[pnum].HoldItem._ivalue; + if(gt >= 2500) { + plr[pnum].InvList[i]._iCurs = 6; + } else if(gt <= 1000) { + plr[pnum].InvList[i]._iCurs = 4; + } else { + plr[pnum].InvList[i]._iCurs = 5; + } + plr[pnum]._pGold = CalculateGold(pnum); + done = TRUE; + } + } + } + if(!done) { + for(i = 0; i < plr[pnum]._pNumInv && !done; i++) { + if(plr[pnum].InvList[i]._itype == ITYPE_GOLD && plr[pnum].InvList[i]._ivalue < 5000) { + gt = plr[pnum].InvList[i]._ivalue + plr[pnum].HoldItem._ivalue; + if(gt <= 5000) { + plr[pnum].InvList[i]._ivalue += plr[pnum].HoldItem._ivalue; + if(gt >= 2500) { + plr[pnum].InvList[i]._iCurs = 6; + } else if(gt <= 1000) { + plr[pnum].InvList[i]._iCurs = 4; + } else { + plr[pnum].InvList[i]._iCurs = 5; + } + plr[pnum]._pGold = CalculateGold(pnum); + done = TRUE; + } + } + } + } + if(!done) { + for(ii = 39; ii >= 0 && !done; ii--) { + yy = 10 * (ii / 10); + xx = ii % 10; + if(plr[pnum].InvGrid[xx + yy] == 0) { + i = plr[pnum]._pNumInv; + plr[pnum].InvList[i] = plr[pnum].HoldItem; + plr[pnum]._pNumInv++; + plr[pnum].InvGrid[xx + yy] = plr[pnum]._pNumInv; + if(plr[pnum].HoldItem._ivalue >= 2500) { + plr[pnum].InvList[i]._iCurs = 6; + } else if(plr[pnum].HoldItem._ivalue <= 1000) { + plr[pnum].InvList[i]._iCurs = 4; + } else { + plr[pnum].InvList[i]._iCurs = 5; + } + plr[pnum]._pGold = CalculateGold(pnum); + done = TRUE; + } + } + } + + return done; +} + +BOOL WeaponAutoPlace(int pnum) +{ + if(plr[pnum].HoldItem._iLoc != ILOC_TWOHAND) { + if(plr[pnum].InvBody[4]._itype != -1 && plr[pnum].InvBody[4]._iClass == ICLASS_WEAPON) { + return FALSE; + } + if(plr[pnum].InvBody[5]._itype != -1 && plr[pnum].InvBody[5]._iClass == ICLASS_WEAPON) { + return FALSE; + } + if(plr[pnum].InvBody[4]._itype == -1) { + NetSendCmdChItem(TRUE, 4); + plr[pnum].InvBody[4] = plr[pnum].HoldItem; + return TRUE; + } + if(plr[pnum].InvBody[5]._itype == -1 && plr[pnum].InvBody[4]._iLoc != ILOC_TWOHAND) { + NetSendCmdChItem(TRUE, 5); + plr[pnum].InvBody[5] = plr[pnum].HoldItem; + return TRUE; + } + } else { + if(plr[pnum].InvBody[4]._itype == -1 && plr[pnum].InvBody[5]._itype == -1) { + NetSendCmdChItem(TRUE, 4); + plr[pnum].InvBody[4] = plr[pnum].HoldItem; + return TRUE; + } + } + + return FALSE; +} + +int SwapItem(ItemStruct *a, ItemStruct *b) +{ + ItemStruct h; + + h = *a; + *a = *b; + *b = h; + + return h._iCurs + 12; +} + +void CheckInvPaste(int pnum, int mx, int my) +{ + int r, rx, ry, sx, sy, i, j, xx, yy, ii; + BOOL done, done2h; + int il, cn, it, iv, ig, idx; + long gt; + ItemStruct tempitem; + + SetICursor(plr[pnum].HoldItem._iCurs + 12); + + rx = mx + (icursW >> 1); + ry = my + (icursH >> 1); + sx = icursW28; + sy = icursH28; + done = FALSE; + for(r = 0; (DWORD)r < 73 && !done; r++) { + if(rx >= InvRect[r].X && rx < InvRect[r].X + 28 + && ry >= InvRect[r].Y - 29 && ry < InvRect[r].Y) { + done = TRUE; + r--; + } + if(r == 24) { + if(!(sx & 1)) { + rx -= 14; + } + if(!(sy & 1)) { + ry -= 14; + } + } + if(r == 64 && !(sy & 1)) { + ry += 14; + } + } + if(!done) { + return; + } + + il = ILOC_UNEQUIPABLE; + if(r >= 0 && r <= 3) { + il = ILOC_HELM; + } + if(r >= 4 && r <= 5) { + il = ILOC_RING; + } + if(r == 6) { + il = ILOC_AMULET; + } + if(r >= 7 && r <= 18) { + il = ILOC_ONEHAND; + } + if(r >= 19 && r <= 24) { + il = ILOC_ARMOR; + } + if(r >= 65 && r <= 72) { + il = ILOC_BELT; + } + + done = FALSE; + if(plr[pnum].HoldItem._iLoc == il) { + done = TRUE; + } + if(il == ILOC_ONEHAND && plr[pnum].HoldItem._iLoc == ILOC_TWOHAND) { + il = ILOC_TWOHAND; + done = TRUE; + } + if(plr[pnum].HoldItem._iLoc == ILOC_UNEQUIPABLE && il == ILOC_BELT && sx == 1 && sy == 1) { + done = TRUE; + idx = plr[pnum].HoldItem.IDidx; + if(!AllItemsList[idx].iUsable) { + done = FALSE; + } + if(!plr[pnum].HoldItem._iStatFlag) { + done = FALSE; + } + if(plr[pnum].HoldItem._itype == ITYPE_GOLD) { + done = FALSE; + } + } + if(il == ILOC_UNEQUIPABLE) { + ii = r - 25; + iv = 0; + done = TRUE; + if(plr[pnum].HoldItem._itype == ITYPE_GOLD) { + yy = 10 * (ii / 10); + xx = ii % 10; + if(plr[pnum].InvGrid[xx + yy] != 0) { + ig = plr[pnum].InvGrid[xx + yy]; + if(ig > 0) { + if(plr[pnum].InvList[ig - 1]._itype != ITYPE_GOLD) { + iv = ig; + } + } else { + iv = -ig; + } + } + } else { + yy = 10 * (ii / 10 - ((sy - 1) >> 1)); + if(yy < 0) { + yy = 0; + } + for(j = 0; j < sy && done; j++) { + if(yy >= 40) { + done = FALSE; + } + xx = ii % 10 - ((sx - 1) >> 1); + if(xx < 0) { + xx = 0; + } + for(i = 0; i < sx && done; i++) { + if(xx >= 10) { + done = FALSE; + } else if(plr[pnum].InvGrid[xx + yy] != 0) { + ig = plr[pnum].InvGrid[xx + yy]; + if(ig < 0) { + ig = -ig; + } + if(iv != 0) { + if(iv != ig) { + done = FALSE; + } + } else { + iv = ig; + } + } + xx++; + } + yy += 10; + } + } + } + if(done && il != ILOC_UNEQUIPABLE && il != ILOC_BELT && !plr[pnum].HoldItem._iStatFlag) { + done = FALSE; + 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); + } + } + if(!done) { + return; + } + + it = ItemCAnimTbl[plr[pnum].HoldItem._iCurs]; + if(pnum == myplr) { + PlaySFX(ItemInvSnds[it]); + } + + cn = CURSOR_HAND; + + switch(il) { + case ILOC_HELM: + NetSendCmdChItem(FALSE, 0); + if(plr[pnum].InvBody[0]._itype == -1) { + plr[pnum].InvBody[0] = plr[pnum].HoldItem; + } else { + cn = SwapItem(&plr[pnum].InvBody[0], &plr[pnum].HoldItem); + } + break; + case ILOC_RING: + if(r == 4) { + NetSendCmdChItem(FALSE, 1); + if(plr[pnum].InvBody[1]._itype == -1) { + plr[pnum].InvBody[1] = plr[pnum].HoldItem; + } else { + cn = SwapItem(&plr[pnum].InvBody[1], &plr[pnum].HoldItem); + } + } else { + NetSendCmdChItem(FALSE, 2); + if(plr[pnum].InvBody[2]._itype == -1) { + plr[pnum].InvBody[2] = plr[pnum].HoldItem; + } else { + cn = SwapItem(&plr[pnum].InvBody[2], &plr[pnum].HoldItem); + } + } + break; + case ILOC_AMULET: + NetSendCmdChItem(FALSE, 3); + if(plr[pnum].InvBody[3]._itype == -1) { + plr[pnum].InvBody[3] = plr[pnum].HoldItem; + } else { + cn = SwapItem(&plr[pnum].InvBody[3], &plr[pnum].HoldItem); + } + break; + case ILOC_ONEHAND: + if(r <= 12) { + if(plr[pnum].InvBody[4]._itype == -1) { + if(plr[pnum].InvBody[5]._itype != -1 && plr[pnum].InvBody[5]._iClass == plr[pnum].HoldItem._iClass) { + NetSendCmdChItem(FALSE, 5); + cn = SwapItem(&plr[pnum].InvBody[5], &plr[pnum].HoldItem); + } else { + NetSendCmdChItem(FALSE, 4); + plr[pnum].InvBody[4] = plr[pnum].HoldItem; + } + } else { + if(plr[pnum].InvBody[5]._itype != -1 && plr[pnum].InvBody[5]._iClass == plr[pnum].HoldItem._iClass) { + NetSendCmdChItem(FALSE, 5); + cn = SwapItem(&plr[pnum].InvBody[5], &plr[pnum].HoldItem); + } else { + NetSendCmdChItem(FALSE, 4); + cn = SwapItem(&plr[pnum].InvBody[4], &plr[pnum].HoldItem); + } + } + } else { + if(plr[pnum].InvBody[5]._itype == -1) { + if(plr[pnum].InvBody[4]._itype != -1 && plr[pnum].InvBody[4]._iLoc == ILOC_TWOHAND) { + NetSendCmdDelItem(FALSE, 4); + NetSendCmdChItem(FALSE, 5); + SwapItem(&plr[pnum].InvBody[5], &plr[pnum].InvBody[4]); + cn = SwapItem(&plr[pnum].InvBody[5], &plr[pnum].HoldItem); + } else if(plr[pnum].InvBody[4]._itype != -1 && plr[pnum].InvBody[4]._iClass == plr[pnum].HoldItem._iClass) { + NetSendCmdChItem(FALSE, 4); + cn = SwapItem(&plr[pnum].InvBody[4], &plr[pnum].HoldItem); + } else { + NetSendCmdChItem(FALSE, 5); + plr[pnum].InvBody[5] = plr[pnum].HoldItem; + } + } else { + if(plr[pnum].InvBody[4]._itype != -1 && plr[pnum].InvBody[4]._iClass == plr[pnum].HoldItem._iClass) { + NetSendCmdChItem(FALSE, 4); + cn = SwapItem(&plr[pnum].InvBody[4], &plr[pnum].HoldItem); + } else { + NetSendCmdChItem(FALSE, 5); + cn = SwapItem(&plr[pnum].InvBody[5], &plr[pnum].HoldItem); + } + } + } + break; + case ILOC_TWOHAND: + NetSendCmdDelItem(FALSE, 5); + if(plr[pnum].InvBody[4]._itype != -1 && plr[pnum].InvBody[5]._itype != -1) { + tempitem = plr[pnum].HoldItem; + if(plr[pnum].InvBody[5]._itype == ITYPE_SHIELD) { + plr[pnum].HoldItem = plr[pnum].InvBody[5]; + } else { + plr[pnum].HoldItem = plr[pnum].InvBody[4]; + } + if(pnum == myplr) { + SetCursor_(plr[pnum].HoldItem._iCurs + 12); + } else { + SetICursor(plr[pnum].HoldItem._iCurs + 12); + } + done2h = FALSE; + for(i = 0; i < 40 && !done2h; i++) { + done2h = AutoPlace(pnum, i, icursW28, icursH28, 1); + } + plr[pnum].HoldItem = tempitem; + if(pnum == myplr) { + SetCursor_(plr[pnum].HoldItem._iCurs + 12); + } else { + SetICursor(plr[pnum].HoldItem._iCurs + 12); + } + if(!done2h) { + return; + } + if(plr[pnum].InvBody[5]._itype == ITYPE_SHIELD) { + plr[pnum].InvBody[5]._itype = -1; + } else { + plr[pnum].InvBody[4]._itype = -1; + } + } + if(plr[pnum].InvBody[4]._itype == -1 && plr[pnum].InvBody[5]._itype == -1) { + NetSendCmdChItem(FALSE, 4); + plr[pnum].InvBody[4] = plr[pnum].HoldItem; + } else { + NetSendCmdChItem(FALSE, 4); + if(plr[pnum].InvBody[4]._itype == -1) { + SwapItem(&plr[pnum].InvBody[4], &plr[pnum].InvBody[5]); + } + cn = SwapItem(&plr[pnum].InvBody[4], &plr[pnum].HoldItem); + } + if(plr[pnum].InvBody[4]._itype == ITYPE_STAFF + && plr[pnum].InvBody[4]._iSpell != SPL_NULL + && plr[pnum].InvBody[4]._iCharges > 0) { + plr[pnum]._pRSpell = plr[pnum].InvBody[4]._iSpell; + plr[pnum]._pRSplType = RSPLTYPE_CHARGES; + force_redraw = 255; + } + break; + case ILOC_ARMOR: + NetSendCmdChItem(FALSE, 6); + if(plr[pnum].InvBody[6]._itype == -1) { + plr[pnum].InvBody[6] = plr[pnum].HoldItem; + } else { + cn = SwapItem(&plr[pnum].InvBody[6], &plr[pnum].HoldItem); + } + break; + case ILOC_UNEQUIPABLE: + if(plr[pnum].HoldItem._itype == ITYPE_GOLD && iv == 0) { + ii = r - 25; + yy = 10 * (ii / 10); + xx = ii % 10; + if(plr[pnum].InvGrid[xx + yy] > 0) { + i = plr[pnum].InvGrid[xx + yy] - 1; + gt = plr[pnum].InvList[i]._ivalue + plr[pnum].HoldItem._ivalue; + if(gt <= 5000) { + plr[pnum].InvList[i]._ivalue += plr[pnum].HoldItem._ivalue; + plr[pnum]._pGold += plr[pnum].HoldItem._ivalue; + if(gt >= 2500) { + plr[pnum].InvList[i]._iCurs = 6; + } else if(gt <= 1000) { + plr[pnum].InvList[i]._iCurs = 4; + } else { + plr[pnum].InvList[i]._iCurs = 5; + } + } else { + gt = 5000 - plr[pnum].InvList[i]._ivalue; + plr[pnum]._pGold += gt; + plr[pnum].HoldItem._ivalue -= gt; + plr[pnum].InvList[i]._ivalue = 5000; + plr[pnum].InvList[i]._iCurs = 6; + if(plr[pnum].HoldItem._ivalue >= 2500) { + cn = 18; /// BUGFIX: wrong cursor from beta + } else if(plr[pnum].HoldItem._ivalue <= 1000) { + cn = 16; /// BUGFIX: wrong cursor from beta + } else { + cn = 17; /// BUGFIX: wrong cursor from beta + } + } + } else { + ii = plr[pnum]._pNumInv; + plr[pnum].InvList[ii] = plr[pnum].HoldItem; + plr[pnum]._pNumInv++; + plr[pnum].InvGrid[xx + yy] = plr[pnum]._pNumInv; + plr[pnum]._pGold += plr[pnum].HoldItem._ivalue; + if(plr[pnum].HoldItem._ivalue <= 5000) { + if(plr[pnum].HoldItem._ivalue >= 2500) { + plr[pnum].InvList[ii]._iCurs = 6; + } else if(plr[pnum].HoldItem._ivalue <= 1000) { + plr[pnum].InvList[ii]._iCurs = 4; + } else { + plr[pnum].InvList[ii]._iCurs = 5; + } + } + } + } else { + if(iv == 0) { + ii = plr[pnum]._pNumInv; + plr[pnum].InvList[ii] = plr[pnum].HoldItem; + plr[pnum]._pNumInv++; + iv = plr[pnum]._pNumInv; + } else { + ii = iv - 1; + if(plr[pnum].HoldItem._itype == ITYPE_GOLD) { + plr[pnum]._pGold += plr[pnum].HoldItem._ivalue; + } + cn = SwapItem(&plr[pnum].InvList[ii], &plr[pnum].HoldItem); + if(plr[pnum].HoldItem._itype == ITYPE_GOLD) { + plr[pnum]._pGold = CalculateGold(pnum); + } + for(i = 0; i < 40; i++) { + if(plr[pnum].InvGrid[i] == iv) { + plr[pnum].InvGrid[i] = 0; + } + if(plr[pnum].InvGrid[i] == -iv) { + plr[pnum].InvGrid[i] = 0; + } + } + } + ii = r - 25; + yy = 10 * (ii / 10 - ((sy - 1) >> 1)); + if(yy < 0) { + yy = 0; + } + for(j = 0; j < sy; j++) { + xx = ii % 10 - ((sx - 1) >> 1); + if(xx < 0) { + xx = 0; + } + for(i = 0; i < sx; i++) { + if(i == 0 && j == sy - 1) { + plr[pnum].InvGrid[xx + yy] = iv; + } else { + plr[pnum].InvGrid[xx + yy] = -iv; + } + xx++; + } + yy += 10; + } + } + break; + case ILOC_BELT: + ii = r - 65; + if(plr[pnum].HoldItem._itype == ITYPE_GOLD) { + if(plr[pnum].SpdList[ii]._itype != -1) { + if(plr[pnum].SpdList[ii]._itype == ITYPE_GOLD) { + gt = plr[pnum].SpdList[ii]._ivalue + plr[pnum].HoldItem._ivalue; + if(gt <= 5000) { + plr[pnum].SpdList[ii]._ivalue += plr[pnum].HoldItem._ivalue; + plr[pnum]._pGold += plr[pnum].HoldItem._ivalue; + if(gt >= 2500) { + plr[pnum].SpdList[ii]._iCurs = 6; + } else if(gt <= 1000) { + plr[pnum].SpdList[ii]._iCurs = 4; + } else { + plr[pnum].SpdList[ii]._iCurs = 5; + } + } else { + gt = 5000 - plr[pnum].SpdList[ii]._ivalue; + plr[pnum]._pGold += gt; + plr[pnum].HoldItem._ivalue -= gt; + plr[pnum].SpdList[ii]._ivalue = 5000; + plr[pnum].SpdList[ii]._iCurs = 6; + if(plr[pnum].HoldItem._ivalue >= 2500) { + cn = 18; /// BUGFIX: wrong cursor from beta + } else if(plr[pnum].HoldItem._ivalue <= 1000) { + cn = 16; /// BUGFIX: wrong cursor from beta + } else { + cn = 17; /// BUGFIX: wrong cursor from beta + } + } + } else { + plr[pnum]._pGold += plr[pnum].HoldItem._ivalue; + cn = SwapItem(&plr[pnum].SpdList[ii], &plr[pnum].HoldItem); + } + } else { + plr[pnum].SpdList[ii] = plr[pnum].HoldItem; + plr[pnum]._pGold += plr[pnum].HoldItem._ivalue; + } + } else if(plr[pnum].SpdList[ii]._itype == -1) { + plr[pnum].SpdList[ii] = plr[pnum].HoldItem; + } else { + cn = SwapItem(&plr[pnum].SpdList[ii], &plr[pnum].HoldItem); + if(plr[pnum].HoldItem._itype == ITYPE_GOLD) { + plr[pnum]._pGold = CalculateGold(pnum); + } + } + drawsbarflag = 1; + break; + } + + CalcPlrInv(pnum, TRUE); + + if(pnum == myplr) { + if(cn == CURSOR_HAND) { + SetCursorPos(MouseX + (cursW >> 1), MouseY + (cursH >> 1)); + } + SetCursor_(cn); + } +} + +void CheckInvSwap(int pnum, BYTE bLoc, int idx, WORD wCI, int seed, BOOL bId) +{ + PlayerStruct *p; + + RecreateItem(127, idx, wCI, seed, 0); + + p = &plr[pnum]; + p->HoldItem = item[127]; + + if(bId) { + p->HoldItem._iIdentified = 1; + } + if(bLoc < 7) { + p->InvBody[bLoc] = p->HoldItem; + if(bLoc == 4 && p->HoldItem._iLoc == ILOC_TWOHAND) { + p->InvBody[5]._itype = -1; + } else if(bLoc == 5 && p->HoldItem._iLoc == ILOC_TWOHAND) { + p->InvBody[4]._itype = -1; + } + } + + CalcPlrInv(pnum, TRUE); +} + +void CheckInvCut(int pnum, int mx, int my) +{ + int r, i, ii, iv; + BOOL done; + + if(plr[pnum]._pmode > PM_WALK3) { + return; + } + + if(dropGoldFlag) { + dropGoldFlag = 0; + dropGoldValue = 0; + } + + done = FALSE; + for(r = 0; (DWORD)r < 73 && !done; r++) { + if(mx >= InvRect[r].X && mx < InvRect[r].X + 29 + && my >= InvRect[r].Y - 29 && my < InvRect[r].Y) { + done = TRUE; + r--; + } + } + if(!done) { + return; + } + + plr[pnum].HoldItem._itype = -1; + + if(r >= 0 && r <= 3 && plr[pnum].InvBody[0]._itype != -1) { + NetSendCmdDelItem(FALSE, 0); + plr[pnum].HoldItem = plr[pnum].InvBody[0]; + plr[pnum].InvBody[0]._itype = -1; + } + if(r == 4 && plr[pnum].InvBody[1]._itype != -1) { + NetSendCmdDelItem(FALSE, 1); + plr[pnum].HoldItem = plr[pnum].InvBody[1]; + plr[pnum].InvBody[1]._itype = -1; + } + if(r == 5 && plr[pnum].InvBody[2]._itype != -1) { + NetSendCmdDelItem(FALSE, 2); + plr[pnum].HoldItem = plr[pnum].InvBody[2]; + plr[pnum].InvBody[2]._itype = -1; + } + if(r == 6 && plr[pnum].InvBody[3]._itype != -1) { + NetSendCmdDelItem(FALSE, 3); + plr[pnum].HoldItem = plr[pnum].InvBody[3]; + plr[pnum].InvBody[3]._itype = -1; + } + if(r >= 7 && r <= 12 && plr[pnum].InvBody[4]._itype != -1) { + NetSendCmdDelItem(FALSE, 4); + plr[pnum].HoldItem = plr[pnum].InvBody[4]; + plr[pnum].InvBody[4]._itype = -1; + } + if(r >= 13 && r <= 18 && plr[pnum].InvBody[5]._itype != -1) { + NetSendCmdDelItem(FALSE, 5); + plr[pnum].HoldItem = plr[pnum].InvBody[5]; + plr[pnum].InvBody[5]._itype = -1; + } + if(r >= 19 && r <= 24 && plr[pnum].InvBody[6]._itype != -1) { + NetSendCmdDelItem(FALSE, 6); + plr[pnum].HoldItem = plr[pnum].InvBody[6]; + plr[pnum].InvBody[6]._itype = -1; + } + if(r >= 25 && r <= 64) { + ii = r - 25; + if(plr[pnum].InvGrid[ii] != 0) { + if(plr[pnum].InvGrid[ii] > 0) { + iv = plr[pnum].InvGrid[ii]; + } else { + iv = -plr[pnum].InvGrid[ii]; + } + for(i = 0; i < 40; i++) { + if(plr[pnum].InvGrid[i] == iv || plr[pnum].InvGrid[i] == -iv) { + plr[pnum].InvGrid[i] = 0; + } + } + iv--; + plr[pnum].HoldItem = plr[pnum].InvList[iv]; + plr[pnum]._pNumInv--; + if(plr[pnum]._pNumInv > 0 && plr[pnum]._pNumInv != iv) { + plr[pnum].InvList[iv] = plr[pnum].InvList[plr[pnum]._pNumInv]; + for(i = 0; i < 40; i++) { + if(plr[pnum].InvGrid[i] == plr[pnum]._pNumInv + 1) { + plr[pnum].InvGrid[i] = iv + 1; + } + if(plr[pnum].InvGrid[i] == -(plr[pnum]._pNumInv + 1)) { + plr[pnum].InvGrid[i] = -(iv + 1); + } + } + } + } + } + if(r >= 65) { + ii = r - 65; + if(plr[pnum].SpdList[ii]._itype != -1) { + plr[pnum].HoldItem = plr[pnum].SpdList[ii]; + plr[pnum].SpdList[ii]._itype = -1; + drawsbarflag = 1; + } + } + + if(plr[pnum].HoldItem._itype != -1) { + if(plr[pnum].HoldItem._itype == ITYPE_GOLD) { + plr[pnum]._pGold = CalculateGold(pnum); + } + CalcPlrInv(pnum, TRUE); + CheckItemStats(pnum); + if(pnum == myplr) { + PlaySFX(IS_IGRAB); + SetCursor_(plr[pnum].HoldItem._iCurs + 12); + SetCursorPos(mx - (cursW >> 1), MouseY - (cursH >> 1)); /// BUGFIX: use 'MouseX' instead 'mx'? + } + } +} + +void inv_update_rem_item(int pnum, BYTE bLoc) +{ + if(bLoc < 7) { + plr[pnum].InvBody[bLoc]._itype = -1; + } + + if(plr[pnum]._pmode != PM_DEATH) { + CalcPlrInv(pnum, TRUE); + } else { + CalcPlrInv(pnum, FALSE); + } +} + +void RemoveInvItem(int pnum, int iv) +{ + int i; + + iv++; + for(i = 0; i < 40; i++) { + if(plr[pnum].InvGrid[i] == iv || plr[pnum].InvGrid[i] == -iv) { + plr[pnum].InvGrid[i] = 0; + } + } + + iv--; + plr[pnum]._pNumInv--; + if(plr[pnum]._pNumInv > 0 && plr[pnum]._pNumInv != iv) { + plr[pnum].InvList[iv] = plr[pnum].InvList[plr[pnum]._pNumInv]; + for(i = 0; i < 40; i++) { + if(plr[pnum].InvGrid[i] == plr[pnum]._pNumInv + 1) { + plr[pnum].InvGrid[i] = iv + 1; + } + if(plr[pnum].InvGrid[i] == -(plr[pnum]._pNumInv + 1)) { + plr[pnum].InvGrid[i] = -(iv + 1); + } + } + } + + CalcPlrScrolls(pnum); + + if(plr[pnum]._pRSplType == RSPLTYPE_SCROLL && plr[pnum]._pRSpell != -1) { + if(!(plr[pnum]._pScrlSpells64 & 1 << (plr[pnum]._pRSpell - 1))) { /// BUGFIX: missing '__int64' cast + plr[pnum]._pRSpell = -1; + } + force_redraw = 255; + } +} + +void RemoveSpdBarItem(int pnum, int iv) +{ + plr[pnum].SpdList[iv]._itype = -1; + CalcPlrScrolls(pnum); + + if(plr[pnum]._pRSplType == RSPLTYPE_SCROLL && plr[pnum]._pRSpell != -1) { + if(!(plr[pnum]._pScrlSpells64 & 1 << (plr[pnum]._pRSpell - 1))) { /// BUGFIX: missing '__int64' cast + plr[pnum]._pRSpell = -1; + } + } + + force_redraw = 255; +} + +void CheckInvItem() +{ + if(pcurs >= CURSOR_FIRSTITEM) { + CheckInvPaste(myplr, MouseX, MouseY); + } else { + CheckInvCut(myplr, MouseX, MouseY); + } +} + +void CheckInvScrn() +{ + if(MouseX > 190 && MouseX < 437 && MouseY > 352 && MouseY < 385) { + CheckInvItem(); + } +} + +void CheckItemStats(int pnum) +{ + PlayerStruct *p; + + p = &plr[pnum]; + p->HoldItem._iStatFlag = 0; + + if(p->_pStrength >= p->HoldItem._iMinStr + && p->_pMagic >= p->HoldItem._iMinMag + && p->_pDexterity >= p->HoldItem._iMinDex) { + p->HoldItem._iStatFlag = 1; + } +} + +void CheckBookLevel(int pnum) +{ + int slvl; + + if(plr[pnum].HoldItem._iMiscId != IMISC_BOOK) { + return; + } + + plr[pnum].HoldItem._iMinMag = spelldata[plr[pnum].HoldItem._iSpell].sMinInt; + slvl = plr[pnum]._pSplLvl[plr[pnum].HoldItem._iSpell]; + while(slvl != 0) { + plr[pnum].HoldItem._iMinMag += 20 * plr[pnum].HoldItem._iMinMag / 100; + slvl--; + if(plr[pnum].HoldItem._iMinMag + 20 * plr[pnum].HoldItem._iMinMag / 100 > 255) { + plr[pnum].HoldItem._iMinMag = 255; + slvl = 0; + } + } +} + +void CheckQuestItem(int pnum) +{ + if(plr[pnum].HoldItem.IDidx == IDI_OPTAMULET) { + quests[Q_BLIND]._qactive = 3; + } + if(plr[pnum].HoldItem.IDidx == IDI_MUSHROOM) { + if(quests[Q_MUSHROOM]._qactive == 2 && quests[Q_MUSHROOM]._qvar1 == 3) { // QS_MUSHSPAWNED + sfxdelay = 10; + if(plr[pnum]._pClass == PC_WARRIOR) { + sfxdnum = PS_WARR95; + } else if(plr[pnum]._pClass == PC_ROGUE) { + sfxdnum = PS_ROGUE95; + } else if(plr[pnum]._pClass == PC_SORCERER) { + sfxdnum = PS_MAGE95; + } + quests[Q_MUSHROOM]._qvar1 = 4; // QS_MUSHPICKED + } + } + if(plr[pnum].HoldItem.IDidx == IDI_ANVIL) { + if(quests[Q_ANVIL]._qactive == 1) { + quests[Q_ANVIL]._qactive = 2; + quests[Q_ANVIL]._qvar1 = 1; + } + if(quests[Q_ANVIL]._qlog == 1) { + sfxdelay = 10; + if(plr[myplr]._pClass == PC_WARRIOR) { + sfxdnum = PS_WARR89; + } else if(plr[myplr]._pClass == PC_ROGUE) { + sfxdnum = PS_ROGUE89; + } else if(plr[myplr]._pClass == PC_SORCERER) { + sfxdnum = PS_MAGE89; + } + } + } + if(plr[pnum].HoldItem.IDidx == IDI_GLDNELIX) { + sfxdelay = 30; + if(plr[myplr]._pClass == PC_WARRIOR) { + sfxdnum = PS_WARR88; + } else if(plr[myplr]._pClass == PC_ROGUE) { + sfxdnum = PS_ROGUE88; + } else if(plr[myplr]._pClass == PC_SORCERER) { + sfxdnum = PS_MAGE88; + } + } + if(plr[pnum].HoldItem.IDidx == IDI_ROCK) { + if(quests[Q_ROCK]._qactive == 1) { + quests[Q_ROCK]._qactive = 2; + quests[Q_ROCK]._qvar1 = 1; + } + if(quests[Q_ROCK]._qlog == 1) { + sfxdelay = 10; + if(plr[myplr]._pClass == PC_WARRIOR) { + sfxdnum = PS_WARR87; + } else if(plr[myplr]._pClass == PC_ROGUE) { + sfxdnum = PS_ROGUE87; + } else if(plr[myplr]._pClass == PC_SORCERER) { + sfxdnum = PS_MAGE87; + } + } + } + if(plr[pnum].HoldItem.IDidx == IDI_ARMOFVAL) { + quests[Q_BLOOD]._qactive = 3; + sfxdelay = 20; + if(plr[myplr]._pClass == PC_WARRIOR) { + sfxdnum = PS_WARR91; + } else if(plr[myplr]._pClass == PC_ROGUE) { + sfxdnum = PS_ROGUE91; + } else if(plr[myplr]._pClass == PC_SORCERER) { + sfxdnum = PS_MAGE91; + } + } +} + +void InvGetItem(int pnum, int ii) +{ + int j, jj; + + if(dropGoldFlag) { + dropGoldFlag = 0; + dropGoldValue = 0; + } + + if(dItem[item[ii]._ix][item[ii]._iy] == 0) { + return; + } + + if(myplr == pnum && pcurs >= CURSOR_FIRSTITEM) { + NetSendCmdPItem(TRUE, CMD_SYNCPUTITEM, plr[myplr].WorldX, plr[myplr].WorldY); + } + + item[ii]._iCreateInfo &= ~0x8000; + plr[pnum].HoldItem = item[ii]; + CheckQuestItem(pnum); + CheckBookLevel(pnum); + CheckItemStats(pnum); + dItem[item[ii]._ix][item[ii]._iy] = 0; + + j = 0; + while(j < numitems) { + jj = itemactive[j]; + if(jj == ii) { + DeleteItem(jj, j); + j = 0; + } else { + j++; + } + } + + pcursitem = -1; + SetCursor_(plr[pnum].HoldItem._iCurs + 12); +} + +void AutoGetItem(int pnum, int ii) +{ + int i, g, w, h, idx, j, jj; + BOOL done; + + if(dropGoldFlag) { + dropGoldFlag = 0; + dropGoldValue = 0; + } + + if(ii != 127 && dItem[item[ii]._ix][item[ii]._iy] == 0) { + return; + } + + item[ii]._iCreateInfo &= ~0x8000; + plr[pnum].HoldItem = item[ii]; /// BUGFIX: overwrites cursor item, allowing for belt dupe bug + CheckQuestItem(pnum); + CheckBookLevel(pnum); + CheckItemStats(pnum); + SetICursor(plr[pnum].HoldItem._iCurs + 12); + + if(plr[pnum].HoldItem._itype == ITYPE_GOLD) { + done = GoldAutoPlace(pnum); + } else { + done = FALSE; + g = plr[pnum]._pgfxnum & 0xF; + if((g == 0 || g == 1) && plr[pnum]._pmode <= PM_WALK3) { + if(plr[pnum].HoldItem._iStatFlag && plr[pnum].HoldItem._iClass == ICLASS_WEAPON) { + done = WeaponAutoPlace(pnum); + if(done) { + CalcPlrInv(pnum, TRUE); + } + } + } + if(!done) { + w = icursW28; + h = icursH28; + if(w == 1 && h == 1) { + idx = plr[pnum].HoldItem.IDidx; + if(plr[pnum].HoldItem._iStatFlag && AllItemsList[idx].iUsable) { + for(i = 0; i < 8 && !done; i++) { + if(plr[pnum].SpdList[i]._itype == -1) { + plr[pnum].SpdList[i] = plr[pnum].HoldItem; + CalcPlrScrolls(pnum); + drawsbarflag = 1; + done = TRUE; + } + } + } + for(i = 30; i <= 39 && !done; i++) { + done = AutoPlace(pnum, i, w, h, TRUE); + } + for(i = 20; i <= 29 && !done; i++) { + done = AutoPlace(pnum, i, w, h, TRUE); + } + for(i = 10; i <= 19 && !done; i++) { + done = AutoPlace(pnum, i, w, h, TRUE); + } + for(i = 0; i <= 9 && !done; i++) { + done = AutoPlace(pnum, i, w, h, TRUE); + } + } + if(w == 1 && h == 2) { + for(i = 29; i >= 20 && !done; i--) { + done = AutoPlace(pnum, i, w, h, TRUE); + } + for(i = 9; i >= 0 && !done; i--) { + done = AutoPlace(pnum, i, w, h, TRUE); + } + for(i = 19; i >= 10 && !done; i--) { + done = AutoPlace(pnum, i, w, h, TRUE); + } + } + if(w == 1 && h == 3) { + for(i = 0; i < 20 && !done; i++) { + done = AutoPlace(pnum, i, w, h, TRUE); + } + } + if(w == 2 && h == 2) { + for(i = 0; i < 10 && !done; i++) { + done = AutoPlace(pnum, AP2x2Tbl[i], w, h, TRUE); + } + for(i = 21; i < 29 && !done; i += 2) { + done = AutoPlace(pnum, i, w, h, TRUE); + } + for(i = 1; i < 9 && !done; i += 2) { + done = AutoPlace(pnum, i, w, h, TRUE); + } + for(i = 10; i < 19 && !done; i++) { + done = AutoPlace(pnum, i, w, h, TRUE); + } + } + if(w == 2 && h == 3) { + for(i = 0; i < 9 && !done; i++) { + done = AutoPlace(pnum, i, w, h, TRUE); + } + for(i = 10; i < 19 && !done; i++) { + done = AutoPlace(pnum, i, w, h, TRUE); + } + } + } + } + + if(done) { + dItem[item[ii]._ix][item[ii]._iy] = 0; + j = 0; + while(j < numitems) { + jj = itemactive[j]; + if(jj == ii) { + DeleteItem(jj, j); + j = 0; + } else { + j++; + } + } + } else { + if(pnum == myplr) { + if(plr[pnum]._pClass == PC_WARRIOR) { + PlaySFX(PS_WARR14 + random(0, 3)); + } else if(plr[pnum]._pClass == PC_ROGUE) { + PlaySFX(PS_ROGUE14 + random(0, 3)); + } else if(plr[pnum]._pClass == PC_SORCERER) { + PlaySFX(PS_MAGE14 + random(0, 3)); + } + } + plr[pnum].HoldItem = item[ii]; + RespawnItem(ii, TRUE); + NetSendCmdPItem(TRUE, CMD_RESPAWNITEM, item[ii]._ix, item[ii]._iy); + plr[pnum].HoldItem._itype = -1; + } +} + +int FindGetItem(int idx, WORD ci, int iseed) +{ + int i, ii; + + for(i = 0; i < numitems; i++) { + ii = itemactive[i]; + if(item[ii].IDidx == idx && item[ii]._iSeed == iseed && item[ii]._iCreateInfo == ci) { + return ii; + } + } + + return -1; +} + +void SyncGetItem(int x, int y, int idx, WORD ci, int iseed) +{ + int ii, j, jj; + + /// BUGFIX: useless calls to 'FindGetItem' not assigning 'ii' were probably assertions + if(dItem[x][y] != 0) { + ii = dItem[x][y] - 1; + if(item[ii].IDidx == idx && item[ii]._iSeed == iseed && item[ii]._iCreateInfo == ci) { + FindGetItem(idx, ci, iseed); + } else { + ii = FindGetItem(idx, ci, iseed); + } + } else { + ii = FindGetItem(idx, ci, iseed); + } + + if(ii == -1) { + return; + } + + dItem[item[ii]._ix][item[ii]._iy] = 0; + j = 0; + while(j < numitems) { + jj = itemactive[j]; + if(jj == ii) { + DeleteItem(jj, j); + FindGetItem(idx, ci, iseed); + /// ASSERT: assert(FindGetItem(idx,ci,iseed) == -1); + FindGetItem(idx, ci, iseed); /* todo replace with above */ + j = 0; + } else { + j++; + } + } + + /// ASSERT: assert(FindGetItem(idx, ci, iseed) == -1); + FindGetItem(idx, ci, iseed); /* todo replace with above */ +} + +BOOL CanPut(int i, int j) +{ + int oi; + + if(dItem[i][j] != 0) { + return FALSE; + } + if(nSolidTable[dPiece[i][j]]) { + return FALSE; + } + if(dObject[i][j] != 0) { + oi = dObject[i][j] > 0 ? dObject[i][j] - 1 : -(dObject[i][j] + 1); + if(object[oi]._oSolidFlag) { + return FALSE; + } + } + if(dObject[i + 1][j + 1] > 0) { + oi = dObject[i + 1][j + 1] - 1; + if(object[oi]._oSelFlag) { + return FALSE; + } + } + if(dObject[i + 1][j + 1] < 0) { + oi = -(dObject[i + 1][j + 1] + 1); + if(object[oi]._oSelFlag) { + return FALSE; + } + } + if(dObject[i + 1][j] > 0 && dObject[i][j + 1] > 0) { + oi = dObject[i + 1][j] - 1; + if(object[oi]._oSelFlag) { + oi = dObject[i][j + 1] - 1; + if(object[oi]._oSelFlag) { + return FALSE; + } + } + } + if(currlevel == 0) { + if(dMonster[i][j] != 0 || dMonster[i + 1][j + 1] != 0) { + return FALSE; + } + } + + return TRUE; +} + +BOOL TryInvPut() +{ + int d, x, y; + + if(numitems >= MAXITEMS) { + return FALSE; + } + + d = GetDirection(plr[myplr].WorldX, plr[myplr].WorldY, cursmx, cursmy); + x = plr[myplr].WorldX + offset_x[d]; + y = plr[myplr].WorldY + offset_y[d]; + if(CanPut(x, y)) { + return TRUE; + } + d = (d - 1) & 7; + x = plr[myplr].WorldX + offset_x[d]; + y = plr[myplr].WorldY + offset_y[d]; + if(CanPut(x, y)) { + return TRUE; + } + d = (d + 2) & 7; + x = plr[myplr].WorldX + offset_x[d]; + y = plr[myplr].WorldY + offset_y[d]; + if(CanPut(x, y)) { + return TRUE; + } + + x = plr[myplr].WorldX; + y = plr[myplr].WorldY; + return CanPut(x, y); +} + +void DrawInvMsg(char *msg) +{ + DWORD dwTicks; + + dwTicks = GetTickCount(); + if(dwTicks - sgdwLastTime >= 5000) { + sgdwLastTime = dwTicks; + ErrorPlrMsg(msg); + } +} + +int InvPutItem(int pnum, int x, int y) +{ + int ii, d, dx, dy, i, j, l, xx, yy; + BOOL done; + + if(numitems >= MAXITEMS) { + return -1; + } + + if(FindGetItem(plr[pnum].HoldItem.IDidx, plr[pnum].HoldItem._iCreateInfo, plr[pnum].HoldItem._iSeed) != -1) { + DrawInvMsg("A duplicate item has been detected. Destroying duplicate..."); + SyncGetItem(x, y, plr[pnum].HoldItem.IDidx, plr[pnum].HoldItem._iCreateInfo, plr[pnum].HoldItem._iSeed); + } + + d = GetDirection(plr[pnum].WorldX, plr[pnum].WorldY, x, y); + dx = x - plr[pnum].WorldX; + dy = y - plr[pnum].WorldY; + if(abs(dx) > 1 || abs(dy) > 1) { + x = plr[pnum].WorldX + offset_x[d]; + y = plr[pnum].WorldY + offset_y[d]; + } + if(!CanPut(x, y)) { + d = (d - 1) & 7; + x = plr[pnum].WorldX + offset_x[d]; + y = plr[pnum].WorldY + offset_y[d]; + if(!CanPut(x, y)) { + d = (d + 2) & 7; + x = plr[pnum].WorldX + offset_x[d]; + y = plr[pnum].WorldY + offset_y[d]; + if(!CanPut(x, y)) { + done = FALSE; + for(l = 1; l < 50 && !done; l++) { + for(j = -l; j <= l && !done; j++) { + yy = j + plr[pnum].WorldY; + for(i = -l; i <= l && !done; i++) { + xx = i + plr[pnum].WorldX; + if(CanPut(xx, yy)) { + done = TRUE; + x = xx; + y = yy; + } + } + } + } + if(!done) { + return -1; + } + } + } + } + + /// ASSERT: assert(CanPut(x,y)); + CanPut(x, y); /* todo: replace with assert */ + + ii = itemavail[0]; + dItem[x][y] = ii + 1; + itemavail[0] = itemavail[MAXITEMS - numitems - 1]; + itemactive[numitems] = ii; + item[ii] = plr[pnum].HoldItem; + item[ii]._ix = x; + item[ii]._iy = y; + RespawnItem(ii, TRUE); + numitems++; + SetCursor_(CURSOR_HAND); + + return ii; +} + +int SyncPutItem(int pnum, int x, int y, int idx, WORD icreateinfo, int iseed, BOOL Id, int dur, int mdur, int ch, int mch, int ivalue, DWORD ibuff) +{ + int ii, d, dx, dy, i, j, l, xx, yy; + BOOL done; + +#if 0 + if(dbg_flag_sync_item) { + sprintf(tempstr, "Player %i dropping item.", pnum); /* todo: implement */ + NetSendCmdString(1 << myplr, tempstr); + } +#endif + + if(numitems >= MAXITEMS) { + return -1; + } + + if(FindGetItem(idx, icreateinfo, iseed) != -1) { + DrawInvMsg("A duplicate item has been detected from another player."); + SyncGetItem(x, y, idx, icreateinfo, iseed); + } + + d = GetDirection(plr[pnum].WorldX, plr[pnum].WorldY, x, y); + dx = x - plr[pnum].WorldX; + dy = y - plr[pnum].WorldY; + if(abs(dx) > 1 || abs(dy) > 1) { + x = plr[pnum].WorldX + offset_x[d]; + y = plr[pnum].WorldY + offset_y[d]; + } + if(!CanPut(x, y)) { + d = (d - 1) & 7; + x = plr[pnum].WorldX + offset_x[d]; + y = plr[pnum].WorldY + offset_y[d]; + if(!CanPut(x, y)) { + d = (d + 2) & 7; + x = plr[pnum].WorldX + offset_x[d]; + y = plr[pnum].WorldY + offset_y[d]; + if(!CanPut(x, y)) { + done = FALSE; + for(l = 1; l < 50 && !done; l++) { + for(j = -l; j <= l && !done; j++) { + yy = j + plr[pnum].WorldY; + for(i = -l; i <= l && !done; i++) { + xx = i + plr[pnum].WorldX; + if(CanPut(xx, yy)) { + done = TRUE; + x = xx; + y = yy; + } + } + } + } + if(!done) { + return -1; + } + } + } + } + + /// ASSERT: assert(CanPut(x,y)); + CanPut(x, y); /* todo: replace with assert */ + + ii = itemavail[0]; + dItem[x][y] = ii + 1; + itemavail[0] = itemavail[MAXITEMS - numitems - 1]; + itemactive[numitems] = ii; + + if(idx == IDI_EAR) { + RecreateEar(ii, icreateinfo, iseed, Id, dur, mdur, ch, mch, ivalue, ibuff); + } else { + RecreateItem(ii, idx, icreateinfo, iseed, ivalue); + if(Id) { + item[ii]._iIdentified = 1; + } + item[ii]._iDurability = dur; + item[ii]._iMaxDur = mdur; + item[ii]._iCharges = ch; + item[ii]._iMaxCharges = mch; + } + + item[ii]._ix = x; + item[ii]._iy = y; + RespawnItem(ii, TRUE); + numitems++; + + return ii; +} + +char CheckInvHLight() +{ + int r, nGold; + char rv; + ItemStruct *pi; + PlayerStruct *p; + + for(r = 0; (DWORD)r < 73; r++) { + if(MouseX >= InvRect[r].X && MouseX < InvRect[r].X + 29 + && MouseY >= InvRect[r].Y - 29 && MouseY < InvRect[r].Y) { + break; + } + } + + if((DWORD)r >= 73) { + return -1; + } + + rv = -1; + infoclr = COL_WHITE; + pi = NULL; + p = &plr[myplr]; + ClearPanel(); + + if(r >= 0 && r <= 3) { + rv = 0; + pi = &p->InvBody[0]; + } else if(r == 4) { + rv = 1; + pi = &p->InvBody[1]; + } else if(r == 5) { + rv = 2; + pi = &p->InvBody[2]; + } else if(r == 6) { + rv = 3; + pi = &p->InvBody[3]; + } else if(r >= 7 && r <= 12) { + rv = 4; + pi = &p->InvBody[4]; + } else if(r >= 13 && r <= 18) { + pi = &p->InvBody[4]; + if(pi->_itype == -1 || pi->_iLoc != 2) { + rv = 5; + pi = &p->InvBody[5]; + } else { + rv = 4; + } + } else if(r >= 19 && r <= 24) { + rv = 6; + pi = &p->InvBody[6]; + } else if(r >= 25 && r <= 64) { + r = abs(p->InvGrid[r - 25]); + if(r == 0) { + return -1; + } + r--; + rv = r + 7; + pi = &p->InvList[r]; + } else if(r >= 65) { + r -= 65; + drawsbarflag = 1; + pi = &p->SpdList[r]; + if(pi->_itype == -1) { + return -1; + } + rv = r + 47; + } + + /// ASSERT: assert(pi); + if(pi->_itype == -1) { + return -1; + } + + if(pi->_itype == ITYPE_GOLD) { + nGold = pi->_ivalue; + sprintf(infostr, "%i gold %s", nGold, get_pieces_str(nGold)); + } else { + if(pi->_iMagical == 1) { + infoclr = COL_BLUE; + } else if(pi->_iMagical == 2) { + infoclr = COL_GOLD; + } + strcpy(infostr, pi->_iName); + if(pi->_iIdentified) { + strcpy(infostr, pi->_iIName); + PrintItemDetails(pi); + } else { + PrintItemDur(pi); + } + } + + return rv; +} + +void RemoveScroll(int pnum) +{ + int i; + + for(i = 0; i < plr[pnum]._pNumInv; i++) { + if(plr[pnum].InvList[i]._itype == -1) { + continue; + } + if(plr[pnum].InvList[i]._iMiscId == IMISC_SCROLL || plr[pnum].InvList[i]._iMiscId == IMISC_SCROLLT) { + if(plr[pnum].InvList[i]._iSpell == plr[pnum]._pSpell) { + RemoveInvItem(pnum, i); + CalcPlrScrolls(pnum); + return; + } + } + } + for(i = 0; i < 8; i++) { + if(plr[pnum].SpdList[i]._itype == -1) { + continue; + } + if(plr[pnum].SpdList[i]._iMiscId == IMISC_SCROLL || plr[pnum].SpdList[i]._iMiscId == IMISC_SCROLLT) { + if(plr[pnum].SpdList[i]._iSpell == plr[pnum]._pSpell) { + RemoveSpdBarItem(pnum, i); + CalcPlrScrolls(pnum); + return; + } + } + } +} + +BOOL UseScroll() +{ + int i; + + if(pcurs != CURSOR_HAND) { + return FALSE; + } + if(leveltype == DTYPE_TOWN && !spelldata[plr[myplr]._pRSpell].sTownSpell) { + return FALSE; + } + + for(i = 0; i < plr[myplr]._pNumInv; i++) { + if(plr[myplr].InvList[i]._itype == -1) { + continue; + } + if(plr[myplr].InvList[i]._iMiscId == IMISC_SCROLL || plr[myplr].InvList[i]._iMiscId == IMISC_SCROLLT) { + if(plr[myplr].InvList[i]._iSpell == plr[myplr]._pRSpell) { + return TRUE; + } + } + } + for(i = 0; i < 8; i++) { + if(plr[myplr].SpdList[i]._itype == -1) { + continue; + } + if(plr[myplr].SpdList[i]._iMiscId == IMISC_SCROLL || plr[myplr].SpdList[i]._iMiscId == IMISC_SCROLLT) { + if(plr[myplr].SpdList[i]._iSpell == plr[myplr]._pRSpell) { + return TRUE; + } + } + } + + return FALSE; +} + +void UseStaffCharge(int pnum) +{ + if(plr[pnum].InvBody[4]._itype != -1 + && plr[pnum].InvBody[4]._iMiscId == IMISC_STAFF + && plr[pnum].InvBody[4]._iSpell == plr[pnum]._pRSpell + && plr[pnum].InvBody[4]._iCharges > 0) { + plr[pnum].InvBody[4]._iCharges--; + CalcPlrStaff(pnum); + } +} + +BOOL UseStaff() +{ + if(pcurs != CURSOR_HAND) { + return FALSE; + } + + if(plr[myplr].InvBody[4]._itype != -1 + && plr[myplr].InvBody[4]._iMiscId == IMISC_STAFF + && plr[myplr].InvBody[4]._iSpell == plr[myplr]._pRSpell + && plr[myplr].InvBody[4]._iCharges > 0) { + return TRUE; + } + + return FALSE; +} + +void StartGoldDrop() +{ + initialDropGoldIndex = pcursinvitem; + + if(pcursinvitem <= 46) { + initialDropGoldValue = plr[myplr].InvList[pcursinvitem - 7]._ivalue; + } else { + initialDropGoldValue = plr[myplr].SpdList[pcursinvitem - 47]._ivalue; + } + + dropGoldFlag = 1; + dropGoldValue = 0; + + if(talkflag) { + control_reset_talk(); + } +} + +BOOL UseInvItem(int pnum, int cii) +{ + int c, idata, it; + ItemStruct *Item; + BOOL speedlist; + + if(plr[pnum]._pInvincible && plr[pnum]._pHitPoints == 0 && pnum == myplr) { + return TRUE; + } + if(pcurs != CURSOR_HAND) { + return TRUE; + } + if(stextflag) { + return TRUE; + } + if(cii <= 5) { + return FALSE; + } + + if(cii <= 46) { + c = cii - 7; + Item = &plr[pnum].InvList[c]; + speedlist = FALSE; + } else { + if(talkflag) { + return TRUE; + } + c = cii - 47; + Item = &plr[pnum].SpdList[c]; + speedlist = TRUE; + } + + switch(Item->IDidx) { + case IDI_MUSHROOM: + sfxdelay = 10; + if(plr[pnum]._pClass == PC_WARRIOR) { + sfxdnum = PS_WARR95; + } else if(plr[pnum]._pClass == PC_ROGUE) { + sfxdnum = PS_ROGUE95; + } else if(plr[pnum]._pClass == PC_SORCERER) { + sfxdnum = PS_MAGE95; + } + return TRUE; + case IDI_FUNGALTM: + PlaySFX(IS_IBOOK); + sfxdelay = 10; + if(plr[pnum]._pClass == PC_WARRIOR) { + sfxdnum = PS_WARR29; + } else if(plr[pnum]._pClass == PC_ROGUE) { + sfxdnum = PS_ROGUE29; + } else if(plr[pnum]._pClass == PC_SORCERER) { + sfxdnum = PS_MAGE29; + } + return TRUE; + } + + idata = Item->IDidx; + if(!AllItemsList[idata].iUsable) { + return FALSE; + } + + 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(Item->_iMiscId == IMISC_NONE && Item->_itype == ITYPE_GOLD) { + StartGoldDrop(); + return TRUE; + } + + if(dropGoldFlag) { + dropGoldFlag = 0; + dropGoldValue = 0; + } + + 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; + } + + it = ItemCAnimTbl[Item->_iCurs]; + if(Item->_iMiscId == IMISC_BOOK) { + PlaySFX(IS_RBOOK); + } else if(pnum == myplr) { + PlaySFX(ItemInvSnds[it]); + } + + UseItem(pnum, Item->_iMiscId, Item->_iSpell); + + if(speedlist) { + RemoveSpdBarItem(pnum, c); + } else if(plr[pnum].InvList[c]._iMiscId != IMISC_MAPOFDOOM) { + RemoveInvItem(pnum, c); + } + + return TRUE; +} + +void DoTelekinesis() +{ + if(pcursobj != -1) { + NetSendCmdParam1(TRUE, CMD_OPOBJT, pcursobj); + } + if(pcursitem != -1) { + NetSendCmdGItem(TRUE, CMD_REQUESTAGITEM, myplr, myplr, pcursitem); + } + if(pcursmonst != -1 && !M_Talker(pcursmonst) && monster[pcursmonst].mtalkmsg == 0) { + NetSendCmdParam1(TRUE, CMD_KNOCKBACK, pcursmonst); + } + + SetCursor_(CURSOR_HAND); +} + +long CalculateGold(int pnum) +{ + int i; + long gold; + + gold = 0; + + for(i = 0; i < 8; i++) { + if(plr[pnum].SpdList[i]._itype == ITYPE_GOLD) { + gold += plr[pnum].SpdList[i]._ivalue; + force_redraw = 255; + } + } + for(i = 0; i < plr[pnum]._pNumInv; i++) { + if(plr[pnum].InvList[i]._itype == ITYPE_GOLD) { + gold += plr[pnum].InvList[i]._ivalue; + } + } + + return gold; +} + +BOOL DropItemBeforeTrig() +{ + if(TryInvPut()) { + NetSendCmdPItem(TRUE, CMD_PUTITEM, cursmx, cursmy); + SetCursor_(CURSOR_HAND); + return TRUE; + } + + return FALSE; +} diff --git a/2020_03_31/Source/inv.h b/2020_03_31/Source/inv.h new file mode 100644 index 00000000..047b5198 --- /dev/null +++ b/2020_03_31/Source/inv.h @@ -0,0 +1,59 @@ +//HEADER_GOES_HERE +#ifndef __INV_H__ +#define __INV_H__ + +extern int invflag; +extern BYTE *pInvCels; +extern int drawsbarflag; // idb +extern int sgdwLastTime; // check name + +void FreeInvGFX(); +void InitInv(); +void InvDrawSlotBack(int X, int Y, int W, int H); +void DrawInv(); +void DrawInvBelt(); +BOOL AutoPlace(int pnum, int ii, int sx, int sy, BOOL saveflag); +BOOL SpecialAutoPlace(int pnum, int ii, int sx, int sy, BOOL saveflag); +BOOL GoldAutoPlace(int pnum); +BOOL WeaponAutoPlace(int pnum); +int SwapItem(ItemStruct *a, ItemStruct *b); +void CheckInvPaste(int pnum, int mx, int my); +void CheckInvSwap(int pnum, BYTE bLoc, int idx, WORD wCI, int seed, BOOL bId); +void CheckInvCut(int pnum, int mx, int my); +void inv_update_rem_item(int pnum, BYTE bLoc); +void RemoveInvItem(int pnum, int iv); +void RemoveSpdBarItem(int pnum, int iv); +void CheckInvItem(); +void CheckInvScrn(); +void CheckItemStats(int pnum); +void CheckBookLevel(int pnum); +void CheckQuestItem(int pnum); +void InvGetItem(int pnum, int ii); +void AutoGetItem(int pnum, int ii); +int FindGetItem(int idx, WORD ci, int iseed); +void SyncGetItem(int x, int y, int idx, WORD ci, int iseed); +BOOL CanPut(int i, int j); +BOOL TryInvPut(); +void DrawInvMsg(char *msg); +int InvPutItem(int pnum, int x, int y); +int SyncPutItem(int pnum, int x, int y, int idx, WORD icreateinfo, int iseed, BOOL Id, int dur, int mdur, int ch, int mch, int ivalue, DWORD ibuff); +char CheckInvHLight(); +void RemoveScroll(int pnum); +BOOL UseScroll(); +void UseStaffCharge(int pnum); +BOOL UseStaff(); +void StartGoldDrop(); +BOOL UseInvItem(int pnum, int cii); +void DoTelekinesis(); +long CalculateGold(int pnum); +BOOL DropItemBeforeTrig(); + +/* rdata */ + +extern const InvXY InvRect[73]; + +/* data */ + +extern int AP2x2Tbl[10]; // weak + +#endif /* __INV_H__ */ diff --git a/2020_03_31/Source/itemdat.cpp b/2020_03_31/Source/itemdat.cpp new file mode 100644 index 00000000..8fd54175 --- /dev/null +++ b/2020_03_31/Source/itemdat.cpp @@ -0,0 +1,21 @@ +#include "diablo.h" + +ItemDataStruct AllItemsList[157] = +{ +#include "Data/xl_item.cpp" +}; + +const PLStruct PL_Prefix[84] = +{ +#include "Data/xl_ipre.cpp" +}; + +const PLStruct PL_Suffix[96] = +{ +#include "Data/xl_isuf.cpp" +}; + +const UItemStruct UniqueItemList[91] = +{ +#include "Data/xl_uitem.cpp" +}; diff --git a/2020_03_31/Source/itemdat.h b/2020_03_31/Source/itemdat.h new file mode 100644 index 00000000..4641b5de --- /dev/null +++ b/2020_03_31/Source/itemdat.h @@ -0,0 +1,10 @@ +//HEADER_GOES_HERE +#ifndef __ITEMDAT_H__ +#define __ITEMDAT_H__ + +extern ItemDataStruct AllItemsList[157]; +extern const PLStruct PL_Prefix[84]; +extern const PLStruct PL_Suffix[96]; +extern const UItemStruct UniqueItemList[91]; + +#endif /* __ITEMDAT_H__ */ diff --git a/2020_03_31/Source/items.cpp b/2020_03_31/Source/items.cpp new file mode 100644 index 00000000..c1e26c6f --- /dev/null +++ b/2020_03_31/Source/items.cpp @@ -0,0 +1,4517 @@ +#include "diablo.h" + +int itemactive[MAXITEMS]; +int uitemflag; +int itemavail[MAXITEMS]; +ItemStruct curruitem; +ItemGetRecordStruct itemrecord[MAXITEMS]; +ItemStruct item[MAXITEMS+1]; +BOOL itemhold[3][3]; +unsigned char *itemanims[35]; +int UniqueItemFlag[128]; +int numitems; +int gnNumGetRecords; + +/* data */ + +unsigned char ItemCAnimTbl[169] = +{ + 20, 16, 16, 16, 4, 4, 4, 12, 12, 12, + 12, 12, 12, 12, 12, 21, 21, 25, 12, 28, + 28, 28, 0, 0, 0, 32, 0, 0, 0, 24, + 24, 26, 2, 25, 22, 23, 24, 25, 27, 27, + 29, 0, 0, 0, 12, 12, 12, 12, 12, 0, + 8, 8, 0, 8, 8, 8, 8, 8, 8, 6, + 8, 8, 8, 6, 8, 8, 6, 8, 8, 6, + 6, 6, 8, 8, 8, 5, 9, 13, 13, 13, + 5, 5, 5, 15, 5, 5, 18, 18, 18, 30, + 5, 5, 14, 5, 14, 13, 16, 18, 5, 5, + 7, 1, 3, 17, 1, 15, 10, 14, 3, 11, + 8, 0, 1, 7, 0, 7, 15, 7, 3, 3, + 3, 6, 6, 11, 11, 11, 31, 14, 14, 14, + 6, 6, 7, 3, 8, 14, 0, 14, 14, 0, + 33, 1, 1, 1, 1, 1, 7, 7, 7, 14, + 14, 17, 17, 17, 0, 34, 1, 0, 3, 17, + 8, 8, 6, 1, 3, 3, 11, 3, 4 +}; +char *ItemDropStrs[35] = +{ + "Armor2", + "Axe", + "FBttle", + "Bow", + "GoldFlip", + "Helmut", + "Mace", + "Shield", + "SwrdFlip", + "Rock", + "Cleaver", + "Staff", + "Ring", + "CrownF", + "LArmor", + "WShield", + "Scroll", + "FPlateAr", + "FBook", + "Food", + "FBttleBB", + "FBttleDY", + "FBttleOR", + "FBttleBR", + "FBttleBL", + "FBttleBY", + "FBttleWH", + "FBttleDB", + "FEar", + "FBrain", + "FMush", + "Innsign", + "Bldstn", + "Fanvil", + "FLazStaf" +}; +unsigned char ItemAnimLs[35] = +{ + 15u, + 13u, + 16u, + 13u, + 10u, + 13u, + 13u, + 13u, + 13u, + 10u, + 13u, + 13u, + 13u, + 13u, + 13u, + 13u, + 13u, + 13u, + 13u, + 1u, + 16u, + 16u, + 16u, + 16u, + 16u, + 16u, + 16u, + 16u, + 13u, + 12u, + 12u, + 13u, + 13u, + 13u, + 8u +}; +int ItemDropSnds[35] = +{ + IS_FHARM, + IS_FAXE, + IS_FPOT, + IS_FBOW, + IS_GOLD, + IS_FCAP, + IS_FSWOR, + IS_FSHLD, + IS_FSWOR, + IS_FROCK, + IS_FAXE, + IS_FSTAF, + IS_FRING, + IS_FCAP, + IS_FLARM, + IS_FSHLD, + IS_FSCRL, + IS_FHARM, + IS_FBOOK, + IS_FLARM, + IS_FPOT, + IS_FPOT, + IS_FPOT, + IS_FPOT, + IS_FPOT, + IS_FPOT, + IS_FPOT, + IS_FPOT, + IS_FBODY, + IS_FBODY, + IS_FMUSH, + IS_ISIGN, + IS_FBLST, + IS_FANVL, + IS_FSTAF +}; +int ItemInvSnds[35] = +{ + IS_IHARM, + IS_IAXE, + IS_IPOT, + IS_IBOW, + IS_GOLD, + IS_ICAP, + IS_ISWORD, + IS_ISHIEL, + IS_ISWORD, + IS_IROCK, + IS_IAXE, + IS_ISTAF, + IS_IRING, + IS_ICAP, + IS_ILARM, + IS_ISHIEL, + IS_ISCROL, + IS_IHARM, + IS_IBOOK, + IS_IHARM, + IS_IPOT, + IS_IPOT, + IS_IPOT, + IS_IPOT, + IS_IPOT, + IS_IPOT, + IS_IPOT, + IS_IPOT, + IS_IBODY, + IS_IBODY, + IS_IMUSH, + IS_ISIGN, + IS_IBLST, + IS_IANVL, + IS_ISTAF +}; +int idoppely = 16; +int premiumlvladd[6] = { -1, -1, 0, 0, 1, 2 }; + +void InitItemGFX() +{ + int i; + char filestr[64]; + + for(i = 0; i < 35; i++) { + sprintf(filestr, "Items\\%s.CEL", ItemDropStrs[i]); + /// ASSERT: assert(! itemanims[i]); + itemanims[i] = DiabLoad(filestr, NULL, 'IGFX'); + } + + memset(UniqueItemFlag, 0, sizeof(UniqueItemFlag)); +} + +BOOL ItemPlace(int xp, int yp) +{ + if(dMonster[xp][yp] != 0) { + return FALSE; + } + if(dPlayer[xp][yp] != 0) { + return FALSE; + } + if(dItem[xp][yp] != 0) { + return FALSE; + } + if(dObject[xp][yp] != 0) { + return FALSE; + } + if(dFlags[xp][yp] & 8) { + return FALSE; + } + if(nSolidTable[dPiece[xp][yp]]) { + return FALSE; + } + + return TRUE; +} + +void AddInitItems() +{ + int i, j, ii, xx, yy; + + j = random(11, 3) + 3; + for(i = 0; i < j; i++) { + ii = itemavail[0]; + itemavail[0] = itemavail[MAXITEMS - numitems - 1]; + itemactive[numitems] = ii; + xx = random(12, 80) + 16; + yy = random(12, 80) + 16; + while(!ItemPlace(xx, yy)) { + xx = random(12, 80) + 16; + yy = random(12, 80) + 16; + } + item[ii]._ix = xx; + item[ii]._iy = yy; + dItem[xx][yy] = ii + 1; + item[ii]._iSeed = GetRndSeed(); + SetRndSeed(item[ii]._iSeed); + if(random(12, 2) != 0) { + GetItemAttrs(ii, IDI_HEAL, currlevel); + } else { + GetItemAttrs(ii, IDI_MANA, currlevel); + } + item[ii]._iCreateInfo = currlevel + 0x8000; + SetupItem(ii); + item[ii]._iAnimFrame = item[ii]._iAnimLen; + item[ii]._iAnimFlag = 0; + item[ii]._iSelFlag = 1; + DeltaAddItem(ii); + numitems++; + } +} + +void InitItems() +{ + int i, s; + + GetItemAttrs(0, IDI_GOLD, 1); + golditem = item[0]; + golditem._iStatFlag = 1; + numitems = 0; + + for(i = 0; i < MAXITEMS; i++) { + item[i]._itype = 0; + item[i]._ix = 0; + item[i]._iy = 0; + item[i]._iAnimFlag = 0; + item[i]._iSelFlag = 0; + item[i]._iIdentified = 0; + item[i]._iPostDraw = 0; + } + + for(i = 0; i < MAXITEMS; i++) { + itemavail[i] = i; + itemactive[i] = 0; + } + + if(!setlevel) { + s = GetRndSeed(); /* unused */ + if(QuestStatus(Q_ROCK)) { + SpawnRock(); + } + if(QuestStatus(Q_ANVIL)) { + SpawnQuestItem(IDI_ANVIL, 2 * setpc_x + 27, 2 * setpc_y + 27, 0, 1); + } + if(currlevel > 0 && currlevel < 16) { + AddInitItems(); + } + } + + uitemflag = 0; +} + +void CalcPlrItemVals(int p, BOOL Loadgfx) +{ + int i, g, d, mi, tmpac; + __int64 t; /* todo: check usage */ + ItemStruct *itm; + + /// ASSERT: assert((DWORD) p < MAX_PLRS); + + int mind = 0; + int maxd = 0; + int tac = 0; + int bdam = 0; + int btohit = 0; + int bac = 0; + long iflgs = 0; + int sadd = 0; + int madd = 0; + int dadd = 0; + int vadd = 0; + __int64 spl = 0; + int fr = 0; + int lr = 0; + int mr = 0; + int dmod = 0; + int ghit = 0; + int lrad = 10; + int ihp = 0; + int imana = 0; + int spllvladd = 0; + int enac = 0; + int fmin = 0; + int fmax = 0; + int lmin = 0; + int lmax = 0; + + for(i = 0; i < NUM_INVLOC; i++) { + itm = &plr[p].InvBody[i]; + if(itm->_itype == -1 || !itm->_iStatFlag) { + continue; + } + mind += itm->_iMinDam; + maxd += itm->_iMaxDam; + tac += itm->_iAC; + if(itm->_iSpell != SPL_NULL) { + t = 1; + spl |= t << (itm->_iSpell - 1); + } + if(itm->_iMagical == 0 || itm->_iIdentified) { + bdam += itm->_iPLDam; + btohit += itm->_iPLToHit; + if(itm->_iPLAC != 0) { + tmpac = itm->_iPLAC * itm->_iAC / 100; + if(tmpac == 0) { + tmpac = 1; + } + bac += tmpac; + } + iflgs |= itm->_iFlags; + sadd += itm->_iPLStr; + madd += itm->_iPLMag; + dadd += itm->_iPLDex; + vadd += itm->_iPLVit; + fr += itm->_iPLFR; + lr += itm->_iPLLR; + mr += itm->_iPLMR; + dmod += itm->_iPLDamMod; + ghit += itm->_iPLGetHit; + lrad += itm->_iPLLight; + ihp += itm->_iPLHP; + imana += itm->_iPLMana; + spllvladd += itm->_iSplLvlAdd; + enac += itm->_iPLEnAc; + fmin += itm->_iFMinDam; + fmax += itm->_iFMaxDam; + lmin += itm->_iLMinDam; + lmax += itm->_iLMaxDam; + } + } + + if(mind == 0 && maxd == 0) { + mind = 1; + maxd = 1; + if(plr[p].InvBody[4]._itype == ITYPE_SHIELD && plr[p].InvBody[4]._iStatFlag) { + maxd = 3; + } + if(plr[p].InvBody[5]._itype == ITYPE_SHIELD && plr[p].InvBody[5]._iStatFlag) { + maxd = 3; + } + } + plr[p]._pIMinDam = mind; + plr[p]._pIMaxDam = maxd; + plr[p]._pIAC = tac; + plr[p]._pIBonusDam = bdam; + plr[p]._pIBonusToHit = btohit; + plr[p]._pIBonusAC = bac; + plr[p]._pIFlags = iflgs; + plr[p]._pIBonusDamMod = dmod; + plr[p]._pIGetHit = ghit; + + if(lrad < 2) { + lrad = 2; + } + if(lrad > 15) { + lrad = 15; + } + if(plr[p]._pLightRad != lrad && p == myplr) { + ChangeLightRadius(plr[p]._plid, lrad); + if(lrad >= 10) { + ChangeVisionRadius(plr[p]._pvid, lrad); + } else { + ChangeVisionRadius(plr[p]._pvid, 10); + } + plr[p]._pLightRad = lrad; + } + + plr[p]._pStrength = sadd + plr[p]._pBaseStr; + if(plr[myplr]._pStrength <= 0) { + plr[myplr]._pStrength = 0; + } + plr[p]._pMagic = madd + plr[p]._pBaseMag; + if(plr[myplr]._pMagic <= 0) { + plr[myplr]._pMagic = 0; + } + plr[p]._pDexterity = dadd + plr[p]._pBaseDex; + if(plr[myplr]._pDexterity <= 0) { + plr[myplr]._pDexterity = 0; + } + plr[p]._pVitality = vadd + plr[p]._pBaseVit; + if(plr[myplr]._pVitality <= 0) { + plr[myplr]._pVitality = 0; + } + + if(plr[p]._pClass == PC_ROGUE) { + plr[p]._pDamageMod = plr[p]._pLevel * (plr[p]._pStrength + plr[p]._pDexterity) / 200; + } else { + plr[p]._pDamageMod = plr[p]._pLevel * plr[p]._pStrength / 100; + } + + plr[p]._pISpells64 = spl; + t = 1; + if(plr[p]._pRSplType == RSPLTYPE_CHARGES && !(spl & t << (plr[p]._pRSpell - 1))) { + plr[p]._pRSpell = -1; + plr[p]._pRSplType = RSPLTYPE_INVALID; + force_redraw = 255; + } + plr[p]._pISplLvlAdd = spllvladd; + plr[p]._pIEnAc = enac; + + if(iflgs & ISPL_ALLRESZERO) { + mr = 0; + fr = 0; + lr = 0; + } + if(mr > 75) { + mr = 75; + } + plr[p]._pMagResist = mr; + if(fr > 75) { + fr = 75; + } + plr[p]._pFireResist = fr; + if(lr > 75) { + lr = 75; + } + plr[p]._pLghtResist = lr; + + if(plr[p]._pClass == PC_WARRIOR) { + vadd *= 2; + } + if(plr[p]._pClass == PC_ROGUE) { + vadd += vadd >> 1; + } + ihp += vadd << 6; + + if(plr[p]._pClass == PC_SORCERER) { + madd *= 2; + } + if(plr[p]._pClass == PC_ROGUE) { + madd += madd >> 1; + } + imana += madd << 6; + + plr[p]._pHitPoints = ihp + plr[p]._pHPBase; + plr[p]._pMaxHP = ihp + plr[p]._pMaxHPBase; + if(p == myplr && plr[p]._pHitPoints >> 6 <= 0) { + SetPlayerHitPoints(p, 0); + } + + plr[p]._pMana = imana + plr[p]._pManaBase; + plr[p]._pMaxMana = imana + plr[p]._pMaxManaBase; + + plr[p]._pIFMinDam = fmin; + plr[p]._pIFMaxDam = fmax; + plr[p]._pILMinDam = lmin; + plr[p]._pILMaxDam = lmax; + + if(iflgs & ISPL_INFRAVISION) { + plr[p]._pInfraFlag = 1; + } else { + plr[p]._pInfraFlag = 0; + } + + plr[p]._pBlockFlag = 0; + plr[p]._pwtype = 0; + + g = 0; + if(plr[p].InvBody[4]._itype != -1 && plr[p].InvBody[4]._iClass == ICLASS_WEAPON && plr[p].InvBody[4]._iStatFlag) { + g = plr[p].InvBody[4]._itype; + } + if(plr[p].InvBody[5]._itype != -1 && plr[p].InvBody[5]._iClass == ICLASS_WEAPON && plr[p].InvBody[5]._iStatFlag) { + g = plr[p].InvBody[5]._itype; + } + + switch(g) { + case ITYPE_SWORD: + g = 2; + break; + case ITYPE_MACE: + g = 6; + break; + case ITYPE_BOW: + plr[p]._pwtype = 1; + g = 4; + break; + case ITYPE_AXE: + g = 5; + break; + case ITYPE_STAFF: + g = 8; + break; + } + + if(plr[p].InvBody[4]._itype == ITYPE_SHIELD && plr[p].InvBody[4]._iStatFlag) { + plr[p]._pBlockFlag = 1; + g++; + } + if(plr[p].InvBody[5]._itype == ITYPE_SHIELD && plr[p].InvBody[5]._iStatFlag) { + plr[p]._pBlockFlag = 1; + g++; + } + if(plr[p].InvBody[6]._itype == ITYPE_MARMOR && plr[p].InvBody[6]._iStatFlag) { + g += 16; + } + if(plr[p].InvBody[6]._itype == ITYPE_HARMOR && plr[p].InvBody[6]._iStatFlag) { + g += 32; + } + if(plr[p]._pgfxnum != g && Loadgfx) { + plr[p]._pgfxnum = g; + plr[p]._pGFXLoad = 0; + LoadPlrGFX(p, 1); + SetPlrAnims(p); + d = plr[p]._pdir; + /// ASSERT: assert(plr[p]._pNAnim[d]); + plr[p]._pAnimData = plr[p]._pNAnim[d]; + plr[p]._pAnimLen = plr[p]._pNFrames; + plr[p]._pAnimFrame = 1; + plr[p]._pAnimCnt = 0; + plr[p]._pAnimDelay = 3; + plr[p]._pAnimWidth = plr[p]._pNWidth; + plr[p]._pAnimWidth2 = (plr[p]._pNWidth - 64) >> 1; + } else { + plr[p]._pgfxnum = g; + } + + for(i = 0; i < nummissiles; i++) { + mi = missileactive[i]; + if(missile[mi]._mitype == MIS_MANASHIELD && missile[mi]._misource == p) { + missile[mi]._miVar1 = plr[p]._pHitPoints; + missile[mi]._miVar2 = plr[p]._pHPBase; + } + } + + drawmanaflag = 1; + drawhpflag = 1; +} + +void CalcPlrScrolls(int p) +{ + int i; + __int64 t; /* todo: check usage */ + + plr[p]._pScrlSpells64 = 0; + + for(i = 0; i < plr[p]._pNumInv; i++) { + if(plr[p].InvList[i]._itype == -1) { + continue; + } + if(plr[p].InvList[i]._iMiscId == IMISC_SCROLL || plr[p].InvList[i]._iMiscId == IMISC_SCROLLT) { + if(plr[p].InvList[i]._iStatFlag) { + t = 1; + plr[p]._pScrlSpells64 |= t << (plr[p].InvList[i]._iSpell - 1); + } + } + } + for(i = 0; i < 8; i++) { + if(plr[p].SpdList[i]._itype == -1) { + continue; + } + if(plr[p].SpdList[i]._iMiscId == IMISC_SCROLL || plr[p].SpdList[i]._iMiscId == IMISC_SCROLLT) { + if(plr[p].SpdList[i]._iStatFlag) { + t = 1; + plr[p]._pScrlSpells64 |= t << (plr[p].SpdList[i]._iSpell - 1); + } + } + } + + /// BUGFIX: add 't = 1' and use in next line + if(plr[p]._pRSplType == RSPLTYPE_SCROLL && !(plr[p]._pScrlSpells64 & 1 << (plr[p]._pRSpell - 1))) { + plr[p]._pRSpell = -1; + plr[p]._pRSplType = RSPLTYPE_INVALID; + force_redraw = 255; + } +} + +void CalcPlrStaff(int p) +{ + __int64 t; /* todo: check usage */ + + plr[p]._pISpells64 = 0; + + if(plr[p].InvBody[4]._itype != -1 && plr[p].InvBody[4]._iStatFlag && plr[p].InvBody[4]._iCharges > 0) { + t = 1; + plr[p]._pISpells64 = t << (plr[p].InvBody[4]._iSpell - 1); + } +} + +void CalcSelfItems(int pnum) +{ + int i, sa, ma, da; + BOOL sf, changeflag; + PlayerStruct *p; + + p = &plr[pnum]; + + sa = 0; + ma = 0; + da = 0; + + for(i = 0; i < NUM_INVLOC; i++) { + if(p->InvBody[i]._itype == -1) { + continue; + } + p->InvBody[i]._iStatFlag = 1; + if(p->InvBody[i]._iIdentified) { + sa += p->InvBody[i]._iPLStr; + ma += p->InvBody[i]._iPLMag; + da += p->InvBody[i]._iPLDex; + } + } + + while(1) { + changeflag = FALSE; + for(i = 0; i < NUM_INVLOC; i++) { + if(p->InvBody[i]._itype == -1 || !p->InvBody[i]._iStatFlag) { + continue; + } + sf = TRUE; + if(sa + p->_pBaseStr < p->InvBody[i]._iMinStr) { + sf = FALSE; + } + if(ma + p->_pBaseMag < p->InvBody[i]._iMinMag) { + sf = FALSE; + } + if(da + p->_pBaseDex < p->InvBody[i]._iMinDex) { + sf = FALSE; + } + if(!sf) { + changeflag = TRUE; + p->InvBody[i]._iStatFlag = 0; + if(p->InvBody[i]._iIdentified) { + sa -= p->InvBody[i]._iPLStr; + ma -= p->InvBody[i]._iPLMag; + da -= p->InvBody[i]._iPLDex; + } + } + } + if(!changeflag) { + break; + } + } +} + +void CalcPlrItemMin(int pnum) +{ + int i; + PlayerStruct *p; + ItemStruct *pi; + + p = &plr[pnum]; + + pi = p->InvList; + i = p->_pNumInv; + while(i--) { + pi->_iStatFlag = ItemMinStats(p, pi); + pi++; + } + + pi = p->SpdList; + i = 8; + while(i--) { + if(pi->_itype != -1) { + pi->_iStatFlag = ItemMinStats(p, pi); + } + pi++; + } +} + +BOOL ItemMinStats(PlayerStruct *p, ItemStruct *x) +{ + if(p->_pMagic < x->_iMinMag) { + return FALSE; + } + if(p->_pStrength < x->_iMinStr) { + return FALSE; + } + if(p->_pDexterity < x->_iMinDex) { + return FALSE; + } + + return TRUE; +} + +void CalcPlrBookVals(int p) +{ + int i, slvl; + + if(currlevel == 0) { + for(i = 1; witchitem[i]._itype != -1; i++) { + WitchBookLevel(i); + witchitem[i]._iStatFlag = StoreStatOk(&witchitem[i]); + } + } + + for(i = 0; i < plr[p]._pNumInv; i++) { + if(plr[p].InvList[i]._itype == ITYPE_MISC && plr[p].InvList[i]._iMiscId == IMISC_BOOK) { + plr[p].InvList[i]._iMinMag = spelldata[plr[p].InvList[i]._iSpell].sMinInt; + slvl = plr[p]._pSplLvl[plr[p].InvList[i]._iSpell]; + while(slvl != 0) { + plr[p].InvList[i]._iMinMag += 20 * plr[p].InvList[i]._iMinMag / 100; + slvl--; + if(plr[p].InvList[i]._iMinMag + 20 * plr[p].InvList[i]._iMinMag / 100 > 255) { + plr[p].InvList[i]._iMinMag = 255; + slvl = 0; + } + } + plr[p].InvList[i]._iStatFlag = ItemMinStats(&plr[p], &plr[p].InvList[i]); + } + } +} + +void CalcPlrInv(int p, BOOL Loadgfx) +{ + CalcPlrItemMin(p); + CalcSelfItems(p); + CalcPlrItemVals(p, Loadgfx); + CalcPlrItemMin(p); + + if(p == myplr) { + CalcPlrBookVals(p); + CalcPlrScrolls(p); + CalcPlrStaff(p); + } + if(p == myplr && currlevel == 0) { + RecalcStoreStats(); + } +} + +void SetPlrHandItem(ItemStruct *h, int idata) +{ + ItemDataStruct *pAllItem; + + pAllItem = &AllItemsList[idata]; + memset(h, 0, sizeof(*h)); + h->_itype = pAllItem->itype; + h->_iCurs = pAllItem->iCurs; + strcpy(h->_iName, pAllItem->iName); + strcpy(h->_iIName, pAllItem->iName); + h->_iLoc = pAllItem->iLoc; + h->_iClass = pAllItem->iClass; + h->_iMinDam = pAllItem->iMinDam; + h->_iMaxDam = pAllItem->iMaxDam; + h->_iAC = pAllItem->iMinAC; + h->_iMiscId = pAllItem->iMiscId; + h->_iSpell = pAllItem->iSpell; + if(pAllItem->iMiscId == IMISC_STAFF) { + h->_iCharges = 40; + } + h->_iMaxCharges = h->_iCharges; + h->_iDurability = pAllItem->iDurability; + h->_iMaxDur = pAllItem->iDurability; + h->_iMinStr = pAllItem->iMinStr; + h->_iMinMag = pAllItem->iMinMag; + h->_iMinDex = pAllItem->iMinDex; + h->_ivalue = pAllItem->iValue; + h->_iIvalue = pAllItem->iValue; + h->_iPrePower = -1; + h->_iSufPower = -1; + h->IDidx = idata; + h->_iMagical = 0; +} + +void GetPlrHandSeed(ItemStruct *h) +{ + h->_iSeed = GetRndSeed(); +} + +void GetGoldSeed(int pnum, ItemStruct *h) +{ + int i, ii, s; + BOOL doneflag; + + while(1) { + doneflag = TRUE; + s = GetRndSeed(); + for(i = 0; i < numitems; i++) { + ii = itemactive[i]; + if(item[ii]._iSeed == s) { + doneflag = FALSE; + } + } + if(pnum == myplr) { + for(i = 0; i < plr[pnum]._pNumInv; i++) { + if(plr[pnum].InvList[i]._iSeed == s) { + doneflag = FALSE; + } + } + } + if(doneflag) { + break; + } + } + + h->_iSeed = s; +} + +void SetPlrHandSeed(ItemStruct *h, int iseed) +{ + h->_iSeed = iseed; +} + +void SetPlrHandGoldCurs(ItemStruct *h) +{ + if(h->_ivalue >= 2500) { + h->_iCurs = 6; + } else if(h->_ivalue <= 1000) { + h->_iCurs = 4; + } else { + h->_iCurs = 5; + } +} + +void CreatePlrItems(int p) +{ + int i; + ItemStruct *pi; + + pi = plr[p].InvBody; + i = NUM_INVLOC; + while(i--) { + pi->_itype = -1; + pi++; + } + + memset(plr[p].InvGrid, 0, sizeof(plr[p].InvGrid)); + + pi = plr[p].InvList; + i = 40; + while(i--) { + pi->_itype = -1; + pi++; + } + + plr[p]._pNumInv = 0; + + pi = plr[p].SpdList; + i = 8; + while(i--) { + pi->_itype = -1; + pi++; + } + + switch(plr[p]._pClass) { + case PC_WARRIOR: + SetPlrHandItem(&plr[p].InvBody[4], IDI_WARRIOR); + GetPlrHandSeed(&plr[p].InvBody[4]); + SetPlrHandItem(&plr[p].InvBody[5], IDI_WARRSHLD); + GetPlrHandSeed(&plr[p].InvBody[5]); +#ifdef _DEBUG + if(!debug_mode_key_w) { +#endif + SetPlrHandItem(&plr[p].HoldItem, IDI_WARRCLUB); + GetPlrHandSeed(&plr[p].HoldItem); + AutoPlace(p, 0, 1, 3, TRUE); +#ifdef _DEBUG + } +#endif + SetPlrHandItem(&plr[p].SpdList[0], IDI_HEAL); + GetPlrHandSeed(&plr[p].SpdList[0]); + SetPlrHandItem(&plr[p].SpdList[1], IDI_HEAL); + GetPlrHandSeed(&plr[p].SpdList[1]); + break; + case PC_ROGUE: + SetPlrHandItem(&plr[p].InvBody[4], IDI_ROGUE); + GetPlrHandSeed(&plr[p].InvBody[4]); + SetPlrHandItem(&plr[p].SpdList[0], IDI_HEAL); + GetPlrHandSeed(&plr[p].SpdList[0]); + SetPlrHandItem(&plr[p].SpdList[1], IDI_HEAL); + GetPlrHandSeed(&plr[p].SpdList[1]); + break; + case PC_SORCERER: + SetPlrHandItem(&plr[p].InvBody[4], IDI_SORCEROR); + GetPlrHandSeed(&plr[p].InvBody[4]); + SetPlrHandItem(&plr[p].SpdList[0], IDI_MANA); + GetPlrHandSeed(&plr[p].SpdList[0]); + SetPlrHandItem(&plr[p].SpdList[1], IDI_MANA); + GetPlrHandSeed(&plr[p].SpdList[1]); + break; + } + + SetPlrHandItem(&plr[p].HoldItem, IDI_GOLD); + GetPlrHandSeed(&plr[p].HoldItem); + +#ifdef _DEBUG + if(!debug_mode_key_w) { +#endif + plr[p].HoldItem._ivalue = 100; + plr[p].HoldItem._iCurs = 4; + plr[p]._pGold = plr[p].HoldItem._ivalue; + plr[p].InvList[plr[p]._pNumInv++] = plr[p].HoldItem; + plr[p].InvGrid[30] = plr[p]._pNumInv; +#ifdef _DEBUG + } else { + plr[p].HoldItem._ivalue = 5000; + plr[p].HoldItem._iCurs = 6; + plr[p]._pGold = plr[p].HoldItem._ivalue * 40; + for(i = 0; i < 40; i++) { + GetPlrHandSeed(&plr[p].HoldItem); + plr[p].InvList[plr[p]._pNumInv++] = plr[p].HoldItem; + plr[p].InvGrid[i] = plr[p]._pNumInv; + } + } +#endif + + CalcPlrItemVals(p, FALSE); +} + +BOOL ItemSpaceOk(int i, int j) +{ + int pn, oi; + + if(i < 0 || i >= MAXDUNX || j < 0 || j >= MAXDUNY) { + return FALSE; + } + if(dMonster[i][j] != 0) { + return FALSE; + } + if(dPlayer[i][j] != 0) { + return FALSE; + } + if(dItem[i][j] != 0) { + return FALSE; + } + if(dObject[i][j] != 0) { + oi = dObject[i][j] > 0 ? dObject[i][j] - 1 : -(dObject[i][j] + 1); + if(object[oi]._oSolidFlag) { + return FALSE; + } + } + if(dObject[i + 1][j + 1] > 0) { + oi = dObject[i + 1][j + 1] - 1; + if(object[oi]._oSelFlag) { + return FALSE; + } + } + if(dObject[i + 1][j + 1] < 0) { + oi = -(dObject[i + 1][j + 1] + 1); + if(object[oi]._oSelFlag) { + return FALSE; + } + } + if(dObject[i + 1][j] > 0 && dObject[i][j + 1] > 0) { + oi = dObject[i + 1][j] - 1; + if(object[oi]._oSelFlag) { + oi = dObject[i][j + 1] - 1; + if(object[oi]._oSelFlag) { + return FALSE; + } + } + } + pn = dPiece[i][j]; + if(nSolidTable[pn]) { + return FALSE; + } + + return TRUE; +} + +BOOL GetItemSpace(int x, int y, char inum) +{ + int i, j, xx, yy, rs; + BOOL savail; + + yy = 0; + for(j = y - 1; j <= y + 1; j++) { + xx = 0; + for(i = x - 1; i <= x + 1; i++) { + itemhold[xx][yy] = ItemSpaceOk(i, j); + xx++; + } + yy++; + } + + savail = FALSE; + for(yy = 0; yy < 3; yy++) { + for(xx = 0; xx < 3; xx++) { + if(itemhold[xx][yy]) { + savail = TRUE; + } + } + } + + rs = random(13, 15) + 1; + if(!savail) { + return FALSE; + } + + xx = 0; + yy = 0; + while(rs > 0) { + if(itemhold[xx][yy]) { + rs--; + } + if(rs > 0) { + xx++; + if(xx == 3) { + xx = 0; + yy++; + if(yy == 3) { + yy = 0; + } + } + } + } + + xx += x - 1; + yy += y - 1; + item[inum]._ix = xx; + item[inum]._iy = yy; + dItem[xx][yy] = inum + 1; + return TRUE; +} + +void GetSuperItemSpace(int x, int y, char inum) +{ + int i, j, l, xx, yy; + + if(GetItemSpace(x, y, inum)) { + return; + } + + for(l = 2; l < 50; l++) { + for(j = -l; j <= l; j++) { + yy = j + y; + for(i = -l; i <= l; i++) { + xx = i + x; + if(ItemSpaceOk(xx, yy)) { + item[inum]._ix = xx; + item[inum]._iy = yy; + dItem[xx][yy] = inum + 1; + return; + } + } + } + } +} + +void GetSuperItemLoc(int x, int y, int &xx, int &yy) +{ + int i, j, l; + + for(l = 1; l < 50; l++) { + for(j = -l; j <= l; j++) { + yy = j + y; + for(i = -l; i <= l; i++) { + xx = i + x; + if(ItemSpaceOk(xx, yy)) { + return; + } + } + } + } +} + +void CalcItemValue(int i) +{ + int v; + + v = item[i]._iVMult1 + item[i]._iVMult2; + if(v > 0) { + v *= item[i]._ivalue; + } + if(v < 0) { + v = item[i]._ivalue / v; + } + v += item[i]._iVAdd1 + item[i]._iVAdd2; + if(v <= 0) { + v = 1; + } + + item[i]._iIvalue = v; +} + +void GetBookSpell(int i, int lvl) +{ + int rv, s, bs; + + if(lvl == 0) { + lvl = 1; + } + + rv = random(14, 37) + 1; + s = 1; + while(rv > 0) { + if(spelldata[s].sBookLvl != -1 && lvl >= spelldata[s].sBookLvl) { + rv--; + bs = s; + } + s++; + if(gbMaxPlayers == 1 && s == SPL_RESURRECT) { + s = SPL_TELEKINESIS; + } + if(gbMaxPlayers == 1 && s == SPL_HEALOTHER) { + s = SPL_FLARE; + } + if(s == 37) { + s = 1; + } + } + + strcat(item[i]._iName, spelldata[bs].sNameText); + strcat(item[i]._iIName, spelldata[bs].sNameText); + item[i]._iSpell = bs; + item[i]._iMinMag = spelldata[bs].sMinInt; + item[i]._ivalue += spelldata[bs].sBookCost; + item[i]._iIvalue += spelldata[bs].sBookCost; + + if(spelldata[bs].sType == STYPE_FIRE) { + item[i]._iCurs = 87; // Red Book + } + if(spelldata[bs].sType == STYPE_LIGHTNING) { + item[i]._iCurs = 88; // Blue Book + } + if(spelldata[bs].sType == STYPE_MAGIC) { + item[i]._iCurs = 86; // Black Book + } +} + +void GetStaffPower(int i, int lvl, int bs, BOOL onlygood) +{ + int nl, j, preidx, rv, idata; + BOOL addok; + int l[256]; + char istr[128]; + + rv = random(15, 10); + preidx = -1; +#ifdef _DEBUG + if(rv == 0 || debug_mode_key_inverted_v || onlygood) { +#else + if(rv == 0 || onlygood) { +#endif + nl = 0; + for(j = 0; PL_Prefix[j].PLPower != -1; j++) { + if(PL_Prefix[j].PLIType & PLT_STAFF && PL_Prefix[j].PLMinLvl <= lvl) { + addok = TRUE; + if(onlygood && !PL_Prefix[j].PLOk) { + addok = FALSE; + } + if(addok) { + l[nl++] = j; + if(PL_Prefix[j].PLDouble) { + l[nl++] = j; + } + } + } + } + if(nl != 0) { + preidx = l[random(16, nl)]; + sprintf(istr, "%s %s", PL_Prefix[preidx].PLName, item[i]._iIName); + strcpy(item[i]._iIName, istr); + item[i]._iMagical = 1; + SaveItemPower( + i, + PL_Prefix[preidx].PLPower, + PL_Prefix[preidx].PLParam1, + PL_Prefix[preidx].PLParam2, + PL_Prefix[preidx].PLMinVal, + PL_Prefix[preidx].PLMaxVal, + PL_Prefix[preidx].PLMultVal); + item[i]._iPrePower = PL_Prefix[preidx].PLPower; + } + } + if(!control_WriteStringToBuffer(item[i]._iIName)) { + idata = item[i].IDidx; + strcpy(item[i]._iIName, AllItemsList[idata].iSName); + if(preidx != -1) { + sprintf(istr, "%s %s", PL_Prefix[preidx].PLName, item[i]._iIName); + strcpy(item[i]._iIName, istr); + } + sprintf(istr, "%s of %s", item[i]._iIName, spelldata[bs].sNameText); + strcpy(item[i]._iIName, istr); + if(item[i]._iMagical == 0) { + strcpy(item[i]._iName, item[i]._iIName); + } + } + + CalcItemValue(i); +} + +void GetStaffSpell(int i, int lvl, BOOL onlygood) +{ + int rv, s, l, bs, maxc, minc, v; + char istr[64]; + + if(random(17, 4) == 0) { + GetItemPower(i, lvl >> 1, lvl, PLT_STAFF, onlygood); + return; + } + + l = lvl >> 1; + if(l == 0) { + l = 1; + } + rv = random(18, 37) + 1; + s = 1; + while(rv > 0) { + if(spelldata[s].sStaffLvl != -1 && l >= spelldata[s].sStaffLvl) { + rv--; + bs = s; + } + s++; + if(gbMaxPlayers == 1 && s == SPL_RESURRECT) { + s = SPL_TELEKINESIS; + } + if(gbMaxPlayers == 1 && s == SPL_HEALOTHER) { + s = SPL_FLARE; + } + if(s == 37) { + s = 1; + } + } + + sprintf(istr, "%s of %s", item[i]._iName, spelldata[bs].sNameText); + if(!control_WriteStringToBuffer(istr)) { + sprintf(istr, "Staff of %s", spelldata[bs].sNameText); + } + strcpy(item[i]._iName, istr); + strcpy(item[i]._iIName, istr); + + item[i]._iSpell = bs; + minc = spelldata[bs].sStaffMin; + maxc = spelldata[bs].sStaffMax; + item[i]._iCharges = random(19, maxc - minc + 1) + minc; + item[i]._iMaxCharges = item[i]._iCharges; + item[i]._iMinMag = spelldata[bs].sMinInt; + v = item[i]._iCharges * spelldata[bs].sStaffCost / 5; + item[i]._ivalue += v; + item[i]._iIvalue += v; + GetStaffPower(i, lvl, bs, onlygood); +} + +void GetItemAttrs(int i, int idata, int lvl) +{ + int rndv; + + item[i]._itype = AllItemsList[idata].itype; + item[i]._iCurs = AllItemsList[idata].iCurs; + strcpy(item[i]._iName, AllItemsList[idata].iName); + strcpy(item[i]._iIName, AllItemsList[idata].iName); + item[i]._iLoc = AllItemsList[idata].iLoc; + item[i]._iClass = AllItemsList[idata].iClass; + item[i]._iMinDam = AllItemsList[idata].iMinDam; + item[i]._iMaxDam = AllItemsList[idata].iMaxDam; + item[i]._iAC = random(20, AllItemsList[idata].iMaxAC - AllItemsList[idata].iMinAC + 1) + AllItemsList[idata].iMinAC; + item[i]._iFlags = AllItemsList[idata].iFlags; + item[i]._iMiscId = AllItemsList[idata].iMiscId; + item[i]._iSpell = AllItemsList[idata].iSpell; + item[i]._iMagical = 0; + item[i]._ivalue = AllItemsList[idata].iValue; + item[i]._iIvalue = AllItemsList[idata].iValue; + item[i]._iVAdd1 = 0; + item[i]._iVMult1 = 0; + item[i]._iVAdd2 = 0; + item[i]._iVMult2 = 0; + item[i]._iPLDam = 0; + item[i]._iPLToHit = 0; + item[i]._iPLAC = 0; + item[i]._iPLStr = 0; + item[i]._iPLMag = 0; + item[i]._iPLDex = 0; + item[i]._iPLVit = 0; + item[i]._iCharges = 0; + item[i]._iMaxCharges = 0; + item[i]._iDurability = AllItemsList[idata].iDurability; + item[i]._iMaxDur = AllItemsList[idata].iDurability; + item[i]._iMinStr = AllItemsList[idata].iMinStr; + item[i]._iMinMag = AllItemsList[idata].iMinMag; + item[i]._iMinDex = AllItemsList[idata].iMinDex; + item[i]._iPLFR = 0; + item[i]._iPLLR = 0; + item[i]._iPLMR = 0; + item[i].IDidx = idata; + item[i]._iPLDamMod = 0; + item[i]._iPLGetHit = 0; + item[i]._iPLLight = 0; + item[i]._iSplLvlAdd = 0; + item[i]._iRequest = 0; + item[i]._iFMinDam = 0; + item[i]._iFMaxDam = 0; + item[i]._iLMinDam = 0; + item[i]._iLMaxDam = 0; + item[i]._iPLEnAc = 0; + item[i]._iPLMana = 0; + item[i]._iPLHP = 0; + item[i]._iPrePower = -1; + item[i]._iSufPower = -1; + + if(item[i]._iMiscId == IMISC_BOOK) { + GetBookSpell(i, lvl); + } + if(item[i]._itype == ITYPE_GOLD) { + if(gnDifficulty == DIFF_NORMAL) { + rndv = 5 * currlevel + random(21, 10 * currlevel); + } + if(gnDifficulty == DIFF_NIGHTMARE) { + rndv = 5 * (currlevel + 16) + random(21, 10 * (currlevel + 16)); + } + if(gnDifficulty == DIFF_HELL) { + rndv = 5 * (currlevel + 32) + random(21, 10 * (currlevel + 32)); + } + if(leveltype == DTYPE_HELL) { + rndv += rndv >> 3; + } + if(rndv > 5000) { + rndv = 5000; + } + item[i]._ivalue = rndv; + if(rndv >= 2500) { + item[i]._iCurs = 6; + } else if(rndv <= 1000) { + item[i]._iCurs = 4; + } else { + item[i]._iCurs = 5; + } + } +} + +int RndPL(int param1, int param2) +{ + return param1 + random(22, param2 - param1 + 1); +} + +int PLVal(int pv, int p1, int p2, int minv, int maxv) +{ + if(p1 == p2) { + return minv; + } + if(minv == maxv) { + return minv; + } + + return minv + (maxv - minv) * (100 * (pv - p1) / (p2 - p1)) / 100; +} + +void SaveItemPower(int i, int power, int param1, int param2, int minval, int maxval, int multval) +{ + int r, r2; + + r = RndPL(param1, param2); + + switch(power) { + case IPL_TOHIT: + item[i]._iPLToHit += r; + break; + case IPL_TOHIT_CURSE: + item[i]._iPLToHit -= r; + break; + case IPL_DAMP: + item[i]._iPLDam += r; + break; + case IPL_DAMP_CURSE: + item[i]._iPLDam -= r; + break; + case IPL_TOHIT_DAMP: + r = RndPL(param1, param2); + item[i]._iPLDam += r; + if(param1 == 20) { + r2 = RndPL(1, 5); + } + if(param1 == 36) { + r2 = RndPL(6, 10); + } + if(param1 == 51) { + r2 = RndPL(11, 15); + } + if(param1 == 66) { + r2 = RndPL(16, 20); + } + if(param1 == 81) { + r2 = RndPL(21, 30); + } + if(param1 == 96) { + r2 = RndPL(31, 40); + } + if(param1 == 111) { + r2 = RndPL(41, 50); + } + if(param1 == 126) { + r2 = RndPL(51, 75); + } + if(param1 == 151) { + r2 = RndPL(76, 100); + } + item[i]._iPLToHit += r2; + break; + case IPL_TOHIT_DAMP_CURSE: + item[i]._iPLDam -= r; + if(param1 == 25) { + r2 = RndPL(1, 5); + } + if(param1 == 50) { + r2 = RndPL(6, 10); + } + item[i]._iPLToHit -= r2; + break; + case IPL_ACP: + item[i]._iPLAC += r; + break; + case IPL_ACP_CURSE: + item[i]._iPLAC -= r; + break; + case IPL_SETAC: + item[i]._iAC = r; + break; + case IPL_AC_CURSE: + item[i]._iAC -= r; + break; + case IPL_FIRERES: + item[i]._iPLFR += r; + break; + case IPL_LIGHTRES: + item[i]._iPLLR += r; + break; + case IPL_MAGICRES: + item[i]._iPLMR += r; + break; + case IPL_ALLRES: + item[i]._iPLFR += r; + item[i]._iPLLR += r; + item[i]._iPLMR += r; + if(item[i]._iPLFR < 0) { + item[i]._iPLFR = 0; + } + if(item[i]._iPLLR < 0) { + item[i]._iPLLR = 0; + } + if(item[i]._iPLMR < 0) { + item[i]._iPLMR = 0; + } + break; + case IPL_SPLLVLADD: + item[i]._iSplLvlAdd = r; + break; + case IPL_CHARGES: + item[i]._iCharges *= param1; + item[i]._iMaxCharges = item[i]._iCharges; + break; + case IPL_SPELL: + item[i]._iSpell = param1; + item[i]._iCharges = param1; + item[i]._iMaxCharges = param2; + break; + case IPL_FIREDAM: + item[i]._iFlags |= ISPL_FIREDAM; + item[i]._iFMinDam = param1; + item[i]._iFMaxDam = param2; + break; + case IPL_LIGHTDAM: + item[i]._iFlags |= ISPL_LIGHTDAM; + item[i]._iLMinDam = param1; + item[i]._iLMaxDam = param2; + break; + case IPL_STR: + item[i]._iPLStr += r; + break; + case IPL_STR_CURSE: + item[i]._iPLStr -= r; + break; + case IPL_MAG: + item[i]._iPLMag += r; + break; + case IPL_MAG_CURSE: + item[i]._iPLMag -= r; + break; + case IPL_DEX: + item[i]._iPLDex += r; + break; + case IPL_DEX_CURSE: + item[i]._iPLDex -= r; + break; + case IPL_VIT: + item[i]._iPLVit += r; + break; + case IPL_VIT_CURSE: + item[i]._iPLVit -= r; + break; + case IPL_ATTRIBS: + item[i]._iPLStr += r; + item[i]._iPLMag += r; + item[i]._iPLDex += r; + item[i]._iPLVit += r; + break; + case IPL_ATTRIBS_CURSE: + item[i]._iPLStr -= r; + item[i]._iPLMag -= r; + item[i]._iPLDex -= r; + item[i]._iPLVit -= r; + break; + case IPL_GETHIT_CURSE: + item[i]._iPLGetHit += r; + break; + case IPL_GETHIT: + item[i]._iPLGetHit -= r; + break; + case IPL_LIFE: + item[i]._iPLHP += r << 6; + break; + case IPL_LIFE_CURSE: + item[i]._iPLHP -= r << 6; + break; + case IPL_MANA: + item[i]._iPLMana += r << 6; + drawmanaflag = 1; + break; + case IPL_MANA_CURSE: + item[i]._iPLMana -= r << 6; + drawmanaflag = 1; + break; + case IPL_DUR: + r2 = r * item[i]._iMaxDur / 100; + item[i]._iMaxDur += r2; + item[i]._iDurability += r2; + break; + case IPL_DUR_CURSE: + item[i]._iMaxDur -= r * item[i]._iMaxDur / 100; + if(item[i]._iMaxDur < 1) { + item[i]._iMaxDur = 1; + } + item[i]._iDurability = item[i]._iMaxDur; + break; + case IPL_INDESTRUCTIBLE: + item[i]._iDurability = 255; + item[i]._iMaxDur = 255; + break; + case IPL_LIGHT: + item[i]._iPLLight += param1; + break; + case IPL_LIGHT_CURSE: + item[i]._iPLLight -= param1; + break; + case IPL_FIRE_ARROWS: + item[i]._iFlags |= ISPL_FIRE_ARROWS; + item[i]._iFMinDam = param1; + item[i]._iFMaxDam = param2; + break; + case IPL_LIGHT_ARROWS: + item[i]._iFlags |= ISPL_LIGHT_ARROWS; + item[i]._iLMinDam = param1; + item[i]._iLMaxDam = param2; + break; + case IPL_THORNS: + item[i]._iFlags |= ISPL_THORNS; + break; + case IPL_NOMANA: + item[i]._iFlags |= ISPL_NOMANA; + drawmanaflag = 1; + break; + case IPL_NOHEALPLR: + item[i]._iFlags |= ISPL_NOHEALPLR; + break; + case IPL_ABSHALFTRAP: + item[i]._iFlags |= ISPL_ABSHALFTRAP; + break; + case IPL_KNOCKBACK: + item[i]._iFlags |= ISPL_KNOCKBACK; + break; + case IPL_3XDAMVDEM: + item[i]._iFlags |= ISPL_3XDAMVDEM; + break; + case IPL_ALLRESZERO: + item[i]._iFlags |= ISPL_ALLRESZERO; + break; + case IPL_NOHEALMON: + item[i]._iFlags |= ISPL_NOHEALMON; + break; + case IPL_STEALMANA: + if(param1 == 3) { + item[i]._iFlags |= ISPL_STEALMANA_3; + } + if(param1 == 5) { + item[i]._iFlags |= ISPL_STEALMANA_5; + } + drawmanaflag = 1; + break; + case IPL_STEALLIFE: + if(param1 == 3) { + item[i]._iFlags |= ISPL_STEALLIFE_3; + } + if(param1 == 5) { + item[i]._iFlags |= ISPL_STEALLIFE_5; + } + drawhpflag = 1; + break; + case IPL_TARGAC: + item[i]._iPLEnAc += r; + break; + case IPL_FASTATTACK: + if(param1 == 1) { + item[i]._iFlags |= ISPL_QUICKATTACK; + } + if(param1 == 2) { + item[i]._iFlags |= ISPL_FASTATTACK; + } + if(param1 == 3) { + item[i]._iFlags |= ISPL_FASTERATTACK; + } + if(param1 == 4) { + item[i]._iFlags |= ISPL_FASTESTATTACK; + } + break; + case IPL_FASTRECOVER: + if(param1 == 1) { + item[i]._iFlags |= ISPL_FASTRECOVER; + } + if(param1 == 2) { + item[i]._iFlags |= ISPL_FASTERRECOVER; + } + if(param1 == 3) { + item[i]._iFlags |= ISPL_FASTESTRECOVER; + } + break; + case IPL_FASTBLOCK: + item[i]._iFlags |= ISPL_FASTBLOCK; + break; + case IPL_DAMMOD: + item[i]._iPLDamMod += r; + break; + case IPL_RNDARROWVEL: + item[i]._iFlags |= ISPL_RNDARROWVEL; + break; + case IPL_SETDAM: + item[i]._iMinDam = param1; + item[i]._iMaxDam = param2; + break; + case IPL_SETDUR: + item[i]._iDurability = param1; + item[i]._iMaxDur = param1; + break; + case IPL_FASTSWING: + item[i]._iFlags |= ISPL_FASTERATTACK; + break; + case IPL_ONEHAND: + item[i]._iLoc = ILOC_ONEHAND; + break; + case IPL_DRAINLIFE: + item[i]._iFlags |= ISPL_DRAINLIFE; + break; + case IPL_RNDSTEALLIFE: + item[i]._iFlags |= ISPL_RNDSTEALLIFE; + break; + case IPL_INFRAVISION: + item[i]._iFlags |= ISPL_INFRAVISION; + break; + case IPL_NOMINSTR: + item[i]._iMinStr = 0; + break; + case IPL_INVCURS: + item[i]._iCurs = param1; + break; + case IPL_ADDACLIFE: + item[i]._iPLHP = (plr[myplr]._pIBonusAC + plr[myplr]._pIAC + plr[myplr]._pDexterity / 5) << 6; + break; + case IPL_ADDMANAAC: + item[i]._iAC += (plr[myplr]._pMaxManaBase >> 6) / 10; + break; + case IPL_FIRERESCLVL: + item[i]._iPLFR = 30 - plr[myplr]._pLevel; + if(item[i]._iPLFR < 0) { + item[i]._iPLFR = 0; + } + break; + } + + if(item[i]._iVAdd1 == 0 && item[i]._iVMult1 == 0) { + item[i]._iVAdd1 = PLVal(r, param1, param2, minval, maxval); + item[i]._iVMult1 = multval; + } else { + item[i]._iVAdd2 = PLVal(r, param1, param2, minval, maxval); + item[i]._iVMult2 = multval; + } +} + +void GetItemPower(int i, int minlvl, int maxlvl, long flgs, BOOL onlygood) +{ + int pre, post, nl, j, preidx, sufidx, idata; + BYTE goe; + int l[256]; + char istr[128]; + + pre = random(23, 4); + post = random(23, 3); + if(pre != 0 && post == 0) { + if(random(23, 2) != 0) { + post = 1; + } else { + pre = 0; + } + } + + preidx = -1; + sufidx = -1; + goe = 0; + + if(!onlygood && random(0, 3) != 0) { + onlygood = TRUE; + } + + if(pre == 0) { + nl = 0; + for(j = 0; PL_Prefix[j].PLPower != -1; j++) { + if(PL_Prefix[j].PLIType & flgs && PL_Prefix[j].PLMinLvl >= minlvl && PL_Prefix[j].PLMinLvl <= maxlvl) { + if(!onlygood || PL_Prefix[j].PLOk) { + if(flgs != PLT_STAFF || PL_Prefix[j].PLPower != IPL_CHARGES) { + l[nl++] = j; + if(PL_Prefix[j].PLDouble) { + l[nl++] = j; + } + } + } + } + } + if(nl != 0) { + preidx = l[random(23, nl)]; + sprintf(istr, "%s %s", PL_Prefix[preidx].PLName, item[i]._iIName); + strcpy(item[i]._iIName, istr); + item[i]._iMagical = 1; + SaveItemPower( + i, + PL_Prefix[preidx].PLPower, + PL_Prefix[preidx].PLParam1, + PL_Prefix[preidx].PLParam2, + PL_Prefix[preidx].PLMinVal, + PL_Prefix[preidx].PLMaxVal, + PL_Prefix[preidx].PLMultVal); + item[i]._iPrePower = PL_Prefix[preidx].PLPower; + goe = PL_Prefix[preidx].PLGOE; + } + } + if(post != 0) { + nl = 0; + for(j = 0; PL_Suffix[j].PLPower != -1; j++) { + if(PL_Suffix[j].PLIType & flgs && PL_Suffix[j].PLMinLvl >= minlvl && PL_Suffix[j].PLMinLvl <= maxlvl) { + if((goe | PL_Suffix[j].PLGOE) != 0x11) { + if(!onlygood || PL_Suffix[j].PLOk) { + l[nl++] = j; + } + } + } + } + if(nl != 0) { + sufidx = l[random(23, nl)]; + sprintf(istr, "%s of %s", item[i]._iIName, PL_Suffix[sufidx].PLName); + strcpy(item[i]._iIName, istr); + item[i]._iMagical = 1; + SaveItemPower( + i, + PL_Suffix[sufidx].PLPower, + PL_Suffix[sufidx].PLParam1, + PL_Suffix[sufidx].PLParam2, + PL_Suffix[sufidx].PLMinVal, + PL_Suffix[sufidx].PLMaxVal, + PL_Suffix[sufidx].PLMultVal); + item[i]._iSufPower = PL_Suffix[sufidx].PLPower; + } + } + + if(!control_WriteStringToBuffer(item[i]._iIName)) { + idata = item[i].IDidx; + strcpy(item[i]._iIName, AllItemsList[idata].iSName); + if(preidx != -1) { + sprintf(istr, "%s %s", PL_Prefix[preidx].PLName, item[i]._iIName); + strcpy(item[i]._iIName, istr); + } + if(sufidx != -1) { + sprintf(istr, "%s of %s", item[i]._iIName, PL_Suffix[sufidx].PLName); + strcpy(item[i]._iIName, istr); + } + } + + if(preidx != -1 || sufidx != -1) { + CalcItemValue(i); + } +} + +void GetItemBonus(int i, int idata, int minlvl, int maxlvl, BOOL onlygood) +{ + if(item[i]._iClass == ICLASS_GOLD) { + return; + } + + if(minlvl > 25) { + minlvl = 25; + } + + switch(item[i]._itype) { + case ITYPE_SWORD: + case ITYPE_AXE: + case ITYPE_MACE: + GetItemPower(i, minlvl, maxlvl, 0x1000, onlygood); + break; + case ITYPE_BOW: + GetItemPower(i, minlvl, maxlvl, 0x10, onlygood); + break; + case ITYPE_SHIELD: + GetItemPower(i, minlvl, maxlvl, 0x10000, onlygood); + break; + case ITYPE_LARMOR: + case ITYPE_HELM: + case ITYPE_MARMOR: + case ITYPE_HARMOR: + GetItemPower(i, minlvl, maxlvl, 0x100000, onlygood); + break; + case ITYPE_STAFF: + GetStaffSpell(i, maxlvl, onlygood); + break; + case ITYPE_RING: + case ITYPE_AMULET: + GetItemPower(i, minlvl, maxlvl, 1, onlygood); + break; + } +} + +void SetupItem(int i) +{ + int it; + + it = ItemCAnimTbl[item[i]._iCurs]; + item[i]._iAnimData = itemanims[it]; + item[i]._iAnimLen = ItemAnimLs[it]; + item[i]._iAnimWidth = 96; + item[i]._iAnimWidth2 = 16; + item[i]._iIdentified = 0; + item[i]._iPostDraw = 0; + + if(plr[myplr].pLvlLoad == 0) { + item[i]._iAnimFrame = 1; + item[i]._iAnimFlag = 1; + item[i]._iSelFlag = 0; + } else { + item[i]._iAnimFrame = item[i]._iAnimLen; + item[i]._iAnimFlag = 0; + item[i]._iSelFlag = 1; + } +} + +int RndItem(int m) +{ + int i, ri, rv; + int ril[512]; + + if(monster[m].MData->mTreasure & 0x8000) { + return -((monster[m].MData->mTreasure & 0xFFF) + 1); + } + if(monster[m].MData->mTreasure & 0x4000) { + return 0; + } + + rv = random(24, 100); +#ifdef _DEBUG + if(debug_mode_key_d) { + rv = 100; + } +#endif +#ifdef _DEBUG + if(!debug_mode_key_inverted_v && rv > 40) { +#else + if(rv > 40) { +#endif + return 0; + } +#ifdef _DEBUG + if(!debug_mode_key_inverted_v && random(24, 100) > 25) { +#else + if(random(24, 100) > 25) { +#endif + return IDI_GOLD + 1; + } + + ri = 0; + for(i = 0; AllItemsList[i].iLoc != -1; i++) { + if(AllItemsList[i].iRnd == IDROP_DOUBLE && monster[m].mLevel >= AllItemsList[i].iMinMLvl) { + ril[ri++] = i; + } + if(AllItemsList[i].iRnd != IDROP_NEVER && monster[m].mLevel >= AllItemsList[i].iMinMLvl) { + ril[ri++] = i; + } + if(AllItemsList[i].iSpell == SPL_RESURRECT && gbMaxPlayers == 1) { + ri--; + } + if(AllItemsList[i].iSpell == SPL_HEALOTHER && gbMaxPlayers == 1) { + ri--; + } + } + + rv = random(24, ri); + return ril[rv] + 1; +} + +int RndUItem(int m) +{ + int i, ri; + int ril[512]; + BOOL okflag; + + if(m != -1 && monster[m].MData->mTreasure & 0x8000 && gbMaxPlayers == 1) { + return -((monster[m].MData->mTreasure & 0xFFF) + 1); + } + + ri = 0; + for(i = 0; AllItemsList[i].iLoc != -1; i++) { + okflag = TRUE; + if(AllItemsList[i].iRnd == IDROP_NEVER) { + okflag = FALSE; + } + if(m != -1) { + if(monster[m].mLevel < AllItemsList[i].iMinMLvl) { + okflag = FALSE; + } + } else { + if(currlevel << 1 < AllItemsList[i].iMinMLvl) { + okflag = FALSE; + } + } + if(AllItemsList[i].itype == ITYPE_MISC) { + okflag = FALSE; + } + if(AllItemsList[i].itype == ITYPE_GOLD) { + okflag = FALSE; + } + if(AllItemsList[i].itype == ITYPE_MEAT) { + okflag = FALSE; + } + if(AllItemsList[i].iMiscId == IMISC_BOOK) { + okflag = TRUE; + } + if(AllItemsList[i].iSpell == SPL_RESURRECT && gbMaxPlayers == 1) { + okflag = FALSE; + } + if(AllItemsList[i].iSpell == SPL_HEALOTHER && gbMaxPlayers == 1) { + okflag = FALSE; + } + if(okflag) { + ril[ri++] = i; + } + } + + return ril[random(25, ri)]; +} + +int RndAllItems() +{ + int i, ri, rv; + int ril[512]; + +#ifdef _DEBUG + if(!debug_mode_key_inverted_v && random(26, 100) > 25) { + return 0; + } +#else + if(random(26, 100) > 25) { + return 0; + } +#endif + + ri = 0; + for(i = 0; AllItemsList[i].iLoc != -1; i++) { + if(AllItemsList[i].iRnd != IDROP_NEVER && currlevel << 1 >= AllItemsList[i].iMinMLvl) { + ril[ri++] = i; + } + if(AllItemsList[i].iSpell == SPL_RESURRECT && gbMaxPlayers == 1) { + ri--; + } + if(AllItemsList[i].iSpell == SPL_HEALOTHER && gbMaxPlayers == 1) { + ri--; + } + } + + rv = random(26, ri); + return ril[rv]; +} + +int RndTypeItems(int itype, int imid) +{ + int i, ri; + int ril[512]; + BOOL okflag; + + ri = 0; + for(i = 0; AllItemsList[i].iLoc != -1; i++) { + okflag = TRUE; + if(AllItemsList[i].iRnd == IDROP_NEVER) { + okflag = FALSE; + } + if(currlevel << 1 < AllItemsList[i].iMinMLvl) { + okflag = FALSE; + } + if(AllItemsList[i].itype != itype) { + okflag = FALSE; + } + if(imid != -1 && AllItemsList[i].iMiscId != imid) { + okflag = FALSE; + } + if(okflag) { + ril[ri++] = i; + } + } + + return ril[random(27, ri)]; +} + +int CheckUnique(int i, int lvl, int uper, BOOL recreate) +{ + int j, idata, numu, rv; + BOOLEAN uok[128]; + +#ifdef _DEBUG + if((!debug_mode_key_d || !debug_mode_key_inverted_v) && random(28, 100) > uper) { +#else + if(random(28, 100) > uper) { +#endif + return -1; + } + + numu = 0; + memset(uok, 0, sizeof(uok)); + + for(j = 0; UniqueItemList[j].UIItemId != -1; j++) { + idata = item[i].IDidx; + if(UniqueItemList[j].UIItemId != AllItemsList[idata].iItemId) { + continue; + } + if(lvl < UniqueItemList[j].UIMinLvl) { + continue; + } + if(recreate || !UniqueItemFlag[j] || gbMaxPlayers != 1) { + uok[j] = TRUE; + numu++; + } + } + + if(numu == 0) { + return -1; + } + + rv = random(29, 10); /// BUGFIX: unused, last unique in array is always chosen + j = 0; + + while(numu > 0) { + if(uok[j]) { + numu--; + } + if(numu > 0) { + j++; + if(j == sizeof(uok)) { + j = 0; + } + } + } + + return j; +} + +void GetUniqueItem(int i, int uid) +{ + UniqueItemFlag[uid] = 1; + SaveItemPower(i, UniqueItemList[uid].UIPower1, UniqueItemList[uid].UIParam1, UniqueItemList[uid].UIParam2, 0, 0, 1); + + if(UniqueItemList[uid].UINumPL > 1) { + SaveItemPower(i, UniqueItemList[uid].UIPower2, UniqueItemList[uid].UIParam3, UniqueItemList[uid].UIParam4, 0, 0, 1); + } + if(UniqueItemList[uid].UINumPL > 2) { + SaveItemPower(i, UniqueItemList[uid].UIPower3, UniqueItemList[uid].UIParam5, UniqueItemList[uid].UIParam6, 0, 0, 1); + } + if(UniqueItemList[uid].UINumPL > 3) { + SaveItemPower(i, UniqueItemList[uid].UIPower4, UniqueItemList[uid].UIParam7, UniqueItemList[uid].UIParam8, 0, 0, 1); + } + if(UniqueItemList[uid].UINumPL > 4) { + SaveItemPower(i, UniqueItemList[uid].UIPower5, UniqueItemList[uid].UIParam9, UniqueItemList[uid].UIParam10, 0, 0, 1); + } + if(UniqueItemList[uid].UINumPL > 5) { + SaveItemPower(i, UniqueItemList[uid].UIPower6, UniqueItemList[uid].UIParam11, UniqueItemList[uid].UIParam12, 0, 0, 1); + } + + strcpy(item[i]._iIName, UniqueItemList[uid].UIName); + item[i]._iIvalue = UniqueItemList[uid].UIValue; + if(item[i]._iMiscId == IMISC_UNIQUE) { + item[i]._iSeed = uid; + } + item[i]._iUid = uid; + item[i]._iMagical = 2; + item[i]._iCreateInfo |= 0x0200; +} + +void SpawnUnique(int uid, int x, int y) +{ + int ii, itype; + + if(numitems >= MAXITEMS) { + return; + } + + ii = itemavail[0]; + GetSuperItemSpace(x, y, ii); + itemavail[0] = itemavail[MAXITEMS - numitems - 1]; + itemactive[numitems] = ii; + + itype = 0; + while(AllItemsList[itype].iItemId != UniqueItemList[uid].UIItemId) { + itype++; + } + + GetItemAttrs(ii, itype, currlevel); + GetUniqueItem(ii, uid); + SetupItem(ii); + numitems++; +} + +void ItemRndDur(int ii) +{ + if(item[ii]._iDurability == 0 || item[ii]._iDurability == 255) { + return; + } + + item[ii]._iDurability = random(0, item[ii]._iMaxDur >> 1) + (item[ii]._iMaxDur >> 2) + 1; +} + +void SetupAllItems(int ii, int idx, int iseed, int lvl, int uper, BOOL onlygood, BOOL recreate, BOOL pregen) +{ + int iblvl, uid; + + item[ii]._iSeed = iseed; + SetRndSeed(iseed); + GetItemAttrs(ii, idx, lvl >> 1); + item[ii]._iCreateInfo = lvl; + + if(pregen) { + item[ii]._iCreateInfo |= 0x8000; + } + if(onlygood) { + item[ii]._iCreateInfo |= 0x40; + } + + if(uper == 15) { + item[ii]._iCreateInfo |= 0x80; + } else if(uper == 1) { + item[ii]._iCreateInfo |= 0x0100; + } + + if(item[ii]._iMiscId != IMISC_UNIQUE) { + iblvl = -1; + if(random(32, 100) <= 10) { + iblvl = lvl; + } else if(random(33, 100) <= lvl) { + iblvl = lvl; + } + if(iblvl == -1 && item[ii]._iMiscId == IMISC_STAFF) { + iblvl = lvl; + } + if(iblvl == -1 && item[ii]._iMiscId == IMISC_RING) { + iblvl = lvl; + } + if(iblvl == -1 && item[ii]._iMiscId == IMISC_AMULET) { + iblvl = lvl; + } + if(onlygood) { + iblvl = lvl; + } +#ifdef _DEBUG + if(debug_mode_key_inverted_v) { + iblvl = lvl; + } +#endif + if(uper == 15) { + iblvl = lvl + 4; + } + if(iblvl != -1) { + uid = CheckUnique(ii, iblvl, uper, recreate); + if(uid == -1) { + GetItemBonus(ii, idx, iblvl >> 1, iblvl, onlygood); + } else { + GetUniqueItem(ii, uid); + item[ii]._iCreateInfo |= 0x0200; + } + } + if(item[ii]._iMagical != 2) { + ItemRndDur(ii); + } + } else if(item[ii]._iLoc != ILOC_UNEQUIPABLE) { + GetUniqueItem(ii, iseed); + } + + SetupItem(ii); +} + +void SpawnItem(int m, int x, int y, BOOL sendmsg) +{ + int ii, idx; + BOOL onlygood; + + if(monster[m]._uniqtype != 0 || (monster[m].MData->mTreasure & 0x8000 && gbMaxPlayers != 1)) { + idx = RndUItem(m); + if(idx < 0) { + SpawnUnique(-(idx + 1), x, y); + return; + } + onlygood = TRUE; + } else if(quests[Q_MUSHROOM]._qactive == 2 && quests[Q_MUSHROOM]._qvar1 == 5) { // QS_MUSHGIVEN + idx = IDI_BRAIN; + quests[Q_MUSHROOM]._qvar1 = 6; // QS_BRAINSPAWNED + } else { + idx = RndItem(m); + if(idx == 0) { + return; + } + if(idx > 0) { + idx--; + onlygood = FALSE; + } else { + SpawnUnique(-(idx + 1), x, y); + return; + } + } + + if(numitems >= MAXITEMS) { + return; + } + + ii = itemavail[0]; + GetSuperItemSpace(x, y, ii); + itemavail[0] = itemavail[MAXITEMS - numitems - 1]; + itemactive[numitems] = ii; + + if(monster[m]._uniqtype != 0) { + SetupAllItems(ii, idx, GetRndSeed(), monster[m].MData->mLevel, 15, onlygood, FALSE, FALSE); + } else { + SetupAllItems(ii, idx, GetRndSeed(), monster[m].MData->mLevel, 1, onlygood, FALSE, FALSE); + } + + numitems++; + + if(sendmsg) { + NetSendCmdDItem(FALSE, ii); + } +} + +void CreateItem(int uid, int x, int y) +{ + int ii, idx; + + if(numitems >= MAXITEMS) { + return; + } + + ii = itemavail[0]; + GetSuperItemSpace(x, y, ii); + itemavail[0] = itemavail[MAXITEMS - numitems - 1]; + itemactive[numitems] = ii; + + idx = 0; + while(AllItemsList[idx].iItemId != UniqueItemList[uid].UIItemId) { + idx++; + } + + GetItemAttrs(ii, idx, currlevel); + GetUniqueItem(ii, uid); + SetupItem(ii); + item[ii]._iMagical = 2; + numitems++; +} + +void CreateRndItem(int x, int y, BOOL onlygood, BOOL sendmsg, BOOL delta) +{ + int ii, idx; + + if(onlygood) { + idx = RndUItem(-1); + } else { + idx = RndAllItems(); + } + + if(numitems >= MAXITEMS) { + return; + } + + ii = itemavail[0]; + GetSuperItemSpace(x, y, ii); + itemavail[0] = itemavail[MAXITEMS - numitems - 1]; + itemactive[numitems] = ii; + SetupAllItems(ii, idx, GetRndSeed(), currlevel << 1, 1, onlygood, FALSE, delta); + + if(sendmsg) { + NetSendCmdDItem(FALSE, ii); + } + if(delta) { + DeltaAddItem(ii); + } + + numitems++; +} + +void SetupAllUseful(int ii, int iseed, int lvl) +{ + int idx; + + item[ii]._iSeed = iseed; + SetRndSeed(iseed); + + if(random(34, 2) != 0) { + idx = IDI_HEAL; + } else { + idx = IDI_MANA; + } + if(lvl > 1 && random(34, 3) == 0) { + idx = IDI_PORTAL; + } + + GetItemAttrs(ii, idx, lvl); + item[ii]._iCreateInfo = lvl + 0x180; + SetupItem(ii); +} + +void CreateRndUseful(int pnum, int x, int y, BOOL sendmsg) +{ + int ii; + + if(numitems >= MAXITEMS) { + return; + } + + ii = itemavail[0]; + GetSuperItemSpace(x, y, ii); + itemavail[0] = itemavail[MAXITEMS - numitems - 1]; + itemactive[numitems] = ii; + SetupAllUseful(ii, GetRndSeed(), currlevel); + + if(sendmsg) { + NetSendCmdDItem(FALSE, ii); + } + + numitems++; +} + +void CreateTypeItem(int x, int y, BOOL onlygood, int itype, int imisc, BOOL sendmsg, BOOL delta) +{ + int ii, idx; + + if(itype != ITYPE_GOLD) { + idx = RndTypeItems(itype, imisc); + } else { + idx = IDI_GOLD; + } + + if(numitems >= MAXITEMS) { + return; + } + + ii = itemavail[0]; + GetSuperItemSpace(x, y, ii); + itemavail[0] = itemavail[MAXITEMS - numitems - 1]; + itemactive[numitems] = ii; + SetupAllItems(ii, idx, GetRndSeed(), currlevel << 1, 1, onlygood, FALSE, delta); + + if(sendmsg) { + NetSendCmdDItem(FALSE, ii); + } + if(delta) { + DeltaAddItem(ii); + } + + numitems++; +} + +void RecreateItem(int ii, int idx, WORD icreateinfo, int iseed, int ivalue) +{ + int uper; + BOOL onlygood, uavail, pregen; + + if(idx == IDI_GOLD) { + SetPlrHandItem(&item[ii], idx); + item[ii]._iSeed = iseed; + item[ii]._iCreateInfo = icreateinfo; + item[ii]._ivalue = ivalue; + if(ivalue >= 2500) { + item[ii]._iCurs = 6; + } else if(ivalue <= 1000) { + item[ii]._iCurs = 4; + } else { + item[ii]._iCurs = 5; + } + } else { + if(icreateinfo == 0) { + SetPlrHandItem(&item[ii], idx); + SetPlrHandSeed(&item[ii], iseed); + } else if(icreateinfo & 0x7C00) { + RecreateTownItem(ii, idx, icreateinfo, iseed, ivalue); + } else if((icreateinfo & 0x0180) == 0x0180) { + SetupAllUseful(ii, iseed, icreateinfo & 0x3F); + } else { + uper = 0; + onlygood = FALSE; + uavail = FALSE; + pregen = FALSE; + if(icreateinfo & 0x0100) { + uper = 1; + } + if(icreateinfo & 0x80) { + uper = 15; + } + if(icreateinfo & 0x40) { + onlygood = TRUE; + } + if(icreateinfo & 0x0200) { + uavail = TRUE; + } + if(icreateinfo & 0x8000) { + pregen = TRUE; + } + SetupAllItems(ii, idx, iseed, icreateinfo & 0x3F, uper, onlygood, uavail, pregen); + } + } +} + +void RecreateEar(int ii, WORD ic, int iseed, BOOL Id, int dur, int mdur, int ch, int mch, int ivalue, int ibuff) +{ + SetPlrHandItem(&item[ii], IDI_EAR); + tempstr[0] = (ic >> 8) & 0x7F; + tempstr[1] = ic & 0x7F; + tempstr[2] = (iseed >> 24) & 0x7F; + tempstr[3] = (iseed >> 16) & 0x7F; + tempstr[4] = (iseed >> 8) & 0x7F; + tempstr[5] = iseed & 0x7F; + tempstr[6] = Id & 0x7F; + tempstr[7] = dur & 0x7F; + tempstr[8] = mdur & 0x7F; + tempstr[9] = ch & 0x7F; + tempstr[10] = mch & 0x7F; + tempstr[11] = (ivalue >> 8) & 0x7F; + tempstr[12] = (ibuff >> 24) & 0x7F; + tempstr[13] = (ibuff >> 16) & 0x7F; + tempstr[14] = (ibuff >> 8) & 0x7F; + tempstr[15] = ibuff & 0x7F; + tempstr[16] = '\0'; + sprintf(item[ii]._iName, "Ear of %s", tempstr); + item[ii]._iCurs = ((ivalue >> 6) & 3) + 19; + item[ii]._ivalue = ivalue & 0x3F; + item[ii]._iCreateInfo = ic; + item[ii]._iSeed = iseed; +} + +void SpawnQuestItem(int itemid, int x, int y, int randarea, int selflag) +{ + int i, j, tries; + BOOL failed; + + if(randarea != 0) { + tries = 0; + while(1) { + tries++; + if(tries > 1000 && randarea > 1) { + randarea--; + } + x = random(0, MAXDUNX); + y = random(0, MAXDUNY); + failed = FALSE; + for(i = 0; i < randarea && !failed; i++) { + for(j = 0; j < randarea && !failed; j++) { + failed = !ItemSpaceOk(i + x, j + y); + } + } + if(!failed) { + break; + } + } + } + + if(numitems >= MAXITEMS) { + return; + } + + i = itemavail[0]; + itemavail[0] = itemavail[MAXITEMS - numitems - 1]; + itemactive[numitems] = i; + item[i]._ix = x; + item[i]._iy = y; + dItem[x][y] = i + 1; + GetItemAttrs(i, itemid, currlevel); + SetupItem(i); + item[i]._iPostDraw = 1; + + if(selflag != 0) { + item[i]._iSelFlag = selflag; + item[i]._iAnimFrame = item[i]._iAnimLen; + item[i]._iAnimFlag = 0; + } + + numitems++; +} + +void SpawnRock() +{ + int i, ii, ostand, xx, yy; + BOOL done; + + done = FALSE; + for(i = 0; i < nobjects && !done; i++) { + ostand = objectactive[i]; + done = object[ostand]._otype == OBJ_STAND; + } + if(done) { + ii = itemavail[0]; + itemavail[0] = itemavail[MAXITEMS - numitems - 1]; + itemactive[numitems] = ii; + item[ii]._ix = object[ostand]._ox; + xx = item[ii]._ix; + item[ii]._iy = object[ostand]._oy; + yy = item[ii]._iy; + dItem[xx][yy] = ii + 1; + GetItemAttrs(ii, IDI_ROCK, currlevel); + SetupItem(ii); + item[ii]._iSelFlag = 2; + item[ii]._iPostDraw = 1; + item[ii]._iAnimFrame = 11; + numitems++; + } +} + +void RespawnItem(int i, BOOL FlipFlag) +{ + int it; + + it = ItemCAnimTbl[item[i]._iCurs]; + item[i]._iAnimData = itemanims[it]; + item[i]._iAnimLen = ItemAnimLs[it]; + item[i]._iAnimWidth = 96; + item[i]._iAnimWidth2 = 16; + item[i]._iPostDraw = 0; + item[i]._iRequest = 0; + + if(FlipFlag) { + item[i]._iAnimFrame = 1; + item[i]._iAnimFlag = 1; + item[i]._iSelFlag = 0; + } else { + item[i]._iAnimFrame = item[i]._iAnimLen; + item[i]._iAnimFlag = 0; + item[i]._iSelFlag = 1; + } + + if(item[i]._iCurs == 76) { // Magic Rock + item[i]._iSelFlag = 1; + PlaySfxLoc(ItemDropSnds[it], item[i]._ix, item[i]._iy); + } + if(item[i]._iCurs == 126) { // Tavern Sign + item[i]._iSelFlag = 1; + } + if(item[i]._iCurs == 140) { // Anvil of Fury + item[i]._iSelFlag = 1; + } +} + +void DeleteItem(int ii, int i) +{ + itemavail[MAXITEMS - numitems] = ii; + numitems--; + + if(numitems > 0 && i != numitems) { + itemactive[i] = itemactive[numitems]; + } +} + +void ItemDoppel() +{ + int idoppelx; + ItemStruct *i; + + if(gbMaxPlayers == 1) { + return; + } + + for(idoppelx = 16; idoppelx < 96; idoppelx++) { + if(dItem[idoppelx][idoppely] != 0) { + i = &item[dItem[idoppelx][idoppely] - 1]; + if(i->_ix != idoppelx || i->_iy != idoppely) { + dItem[idoppelx][idoppely] = 0; + } + } + } + + idoppely++; + if(idoppely == 96) { + idoppely = 16; + } +} + +void ProcessItems() +{ + int i, ii, it; + + for(i = 0; i < numitems; i++) { + ii = itemactive[i]; + if(item[ii]._iAnimFlag) { + item[ii]._iAnimFrame++; + if(item[ii]._iCurs == 76) { // Magic Rock + if(item[ii]._iSelFlag == 1 && item[ii]._iAnimFrame == 11) { + item[ii]._iAnimFrame = 1; + } + if(item[ii]._iSelFlag == 2 && item[ii]._iAnimFrame == 21) { + item[ii]._iAnimFrame = 11; + } + } else { + if(item[ii]._iAnimFrame == item[ii]._iAnimLen >> 1) { + it = ItemCAnimTbl[item[ii]._iCurs]; + PlaySfxLoc(ItemDropSnds[it], item[ii]._ix, item[ii]._iy); + } + if(item[ii]._iAnimFrame >= item[ii]._iAnimLen) { + item[ii]._iAnimFrame = item[ii]._iAnimLen; + item[ii]._iAnimFlag = 0; + item[ii]._iSelFlag = 1; + } + } + } + } + + ItemDoppel(); +} + +void FreeItemGFX() +{ + int i; + + for(i = 0; i < 35; i++) { + MemFreeDbg(itemanims[i]); + } +} + +void GetItemFrm(int i) +{ + int it; + + it = ItemCAnimTbl[item[i]._iCurs]; + item[i]._iAnimData = itemanims[it]; +} + +void GetItemStr(int i) +{ + int nGold; + + if(item[i]._itype != ITYPE_GOLD) { + if(item[i]._iIdentified) { + strcpy(infostr, item[i]._iIName); + } else { + strcpy(infostr, item[i]._iName); + } + if(item[i]._iMagical == 1) { + infoclr = COL_BLUE; + } + if(item[i]._iMagical == 2) { + infoclr = COL_GOLD; + } + } else { + nGold = item[i]._ivalue; + sprintf(infostr, "%i gold %s", nGold, get_pieces_str(nGold)); + } +} + +void CheckIdentify(int pnum, int cii) +{ + ItemStruct *pi; + + if(cii >= 7) { + pi = &plr[pnum].InvList[cii - 7]; + } else { + pi = &plr[pnum].InvBody[cii]; + } + + pi->_iIdentified = 1; + CalcPlrInv(pnum, TRUE); + + if(pnum == myplr) { + SetCursor_(CURSOR_HAND); + } +} + +void DoRepair(int pnum, int cii) +{ + PlayerStruct *p; + ItemStruct *pi; + + p = &plr[pnum]; + PlaySfxLoc(IS_REPAIR, p->WorldX, p->WorldY); + + if(cii >= 7) { + pi = &p->InvList[cii - 7]; + } else { + pi = &p->InvBody[cii]; + } + + RepairItem(pi, p->_pLevel); + CalcPlrInv(pnum, TRUE); + + if(pnum == myplr) { + SetCursor_(CURSOR_HAND); + } +} + +void RepairItem(ItemStruct *i, int lvl) +{ + int d, rep; + + if(i->_iDurability == i->_iMaxDur) { + return; + } + if(i->_iMaxDur <= 0) { + i->_itype = -1; + return; + } + + rep = 0; + while(1) { + rep += random(37, lvl) + lvl; + d = i->_iMaxDur / (lvl + 9); + if(d < 1) { + d = 1; + } + i->_iMaxDur -= d; + if(i->_iMaxDur == 0) { + i->_itype = -1; + return; + } + if(rep + i->_iDurability >= i->_iMaxDur) { + break; + } + } + + i->_iDurability += rep; + if(i->_iDurability > i->_iMaxDur) { + i->_iDurability = i->_iMaxDur; + } +} + +void DoRecharge(int pnum, int cii) +{ + int r, sn; + PlayerStruct *p; + ItemStruct *pi; + + p = &plr[pnum]; + if(cii >= 7) { + pi = &p->InvList[cii - 7]; + } else { + pi = &p->InvBody[cii]; + } + + if(pi->_itype == ITYPE_STAFF && pi->_iSpell != SPL_NULL) { + sn = pi->_iSpell; + r = spelldata[sn].sBookLvl; + r = random(38, p->_pLevel / r) + 1; + RechargeItem(pi, r); + CalcPlrInv(pnum, TRUE); + } + + if(pnum == myplr) { + SetCursor_(CURSOR_HAND); + } +} + +void RechargeItem(ItemStruct *i, int r) +{ + if(i->_iCharges == i->_iMaxCharges) { + return; + } + + while(1) { + i->_iMaxCharges--; + if(i->_iMaxCharges == 0) { + return; + } + i->_iCharges += r; + if(i->_iCharges >= i->_iMaxCharges) { + break; + } + } + + if(i->_iCharges > i->_iMaxCharges) { + i->_iCharges = i->_iMaxCharges; + } +} + +void PrintItemOil(char IDidx) +{ + switch(IDidx) { + case IMISC_FULLHEAL: + strcpy(tempstr, "fully recover life"); + AddPanelString(tempstr, 1); + break; + case IMISC_HEAL: + strcpy(tempstr, "recover partial life"); + AddPanelString(tempstr, 1); + break; + case IMISC_OLDHEAL: + strcpy(tempstr, "recover life"); + AddPanelString(tempstr, 1); + break; + case IMISC_DEADHEAL: + strcpy(tempstr, "deadly heal"); + AddPanelString(tempstr, 1); + break; + case IMISC_MANA: + strcpy(tempstr, "recover mana"); + AddPanelString(tempstr, 1); + break; + case IMISC_FULLMANA: + strcpy(tempstr, "fully recover mana"); + AddPanelString(tempstr, 1); + break; + case IMISC_ELIXSTR: + strcpy(tempstr, "increase strength"); + AddPanelString(tempstr, 1); + break; + case IMISC_ELIXMAG: + strcpy(tempstr, "increase magic"); + AddPanelString(tempstr, 1); + break; + case IMISC_ELIXDEX: + strcpy(tempstr, "increase dexterity"); + AddPanelString(tempstr, 1); + break; + case IMISC_ELIXVIT: + strcpy(tempstr, "increase vitality"); + AddPanelString(tempstr, 1); + break; + case IMISC_ELIXWEAK: + strcpy(tempstr, "decrease strength"); + AddPanelString(tempstr, 1); + break; + case IMISC_ELIXDIS: + strcpy(tempstr, "decrease strength"); /// BUGFIX: "decrease magic" + AddPanelString(tempstr, 1); + break; + case IMISC_ELIXCLUM: + strcpy(tempstr, "decrease dexterity"); + AddPanelString(tempstr, 1); + break; + case IMISC_ELIXSICK: + strcpy(tempstr, "decrease vitality"); + AddPanelString(tempstr, 1); + break; + case IMISC_REJUV: + strcpy(tempstr, "recover life and mana"); + AddPanelString(tempstr, 1); + break; + case IMISC_FULLREJUV: + strcpy(tempstr, "fully recover life and mana"); + AddPanelString(tempstr, 1); + break; + } +} + +void PrintItemPower(char plidx, const ItemStruct *x) +{ + int v; + + switch(plidx) { + case IPL_TOHIT: + case IPL_TOHIT_CURSE: + sprintf(tempstr, "chance to hit : %+i%%", x->_iPLToHit); + break; + case IPL_DAMP: + case IPL_DAMP_CURSE: + sprintf(tempstr, "%+i%% damage", x->_iPLDam); + break; + case IPL_TOHIT_DAMP: + case IPL_TOHIT_DAMP_CURSE: + sprintf(tempstr, "to hit: %+i%%, %+i%% damage", x->_iPLToHit, x->_iPLDam); + break; + case IPL_ACP: + case IPL_ACP_CURSE: + sprintf(tempstr, "%+i%% armor", x->_iPLAC); + break; + case IPL_SETAC: + sprintf(tempstr, "armor class: %i", x->_iAC); + break; + case IPL_AC_CURSE: + sprintf(tempstr, "armor class: %i", x->_iAC); + break; + case IPL_FIRERES: + if(x->_iPLFR < 75) { + sprintf(tempstr, "Resist Fire : %+i%%", x->_iPLFR); + } + if(x->_iPLFR >= 75) { + sprintf(tempstr, "Resist Fire : 75%% MAX"); + } + break; + case IPL_LIGHTRES: + if(x->_iPLLR < 75) { + sprintf(tempstr, "Resist Lightning : %+i%%", x->_iPLLR); + } + if(x->_iPLLR >= 75) { + sprintf(tempstr, "Resist Lightning : 75%% MAX"); + } + break; + case IPL_MAGICRES: + if(x->_iPLMR < 75) { + sprintf(tempstr, "Resist Magic : %+i%%", x->_iPLMR); + } + if(x->_iPLMR >= 75) { + sprintf(tempstr, "Resist Magic : 75%% MAX"); + } + break; + case IPL_ALLRES: + if(x->_iPLFR < 75) { + sprintf(tempstr, "Resist All : %+i%%", x->_iPLFR); + } + if(x->_iPLFR >= 75) { + sprintf(tempstr, "Resist All : 75%% MAX"); + } + break; + case IPL_SPLLVLADD: + if(x->_iSplLvlAdd == 1) { + strcpy(tempstr, "spells are increased 1 level"); + } + if(x->_iSplLvlAdd == 2) { + strcpy(tempstr, "spells are increased 2 levels"); + } + if(x->_iSplLvlAdd < 1) { + strcpy(tempstr, "spells are decreased 1 level"); + } + break; + case IPL_CHARGES: + strcpy(tempstr, "Extra charges"); + break; + case IPL_SPELL: + sprintf(tempstr, "%i %s charges", x->_iMaxCharges, spelldata[x->_iSpell].sNameText); + break; + case IPL_FIREDAM: + sprintf(tempstr, "Fire hit damage: %i-%i", x->_iFMinDam, x->_iFMaxDam); + break; + case IPL_LIGHTDAM: + sprintf(tempstr, "Lightning hit damage: %i-%i", x->_iLMinDam, x->_iLMaxDam); + break; + case IPL_STR: + case IPL_STR_CURSE: + sprintf(tempstr, "%+i to strength", x->_iPLStr); + break; + case IPL_MAG: + case IPL_MAG_CURSE: + sprintf(tempstr, "%+i to magic", x->_iPLMag); + break; + case IPL_DEX: + case IPL_DEX_CURSE: + sprintf(tempstr, "%+i to dexterity", x->_iPLDex); + break; + case IPL_VIT: + case IPL_VIT_CURSE: + sprintf(tempstr, "%+i to vitality", x->_iPLVit); + break; + case IPL_ATTRIBS: + case IPL_ATTRIBS_CURSE: + sprintf(tempstr, "%+i to all attributes", x->_iPLStr); + break; + case IPL_GETHIT_CURSE: + case IPL_GETHIT: + sprintf(tempstr, "%+i damage from enemies", x->_iPLGetHit); + break; + case IPL_LIFE: + case IPL_LIFE_CURSE: + sprintf(tempstr, "Hit Points : %+i", x->_iPLHP >> 6); + break; + case IPL_MANA: + case IPL_MANA_CURSE: + sprintf(tempstr, "Mana : %+i", x->_iPLMana >> 6); + break; + case IPL_DUR: + strcpy(tempstr, "high durability"); + break; + case IPL_DUR_CURSE: + strcpy(tempstr, "decreased durability"); + break; + case IPL_INDESTRUCTIBLE: + strcpy(tempstr, "indestructible"); + break; + case IPL_LIGHT: + v = 10 * x->_iPLLight; + sprintf(tempstr, "+%i%% light radius", v); + break; + case IPL_LIGHT_CURSE: + v = -10 * x->_iPLLight; + sprintf(tempstr, "-%i%% light radius", v); + break; + case IPL_FIRE_ARROWS: + sprintf(tempstr, "fire arrows damage: %i-%i", x->_iFMinDam, x->_iFMaxDam); + break; + case IPL_LIGHT_ARROWS: + sprintf(tempstr, "lightning arrows damage %i-%i", x->_iLMinDam, x->_iLMaxDam); + break; + case IPL_THORNS: + strcpy(tempstr, "attacker takes 1-3 damage"); + break; + case IPL_NOMANA: + strcpy(tempstr, "user loses all mana"); + break; + case IPL_NOHEALPLR: + strcpy(tempstr, "you can't heal"); + break; + case IPL_ABSHALFTRAP: + strcpy(tempstr, "absorbs half of trap damage"); + break; + case IPL_KNOCKBACK: + strcpy(tempstr, "knocks target back"); + break; + case IPL_3XDAMVDEM: + strcpy(tempstr, "+200% damage vs. demons"); + break; + case IPL_ALLRESZERO: + strcpy(tempstr, "All Resistance equals 0"); + break; + case IPL_NOHEALMON: + strcpy(tempstr, "hit monster doesn't heal"); + break; + case IPL_STEALMANA: + if(x->_iFlags & ISPL_STEALMANA_3) { + strcpy(tempstr, "hit steals 3% mana"); + } + if(x->_iFlags & ISPL_STEALMANA_5) { + strcpy(tempstr, "hit steals 5% mana"); + } + break; + case IPL_STEALLIFE: + if(x->_iFlags & ISPL_STEALLIFE_3) { + strcpy(tempstr, "hit steals 3% life"); + } + if(x->_iFlags & ISPL_STEALLIFE_5) { + strcpy(tempstr, "hit steals 5% life"); + } + break; + case IPL_TARGAC: + strcpy(tempstr, "damages target's armor"); + break; + case IPL_FASTATTACK: + if(x->_iFlags & ISPL_QUICKATTACK) { + strcpy(tempstr, "quick attack"); + } + if(x->_iFlags & ISPL_FASTATTACK) { + strcpy(tempstr, "fast attack"); + } + if(x->_iFlags & ISPL_FASTERATTACK) { + strcpy(tempstr, "faster attack"); + } + if(x->_iFlags & ISPL_FASTESTATTACK) { + strcpy(tempstr, "fastest attack"); + } + break; + case IPL_FASTRECOVER: + if(x->_iFlags & ISPL_FASTRECOVER) { + strcpy(tempstr, "fast hit recovery"); + } + if(x->_iFlags & ISPL_FASTERRECOVER) { + strcpy(tempstr, "faster hit recovery"); + } + if(x->_iFlags & ISPL_FASTESTRECOVER) { + strcpy(tempstr, "fastest hit recovery"); + } + break; + case IPL_FASTBLOCK: + strcpy(tempstr, "fast block"); + break; + case IPL_DAMMOD: + sprintf(tempstr, "adds %i points to damage", x->_iPLDamMod); + break; + case IPL_RNDARROWVEL: + strcpy(tempstr, "fires random speed arrows"); + break; + case IPL_SETDAM: + sprintf(tempstr, "unusual item damage"); + break; + case IPL_SETDUR: + strcpy(tempstr, "altered durability"); + break; + case IPL_FASTSWING: + strcpy(tempstr, "Faster attack swing"); + break; + case IPL_ONEHAND: + strcpy(tempstr, "one handed sword"); + break; + case IPL_DRAINLIFE: + strcpy(tempstr, "constantly lose hit points"); + break; + case IPL_RNDSTEALLIFE: + strcpy(tempstr, "life stealing"); + break; + case IPL_NOMINSTR: + strcpy(tempstr, "no strength requirement"); + break; + case IPL_INFRAVISION: + strcpy(tempstr, "see with infravision"); + break; + case IPL_INVCURS: + strcpy(tempstr, " "); + break; + case IPL_ADDACLIFE: + strcpy(tempstr, "Armor class added to life"); + break; + case IPL_ADDMANAAC: + strcpy(tempstr, "10% of mana added to armor"); + break; + case IPL_FIRERESCLVL: + if(x->_iPLFR <= 0) { + sprintf(tempstr, " "); + } else if(x->_iPLFR >= 1) { + sprintf(tempstr, "Resist Fire : %+i%%", x->_iPLFR); + } + break; + default: + strcpy(tempstr, "Another ability (NW)"); + break; + } +} + +void DrawUTextBack() +{ + CelDecodeOnly(88, 487, (BYTE *)pSTextBoxCels, 1, 271); + + /// ASSERT: assert(gpBuffer); + +#ifdef USE_ASM + __asm { + mov edi, gpBuffer + add edi, SCREENXY(27, 324) + xor eax, eax + mov edx, 297 / 2 + label1: + mov ecx, 265 / 2 + label2: + stosb + inc edi + loop label2 + stosb + sub edi, 768 + 265 + mov ecx, 265 / 2 + label3: + inc edi + stosb + loop label3 + sub edi, 768 + (265 - 1) + dec edx + jnz label1 + mov ecx, 265 / 2 + label4: + stosb + inc edi + loop label4 + stosb + } +#else + int wdt, hgt; + BYTE *dst; + + dst = &gpBuffer[SCREENXY(27, 324)]; + + for(hgt = 297 / 2; hgt != 0; hgt--) { + for(wdt = 265 / 2; wdt != 0; wdt--) { + dst[0] = 0; + dst += 2; + } + *dst = 0; + dst -= 768 + (265 - 1); + for(wdt = 265 / 2; wdt != 0; wdt--) { + dst[1] = 0; + dst += 2; + } + dst -= 768 + (265 - 1); + } + for(wdt = 265 / 2; wdt != 0; wdt--) { + dst[0] = 0; + dst += 2; + } + *dst = 0; +#endif +} + +void PrintUString(int x, int y, int cjustflag, char *str, int col) +{ + int i, l, w, o, sy, No; + BYTE c; + + sy = SStringY[y]; + No = x + 32 + 64 + PitchTbl[sy + 44 + 160]; + l = strlen(str); + o = 0; + + if(cjustflag) { + w = 0; + for(i = 0; i < l; i++) { + c = fontframe[gbFontTransTbl[(BYTE)str[i]]]; + w += fontkern[c] + 1; + } + if(w < 257) { + o = (257 - w) >> 1; + } + No += o; + } + + for(i = 0; i < l; i++) { + c = fontframe[gbFontTransTbl[(BYTE)str[i]]]; + o += fontkern[c] + 1; + if(c != '\0' && o <= 257) { + PrintChar(No, c, col); + } + No += fontkern[c] + 1; + } +} + +void DrawULine(int y) +{ + /// ASSERT: assert(gpBuffer); + +#ifdef USE_ASM + int yy; + + yy = PitchTbl[SStringY[y] + 198] + 26 + 64; + + __asm { + mov esi, gpBuffer + mov edi, esi + add esi, SCREENXY(26, 25) + add edi, yy + mov ebx, 768 - 266 + mov edx, 3 + copyline: + mov ecx, 266 / 4 + rep movsd + movsw + add esi, ebx + add edi, ebx + dec edx + jnz copyline + } +#else + int i; + BYTE *src, *dst; + + src = &gpBuffer[SCREENXY(26, 25)]; + dst = &gpBuffer[PitchTbl[SStringY[y] + 198] + 26 + 64]; + + for(i = 0; i < 3; i++, src += 768, dst += 768) + memcpy(dst, src, 266); +#endif +} + +void DrawUniqueInfo() +{ + int uid, y; + + if(chrflag || questlog) { + return; + } + + uid = curruitem._iUid; + DrawUTextBack(); + PrintUString(0, 2, 1, UniqueItemList[uid].UIName, COL_GOLD); + DrawULine(5); + PrintItemPower(UniqueItemList[uid].UIPower1, &curruitem); + y = 6 - UniqueItemList[uid].UINumPL + 8; + PrintUString(0, y, 1, tempstr, COL_WHITE); + + if(UniqueItemList[uid].UINumPL > 1) { + PrintItemPower(UniqueItemList[uid].UIPower2, &curruitem); + PrintUString(0, y + 2, 1, tempstr, COL_WHITE); + } + if(UniqueItemList[uid].UINumPL > 2) { + PrintItemPower(UniqueItemList[uid].UIPower3, &curruitem); + PrintUString(0, y + 4, 1, tempstr, COL_WHITE); + } + if(UniqueItemList[uid].UINumPL > 3) { + PrintItemPower(UniqueItemList[uid].UIPower4, &curruitem); + PrintUString(0, y + 6, 1, tempstr, COL_WHITE); + } + if(UniqueItemList[uid].UINumPL > 4) { + PrintItemPower(UniqueItemList[uid].UIPower5, &curruitem); + PrintUString(0, y + 8, 1, tempstr, COL_WHITE); + } + if(UniqueItemList[uid].UINumPL > 5) { + PrintItemPower(UniqueItemList[uid].UIPower6, &curruitem); + PrintUString(0, y + 10, 1, tempstr, COL_WHITE); + } +} + +void PrintItemMisc(ItemStruct *x) +{ + if(x->_iMiscId == IMISC_SCROLL) { + strcpy(tempstr, "Right-click to read"); + AddPanelString(tempstr, 1); + } + if(x->_iMiscId == IMISC_SCROLLT) { + strcpy(tempstr, "Right-click to read, then"); + AddPanelString(tempstr, 1); + strcpy(tempstr, "left-click to target"); + AddPanelString(tempstr, 1); + } + if(x->_iMiscId >= IMISC_USEFIRST && x->_iMiscId <= IMISC_USELAST) { + PrintItemOil(x->_iMiscId); + strcpy(tempstr, "Right click to use"); + AddPanelString(tempstr, 1); + } + if(x->_iMiscId == IMISC_BOOK) { + strcpy(tempstr, "Right click to read"); + AddPanelString(tempstr, 1); + } + if(x->_iMiscId == IMISC_MAPOFDOOM) { + strcpy(tempstr, "Right click to view"); + AddPanelString(tempstr, 1); + } + if(x->_iMiscId == IMISC_EAR) { + sprintf(tempstr, "Level : %i", x->_ivalue); + AddPanelString(tempstr, 1); + } +} + +void PrintItemDetails(ItemStruct *x) +{ + if(x->_iClass == ICLASS_WEAPON) { + if(x->_iMaxDur == 255) { + sprintf(tempstr, "damage: %i-%i Indestructible", x->_iMinDam, x->_iMaxDam); + } else { + sprintf(tempstr, "damage: %i-%i Dur: %i/%i", x->_iMinDam, x->_iMaxDam, x->_iDurability, x->_iMaxDur); + } + AddPanelString(tempstr, 1); + } + if(x->_iClass == ICLASS_ARMOR) { + if(x->_iMaxDur == 255) { + sprintf(tempstr, "armor: %i Indestructible", x->_iAC); + } else { + sprintf(tempstr, "armor: %i Dur: %i/%i", x->_iAC, x->_iDurability, x->_iMaxDur); + } + AddPanelString(tempstr, 1); + } + if(x->_iMiscId == IMISC_STAFF && x->_iMaxCharges != 0) { + sprintf(tempstr, "dam: %i-%i Dur: %i/%i", x->_iMinDam, x->_iMaxDam, x->_iDurability, x->_iMaxDur); + sprintf(tempstr, "Charges: %i/%i", x->_iCharges, x->_iMaxCharges); + AddPanelString(tempstr, 1); + } + if(x->_iPrePower != -1) { + PrintItemPower(x->_iPrePower, x); + AddPanelString(tempstr, 1); + } + if(x->_iSufPower != -1) { + PrintItemPower(x->_iSufPower, x); + AddPanelString(tempstr, 1); + } + if(x->_iMagical == 2) { + AddPanelString("unique item", 1); + uitemflag = 1; + curruitem = *x; + } + + PrintItemMisc(x); + + if(x->_iMinStr + x->_iMinMag + x->_iMinDex) { + strcpy(tempstr, "Required:"); + if(x->_iMinStr != 0) { + sprintf(tempstr, "%s %i Str", tempstr, x->_iMinStr); + } + if(x->_iMinMag != 0) { + sprintf(tempstr, "%s %i Mag", tempstr, x->_iMinMag); + } + if(x->_iMinDex != 0) { + sprintf(tempstr, "%s %i Dex", tempstr, x->_iMinDex); + } + AddPanelString(tempstr, 1); + } + + pinfoflag = 1; +} + +void PrintItemDur(ItemStruct *x) +{ + if(x->_iClass == ICLASS_WEAPON) { + if(x->_iMaxDur == 255) { + sprintf(tempstr, "damage: %i-%i Indestructible", x->_iMinDam, x->_iMaxDam); + } else { + sprintf(tempstr, "damage: %i-%i Dur: %i/%i", x->_iMinDam, x->_iMaxDam, x->_iDurability, x->_iMaxDur); + } + AddPanelString(tempstr, 1); + if(x->_iMiscId == IMISC_STAFF && x->_iMaxCharges != 0) { + sprintf(tempstr, "Charges: %i/%i", x->_iCharges, x->_iMaxCharges); + AddPanelString(tempstr, 1); + } + if(x->_iMagical != 0) { + AddPanelString("Not Identified", 1); + } + } + if(x->_iClass == ICLASS_ARMOR) { + if(x->_iMaxDur == 255) { + sprintf(tempstr, "armor: %i Indestructible", x->_iAC); + } else { + sprintf(tempstr, "armor: %i Dur: %i/%i", x->_iAC, x->_iDurability, x->_iMaxDur); + } + AddPanelString(tempstr, 1); + if(x->_iMagical != 0) { + AddPanelString("Not Identified", 1); + } + if(x->_iMiscId == IMISC_STAFF && x->_iMaxCharges != 0) { /// BUGFIX: Staff code is useless here, remove + sprintf(tempstr, "Charges: %i/%i", x->_iCharges, x->_iMaxCharges); + AddPanelString(tempstr, 1); + } + } + if(x->_itype == ITYPE_RING || x->_itype == ITYPE_AMULET) { + AddPanelString("Not Identified", 1); + } + + PrintItemMisc(x); + + if(x->_iMinStr + x->_iMinMag + x->_iMinDex) { + strcpy(tempstr, "Required:"); + if(x->_iMinStr != 0) { + sprintf(tempstr, "%s %i Str", tempstr, x->_iMinStr); + } + if(x->_iMinMag != 0) { + sprintf(tempstr, "%s %i Mag", tempstr, x->_iMinMag); + } + if(x->_iMinDex != 0) { + sprintf(tempstr, "%s %i Dex", tempstr, x->_iMinDex); + } + AddPanelString(tempstr, 1); + } + + pinfoflag = 1; +} + +void UseItem(int p, int Mid, int spl) +{ + long l; + __int64 t; /* todo: check usage */ + + switch(Mid) { + case IMISC_HEAL: + case IMISC_MEAT: + l = plr[p]._pMaxHP >> 8; + l = ((l >> 1) + random(39, l)) << 6; + if(plr[p]._pClass == PC_WARRIOR) { + l *= 2; + } + if(plr[p]._pClass == PC_ROGUE) { + l += l >> 1; + } + plr[p]._pHitPoints += l; + if(plr[p]._pHitPoints > plr[p]._pMaxHP) { + plr[p]._pHitPoints = plr[p]._pMaxHP; + } + plr[p]._pHPBase += l; + if(plr[p]._pHPBase > plr[p]._pMaxHPBase) { + plr[p]._pHPBase = plr[p]._pMaxHPBase; + } + drawhpflag = 1; + break; + case IMISC_FULLHEAL: + plr[p]._pHitPoints = plr[p]._pMaxHP; + plr[p]._pHPBase = plr[p]._pMaxHPBase; + drawhpflag = 1; + break; + case IMISC_MANA: + l = plr[p]._pMaxMana >> 8; + l = ((l >> 1) + random(40, l)) << 6; + if(plr[p]._pClass == PC_SORCERER) { + l *= 2; + } + if(plr[p]._pClass == PC_ROGUE) { + l += l >> 1; + } + if(!(plr[p]._pIFlags & ISPL_NOMANA)) { + plr[p]._pMana += l; + if(plr[p]._pMana > plr[p]._pMaxMana) { + plr[p]._pMana = plr[p]._pMaxMana; + } + plr[p]._pManaBase += l; + if(plr[p]._pManaBase > plr[p]._pMaxManaBase) { + plr[p]._pManaBase = plr[p]._pMaxManaBase; + } + drawmanaflag = 1; + } + break; + case IMISC_FULLMANA: + if(!(plr[p]._pIFlags & ISPL_NOMANA)) { + plr[p]._pMana = plr[p]._pMaxMana; + plr[p]._pManaBase = plr[p]._pMaxManaBase; + drawmanaflag = 1; + } + break; + case IMISC_ELIXSTR: + ModifyPlrStr(p, 1); + break; + case IMISC_ELIXMAG: + ModifyPlrMag(p, 1); + break; + case IMISC_ELIXDEX: + ModifyPlrDex(p, 1); + break; + case IMISC_ELIXVIT: + ModifyPlrVit(p, 1); + break; + case IMISC_BOOK: + t = 1; + plr[p]._pMemSpells64 |= t << (spl - 1); + if(plr[p]._pSplLvl[spl] < 15) { + plr[p]._pSplLvl[spl]++; + } + plr[p]._pMana += spelldata[spl].sManaCost << 6; + if(plr[p]._pMana > plr[p]._pMaxMana) { + plr[p]._pMana = plr[p]._pMaxMana; + } + plr[p]._pManaBase += spelldata[spl].sManaCost << 6; + if(plr[p]._pManaBase > plr[p]._pMaxManaBase) { + plr[p]._pManaBase = plr[p]._pMaxManaBase; + } + if(p == myplr) { + CalcPlrBookVals(p); + } + drawmanaflag = 1; + break; + case IMISC_REJUV: + l = plr[p]._pMaxHP >> 8; + l = ((l >> 1) + random(39, l)) << 6; + if(plr[p]._pClass == PC_WARRIOR) { + l *= 2; + } + if(plr[p]._pClass == PC_ROGUE) { + l += l >> 1; + } + plr[p]._pHitPoints += l; + if(plr[p]._pHitPoints > plr[p]._pMaxHP) { + plr[p]._pHitPoints = plr[p]._pMaxHP; + } + plr[p]._pHPBase += l; + if(plr[p]._pHPBase > plr[p]._pMaxHPBase) { + plr[p]._pHPBase = plr[p]._pMaxHPBase; + } + drawhpflag = 1; + l = plr[p]._pMaxMana >> 8; + l = ((l >> 1) + random(40, l)) << 6; + if(plr[p]._pClass == PC_SORCERER) { + l *= 2; + } + if(plr[p]._pClass == PC_ROGUE) { + l += l >> 1; + } + if(!(plr[p]._pIFlags & ISPL_NOMANA)) { + plr[p]._pMana += l; + if(plr[p]._pMana > plr[p]._pMaxMana) { + plr[p]._pMana = plr[p]._pMaxMana; + } + plr[p]._pManaBase += l; + if(plr[p]._pManaBase > plr[p]._pMaxManaBase) { + plr[p]._pManaBase = plr[p]._pMaxManaBase; + } + drawmanaflag = 1; + } + break; + case IMISC_FULLREJUV: + plr[p]._pHitPoints = plr[p]._pMaxHP; + plr[p]._pHPBase = plr[p]._pMaxHPBase; + drawhpflag = 1; + if(!(plr[p]._pIFlags & ISPL_NOMANA)) { + plr[p]._pMana = plr[p]._pMaxMana; + plr[p]._pManaBase = plr[p]._pMaxManaBase; + drawmanaflag = 1; + } + break; + case IMISC_SCROLL: + if(spelldata[spl].sTargeted) { + plr[p]._pTSpell = spl; + plr[p]._pTSplType = 4; + if(p == myplr) { + SetCursor_(CURSOR_TELEPORT); /* NewCursor */ + } + } else { + ClrPlrPath(p); + plr[p]._pSpell = spl; + plr[p]._pSplType = 4; + plr[p]._pSplFrom = 3; + plr[p].destAction = 12; + plr[p].destParam1 = cursmx; + plr[p].destParam2 = cursmy; + if(p == myplr && spl == SPL_NOVA) { + NetSendCmdLoc(TRUE, CMD_NOVA, cursmx, cursmy); + } + } + break; + case IMISC_SCROLLT: + if(spelldata[spl].sTargeted) { + plr[p]._pTSpell = spl; + plr[p]._pTSplType = 4; + if(p == myplr) { + SetCursor_(CURSOR_TELEPORT); /* NewCursor */ + } + } else { + ClrPlrPath(p); + plr[p]._pSpell = spl; + plr[p]._pSplType = 4; + plr[p]._pSplFrom = 3; + plr[p].destAction = 12; + plr[p].destParam1 = cursmx; + plr[p].destParam2 = cursmy; + } + break; + case IMISC_MAPOFDOOM: + doom_init(); + break; + case IMISC_SPECELIX: + ModifyPlrStr(p, 3); + ModifyPlrMag(p, 3); + ModifyPlrDex(p, 3); + ModifyPlrVit(p, 3); + break; + } +} + +BOOL StoreStatOk(ItemStruct *h) +{ + BOOL sf; + + sf = TRUE; + if(plr[myplr]._pStrength < h->_iMinStr) { + sf = FALSE; + } + if(plr[myplr]._pMagic < h->_iMinMag) { + sf = FALSE; + } + if(plr[myplr]._pDexterity < h->_iMinDex) { + sf = FALSE; + } + + return sf; +} + +BOOL SmithItemOk(int i) +{ + BOOL rv; + + rv = TRUE; + if(AllItemsList[i].itype == ITYPE_MISC) { + rv = FALSE; + } + if(AllItemsList[i].itype == ITYPE_GOLD) { + rv = FALSE; + } + if(AllItemsList[i].itype == ITYPE_MEAT) { + rv = FALSE; + } + if(AllItemsList[i].itype == ITYPE_STAFF) { + rv = FALSE; + } + if(AllItemsList[i].itype == ITYPE_RING) { + rv = FALSE; + } + if(AllItemsList[i].itype == ITYPE_AMULET) { + rv = FALSE; + } + + return rv; +} + +int RndSmithItem(int lvl) +{ + int i, ri; + int ril[512]; + + ri = 0; + for(i = 1; AllItemsList[i].iLoc != -1; i++) { + if(AllItemsList[i].iRnd != IDROP_NEVER && SmithItemOk(i) && lvl >= AllItemsList[i].iMinMLvl) { + ril[ri++] = i; + if(AllItemsList[i].iRnd == IDROP_DOUBLE) { + ril[ri++] = i; + } + } + } + + return ril[random(50, ri)] + 1; +} + +void BubbleSwapItem(ItemStruct *a, ItemStruct *b) +{ + ItemStruct h; + + h = *a; + *a = *b; + *b = h; +} + +void SortSmith() +{ + int j, k; + BOOL sorted; + + k = 0; + for(j = 1; smithitem[j]._itype != -1; j++) { + k++; + } + + sorted = FALSE; + while(k > 0 && !sorted) { + sorted = TRUE; + for(j = 0; j < k; j++) { + if(smithitem[j].IDidx > smithitem[j + 1].IDidx) { + BubbleSwapItem(&smithitem[j], &smithitem[j + 1]); + sorted = FALSE; + } + } + k--; + } +} + +void SpawnSmith(int lvl) +{ + int i, nsi, itype, maxval; + + maxval = 140000; + nsi = random(50, 10) + 10; + for(i = 0; i < nsi; i++) { + do { + item[0]._iSeed = GetRndSeed(); + SetRndSeed(item[0]._iSeed); + itype = RndSmithItem(lvl) - 1; + GetItemAttrs(0, itype, lvl); + } while(item[0]._iIvalue > maxval); + smithitem[i] = item[0]; + smithitem[i]._iCreateInfo = lvl | 0x400; + smithitem[i]._iIdentified = 1; + smithitem[i]._iStatFlag = StoreStatOk(&smithitem[i]); + } + for(i = nsi; i < 20; i++) { + smithitem[i]._itype = -1; + } + + SortSmith(); +} + +BOOL PremiumItemOk(int i) +{ + BOOL rv; + + rv = TRUE; + if(AllItemsList[i].itype == ITYPE_MISC) { + rv = FALSE; + } + if(AllItemsList[i].itype == ITYPE_GOLD) { + rv = FALSE; + } + if(AllItemsList[i].itype == ITYPE_MEAT) { + rv = FALSE; + } + if(AllItemsList[i].itype == ITYPE_STAFF) { + rv = FALSE; + } + if(gbMaxPlayers != 1 && AllItemsList[i].itype == ITYPE_RING) { + rv = FALSE; + } + if(gbMaxPlayers != 1 && AllItemsList[i].itype == ITYPE_AMULET) { + rv = FALSE; + } + + return rv; +} + +int RndPremiumItem(int minlvl, int maxlvl) +{ + int i, ri; + int ril[512]; + + ri = 0; + for(i = 1; AllItemsList[i].iLoc != -1; i++) { + if(AllItemsList[i].iRnd != IDROP_NEVER + && PremiumItemOk(i) + && AllItemsList[i].iMinMLvl >= minlvl + && AllItemsList[i].iMinMLvl <= maxlvl) { + ril[ri++] = i; + } + } + + return ril[random(50, ri)] + 1; +} + +void SpawnOnePremium(int i, int plvl) +{ + int itype, maxval; + ItemStruct holditem; + + maxval = 140000; + holditem = item[0]; + +#ifdef _DEBUG + if(plvl > 30 || debug_mode_key_w) { +#else + if(plvl > 30) { +#endif + plvl = 30; + } + if(plvl < 1) { + plvl = 1; + } + + do { + item[0]._iSeed = GetRndSeed(); + SetRndSeed(item[0]._iSeed); + itype = RndPremiumItem(plvl >> 2, plvl) - 1; + GetItemAttrs(0, itype, plvl); + GetItemBonus(0, itype, plvl >> 1, plvl, 1); + } while(item[0]._iIvalue > maxval); + premiumitem[i] = item[0]; + premiumitem[i]._iCreateInfo = plvl | 0x800; + premiumitem[i]._iIdentified = 1; + premiumitem[i]._iStatFlag = StoreStatOk(&premiumitem[i]); + + item[0] = holditem; +} + +void SpawnPremium(int lvl) +{ + int i; + + if(numpremium < 6) { + for(i = 0; i < 6; i++) { + if(premiumitem[i]._itype == -1) { + SpawnOnePremium(i, premiumlevel + premiumlvladd[i]); + } + } + numpremium = 6; + } + while(premiumlevel < lvl) { + premiumlevel++; + premiumitem[0] = premiumitem[2]; + premiumitem[1] = premiumitem[3]; + premiumitem[2] = premiumitem[4]; + SpawnOnePremium(3, premiumlevel + premiumlvladd[3]); + premiumitem[4] = premiumitem[5]; + SpawnOnePremium(5, premiumlevel + premiumlvladd[5]); + } +} + +BOOL WitchItemOk(int i) +{ + BOOL rv; + + rv = FALSE; + if(AllItemsList[i].itype == ITYPE_MISC) { + rv = TRUE; + } + if(AllItemsList[i].itype == ITYPE_STAFF) { + rv = TRUE; + } + if(AllItemsList[i].iMiscId == IMISC_MANA) { + rv = FALSE; + } + if(AllItemsList[i].iMiscId == IMISC_FULLMANA) { + rv = FALSE; + } + if(AllItemsList[i].iSpell == SPL_TOWN) { + rv = FALSE; + } + if(AllItemsList[i].iMiscId == IMISC_FULLHEAL) { + rv = FALSE; + } + if(AllItemsList[i].iMiscId == IMISC_HEAL) { + rv = FALSE; + } + if(AllItemsList[i].iSpell == SPL_RESURRECT && gbMaxPlayers == 1) { + rv = FALSE; + } + if(AllItemsList[i].iSpell == SPL_HEALOTHER && gbMaxPlayers == 1) { + rv = FALSE; + } + + return rv; +} + +int RndWitchItem(int lvl) +{ + int i, ri; + int ril[512]; + + ri = 0; + for(i = 1; AllItemsList[i].iLoc != -1; i++) { + if(AllItemsList[i].iRnd != IDROP_NEVER && WitchItemOk(i) && lvl >= AllItemsList[i].iMinMLvl) { + ril[ri++] = i; + } + } + + return ril[random(51, ri)] + 1; +} + +void SortWitch() +{ + int j, k; + BOOL sorted; + + k = 3; + for(j = 4; witchitem[j]._itype != -1; j++) { + k++; + } + + sorted = FALSE; + while(k > 3 && !sorted) { + sorted = TRUE; + for(j = 3; j < k; j++) { + if(witchitem[j].IDidx > witchitem[j + 1].IDidx) { + BubbleSwapItem(&witchitem[j], &witchitem[j + 1]); + sorted = FALSE; + } + } + k--; + } +} + +void WitchBookLevel(int ii) +{ + int slvl; + + if(witchitem[ii]._iMiscId != IMISC_BOOK) { + return; + } + + witchitem[ii]._iMinMag = spelldata[witchitem[ii]._iSpell].sMinInt; + slvl = plr[myplr]._pSplLvl[witchitem[ii]._iSpell]; + while(slvl != 0) { + witchitem[ii]._iMinMag += 20 * witchitem[ii]._iMinMag / 100; + slvl--; + if(witchitem[ii]._iMinMag + 20 * witchitem[ii]._iMinMag / 100 > 255) { + witchitem[ii]._iMinMag = 255; + slvl = 0; + } + } +} + +void SpawnWitch(int lvl) +{ + int itype, iblvl, i, nsi, maxval; + + maxval = 140000; + + GetItemAttrs(0, IDI_MANA, 1); + witchitem[0] = item[0]; + witchitem[0]._iCreateInfo = lvl; + witchitem[0]._iStatFlag = 1; + GetItemAttrs(0, IDI_FULLMANA, 1); + witchitem[1] = item[0]; + witchitem[1]._iCreateInfo = lvl; + witchitem[1]._iStatFlag = 1; + GetItemAttrs(0, IDI_PORTAL, 1); + witchitem[2] = item[0]; + witchitem[2]._iCreateInfo = lvl; + witchitem[2]._iStatFlag = 1; + + nsi = random(51, 8) + 10; + for(i = 3; i < nsi; i++) { + do { + item[0]._iSeed = GetRndSeed(); + SetRndSeed(item[0]._iSeed); + itype = RndWitchItem(lvl) - 1; + GetItemAttrs(0, itype, lvl); + iblvl = -1; + if(random(51, 100) <= 5) { + iblvl = 2 * lvl; + } + if(iblvl == -1 && item[0]._iMiscId == IMISC_STAFF) { + iblvl = 2 * lvl; + } +#ifdef _DEBUG + if(debug_mode_key_inverted_v) { + iblvl = 2 * lvl; + } +#endif + if(iblvl != -1) { + GetItemBonus(0, itype, iblvl >> 1, iblvl, 1); + } + } while(item[0]._iIvalue > maxval); + witchitem[i] = item[0]; + witchitem[i]._iCreateInfo = lvl | 0x2000; + witchitem[i]._iIdentified = 1; + WitchBookLevel(i); + witchitem[i]._iStatFlag = StoreStatOk(&witchitem[i]); + } + for(i = nsi; i < 20; i++) { + witchitem[i]._itype = -1; + } + + SortWitch(); +} + +int RndBoyItem(int lvl) +{ + int i, ri; + int ril[512]; + + ri = 0; + for(i = 1; AllItemsList[i].iLoc != -1; i++) { + if(AllItemsList[i].iRnd != IDROP_NEVER && PremiumItemOk(i) && lvl >= AllItemsList[i].iMinMLvl) { + ril[ri++] = i; + } + } + + return ril[random(49, ri)] + 1; +} + +void SpawnBoy(int lvl) +{ + int itype, maxval; + + maxval = 90000; + + if(boylevel >= lvl >> 1 && boyitem._itype != -1) { + return; + } + + do { + item[0]._iSeed = GetRndSeed(); + SetRndSeed(item[0]._iSeed); + itype = RndBoyItem(lvl) - 1; + GetItemAttrs(0, itype, lvl); + GetItemBonus(0, itype, lvl, 2 * lvl, 1); + } while(item[0]._iIvalue > maxval); + boyitem = item[0]; + boyitem._iCreateInfo = lvl | 0x1000; + boyitem._iIdentified = 1; + boyitem._iStatFlag = StoreStatOk(&boyitem); + boylevel = lvl >> 1; +} + +BOOL HealerItemOk(int i) +{ + BOOL rv; + + rv = FALSE; + if(AllItemsList[i].itype != ITYPE_MISC) { + return FALSE; + } + if(AllItemsList[i].iMiscId == IMISC_SCROLL && AllItemsList[i].iSpell == SPL_HEAL) { + rv = TRUE; + } + if(AllItemsList[i].iMiscId == IMISC_SCROLLT && AllItemsList[i].iSpell == SPL_RESURRECT && gbMaxPlayers != 1) { + rv = FALSE; + } + if(AllItemsList[i].iMiscId == IMISC_SCROLLT && AllItemsList[i].iSpell == SPL_HEALOTHER && gbMaxPlayers != 1) { + rv = TRUE; + } + if(gbMaxPlayers == 1) { + if(AllItemsList[i].iMiscId == IMISC_ELIXSTR) { + rv = TRUE; + } + if(AllItemsList[i].iMiscId == IMISC_ELIXMAG) { + rv = TRUE; + } + if(AllItemsList[i].iMiscId == IMISC_ELIXDEX) { + rv = TRUE; + } + if(AllItemsList[i].iMiscId == IMISC_ELIXVIT) { + rv = TRUE; + } + } + if(AllItemsList[i].iMiscId == IMISC_FULLHEAL) { /// BUGFIX: same value checked below + rv = TRUE; + } + if(AllItemsList[i].iMiscId == IMISC_REJUV) { + rv = TRUE; + } + if(AllItemsList[i].iMiscId == IMISC_FULLREJUV) { + rv = TRUE; + } + if(AllItemsList[i].iMiscId == IMISC_HEAL) { + rv = FALSE; + } + if(AllItemsList[i].iMiscId == IMISC_FULLHEAL) { + rv = FALSE; + } + if(AllItemsList[i].iMiscId == IMISC_MANA) { + rv = FALSE; + } + if(AllItemsList[i].iMiscId == IMISC_FULLMANA) { + rv = FALSE; + } + + return rv; +} + +int RndHealerItem(int lvl) +{ + int i, ri; + int ril[512]; + + ri = 0; + for(i = 1; AllItemsList[i].iLoc != -1; i++) { + if(AllItemsList[i].iRnd != IDROP_NEVER && HealerItemOk(i) && lvl >= AllItemsList[i].iMinMLvl) { + ril[ri++] = i; + } + } + + return ril[random(50, ri)] + 1; +} + +void SortHealer() +{ + int j, k; + BOOL sorted; + + k = 2; + for(j = 3; healitem[j]._itype != -1; j++) { + k++; + } + + sorted = FALSE; + while(k > 2 && !sorted) { + sorted = TRUE; + for(j = 2; j < k; j++) { + if(healitem[j].IDidx > healitem[j + 1].IDidx) { + BubbleSwapItem(&healitem[j], &healitem[j + 1]); + sorted = FALSE; + } + } + k--; + } +} + +void SpawnHealer(int lvl) +{ + int i, nsi, srnd, itype; + + GetItemAttrs(0, IDI_HEAL, 1); + healitem[0] = item[0]; + healitem[0]._iCreateInfo = lvl; + healitem[0]._iStatFlag = 1; + GetItemAttrs(0, IDI_FULLHEAL, 1); + healitem[1] = item[0]; + healitem[1]._iCreateInfo = lvl; + healitem[1]._iStatFlag = 1; + + if(gbMaxPlayers != 1) { + GetItemAttrs(0, IDI_RESURRECT, 1); + healitem[2] = item[0]; + healitem[2]._iCreateInfo = lvl; + healitem[2]._iStatFlag = 1; + srnd = 3; + } else { + srnd = 2; + } + + nsi = random(50, 8) + 10; + for(i = srnd; i < nsi; i++) { + item[0]._iSeed = GetRndSeed(); + SetRndSeed(item[0]._iSeed); + itype = RndHealerItem(lvl) - 1; + GetItemAttrs(0, itype, lvl); + healitem[i] = item[0]; + healitem[i]._iCreateInfo = lvl | 0x4000; + healitem[i]._iIdentified = 1; + healitem[i]._iStatFlag = StoreStatOk(&healitem[i]); + } + for(i = nsi; i < 20; i++) { + healitem[i]._itype = -1; + } + + SortHealer(); +} + +void SpawnStoreGold() +{ + GetItemAttrs(0, IDI_GOLD, 1); + golditem = item[0]; + golditem._iStatFlag = 1; +} + +void RecreateSmithItem(int ii, int idx, int lvl, int iseed) +{ + int itype; + + SetRndSeed(iseed); + itype = RndSmithItem(lvl) - 1; + GetItemAttrs(ii, itype, lvl); + item[ii]._iSeed = iseed; + item[ii]._iCreateInfo = lvl | 0x400; + item[ii]._iIdentified = 1; +} + +void RecreatePremiumItem(int ii, int idx, int plvl, int iseed) +{ + int itype; + + SetRndSeed(iseed); + itype = RndPremiumItem(plvl >> 2, plvl) - 1; + GetItemAttrs(ii, itype, plvl); + GetItemBonus(ii, itype, plvl >> 1, plvl, 1); + item[ii]._iSeed = iseed; + item[ii]._iCreateInfo = plvl | 0x800; + item[ii]._iIdentified = 1; +} + +void RecreateBoyItem(int ii, int idx, int lvl, int iseed) +{ + int itype; + + SetRndSeed(iseed); + itype = RndBoyItem(lvl) - 1; + GetItemAttrs(ii, itype, lvl); + GetItemBonus(ii, itype, lvl, 2 * lvl, 1); + item[ii]._iSeed = iseed; + item[ii]._iCreateInfo = lvl | 0x1000; + item[ii]._iIdentified = 1; +} + +void RecreateWitchItem(int ii, int idx, int lvl, int iseed) +{ + int itype, iblvl; + + if(idx == IDI_MANA || idx == IDI_FULLMANA || idx == IDI_PORTAL) { + GetItemAttrs(ii, idx, lvl); + } else { + SetRndSeed(iseed); + itype = RndWitchItem(lvl) - 1; + GetItemAttrs(ii, itype, lvl); + iblvl = -1; + if(random(51, 100) <= 5) { + iblvl = 2 * lvl; + } + if(iblvl == -1 && item[ii]._iMiscId == IMISC_STAFF) { + iblvl = 2 * lvl; + } +#ifdef _DEBUG + if(debug_mode_key_inverted_v) { + iblvl = 2 * lvl; + } +#endif + if(iblvl != -1) { + GetItemBonus(ii, itype, iblvl >> 1, iblvl, 1); + } + } + + item[ii]._iSeed = iseed; + item[ii]._iCreateInfo = lvl | 0x2000; + item[ii]._iIdentified = 1; +} + +void RecreateHealerItem(int ii, int idx, int lvl, int iseed) +{ + int itype; + + if(idx == IDI_HEAL || idx == IDI_FULLHEAL || idx == IDI_RESURRECT) { + GetItemAttrs(ii, idx, lvl); + } else { + SetRndSeed(iseed); + itype = RndHealerItem(lvl) - 1; + GetItemAttrs(ii, itype, lvl); + } + + item[ii]._iSeed = iseed; + item[ii]._iCreateInfo = lvl | 0x4000; + item[ii]._iIdentified = 1; +} + +void RecreateTownItem(int ii, int idx, WORD icreateinfo, int iseed, int ivalue) +{ + if(icreateinfo & 0x400) { + RecreateSmithItem(ii, idx, icreateinfo & 0x3F, iseed); + } else if(icreateinfo & 0x800) { + RecreatePremiumItem(ii, idx, icreateinfo & 0x3F, iseed); + } else if(icreateinfo & 0x1000) { + RecreateBoyItem(ii, idx, icreateinfo & 0x3F, iseed); + } else if(icreateinfo & 0x2000) { + RecreateWitchItem(ii, idx, icreateinfo & 0x3F, iseed); + } else if(icreateinfo & 0x4000) { + RecreateHealerItem(ii, idx, icreateinfo & 0x3F, iseed); + } +} + +void RecalcStoreStats() +{ + int i; + + for(i = 0; i < 20; i++) { + if(smithitem[i]._itype != -1) { + smithitem[i]._iStatFlag = StoreStatOk(&smithitem[i]); + } + } + for(i = 0; i < 6; i++) { + if(premiumitem[i]._itype != -1) { + premiumitem[i]._iStatFlag = StoreStatOk(&premiumitem[i]); + } + } + for(i = 0; i < 20; i++) { + if(witchitem[i]._itype != -1) { + witchitem[i]._iStatFlag = StoreStatOk(&witchitem[i]); + } + } + for(i = 0; i < 20; i++) { + if(healitem[i]._itype != -1) { + healitem[i]._iStatFlag = StoreStatOk(&healitem[i]); + } + } + + boyitem._iStatFlag = StoreStatOk(&boyitem); +} + +int ItemNoFlippy() +{ + int r; + + r = itemactive[numitems - 1]; + item[r]._iAnimFrame = item[r]._iAnimLen; + item[r]._iAnimFlag = 0; + item[r]._iSelFlag = 1; + + return r; +} + +void CreateSpellBook(int x, int y, int ispell, BOOL sendmsg, BOOL delta) +{ + int ii, idx; + BOOL done; + + done = FALSE; + idx = RndTypeItems(ITYPE_MISC, IMISC_BOOK); + + if(numitems >= MAXITEMS) { + return; + } + + ii = itemavail[0]; + GetSuperItemSpace(x, y, ii); + itemavail[0] = itemavail[MAXITEMS - numitems - 1]; + itemactive[numitems] = ii; + + while(!done) { + SetupAllItems(ii, idx, GetRndSeed(), currlevel << 1, 1, TRUE, FALSE, delta); + if(item[ii]._iMiscId == IMISC_BOOK && item[ii]._iSpell == ispell) { + done = TRUE; + } + } + + if(sendmsg) { + NetSendCmdDItem(FALSE, ii); + } + if(delta) { + DeltaAddItem(ii); + } + + numitems++; +} + +void CreateMagicArmor(int x, int y, int imisc, int icurs, BOOL sendmsg, BOOL delta) +{ + int ii, idx; + BOOL done; + + done = FALSE; + + if(numitems >= MAXITEMS) { + return; + } + + ii = itemavail[0]; + GetSuperItemSpace(x, y, ii); + itemavail[0] = itemavail[MAXITEMS - numitems - 1]; + itemactive[numitems] = ii; + idx = RndTypeItems(imisc, IMISC_NONE); + + while(!done) { + SetupAllItems(ii, idx, GetRndSeed(), currlevel << 1, 1, TRUE, FALSE, delta); + if(item[ii]._iCurs == icurs) { + done = TRUE; + } else { + idx = RndTypeItems(imisc, IMISC_NONE); + } + } + + if(sendmsg) { + NetSendCmdDItem(FALSE, ii); + } + if(delta) { + DeltaAddItem(ii); + } + + numitems++; +} + +void CreateMagicWeapon(int x, int y, int imisc, int icurs, BOOL sendmsg, BOOL delta) +{ + int ii, idx; + BOOL done; + + done = FALSE; + + if(numitems >= MAXITEMS) { + return; + } + + ii = itemavail[0]; + GetSuperItemSpace(x, y, ii); + itemavail[0] = itemavail[MAXITEMS - numitems - 1]; + itemactive[numitems] = ii; + idx = RndTypeItems(imisc, IMISC_NONE); + + while(!done) { + SetupAllItems(ii, idx, GetRndSeed(), currlevel << 1, 1, TRUE, FALSE, delta); + if(item[ii]._iCurs == icurs) { + done = TRUE; + } else { + idx = RndTypeItems(imisc, IMISC_NONE); + } + } + + if(sendmsg) { + NetSendCmdDItem(FALSE, ii); + } + if(delta) { + DeltaAddItem(ii); + } + + numitems++; +} + +BOOL GetItemRecord(int nSeed, WORD wCI, int nIndex) +{ + int i; + DWORD dwTicks; + + dwTicks = GetTickCount(); + + for(i = 0; i < gnNumGetRecords; i++) { + if(dwTicks - itemrecord[i].dwTimestamp > 6000) { + NextItemRecord(i); + i--; + } else if(nSeed == itemrecord[i].nSeed && wCI == itemrecord[i].wCI && nIndex == itemrecord[i].nIndex) { + return FALSE; + } + } + + return TRUE; +} + +void NextItemRecord(int i) +{ + gnNumGetRecords--; + + if(gnNumGetRecords == 0) { + return; + } + + itemrecord[i].dwTimestamp = itemrecord[gnNumGetRecords].dwTimestamp; + itemrecord[i].nSeed = itemrecord[gnNumGetRecords].nSeed; + itemrecord[i].wCI = itemrecord[gnNumGetRecords].wCI; + itemrecord[i].nIndex = itemrecord[gnNumGetRecords].nIndex; +} + +void SetItemRecord(int nSeed, WORD wCI, int nIndex) +{ + DWORD dwTicks; + + dwTicks = GetTickCount(); + + if(gnNumGetRecords == MAXITEMS) { + return; + } + + itemrecord[gnNumGetRecords].dwTimestamp = dwTicks; + itemrecord[gnNumGetRecords].nSeed = nSeed; + itemrecord[gnNumGetRecords].wCI = wCI; + itemrecord[gnNumGetRecords].nIndex = nIndex; + gnNumGetRecords++; +} + +void PutItemRecord(int nSeed, WORD wCI, int nIndex) +{ + int i; + DWORD dwTicks; + + dwTicks = GetTickCount(); + + for(i = 0; i < gnNumGetRecords; i++) { + if(dwTicks - itemrecord[i].dwTimestamp > 6000) { + NextItemRecord(i); + i--; + } else if(nSeed == itemrecord[i].nSeed && wCI == itemrecord[i].wCI && nIndex == itemrecord[i].nIndex) { + NextItemRecord(i); + break; + } + } +} diff --git a/2020_03_31/Source/items.h b/2020_03_31/Source/items.h new file mode 100644 index 00000000..6b10478c --- /dev/null +++ b/2020_03_31/Source/items.h @@ -0,0 +1,139 @@ +//HEADER_GOES_HERE +#ifndef __ITEMS_H__ +#define __ITEMS_H__ + +extern int itemactive[MAXITEMS]; +extern int uitemflag; +extern int itemavail[MAXITEMS]; +extern ItemStruct curruitem; +extern ItemGetRecordStruct itemrecord[MAXITEMS]; +extern ItemStruct item[MAXITEMS+1]; +extern BOOL itemhold[3][3]; +extern unsigned char *itemanims[35]; +extern int UniqueItemFlag[128]; +extern int numitems; +extern int gnNumGetRecords; + +void InitItemGFX(); +BOOL ItemPlace(int xp, int yp); +void AddInitItems(); +void InitItems(); +void CalcPlrItemVals(int p, BOOL Loadgfx); +void CalcPlrScrolls(int p); +void CalcPlrStaff(int p); +void CalcSelfItems(int pnum); +void CalcPlrItemMin(int pnum); +BOOL ItemMinStats(PlayerStruct *p, ItemStruct *x); +void CalcPlrBookVals(int p); +void CalcPlrInv(int p, BOOL Loadgfx); +void SetPlrHandItem(ItemStruct *h, int idata); +void GetPlrHandSeed(ItemStruct *h); +void GetGoldSeed(int pnum, ItemStruct *h); +void SetPlrHandSeed(ItemStruct *h, int iseed); +void SetPlrHandGoldCurs(ItemStruct *h); +void CreatePlrItems(int p); +BOOL ItemSpaceOk(int i, int j); +BOOL GetItemSpace(int x, int y, char inum); +void GetSuperItemSpace(int x, int y, char inum); +void GetSuperItemLoc(int x, int y, int &xx, int &yy); +void CalcItemValue(int i); +void GetBookSpell(int i, int lvl); +void GetStaffPower(int i, int lvl, int bs, BOOL onlygood); +void GetStaffSpell(int i, int lvl, BOOL onlygood); +void GetItemAttrs(int i, int idata, int lvl); +int RndPL(int param1, int param2); +int PLVal(int pv, int p1, int p2, int minv, int maxv); +void SaveItemPower(int i, int power, int param1, int param2, int minval, int maxval, int multval); +void GetItemPower(int i, int minlvl, int maxlvl, long flgs, BOOL onlygood); +void GetItemBonus(int i, int idata, int minlvl, int maxlvl, BOOL onlygood); +void SetupItem(int i); +int RndItem(int m); +int RndUItem(int m); +int RndAllItems(); +int RndTypeItems(int itype, int imid); +int CheckUnique(int i, int lvl, int uper, BOOL recreate); +void GetUniqueItem(int i, int uid); +void SpawnUnique(int uid, int x, int y); +void ItemRndDur(int ii); +void SetupAllItems(int ii, int idx, int iseed, int lvl, int uper, BOOL onlygood, BOOL recreate, BOOL pregen); +void SpawnItem(int m, int x, int y, BOOL sendmsg); +void CreateItem(int uid, int x, int y); +void CreateRndItem(int x, int y, BOOL onlygood, BOOL sendmsg, BOOL delta); +void SetupAllUseful(int ii, int iseed, int lvl); +void CreateRndUseful(int pnum, int x, int y, BOOL sendmsg); +void CreateTypeItem(int x, int y, BOOL onlygood, int itype, int imisc, BOOL sendmsg, BOOL delta); +void RecreateItem(int ii, int idx, WORD icreateinfo, int iseed, int ivalue); +void RecreateEar(int ii, WORD ic, int iseed, BOOL Id, int dur, int mdur, int ch, int mch, int ivalue, int ibuff); +void SpawnQuestItem(int itemid, int x, int y, int randarea, int selflag); +void SpawnRock(); +void RespawnItem(int i, BOOL FlipFlag); +void DeleteItem(int ii, int i); +void ItemDoppel(); +void ProcessItems(); +void FreeItemGFX(); +void GetItemFrm(int i); +void GetItemStr(int i); +void CheckIdentify(int pnum, int cii); +void DoRepair(int pnum, int cii); +void RepairItem(ItemStruct *i, int lvl); +void DoRecharge(int pnum, int cii); +void RechargeItem(ItemStruct *i, int r); +void PrintItemOil(char IDidx); +void PrintItemPower(char plidx, const ItemStruct *x); +void DrawUTextBack(); +void PrintUString(int x, int y, int cjustflag, char *str, int col); +void DrawULine(int y); +void DrawUniqueInfo(); +void PrintItemMisc(ItemStruct *x); +void PrintItemDetails(ItemStruct *x); +void PrintItemDur(ItemStruct *x); +void UseItem(int p, int Mid, int spl); +BOOL StoreStatOk(ItemStruct *h); +BOOL SmithItemOk(int i); +int RndSmithItem(int lvl); +void BubbleSwapItem(ItemStruct *a, ItemStruct *b); +void SortSmith(); +void SpawnSmith(int lvl); +BOOL PremiumItemOk(int i); +int RndPremiumItem(int minlvl, int maxlvl); +void SpawnOnePremium(int i, int plvl); +void SpawnPremium(int lvl); +BOOL WitchItemOk(int i); +int RndWitchItem(int lvl); +void SortWitch(); +void WitchBookLevel(int ii); +void SpawnWitch(int lvl); +int RndBoyItem(int lvl); +void SpawnBoy(int lvl); +BOOL HealerItemOk(int i); +int RndHealerItem(int lvl); +void SortHealer(); +void SpawnHealer(int lvl); +void SpawnStoreGold(); +void RecreateSmithItem(int ii, int idx, int lvl, int iseed); +void RecreatePremiumItem(int ii, int idx, int plvl, int iseed); +void RecreateBoyItem(int ii, int idx, int lvl, int iseed); +void RecreateWitchItem(int ii, int idx, int lvl, int iseed); +void RecreateHealerItem(int ii, int idx, int lvl, int iseed); +void RecreateTownItem(int ii, int idx, WORD icreateinfo, int iseed, int ivalue); +void RecalcStoreStats(); +int ItemNoFlippy(); +void CreateSpellBook(int x, int y, int ispell, BOOL sendmsg, BOOL delta); +void CreateMagicArmor(int x, int y, int imisc, int icurs, BOOL sendmsg, BOOL delta); +void CreateMagicWeapon(int x, int y, int imisc, int icurs, BOOL sendmsg, BOOL delta); +BOOL GetItemRecord(int nSeed, WORD wCI, int nIndex); +void NextItemRecord(int i); +void SetItemRecord(int nSeed, WORD wCI, int nIndex); +void PutItemRecord(int nSeed, WORD wCI, int nIndex); + +/* data */ + +extern unsigned char ItemCAnimTbl[169]; +extern char *ItemDropStrs[35]; +extern unsigned char ItemAnimLs[35]; +extern int ItemDropSnds[35]; +extern int ItemInvSnds[35]; +extern int idoppely; // weak +extern int premiumlvladd[6]; + +#endif /* __ITEMS_H__ */ diff --git a/2020_03_31/Source/lighting.cpp b/2020_03_31/Source/lighting.cpp new file mode 100644 index 00000000..ec4d82b5 --- /dev/null +++ b/2020_03_31/Source/lighting.cpp @@ -0,0 +1,1281 @@ +#include "diablo.h" + +LightListStruct VisionList[MAXVISION]; +unsigned char lightactive[MAXLIGHTS]; +LightListStruct LightList[MAXLIGHTS]; +int numlights; +BYTE lightradius[16][128]; +int dovision; // weak +int numvision; +char lightmax; // weak +int dolighting; // weak +BYTE lightblock[8][8][16][16]; +int visionid; +BYTE *pLightTbl; +int lightflag; // weak + +char CrawlTable[2749] = +{ + 1, + 0, 0, + 4, + 0, 1, 0, -1, -1, 0, 1, 0, + 16, + 0, 2, 0, -2, -1, 2, 1, 2, + -1, -2, 1, -2, -1, 1, 1, 1, + -1, -1, 1, -1, -2, 1, 2, 1, + -2, -1, 2, -1, -2, 0, 2, 0, + 24, + 0, 3, 0, -3, -1, 3, 1, 3, + -1, -3, 1, -3, -2, 3, 2, 3, + -2, -3, 2, -3, -2, 2, 2, 2, + -2, -2, 2, -2, -3, 2, 3, 2, + -3, -2, 3, -2, -3, 1, 3, 1, + -3, -1, 3, -1, -3, 0, 3, 0, + 32, + 0, 4, 0, -4, -1, 4, 1, 4, + -1, -4, 1, -4, -2, 4, 2, 4, + -2, -4, 2, -4, -3, 4, 3, 4, + -3, -4, 3, -4, -3, 3, 3, 3, + -3, -3, 3, -3, -4, 3, 4, 3, + -4, -3, 4, -3, -4, 2, 4, 2, + -4, -2, 4, -2, -4, 1, 4, 1, + -4, -1, 4, -1, -4, 0, 4, 0, + 40, + 0, 5, 0, -5, -1, 5, 1, 5, + -1, -5, 1, -5, -2, 5, 2, 5, + -2, -5, 2, -5, -3, 5, 3, 5, + -3, -5, 3, -5, -4, 5, 4, 5, + -4, -5, 4, -5, -4, 4, 4, 4, + -4, -4, 4, -4, -5, 4, 5, 4, + -5, -4, 5, -4, -5, 3, 5, 3, + -5, -3, 5, -3, -5, 2, 5, 2, + -5, -2, 5, -2, -5, 1, 5, 1, + -5, -1, 5, -1, -5, 0, 5, 0, + 48, + 0, 6, 0, -6, -1, 6, 1, 6, + -1, -6, 1, -6, -2, 6, 2, 6, + -2, -6, 2, -6, -3, 6, 3, 6, + -3, -6, 3, -6, -4, 6, 4, 6, + -4, -6, 4, -6, -5, 6, 5, 6, + -5, -6, 5, -6, -5, 5, 5, 5, + -5, -5, 5, -5, -6, 5, 6, 5, + -6, -5, 6, -5, -6, 4, 6, 4, + -6, -4, 6, -4, -6, 3, 6, 3, + -6, -3, 6, -3, -6, 2, 6, 2, + -6, -2, 6, -2, -6, 1, 6, 1, + -6, -1, 6, -1, -6, 0, 6, 0, + 56, + 0, 7, 0, -7, -1, 7, 1, 7, + -1, -7, 1, -7, -2, 7, 2, 7, + -2, -7, 2, -7, -3, 7, 3, 7, + -3, -7, 3, -7, -4, 7, 4, 7, + -4, -7, 4, -7, -5, 7, 5, 7, + -5, -7, 5, -7, -6, 7, 6, 7, + -6, -7, 6, -7, -6, 6, 6, 6, + -6, -6, 6, -6, -7, 6, 7, 6, + -7, -6, 7, -6, -7, 5, 7, 5, + -7, -5, 7, -5, -7, 4, 7, 4, + -7, -4, 7, -4, -7, 3, 7, 3, + -7, -3, 7, -3, -7, 2, 7, 2, + -7, -2, 7, -2, -7, 1, 7, 1, + -7, -1, 7, -1, -7, 0, 7, 0, + 64, + 0, 8, 0, -8, -1, 8, 1, 8, + -1, -8, 1, -8, -2, 8, 2, 8, + -2, -8, 2, -8, -3, 8, 3, 8, + -3, -8, 3, -8, -4, 8, 4, 8, + -4, -8, 4, -8, -5, 8, 5, 8, + -5, -8, 5, -8, -6, 8, 6, 8, + -6, -8, 6, -8, -7, 8, 7, 8, + -7, -8, 7, -8, -7, 7, 7, 7, + -7, -7, 7, -7, -8, 7, 8, 7, + -8, -7, 8, -7, -8, 6, 8, 6, + -8, -6, 8, -6, -8, 5, 8, 5, + -8, -5, 8, -5, -8, 4, 8, 4, + -8, -4, 8, -4, -8, 3, 8, 3, + -8, -3, 8, -3, -8, 2, 8, 2, + -8, -2, 8, -2, -8, 1, 8, 1, + -8, -1, 8, -1, -8, 0, 8, 0, + 72, + 0, 9, 0, -9, -1, 9, 1, 9, + -1, -9, 1, -9, -2, 9, 2, 9, + -2, -9, 2, -9, -3, 9, 3, 9, + -3, -9, 3, -9, -4, 9, 4, 9, + -4, -9, 4, -9, -5, 9, 5, 9, + -5, -9, 5, -9, -6, 9, 6, 9, + -6, -9, 6, -9, -7, 9, 7, 9, + -7, -9, 7, -9, -8, 9, 8, 9, + -8, -9, 8, -9, -8, 8, 8, 8, + -8, -8, 8, -8, -9, 8, 9, 8, + -9, -8, 9, -8, -9, 7, 9, 7, + -9, -7, 9, -7, -9, 6, 9, 6, + -9, -6, 9, -6, -9, 5, 9, 5, + -9, -5, 9, -5, -9, 4, 9, 4, + -9, -4, 9, -4, -9, 3, 9, 3, + -9, -3, 9, -3, -9, 2, 9, 2, + -9, -2, 9, -2, -9, 1, 9, 1, + -9, -1, 9, -1, -9, 0, 9, 0, + 80, + 0, 10, 0, -10, -1, 10, 1, 10, + -1, -10, 1, -10, -2, 10, 2, 10, + -2, -10, 2, -10, -3, 10, 3, 10, + -3, -10, 3, -10, -4, 10, 4, 10, + -4, -10, 4, -10, -5, 10, 5, 10, + -5, -10, 5, -10, -6, 10, 6, 10, + -6, -10, 6, -10, -7, 10, 7, 10, + -7, -10, 7, -10, -8, 10, 8, 10, + -8, -10, 8, -10, -9, 10, 9, 10, + -9, -10, 9, -10, -9, 9, 9, 9, + -9, -9, 9, -9, -10, 9, 10, 9, + -10, -9, 10, -9, -10, 8, 10, 8, + -10, -8, 10, -8, -10, 7, 10, 7, + -10, -7, 10, -7, -10, 6, 10, 6, + -10, -6, 10, -6, -10, 5, 10, 5, + -10, -5, 10, -5, -10, 4, 10, 4, + -10, -4, 10, -4, -10, 3, 10, 3, + -10, -3, 10, -3, -10, 2, 10, 2, + -10, -2, 10, -2, -10, 1, 10, 1, + -10, -1, 10, -1, -10, 0, 10, 0, + 88, + 0, 11, 0, -11, -1, 11, 1, 11, + -1, -11, 1, -11, -2, 11, 2, 11, + -2, -11, 2, -11, -3, 11, 3, 11, + -3, -11, 3, -11, -4, 11, 4, 11, + -4, -11, 4, -11, -5, 11, 5, 11, + -5, -11, 5, -11, -6, 11, 6, 11, + -6, -11, 6, -11, -7, 11, 7, 11, + -7, -11, 7, -11, -8, 11, 8, 11, + -8, -11, 8, -11, -9, 11, 9, 11, + -9, -11, 9, -11, -10, 11, 10, 11, + -10, -11, 10, -11, -10, 10, 10, 10, + -10, -10, 10, -10, -11, 10, 11, 10, + -11, -10, 11, -10, -11, 9, 11, 9, + -11, -9, 11, -9, -11, 8, 11, 8, + -11, -8, 11, -8, -11, 7, 11, 7, + -11, -7, 11, -7, -11, 6, 11, 6, + -11, -6, 11, -6, -11, 5, 11, 5, + -11, -5, 11, -5, -11, 4, 11, 4, + -11, -4, 11, -4, -11, 3, 11, 3, + -11, -3, 11, -3, -11, 2, 11, 2, + -11, -2, 11, -2, -11, 1, 11, 1, + -11, -1, 11, -1, -11, 0, 11, 0, + 96, + 0, 12, 0, -12, -1, 12, 1, 12, + -1, -12, 1, -12, -2, 12, 2, 12, + -2, -12, 2, -12, -3, 12, 3, 12, + -3, -12, 3, -12, -4, 12, 4, 12, + -4, -12, 4, -12, -5, 12, 5, 12, + -5, -12, 5, -12, -6, 12, 6, 12, + -6, -12, 6, -12, -7, 12, 7, 12, + -7, -12, 7, -12, -8, 12, 8, 12, + -8, -12, 8, -12, -9, 12, 9, 12, + -9, -12, 9, -12, -10, 12, 10, 12, + -10, -12, 10, -12, -11, 12, 11, 12, + -11, -12, 11, -12, -11, 11, 11, 11, + -11, -11, 11, -11, -12, 11, 12, 11, + -12, -11, 12, -11, -12, 10, 12, 10, + -12, -10, 12, -10, -12, 9, 12, 9, + -12, -9, 12, -9, -12, 8, 12, 8, + -12, -8, 12, -8, -12, 7, 12, 7, + -12, -7, 12, -7, -12, 6, 12, 6, + -12, -6, 12, -6, -12, 5, 12, 5, + -12, -5, 12, -5, -12, 4, 12, 4, + -12, -4, 12, -4, -12, 3, 12, 3, + -12, -3, 12, -3, -12, 2, 12, 2, + -12, -2, 12, -2, -12, 1, 12, 1, + -12, -1, 12, -1, -12, 0, 12, 0, + 104, + 0, 13, 0, -13, -1, 13, 1, 13, + -1, -13, 1, -13, -2, 13, 2, 13, + -2, -13, 2, -13, -3, 13, 3, 13, + -3, -13, 3, -13, -4, 13, 4, 13, + -4, -13, 4, -13, -5, 13, 5, 13, + -5, -13, 5, -13, -6, 13, 6, 13, + -6, -13, 6, -13, -7, 13, 7, 13, + -7, -13, 7, -13, -8, 13, 8, 13, + -8, -13, 8, -13, -9, 13, 9, 13, + -9, -13, 9, -13, -10, 13, 10, 13, + -10, -13, 10, -13, -11, 13, 11, 13, + -11, -13, 11, -13, -12, 13, 12, 13, + -12, -13, 12, -13, -12, 12, 12, 12, + -12, -12, 12, -12, -13, 12, 13, 12, + -13, -12, 13, -12, -13, 11, 13, 11, + -13, -11, 13, -11, -13, 10, 13, 10, + -13, -10, 13, -10, -13, 9, 13, 9, + -13, -9, 13, -9, -13, 8, 13, 8, + -13, -8, 13, -8, -13, 7, 13, 7, + -13, -7, 13, -7, -13, 6, 13, 6, + -13, -6, 13, -6, -13, 5, 13, 5, + -13, -5, 13, -5, -13, 4, 13, 4, + -13, -4, 13, -4, -13, 3, 13, 3, + -13, -3, 13, -3, -13, 2, 13, 2, + -13, -2, 13, -2, -13, 1, 13, 1, + -13, -1, 13, -1, -13, 0, 13, 0, + 112, + 0, 14, 0, -14, -1, 14, 1, 14, + -1, -14, 1, -14, -2, 14, 2, 14, + -2, -14, 2, -14, -3, 14, 3, 14, + -3, -14, 3, -14, -4, 14, 4, 14, + -4, -14, 4, -14, -5, 14, 5, 14, + -5, -14, 5, -14, -6, 14, 6, 14, + -6, -14, 6, -14, -7, 14, 7, 14, + -7, -14, 7, -14, -8, 14, 8, 14, + -8, -14, 8, -14, -9, 14, 9, 14, + -9, -14, 9, -14, -10, 14, 10, 14, + -10, -14, 10, -14, -11, 14, 11, 14, + -11, -14, 11, -14, -12, 14, 12, 14, + -12, -14, 12, -14, -13, 14, 13, 14, + -13, -14, 13, -14, -13, 13, 13, 13, + -13, -13, 13, -13, -14, 13, 14, 13, + -14, -13, 14, -13, -14, 12, 14, 12, + -14, -12, 14, -12, -14, 11, 14, 11, + -14, -11, 14, -11, -14, 10, 14, 10, + -14, -10, 14, -10, -14, 9, 14, 9, + -14, -9, 14, -9, -14, 8, 14, 8, + -14, -8, 14, -8, -14, 7, 14, 7, + -14, -7, 14, -7, -14, 6, 14, 6, + -14, -6, 14, -6, -14, 5, 14, 5, + -14, -5, 14, -5, -14, 4, 14, 4, + -14, -4, 14, -4, -14, 3, 14, 3, + -14, -3, 14, -3, -14, 2, 14, 2, + -14, -2, 14, -2, -14, 1, 14, 1, + -14, -1, 14, -1, -14, 0, 14, 0, + 120, + 0, 15, 0, -15, -1, 15, 1, 15, + -1, -15, 1, -15, -2, 15, 2, 15, + -2, -15, 2, -15, -3, 15, 3, 15, + -3, -15, 3, -15, -4, 15, 4, 15, + -4, -15, 4, -15, -5, 15, 5, 15, + -5, -15, 5, -15, -6, 15, 6, 15, + -6, -15, 6, -15, -7, 15, 7, 15, + -7, -15, 7, -15, -8, 15, 8, 15, + -8, -15, 8, -15, -9, 15, 9, 15, + -9, -15, 9, -15, -10, 15, 10, 15, + -10, -15, 10, -15, -11, 15, 11, 15, + -11, -15, 11, -15, -12, 15, 12, 15, + -12, -15, 12, -15, -13, 15, 13, 15, + -13, -15, 13, -15, -14, 15, 14, 15, + -14, -15, 14, -15, -14, 14, 14, 14, + -14, -14, 14, -14, -15, 14, 15, 14, + -15, -14, 15, -14, -15, 13, 15, 13, + -15, -13, 15, -13, -15, 12, 15, 12, + -15, -12, 15, -12, -15, 11, 15, 11, + -15, -11, 15, -11, -15, 10, 15, 10, + -15, -10, 15, -10, -15, 9, 15, 9, + -15, -9, 15, -9, -15, 8, 15, 8, + -15, -8, 15, -8, -15, 7, 15, 7, + -15, -7, 15, -7, -15, 6, 15, 6, + -15, -6, 15, -6, -15, 5, 15, 5, + -15, -5, 15, -5, -15, 4, 15, 4, + -15, -4, 15, -4, -15, 3, 15, 3, + -15, -3, 15, -3, -15, 2, 15, 2, + -15, -2, 15, -2, -15, 1, 15, 1, + -15, -1, 15, -1, -15, 0, 15, 0, + (char)128, + 0, 16, 0, -16, -1, 16, 1, 16, + -1, -16, 1, -16, -2, 16, 2, 16, + -2, -16, 2, -16, -3, 16, 3, 16, + -3, -16, 3, -16, -4, 16, 4, 16, + -4, -16, 4, -16, -5, 16, 5, 16, + -5, -16, 5, -16, -6, 16, 6, 16, + -6, -16, 6, -16, -7, 16, 7, 16, + -7, -16, 7, -16, -8, 16, 8, 16, + -8, -16, 8, -16, -9, 16, 9, 16, + -9, -16, 9, -16, -10, 16, 10, 16, + -10, -16, 10, -16, -11, 16, 11, 16, + -11, -16, 11, -16, -12, 16, 12, 16, + -12, -16, 12, -16, -13, 16, 13, 16, + -13, -16, 13, -16, -14, 16, 14, 16, + -14, -16, 14, -16, -15, 16, 15, 16, + -15, -16, 15, -16, -15, 15, 15, 15, + -15, -15, 15, -15, -16, 15, 16, 15, + -16, -15, 16, -15, -16, 14, 16, 14, + -16, -14, 16, -14, -16, 13, 16, 13, + -16, -13, 16, -13, -16, 12, 16, 12, + -16, -12, 16, -12, -16, 11, 16, 11, + -16, -11, 16, -11, -16, 10, 16, 10, + -16, -10, 16, -10, -16, 9, 16, 9, + -16, -9, 16, -9, -16, 8, 16, 8, + -16, -8, 16, -8, -16, 7, 16, 7, + -16, -7, 16, -7, -16, 6, 16, 6, + -16, -6, 16, -6, -16, 5, 16, 5, + -16, -5, 16, -5, -16, 4, 16, 4, + -16, -4, 16, -4, -16, 3, 16, 3, + -16, -3, 16, -3, -16, 2, 16, 2, + -16, -2, 16, -2, -16, 1, 16, 1, + -16, -1, 16, -1, -16, 0, 16, 0, + (char)136, + 0, 17, 0, -17, -1, 17, 1, 17, + -1, -17, 1, -17, -2, 17, 2, 17, + -2, -17, 2, -17, -3, 17, 3, 17, + -3, -17, 3, -17, -4, 17, 4, 17, + -4, -17, 4, -17, -5, 17, 5, 17, + -5, -17, 5, -17, -6, 17, 6, 17, + -6, -17, 6, -17, -7, 17, 7, 17, + -7, -17, 7, -17, -8, 17, 8, 17, + -8, -17, 8, -17, -9, 17, 9, 17, + -9, -17, 9, -17, -10, 17, 10, 17, + -10, -17, 10, -17, -11, 17, 11, 17, + -11, -17, 11, -17, -12, 17, 12, 17, + -12, -17, 12, -17, -13, 17, 13, 17, + -13, -17, 13, -17, -14, 17, 14, 17, + -14, -17, 14, -17, -15, 17, 15, 17, + -15, -17, 15, -17, -16, 17, 16, 17, + -16, -17, 16, -17, -16, 16, 16, 16, + -16, -16, 16, -16, -17, 16, 17, 16, + -17, -16, 17, -16, -17, 15, 17, 15, + -17, -15, 17, -15, -17, 14, 17, 14, + -17, -14, 17, -14, -17, 13, 17, 13, + -17, -13, 17, -13, -17, 12, 17, 12, + -17, -12, 17, -12, -17, 11, 17, 11, + -17, -11, 17, -11, -17, 10, 17, 10, + -17, -10, 17, -10, -17, 9, 17, 9, + -17, -9, 17, -9, -17, 8, 17, 8, + -17, -8, 17, -8, -17, 7, 17, 7, + -17, -7, 17, -7, -17, 6, 17, 6, + -17, -6, 17, -6, -17, 5, 17, 5, + -17, -5, 17, -5, -17, 4, 17, 4, + -17, -4, 17, -4, -17, 3, 17, 3, + -17, -3, 17, -3, -17, 2, 17, 2, + -17, -2, 17, -2, -17, 1, 17, 1, + -17, -1, 17, -1, -17, 0, 17, 0, + (char)144, + 0, 18, 0, -18, -1, 18, 1, 18, + -1, -18, 1, -18, -2, 18, 2, 18, + -2, -18, 2, -18, -3, 18, 3, 18, + -3, -18, 3, -18, -4, 18, 4, 18, + -4, -18, 4, -18, -5, 18, 5, 18, + -5, -18, 5, -18, -6, 18, 6, 18, + -6, -18, 6, -18, -7, 18, 7, 18, + -7, -18, 7, -18, -8, 18, 8, 18, + -8, -18, 8, -18, -9, 18, 9, 18, + -9, -18, 9, -18, -10, 18, 10, 18, + -10, -18, 10, -18, -11, 18, 11, 18, + -11, -18, 11, -18, -12, 18, 12, 18, + -12, -18, 12, -18, -13, 18, 13, 18, + -13, -18, 13, -18, -14, 18, 14, 18, + -14, -18, 14, -18, -15, 18, 15, 18, + -15, -18, 15, -18, -16, 18, 16, 18, + -16, -18, 16, -18, -17, 18, 17, 18, + -17, -18, 17, -18, -17, 17, 17, 17, + -17, -17, 17, -17, -18, 17, 18, 17, + -18, -17, 18, -17, -18, 16, 18, 16, + -18, -16, 18, -16, -18, 15, 18, 15, + -18, -15, 18, -15, -18, 14, 18, 14, + -18, -14, 18, -14, -18, 13, 18, 13, + -18, -13, 18, -13, -18, 12, 18, 12, + -18, -12, 18, -12, -18, 11, 18, 11, + -18, -11, 18, -11, -18, 10, 18, 10, + -18, -10, 18, -10, -18, 9, 18, 9, + -18, -9, 18, -9, -18, 8, 18, 8, + -18, -8, 18, -8, -18, 7, 18, 7, + -18, -7, 18, -7, -18, 6, 18, 6, + -18, -6, 18, -6, -18, 5, 18, 5, + -18, -5, 18, -5, -18, 4, 18, 4, + -18, -4, 18, -4, -18, 3, 18, 3, + -18, -3, 18, -3, -18, 2, 18, 2, + -18, -2, 18, -2, -18, 1, 18, 1, + -18, -1, 18, -1, -18, 0, 18, 0 +}; + +char *pCrawlTable[19] = /* figure out what this is for */ +{ + CrawlTable, + CrawlTable+3, + CrawlTable+12, + CrawlTable+45, + CrawlTable+94, + CrawlTable+159, + CrawlTable+240, + CrawlTable+337, + CrawlTable+450, + CrawlTable+579, + CrawlTable+724, + CrawlTable+885, + CrawlTable+1062, + CrawlTable+1255, + CrawlTable+1464, + CrawlTable+1689, + CrawlTable+1930, + CrawlTable+2187, + CrawlTable+2460 +}; +unsigned char vCrawlTable[23][30] = +{ + { 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 8, 0, 9, 0, 10, 0, 11, 0, 12, 0, 13, 0, 14, 0, 15, 0 }, + { 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 8, 1, 9, 1, 10, 1, 11, 1, 12, 1, 13, 1, 14, 1, 15, 1 }, + { 1, 0, 2, 0, 3, 0, 4, 1, 5, 1, 6, 1, 7, 1, 8, 1, 9, 1, 10, 1, 11, 1, 12, 2, 13, 2, 14, 2, 15, 2 }, + { 1, 0, 2, 0, 3, 1, 4, 1, 5, 1, 6, 1, 7, 1, 8, 2, 9, 2, 10, 2, 11, 2, 12, 2, 13, 3, 14, 3, 15, 3 }, + { 1, 0, 2, 1, 3, 1, 4, 1, 5, 1, 6, 2, 7, 2, 8, 2, 9, 3, 10, 3, 11, 3, 12, 3, 13, 4, 14, 4, 0, 0 }, + { 1, 0, 2, 1, 3, 1, 4, 1, 5, 2, 6, 2, 7, 3, 8, 3, 9, 3, 10, 4, 11, 4, 12, 4, 13, 5, 14, 5, 0, 0 }, + { 1, 0, 2, 1, 3, 1, 4, 2, 5, 2, 6, 3, 7, 3, 8, 3, 9, 4, 10, 4, 11, 5, 12, 5, 13, 6, 14, 6, 0, 0 }, + { 1, 1, 2, 1, 3, 2, 4, 2, 5, 3, 6, 3, 7, 4, 8, 4, 9, 5, 10, 5, 11, 6, 12, 6, 13, 7, 0, 0, 0, 0 }, + { 1, 1, 2, 1, 3, 2, 4, 2, 5, 3, 6, 4, 7, 4, 8, 5, 9, 6, 10, 6, 11, 7, 12, 7, 12, 8, 13, 8, 0, 0 }, + { 1, 1, 2, 2, 3, 2, 4, 3, 5, 4, 6, 5, 7, 5, 8, 6, 9, 7, 10, 7, 10, 8, 11, 8, 12, 9, 0, 0, 0, 0 }, + { 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 5, 7, 6, 8, 7, 9, 8, 10, 9, 11, 9, 11, 10, 0, 0, 0, 0, 0, 0 }, + { 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 9, 11, 10, 11, 0, 0, 0, 0, 0, 0 }, + { 1, 1, 2, 2, 2, 3, 3, 4, 4, 5, 5, 6, 5, 7, 6, 8, 7, 9, 7, 10, 8, 10, 8, 11, 9, 12, 0, 0, 0, 0 }, + { 1, 1, 1, 2, 2, 3, 2, 4, 3, 5, 4, 6, 4, 7, 5, 8, 6, 9, 6, 10, 7, 11, 7, 12, 8, 12, 8, 13, 0, 0 }, + { 1, 1, 1, 2, 2, 3, 2, 4, 3, 5, 3, 6, 4, 7, 4, 8, 5, 9, 5, 10, 6, 11, 6, 12, 7, 13, 0, 0, 0, 0 }, + { 0, 1, 1, 2, 1, 3, 2, 4, 2, 5, 3, 6, 3, 7, 3, 8, 4, 9, 4, 10, 5, 11, 5, 12, 6, 13, 6, 14, 0, 0 }, + { 0, 1, 1, 2, 1, 3, 1, 4, 2, 5, 2, 6, 3, 7, 3, 8, 3, 9, 4, 10, 4, 11, 4, 12, 5, 13, 5, 14, 0, 0 }, + { 0, 1, 1, 2, 1, 3, 1, 4, 1, 5, 2, 6, 2, 7, 2, 8, 3, 9, 3, 10, 3, 11, 3, 12, 4, 13, 4, 14, 0, 0 }, + { 0, 1, 0, 2, 1, 3, 1, 4, 1, 5, 1, 6, 1, 7, 2, 8, 2, 9, 2, 10, 2, 11, 2, 12, 3, 13, 3, 14, 3, 15 }, + { 0, 1, 0, 2, 0, 3, 1, 4, 1, 5, 1, 6, 1, 7, 1, 8, 1, 9, 1, 10, 1, 11, 2, 12, 2, 13, 2, 14, 2, 15 }, + { 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 1, 8, 1, 9, 1, 10, 1, 11, 1, 12, 1, 13, 1, 14, 1, 15 }, + { 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 8, 0, 9, 0, 10, 0, 11, 0, 12, 0, 13, 0, 14, 0, 15 } +}; +unsigned char byte_49463C[18][18] = /* unused */ +{ + { 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, + { 0, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, + { 0, 1, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, + { 0, 0, 1, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, + { 0, 0, 1, 1, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, + { 0, 0, 1, 1, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, + { 0, 0, 0, 1, 1, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, + { 0, 0, 0, 1, 1, 1, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, + { 0, 0, 0, 0, 1, 1, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, + { 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3 }, + { 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3 }, + { 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3 }, + { 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3 }, + { 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3 }, + { 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3 }, + { 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3 }, + { 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2 } +}; + +unsigned char RadiusAdj[23] = { 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 4, 3, 2, 2, 2, 1, 1, 1, 0, 0, 0, 0 }; + +void RotateRadius(int *x, int *y, int *dx, int *dy, int *lx, int *ly, int *bx, int *by) +{ + int swap; + + *bx = 0; + *by = 0; + + swap = *dx; + *dx = 7 - *dy; + *dy = swap; + swap = *lx; + *lx = 7 - *ly; + *ly = swap; + + *x = *dx - *lx; + *y = *dy - *ly; + + if(*x < 0) { + *x += 8; + *bx = 1; + } + if(*y < 0) { + *y += 8; + *by = 1; + } +} + +void DoLighting(int nXPos, int nYPos, int nRadius, int Lnum) +{ + int x, y, v, xoff, yoff, mult, radius_block; + int min_x, max_x, min_y, max_y; + int dist_x, dist_y, light_x, light_y, block_x, block_y, temp_x, temp_y; + + xoff = 0; + yoff = 0; + light_x = 0; + light_y = 0; + block_x = 0; + block_y = 0; + + if(Lnum >= 0) { + xoff = LightList[Lnum]._xoff; + yoff = LightList[Lnum]._yoff; + if(xoff < 0) { + xoff += 8; + nXPos--; + } + if(yoff < 0) { + yoff += 8; + nYPos--; + } + } + + dist_x = xoff; + dist_y = yoff; + + if(nXPos - 15 < 0) { + min_x = nXPos + 1; + } else { + min_x = 15; + } + if(nXPos + 15 > MAXDUNX) { + max_x = MAXDUNX - nXPos; + } else { + max_x = 15; + } + if(nYPos - 15 < 0) { + min_y = nYPos + 1; + } else { + min_y = 15; + } + if(nYPos + 15 > MAXDUNY) { + max_y = MAXDUNY - nYPos; + } else { + max_y = 15; + } + + if(nXPos >= 0 && nXPos < MAXDUNX && nYPos >= 0 && nYPos < MAXDUNY) { + dLight[nXPos][nYPos] = 0; + } + + mult = xoff + 8 * yoff; + for(y = 0; y < min_y; y++) { + for(x = 1; x < max_x; x++) { + radius_block = lightblock[0][mult][y][x]; + if(radius_block < 128) { + temp_x = nXPos + x; + temp_y = nYPos + y; + v = lightradius[nRadius][radius_block]; + if(temp_x >= 0 && temp_x < MAXDUNX && temp_y >= 0 && temp_y < MAXDUNY) { + if(v < dLight[temp_x][temp_y]) { + dLight[temp_x][temp_y] = v; + } + } + } + } + } + RotateRadius(&xoff, &yoff, &dist_x, &dist_y, &light_x, &light_y, &block_x, &block_y); + mult = xoff + 8 * yoff; + for(y = 0; y < max_y; y++) { + for(x = 1; x < max_x; x++) { + radius_block = lightblock[0][mult][y + block_y][x + block_x]; + if(radius_block < 128) { + temp_x = nXPos + y; + temp_y = nYPos - x; + v = lightradius[nRadius][radius_block]; + if(temp_x >= 0 && temp_x < MAXDUNX && temp_y >= 0 && temp_y < MAXDUNY) { + if(v < dLight[temp_x][temp_y]) { + dLight[temp_x][temp_y] = v; + } + } + } + } + } + RotateRadius(&xoff, &yoff, &dist_x, &dist_y, &light_x, &light_y, &block_x, &block_y); + mult = xoff + 8 * yoff; + for(y = 0; y < max_y; y++) { + for(x = 1; x < min_x; x++) { + radius_block = lightblock[0][mult][y + block_y][x + block_x]; + if(radius_block < 128) { + temp_x = nXPos - x; + temp_y = nYPos - y; + v = lightradius[nRadius][radius_block]; + if(temp_x >= 0 && temp_x < MAXDUNX && temp_y >= 0 && temp_y < MAXDUNY) { + if(v < dLight[temp_x][temp_y]) { + dLight[temp_x][temp_y] = v; + } + } + } + } + } + RotateRadius(&xoff, &yoff, &dist_x, &dist_y, &light_x, &light_y, &block_x, &block_y); + mult = xoff + 8 * yoff; + for(y = 0; y < min_y; y++) { + for(x = 1; x < min_x; x++) { + radius_block = lightblock[0][mult][y + block_y][x + block_x]; + if(radius_block < 128) { + temp_x = nXPos - y; + temp_y = nYPos + x; + v = lightradius[nRadius][radius_block]; + if(temp_x >= 0 && temp_x < MAXDUNX && temp_y >= 0 && temp_y < MAXDUNY) { + if(v < dLight[temp_x][temp_y]) { + dLight[temp_x][temp_y] = v; + } + } + } + } + } +} + +void DoUnLight(int nXPos, int nYPos, int nRadius) +{ + int x, y, min_x, min_y, max_x, max_y; + + nRadius++; + min_y = nYPos - nRadius; + max_y = nYPos + nRadius; + min_x = nXPos - nRadius; + max_x = nXPos + nRadius; + + if(min_y < 0) { + min_y = 0; + } + if(max_y > MAXDUNY) { + max_y = MAXDUNY; + } + if(min_x < 0) { + min_x = 0; + } + if(max_x > MAXDUNX) { + max_x = MAXDUNX; + } + + for(y = min_y; y < max_y; y++) { + for(x = min_x; x < max_x; x++) { + if(x >= 0 && x < MAXDUNX && y >= 0 && y < MAXDUNY) { + dLight[x][y] = dPreLight[x][y]; + } + } + } +} + +void DoUnVision(int nXPos, int nYPos, int nRadius) +{ + int i, j, x1, y1, x2, y2; + + nRadius++; + y1 = nYPos - nRadius; + y2 = nYPos + nRadius; + x1 = nXPos - nRadius; + x2 = nXPos + nRadius; + + if(y1 < 0) { + y1 = 0; + } + if(y2 > MAXDUNY) { + y2 = MAXDUNY; + } + if(x1 < 0) { + x1 = 0; + } + if(x2 > MAXDUNX) { + x2 = MAXDUNX; + } + + for(i = x1; i < x2; i++) { + for(j = y1; j < y2; j++) { + dFlags[i][j] &= ~0x42; + } + } +} + +void DoVision(int nXPos, int nYPos, int nRadius, BOOL doautomap, BOOL visible) +{ + int nCrawlX, nCrawlY, nLineLen, nBlockerFlag, nTrans; + int j, k, v, x1adj, x2adj, y1adj, y2adj; + + if(nXPos >= 0 && nXPos <= MAXDUNX && nYPos >= 0 && nYPos <= MAXDUNY) { + if(doautomap) { + if(dFlags[nXPos][nYPos] >= 0) { + SetAutomapView(nXPos, nXPos); + } + dFlags[nXPos][nYPos] |= 0x80; + } + if(visible) { + dFlags[nXPos][nYPos] |= 0x40; + } + dFlags[nXPos][nYPos] |= 2; + } + + for(v = 0; v < 4; v++) { + for(j = 0; j < 23; j++) { + nBlockerFlag = FALSE; + nLineLen = 2 * (nRadius - RadiusAdj[j]); + for(k = 0; k < nLineLen && !nBlockerFlag; k += 2) { + x1adj = 0; + x2adj = 0; + y1adj = 0; + y2adj = 0; + switch(v) { + case 0: + nCrawlX = nXPos + vCrawlTable[j][k]; + nCrawlY = nYPos + vCrawlTable[j][k + 1]; + if(vCrawlTable[j][k] > 0 && vCrawlTable[j][k + 1] > 0) { + x1adj = -1; + y2adj = -1; + } + break; + case 1: + nCrawlX = nXPos - vCrawlTable[j][k]; + nCrawlY = nYPos - vCrawlTable[j][k + 1]; + if(vCrawlTable[j][k] > 0 && vCrawlTable[j][k + 1] > 0) { + y1adj = 1; + x2adj = 1; + } + break; + case 2: + nCrawlX = nXPos + vCrawlTable[j][k]; + nCrawlY = nYPos - vCrawlTable[j][k + 1]; + if(vCrawlTable[j][k] > 0 && vCrawlTable[j][k + 1] > 0) { + x1adj = -1; + y2adj = 1; + } + break; + case 3: + nCrawlX = nXPos - vCrawlTable[j][k]; + nCrawlY = nYPos + vCrawlTable[j][k + 1]; + if(vCrawlTable[j][k] > 0 && vCrawlTable[j][k + 1] > 0) { + y1adj = -1; + x2adj = 1; + } + break; + } + if(nCrawlX >= 0 && nCrawlX <= MAXDUNX && nCrawlY >= 0 && nCrawlY <= MAXDUNY) { + nBlockerFlag = (unsigned char)nBlockTable[dPiece[nCrawlX][nCrawlY]]; + if(!nBlockTable[dPiece[x1adj + nCrawlX][y1adj + nCrawlY]] + || !nBlockTable[dPiece[x2adj + nCrawlX][y2adj + nCrawlY]]) { + if(doautomap) { + if(dFlags[nCrawlX][nCrawlY] >= 0) { + SetAutomapView(nCrawlX, nCrawlY); + } + dFlags[nCrawlX][nCrawlY] |= 0x80; + } + if(visible) { + dFlags[nCrawlX][nCrawlY] |= 0x40; + } + dFlags[nCrawlX][nCrawlY] |= 2; + if(!nBlockerFlag) { + nTrans = dTransVal[nCrawlX][nCrawlY]; + if(nTrans != 0) { + TransList[nTrans] = 1; + } + } + } + } + } + } + } +} + +void FreeLightTable() +{ + MemFreeDbg(pLightTbl); +} + +void InitLightTable() +{ + /// ASSERT: assert(! pLightTbl); + pLightTbl = DiabloAllocPtr(LIGHTSIZE); +} + +void MakeLightTable() +{ + int i, j, k, l, lights, shade, l1, l2, cnt, rem, div; + double fs, fa; + BYTE col, max; + BYTE *tbl, *trn; + BYTE blood[16]; + + tbl = pLightTbl; + shade = 0; + + if(light4flag) { + lights = 3; + } else { + lights = 15; + } + + for(i = 0; i < lights; i++) { + *tbl++ = 0; + for(j = 0; j < 8; j++) { + col = 16 * j + shade; + max = 16 * j + 15; + for(k = 0; k < 16; k++) { + if(k != 0 || j != 0) { + *tbl++ = col; + } + if(col < max) { + col++; + } else { + max = 0; + col = 0; + } + } + } + for(j = 16; j < 20; j++) { + col = 8 * j + (shade >> 1); + max = 8 * j + 7; + for(k = 0; k < 8; k++) { + *tbl++ = col; + if(col < max) { + col++; + } else { + max = 0; + col = 0; + } + } + } + for(j = 10; j < 16; j++) { + col = 16 * j + shade; + max = 16 * j + 15; + for(k = 0; k < 16; k++) { + *tbl++ = col; + if(col < max) { + col++; + } else { + max = 0; + col = 0; + } + if(col == 255) { + max = 0; + col = 0; + } + } + } + if(light4flag) { + shade += 5; + } else { + shade++; + } + } + + for(i = 0; i < 256; i++) { + *tbl++ = 0; + } + + if(leveltype == DTYPE_HELL) { + tbl = pLightTbl; + for(i = 0; i < lights; i++) { + l1 = lights - i; + l2 = l1; + div = lights / l1; + rem = lights % l1; + cnt = 0; + blood[0] = 0; + col = 1; + for(j = 1; j < 16; j++) { + blood[j] = col; + l2 += rem; + if(l2 > l1 && j < 15) { + j++; + blood[j] = col; + l2 -= l1; + } + cnt++; + if(cnt == div) { + col++; + cnt = 0; + } + } + *tbl++ = 0; + for(j = 1; j <= 15; j++) { + *tbl++ = blood[j]; + } + for(j = 15; j > 0; j--) { + *tbl++ = blood[j]; + } + *tbl++ = 1; + tbl += 224; + } + *tbl++ = 0; + for(j = 0; j < 31; j++) { + *tbl++ = 1; + } + tbl += 224; + } + + trn = DiabLoad("PlrGFX\\Infra.TRN", NULL, 'LGTt'); + for(i = 0; i < 256; i++) { + *tbl++ = trn[i]; + } + mem_free_dbg(trn); + + trn = DiabLoad("PlrGFX\\Stone.TRN", NULL, 'LGTt'); + for(i = 0; i < 256; i++) { + *tbl++ = trn[i]; + } + mem_free_dbg(trn); + + for(i = 0; i < 8; i++) { + for(col = 226; col < 239; col++) { + if(i != 0 || col != 226) { + *tbl++ = col; + } else { + *tbl++ = 0; + } + } + *tbl++ = 0; + *tbl++ = 0; + *tbl++ = 0; + } + for(i = 0; i < 4; i++) { + col = 224; + for(j = 224; j < 239; j += 2) { + *tbl++ = col; + col += 2; + } + } + for(i = 0; i < 6; i++) { + for(col = 224; col < 239; col++) { + *tbl++ = col; + } + *tbl++ = 0; + } + + for(k = 0; k < 16; k++) { + for(l = 0; l < 128; l++) { + if(l > (k + 1) * 8) { + lightradius[k][l] = 15; + } else { + lightradius[k][l] = l * 15.0 / ((k + 1) * 8.0) + 0.5; + } + } + } + + for(i = 0; i < 8; i++) { + for(j = 0; j < 8; j++) { + for(k = 0; k < 16; k++) { + for(l = 0; l < 16; l++) { + fs = (BYTE)sqrt((8 * l - j) * (8 * l - j) + (8 * k - i) * (8 * k - i)); + if(fs < 0.0) { + fa = -0.5; + } else { + fa = 0.5; + } + lightblock[i][j][k][l] = fs + fa; + } + } + } + } +} + +#ifdef _DEBUG +void ToggleLighting_2() +{ + int i; + + if(lightflag) { + memset(dLight, 0, sizeof(dLight)); + } else { + memset(dLight, lightmax, sizeof(dLight)); + for(i = 0; i < MAX_PLRS; i++) { + if(plr[i].plractive && plr[i].plrlevel == currlevel) { + DoLighting(plr[i].WorldX, plr[i].WorldY, plr[i]._pLightRad, -1); + } + } + } +} + +void ToggleLighting() +{ + int i; + + lightflag ^= TRUE; + + if(lightflag) { + memset(dLight, 0, sizeof(dLight)); + } else { + memcpy(dLight, dPreLight, sizeof(dLight)); + for(i = 0; i < MAX_PLRS; i++) { + if(plr[i].plractive && plr[i].plrlevel == currlevel) { + DoLighting(plr[i].WorldX, plr[i].WorldY, plr[i]._pLightRad, -1); + } + } + } +} +#endif + +void InitLightMax() +{ + if(light4flag) { + lightmax = 3; + } else { + lightmax = 15; + } +} + +void InitLighting() +{ + int i; + + numlights = 0; + dolighting = 0; + lightflag = 0; + + for(i = 0; i < MAXLIGHTS; i++) { + lightactive[i] = i; + } +} + +int AddLight(int x, int y, int r) +{ + int lid; + + if(lightflag) { + return -1; + } + + lid = -1; + + if(numlights < MAXLIGHTS) { + lid = lightactive[numlights++]; + LightList[lid]._lx = x; + LightList[lid]._ly = y; + LightList[lid]._lradius = r; + LightList[lid]._xoff = 0; + LightList[lid]._yoff = 0; + LightList[lid]._ldel = 0; + LightList[lid]._lunflag = 0; + dolighting = 1; + } + + return lid; +} + +void AddUnLight(int i) +{ + if(lightflag || i == -1) { + return; + } + + LightList[i]._ldel = 1; + dolighting = 1; +} + +void ChangeLightRadius(int i, int r) +{ + if(lightflag || i == -1) { + return; + } + + LightList[i]._lunflag = 1; + LightList[i]._lunx = LightList[i]._lx; + LightList[i]._luny = LightList[i]._ly; + LightList[i]._lunr = LightList[i]._lradius; + LightList[i]._lradius = r; + dolighting = 1; +} + +void ChangeLightXY(int i, int x, int y) +{ + if(lightflag || i == -1) { + return; + } + + LightList[i]._lunflag = 1; + LightList[i]._lunx = LightList[i]._lx; + LightList[i]._luny = LightList[i]._ly; + LightList[i]._lunr = LightList[i]._lradius; + LightList[i]._lx = x; + LightList[i]._ly = y; + dolighting = 1; +} + +void ChangeLightOff(int i, int x, int y) +{ + if(lightflag || i == -1) { + return; + } + + LightList[i]._lunflag = 1; + LightList[i]._lunx = LightList[i]._lx; + LightList[i]._luny = LightList[i]._ly; + LightList[i]._lunr = LightList[i]._lradius; + LightList[i]._xoff = x; + LightList[i]._yoff = y; + dolighting = 1; +} + +void ChangeLight(int i, int x, int y, int r) +{ + if(lightflag || i == -1) { + return; + } + + LightList[i]._lunflag = 1; + LightList[i]._lunx = LightList[i]._lx; + LightList[i]._luny = LightList[i]._ly; + LightList[i]._lunr = LightList[i]._lradius; + LightList[i]._lx = x; + LightList[i]._ly = y; + LightList[i]._lradius = r; + dolighting = 1; +} + +void ProcessLightList() +{ + int i, j; + unsigned char temp; + + if(lightflag) { + return; + } + + if(dolighting) { + for(i = 0; i < numlights; i++) { + j = lightactive[i]; + if(LightList[j]._ldel) { + DoUnLight(LightList[j]._lx, LightList[j]._ly, LightList[j]._lradius); + } + if(LightList[j]._lunflag) { + DoUnLight(LightList[j]._lunx, LightList[j]._luny, LightList[j]._lunr); + LightList[j]._lunflag = 0; + } + } + for(i = 0; i < numlights; i++) { + j = lightactive[i]; + if(!LightList[j]._ldel) { + DoLighting(LightList[j]._lx, LightList[j]._ly, LightList[j]._lradius, j); + } + } + i = 0; + while(i < numlights) { + if(LightList[lightactive[i]]._ldel) { + numlights--; + temp = lightactive[numlights]; + lightactive[numlights] = lightactive[i]; + lightactive[i] = temp; + } else { + i++; + } + } + } + + dolighting = 0; +} + +void SavePreLighting() +{ + memcpy(dPreLight, dLight, sizeof(dPreLight)); +} + +void InitVision() +{ + int i; + + numvision = 0; + dovision = 0; + visionid = 1; + + for(i = 0; i < TransVal; i++) { + TransList[i] = 0; + } +} + +int AddVision(int x, int y, int r, BOOL mine) +{ + int vid; /// BUGFIX: should be initialized with '-1' + + if(numvision < MAXVISION) { + VisionList[numvision]._lx = x; + VisionList[numvision]._ly = y; + VisionList[numvision]._lradius = r; + vid = visionid++; + VisionList[numvision]._lid = vid; + VisionList[numvision]._ldel = 0; + VisionList[numvision]._lunflag = 0; + VisionList[numvision]._lflags = mine != 0; + numvision++; + dovision = 1; + } + + return vid; +} + +void ChangeVisionRadius(int id, int r) +{ + int i; + + for(i = 0; i < numvision; i++) { + if(VisionList[i]._lid == id) { + VisionList[i]._lunflag = 1; + VisionList[i]._lunx = VisionList[i]._lx; + VisionList[i]._luny = VisionList[i]._ly; + VisionList[i]._lunr = VisionList[i]._lradius; + VisionList[i]._lradius = r; + dovision = 1; + } + } +} + +void ChangeVisionXY(int id, int x, int y) +{ + int i; + + for(i = 0; i < numvision; i++) { + if(VisionList[i]._lid == id) { + VisionList[i]._lunflag = 1; + VisionList[i]._lunx = VisionList[i]._lx; + VisionList[i]._luny = VisionList[i]._ly; + VisionList[i]._lunr = VisionList[i]._lradius; + VisionList[i]._lx = x; + VisionList[i]._ly = y; + dovision = 1; + } + } +} + +void ProcessVisionList() +{ + int i; + BOOL delflag; + + if(dovision) { + for(i = 0; i < numvision; i++) { + if(VisionList[i]._ldel) { + DoUnVision(VisionList[i]._lx, VisionList[i]._ly, VisionList[i]._lradius); + } + if(VisionList[i]._lunflag) { + DoUnVision(VisionList[i]._lunx, VisionList[i]._luny, VisionList[i]._lunr); + VisionList[i]._lunflag = 0; + } + } + for(i = 0; i < TransVal; i++) { + TransList[i] = 0; + } + for(i = 0; i < numvision; i++) { + if(!VisionList[i]._ldel) { + DoVision( + VisionList[i]._lx, + VisionList[i]._ly, + VisionList[i]._lradius, + VisionList[i]._lflags & 1, + VisionList[i]._lflags & 1); + } + } + do { + delflag = FALSE; + for(i = 0; i < numvision; i++) { + if(VisionList[i]._ldel) { + numvision--; + if(numvision > 0 && i != numvision) { + VisionList[i] = VisionList[numvision]; + } + delflag = TRUE; + } + } + } while(delflag); + } + + dovision = 0; +} + +void lighting_color_cycling() +{ + int i, j, l; + BYTE col; + BYTE *tbl; + + l = light4flag ? 4 : 16; + + if(leveltype != DTYPE_HELL) { + return; + } + + tbl = pLightTbl; + + for(j = 0; j < l; j++) { + tbl++; + col = *tbl; + for(i = 0; i < 30; i++) { + tbl[0] = tbl[1]; + tbl++; + } + *tbl++ = col; + tbl += 224; + } +} diff --git a/2020_03_31/Source/lighting.h b/2020_03_31/Source/lighting.h new file mode 100644 index 00000000..0930f684 --- /dev/null +++ b/2020_03_31/Source/lighting.h @@ -0,0 +1,56 @@ +//HEADER_GOES_HERE +#ifndef __LIGHTING_H__ +#define __LIGHTING_H__ + +extern LightListStruct VisionList[MAXVISION]; +extern unsigned char lightactive[MAXLIGHTS]; +extern LightListStruct LightList[MAXLIGHTS]; +extern int numlights; +extern BYTE lightradius[16][128]; +extern int dovision; // weak +extern int numvision; +extern char lightmax; // weak +extern int dolighting; // weak +extern BYTE lightblock[8][8][16][16]; +extern int visionid; +extern BYTE *pLightTbl; +extern int lightflag; // weak + +void RotateRadius(int *x, int *y, int *dx, int *dy, int *lx, int *ly, int *bx, int *by); +void DoLighting(int nXPos, int nYPos, int nRadius, int Lnum); +void DoUnLight(int nXPos, int nYPos, int nRadius); +void DoUnVision(int nXPos, int nYPos, int nRadius); +void DoVision(int nXPos, int nYPos, int nRadius, BOOL doautomap, BOOL visible); +void FreeLightTable(); +void InitLightTable(); +void MakeLightTable(); +#ifdef _DEBUG +void ToggleLighting_2(); +void ToggleLighting(); +#endif +void InitLightMax(); +void InitLighting(); +int AddLight(int x, int y, int r); +void AddUnLight(int i); +void ChangeLightRadius(int i, int r); +void ChangeLightXY(int i, int x, int y); +void ChangeLightOff(int i, int x, int y); +void ChangeLight(int i, int x, int y, int r); +void ProcessLightList(); +void SavePreLighting(); +void InitVision(); +int AddVision(int x, int y, int r, BOOL mine); +void ChangeVisionRadius(int id, int r); +void ChangeVisionXY(int id, int x, int y); +void ProcessVisionList(); +void lighting_color_cycling(); + +/* rdata */ + +extern char CrawlTable[2749]; +extern char *pCrawlTable[19]; +extern unsigned char vCrawlTable[23][30]; +extern unsigned char byte_49463C[18][18]; +extern unsigned char RadiusAdj[23]; + +#endif /* __LIGHTING_H__ */ diff --git a/2020_03_31/Source/list.h b/2020_03_31/Source/list.h new file mode 100644 index 00000000..3a12f8de --- /dev/null +++ b/2020_03_31/Source/list.h @@ -0,0 +1,261 @@ +/* Intrusive double-linked list implementation, + * based on https://github.com/webcoyote/coho/blob/master/Base/List.h + */ + +#include // for placement new +#include // for offsetof +#include // for typeid + +#include "../3rdParty/Storm/Source/storm.h" + +#ifdef _MSC_VER +#pragma warning (disable : 4291) // no matching operator delete found +#endif + +#define OBJECT_NAME(obj) (((const char *)&typeid(obj)) + 8) + +/****************************************************************************** +* +* List definition macros +* +***/ + +// Define a field within a structure that will be used to link it into a list +#define LIST_LINK(T) TLink + +template +class TLink; + +/****************************************************************************** +* +* TList +* +***/ + +//============================================================================= +template +class TList { +public: + TList(); + ~TList(); + + void UnlinkAll(); + void DeleteAll(); + + T *Head(); + + enum InsertPos { + NONE = 0, + AFTER, + BEFORE + }; + + void Insert(T *node, InsertPos pos, T *ref); + T *Remove(T *node); + T *Create(InsertPos pos = BEFORE, size_t extra = 0, int memflags = 0); + +private: + size_t m_offset; + TLink m_link; + + TLink *GetLinkFromNode(T *node) const; + + // Hide copy-constructor and assignment operator + TList(const TList &); + TList &operator=(const TList &); + + // replacement new/delete operators for Storm objects + static __forceinline T *SNew(size_t extralen, int flags) + { + void *obj = SMemAlloc(sizeof(T) + extralen, (char *)OBJECT_NAME(T), SLOG_OBJECT, flags | (1<<3)); + return new (obj) T(); + } + + static __forceinline void SDelete(T *node) + { + node->~T(); + SMemFree(node, (char *)OBJECT_NAME(T), SLOG_OBJECT, 0); + } +}; + +//============================================================================= +template +TList::~TList() +{ + // BUGFIX: Unlinking does not free memory, should use DeleteAll() + UnlinkAll(); +} + +//============================================================================= +template +TList::TList() +{ + size_t offset = offsetof(T, m_Link); + // Mark this node as the end of the list, with the link offset set + m_link.m_prevLink = &m_link; + m_offset = offset; + m_link.m_nextNode = (T *)~((size_t)&m_link - offset); +} + +//============================================================================= +template +void TList::DeleteAll() +{ + while (T *node = m_link.Next()) + SDelete(node); +} + +//============================================================================= +template +__forceinline T *TList::Head() +{ + return m_link.Next(); +} + +//============================================================================= +template +__forceinline TLink *TList::GetLinkFromNode(T *node) const +{ + // assert(m_offset != (size_t) -1); + // return (TLink *) ((size_t) node + m_offset); + return &node->m_Link; +} + +template +T *TList::Remove(T *node) +{ + TLink *link = node ? &node->m_Link : &m_link; + T *next = link->Next(); + SDelete(node); + return next; +} + +template +T *TList::Create(InsertPos pos, size_t extra, int memflags) +{ + T *node = SNew(extra, memflags); + if (pos != NONE) + Insert(node, pos, NULL); + return node; +} + +template +void TList::Insert(T *node, InsertPos pos, T *ref) +{ + TLink *reflink; + TLink *i = node ? GetLinkFromNode(node) : &m_link; + if (i->IsLinked()) + i->Unlink(); + + reflink = ref ? GetLinkFromNode(ref) : &m_link; + + switch (pos) { + case AFTER: + i->InsertAfter(node, reflink, m_offset); + break; + case BEFORE: + i->InsertBefore(node, reflink); + } +} + +//============================================================================= +template +void TList::UnlinkAll() +{ + for (;;) { + T *node = m_link.Next(); + if ((int)node <= 0) + break; + node->m_Link.Unlink(); + } +} + +/****************************************************************************** +* +* TLink +* +***/ + +//============================================================================= +template +class TLink { +public: + TLink() + : m_prevLink(NULL) + , m_nextNode(NULL) + { + } + ~TLink() + { + Unlink(); + } + + bool IsLinked() const + { + return m_prevLink != NULL; + } + void Unlink(); + + T *Next() + { + if ((int)m_nextNode <= 0) + return NULL; + return m_nextNode; + } + + TLink *NextLink(size_t offset = -1) + { + if ((int)m_nextNode <= 0) + return (TLink *)~((size_t)m_nextNode); + + if ((int)offset < 0) { + // Calculate the offset from a node pointer to a link structure + offset = (size_t)this - (size_t)m_prevLink->m_nextNode; + } + + // Get the link field for the next node + return (TLink *)((size_t)m_nextNode + offset); + } + + void InsertBefore(T *node, TLink *nextLink) + { + TLink *p = nextLink->m_prevLink; + m_prevLink = p; + m_nextNode = p->m_nextNode; + + p->m_nextNode = node; + nextLink->m_prevLink = this; + } + + __forceinline void InsertAfter(T *node, TLink *prevLink, const size_t &offset) + { + m_prevLink = prevLink; + m_nextNode = prevLink->m_nextNode; + + prevLink->NextLink(offset)->m_prevLink = this; + prevLink->m_nextNode = node; + } + +private: + TLink *m_prevLink; // pointer to the previous >link field< + T *m_nextNode; // pointer to the next >object< + + // Hide copy-constructor and assignment operator + TLink(const TLink &); + TLink &operator=(const TLink &); + + friend class TList; +}; + +//============================================================================= +template +void TLink::Unlink() +{ + if (IsLinked()) { + NextLink()->m_prevLink = m_prevLink; + m_prevLink->m_nextNode = m_nextNode; + + m_prevLink = NULL; + m_nextNode = NULL; + } +} diff --git a/2020_03_31/Source/loadsave.cpp b/2020_03_31/Source/loadsave.cpp new file mode 100644 index 00000000..a9cd410b --- /dev/null +++ b/2020_03_31/Source/loadsave.cpp @@ -0,0 +1,691 @@ +#include "diablo.h" + +unsigned char *tbuff; + +void LoadGame(BOOL firstflag) +{ + int i, j; + int dwLen; + char szName[MAX_PATH]; + + FreeGameMem(); + pfile_remove_temp_files(); + pfile_get_game_name(szName); + unsigned char *LoadBuff = (unsigned char *)pfile_read(szName, &dwLen); + tbuff = LoadBuff; + + if(ILoad() != 'RETL') + app_fatal("Invalid save file"); + + setlevel = OLoad(); + setlvlnum = WLoad(); + currlevel = WLoad(); + leveltype = WLoad(); + int _ViewX = WLoad(); + int _ViewY = WLoad(); + invflag = OLoad(); + chrflag = OLoad(); + int _nummonsters = WLoad(); + int _numitems = WLoad(); + int _nummissiles = WLoad(); + int _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) { + 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) { + 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) + ProcessLightList(); + + RedoPlayerVision(); + ProcessVisionList(); + missiles_process_charge(); + ResetPal(); + SetCursor_(1); + gbProcessPlayers = 1; +} + +char BLoad() +{ + return *tbuff++; +} + +int WLoad() +{ + int rv = *tbuff++ << 24; + rv |= *tbuff++ << 16; + rv |= *tbuff++ << 8; + rv |= *tbuff++; + + return rv; +} + +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; +} + +void LoadPlayer(int i) +{ + memcpy(&plr[i], tbuff, sizeof(*plr) - (10 * sizeof(void *))); + tbuff += sizeof(*plr) - (10 * sizeof(void *)); // omit last 10 pointers +} + +void LoadMonster(int i) +{ + memcpy(&monster[i], tbuff, sizeof(*monster) - (3 * sizeof(void *))); + tbuff += sizeof(*monster) - (3 * sizeof(void *)); // omit last 3 pointers + SyncMonsterAnim(i); +} + +void LoadMissile(int i) +{ + memcpy(&missile[i], tbuff, sizeof(*missile)); + tbuff += sizeof(*missile); +} + +void LoadObject(int i) +{ + memcpy(&object[i], tbuff, sizeof(*object)); + tbuff += sizeof(*object); +} + +void LoadItem(int i) +{ + memcpy(&item[i], tbuff, sizeof(*item)); + tbuff += sizeof(*item); + GetItemFrm(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]; + + int dwLen = codec_get_encoded_len(FILEBUFF); + unsigned char *SaveBuff = DiabloAllocPtr(dwLen); + tbuff = SaveBuff; + + ISave('RETL'); + OSave((unsigned char)setlevel); + WSave((unsigned char)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) { + 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] & 0xF8); + } + 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) { + 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]; + + if(!currlevel) + glSeedTbl[0] = GetRndSeed(); + + int dwLen = codec_get_encoded_len(FILEBUFF); + unsigned char *SaveBuff = DiabloAllocPtr(dwLen); + tbuff = SaveBuff; + + if(leveltype) { + for(j = 0; j < MAXDUNY; j++) { + for(i = 0; i < MAXDUNX; i++) + BSave(dDead[i][j]); + } + } + + WSave(nummonsters); + WSave(numitems); + WSave(nobjects); + + if(leveltype) { + 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] & 0xF8); + } + for(j = 0; j < MAXDUNY; j++) { + for(i = 0; i < MAXDUNX; i++) + BSave(dItem[i][j]); + } + + if(leveltype) { + 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[(unsigned char)setlvlnum] = 1; +} + +void LoadLevel() +{ + int i, j; + int dwLen; + char szName[MAX_PATH]; + + GetPermLevelNames(szName); + unsigned char *LoadBuff = (unsigned char *)pfile_read(szName, &dwLen); + tbuff = LoadBuff; + + if(leveltype) { + 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) { + 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) { + 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); +} diff --git a/2020_03_31/Source/loadsave.h b/2020_03_31/Source/loadsave.h new file mode 100644 index 00000000..d9c9982a --- /dev/null +++ b/2020_03_31/Source/loadsave.h @@ -0,0 +1,40 @@ +//HEADER_GOES_HERE +#ifndef __LOADSAVE_H__ +#define __LOADSAVE_H__ + +extern unsigned char *tbuff; + +void LoadGame(BOOL firstflag); +char BLoad(); +int WLoad(); +int ILoad(); +BOOL OLoad(); +void LoadPlayer(int i); +void LoadMonster(int i); +void LoadMissile(int i); +void LoadObject(int i); +void LoadItem(int i); +void LoadPremium(int i); +void LoadQuest(int i); +void LoadLighting(int i); +void LoadVision(int i); +void LoadPortal(int i); +void SaveGame(); +void BSave(char v); +void WSave(int v); +void ISave(int v); +void OSave(BOOL v); +void SavePlayer(int i); +void SaveMonster(int i); +void SaveMissile(int i); +void SaveObject(int i); +void SaveItem(int i); +void SavePremium(int i); +void SaveQuest(int i); +void SaveLighting(int i); +void SaveVision(int i); +void SavePortal(int i); +void SaveLevel(); +void LoadLevel(); + +#endif /* __LOADSAVE_H__ */ diff --git a/2020_03_31/Source/logging.cpp b/2020_03_31/Source/logging.cpp new file mode 100644 index 00000000..37e8d40d --- /dev/null +++ b/2020_03_31/Source/logging.cpp @@ -0,0 +1,190 @@ +#include "diablo.h" +#include "../3rdParty/Storm/Source/storm.h" + +static CCritSect sgMemCrit; +CHAR FileName[260]; // idb +char log_buffer[388]; +LPCVOID lpAddress; // idb +DWORD nNumberOfBytesToWrite; // idb + +/* data */ + +int log_not_created = 1; // weak +HANDLE log_file = (HANDLE)0xFFFFFFFF; // idb + +void __cdecl log_flush(_bool force_close) +{ + void *v1; // eax + DWORD NumberOfBytesWritten; // [esp+8h] [ebp-4h] + + sgMemCrit.Enter(); + if ( nNumberOfBytesToWrite ) + { + if ( log_file == (HANDLE)-1 ) + { + v1 = log_create(); + log_file = v1; + if ( v1 == (void *)-1 ) + { + nNumberOfBytesToWrite = 0; + return; + } + SetFilePointer(v1, 0, NULL, FILE_END); + } + WriteFile(log_file, lpAddress, nNumberOfBytesToWrite, &NumberOfBytesWritten, 0); + nNumberOfBytesToWrite = 0; + } + if ( force_close && log_file != (HANDLE)-1 ) + { + CloseHandle(log_file); + log_file = (HANDLE)-1; + } + sgMemCrit.Leave(); +} + +void *log_create() +{ + char *v0; // eax + void *v1; // ebx + HANDLE v2; // eax + char *v3; // edx + char Filename[260]; // [esp+Ch] [ebp-15Ch] + VS_FIXEDFILEINFO file_info; // [esp+110h] [ebp-58h] + char Buffer[32]; // [esp+144h] [ebp-24h] + DWORD pcbBuffer; // [esp+164h] [ebp-4h] + + if ( log_not_created ) + { + if ( GetModuleFileName(0, Filename, 0x104u) && (v0 = strrchr(Filename, '\\')) != 0 ) + v0[1] = 0; + else + Filename[0] = 0; + pcbBuffer = 32; + if ( !GetUserName(Buffer, &pcbBuffer) ) + Buffer[0] = 0; + log_get_version(&file_info); + _snprintf( + FileName, + 0x104u, + "%s%s%02u%02u%02u.ERR", + Filename, + Buffer, + _LOWORD(file_info.dwProductVersionMS), + file_info.dwProductVersionLS >> 16, + _LOWORD(file_info.dwProductVersionLS)); + } + v1 = (void *)-1; + for ( pcbBuffer = log_not_created == 0; (signed int)pcbBuffer < 2; ++pcbBuffer ) + { + v2 = CreateFile(FileName, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + v1 = v2; + if ( v2 != (HANDLE)-1 ) + { + if ( GetFileSize(v2, 0) > 0x10000 ) + SetEndOfFile(v1); + break; + } + v3 = strrchr(FileName, '\\'); + if ( !v3 ) + v3 = FileName; + strcpy(Filename, "c:\\"); + memset(&Filename[4], 0, 0x100u); + strcat(Filename, v3); + strcpy(FileName, Filename); + } + log_not_created = 0; + return v1; +} + +void log_get_version(VS_FIXEDFILEINFO *file_info) +{ + DWORD v1; // eax + DWORD v2; // esi + void *v3; // ebx + unsigned int v4; // eax + char Filename[260]; // [esp+8h] [ebp-114h] + DWORD dwHandle; // [esp+10Ch] [ebp-10h] + LPVOID lpBuffer; // [esp+110h] [ebp-Ch] + unsigned int puLen; // [esp+114h] [ebp-8h] + void *v9; // [esp+118h] [ebp-4h] + + v9 = file_info; + memset(file_info, 0, 0x34u); + if ( GetModuleFileName(0, Filename, 0x104u) ) + { + v1 = GetFileVersionInfoSize(Filename, &dwHandle); + v2 = v1; + if ( v1 ) + { + v3 = VirtualAlloc(0, v1, 0x1000u, 4u); + if ( GetFileVersionInfo(Filename, 0, v2, v3) && VerQueryValue(v3, "\\", &lpBuffer, &puLen) ) + { + v4 = puLen; + if ( puLen >= 0x34 ) + v4 = 52; + memcpy(v9, lpBuffer, v4); + } + VirtualFree(v3, 0, 0x8000u); + } + } +} + +void __cdecl log_printf(const char *pszFmt, ...) +{ + size_t v1; // edi + char *v2; // eax + char v3[512]; // [esp+Ch] [ebp-200h] + va_list va; // [esp+218h] [ebp+Ch] + + va_start(va, pszFmt); + sgMemCrit.Enter(); + _vsnprintf(v3, 0x200u, pszFmt, va); + v3[511] = 0; + v1 = strlen(v3); + if ( v1 + nNumberOfBytesToWrite > 0x1000 ) + log_flush(0); + v2 = (char *)lpAddress; + if ( lpAddress + || (v2 = (char *)VirtualAlloc((LPVOID)lpAddress, 0x1000u, 0x1000u, 4u), + nNumberOfBytesToWrite = 0, + (lpAddress = v2) != 0) ) + { + memcpy(&v2[nNumberOfBytesToWrite], v3, v1); + nNumberOfBytesToWrite += v1; + } + sgMemCrit.Leave(); +} + +void log_dump_computer_info() +{ + char Buffer[64]; // [esp+0h] [ebp-88h] + VS_FIXEDFILEINFO file_info; // [esp+40h] [ebp-48h] + struct _SYSTEMTIME SystemTime; // [esp+74h] [ebp-14h] + DWORD pcbBuffer; // [esp+84h] [ebp-4h] + + GetLocalTime(&SystemTime); + pcbBuffer = 64; + if ( !GetUserName(Buffer, &pcbBuffer) ) + Buffer[0] = 0; + log_get_version(&file_info); + log_printf( + "\r\n" + "------------------------------------------------------\r\n" + "PROGRAM VERSION: %d.%d.%d.%d\r\n" + "COMPUTER NAME: %s\r\n" + "TIME: %02u/%02u/%02u %02u:%02u:%02u\r\n" + "INFO: %s\r\n" + "\r\n", + file_info.dwProductVersionMS >> 16, + _LOWORD(file_info.dwProductVersionMS), + file_info.dwProductVersionLS >> 16, + _LOWORD(file_info.dwProductVersionLS), + Buffer, + SystemTime.wMonth, + SystemTime.wDay, + SystemTime.wYear % 100, + SystemTime.wHour, + SystemTime.wMinute, + SystemTime.wSecond, + log_buffer); +} diff --git a/2020_03_31/Source/logging.h b/2020_03_31/Source/logging.h new file mode 100644 index 00000000..0e45fb24 --- /dev/null +++ b/2020_03_31/Source/logging.h @@ -0,0 +1,21 @@ +//HEADER_GOES_HERE +#ifndef __LOGGING_H__ +#define __LOGGING_H__ + +extern CHAR FileName[260]; // idb +extern char log_buffer[388]; +extern LPCVOID lpAddress; // idb +extern DWORD nNumberOfBytesToWrite; // idb + +void __cdecl log_flush(_bool force_close); +void *log_create(); // should be HANDLE +void log_get_version(VS_FIXEDFILEINFO *file_info); +void __cdecl log_printf(const char *pszFmt, ...); // LogMessage +void log_dump_computer_info(); + +/* data */ + +extern int log_not_created; // weak +extern HANDLE log_file; // idb + +#endif /* __LOGGING_H__ */ diff --git a/2020_03_31/Source/mainmenu.cpp b/2020_03_31/Source/mainmenu.cpp new file mode 100644 index 00000000..ad3bdc87 --- /dev/null +++ b/2020_03_31/Source/mainmenu.cpp @@ -0,0 +1,166 @@ +#include "diablo.h" +#include "../3rdParty/Storm/Source/storm.h" +#include "../DiabloUI/diabloui.h" + +char gszHero[16]; + +/* data */ + +int menu_music_track_id = 5; // idb + +void mainmenu_refresh_music() +{ + int v0; // eax + + music_start(menu_music_track_id); + v0 = menu_music_track_id; + do + { + if ( ++v0 == 6 ) + v0 = 0; + } + while ( !v0 || v0 == 1 ); + menu_music_track_id = v0; +} + +void __stdcall mainmenu_create_hero(int a1, int a2, int a3, int a4, char *name_1, char *name_2) +{ + if ( UiValidPlayerName(name_2) ) + pfile_create_save_file(name_1, name_2); +} + +int __stdcall mainmenu_select_hero_dialog(int u1, int u2, int u3, int u4, int mode, char *cname, int clen, char *cdesc, int cdlen, int *multi) /* fix args */ +{ + int v10; // eax + int a6; // [esp+8h] [ebp-8h] + int a5; // [esp+Ch] [ebp-4h] + + a6 = 1; + a5 = 0; + if ( gbMaxPlayers == 1 ) + { + if ( !UiSelHeroSingDialog( + pfile_ui_set_hero_infos, + pfile_ui_save_create, + pfile_delete_save, + pfile_ui_set_class_stats, + &a5, + gszHero, + &gnDifficulty) ) + app_fatal("Unable to display SelHeroSing"); + if ( a5 == SELHERO_CONTINUE ) + { + gbLoadGame = 1; + goto LABEL_6; + } + gbLoadGame = 0; // SELHERO_NEW_DUNGEON + } + else if ( !UiSelHeroMultDialog( + pfile_ui_set_hero_infos, + pfile_ui_save_create, + pfile_delete_save, + pfile_ui_set_class_stats, + &a5, + &a6, + gszHero) ) + { + app_fatal("Can't load multiplayer dialog"); + } + if ( a5 == SELHERO_PREVIOUS ) + { + SErrSetLastError(1223); + return 0; + } +LABEL_6: + pfile_create_player_description(cdesc, cdlen); + if ( multi ) + { + if ( mode == 'BNET' ) + v10 = a6 || !plr[myplr].pBattleNet; + else + v10 = a6; + *multi = v10; + } + if ( cname ) + { + if ( clen ) + SStrCopy(cname, gszHero, clen); + } + return 1; +} + +void mainmenu_loop() +{ + BOOL done; + int menu; + + mainmenu_refresh_music(); + done = FALSE; + + while(!done) { + menu = 0; + if(!UiMainMenuDialog(gszProductName, &menu, effects_play_sound, 30)) { + app_fatal("Unable to display mainmenu"); + } + switch(menu) { + case MAINMENU_SINGLE_PLAYER: + if(!mainmenu_single_player()) { + done = TRUE; + } + break; + case MAINMENU_MULTIPLAYER: + if(!mainmenu_multi_player()) { + done = TRUE; + } + break; + case MAINMENU_REPLAY_INTRO: + case MAINMENU_ATTRACT_MODE: + if(gbActive) { + mainmenu_play_intro(); + } + break; + case MAINMENU_SHOW_CREDITS: + UiCreditsDialog(16); + break; + case MAINMENU_EXIT_DIABLO: + done = TRUE; + break; + } + } + + music_stop(); +} + +int mainmenu_single_player() +{ + gbMaxPlayers = 1; + return mainmenu_init_menu(SELHERO_NEW_DUNGEON); +} + +int mainmenu_init_menu(int a1) +{ + int v1; // esi + int v3; // esi + + v1 = a1; + if ( a1 == SELHERO_PREVIOUS ) + return 1; + music_stop(); + v3 = StartGame(v1 != SELHERO_CONTINUE, v1 != SELHERO_CONNECT); + if ( v3 ) + mainmenu_refresh_music(); + return v3; +} + +int mainmenu_multi_player() +{ + gbMaxPlayers = 4; + return mainmenu_init_menu(SELHERO_CONNECT); +} + +void mainmenu_play_intro() +{ + music_stop(); + play_movie("gendata\\diablo1.smk", 1); + mainmenu_refresh_music(); +} diff --git a/2020_03_31/Source/mainmenu.h b/2020_03_31/Source/mainmenu.h new file mode 100644 index 00000000..27ba7b84 --- /dev/null +++ b/2020_03_31/Source/mainmenu.h @@ -0,0 +1,20 @@ +//HEADER_GOES_HERE +#ifndef __MAINMENU_H__ +#define __MAINMENU_H__ + +extern char gszHero[16]; + +void mainmenu_refresh_music(); +void __stdcall mainmenu_create_hero(int a1, int a2, int a3, int a4, char *name_1, char *name_2); +int __stdcall mainmenu_select_hero_dialog(int u1, int u2, int u3, int u4, int mode, char *cname, int clen, char *cdesc, int cdlen, int *multi); +void mainmenu_loop(); +int mainmenu_single_player(); +int mainmenu_init_menu(int a1); +int mainmenu_multi_player(); +void mainmenu_play_intro(); + +/* data */ + +extern int menu_music_track_id; // idb + +#endif /* __MAINMENU_H__ */ diff --git a/2020_03_31/Source/minitext.cpp b/2020_03_31/Source/minitext.cpp new file mode 100644 index 00000000..10640164 --- /dev/null +++ b/2020_03_31/Source/minitext.cpp @@ -0,0 +1,349 @@ +#include "diablo.h" + +int qtexty; // weak +char *qtextptr; +int qtextSpd; // weak +char qtextflag; // weak +int scrolltexty; // weak +int sgLastScroll; // weak +void *pMedTextCels; +void *pTextBoxCels; + +const unsigned char mfontframe[127] = +{ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 37, 49, 38, 0, 39, 40, 47, + 42, 43, 41, 45, 52, 44, 53, 55, 36, 27, + 28, 29, 30, 31, 32, 33, 34, 35, 51, 50, + 48, 46, 49, 54, 0, 1, 2, 3, 4, 5, + 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 26, 42, 0, 43, 0, 0, 0, 1, 2, 3, + 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 48, 0, 49, 0 +}; +const unsigned char mfontkern[56] = +{ + 5, 15, 10, 13, 14, 10, 9, 13, 11, 5, + 5, 11, 10, 16, 13, 16, 10, 15, 12, 10, + 14, 17, 17, 22, 17, 16, 11, 5, 11, 11, + 11, 10, 11, 11, 11, 11, 15, 5, 10, 18, + 15, 8, 6, 6, 7, 10, 9, 6, 10, 10, + 5, 5, 5, 5, 11, 12 +}; + +/* data */ + +int qscroll_spd_tbl[9] = { 2, 4, 6, 8, 0, -1, -2, -3, -4 }; + +void FreeQuestText() +{ + void *v0; // ecx + void *v1; // ecx + + v0 = pMedTextCels; + pMedTextCels = 0; + mem_free_dbg(v0); + v1 = pTextBoxCels; + pTextBoxCels = 0; + mem_free_dbg(v1); +} + +void InitQuestText() +{ + unsigned char *v0; // eax + + pMedTextCels = DiabLoad("Data\\MedTextS.CEL", NULL, 'MINI'); + v0 = DiabLoad("Data\\TextBox.CEL", NULL, 'MINI'); + qtextflag = 0; + pTextBoxCels = v0; +} + +void InitQTextMsg(int m) +{ + if ( alltext[m].scrlltxt ) + { + questlog = 0; + qtextptr = alltext[m].txtstr; + qtextflag = 1; + qtexty = 500; + sgLastScroll = qscroll_spd_tbl[alltext[m].txtspd - 1]; /* double check offset */ + scrolltexty = sgLastScroll; + qtextSpd = GetTickCount(); + } + PlaySFX(alltext[m].sfxnr); +} + +void DrawQTextBack() +{ + CelDecodeOnly(88, 487, (BYTE *)pTextBoxCels, 1, 591); + + /// ASSERT: assert(gpBuffer); + +#ifdef USE_ASM + __asm { + mov edi, gpBuffer + add edi, SCREENXY(27, 324) + xor eax, eax + mov edx, 297 / 2 + label1: + mov ecx, 585 / 2 + label2: + stosb + inc edi + loop label2 + stosb + sub edi, 768 + 585 + mov ecx, 585 / 2 + label3: + inc edi + stosb + loop label3 + sub edi, 768 + (585 - 1) + dec edx + jnz label1 + mov ecx, 585 / 2 + label4: + stosb + inc edi + loop label4 + stosb + } +#else + int wdt, hgt; + BYTE *dst; + + dst = &gpBuffer[SCREENXY(27, 324)]; + + for(hgt = 297 / 2; hgt != 0; hgt--) { + for(wdt = 585 / 2; wdt != 0; wdt--) { + dst[0] = 0; + dst += 2; + } + *dst = 0; + dst -= 768 + (585 - 1); + for(wdt = 585 / 2; wdt != 0; wdt--) { + dst[1] = 0; + dst += 2; + } + dst -= 768 + (585 - 1); + } + for(wdt = 585 / 2; wdt != 0; wdt--) { + dst[0] = 0; + dst += 2; + } + *dst = 0; +#endif +} + +void PrintQTextChr(int sx, int sy, BYTE *pCelBuff, int nCel) +{ + BYTE *dst, *pStart, *pEnd, *end; + + /// ASSERT: assert(gpBuffer); + + dst = &gpBuffer[sx + PitchTbl[sy]]; + pStart = &gpBuffer[PitchTbl[209]]; + pEnd = &gpBuffer[PitchTbl[469]]; + +#ifdef USE_ASM + __asm { + mov ebx, pCelBuff + mov eax, nCel + shl eax, 2 + add ebx, eax + mov eax, [ebx+4] + sub eax, [ebx] + mov end, eax + mov esi, pCelBuff + add esi, [ebx] + mov edi, dst + mov ebx, end + add ebx, esi + label1: + mov edx, 22 + label2: + xor eax, eax + lodsb + or al, al + js label7 + sub edx, eax + cmp edi, pStart + jb label5 + cmp edi, pEnd + ja label5 + mov ecx, eax + shr ecx, 1 + jnb label3 + movsb + jecxz label6 + label3: + shr ecx, 1 + jnb label4 + movsw + jecxz label6 + label4: + rep movsd + jmp label6 + label5: + add esi, eax + add edi, eax + label6: + or edx, edx + jz label8 + jmp label2 + label7: + neg al + add edi, eax + sub edx, eax + jnz label2 + label8: + sub edi, 768 + 22 + cmp ebx, esi + jnz label1 + } +#else + int i; + BYTE width; + BYTE *src; + DWORD *pFrameTable; + + pFrameTable = (DWORD *)&pCelBuff[4 * nCel]; + src = &pCelBuff[pFrameTable[0]]; + end = &src[pFrameTable[1] - pFrameTable[0]]; + + for(; src != end; dst -= 768 + 22) { + for(i = 22; i;) { + width = *src++; + if(!(width & 0x80)) { + i -= width; + if(dst >= pStart && dst <= pEnd) { + if(width & 1) { + dst[0] = src[0]; + src++; + dst++; + } + width >>= 1; + if(width & 1) { + dst[0] = src[0]; + dst[1] = src[1]; + src += 2; + dst += 2; + } + width >>= 1; + for(; width; width--) { + dst[0] = src[0]; + dst[1] = src[1]; + dst[2] = src[2]; + dst[3] = src[3]; + src += 4; + dst += 4; + } + } else { + src += width; + dst += width; + } + } else { + width = -(char)width; + dst += width; + i -= width; + } + } + } +#endif +} + +void DrawQText() +{ + int i, l, w, tx, ty; + BYTE c; + char *p, *pnl, *s; + char tempstr[128]; + BOOL doneflag; + DWORD currTime; + + DrawQTextBack(); + + p = qtextptr; + pnl = NULL; + tx = 112; + ty = qtexty; + + doneflag = FALSE; + while(!doneflag) { + w = 0; + s = p; + l = 0; + while(*s != '\n' && *s != '|' && w < 543) { + c = gbFontTransTbl[(BYTE)*s]; + s++; + if(c != '\0') { + tempstr[l] = c; + w += mfontkern[mfontframe[c]] + 2; + } else { + l--; + } + l++; + } + tempstr[l] = '\0'; + if(*s == '|') { + tempstr[l] = '\0'; + doneflag = TRUE; + } else if(*s != '\n') { + while(tempstr[l] != ' ' && l > 0) { + tempstr[l] = '\0'; + l--; + } + } + for(i = 0; tempstr[i]; i++) { + p++; + c = mfontframe[gbFontTransTbl[(BYTE)tempstr[i]]]; + if(*p == '\n') { + p++; + } + if(c != 0) { + PrintQTextChr(tx, ty, (BYTE *)pMedTextCels, c); + } + tx += mfontkern[c] + 2; + } + if(pnl == NULL) { + pnl = p; + } + tx = 112; + ty += 38; + if(ty > 501) { + doneflag = TRUE; + } + } + + currTime = GetTickCount(); + while(1) { + if(sgLastScroll <= 0) { + qtexty--; + qtexty += sgLastScroll; + } else { + scrolltexty--; + if(scrolltexty != 0) { + qtexty--; + } + } + if(scrolltexty == 0) { + scrolltexty = sgLastScroll; + } + if(qtexty <= 209) { + qtexty += 38; + qtextptr = pnl; + if(*pnl == '|') { + qtextflag = 0; + } + break; + } + qtextSpd += 50; + if(currTime - qtextSpd >= 0x7FFFFFFF) { + break; + } + } +} diff --git a/2020_03_31/Source/minitext.h b/2020_03_31/Source/minitext.h new file mode 100644 index 00000000..03a4381d --- /dev/null +++ b/2020_03_31/Source/minitext.h @@ -0,0 +1,30 @@ +//HEADER_GOES_HERE +#ifndef __MINITEXT_H__ +#define __MINITEXT_H__ + +extern int qtexty; // weak +extern char *qtextptr; +extern int qtextSpd; // weak +extern char qtextflag; // weak +extern int scrolltexty; // weak +extern int sgLastScroll; // weak +extern void *pMedTextCels; +extern void *pTextBoxCels; + +void FreeQuestText(); +void InitQuestText(); +void InitQTextMsg(int m); +void DrawQTextBack(); +void PrintQTextChr(int sx, int sy, BYTE *pCelBuff, int nCel); +void DrawQText(); + +/* rdata */ + +extern const unsigned char mfontframe[127]; +extern const unsigned char mfontkern[56]; + +/* data */ + +extern int qscroll_spd_tbl[9]; + +#endif /* __MINITEXT_H__ */ diff --git a/2020_03_31/Source/misdat.cpp b/2020_03_31/Source/misdat.cpp new file mode 100644 index 00000000..2aa9c10b --- /dev/null +++ b/2020_03_31/Source/misdat.cpp @@ -0,0 +1,11 @@ +#include "diablo.h" + +MissileData missiledata[68] = +{ +#include "Data/xl_mis.cpp" +}; + +MisFileData misfiledata[47] = +{ +#include "Data/xl_mfile.cpp" +}; diff --git a/2020_03_31/Source/misdat.h b/2020_03_31/Source/misdat.h new file mode 100644 index 00000000..1dd8a429 --- /dev/null +++ b/2020_03_31/Source/misdat.h @@ -0,0 +1,8 @@ +//HEADER_GOES_HERE +#ifndef __MISDAT_H__ +#define __MISDAT_H__ + +extern MissileData missiledata[68]; +extern MisFileData misfiledata[47]; + +#endif /* __MISDAT_H__ */ diff --git a/2020_03_31/Source/missiles.cpp b/2020_03_31/Source/missiles.cpp new file mode 100644 index 00000000..e2ad778b --- /dev/null +++ b/2020_03_31/Source/missiles.cpp @@ -0,0 +1,4670 @@ +#include "diablo.h" + +int missileactive[MAXMISSILES]; +int missileavail[MAXMISSILES]; +MissileStruct missile[MAXMISSILES]; +int nummissiles; // idb +int ManashieldFlag; +ChainStruct chain[MAXMISSILES]; +int MissilePreFlag; // weak +int numchains; // weak + +int XDirAdd[8] = { 1, 0, -1, -1, -1, 0, 1, 1 }; +int YDirAdd[8] = { 1, 1, 1, 0, -1, -1, -1, 0 }; + +void GetDamageAmt(int i, int *mind, int *maxd) +{ + int k, sl; + + /// ASSERT: assert((DWORD)myplr < MAX_PLRS); + /// ASSERT: assert((DWORD)i < 64); + sl = plr[myplr]._pSplLvl[i] + plr[myplr]._pISplLvlAdd; + + switch(i) { + case SPL_FIREBOLT: + *mind = (plr[myplr]._pMagic >> 3) + sl + 1; + *maxd = (plr[myplr]._pMagic >> 3) + sl + 10; + break; + case SPL_HEAL: /// BUGFIX: healing calculation is unused + *mind = plr[myplr]._pLevel + sl + 1; + if(plr[myplr]._pClass == PC_WARRIOR) { + *mind *= 2; + } + if(plr[myplr]._pClass == PC_ROGUE) { + *mind += *mind >> 1; + } + *maxd = 10; + for(k = 0; k < plr[myplr]._pLevel; k++) { + *maxd += 4; + } + for(k = 0; k < sl; k++) { + *maxd += 6; + } + if(plr[myplr]._pClass == PC_WARRIOR) { + *maxd *= 2; + } + if(plr[myplr]._pClass == PC_ROGUE) { + *maxd += *maxd >> 1; + } + *mind = -1; + *maxd = -1; + break; + case SPL_LIGHTNING: + *mind = 2; + *maxd = plr[myplr]._pLevel + 2; + break; + case SPL_FLASH: + *mind = plr[myplr]._pLevel; + for(k = 0; k < sl; k++) { + *mind += *mind >> 3; + } + *mind += *mind >> 1; + *maxd = *mind * 2; + break; + case SPL_IDENTIFY: + case SPL_TOWN: + case SPL_STONE: + case SPL_INFRA: + case SPL_RNDTELEPORT: + case SPL_MANASHIELD: + case SPL_DOOMSERP: + case SPL_BLODRIT: + case SPL_INVISIBIL: + case SPL_BLODBOIL: + case SPL_TELEPORT: + case SPL_ETHEREALIZE: + case SPL_REPAIR: + case SPL_RECHARGE: + case SPL_DISARM: + case SPL_RESURRECT: + case SPL_TELEKINESIS: + case SPL_BONESPIRIT: + *mind = -1; + *maxd = -1; + break; + case SPL_FIREWALL: + *mind = (4 * plr[myplr]._pLevel + 8) >> 1; + *maxd = (4 * plr[myplr]._pLevel + 80) >> 1; + break; + case SPL_FIREBALL: + *mind = 2 * plr[myplr]._pLevel + 4; + for(k = 0; k < sl; k++) { + *mind += *mind >> 3; + } + *maxd = 2 * plr[myplr]._pLevel + 40; + for(k = 0; k < sl; k++) { + *maxd += *maxd >> 3; + } + break; + case SPL_GUARDIAN: + *mind = (plr[myplr]._pLevel >> 1) + 1; + for(k = 0; k < sl; k++) { + *mind += *mind >> 3; + } + *maxd = (plr[myplr]._pLevel >> 1) + 10; + for(k = 0; k < sl; k++) { + *maxd += *maxd >> 3; + } + break; + case SPL_CHAIN: + *mind = 4; + *maxd = 2 * plr[myplr]._pLevel + 4; + break; + case SPL_WAVE: + *mind = 6 * (plr[myplr]._pLevel + 1); + *maxd = 6 * (plr[myplr]._pLevel + 10); + break; + case SPL_NOVA: + *mind = (plr[myplr]._pLevel + 5) >> 1; + for(k = 0; k < sl; k++) { + *mind += *mind >> 3; + } + *mind *= 5; + *maxd = (plr[myplr]._pLevel + 30) >> 1; + for(k = 0; k < sl; k++) { + *maxd += *maxd >> 3; + } + *maxd *= 5; + break; + case SPL_FLAME: + *mind = 3; + *maxd = plr[myplr]._pLevel + 4; + *maxd += *maxd >> 1; + break; + case SPL_GOLEM: + *mind = 11; + *maxd = 17; + break; + case SPL_APOCA: + *mind = 0; + for(k = 0; k < plr[myplr]._pLevel; k++) { + (*mind)++; + } + *maxd = 0; + for(k = 0; k < plr[myplr]._pLevel; k++) { + *maxd += 6; + } + break; + case SPL_ELEMENT: + *mind = 2 * plr[myplr]._pLevel + 4; + for(k = 0; k < sl; k++) { + *mind += *mind >> 3; + } + /// BUGFIX: add here '*mind >>= 1;' + *maxd = 2 * plr[myplr]._pLevel + 40; + for(k = 0; k < sl; k++) { + *maxd += *maxd >> 3; + } + /// BUGFIX: add here '*maxd >>= 1;' + break; + case SPL_CBOLT: + *mind = 1; + *maxd = (plr[myplr]._pMagic >> 2) + 1; + break; + case SPL_HBOLT: + *mind = plr[myplr]._pLevel + 9; + *maxd = plr[myplr]._pLevel + 18; + break; + case SPL_HEALOTHER: /// BUGFIX: healing calculation is unused + *mind = plr[myplr]._pLevel + sl + 1; + if(plr[myplr]._pClass == PC_WARRIOR) { + *mind *= 2; + } + if(plr[myplr]._pClass == PC_ROGUE) { + *mind += *mind >> 1; + } + *maxd = 10; + for(k = 0; k < plr[myplr]._pLevel; k++) { + *maxd += 4; + } + for(k = 0; k < sl; k++) { + *maxd += 6; + } + if(plr[myplr]._pClass == PC_WARRIOR) { + *maxd *= 2; + } + if(plr[myplr]._pClass == PC_ROGUE) { + *maxd += *maxd >> 1; + } + *mind = -1; + *maxd = -1; + break; + case SPL_FLARE: + *mind = (plr[myplr]._pMagic >> 1) + 3 * sl - (plr[myplr]._pMagic >> 3); + *maxd = *mind; + break; + } +} + +BOOL CheckBlock(int fx, int fy, int tx, int ty) +{ + int pn, d; + BOOL coll; + + coll = FALSE; + while(fx != tx || fy != ty) { + d = GetDirection(fx, fy, tx, ty); + fx += XDirAdd[d]; + fy += YDirAdd[d]; + /// ASSERT: assert((DWORD)fx < MAXDUNX); + /// ASSERT: assert((DWORD)fy < MAXDUNY); + pn = dPiece[fx][fy]; + /// ASSERT: assert((DWORD)pn <= MAXTILES); + if(nSolidTable[pn]) { + coll = TRUE; + } + } + + return coll; +} + +int FindClosest(int sx, int sy, int rad) +{ + int cr, cidx, cent, cne, mid, tx, ty; + int CrawlNum[19] = { 0, 3, 12, 45, 94, 159, 240, 337, 450, 579, 724, 885, 1062, 1255, 1464, 1689, 1930, 2187, 2460 }; + + if(rad > 19) { + rad = 19; + } + + for(cr = 1; cr < rad; cr++) { + cidx = CrawlNum[cr]; + cent = cidx + 1; + for(cne = (BYTE)CrawlTable[cidx]; cne > 0; cne--) { + tx = sx + CrawlTable[cent]; + ty = sy + CrawlTable[cent + 1]; + if(tx > 0 && tx < MAXDUNX && ty > 0 && ty < MAXDUNY) { + mid = dMonster[tx][ty]; + if(mid > 0 && !CheckBlock(sx, sy, tx, ty)) { + return mid - 1; + } + } + cent += 2; + } + } + + return -1; +} + +int GetSpellLevel(int id, int sn) +{ + int rv; + + /// ASSERT: assert((DWORD)id < MAX_PLRS); + /// ASSERT: assert((DWORD)sn < 64); + + if(id == myplr) { + rv = plr[id]._pSplLvl[sn] + plr[id]._pISplLvlAdd; + } else { + rv = 1; + } + + if(rv < 0) { + rv = 0; + } + + return rv; +} + +int GetDirection8(int x1, int y1, int x2, int y2) +{ + int mx, my, md; + BYTE Dirs[16][16] = { + { 99, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 2, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 2, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 2, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 }, + { 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0 }, + { 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 }, + { 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, + { 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, + { 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, + { 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, + { 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, + { 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, + { 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, + { 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, + { 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, + { 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } + }; + __declspec(align(1)) BYTE lrtoul[3] = { 3, 4, 5 }; + __declspec(align(1)) BYTE urtoll[3] = { 3, 2, 1 }; + __declspec(align(1)) BYTE lltour[3] = { 7, 6, 5 }; + __declspec(align(1)) BYTE ultolr[3] = { 7, 0, 1 }; + + mx = abs(x2 - x1); + if(mx > 15) { + mx = 15; + } + my = abs(y2 - y1); + if(my > 15) { + my = 15; + } + md = Dirs[my][mx]; + + if(x1 > x2) { + if(y1 > y2) { + md = lrtoul[md]; + } else { + md = urtoll[md]; + } + } else { + if(y1 > y2) { + md = lltour[md]; + } else { + md = ultolr[md]; + } + } + + return md; +} + +int GetDirection16(int x1, int y1, int x2, int y2) +{ + int mx, my, md; + BYTE Dirs[16][16] = { + { 99, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 4, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 4, 3, 2, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 4, 3, 3, 2, 2, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0 }, + { 4, 4, 3, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, + { 4, 4, 3, 3, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, + { 4, 4, 3, 3, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1 }, + { 4, 4, 3, 3, 3, 3, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1 }, + { 4, 4, 4, 3, 3, 3, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1 }, + { 4, 4, 4, 3, 3, 3, 3, 2, 2, 2, 2, 2, 1, 1, 1, 1 }, + { 4, 4, 4, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 1, 1 }, + { 4, 4, 4, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 1 }, + { 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2 }, + { 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2 }, + { 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2 }, + { 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2 } + }; + BYTE lrtoul[5] = { 6, 7, 8, 9, 10 }; + BYTE urtoll[5] = { 6, 5, 4, 3, 2 }; + BYTE lltour[5] = { 14, 13, 12, 11, 10 }; + BYTE ultolr[5] = { 14, 15, 0, 1, 2 }; + + mx = abs(x2 - x1); + if(mx > 15) { + mx = 15; + } + my = abs(y2 - y1); + if(my > 15) { + my = 15; + } + md = Dirs[my][mx]; + + if(x1 > x2) { + if(y1 > y2) { + md = lrtoul[md]; + } else { + md = urtoll[md]; + } + } else { + if(y1 > y2) { + md = lltour[md]; + } else { + md = ultolr[md]; + } + } + + return md; +} + +void DeleteMissile(int mi, int i) +{ + int id; + + if(missile[mi]._mitype == MIS_MANASHIELD) { + id = missile[mi]._misource; + if(id == myplr) { + NetSendCmd(TRUE, CMD_REMSHIELD); + } + plr[id].pManaShield = 0; + } + + /// ASSERT: assert((DWORD)nummissiles <= MAXMISSILES); + missileavail[MAXMISSILES - nummissiles] = mi; + nummissiles--; + if(nummissiles > 0 && i != nummissiles) { + /// ASSERT: assert((DWORD)i < MAXMISSILES); + missileactive[i] = missileactive[nummissiles]; + } +} + +void GetMissileVel(int i, int sx, int sy, int dx, int dy, int v) +{ + double dxp, dyp, dr; + + if(dx == sx && dy == sy) { + missile[i]._mixvel = 0; + missile[i]._miyvel = 0; + } else { + dxp = (((dx - sx) << 5) - ((dy - sy) << 5)) << 16; + dyp = (((dx - sx) << 5) + ((dy - sy) << 5)) << 16; + dr = sqrt(dyp * dyp + dxp * dxp); + /// ASSERT: assert((DWORD)i < MAXMISSILES); + missile[i]._mixvel = (dxp * (v << 16)) / dr; + missile[i]._miyvel = (dyp * (v << 15)) / dr; + } +} + +void PutMissile(int i) +{ + int mx, my; + + /// ASSERT: assert((DWORD)i < MAXMISSILES); + mx = missile[i]._mix; + my = missile[i]._miy; + if(mx <= 0 || my <= 0 || mx >= MAXDUNX || my >= MAXDUNY) { + missile[i]._miDelFlag = 1; + } + + if(!missile[i]._miDelFlag) { + dFlags[mx][my] |= 1; + if(dMissile[mx][my] == 0) { + dMissile[mx][my] = i + 1; + } else { + dMissile[mx][my] = -1; + } + if(missile[i]._miPreFlag) { + MissilePreFlag = 1; + } + } +} + +void GetMissilePos(int i) +{ + long mx, my, dx, dy, lx, ly; + + /// ASSERT: assert((DWORD)i < MAXMISSILES); + mx = missile[i]._mitxoff >> 16; + my = missile[i]._mityoff >> 16; + dx = 2 * my + mx; + dy = 2 * my - mx; + + if(dx < 0) { + lx = -(-dx >> 3); + dx = -(-dx >> 6); + } else { + lx = dx >> 3; + dx = dx >> 6; + } + if(dy < 0) { + ly = -(-dy >> 3); + dy = -(-dy >> 6); + } else { + ly = dy >> 3; + dy = dy >> 6; + } + + missile[i]._mix = dx + missile[i]._misx; + missile[i]._miy = dy + missile[i]._misy; + missile[i]._mixoff = mx - ((dx - dy) << 5); + missile[i]._miyoff = my - ((dx + dy) << 4); + ChangeLightOff(missile[i]._mlid, lx - (dx << 3), ly - (dy << 3)); +} + +void MoveMissilePos(int i) +{ + int dx, dy, mx, my; + + /// ASSERT: assert((DWORD)i < MAXMISSILES); + switch(missile[i]._mimfnum) { + case 0: + dx = 1; + dy = 1; + break; + case 1: + dx = 1; + dy = 1; + break; + case 2: + dx = 0; + dy = 1; + break; + case 3: + dx = 0; + dy = 0; + break; + case 4: + dx = 0; + dy = 0; + break; + case 5: + dx = 0; + dy = 0; + break; + case 6: + dx = 1; + dy = 0; + break; + case 7: + dx = 1; + dy = 1; + break; + } + + mx = dx + missile[i]._mix; + my = dy + missile[i]._miy; + if(PosOkMonst(missile[i]._misource, mx, my)) { + missile[i]._mix += dx; + missile[i]._miy += dy; + missile[i]._mixoff -= (dx - dy) << 5; + missile[i]._miyoff -= (dx + dy) << 4; + } +} + +BOOL MonsterTrapHit(int m, int mindam, int maxdam, int dist, int t, BOOLEAN shift) +{ + int hit, hper, mor, mir; + long dam; + BOOL resist, ret; + + resist = FALSE; + + /// ASSERT: assert((DWORD)m < MAXMONSTERS); + if(monster[m].mtalkmsg != 0) { + return FALSE; + } + if(monster[m]._mhitpoints >> 6 <= 0) { + return FALSE; + } + /// ASSERT: assert(monster[m].MType != NULL); + if(monster[m].MType->mtype == MT_ILLWEAV && monster[m]._mgoal == 2) { + return FALSE; + } + if(monster[m]._mmode == MM_CHARGE) { + return FALSE; + } + + mir = missiledata[t].mResist; + mor = monster[m].mMagicRes; + if(mor & 8 && mir == 3 || mor & 0x10 && mir == 1 || mor & 0x20 && mir == 2) { + return FALSE; + } + if(mor & 1 && mir == 3 || mor & 2 && mir == 1 || mor & 4 && mir == 2) { + resist = TRUE; + } + + hit = random(68, 100); + hper = 90 - (BYTE)monster[m].mArmorClass - dist; + if(hper < 5) { + hper = 5; + } + if(hper > 95) { + hper = 95; + } + + if(CheckMonsterHit(m, ret)) { + return ret; + } +#ifdef _DEBUG + else if(hit < hper || debug_mode_dollar_sign || debug_mode_key_inverted_v || monster[m]._mmode == MM_STONE) { +#else + else if(hit < hper || monster[m]._mmode == MM_STONE) { +#endif + dam = random(68, maxdam - mindam + 1) + mindam; + if(!shift) { + dam <<= 6; + } + if(resist) { + monster[m]._mhitpoints -= dam >> 2; + } else { + monster[m]._mhitpoints -= dam; + } +#ifdef _DEBUG + if(debug_mode_dollar_sign || debug_mode_key_inverted_v) { + monster[m]._mhitpoints = 0; + } +#endif + if(monster[m]._mhitpoints >> 6 <= 0) { + if(monster[m]._mmode == MM_STONE) { + M_StartKill(m, -1); + monster[m]._mmode = MM_STONE; + } else { + M_StartKill(m, -1); + } + } else { + if(resist) { + PlayEffect(m, 1); + } else if(monster[m]._mmode == MM_STONE) { + if(m > 3) { + M_StartHit(m, -1, dam); + } + monster[m]._mmode = MM_STONE; + } else { + if(m > 3) { + M_StartHit(m, -1, dam); + } + } + } + return TRUE; + } else { + return FALSE; + } +} + +BOOL MonsterMHit(int pnum, int m, int mindam, int maxdam, int dist, int t, BOOLEAN shift) +{ + int hit, hper, mor, mir; + long dam; + BOOL resist, ret; + + resist = FALSE; + + /// ASSERT: assert((DWORD)m < MAXMONSTERS); + if(monster[m].mtalkmsg != 0) { + return FALSE; + } + if(monster[m]._mhitpoints >> 6 <= 0) { + return FALSE; + } + /// ASSERT: assert(monster[m].MData != NULL); + if(t == MIS_HBOLT && monster[m].MType->mtype != MT_DIABLO && monster[m].MData->mMonstClass != MC_UNDEAD) { + return FALSE; + } + /// ASSERT: assert(monster[m].MType != NULL); + if(monster[m].MType->mtype == MT_ILLWEAV && monster[m]._mgoal == 2) { + return FALSE; + } + if(monster[m]._mmode == MM_CHARGE) { + return FALSE; + } + + mir = missiledata[t].mResist; + mor = monster[m].mMagicRes; + if(mor & 8 && mir == 3 || mor & 0x10 && mir == 1 || mor & 0x20 && mir == 2 || mor & 0x80 && mir == 4) { + return FALSE; + } + if(mor & 1 && mir == 3 || mor & 2 && mir == 1 || mor & 4 && mir == 2) { + resist = TRUE; + } + + hit = random(69, 100); + if(missiledata[t].mType == 0) { + hper = plr[pnum]._pLevel + 50 - (BYTE)monster[m].mArmorClass + plr[pnum]._pIEnAc; + hper += plr[pnum]._pIBonusToHit + plr[pnum]._pDexterity; + hper -= dist * dist >> 1; + if(plr[pnum]._pClass == PC_ROGUE) { + hper += 20; + } + if(plr[pnum]._pClass == PC_WARRIOR) { + hper += 10; + } + } else { + hper = plr[pnum]._pMagic + 50 - (monster[m].mLevel << 1) - dist; + if(plr[pnum]._pClass == PC_SORCERER) { + hper += 20; + } + } + if(hper < 5) { + hper = 5; + } + if(hper > 95) { + hper = 95; + } + if(monster[m]._mmode == MM_STONE) { + hit = 0; + } + + if(CheckMonsterHit(m, ret)) { + return ret; + } +#ifdef _DEBUG + else if(hit < hper || debug_mode_key_inverted_v || debug_mode_dollar_sign) { +#else + else if(hit < hper) { +#endif + if(t == MIS_BONESPIRIT) { + dam = monster[m]._mhitpoints / 3 >> 6; + } else { + dam = random(70, maxdam - mindam + 1) + mindam; + } + if(missiledata[t].mType == 0) { + dam += plr[pnum]._pIBonusDamMod + dam * plr[pnum]._pIBonusDam / 100; + if(plr[pnum]._pClass == PC_ROGUE) { + dam += plr[pnum]._pDamageMod; + } else { + dam += plr[pnum]._pDamageMod >> 1; + } + } + if(!shift) { + dam <<= 6; + } + if(resist) { + dam >>= 2; + } + if(pnum == myplr) { + monster[m]._mhitpoints -= dam; + } + if(plr[pnum]._pIFlags & ISPL_FIRE_ARROWS) { + monster[m]._mFlags |= 8; + } + if(monster[m]._mhitpoints >> 6 <= 0) { + if(monster[m]._mmode == MM_STONE) { + M_StartKill(m, pnum); + monster[m]._mmode = MM_STONE; + } else { + M_StartKill(m, pnum); + } + } else { + if(resist) { + PlayEffect(m, 1); + } else if(monster[m]._mmode == MM_STONE) { + if(m > 3) { + M_StartHit(m, pnum, dam); + } + monster[m]._mmode = MM_STONE; + } else { + if(missiledata[t].mType == 0 && plr[pnum]._pIFlags & ISPL_KNOCKBACK) { + M_GetKnockback(m); + } + if(m > 3) { + M_StartHit(m, pnum, dam); + } + } + } + if(monster[m]._msquelch == 0) { + monster[m]._msquelch = 255; + monster[m]._lastx = plr[pnum].WorldX; + monster[m]._lasty = plr[pnum].WorldY; + } + return TRUE; + } else { + return FALSE; + } +} + +BOOL PlayerMHit(int pnum, int m, int dist, int mind, int maxd, int mtype, BOOLEAN shift, int earflag) +{ + int hit, hper, tac, blk, blkper, blkdir, resper; + long dam; + + /// ASSERT: assert((DWORD)pnum < MAX_PLRS); + if(plr[pnum]._pHitPoints >> 6 <= 0) { + return FALSE; + } + if(plr[pnum]._pInvincible) { + return FALSE; + } + if(plr[pnum]._pSpellFlags & 1 && missiledata[mtype].mType == 0) { + return FALSE; + } + + hit = random(72, 100); +#ifdef _DEBUG + if(debug_mode_dollar_sign || debug_mode_key_inverted_v) { + hit = 1000; + } +#endif + + if(missiledata[mtype].mType == 0) { + tac = plr[pnum]._pIAC + plr[pnum]._pIBonusAC + plr[pnum]._pDexterity / 5; + if(m != -1) { + hper = monster[m].mHit + 30 + ((monster[m].mLevel - plr[pnum]._pLevel) << 1) - tac; + hper -= dist << 1; + } else { + hper = 100 - (tac >> 1); + hper -= dist << 1; + } + } else { + if(m != -1) { + hper = 40 + (monster[m].mLevel << 1) - (plr[pnum]._pLevel << 1); + hper -= dist << 1; + } else { + hper = 40; + } + } + + if(hper < 10) { + hper = 10; + } + if(currlevel == 14 && hper < 20) { + hper = 20; + } + if(currlevel == 15 && hper < 25) { + hper = 25; + } + if(currlevel == 16 && hper < 30) { + hper = 30; + } + + if((plr[pnum]._pmode == PM_STAND || plr[pnum]._pmode == PM_ATTACK) && plr[pnum]._pBlockFlag) { + blk = random(73, 100); + } else { + blk = 100; + } + if(shift == TRUE) { + blk = 100; + } + if(mtype == MIS_ACIDPUD) { + blk = 100; + } + + if(m != -1) { + blkper = plr[pnum]._pBaseToBlk + plr[pnum]._pDexterity - ((monster[m].mLevel - plr[pnum]._pLevel) << 1); + } else { + blkper = plr[pnum]._pBaseToBlk + plr[pnum]._pDexterity; + } + if(blkper < 0) { + blkper = 0; + } + if(blkper > 100) { + blkper = 100; + } + + switch(missiledata[mtype].mResist) { + case 1: + resper = plr[pnum]._pFireResist; + break; + case 2: + resper = plr[pnum]._pLghtResist; + break; + case 3: + case 4: + resper = plr[pnum]._pMagResist; + break; + default: + resper = 0; + break; + } + + if(hit < hper) { + if(mtype == MIS_BONESPIRIT) { + dam = plr[pnum]._pHitPoints / 3; + } else { + if(!shift) { + dam = random(75, (maxd - mind + 1) << 6) + (mind << 6); + if(m == -1 && plr[pnum]._pIFlags & ISPL_ABSHALFTRAP) { + dam >>= 1; + } + dam += plr[pnum]._pIGetHit << 6; + if(dam < 64) { + dam = 64; + } + } else { + dam = random(75, maxd - mind + 1) + mind; + if(m == -1 && plr[pnum]._pIFlags & ISPL_ABSHALFTRAP) { + dam >>= 1; + } + dam += plr[pnum]._pIGetHit; + if(dam < 64) { + dam = 64; + } + } + } + if(resper > 0) { + dam -= resper * dam / 100; + if(pnum == myplr) { + plr[pnum]._pHitPoints -= dam; + plr[pnum]._pHPBase -= dam; + } + if(plr[pnum]._pHitPoints > plr[pnum]._pMaxHP) { + plr[pnum]._pHitPoints = plr[pnum]._pMaxHP; + plr[pnum]._pHPBase = plr[pnum]._pMaxHPBase; + } + if(plr[pnum]._pHitPoints >> 6 <= 0) { + SyncPlrKill(pnum, earflag); + } else { + if(plr[pnum]._pClass == PC_WARRIOR) { + PlaySfxLoc(PS_WARR69, plr[pnum].WorldX, plr[pnum].WorldY); + } 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); + } + drawhpflag = 1; + } + return TRUE; + } else if(blk < blkper) { + if(m != -1) { + blkdir = GetDirection(plr[pnum].WorldX, plr[pnum].WorldY, monster[m]._mx, monster[m]._my); + } else { + blkdir = plr[pnum]._pdir; + } + StartPlrBlock(pnum, blkdir); + return TRUE; + } else { + if(pnum == myplr) { + plr[pnum]._pHitPoints -= dam; + plr[pnum]._pHPBase -= dam; + } + if(plr[pnum]._pHitPoints > plr[pnum]._pMaxHP) { + plr[pnum]._pHitPoints = plr[pnum]._pMaxHP; + plr[pnum]._pHPBase = plr[pnum]._pMaxHPBase; + } + if(plr[pnum]._pHitPoints >> 6 <= 0) { + SyncPlrKill(pnum, earflag); + } else { + StartPlrHit(pnum, dam, FALSE); + } + return TRUE; + } + } + + return FALSE; +} + +BOOL Plr2PlrMHit(int pnum, int p, int mindam, int maxdam, int dist, int mtype, BOOLEAN shift) +{ + int hit, hper, tac, blk, blkper, blkdir, resper; + long dam; + + /// ASSERT: assert((DWORD)p < MAX_PLRS); + if(plr[p]._pInvincible) { + return FALSE; + } + if(mtype == MIS_HBOLT) { + return FALSE; + } + if(plr[p]._pSpellFlags & 1 && missiledata[mtype].mType == 0) { + return FALSE; + } + + switch(missiledata[mtype].mResist) { + case 1: + resper = plr[p]._pFireResist; + break; + case 2: + resper = plr[p]._pLghtResist; + break; + case 3: + case 4: + resper = plr[p]._pMagResist; + break; + default: + resper = 0; + break; + } + + hit = random(69, 100); + + if(missiledata[mtype].mType == 0) { + tac = plr[p]._pIAC + plr[p]._pIBonusAC + plr[p]._pDexterity / 5; + hper = plr[pnum]._pLevel + 50 - tac; + hper += plr[pnum]._pIBonusToHit + plr[pnum]._pDexterity; + hper -= dist * dist >> 1; + if(plr[pnum]._pClass == PC_ROGUE) { + hper += 20; + } + if(plr[pnum]._pClass == PC_WARRIOR) { + hper += 10; + } + } else { + hper = plr[pnum]._pMagic + 50 - (plr[p]._pLevel << 1) - dist; + if(plr[pnum]._pClass == PC_SORCERER) { + hper += 20; + } + } + + if(hper < 5) { + hper = 5; + } + if(hper > 95) { + hper = 95; + } + + if(hit < hper) { + if((plr[p]._pmode == PM_STAND || plr[p]._pmode == PM_ATTACK) && plr[p]._pBlockFlag) { + blk = random(73, 100); + } else { + blk = 100; + } + if(shift == TRUE) { + blk = 100; + } + blkper = plr[p]._pDexterity + plr[p]._pBaseToBlk - ((plr[pnum]._pLevel - plr[p]._pLevel) << 1); + if(blkper < 0) { + blkper = 0; + } + if(blkper > 100) { + blkper = 100; + } + if(mtype == MIS_BONESPIRIT) { + dam = plr[p]._pHitPoints / 3; + } else { + dam = random(70, maxdam - mindam + 1) + mindam; + if(missiledata[mtype].mType == 0) { + dam += plr[pnum]._pDamageMod + plr[pnum]._pIBonusDamMod + dam * plr[pnum]._pIBonusDam / 100; + } + if(!shift) { + dam <<= 6; + } + } + if(missiledata[mtype].mType != 0) { + dam >>= 1; + } + if(resper > 0) { + dam -= resper * dam / 100; + if(pnum == myplr) { + NetSendCmdDamage(TRUE, p, dam); + } + if(plr[pnum]._pClass == PC_WARRIOR) { + PlaySfxLoc(PS_WARR69, plr[pnum].WorldX, plr[pnum].WorldY); + } 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); + } + return TRUE; + } else if(blk < blkper) { + blkdir = GetDirection(plr[p].WorldX, plr[p].WorldY, plr[pnum].WorldX, plr[pnum].WorldY); + StartPlrBlock(p, blkdir); + return TRUE; + } else { + if(pnum == myplr) { + NetSendCmdDamage(TRUE, p, dam); + } + StartPlrHit(p, dam, FALSE); + return TRUE; + } + } + + return FALSE; +} + +void CheckMissileCol(int i, int mindam, int maxdam, BOOLEAN shift, int mx, int my, BOOLEAN nodel) +{ + int pn, oi; + + /// ASSERT: assert((DWORD)i < MAXMISSILES); + /// ASSERT: assert((DWORD)mx < MAXDUNX); + /// ASSERT: assert((DWORD)my < MAXDUNY); + + if(missile[i]._miAnimType == 4 || missile[i]._misource == -1) { + if(dMonster[mx][my] > 0) { + if(missile[i]._miAnimType == 4) { + if(MonsterMHit(missile[i]._misource, dMonster[mx][my] - 1, mindam, maxdam, missile[i]._midist, missile[i]._mitype, shift)) { + if(!nodel) { + missile[i]._mirange = 0; + } + missile[i]._miHitFlag = 1; + } + } else { + if(MonsterTrapHit(dMonster[mx][my] - 1, mindam, maxdam, missile[i]._midist, missile[i]._mitype, shift)) { + if(!nodel) { + missile[i]._mirange = 0; + } + missile[i]._miHitFlag = 1; + } + } + } + if(dPlayer[mx][my] > 0) { + if(PlayerMHit(dPlayer[mx][my] - 1, -1, missile[i]._midist, mindam, maxdam, missile[i]._mitype, shift, missile[i]._miAnimType == 4)) { + if(!nodel) { + missile[i]._mirange = 0; + } + missile[i]._miHitFlag = 1; + } + } + } else { + if(missile[i]._micaster == 0) { + if(dMonster[mx][my] > 0) { + if(MonsterMHit(missile[i]._misource, dMonster[mx][my] - 1, mindam, maxdam, missile[i]._midist, missile[i]._mitype, shift)) { + if(!nodel) { + missile[i]._mirange = 0; + } + missile[i]._miHitFlag = 1; + } + } else if(dMonster[mx][my] < 0 && monster[-(dMonster[mx][my] + 1)]._mmode == MM_STONE) { + if(MonsterMHit(missile[i]._misource, -(dMonster[mx][my] + 1), mindam, maxdam, missile[i]._midist, missile[i]._mitype, shift)) { + if(!nodel) { + missile[i]._mirange = 0; + } + missile[i]._miHitFlag = 1; + } + } + if(dPlayer[mx][my] > 0 && dPlayer[mx][my] - 1 != missile[i]._misource) { + if(Plr2PlrMHit(missile[i]._misource, dPlayer[mx][my] - 1, mindam, maxdam, missile[i]._midist, missile[i]._mitype, shift)) { + if(!nodel) { + missile[i]._mirange = 0; + } + missile[i]._miHitFlag = 1; + } + } + } else { + if(monster[missile[i]._misource]._mFlags & 0x10 && dMonster[mx][my] > 0 && monster[dMonster[mx][my] - 1]._mFlags & 0x20) { + if(MonsterTrapHit(dMonster[mx][my] - 1, mindam, maxdam, missile[i]._midist, missile[i]._mitype, shift)) { + if(!nodel) { + missile[i]._mirange = 0; + } + missile[i]._miHitFlag = 1; + } + } + if(dPlayer[mx][my] > 0) { + if(PlayerMHit(dPlayer[mx][my] - 1, missile[i]._misource, missile[i]._midist, mindam, maxdam, missile[i]._mitype, shift, 0)) { + if(!nodel) { + missile[i]._mirange = 0; + } + missile[i]._miHitFlag = 1; + } + } + } + } + + if(dObject[mx][my] != 0) { + oi = dObject[mx][my] > 0 ? dObject[mx][my] - 1 : -(dObject[mx][my] + 1); + if(!object[oi]._oMissFlag) { + if(object[oi]._oBreak == 1) { + BreakObject(-1, oi); + } + if(!nodel) { + missile[i]._mirange = 0; + } + missile[i]._miHitFlag = 0; + } + } + + pn = dPiece[mx][my]; + /// ASSERT: assert((DWORD)pn <= MAXTILES); + if(nMissileTable[pn]) { + if(!nodel) { + missile[i]._mirange = 0; + } + missile[i]._miHitFlag = 0; + } + + if(missile[i]._mirange == 0 && missiledata[missile[i]._mitype].miSFX != -1) { + PlaySfxLoc(missiledata[missile[i]._mitype].miSFX, missile[i]._mix, missile[i]._miy); + } +} + +void SetMissAnim(int mi, int animtype) +{ + int dir; + + /// ASSERT: assert((DWORD)mi < MAXMISSILES); + dir = missile[mi]._mimfnum; + missile[mi]._miAnimType = animtype; + missile[mi]._miAnimFlags = misfiledata[animtype].mFlags; + missile[mi]._miAnimData = misfiledata[animtype].mAnimData[dir]; + missile[mi]._miAnimDelay = misfiledata[animtype].mAnimDelay[dir]; + missile[mi]._miAnimLen = misfiledata[animtype].mAnimLen[dir]; + missile[mi]._miAnimWidth = misfiledata[animtype].mAnimWidth[dir]; + missile[mi]._miAnimWidth2 = misfiledata[animtype].mAnimWidth2[dir]; + missile[mi]._miAnimCnt = 0; + missile[mi]._miAnimFrame = 1; +} + +void SetMissDir(int mi, int dir) +{ + /// ASSERT: assert((DWORD)mi < MAXMISSILES); + missile[mi]._mimfnum = dir; + SetMissAnim(mi, missile[mi]._miAnimType); +} + +void LoadMissileGFX(BYTE mi) +{ + int i; + BYTE *p; + MisFileData *m; + char filestr[256]; + + m = &misfiledata[mi]; + + if(m->mFlags & 4) { + sprintf(filestr, "Missiles\\%s.CL2", m->mName); + p = DiabLoad(filestr, NULL, 'MISS'); + for(i = 0; i < m->mAnimFAmt; i++) { + m->mAnimData[i] = &p[((DWORD *)p)[i]]; + } + } else if(m->mAnimFAmt == 1) { + sprintf(filestr, "Missiles\\%s.CL2", m->mName); + if(m->mAnimData[0] == NULL) { + m->mAnimData[0] = DiabLoad(filestr, NULL, 'MISS'); + } + } else { + for(i = 0; i < m->mAnimFAmt; i++) { + sprintf(filestr, "Missiles\\%s%i.CL2", m->mName, i + 1); + if(m->mAnimData[i] == NULL) { + m->mAnimData[i] = DiabLoad(filestr, NULL, 'MISS'); + } + } + } +} + +void InitMissileGFX() +{ + int i; + + for(i = 0; misfiledata[i].mAnimFAmt != 0; i++) { + if(!(misfiledata[i].mFlags & 1)) { + LoadMissileGFX(i); + } + } +} + +void FreeMissileGFX(int mi) +{ + int i; + DWORD *p; + + if(misfiledata[mi].mFlags & 4) { + if(misfiledata[mi].mAnimData[0] != NULL) { + p = (DWORD *)misfiledata[mi].mAnimData[0]; + p -= misfiledata[mi].mAnimFAmt; + MemFreeDbg(p); + misfiledata[mi].mAnimData[0] = NULL; + } + } else { + for(i = 0; i < misfiledata[mi].mAnimFAmt; i++) { + if(misfiledata[mi].mAnimData[i] != NULL) { + MemFreeDbg(misfiledata[mi].mAnimData[i]); + } + } + } +} + +void FreeMissiles() +{ + int i; + + for(i = 0; misfiledata[i].mAnimFAmt != 0; i++) { + if(!(misfiledata[i].mFlags & 1)) { + FreeMissileGFX(i); + } + } +} + +void FreeMissiles2() +{ + int i; + + for(i = 0; misfiledata[i].mAnimFAmt != 0; i++) { + if(misfiledata[i].mFlags & 1) { + FreeMissileGFX(i); + } + } +} + +void InitMissiles() +{ + int i, j, mx; + + plr[myplr]._pSpellFlags &= ~1; + + if(plr[myplr]._pInfraFlag == 1) { + /// ASSERT: assert((DWORD)nummissiles <= MAXMISSILES); + for(i = 0; i < nummissiles; i++) { + mx = missileactive[i]; + /// ASSERT: assert((DWORD)mx < MAXMISSILES); + if(missile[mx]._mitype == MIS_INFRA && missile[mx]._misource == myplr) { + CalcPlrItemVals(missile[mx]._misource, TRUE); + } + } + } + + nummissiles = 0; + for(i = 0; i < MAXMISSILES; i++) { + missileavail[i] = i; + missileactive[i] = 0; + } + + numchains = 0; + for(i = 0; i < MAXMISSILES; i++) { + chain[i].idx = -1; + chain[i]._mitype = 0; + chain[i]._mirange = 0; + } + + for(j = 0; j < MAXDUNY; j++) { + for(i = 0; i < MAXDUNX; i++) { + dFlags[i][j] &= ~1; + } + } +} + +void AddLArrow(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + if(sx == dx && sy == dy) { + dx += XDirAdd[midir]; + dy += YDirAdd[midir]; + } + + if(mienemy == 0) { + if(plr[id]._pClass == PC_ROGUE) { + GetMissileVel(mi, sx, sy, dx, dy, (plr[id]._pLevel >> 2) + 31); + } else if(plr[id]._pClass == PC_WARRIOR) { + GetMissileVel(mi, sx, sy, dx, dy, (plr[id]._pLevel >> 3) + 31); + } else { + GetMissileVel(mi, sx, sy, dx, dy, 32); + } + } else { + GetMissileVel(mi, sx, sy, dx, dy, 32); + } + + SetMissDir(mi, GetDirection16(sx, sy, dx, dy)); + /// ASSERT: assert((DWORD)mi < MAXMISSILES); + missile[mi]._mirange = 256; + missile[mi]._miVar1 = sx; + missile[mi]._miVar2 = sy; + missile[mi]._mlid = AddLight(sx, sy, 5); +} + +void AddArrow(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + int av; + + if(sx == dx && sy == dy) { + dx += XDirAdd[midir]; + dy += YDirAdd[midir]; + } + + if(mienemy == 0) { + av = 32; + if(plr[id]._pIFlags & ISPL_RNDARROWVEL) { + av = random(64, 32) + 16; + } + if(plr[id]._pClass == PC_ROGUE) { + av += (plr[id]._pLevel - 1) >> 2; + } + if(plr[id]._pClass == PC_WARRIOR) { + av += (plr[id]._pLevel - 1) >> 3; + } + GetMissileVel(mi, sx, sy, dx, dy, av); + } else { + GetMissileVel(mi, sx, sy, dx, dy, 32); + } + + /// ASSERT: assert((DWORD)mi < MAXMISSILES); + missile[mi]._miAnimFrame = GetDirection16(sx, sy, dx, dy) + 1; + missile[mi]._mirange = 256; +} + +void GetVileMissPos(int mi, int dx, int dy) +{ + int xx, yy, i, j, l; + + /// ASSERT: assert((DWORD)mi < MAXMISSILES); + + for(l = 1; l < 50; l++) { + for(j = -l; j <= l; j++) { + yy = j + dy; + for(i = -l; i <= l; i++) { + xx = i + dx; + if(PosOkPlayer(myplr, xx, yy)) { + missile[mi]._mix = xx; + missile[mi]._miy = yy; + return; + } + } + } + } + + missile[mi]._mix = dx; + missile[mi]._miy = dy; +} + +void AddRndTeleport(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + int pn, r1, r2, nTries, oi; + BOOL dirok; + + dirok = FALSE; + nTries = 0; + while(1) { + nTries++; + if(nTries > 500) { + break; + } + r1 = random(58, 3) + 4; + r2 = random(58, 3) + 4; + if(random(58, 2) == 1) { + r1 = -r1; + } + if(random(58, 2) == 1) { + r2 = -r2; + } + pn = dPiece[r1 + sx][r2 + sy]; + if(!nSolidTable[pn] && dObject[r1 + sx][r2 + sy] == 0 && dMonster[r1 + sx][r2 + sy] == 0) { + dirok = TRUE; + break; + } + } + if(!dirok) { + r1 = 0; + r2 = 0; + } + + /// ASSERT: assert((DWORD)mi < MAXMISSILES); + missile[mi]._mirange = 2; + missile[mi]._miVar1 = 0; + + if(setlevel && setlvlnum == SL_VILEBETRAYER) { + oi = dObject[dx][dy] - 1; + if(object[oi]._otype == OBJ_MCIRCLE1 || object[oi]._otype == OBJ_MCIRCLE2) { + missile[mi]._mix = dx; + missile[mi]._miy = dy; + if(!PosOkPlayer(myplr, dx, dy)) { + GetVileMissPos(mi, dx, dy); + } + } + } else { + missile[mi]._mix = sx + r1; + missile[mi]._miy = sy + r2; + if(mienemy == 0) { + UseMana(id, SPL_RNDTELEPORT); + } + } +} + +void AddFirebolt(int mi, int sx, int sy, int dx, int dy, int midir, char micaster, int id, int dam) +{ + int sp, i, mx; + + if(sx == dx && sy == dy) { + dx += XDirAdd[midir]; + dy += YDirAdd[midir]; + } + + /// ASSERT: assert((DWORD)mi < MAXMISSILES); + if(micaster == 0) { + /// ASSERT: assert((DWORD)nummissiles <= MAXMISSILES); + for(i = 0; i < nummissiles; i++) { + mx = missileactive[i]; + /// ASSERT: assert((DWORD)mx < MAXMISSILES); + if(missile[mx]._mitype == MIS_GUARDIAN && missile[mx]._misource == id && missile[mx]._miVar3 == mi) { + break; + } + } + if(i == nummissiles) { + UseMana(id, SPL_FIREBOLT); + } + if(id != -1) { + sp = 2 * missile[mi]._mispllvl + 16; + if(sp >= 63) { + sp = 63; + } + } else { + sp = 16; + } + } else { + sp = 26; + } + + GetMissileVel(mi, sx, sy, dx, dy, sp); + SetMissDir(mi, GetDirection16(sx, sy, dx, dy)); + missile[mi]._mirange = 256; + missile[mi]._miVar1 = sx; + missile[mi]._miVar2 = sy; + missile[mi]._mlid = AddLight(sx, sy, 8); +} + +void AddMagmaball(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + GetMissileVel(mi, sx, sy, dx, dy, 16); + /// ASSERT: assert((DWORD)mi < MAXMISSILES); + missile[mi]._mitxoff += 3 * missile[mi]._mixvel; + missile[mi]._mityoff += 3 * missile[mi]._miyvel; + GetMissilePos(mi); + missile[mi]._mirange = 256; + missile[mi]._miVar1 = sx; + missile[mi]._miVar2 = sy; + missile[mi]._mlid = AddLight(sx, sy, 8); +} + +void miss_null_33(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + GetMissileVel(mi, sx, sy, dx, dy, 16); + /// ASSERT: assert((DWORD)mi < MAXMISSILES); + missile[mi]._mirange = 256; + missile[mi]._miVar1 = sx; + missile[mi]._miVar2 = sy; + PutMissile(mi); +} + +void AddTeleport(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + int i, pn, k, l, j, tx, ty; + int CrawlNum[6] = { 0, 3, 12, 45, 94, 159 }; + + /// ASSERT: assert((DWORD)dx < MAXDUNX); + /// ASSERT: assert((DWORD)dy < MAXDUNY); + /// ASSERT: assert((DWORD)mi < MAXMISSILES); + missile[mi]._miDelFlag = 1; + + for(j = 0; j < 6; j++) { + k = CrawlNum[j]; + l = k + 1; + for(i = (BYTE)CrawlTable[k]; i > 0; i--) { + tx = dx + CrawlTable[l]; + ty = dy + CrawlTable[l + 1]; + if(tx > 0 && tx < MAXDUNX && ty > 0 && ty < MAXDUNY) { + pn = dPiece[tx][ty]; + if(!(dMonster[tx][ty] | dObject[tx][ty] | dPlayer[tx][ty] | nSolidTable[pn])) { + missile[mi]._mix = tx; + missile[mi]._miy = ty; + missile[mi]._misx = tx; + missile[mi]._misy = ty; + missile[mi]._miDelFlag = 0; + j = 6; + break; + } + } + l += 2; + } + } + + if(!missile[mi]._miDelFlag) { + UseMana(id, SPL_TELEPORT); + missile[mi]._mirange = 2; + } +} + +void AddLightball(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + GetMissileVel(mi, sx, sy, dx, dy, 16); + /// ASSERT: assert((DWORD)mi < MAXMISSILES); + missile[mi]._midam = dam; + missile[mi]._miAnimFrame = random(63, 8) + 1; + missile[mi]._mirange = 255; + + if(id < 0) { + missile[mi]._miVar1 = sx; + missile[mi]._miVar2 = sy; + } else { + missile[mi]._miVar1 = plr[id].WorldX; + missile[mi]._miVar2 = plr[id].WorldY; + } +} + +void AddFirewall(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + int i; + + /// ASSERT: assert((DWORD)mi < MAXMISSILES); + missile[mi]._midam = 16 * (random(53, 10) + random(53, 10) + plr[id]._pLevel + 2); + missile[mi]._midam >>= 1; + GetMissileVel(mi, sx, sy, dx, dy, 16); + missile[mi]._mirange = 10; + for(i = missile[mi]._mispllvl; i > 0; i--) { + missile[mi]._mirange += 10; + } + missile[mi]._mirange += missile[mi]._mirange * plr[id]._pISplDur >> 7; + missile[mi]._mirange <<= 4; + missile[mi]._miVar1 = missile[mi]._mirange - missile[mi]._miAnimLen; + missile[mi]._miVar2 = 0; +} + +void AddFireball(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + int i; + + if(sx == dx && sy == dy) { + dx += XDirAdd[midir]; + dy += YDirAdd[midir]; + } + + /// ASSERT: assert((DWORD)mi < MAXMISSILES); + if(mienemy == 0) { + missile[mi]._midam = 2 * (random(60, 10) + random(60, 10) + plr[id]._pLevel + 2); + for(i = missile[mi]._mispllvl; i > 0; i--) { + missile[mi]._midam += missile[mi]._midam >> 3; + } + i = 2 * missile[mi]._mispllvl + 16; + if(i > 50) { + i = 50; + } + UseMana(id, SPL_FIREBALL); + } else { + i = 16; + } + + GetMissileVel(mi, sx, sy, dx, dy, i); + SetMissDir(mi, GetDirection16(sx, sy, dx, dy)); + missile[mi]._mirange = 256; + missile[mi]._miVar1 = sx; + missile[mi]._miVar2 = sy; + missile[mi]._miVar3 = 0; + missile[mi]._miVar4 = sx; + missile[mi]._miVar5 = sy; + missile[mi]._mlid = AddLight(sx, sy, 8); +} + +void AddLightctrl(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + if(dam == 0 && mienemy == 0) { + UseMana(id, SPL_LIGHTNING); + } + + /// ASSERT: assert((DWORD)mi < MAXMISSILES); + missile[mi]._miVar1 = sx; + missile[mi]._miVar2 = sy; + GetMissileVel(mi, sx, sy, dx, dy, 32); + missile[mi]._miAnimFrame = random(52, 8) + 1; + missile[mi]._mirange = 256; +} + +void AddLightning(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + /// ASSERT: assert((DWORD)mi < MAXMISSILES); + missile[mi]._misx = dx; + missile[mi]._misy = dy; + + if(midir >= 0) { + missile[mi]._mixoff = missile[midir]._mixoff; + missile[mi]._miyoff = missile[midir]._miyoff; + missile[mi]._mitxoff = missile[midir]._mitxoff; + missile[mi]._mityoff = missile[midir]._mityoff; + } + + missile[mi]._miAnimFrame = random(52, 8) + 1; + + if(midir >= 0 && mienemy != 1 && id != -1) { + missile[mi]._mirange = (missile[mi]._mispllvl >> 1) + 6; + } else if(midir >= 0 && id != -1) { + missile[mi]._mirange = 10; + } else { + missile[mi]._mirange = 8; + } + + missile[mi]._mlid = AddLight(missile[mi]._mix, missile[mi]._miy, 4); +} + +void AddMisexp(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + if(mienemy != 0 && id > 0) { + /// ASSERT: assert((DWORD)id < MAXMONSTERS); + /// ASSERT: assert(monster[id].MType != NULL); + if(monster[id].MType->mtype == MT_SUCCUBUS) { + SetMissAnim(mi, MFILE_FLAREEXP); + } + if(monster[id].MType->mtype == MT_SNOWWICH) { + SetMissAnim(mi, MFILE_SCBSEXPB); + } + if(monster[id].MType->mtype == MT_HLSPWN) { + SetMissAnim(mi, MFILE_SCBSEXPD); + } + if(monster[id].MType->mtype == MT_SOLBRNR) { + SetMissAnim(mi, MFILE_SCBSEXPC); + } + } + + /// ASSERT: assert((DWORD)mi < MAXMISSILES); + missile[mi]._mix = missile[dx]._mix; + missile[mi]._miy = missile[dx]._miy; + missile[mi]._misx = missile[dx]._misx; + missile[mi]._misy = missile[dx]._misy; + missile[mi]._mixoff = missile[dx]._mixoff; + missile[mi]._miyoff = missile[dx]._miyoff; + missile[mi]._mitxoff = missile[dx]._mitxoff; + missile[mi]._mityoff = missile[dx]._mityoff; + missile[mi]._mixvel = 0; + missile[mi]._miyvel = 0; + missile[mi]._mirange = missile[mi]._miAnimLen; + missile[mi]._miVar1 = 0; +} + +void AddWeapexp(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + /// ASSERT: assert((DWORD)mi < MAXMISSILES); + missile[mi]._mix = sx; + missile[mi]._miy = sy; + missile[mi]._misx = sx; + missile[mi]._misy = sy; + missile[mi]._mixvel = 0; + missile[mi]._miyvel = 0; + missile[mi]._miVar1 = 0; + missile[mi]._miVar2 = dx; + missile[mi]._mimfnum = 0; + + if(dx == 1) { + SetMissAnim(mi, MFILE_MAGBLOS); + } else { + SetMissAnim(mi, MFILE_MINILTNG); + } + + missile[mi]._mirange = missile[mi]._miAnimLen - 1; +} + +BOOL CheckIfTrig(int x, int y) +{ + int i; + + /// ASSERT: assert((DWORD)numtrigs <= MAXTRIGGERS); + for(i = 0; i < numtrigs; i++) { + if(x == trigs[i]._tx && y == trigs[i]._ty) { + return TRUE; + } + if(abs(trigs[i]._tx - x) < 2 && abs(trigs[i]._ty - y) < 2) { + return TRUE; + } + } + + return FALSE; +} + +void AddTown(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + int i, pn, k, l, j, tx, ty, mx; + int CrawlNum[6] = { 0, 3, 12, 45, 94, 159 }; + + /// ASSERT: assert((DWORD)mi < MAXMISSILES); + if(currlevel != 0) { + missile[mi]._miDelFlag = 1; + for(j = 0; j < 6; j++) { + k = CrawlNum[j]; + l = k + 1; + for(i = (BYTE)CrawlTable[k]; i > 0; i--) { + tx = dx + CrawlTable[l]; + ty = dy + CrawlTable[l + 1]; + if(tx > 0 && tx < MAXDUNX && ty > 0 && ty < MAXDUNY) { + pn = dPiece[tx][ty]; + /// ASSERT: assert((DWORD)pn <= MAXTILES); + if(!(dObject[tx][ty] | dPlayer[tx][ty] | dMissile[tx][ty] | nSolidTable[pn] | nMissileTable[pn])) { + if(!CheckIfTrig(tx, ty)) { + missile[mi]._mix = tx; + missile[mi]._miy = ty; + missile[mi]._misx = tx; + missile[mi]._misy = ty; + missile[mi]._miDelFlag = 0; + j = 6; + break; + } + } + } + l += 2; + } + } + } else { + tx = dx; + ty = dy; + missile[mi]._mix = tx; + missile[mi]._miy = ty; + missile[mi]._misx = tx; + missile[mi]._misy = ty; + missile[mi]._miDelFlag = 0; + } + + missile[mi]._mirange = 100; + missile[mi]._miVar1 = missile[mi]._mirange - missile[mi]._miAnimLen; + missile[mi]._miVar2 = 0; + + for(i = 0; i < nummissiles; i++) { + mx = missileactive[i]; + if(missile[mx]._mitype == MIS_TOWN && mx != mi && missile[mx]._misource == id) { + missile[mx]._mirange = 0; + } + } + + PutMissile(mi); + + if(id == myplr && !missile[mi]._miDelFlag && currlevel != 0) { + if(!setlevel) { + NetSendCmdLocParam3(TRUE, CMD_ACTIVATEPORTAL, tx, ty, currlevel, leveltype, 0); + } else { + NetSendCmdLocParam3(TRUE, CMD_ACTIVATEPORTAL, tx, ty, setlvlnum, leveltype, 1); + } + } +} + +void AddFlash(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + int i; + + /// ASSERT: assert((DWORD)mi < MAXMISSILES); + if(mienemy == 0) { + if(id != -1) { + missile[mi]._midam = 0; + for(i = 0; i <= plr[id]._pLevel; i++) { + missile[mi]._midam += random(55, 20) + 1; + } + for(i = missile[mi]._mispllvl; i > 0; i--) { + missile[mi]._midam += missile[mi]._midam >> 3; + } + missile[mi]._midam += missile[mi]._midam >> 1; + UseMana(id, SPL_FLASH); + } else { + missile[mi]._midam = currlevel >> 1; + } + } else { + missile[mi]._midam = 2 * monster[id].mLevel; + } + + missile[mi]._mirange = 19; +} + +void AddFlash2(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + int i; + + /// ASSERT: assert((DWORD)mi < MAXMISSILES); + if(mienemy == 0) { + if(id != -1) { + missile[mi]._midam = 0; /// BUGFIX: damage mechanics should be the same as 'AddFlash' above? + for(i = 0; i <= plr[id]._pLevel; i++) { + missile[mi]._midam += random(56, 2) + 1; + } + for(i = missile[mi]._mispllvl; i > 0; i--) { + missile[mi]._midam += missile[mi]._midam >> 3; + } + missile[mi]._midam += missile[mi]._midam >> 1; + } else { + missile[mi]._midam = currlevel >> 1; + } + } + + missile[mi]._miPreFlag = 1; + missile[mi]._mirange = 19; +} + +void AddManashield(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + /// ASSERT: assert((DWORD)mi < MAXMISSILES); + missile[mi]._mirange = 48 * plr[id]._pLevel; + missile[mi]._miVar1 = plr[id]._pHitPoints; + missile[mi]._miVar2 = plr[id]._pHPBase; + missile[mi]._miVar8 = -1; + + if(mienemy == 0) { + UseMana(id, SPL_MANASHIELD); + } + if(id == myplr) { + NetSendCmd(TRUE, CMD_SETSHIELD); + } + + plr[id].pManaShield = 1; +} + +void AddFiremove(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + /// ASSERT: assert((DWORD)mi < MAXMISSILES); + missile[mi]._midam = random(59, 10) + plr[id]._pLevel + 1; + GetMissileVel(mi, sx, sy, dx, dy, 16); + missile[mi]._mirange = 255; + missile[mi]._miVar1 = 0; + missile[mi]._miVar2 = 0; + missile[mi]._mix++; + missile[mi]._miy++; + missile[mi]._miyoff -= 32; +} + +void AddGuardian(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + int i, pn, k, l, j, tx, ty; + int CrawlNum[6] = { 0, 3, 12, 45, 94, 159 }; + + /// ASSERT: assert((DWORD)mi < MAXMISSILES); + missile[mi]._midam = random(62, 10) + (plr[id]._pLevel >> 1) + 1; + for(i = missile[mi]._mispllvl; i > 0; i--) { + missile[mi]._midam += missile[mi]._midam >> 3; + } + + missile[mi]._miDelFlag = 1; + + for(j = 0; j < 6; j++) { + k = CrawlNum[j]; + l = k + 1; + for(i = (BYTE)CrawlTable[k]; i > 0; i--) { + tx = dx + CrawlTable[l]; + ty = dy + CrawlTable[l + 1]; + /// ASSERT: assert((DWORD)tx < MAXDUNX); + /// ASSERT: assert((DWORD)ty < MAXDUNY); + pn = dPiece[tx][ty]; + /// ASSERT: assert((DWORD)pn <= MAXTILES); + if(tx > 0 && tx < MAXDUNX && ty > 0 && ty < MAXDUNY) { + if(LineClear(sx, sy, tx, ty)) { + if(!(dMonster[tx][ty] | dObject[tx][ty] | dMissile[tx][ty] | nSolidTable[pn] | nMissileTable[pn])) { + missile[mi]._mix = tx; + missile[mi]._miy = ty; + missile[mi]._misx = tx; + missile[mi]._misy = ty; + missile[mi]._miDelFlag = 0; + UseMana(id, SPL_GUARDIAN); + j = 6; + break; + } + } + } + l += 2; + } + } + + if(missile[mi]._miDelFlag != 1) { + missile[mi]._misource = id; + missile[mi]._mlid = AddLight(missile[mi]._mix, missile[mi]._miy, 1); + missile[mi]._mirange = missile[mi]._mispllvl + (plr[id]._pLevel >> 1); + missile[mi]._mirange += missile[mi]._mirange * plr[id]._pISplDur >> 7; + if(missile[mi]._mirange > 30) { + missile[mi]._mirange = 30; + } + missile[mi]._mirange <<= 4; + if(missile[mi]._mirange < 30) { + missile[mi]._mirange = 30; + } + missile[mi]._miVar1 = missile[mi]._mirange - missile[mi]._miAnimLen; + missile[mi]._miVar2 = 0; + missile[mi]._miVar3 = 1; + } +} + +void AddChain(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + /// ASSERT: assert((DWORD)mi < MAXMISSILES); + missile[mi]._miVar1 = dx; + missile[mi]._miVar2 = dy; + missile[mi]._mirange = 1; + UseMana(id, SPL_CHAIN); +} + +void miss_null_11(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + SetMissDir(mi, dx); + /// ASSERT: assert((DWORD)mi < MAXMISSILES); + missile[mi]._midam = 0; + missile[mi]._miLightFlag = 1; + missile[mi]._mirange = 250; +} + +void miss_null_12(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + if(dx > 3) { + dx = 2; + } + + SetMissDir(mi, dx); + /// ASSERT: assert((DWORD)mi < MAXMISSILES); + missile[mi]._midam = 0; + missile[mi]._miLightFlag = 1; + missile[mi]._mirange = 250; +} + +void miss_null_13(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + if(dx > 3) { + dx = 2; + } + + SetMissDir(mi, dx); + /// ASSERT: assert((DWORD)mi < MAXMISSILES); + missile[mi]._midam = 0; + missile[mi]._miLightFlag = 1; + missile[mi]._mirange = missile[mi]._miAnimLen; +} + +void AddRhino(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + AnimStruct *anim; + + /// ASSERT: assert((DWORD)id < MAXMONSTERS); + /// ASSERT: assert(monster[id].MType != NULL); + if(monster[id].MType->mtype >= MT_HORNED && monster[id].MType->mtype <= MT_OBLORD) { + anim = &monster[id].MType->Anims[5]; + } else if(monster[id].MType->mtype >= MT_NSNAKE && monster[id].MType->mtype <= MT_GSNAKE) { + anim = &monster[id].MType->Anims[2]; + } else { + anim = &monster[id].MType->Anims[1]; + } + + GetMissileVel(mi, sx, sy, dx, dy, 18); + /// ASSERT: assert((DWORD)mi < MAXMISSILES); + missile[mi]._mimfnum = midir; + missile[mi]._miAnimFlags = 0; + missile[mi]._miAnimData = anim->Frames[midir]; + missile[mi]._miAnimDelay = anim->Delay; + missile[mi]._miAnimLen = anim->Rate; + missile[mi]._miAnimWidth = monster[id].MType->flags_1; + missile[mi]._miAnimWidth2 = monster[id].MType->flags_2; + missile[mi]._miAnimAdd = 1; + if(monster[id].MType->mtype >= MT_NSNAKE && monster[id].MType->mtype <= MT_GSNAKE) { + missile[mi]._miAnimFrame = 7; + } + missile[mi]._miVar1 = 0; + missile[mi]._miVar2 = 0; + missile[mi]._miLightFlag = 1; + if(monster[id]._uniqtype != 0) { + missile[mi]._miUniqTrans = monster[id]._uniqtrans + 1; + missile[mi]._mlid = monster[id].mlid; + } + missile[mi]._mirange = 256; + PutMissile(mi); +} + +void miss_null_32(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + AnimStruct *anim; + + /// ASSERT: assert((DWORD)id < MAXMONSTERS); + /// ASSERT: assert(monster[id].MType != NULL); + anim = &monster[id].MType->Anims[1]; + + GetMissileVel(mi, sx, sy, dx, dy, 16); + /// ASSERT: assert((DWORD)mi < MAXMISSILES); + missile[mi]._mimfnum = midir; + missile[mi]._miAnimFlags = 0; + missile[mi]._miAnimData = anim->Frames[midir]; + missile[mi]._miAnimDelay = anim->Delay; + missile[mi]._miAnimLen = anim->Rate; + missile[mi]._miAnimWidth = monster[id].MType->flags_1; + missile[mi]._miAnimWidth2 = monster[id].MType->flags_2; + missile[mi]._miAnimAdd = 1; + missile[mi]._miVar1 = 0; + missile[mi]._miVar2 = 0; + missile[mi]._miLightFlag = 1; + if(monster[id]._uniqtype != 0) { + missile[mi]._miUniqTrans = monster[id]._uniqtrans + 1; + } + dMonster[monster[id]._mx][monster[id]._my] = 0; + missile[mi]._mirange = 256; + PutMissile(mi); +} + +void AddFlare(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + long l; + + if(sx == dx && sy == dy) { + dx += XDirAdd[midir]; + dy += YDirAdd[midir]; + } + + GetMissileVel(mi, sx, sy, dx, dy, 16); + /// ASSERT: assert((DWORD)mi < MAXMISSILES); + missile[mi]._mirange = 256; + missile[mi]._miVar1 = sx; + missile[mi]._miVar2 = sy; + missile[mi]._mlid = AddLight(sx, sy, 8); + + if(mienemy == 0) { + UseMana(id, SPL_FLARE); + l = 5; +#ifdef _DEBUG + if(debug_mode_dollar_sign || debug_mode_key_inverted_v) { + l = 0; + } +#endif + plr[id]._pHitPoints -= l << 6; + plr[id]._pHPBase -= l << 6; + drawhpflag = 1; + if(plr[id]._pHitPoints <= 0) { + SyncPlrKill(id, 0); + } + } else if(id > 0) { + if(monster[id].MType->mtype == MT_SUCCUBUS) { + SetMissAnim(mi, MFILE_FLARE); + } + if(monster[id].MType->mtype == MT_SNOWWICH) { + SetMissAnim(mi, MFILE_SCUBMISB); + } + if(monster[id].MType->mtype == MT_HLSPWN) { + SetMissAnim(mi, MFILE_SCUBMISD); + } + if(monster[id].MType->mtype == MT_SOLBRNR) { + SetMissAnim(mi, MFILE_SCUBMISC); + } + } +} + +void AddAcid(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + GetMissileVel(mi, sx, sy, dx, dy, 16); + SetMissDir(mi, GetDirection16(sx, sy, dx, dy)); + /// ASSERT: assert((DWORD)mi < MAXMISSILES); + missile[mi]._mirange = 5 * (monster[id]._mint + 4); + missile[mi]._mlid = -1; + missile[mi]._miVar1 = sx; + missile[mi]._miVar2 = sy; + PutMissile(mi); +} + +void miss_null_1D(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + /// ASSERT: assert((DWORD)mi < MAXMISSILES); + missile[mi]._midam = dam; + missile[mi]._mixvel = 0; + missile[mi]._miyvel = 0; + missile[mi]._mirange = 50; + missile[mi]._miVar1 = missile[mi]._mirange - missile[mi]._miAnimLen; + missile[mi]._miVar2 = 0; +} + +void AddAcidpud(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + int monst; + + /// ASSERT: assert((DWORD)mi < MAXMISSILES); + missile[mi]._mixvel = 0; + missile[mi]._miyvel = 0; + missile[mi]._mixoff = 0; + missile[mi]._miyoff = 0; + missile[mi]._miLightFlag = 1; + monst = missile[mi]._misource; + missile[mi]._mirange = random(50, 15) + 40 * (monster[monst]._mint + 1); + missile[mi]._miPreFlag = 1; +} + +void AddStone(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + int i, j, k, l, tx, ty, mid; + int CrawlNum[6] = { 0, 3, 12, 45, 94, 159 }; + + /// ASSERT: assert((DWORD)mi < MAXMISSILES); + missile[mi]._misource = id; + + for(j = 0; j < 6; j++) { + k = CrawlNum[j]; + l = k + 1; + for(i = (BYTE)CrawlTable[k]; i > 0; i--) { + tx = dx + CrawlTable[l]; + ty = dy + CrawlTable[l + 1]; + if(tx > 0 && tx < MAXDUNX && ty > 0 && ty < MAXDUNY) { + mid = dMonster[tx][ty]; + mid = mid > 0 ? mid - 1 : -(mid + 1); + if(mid > 3 && monster[mid]._mAi != AI_DIABLO) { + if(monster[mid]._mmode != MM_FADEIN && monster[mid]._mmode != MM_FADEOUT && monster[mid]._mmode != MM_CHARGE) { + i = -99; + j = 6; + missile[mi]._miVar1 = monster[mid]._mmode; + missile[mi]._miVar2 = mid; + monster[mid]._mmode = MM_STONE; + break; + } + } + } + l += 2; + } + } + + if(i != -99) { + missile[mi]._miDelFlag = 1; + } else { + missile[mi]._mix = tx; + missile[mi]._miy = ty; + missile[mi]._misx = tx; + missile[mi]._misy = ty; + missile[mi]._mirange = missile[mi]._mispllvl + 6; + missile[mi]._mirange += missile[mi]._mirange * plr[id]._pISplDur >> 7; + if(missile[mi]._mirange > 15) { + missile[mi]._mirange = 15; + } + missile[mi]._mirange <<= 4; + UseMana(id, SPL_STONE); + } +} + +void AddGolem(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + int i, mx; + + /// ASSERT: assert((DWORD)mi < MAXMISSILES); + missile[mi]._miDelFlag = 0; + + for(i = 0; i < nummissiles; i++) { + mx = missileactive[i]; + if(missile[mx]._mitype == MIS_GOLEM && mx != mi && missile[mx]._misource == id) { + missile[mi]._miDelFlag = 1; + return; + } + } + + missile[mi]._miVar1 = sx; + missile[mi]._miVar2 = sy; + missile[mi]._miVar4 = dx; + missile[mi]._miVar5 = dy; + + if((monster[id]._mx != 1 || monster[id]._my != 0) && id == myplr) { + M_StartKill(id, id); + } + + UseMana(id, SPL_GOLEM); +} + +void AddEtherealize(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + int i; + + /// ASSERT: assert((DWORD)mi < MAXMISSILES); + missile[mi]._mirange = 16 * plr[id]._pLevel >> 1; + for(i = missile[mi]._mispllvl; i > 0; i--) { + missile[mi]._mirange += missile[mi]._mirange >> 3; + } + missile[mi]._mirange += missile[mi]._mirange * plr[id]._pISplDur >> 7; + missile[mi]._miVar1 = plr[id]._pHitPoints; + missile[mi]._miVar2 = plr[id]._pHPBase; + + if(mienemy == 0) { + UseMana(id, SPL_ETHEREALIZE); + } +} + +void miss_null_1F(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + /// ASSERT: assert((DWORD)mi < MAXMISSILES); + missile[mi]._miDelFlag = 1; +} + +void miss_null_23(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + /// ASSERT: assert((DWORD)mi < MAXMISSILES); + missile[mi]._midam = dam; + missile[mi]._mix = sx; + missile[mi]._miy = sy; + missile[mi]._misx = sx; + missile[mi]._misy = sy; + missile[mi]._misource = id; + if(dam == 1) { + SetMissDir(mi, 0); + } else { + SetMissDir(mi, 1); + } + missile[mi]._miLightFlag = 1; + missile[mi]._mirange = missile[mi]._miAnimLen; +} + +void AddBoom(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + /// ASSERT: assert((DWORD)mi < MAXMISSILES); + missile[mi]._mix = dx; + missile[mi]._miy = dy; + missile[mi]._misx = dx; + missile[mi]._misy = dy; + missile[mi]._mixvel = 0; + missile[mi]._miyvel = 0; + missile[mi]._midam = dam; + missile[mi]._mirange = missile[mi]._miAnimLen; + missile[mi]._miVar1 = 0; +} + +void AddHeal(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + int i; + long l; + + l = (random(57, 10) + 1) << 6; + for(i = 0; i < plr[id]._pLevel; i++) { + l += (random(57, 4) + 1) << 6; + } + /// ASSERT: assert((DWORD)mi < MAXMISSILES); + for(i = 0; i < missile[mi]._mispllvl; i++) { + l += (random(57, 6) + 1) << 6; + } + if(plr[id]._pClass == PC_WARRIOR) { + l *= 2; + } + if(plr[id]._pClass == PC_ROGUE) { + l += l >> 1; + } + + plr[id]._pHitPoints += l; + if(plr[id]._pHitPoints > plr[id]._pMaxHP) { + plr[id]._pHitPoints = plr[id]._pMaxHP; + } + plr[id]._pHPBase += l; + if(plr[id]._pHPBase > plr[id]._pMaxHPBase) { + plr[id]._pHPBase = plr[id]._pMaxHPBase; + } + + UseMana(id, SPL_HEAL); + drawhpflag = 1; + missile[mi]._miDelFlag = 1; +} + +void AddHealOther(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + /// ASSERT: assert((DWORD)mi < MAXMISSILES); + missile[mi]._miDelFlag = 1; + UseMana(id, SPL_HEALOTHER); + + if(id == myplr) { + SetCursor_(CURSOR_HEALOTHER); + } +} + +void AddElement(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + int i; + + if(sx == dx && sy == dy) { + dx += XDirAdd[midir]; + dy += YDirAdd[midir]; + } + + /// ASSERT: assert((DWORD)mi < MAXMISSILES); + missile[mi]._midam = 2 * (random(60, 10) + random(60, 10) + plr[id]._pLevel + 2); + for(i = missile[mi]._mispllvl; i > 0; i--) { + missile[mi]._midam += missile[mi]._midam >> 3; + } + missile[mi]._midam >>= 1; + GetMissileVel(mi, sx, sy, dx, dy, 16); + SetMissDir(mi, GetDirection8(sx, sy, dx, dy)); + missile[mi]._mirange = 256; + missile[mi]._miVar1 = sx; + missile[mi]._miVar2 = sy; + missile[mi]._miVar3 = 0; + missile[mi]._miVar4 = dx; + missile[mi]._miVar5 = dy; + missile[mi]._mlid = AddLight(sx, sy, 8); + UseMana(id, SPL_ELEMENT); +} + +void AddIdentify(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + /// ASSERT: assert((DWORD)mi < MAXMISSILES); + missile[mi]._miDelFlag = 1; + UseMana(id, SPL_IDENTIFY); + + if(id == myplr) { + if(sbookflag) { + sbookflag = 0; + } + if(!invflag) { + invflag = 1; + } + SetCursor_(CURSOR_IDENTIFY); + } +} + +void AddFirewallC(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + int i, pn, k, l, j, tx, ty; + int CrawlNum[6] = { 0, 3, 12, 45, 94, 159 }; + + /// ASSERT: assert((DWORD)mi < MAXMISSILES); + missile[mi]._miDelFlag = 1; + + for(j = 0; j < 6; j++) { + k = CrawlNum[j]; + l = k + 1; + for(i = (BYTE)CrawlTable[k]; i > 0; i--) { + tx = dx + CrawlTable[l]; + ty = dy + CrawlTable[l + 1]; + if(tx > 0 && tx < MAXDUNX && ty > 0 && ty < MAXDUNY) { + pn = dPiece[tx][ty]; + if(LineClear(sx, sy, tx, ty)) { + if((sx != tx || sy != ty) && !(nSolidTable[pn] | dObject[tx][ty])) { + missile[mi]._miVar1 = tx; + missile[mi]._miVar2 = ty; + missile[mi]._miVar5 = tx; + missile[mi]._miVar6 = ty; + missile[mi]._miDelFlag = 0; + j = 6; + break; + } + } + } + l += 2; + } + } + + if(missile[mi]._miDelFlag != 1) { + missile[mi]._miVar7 = 0; + missile[mi]._miVar8 = 0; + missile[mi]._miVar3 = (midir - 2) & 7; + missile[mi]._miVar4 = (midir + 2) & 7; + missile[mi]._mirange = 7; + UseMana(id, SPL_FIREWALL); + } +} + +void AddInfra(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + int i; + + /// ASSERT: assert((DWORD)mi < MAXMISSILES); + missile[mi]._mirange = 1584; + for(i = missile[mi]._mispllvl; i > 0; i--) { + missile[mi]._mirange += missile[mi]._mirange >> 3; + } + missile[mi]._mirange += missile[mi]._mirange * plr[id]._pISplDur >> 7; + + if(mienemy == 0) { + UseMana(id, SPL_INFRA); + } +} + +void AddWave(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + missile[mi]._miVar1 = dx; + missile[mi]._miVar2 = dy; + missile[mi]._miVar3 = 0; + missile[mi]._miVar4 = 0; + missile[mi]._mirange = 1; + missile[mi]._miAnimFrame = 4; + UseMana(id, SPL_WAVE); +} + +void AddNova(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + int k; + + /// ASSERT: assert((DWORD)mi < MAXMISSILES); + missile[mi]._miVar1 = dx; + missile[mi]._miVar2 = dy; + + if(id != -1) { + missile[mi]._midam = random(66, 6) + random(66, 6) + random(66, 6) + random(66, 6) + random(66, 6); + missile[mi]._midam += plr[id]._pLevel + 5; + missile[mi]._midam >>= 1; + for(k = missile[mi]._mispllvl; k > 0; k--) { + missile[mi]._midam += missile[mi]._midam >> 3; + } + if(mienemy == 0) { + UseMana(id, SPL_NOVA); + } + } else { + missile[mi]._midam = random(66, 3) + random(66, 3) + random(66, 3); + missile[mi]._midam += currlevel >> 1; + } + + missile[mi]._mirange = 1; +} + +void AddBlodboil(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + missile[mi]._miDelFlag = 1; +} + +void AddRepair(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + /// ASSERT: assert((DWORD)mi < MAXMISSILES); + missile[mi]._miDelFlag = 1; + UseMana(id, SPL_REPAIR); + + if(id == myplr) { + if(sbookflag) { + sbookflag = 0; + } + if(!invflag) { + invflag = 1; + } + SetCursor_(CURSOR_REPAIR); + } +} + +void AddRecharge(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + /// ASSERT: assert((DWORD)mi < MAXMISSILES); + missile[mi]._miDelFlag = 1; + UseMana(id, SPL_RECHARGE); + + if(id == myplr) { + if(sbookflag) { + sbookflag = 0; + } + if(!invflag) { + invflag = 1; + } + SetCursor_(CURSOR_RECHARGE); + } +} + +void AddDisarm(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + /// ASSERT: assert((DWORD)mi < MAXMISSILES); + missile[mi]._miDelFlag = 1; + UseMana(id, SPL_DISARM); + + if(id == myplr) { + SetCursor_(CURSOR_DISARM); + } +} + +void AddApoca(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + int i; + + /// ASSERT: assert((DWORD)mi < MAXMISSILES); + missile[mi]._miVar1 = 8; + missile[mi]._miVar2 = sy - missile[mi]._miVar1; + missile[mi]._miVar3 = sy + missile[mi]._miVar1; + missile[mi]._miVar4 = sx - missile[mi]._miVar1; + missile[mi]._miVar5 = sx + missile[mi]._miVar1; + missile[mi]._miVar6 = missile[mi]._miVar4; + + if(missile[mi]._miVar2 <= 0) { + missile[mi]._miVar2 = 1; + } + if(missile[mi]._miVar3 >= MAXDUNY) { + missile[mi]._miVar3 = MAXDUNY - 1; + } + if(missile[mi]._miVar4 <= 0) { + missile[mi]._miVar4 = 1; + } + if(missile[mi]._miVar5 >= MAXDUNX) { + missile[mi]._miVar5 = MAXDUNX - 1; + } + + for(i = 0; i < plr[id]._pLevel; i++) { + missile[mi]._midam += random(67, 6) + 1; + } + + missile[mi]._mirange = 255; + missile[mi]._miDelFlag = 0; + UseMana(id, SPL_APOCA); +} + +void AddFlame(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + int i; + + /// ASSERT: assert((DWORD)mi < MAXMISSILES); + missile[mi]._miVar2 = 0; + for(i = dam; i > 0; i--) { + missile[mi]._miVar2 += 5; + } + missile[mi]._misx = dx; + missile[mi]._misy = dy; + missile[mi]._mixoff = missile[midir]._mixoff; + missile[mi]._miyoff = missile[midir]._miyoff; + missile[mi]._mitxoff = missile[midir]._mitxoff; + missile[mi]._mityoff = missile[midir]._mityoff; + missile[mi]._mirange = missile[mi]._miVar2 + 20; + missile[mi]._mlid = AddLight(sx, sy, 1); + + if(mienemy == 0) { + missile[mi]._midam = 8 * (random(79, 2) + random(79, plr[id]._pLevel) + 2); + missile[mi]._midam += missile[mi]._midam >> 1; + } else { + missile[mi]._midam = random(77, monster[id].mMaxDamage - monster[id].mMinDamage + 1) + monster[id].mMinDamage; + } +} + +void AddFlamec(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + if(sx == dx && sy == dy) { + dx += XDirAdd[midir]; + dy += YDirAdd[midir]; + } + + GetMissileVel(mi, sx, sy, dx, dy, 32); + + if(mienemy == 0) { + UseMana(id, SPL_FLAME); + } + + /// ASSERT: assert((DWORD)mi < MAXMISSILES); + missile[mi]._miVar1 = sx; + missile[mi]._miVar2 = sy; + missile[mi]._miVar3 = 0; + missile[mi]._mirange = 256; +} + +void AddCbolt(int mi, int sx, int sy, int dx, int dy, int midir, char micaster, int id, int dam) +{ + /// ASSERT: assert((DWORD)mi < MAXMISSILES); + if(micaster == 0) { + if(id == myplr) { + missile[mi]._mirnd = random(63, 15) + 1; + missile[mi]._midam = random(68, plr[id]._pMagic >> 2) + 1; + } else { + missile[mi]._mirnd = random(63, 15) + 1; + missile[mi]._midam = random(68, plr[id]._pMagic >> 2) + 1; + } + } else { + missile[mi]._mirnd = random(63, 15) + 1; + missile[mi]._midam = 15; + } + + if(sx == dx && sy == dy) { + dx += XDirAdd[midir]; + dy += YDirAdd[midir]; + } + + missile[mi]._miAnimFrame = random(63, 8) + 1; + missile[mi]._mlid = AddLight(sx, sy, 5); + GetMissileVel(mi, sx, sy, dx, dy, 8); + missile[mi]._miVar1 = 5; + missile[mi]._miVar2 = midir; + missile[mi]._miVar3 = 0; + missile[mi]._mirange = 256; +} + +void AddHbolt(int mi, int sx, int sy, int dx, int dy, int midir, char micaster, int id, int dam) +{ + int sp; + + if(sx == dx && sy == dy) { + dx += XDirAdd[midir]; + dy += YDirAdd[midir]; + } + + /// ASSERT: assert((DWORD)mi < MAXMISSILES); + if(id != -1) { + sp = 2 * missile[mi]._mispllvl + 16; + if(sp >= 63) { + sp = 63; + } + } else { + sp = 16; + } + + GetMissileVel(mi, sx, sy, dx, dy, sp); + SetMissDir(mi, GetDirection16(sx, sy, dx, dy)); + missile[mi]._mirange = 256; + missile[mi]._miVar1 = sx; + missile[mi]._miVar2 = sy; + missile[mi]._mlid = AddLight(sx, sy, 8); + missile[mi]._midam = random(69, 10) + plr[id]._pLevel + 9; + UseMana(id, SPL_HBOLT); +} + +void AddResurrect(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + UseMana(id, SPL_RESURRECT); + + if(id == myplr) { + SetCursor_(CURSOR_RESURRECT); + } + + /// ASSERT: assert((DWORD)mi < MAXMISSILES); + missile[mi]._miDelFlag = 1; +} + +void AddResurrectBeam(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + /// ASSERT: assert((DWORD)mi < MAXMISSILES); + missile[mi]._mix = dx; + missile[mi]._miy = dy; + missile[mi]._misx = missile[mi]._mix; + missile[mi]._misy = missile[mi]._miy; + missile[mi]._mixvel = 0; + missile[mi]._miyvel = 0; + missile[mi]._mirange = misfiledata[MFILE_RESSUR1].mAnimLen[0]; +} + +void AddTelekinesis(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + /// ASSERT: assert((DWORD)mi < MAXMISSILES); + missile[mi]._miDelFlag = 1; + UseMana(id, SPL_TELEKINESIS); + + if(id == myplr) { + SetCursor_(CURSOR_TELEKINESIS); + } +} + +void AddBoneSpirit(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + long l; + + if(sx == dx && sy == dy) { + dx += XDirAdd[midir]; + dy += YDirAdd[midir]; + } + + /// ASSERT: assert((DWORD)mi < MAXMISSILES); + missile[mi]._midam = 0; + GetMissileVel(mi, sx, sy, dx, dy, 16); + SetMissDir(mi, GetDirection8(sx, sy, dx, dy)); + missile[mi]._mirange = 256; + missile[mi]._miVar1 = sx; + missile[mi]._miVar2 = sy; + missile[mi]._miVar3 = 0; + missile[mi]._miVar4 = dx; + missile[mi]._miVar5 = dy; + missile[mi]._mlid = AddLight(sx, sy, 8); + + if(mienemy == 0) { + UseMana(id, SPL_BONESPIRIT); + l = 6; +#ifdef _DEBUG + if(debug_mode_dollar_sign || debug_mode_key_inverted_v) { + l = 0; + } +#endif + plr[id]._pHitPoints -= l << 6; + plr[id]._pHPBase -= l << 6; + drawhpflag = 1; + if(plr[id]._pHitPoints <= 0) { + SyncPlrKill(id, 0); + } + } +} + +void AddRportal(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + /// ASSERT: assert((DWORD)mi < MAXMISSILES); + missile[mi]._mix = sx; + missile[mi]._miy = sy; + missile[mi]._misx = sx; + missile[mi]._misy = sy; + missile[mi]._mirange = 100; + missile[mi]._miVar1 = missile[mi]._mirange - missile[mi]._miAnimLen; + missile[mi]._miVar2 = 0; + PutMissile(mi); +} + +void AddDiabApoca(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + int pnum; + + for(pnum = 0; pnum < gbMaxPlayers; pnum++) { + if(plr[pnum].plractive && LineClear(sx, sy, plr[pnum]._px, plr[pnum]._py)) { + AddMissile(0, 0, plr[pnum]._px, plr[pnum]._py, 0, MIS_BOOM2, mienemy, id, dam, 0); + } + } + + /// ASSERT: assert((DWORD)mi < MAXMISSILES); + missile[mi]._miDelFlag = 1; +} + +int AddMissile(int sx, int sy, int v1, int v2, int midir, int mitype, char micaster, int id, int v3, int spllvl) +{ + int i, mi; + + if(nummissiles >= MAXMISSILES) { + return -1; + } + + if(mitype == MIS_MANASHIELD && plr[id].pManaShield == 1) { + if(currlevel != plr[id].plrlevel) { + return -1; + } + for(i = 0; i < nummissiles; i++) { + mi = missileactive[i]; + if(missile[mi]._mitype == MIS_MANASHIELD && missile[mi]._misource == id) { + return -1; + } + } + } + + mi = missileavail[0]; + missileavail[0] = missileavail[MAXMISSILES - nummissiles - 1]; + missileactive[nummissiles] = mi; + nummissiles++; + + missile[mi]._mitype = mitype; + missile[mi]._micaster = micaster; + missile[mi]._misource = id; + missile[mi]._miAnimType = missiledata[mitype].mFileNum; + missile[mi]._miDrawFlag = missiledata[mitype].mDraw; + missile[mi]._mispllvl = spllvl; + missile[mi]._mimfnum = midir; + + if(missile[mi]._miAnimType != 255 && misfiledata[missile[mi]._miAnimType].mAnimFAmt >= 8) { + SetMissDir(mi, midir); + } else { + SetMissDir(mi, 0); + } + + missile[mi]._mix = sx; + missile[mi]._miy = sy; + missile[mi]._mixoff = 0; + missile[mi]._miyoff = 0; + missile[mi]._misx = sx; + missile[mi]._misy = sy; + missile[mi]._mitxoff = 0; + missile[mi]._mityoff = 0; + missile[mi]._miDelFlag = 0; + missile[mi]._miAnimAdd = 1; + missile[mi]._miLightFlag = 0; + missile[mi]._miPreFlag = 0; + missile[mi]._miUniqTrans = 0; + missile[mi]._midam = v3; + missile[mi]._miHitFlag = 0; + missile[mi]._midist = 0; + missile[mi]._mlid = -1; + missile[mi]._mirnd = 0; + + if(missiledata[mitype].mlSFX != -1) { + PlaySfxLoc(missiledata[mitype].mlSFX, sx, sy); + } + + missiledata[mitype].mAddProc(mi, sx, sy, v1, v2, midir, micaster, id, v3); + + return mi; +} + +int Sentfire(int i, int sx, int sy) +{ + int ex, dir; + + ex = 0; + + /// ASSERT: assert((DWORD)i < MAXMISSILES); + if(LineClear(missile[i]._mix, missile[i]._miy, sx, sy)) { + if(dMonster[sx][sy] > 0 && monster[dMonster[sx][sy] - 1]._mhitpoints >> 6 > 0 && dMonster[sx][sy] - 1 > 3) { + dir = GetDirection(missile[i]._mix, missile[i]._miy, sx, sy); + missile[i]._miVar3 = missileavail[0]; + AddMissile( + missile[i]._mix, + missile[i]._miy, + sx, + sy, + dir, + MIS_FIREBOLT, + 0, + missile[i]._misource, + missile[i]._midam, + GetSpellLevel(missile[i]._misource, 1)); + ex = -1; + } + } + if(ex == -1) { + SetMissDir(i, 2); + missile[i]._miVar2 = 3; + } + + return ex; +} + +void MI_Dummy(int i) +{ + return; +} + +void MI_Golem(int i) +{ + int id, pn, j, k, l, m, tx, ty; + int CrawlNum[6] = { 0, 3, 12, 45, 94, 159 }; + + /// ASSERT: assert((DWORD)i < MAXMISSILES); + id = missile[i]._misource; + + if(monster[id]._mx == 1 && monster[id]._my == 0) { + for(j = 0; j < 6; j++) { + k = CrawlNum[j]; + l = k + 1; + for(m = (BYTE)CrawlTable[k]; m > 0; m--) { + tx = missile[i]._miVar4 + CrawlTable[l]; + ty = missile[i]._miVar5 + CrawlTable[l + 1]; + if(tx > 0 && tx < MAXDUNX && ty > 0 && ty < MAXDUNY) { + pn = dPiece[tx][ty]; + if(LineClear(missile[i]._miVar1, missile[i]._miVar2, tx, ty)) { + if(!(dMonster[tx][ty] | nSolidTable[pn] | dObject[tx][ty])) { + j = 6; + SpawnGolum(id, tx, ty, i); + break; + } + } + } + l += 2; + } + } + } + + missile[i]._miDelFlag = 1; +} + +void MI_SetManashield(int i) +{ + ManashieldFlag = 1; +} + +void MI_LArrow(int i) +{ + int p, mind, maxd, rst; + + /// ASSERT: assert((DWORD)i < MAXMISSILES); + missile[i]._mirange--; + p = missile[i]._misource; + + if(missile[i]._miAnimType != MFILE_MINILTNG && missile[i]._miAnimType != MFILE_MAGBLOS) { + missile[i]._midist++; + missile[i]._mitxoff += missile[i]._mixvel; + missile[i]._mityoff += missile[i]._miyvel; + GetMissilePos(i); + if(p != -1) { + if(missile[i]._micaster == 0) { + mind = plr[p]._pIMinDam; + maxd = plr[p]._pIMaxDam; + } else { + mind = monster[p].mMinDamage; + maxd = monster[p].mMaxDamage; + } + } else { + mind = random(68, 10) + currlevel + 1; + maxd = random(68, 10) + 2 * currlevel + 1; + } + if(missile[i]._mix != missile[i]._misx || missile[i]._miy != missile[i]._misy) { + rst = missiledata[missile[i]._mitype].mResist; + missiledata[missile[i]._mitype].mResist = 0; + CheckMissileCol(i, mind, maxd, 0, missile[i]._mix, missile[i]._miy, 0); + missiledata[missile[i]._mitype].mResist = rst; + } + if(missile[i]._mirange == 0) { + missile[i]._mimfnum = 0; + missile[i]._mitxoff -= missile[i]._mixvel; + missile[i]._mityoff -= missile[i]._miyvel; + GetMissilePos(i); + if(missile[i]._mitype == MIS_LARROW) { + SetMissAnim(i, MFILE_MINILTNG); + } else { + SetMissAnim(i, MFILE_MAGBLOS); + } + missile[i]._mirange = missile[i]._miAnimLen - 1; + } else if(missile[i]._mix != missile[i]._miVar1 || missile[i]._miy != missile[i]._miVar2) { + missile[i]._miVar1 = missile[i]._mix; + missile[i]._miVar2 = missile[i]._miy; + ChangeLight(missile[i]._mlid, missile[i]._miVar1, missile[i]._miVar2, 5); + } + } else { + ChangeLight(missile[i]._mlid, missile[i]._mix, missile[i]._miy, missile[i]._miAnimFrame + 5); + rst = missiledata[missile[i]._mitype].mResist; + if(missile[i]._mitype == MIS_LARROW) { + if(p != -1) { + mind = plr[p]._pILMinDam; + maxd = plr[p]._pILMaxDam; + } else { + mind = random(68, 10) + currlevel + 1; + maxd = random(68, 10) + 2 * currlevel + 1; + } + missiledata[MIS_LARROW].mResist = 2; + CheckMissileCol(i, mind, maxd, 0, missile[i]._mix, missile[i]._miy, 1); + } + if(missile[i]._mitype == MIS_FARROW) { + if(p != -1) { + mind = plr[p]._pIFMinDam; + maxd = plr[p]._pIFMaxDam; + } else { + mind = random(68, 10) + currlevel + 1; + maxd = random(68, 10) + 2 * currlevel + 1; + } + missiledata[MIS_FARROW].mResist = 1; + CheckMissileCol(i, mind, maxd, 0, missile[i]._mix, missile[i]._miy, 1); + } + missiledata[missile[i]._mitype].mResist = rst; + } + + if(missile[i]._mirange == 0) { + missile[i]._miDelFlag = 1; + AddUnLight(missile[i]._mlid); + } + + PutMissile(i); +} + +void MI_Arrow(int i) +{ + int p, mind, maxd; + + /// ASSERT: assert((DWORD)i < MAXMISSILES); + missile[i]._mirange--; + missile[i]._midist++; + missile[i]._mitxoff += missile[i]._mixvel; + missile[i]._mityoff += missile[i]._miyvel; + GetMissilePos(i); + + p = missile[i]._misource; + if(p != -1) { + if(missile[i]._micaster == 0) { + mind = plr[p]._pIMinDam; + maxd = plr[p]._pIMaxDam; + } else { + mind = monster[p].mMinDamage; + maxd = monster[p].mMaxDamage; + } + } else { + mind = currlevel; + maxd = 2 * currlevel; + } + + if(missile[i]._mix != missile[i]._misx || missile[i]._miy != missile[i]._misy) { + CheckMissileCol(i, mind, maxd, 0, missile[i]._mix, missile[i]._miy, 0); + } + if(missile[i]._mirange == 0) { + missile[i]._miDelFlag = 1; + } + + PutMissile(i); +} + +void MI_Firebolt(int i) +{ + int omx, omy, d, p; + + /// ASSERT: assert((DWORD)i < MAXMISSILES); + missile[i]._mirange--; + + if(missile[i]._mitype == MIS_BONESPIRIT && missile[i]._mimfnum == 8) { + if(missile[i]._mirange == 0) { + if(missile[i]._mlid >= 0) { + AddUnLight(missile[i]._mlid); + } + missile[i]._miDelFlag = 1; + PlaySfxLoc(LS_BSIMPCT, missile[i]._mix, missile[i]._miy); + } + PutMissile(i); + return; + } + + omx = missile[i]._mitxoff; + omy = missile[i]._mityoff; + missile[i]._mitxoff += missile[i]._mixvel; + missile[i]._mityoff += missile[i]._miyvel; + GetMissilePos(i); + + p = missile[i]._misource; + if(p != -1) { + if(missile[i]._micaster == 0) { + switch(missile[i]._mitype) { + case MIS_FIREBOLT: + d = (plr[p]._pMagic >> 3) + random(75, 10) + missile[i]._mispllvl + 1; + break; + case MIS_FLARE: + d = (plr[p]._pMagic >> 1) + 3 * missile[i]._mispllvl - (plr[p]._pMagic >> 3); + break; + case MIS_BONESPIRIT: + d = 0; + break; + } + } else { + d = random(77, monster[p].mMaxDamage - monster[p].mMinDamage + 1) + monster[p].mMinDamage; + } + } else { + d = random(78, 2 * currlevel) + currlevel; + } + + if(missile[i]._mix != missile[i]._misx || missile[i]._miy != missile[i]._misy) { + CheckMissileCol(i, d, d, 0, missile[i]._mix, missile[i]._miy, 0); + } + + if(missile[i]._mirange == 0) { + missile[i]._miDelFlag = 1; + missile[i]._mitxoff = omx; + missile[i]._mityoff = omy; + GetMissilePos(i); + switch(missile[i]._mitype) { + case MIS_FLARE: + AddMissile(missile[i]._mix, missile[i]._miy, i, 0, missile[i]._mimfnum, MIS_MISEXP2, missile[i]._micaster, missile[i]._misource, 0, 0); + break; + case MIS_FIREBOLT: + case MIS_MAGMABALL: + AddMissile(missile[i]._mix, missile[i]._miy, i, 0, missile[i]._mimfnum, MIS_MISEXP, missile[i]._micaster, missile[i]._misource, 0, 0); + break; + case MIS_ACID: + AddMissile(missile[i]._mix, missile[i]._miy, i, 0, missile[i]._mimfnum, MIS_MISEXP3, missile[i]._micaster, missile[i]._misource, 0, 0); + break; + case MIS_BONESPIRIT: + SetMissDir(i, 8); + missile[i]._mirange = 7; + missile[i]._miDelFlag = 0; + PutMissile(i); + return; + } + if(missile[i]._mlid >= 0) { + AddUnLight(missile[i]._mlid); + } + } else if(missile[i]._mix != missile[i]._miVar1 || missile[i]._miy != missile[i]._miVar2) { + missile[i]._miVar1 = missile[i]._mix; + missile[i]._miVar2 = missile[i]._miy; + if(missile[i]._mlid >= 0) { + ChangeLight(missile[i]._mlid, missile[i]._miVar1, missile[i]._miVar2, 8); + } + } + + PutMissile(i); +} + +void MI_Lightball(int i) +{ + int j, tx, ty, oi; + + /// ASSERT: assert((DWORD)i < MAXMISSILES); + tx = missile[i]._miVar1; + ty = missile[i]._miVar2; + missile[i]._mirange--; + missile[i]._mitxoff += missile[i]._mixvel; + missile[i]._mityoff += missile[i]._miyvel; + GetMissilePos(i); + j = missile[i]._mirange; + CheckMissileCol(i, missile[i]._midam, missile[i]._midam, 0, missile[i]._mix, missile[i]._miy, 0); + + if(missile[i]._miHitFlag == 1) { + missile[i]._mirange = j; + } + if(dObject[tx][ty] != 0 && tx == missile[i]._mix && ty == missile[i]._miy) { + oi = dObject[tx][ty] > 0 ? dObject[tx][ty] - 1 : -(dObject[tx][ty] + 1); + if(object[oi]._otype == OBJ_SHRINEL || object[oi]._otype == OBJ_SHRINER) { + missile[i]._mirange = j; + } + } + if(missile[i]._mirange == 0) { + missile[i]._miDelFlag = 1; + } + + PutMissile(i); +} + +void mi_null_33(int i) +{ + /// ASSERT: assert((DWORD)i < MAXMISSILES); + missile[i]._mirange--; + missile[i]._mitxoff += missile[i]._mixvel; + missile[i]._mityoff += missile[i]._miyvel; + GetMissilePos(i); + CheckMissileCol(i, missile[i]._midam, missile[i]._midam, 0, missile[i]._mix, missile[i]._miy, 0); + + if(missile[i]._mirange == 0) { + missile[i]._miDelFlag = 1; + } + + PutMissile(i); +} + +void MI_Acidpud(int i) +{ + int range; + + /// ASSERT: assert((DWORD)i < MAXMISSILES); + missile[i]._mirange--; + range = missile[i]._mirange; + CheckMissileCol(i, missile[i]._midam, missile[i]._midam, 1, missile[i]._mix, missile[i]._miy, 0); + missile[i]._mirange = range; + + if(missile[i]._mirange == 0) { + if(missile[i]._mimfnum != 0) { + missile[i]._miDelFlag = 1; + } else { + SetMissDir(i, 1); + missile[i]._mirange = missile[i]._miAnimLen; + } + } + + PutMissile(i); +} + +void MI_Firewall(int i) +{ + int ExpLight[14] = { 2, 3, 4, 5, 5, 6, 7, 8, 9, 10, 11, 12, 12 }; /// BUGFIX: array size should be '12' + + /// ASSERT: assert((DWORD)i < MAXMISSILES); + missile[i]._mirange--; + + if(missile[i]._mirange == missile[i]._miVar1) { + SetMissDir(i, 1); + missile[i]._miAnimFrame = random(83, 11) + 1; + } + if(missile[i]._mirange == missile[i]._miAnimLen - 1) { + SetMissDir(i, 0); + missile[i]._miAnimFrame = 13; + missile[i]._miAnimAdd = -1; + } + + CheckMissileCol(i, missile[i]._midam, missile[i]._midam, 1, missile[i]._mix, missile[i]._miy, 1); + + if(missile[i]._mirange == 0) { + missile[i]._miDelFlag = 1; + AddUnLight(missile[i]._mlid); + } + if(missile[i]._mimfnum != 0 && missile[i]._mirange != 0 && missile[i]._miAnimAdd != -1 && missile[i]._miVar2 < 12) { + if(missile[i]._miVar2 == 0) { + missile[i]._mlid = AddLight(missile[i]._mix, missile[i]._miy, ExpLight[missile[i]._miVar2]); + } + ChangeLight(missile[i]._mlid, missile[i]._mix, missile[i]._miy, ExpLight[missile[i]._miVar2]); + missile[i]._miVar2++; + } + + PutMissile(i); +} + +void MI_Fireball(int i) +{ + int dam, px, py, id, mx, my; + + /// ASSERT: assert((DWORD)i < MAXMISSILES); + id = missile[i]._misource; + dam = missile[i]._midam; + missile[i]._mirange--; + + if(missile[i]._micaster == 0) { + px = plr[id].WorldX; + py = plr[id].WorldY; + } else { + px = monster[id]._mx; + py = monster[id]._my; + } + + if(missile[i]._miAnimType == MFILE_BIGEXP) { + if(missile[i]._mirange == 0) { + missile[i]._miDelFlag = 1; + AddUnLight(missile[i]._mlid); + } + } else { + missile[i]._mitxoff += missile[i]._mixvel; + missile[i]._mityoff += missile[i]._miyvel; + GetMissilePos(i); + if(missile[i]._mix != missile[i]._misx || missile[i]._miy != missile[i]._misy) { + CheckMissileCol(i, dam, dam, FALSE, missile[i]._mix, missile[i]._miy, FALSE); + } + if(missile[i]._mirange == 0) { + mx = missile[i]._mix; + my = missile[i]._miy; + ChangeLight(missile[i]._mlid, mx, my, missile[i]._miAnimFrame); + if(!CheckBlock(px, py, mx, my)) { + CheckMissileCol(i, dam, dam, FALSE, mx, my, TRUE); + } + if(!CheckBlock(px, py, mx, my + 1)) { + CheckMissileCol(i, dam, dam, FALSE, mx, my + 1, TRUE); + } + if(!CheckBlock(px, py, mx, my - 1)) { + CheckMissileCol(i, dam, dam, FALSE, mx, my - 1, TRUE); + } + if(!CheckBlock(px, py, mx + 1, my)) { + CheckMissileCol(i, dam, dam, FALSE, mx + 1, my, TRUE); + } + if(!CheckBlock(px, py, mx + 1, my - 1)) { + CheckMissileCol(i, dam, dam, FALSE, mx + 1, my - 1, TRUE); + } + if(!CheckBlock(px, py, mx + 1, my + 1)) { + CheckMissileCol(i, dam, dam, FALSE, mx + 1, my + 1, TRUE); + } + if(!CheckBlock(px, py, mx - 1, my)) { + CheckMissileCol(i, dam, dam, FALSE, mx - 1, my, TRUE); + } + if(!CheckBlock(px, py, mx - 1, my + 1)) { + CheckMissileCol(i, dam, dam, FALSE, mx - 1, my + 1, TRUE); + } + if(!CheckBlock(px, py, mx - 1, my - 1)) { + CheckMissileCol(i, dam, dam, FALSE, mx - 1, my - 1, TRUE); + } + if(!TransList[dTransVal[mx][my]] + || missile[i]._mixvel < 0 + && (TransList[dTransVal[mx][my + 1]] && nSolidTable[dPiece[mx][my + 1]] + || TransList[dTransVal[mx][my - 1]] && nSolidTable[dPiece[mx][my - 1]])) { + missile[i]._mix++; + missile[i]._miy++; + missile[i]._miyoff -= 32; + } + if(missile[i]._miyvel > 0 + && (TransList[dTransVal[mx + 1][my]] && nSolidTable[dPiece[mx + 1][my]] + || TransList[dTransVal[mx - 1][my]] && nSolidTable[dPiece[mx - 1][my]])) { + missile[i]._miyoff -= 32; + } + if(missile[i]._mixvel > 0 + && (TransList[dTransVal[mx][my + 1]] && nSolidTable[dPiece[mx][my + 1]] + || TransList[dTransVal[mx][my - 1]] && nSolidTable[dPiece[mx][my - 1]])) { + missile[i]._mixoff -= 32; + } + missile[i]._mimfnum = 0; + SetMissAnim(i, MFILE_BIGEXP); + missile[i]._mirange = missile[i]._miAnimLen - 1; + } else if(missile[i]._mix != missile[i]._miVar1 || missile[i]._miy != missile[i]._miVar2) { + missile[i]._miVar1 = missile[i]._mix; + missile[i]._miVar2 = missile[i]._miy; + ChangeLight(missile[i]._mlid, missile[i]._miVar1, missile[i]._miVar2, 8); + } + } + + PutMissile(i); +} + +void MI_Lightctrl(int i) +{ + int pn, dam, p, mx, my; + + /// ASSERT: assert((DWORD)i < MAXMISSILES); + missile[i]._mirange--; + + p = missile[i]._misource; + if(p != -1) { + if(missile[i]._micaster == 0) { + dam = (random(79, 2) + random(79, plr[p]._pLevel) + 2) << 6; + } else { + dam = 2 * (random(80, monster[p].mMaxDamage - monster[p].mMinDamage + 1) + monster[p].mMinDamage); + } + } else { + dam = random(81, currlevel) + 2 * currlevel; + } + + missile[i]._mitxoff += missile[i]._mixvel; + missile[i]._mityoff += missile[i]._miyvel; + GetMissilePos(i); + + mx = missile[i]._mix; + my = missile[i]._miy; + /// ASSERT: assert((DWORD)mx < MAXDUNX); + /// ASSERT: assert((DWORD)my < MAXDUNY); + pn = dPiece[missile[i]._mix][missile[i]._miy]; + /// ASSERT: assert((DWORD)pn <= MAXTILES); + + if(missile[i]._misource == -1) { + if((missile[i]._mix != missile[i]._misx || missile[i]._miy != missile[i]._misy) && nMissileTable[pn]) { + missile[i]._mirange = 0; + } + } else if(nMissileTable[pn]) { + missile[i]._mirange = 0; + } + + if(!nMissileTable[pn]) { + if(missile[i]._mix != missile[i]._miVar1 || missile[i]._miy != missile[i]._miVar2) { + if(mx > 0 && my > 0 && mx < MAXDUNX && my < MAXDUNY) { + if(missile[i]._misource != -1) { + if(missile[i]._micaster == 1 + && monster[missile[i]._misource].MType->mtype >= MT_STORM + && monster[missile[i]._misource].MType->mtype <= MT_MAEL) { + AddMissile( + missile[i]._mix, + missile[i]._miy, + missile[i]._misx, + missile[i]._misy, + i, + MIS_LIGHTNING2, + missile[i]._micaster, + missile[i]._misource, + dam, + missile[i]._mispllvl); + } else { + AddMissile( + missile[i]._mix, + missile[i]._miy, + missile[i]._misx, + missile[i]._misy, + i, + MIS_LIGHTNING, + missile[i]._micaster, + missile[i]._misource, + dam, + missile[i]._mispllvl); + } + } else { + AddMissile( + missile[i]._mix, + missile[i]._miy, + missile[i]._misx, + missile[i]._misy, + i, + MIS_LIGHTNING, + missile[i]._micaster, + missile[i]._misource, + dam, + missile[i]._mispllvl); + } + missile[i]._miVar1 = missile[i]._mix; + missile[i]._miVar2 = missile[i]._miy; + } + } + } + + if(missile[i]._mirange == 0 || mx <= 0 || my <= 0 || mx >= MAXDUNX || my > MAXDUNY) { /// BUGFIX: 'my >=' + missile[i]._miDelFlag = 1; + } +} + +void MI_Lightning(int i) +{ + int j; + + /// ASSERT: assert((DWORD)i < MAXMISSILES); + missile[i]._mirange--; + j = missile[i]._mirange; + + if(missile[i]._mix != missile[i]._misx || missile[i]._miy != missile[i]._misy) { + CheckMissileCol(i, missile[i]._midam, missile[i]._midam, TRUE, missile[i]._mix, missile[i]._miy, FALSE); + } + if(missile[i]._miHitFlag == 1) { + missile[i]._mirange = j; + } + if(missile[i]._mirange == 0) { + missile[i]._miDelFlag = 1; + AddUnLight(missile[i]._mlid); + } + + PutMissile(i); +} + +void MI_Town(int i) +{ + int p; + int ExpLight[17] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15 }; + + /// ASSERT: assert((DWORD)i < MAXMISSILES); + if(missile[i]._mirange > 1) { + missile[i]._mirange--; + } + if(missile[i]._mirange == missile[i]._miVar1) { + SetMissDir(i, 1); + } + if(currlevel != 0 && missile[i]._mimfnum != 1 && missile[i]._mirange != 0) { + if(missile[i]._miVar2 == 0) { + missile[i]._mlid = AddLight(missile[i]._mix, missile[i]._miy, ExpLight[missile[i]._miVar2]); + } + ChangeLight(missile[i]._mlid, missile[i]._mix, missile[i]._miy, ExpLight[missile[i]._miVar2]); + missile[i]._miVar2++; + } + + for(p = 0; p < MAX_PLRS; p++) { + if(plr[p].plractive && currlevel == plr[p].plrlevel && !plr[p]._pLvlChanging && plr[p]._pmode == PM_STAND) { + if(plr[p].WorldX == missile[i]._mix && plr[p].WorldY == missile[i]._miy) { + ClrPlrPath(p); + if(p == myplr) { + NetSendCmdParam1(TRUE, CMD_WARP, missile[i]._misource); + plr[p]._pmode = PM_NEWLVL; + } + } + } + } + + if(missile[i]._mirange == 0) { + missile[i]._miDelFlag = 1; + AddUnLight(missile[i]._mlid); + } + + PutMissile(i); +} + +void MI_Flash(int i) +{ + /// ASSERT: assert((DWORD)i < MAXMISSILES); + if(missile[i]._micaster == 0 && missile[i]._misource != -1) { + plr[missile[i]._misource]._pInvincible = 1; + } + + missile[i]._mirange--; + CheckMissileCol(i, missile[i]._midam, missile[i]._midam, TRUE, missile[i]._mix - 1, missile[i]._miy, TRUE); + CheckMissileCol(i, missile[i]._midam, missile[i]._midam, TRUE, missile[i]._mix, missile[i]._miy, TRUE); + CheckMissileCol(i, missile[i]._midam, missile[i]._midam, TRUE, missile[i]._mix + 1, missile[i]._miy, TRUE); + CheckMissileCol(i, missile[i]._midam, missile[i]._midam, TRUE, missile[i]._mix - 1, missile[i]._miy + 1, TRUE); + CheckMissileCol(i, missile[i]._midam, missile[i]._midam, TRUE, missile[i]._mix, missile[i]._miy + 1, TRUE); + CheckMissileCol(i, missile[i]._midam, missile[i]._midam, TRUE, missile[i]._mix + 1, missile[i]._miy + 1, TRUE); + + if(missile[i]._mirange == 0) { + missile[i]._miDelFlag = 1; + if(missile[i]._micaster == 0 && missile[i]._misource != -1) { + plr[missile[i]._misource]._pInvincible = 0; + } + } + + PutMissile(i); +} + +void MI_Flash2(int i) +{ + /// ASSERT: assert((DWORD)i < MAXMISSILES); + if(missile[i]._micaster == 0 && missile[i]._misource != -1) { + plr[missile[i]._misource]._pInvincible = 1; + } + + missile[i]._mirange--; + CheckMissileCol(i, missile[i]._midam, missile[i]._midam, TRUE, missile[i]._mix - 1, missile[i]._miy - 1, TRUE); + CheckMissileCol(i, missile[i]._midam, missile[i]._midam, TRUE, missile[i]._mix, missile[i]._miy - 1, TRUE); + CheckMissileCol(i, missile[i]._midam, missile[i]._midam, TRUE, missile[i]._mix + 1, missile[i]._miy - 1, TRUE); + + if(missile[i]._mirange == 0) { + missile[i]._miDelFlag = 1; + if(missile[i]._micaster == 0 && missile[i]._misource != -1) { + plr[missile[i]._misource]._pInvincible = 0; + } + } + + PutMissile(i); +} + +void MI_Manashield(int i) +{ + int id; + long diff, pct; + + /// ASSERT: assert((DWORD)i < MAXMISSILES); + id = missile[i]._misource; + missile[i]._mix = plr[id].WorldX; + missile[i]._miy = plr[id].WorldY; + missile[i]._mitxoff = plr[id]._pxoff << 16; + missile[i]._mityoff = plr[id]._pyoff << 16; + + if(plr[id]._pmode == PM_WALK3) { + missile[i]._misx = plr[id]._px; + missile[i]._misy = plr[id]._py; + } else { + missile[i]._misx = plr[id].WorldX; + missile[i]._misy = plr[id].WorldY; + } + + GetMissilePos(i); + + if(plr[id]._pmode == PM_WALK3) { + if(plr[id]._pdir == 2) { + missile[i]._mix++; + } else { + missile[i]._miy++; + } + } + + if(id != myplr) { + if(currlevel != plr[id].plrlevel) { + missile[i]._miDelFlag = 1; + } + PutMissile(i); + return; + } + + if(plr[id]._pMana <= 0 || !plr[id].plractive) { + missile[i]._mirange = 0; + } + + if(plr[id]._pHitPoints < missile[i]._miVar1) { + diff = missile[i]._miVar1 - plr[id]._pHitPoints; + pct = 0; + if(missile[i]._mispllvl > 0) { + pct += 3; + } + if(pct > 0) { + diff -= diff / pct; + } + if(diff < 0) { + diff = 0; + } + drawmanaflag = 1; + drawhpflag = 1; + if(plr[id]._pMana >= diff) { + plr[id]._pHitPoints = missile[i]._miVar1; + plr[id]._pHPBase = missile[i]._miVar2; + plr[id]._pMana -= diff; + plr[id]._pManaBase -= diff; + } else { + plr[id]._pHitPoints = missile[i]._miVar1 + plr[id]._pMana - diff; + plr[id]._pHPBase = missile[i]._miVar2 + plr[id]._pMana - diff; + plr[id]._pMana = 0; + plr[id]._pManaBase = plr[id]._pMaxManaBase - plr[id]._pMaxMana; + missile[i]._mirange = 0; + missile[i]._miDelFlag = 1; + if(plr[id]._pHitPoints < 0) { + SetPlayerHitPoints(id, 0); + } + if(plr[id]._pHitPoints >> 6 == 0 && id == myplr) { + SyncPlrKill(id, missile[i]._miVar8); + } + } + } + + if(id == myplr && plr[id]._pHitPoints == 0 && missile[i]._miVar1 == 0 && plr[id]._pmode != PM_DEATH) { + missile[i]._mirange = 0; + missile[i]._miDelFlag = 1; + SyncPlrKill(id, -1); + } + + missile[i]._miVar1 = plr[id]._pHitPoints; + missile[i]._miVar2 = plr[id]._pHPBase; + + if(missile[i]._mirange == 0) { + missile[i]._miDelFlag = 1; + NetSendCmd(TRUE, CMD_ENDSHIELD); + } + + PutMissile(i); +} + +void MI_Etherealize(int i) +{ + int id; + + /// ASSERT: assert((DWORD)i < MAXMISSILES); + missile[i]._mirange--; + id = missile[i]._misource; + missile[i]._mix = plr[id].WorldX; + missile[i]._miy = plr[id].WorldY; + missile[i]._mitxoff = plr[id]._pxoff << 16; + missile[i]._mityoff = plr[id]._pyoff << 16; + + if(plr[id]._pmode == PM_WALK3) { + missile[i]._misx = plr[id]._px; + missile[i]._misy = plr[id]._py; + } else { + missile[i]._misx = plr[id].WorldX; + missile[i]._misy = plr[id].WorldY; + } + + GetMissilePos(i); + + if(plr[id]._pmode == PM_WALK3) { + if(plr[id]._pdir == 2) { + missile[i]._mix++; + } else { + missile[i]._miy++; + } + } + + plr[id]._pSpellFlags |= 1; + + if(missile[i]._mirange == 0 || plr[id]._pHitPoints <= 0) { + missile[i]._miDelFlag = 1; + plr[id]._pSpellFlags &= ~1; + } + + PutMissile(i); +} + +void MI_Firemove(int i) +{ + int j; + int ExpLight[14] = { 2, 3, 4, 5, 5, 6, 7, 8, 9, 10, 11, 12, 12 }; /// BUGFIX: array size should be '13' + + /// ASSERT: assert((DWORD)i < MAXMISSILES); + missile[i]._mix--; + missile[i]._miy--; + missile[i]._miyoff += 32; + missile[i]._miVar1++; + + if(missile[i]._miVar1 == missile[i]._miAnimLen) { + SetMissDir(i, 1); + missile[i]._miAnimFrame = random(82, 11) + 1; + } + + missile[i]._mitxoff += missile[i]._mixvel; + missile[i]._mityoff += missile[i]._miyvel; + GetMissilePos(i); + j = missile[i]._mirange; + CheckMissileCol(i, missile[i]._midam, missile[i]._midam, FALSE, missile[i]._mix, missile[i]._miy, FALSE); + + if(missile[i]._miHitFlag == 1) { + missile[i]._mirange = j; + } + if(missile[i]._mirange == 0) { + missile[i]._miDelFlag = 1; + AddUnLight(missile[i]._mlid); + } + + if(missile[i]._mimfnum == 0 && missile[i]._mirange != 0) { + if(missile[i]._miVar2 == 0) { + missile[i]._mlid = AddLight(missile[i]._mix, missile[i]._miy, ExpLight[missile[i]._miVar2]); + } + ChangeLight(missile[i]._mlid, missile[i]._mix, missile[i]._miy, ExpLight[missile[i]._miVar2]); + missile[i]._miVar2++; + } else if(missile[i]._mix != missile[i]._miVar3 || missile[i]._miy != missile[i]._miVar4) { + missile[i]._miVar3 = missile[i]._mix; + missile[i]._miVar4 = missile[i]._miy; + ChangeLight(missile[i]._mlid, missile[i]._miVar3, missile[i]._miVar4, 8); + } + + missile[i]._mix++; + missile[i]._miy++; + missile[i]._miyoff -= 32; + PutMissile(i); +} + +void MI_Guardian(int i) +{ + int j, k, sx, sy, sx1, sy1, ex; + + sx1 = 0; + sy1 = 0; + + /// ASSERT: assert((DWORD)i < MAXMISSILES); + missile[i]._mirange--; + + if(missile[i]._miVar2 > 0) { + missile[i]._miVar2--; + } + if(missile[i]._mirange == missile[i]._miVar1 || missile[i]._mimfnum == MFILE_GUARD && missile[i]._miVar2 == 0) { + SetMissDir(i, 1); + } + + if(!(missile[i]._mirange % 16)) { + ex = 0; + for(j = 0; j < 23 && ex != -1; j++) { + for(k = 10; k >= 0 && ex != -1 && (vCrawlTable[j][k] != 0 || vCrawlTable[j][k + 1] != 0); k -= 2) { + if(sx1 == vCrawlTable[j][k] && sy1 == vCrawlTable[j][k + 1]) { + continue; + } + sx = missile[i]._mix + vCrawlTable[j][k]; + sy = missile[i]._miy + vCrawlTable[j][k + 1]; + ex = Sentfire(i, sx, sy); + if(ex == -1) { + break; + } + sx = missile[i]._mix - vCrawlTable[j][k]; + sy = missile[i]._miy - vCrawlTable[j][k + 1]; + ex = Sentfire(i, sx, sy); + if(ex == -1) { + break; + } + sx = missile[i]._mix + vCrawlTable[j][k]; + sy = missile[i]._miy - vCrawlTable[j][k + 1]; + ex = Sentfire(i, sx, sy); + if(ex == -1) { + break; + } + sx = missile[i]._mix - vCrawlTable[j][k]; + sy = missile[i]._miy + vCrawlTable[j][k + 1]; + ex = Sentfire(i, sx, sy); + if(ex == -1) { + break; + } + sx1 = vCrawlTable[j][k]; + sy1 = vCrawlTable[j][k + 1]; + } + } + } + + if(missile[i]._mirange == 14) { + SetMissDir(i, 0); + missile[i]._miAnimFrame = 15; + missile[i]._miAnimAdd = -1; + } + + missile[i]._miVar3 += missile[i]._miAnimAdd; + + if(missile[i]._miVar3 > 15) { + missile[i]._miVar3 = 15; + } else if(missile[i]._miVar3 > 0) { + ChangeLight(missile[i]._mlid, missile[i]._mix, missile[i]._miy, missile[i]._miVar3); + } + + if(missile[i]._mirange == 0) { + missile[i]._miDelFlag = 1; + AddUnLight(missile[i]._mlid); + } + + PutMissile(i); +} + +void MI_Chain(int i) +{ + int sx, sy, id, l, n, m, k, rad, tx, ty, dir; + int CrawlNum[19] = { 0, 3, 12, 45, 94, 159, 240, 337, 450, 579, 724, 885, 1062, 1255, 1464, 1689, 1930, 2187, 2460 }; + + /// ASSERT: assert((DWORD)i < MAXMISSILES); + id = missile[i]._misource; + sx = missile[i]._mix; + sy = missile[i]._miy; + dir = GetDirection(sx, sy, missile[i]._miVar1, missile[i]._miVar2); + AddMissile(sx, sy, missile[i]._miVar1, missile[i]._miVar2, dir, MIS_LIGHTCTRL, 0, id, 1, missile[i]._mispllvl); + + rad = missile[i]._mispllvl + 3; + if(rad > 19) { + rad = 19; + } + + for(n = 1; n < rad; n++) { + k = CrawlNum[n]; + l = k + 1; + for(m = (BYTE)CrawlTable[k]; m > 0; m--) { + tx = sx + CrawlTable[l]; + ty = sy + CrawlTable[l + 1]; + if(tx > 0 && tx < MAXDUNX && ty > 0 && ty < MAXDUNY && dMonster[tx][ty] > 0) { + dir = GetDirection(sx, sy, tx, ty); + AddMissile(sx, sy, tx, ty, dir, MIS_LIGHTCTRL, 0, id, 1, missile[i]._mispllvl); + } + l += 2; + } + } + + missile[i]._mirange--; + + if(missile[i]._mirange == 0) { + missile[i]._miDelFlag = 1; + } +} + +void mi_null_11(int i) +{ + /// ASSERT: assert((DWORD)i < MAXMISSILES); + missile[i]._mirange--; + + if(missile[i]._mirange == 0) { + missile[i]._miDelFlag = 1; + } + if(missile[i]._miAnimFrame == missile[i]._miAnimLen) { + missile[i]._miPreFlag = 1; + } + + PutMissile(i); +} + +void MI_Weapexp(int i) +{ + int id, mind, maxd; + int ExpLight[10] = { 9, 10, 11, 12, 11, 10, 8, 6, 4, 2 }; + + /// ASSERT: assert((DWORD)i < MAXMISSILES); + missile[i]._mirange--; + id = missile[i]._misource; + + if(missile[i]._miVar2 == 1) { + mind = plr[id]._pIFMinDam; + maxd = plr[id]._pIFMaxDam; + missiledata[missile[i]._mitype].mResist = 1; + } else { + mind = plr[id]._pILMinDam; + maxd = plr[id]._pILMaxDam; + missiledata[missile[i]._mitype].mResist = 2; + } + + CheckMissileCol(i, mind, maxd, FALSE, missile[i]._mix, missile[i]._miy, FALSE); + + if(missile[i]._miVar1 == 0) { + missile[i]._mlid = AddLight(missile[i]._mix, missile[i]._miy, ExpLight[missile[i]._miVar1]); + } else if(missile[i]._mirange != 0) { + ChangeLight(missile[i]._mlid, missile[i]._mix, missile[i]._miy, ExpLight[missile[i]._miVar1]); + } + + missile[i]._miVar1++; + + if(missile[i]._mirange == 0) { + missile[i]._miDelFlag = 1; + AddUnLight(missile[i]._mlid); + } else { + PutMissile(i); + } +} + +void MI_Misexp(int i) +{ + int ExpLight[10] = { 9, 10, 11, 12, 11, 10, 8, 6, 4, 2 }; + + /// ASSERT: assert((DWORD)i < MAXMISSILES); + missile[i]._mirange--; + + if(missile[i]._mirange == 0) { + missile[i]._miDelFlag = 1; + AddUnLight(missile[i]._mlid); + } else { + if(missile[i]._miVar1 == 0) { + missile[i]._mlid = AddLight(missile[i]._mix, missile[i]._miy, ExpLight[missile[i]._miVar1]); + } else { + ChangeLight(missile[i]._mlid, missile[i]._mix, missile[i]._miy, ExpLight[missile[i]._miVar1]); + } + missile[i]._miVar1++; + PutMissile(i); + } +} + +void MI_Acidsplat(int i) +{ + int monst, dam; + + /// ASSERT: assert((DWORD)i < MAXMISSILES); + if(missile[i]._mirange == missile[i]._miAnimLen) { + missile[i]._mix++; + missile[i]._miy++; + missile[i]._miyoff -= 32; + } + + missile[i]._mirange--; + + if(missile[i]._mirange == 0) { + missile[i]._miDelFlag = 1; + monst = missile[i]._misource; + dam = (monster[monst].MData->mLevel >= 2) + 1; + AddMissile(missile[i]._mix, missile[i]._miy, i, 0, missile[i]._mimfnum, MIS_ACIDPUD, 1, missile[i]._misource, dam, missile[i]._mispllvl); + } else { + PutMissile(i); + } +} + +void MI_Teleport(int i) +{ + int id; + + /// ASSERT: assert((DWORD)i < MAXMISSILES); + id = missile[i]._misource; + missile[i]._mirange--; + + if(missile[i]._mirange <= 0) { + missile[i]._miDelFlag = 1; + } else { + dPlayer[plr[id].WorldX][plr[id].WorldY] = 0; + PlrClrTrans(plr[id].WorldX, plr[id].WorldY); + plr[id].WorldX = missile[i]._mix; + plr[id].WorldY = missile[i]._miy; + plr[id]._px = plr[id].WorldX; + plr[id]._py = plr[id].WorldY; + plr[id]._poldx = plr[id].WorldX; + plr[id]._poldy = plr[id].WorldY; + PlrDoTrans(plr[id].WorldX, plr[id].WorldY); + missile[i]._miVar1 = 1; + dPlayer[plr[id].WorldX][plr[id].WorldY] = id + 1; + if(leveltype != DTYPE_TOWN) { + ChangeLightXY(plr[id]._plid, plr[id].WorldX, plr[id].WorldY); + ChangeVisionXY(plr[id]._pvid, plr[id].WorldX, plr[id].WorldY); + } + if(id == myplr) { + ViewX = plr[id].WorldX - ScrollInfo._sdx; + ViewY = plr[id].WorldY - ScrollInfo._sdy; + } + } +} + +void MI_Stone(int i) +{ + int m; + + /// ASSERT: assert((DWORD)i < MAXMISSILES); + missile[i]._mirange--; + m = missile[i]._miVar2; + + if(monster[m]._mhitpoints == 0 && missile[i]._miAnimType != MFILE_SHATTER1) { + missile[i]._mimfnum = 0; + missile[i]._miDrawFlag = 1; + SetMissAnim(i, MFILE_SHATTER1); + missile[i]._mirange = 11; + } + + if(monster[m]._mmode != MM_STONE) { + missile[i]._miDelFlag = 1; + return; + } + + if(missile[i]._mirange == 0) { + missile[i]._miDelFlag = 1; + if(monster[m]._mhitpoints > 0) { + /// ASSERT: assert(dMonster[monster[m]._mx][monster[m]._my] == m+1 || dMonster[monster[m]._mx][monster[m]._my] == -(m+1)); + monster[m]._mmode = missile[i]._miVar1; + } else { + AddDead(monster[m]._mx, monster[m]._my, stonendx, monster[m]._mdir); + } + } + if(missile[i]._miAnimType == MFILE_SHATTER1) { + PutMissile(i); + } +} + +void MI_Boom(int i) +{ + /// ASSERT: assert((DWORD)i < MAXMISSILES); + missile[i]._mirange--; + + if(missile[i]._miVar1 == 0) { + CheckMissileCol(i, missile[i]._midam, missile[i]._midam, FALSE, missile[i]._mix, missile[i]._miy, TRUE); + } + if(missile[i]._miHitFlag == 1) { + missile[i]._miVar1 = 1; + } + if(missile[i]._mirange == 0) { + missile[i]._miDelFlag = 1; + } + + PutMissile(i); +} + +void MI_Rhino(int i) +{ + int mix, miy, mix2, miy2, omx, omy, monst; + + /// ASSERT: assert((DWORD)i < MAXMISSILES); + monst = missile[i]._misource; + /// ASSERT: assert((DWORD)monst < MAXMONSTERS); + + if(monster[monst]._mmode != MM_CHARGE) { + missile[i]._miDelFlag = 1; + return; + } + + GetMissilePos(i); + omx = missile[i]._mix; + omy = missile[i]._miy; + dMonster[omx][omy] = 0; + + if(monster[monst]._mAi == AI_SNAKE) { + missile[i]._mitxoff += 2 * missile[i]._mixvel; + missile[i]._mityoff += 2 * missile[i]._miyvel; + GetMissilePos(i); + mix2 = missile[i]._mix; + miy2 = missile[i]._miy; + missile[i]._mitxoff -= missile[i]._mixvel; + missile[i]._mityoff -= missile[i]._miyvel; + } else { + missile[i]._mitxoff += missile[i]._mixvel; + missile[i]._mityoff += missile[i]._miyvel; + } + + GetMissilePos(i); + mix = missile[i]._mix; + miy = missile[i]._miy; + + if(!PosOkMonst(monst, mix, miy) || monster[monst]._mAi == AI_SNAKE && !PosOkMonst(monst, mix2, miy2)) { + MissToMonst(i, omx, omy); + missile[i]._miDelFlag = 1; + return; + } + + dMonster[mix][miy] = -(monst + 1); + monster[monst]._mfutx = mix; + monster[monst]._moldx = mix; + monster[monst]._mx = mix; + monster[monst]._mfuty = miy; + monster[monst]._moldy = miy; + monster[monst]._my = miy; + + if(monster[monst]._uniqtype != 0) { + ChangeLightXY(missile[i]._mlid, mix, miy); + } + + MoveMissilePos(i); + PutMissile(i); +} + +void mi_null_32(int i) +{ + int mix, miy, omx, omy, monst, p, px, py, mid; + + GetMissilePos(i); + /// ASSERT: assert((DWORD)i < MAXMISSILES); + omx = missile[i]._mix; + omy = missile[i]._miy; + missile[i]._mitxoff += missile[i]._mixvel; + missile[i]._mityoff += missile[i]._miyvel; + + GetMissilePos(i); + monst = missile[i]._misource; + mix = missile[i]._mix; + miy = missile[i]._miy; + p = monster[monst]._menemy; + + if(!(monster[monst]._mFlags & 0x10)) { + px = plr[p].WorldX; + py = plr[p].WorldY; + } else { + px = monster[p]._mx; + py = monster[p]._my; + } + + if((mix != omx || miy != omy) + && (missile[i]._miVar1 & 1 && (abs(omx - px) >= 4 || abs(omy - py) >= 4) || missile[i]._miVar2 > 1) + && PosOkMonst(missile[i]._misource, omx, omy)) { + MissToMonst(i, omx, omy); + missile[i]._miDelFlag = 1; + } else { + if(!(monster[monst]._mFlags & 0x10)) { + mid = dPlayer[mix][miy]; + } else { + mid = dMonster[mix][miy]; + } + } + + if(!PosOkMissile(mix, miy) || mid > 0 && !(missile[i]._miVar1 & 1)) { + missile[i]._mixvel = -missile[i]._mixvel; + missile[i]._miyvel = -missile[i]._miyvel; + missile[i]._mimfnum = opposite[missile[i]._mimfnum]; + missile[i]._miAnimData = monster[monst].MType->Anims[1].Frames[missile[i]._mimfnum]; + missile[i]._miVar2++; + if(mid > 0) { + missile[i]._miVar1 |= 1; + } + } + + MoveMissilePos(i); + PutMissile(i); +} + +void MI_FirewallC(int i) +{ + int tx, ty, pn, id; + + /// ASSERT: assert((DWORD)i < MAXMISSILES); + missile[i]._mirange--; + id = missile[i]._misource; + + if(missile[i]._mirange == 0) { + missile[i]._miDelFlag = 1; + } else { + pn = dPiece[missile[i]._miVar1][missile[i]._miVar2]; + /// ASSERT: assert((DWORD)pn <= MAXTILES); + tx = missile[i]._miVar1 + XDirAdd[missile[i]._miVar3]; + ty = missile[i]._miVar2 + YDirAdd[missile[i]._miVar3]; + if(!nMissileTable[pn] && missile[i]._miVar8 == 0 && tx > 0 && tx < MAXDUNX && ty > 0 && ty < MAXDUNY) { + AddMissile( + missile[i]._miVar1, + missile[i]._miVar2, + missile[i]._miVar1, + missile[i]._miVar2, + plr[id]._pdir, + MIS_FIREWALL, + 0, + id, + 0, + missile[i]._mispllvl); + missile[i]._miVar1 = tx; + missile[i]._miVar2 = ty; + } else { + missile[i]._miVar8 = 1; + } + pn = dPiece[missile[i]._miVar5][missile[i]._miVar6]; + /// ASSERT: assert((DWORD)pn <= MAXTILES); + tx = missile[i]._miVar5 + XDirAdd[missile[i]._miVar4]; + ty = missile[i]._miVar6 + YDirAdd[missile[i]._miVar4]; + if(!nMissileTable[pn] && missile[i]._miVar7 == 0 && tx > 0 && tx < MAXDUNX && ty > 0 && ty < MAXDUNY) { + AddMissile( + missile[i]._miVar5, + missile[i]._miVar6, + missile[i]._miVar5, + missile[i]._miVar6, + plr[id]._pdir, + MIS_FIREWALL, + 0, + id, + 0, + missile[i]._mispllvl); + missile[i]._miVar5 = tx; + missile[i]._miVar6 = ty; + } else { + missile[i]._miVar7 = 1; + } + } +} + +void MI_Infra(int i) +{ + /// ASSERT: assert((DWORD)i < MAXMISSILES); + missile[i]._mirange--; + plr[missile[i]._misource]._pInfraFlag = 1; + + if(missile[i]._mirange == 0) { + missile[i]._miDelFlag = 1; + CalcPlrItemVals(missile[i]._misource, TRUE); + } +} + +void MI_Apoca(int i) +{ + int j, k, id; + BOOL exit; + + /// ASSERT: assert((DWORD)i < MAXMISSILES); + id = missile[i]._misource; + + exit = FALSE; + for(k = missile[i]._miVar2; k < missile[i]._miVar3 && !exit; k++) { + for(j = missile[i]._miVar4; j < missile[i]._miVar5 && !exit; j++) { + if(dMonster[j][k] > 3 && !nSolidTable[dPiece[j][k]]) { + AddMissile(j, k, j, k, plr[id]._pdir, MIS_BOOM, 0, id, missile[i]._midam, 0); + exit = TRUE; + } + } + if(!exit) { + missile[i]._miVar4 = missile[i]._miVar6; + } + } + + if(exit == TRUE) { + missile[i]._miVar2 = k - 1; + missile[i]._miVar4 = j; + } else { + missile[i]._miDelFlag = 1; + } +} + +void MI_Wave(int i) +{ + int dira, dirb, nxa, nya, nxb, nyb, pn, j, sd, id, sx, sy, v1, v2; + BOOL f1, f2; + + f1 = FALSE; + f2 = FALSE; + + /// ASSERT: assert((DWORD)i < MAXMISSILES); + id = missile[i]._misource; + sx = missile[i]._mix; + sy = missile[i]._miy; + v1 = missile[i]._miVar1; + v2 = missile[i]._miVar2; + sd = GetDirection(sx, sy, v1, v2); + dira = (sd - 2) & 7; + dirb = (sd + 2) & 7; + nxa = sx + XDirAdd[sd]; + nya = sy + YDirAdd[sd]; + pn = dPiece[nxa][nya]; + /// ASSERT: assert((DWORD)pn <= MAXTILES); + + if(!nMissileTable[pn]) { + AddMissile(nxa, nya, nxa + XDirAdd[sd], nya + YDirAdd[sd], plr[id]._pdir, MIS_FIREMOVE, 0, id, 0, missile[i]._mispllvl); + nxa += XDirAdd[dira]; + nya += YDirAdd[dira]; + nxb = sx + XDirAdd[sd] + XDirAdd[dirb]; + nyb = sy + YDirAdd[sd] + YDirAdd[dirb]; + for(j = 0; j < (missile[i]._mispllvl >> 1) + 2; j++) { + pn = dPiece[nxa][nya]; + /// ASSERT: assert((DWORD)pn <= MAXTILES); + if(!nMissileTable[pn] && !f1 && nxa > 0 && nxa < MAXDUNX && nya > 0 && nya < MAXDUNY) { + AddMissile(nxa, nya, nxa + XDirAdd[sd], nya + YDirAdd[sd], plr[id]._pdir, MIS_FIREMOVE, 0, id, 0, missile[i]._mispllvl); + nxa += XDirAdd[dira]; + nya += YDirAdd[dira]; + } else { + f1 = TRUE; + } + pn = dPiece[nxb][nyb]; + /// ASSERT: assert((DWORD)pn <= MAXTILES); + if(!nMissileTable[pn] && !f2 && nxb > 0 && nxb < MAXDUNX && nyb > 0 && nyb < MAXDUNY) { + AddMissile(nxb, nyb, nxb + XDirAdd[sd], nyb + YDirAdd[sd], plr[id]._pdir, MIS_FIREMOVE, 0, id, 0, missile[i]._mispllvl); + nxb += XDirAdd[dirb]; + nyb += YDirAdd[dirb]; + } else { + f2 = TRUE; + } + } + } + + missile[i]._mirange--; + + if(missile[i]._mirange == 0) { + missile[i]._miDelFlag = 1; + } +} + +void MI_Nova(int i) +{ + int k, id, sx, sy, dir, en, sx1, sy1, dam, v1, v2; + + sx1 = sy1 = 0; + + /// ASSERT: assert((DWORD)i < MAXMISSILES); + id = missile[i]._misource; + dam = missile[i]._midam; + sx = missile[i]._mix; + sy = missile[i]._miy; + v1 = missile[i]._miVar1; + v2 = missile[i]._miVar2; + + if(id != -1) { + dir = plr[id]._pdir; + en = 0; + } else { + dir = 0; + en = 1; + } + + for(k = 0; k < 23; k++) { + if(sx1 == vCrawlTable[k][6] && sy1 == vCrawlTable[k][7]) { + continue; + } + v1 = sx + vCrawlTable[k][6]; + v2 = sy + vCrawlTable[k][7]; + AddMissile(sx, sy, v1, v2, dir, MIS_LIGHTBALL, en, id, dam, missile[i]._mispllvl); + v1 = sx - vCrawlTable[k][6]; + v2 = sy - vCrawlTable[k][7]; + AddMissile(sx, sy, v1, v2, dir, MIS_LIGHTBALL, en, id, dam, missile[i]._mispllvl); + v1 = sx - vCrawlTable[k][6]; + v2 = sy + vCrawlTable[k][7]; + AddMissile(sx, sy, v1, v2, dir, MIS_LIGHTBALL, en, id, dam, missile[i]._mispllvl); + v1 = sx + vCrawlTable[k][6]; + v2 = sy - vCrawlTable[k][7]; + AddMissile(sx, sy, v1, v2, dir, MIS_LIGHTBALL, en, id, dam, missile[i]._mispllvl); + sx1 = vCrawlTable[k][6]; + sy1 = vCrawlTable[k][7]; + } + + missile[i]._mirange--; + + if(missile[i]._mirange == 0) { + missile[i]._miDelFlag = 1; + } +} + +void MI_Blodboil(int i) +{ + /// ASSERT: assert((DWORD)i < MAXMISSILES); + missile[i]._miDelFlag = 1; +} + +void MI_Flame(int i) +{ + int k; + + /// ASSERT: assert((DWORD)i < MAXMISSILES); + missile[i]._mirange--; + missile[i]._miVar2--; + k = missile[i]._mirange; + CheckMissileCol(i, missile[i]._midam, missile[i]._midam, TRUE, missile[i]._mix, missile[i]._miy, FALSE); + + if(missile[i]._mirange == 0 && missile[i]._miHitFlag == 1) { + missile[i]._mirange = k; + } + if(missile[i]._miVar2 == 0) { + missile[i]._miAnimFrame = 20; + } + if(missile[i]._miVar2 <= 0) { + k = missile[i]._miAnimFrame; + if(k > 11) { + k = 24 - k; + } + ChangeLight(missile[i]._mlid, missile[i]._mix, missile[i]._miy, k); + } + if(missile[i]._mirange == 0) { + missile[i]._miDelFlag = 1; + AddUnLight(missile[i]._mlid); + } + if(missile[i]._miVar2 <= 0) { + PutMissile(i); + } +} + +void MI_Flamec(int i) +{ + int id, pn; + + /// ASSERT: assert((DWORD)i < MAXMISSILES); + missile[i]._mirange--; + id = missile[i]._misource; + missile[i]._mitxoff += missile[i]._mixvel; + missile[i]._mityoff += missile[i]._miyvel; + GetMissilePos(i); + + if(missile[i]._mix != missile[i]._miVar1 || missile[i]._miy != missile[i]._miVar2) { + /// ASSERT: assert((DWORD)missile[i]._mix < MAXDUNX); + /// ASSERT: assert((DWORD)missile[i]._miy < MAXDUNY); + pn = dPiece[missile[i]._mix][missile[i]._miy]; + /// ASSERT: assert((DWORD)pn <= MAXTILES); + if(!nMissileTable[pn]) { + AddMissile( + missile[i]._mix, + missile[i]._miy, + missile[i]._misx, + missile[i]._misy, + i, + MIS_FLAME, + missile[i]._micaster, + id, + missile[i]._miVar3, + missile[i]._mispllvl); + } else { + missile[i]._mirange = 0; + } + missile[i]._miVar1 = missile[i]._mix; + missile[i]._miVar2 = missile[i]._miy; + missile[i]._miVar3++; + } + if(missile[i]._mirange == 0 || missile[i]._miVar3 == 3) { + missile[i]._miDelFlag = 1; + } +} + +void MI_Cbolt(int i) +{ + int sx, sy, dx, dy, md; + int bpath[16] = { -1, 0, 1, -1, 0, 1, -1, -1, 0, 0, 1, 1, 0, 1, -1, 0 }; + + /// ASSERT: assert((DWORD)i < MAXMISSILES); + missile[i]._mirange--; + + if(missile[i]._miAnimType != MFILE_LGHNING) { + if(missile[i]._miVar3 == 0) { + md = (missile[i]._miVar2 + bpath[missile[i]._mirnd]) & 7; + missile[i]._mirnd = (missile[i]._mirnd + 1) & 0xF; + sx = missile[i]._mix; + sy = missile[i]._miy; + dx = sx + XDirAdd[md]; + dy = sy + YDirAdd[md]; + GetMissileVel(i, sx, sy, dx, dy, 8); + missile[i]._miVar3 = 16; + } else { + missile[i]._miVar3--; + } + missile[i]._mitxoff += missile[i]._mixvel; + missile[i]._mityoff += missile[i]._miyvel; + GetMissilePos(i); + CheckMissileCol(i, missile[i]._midam, missile[i]._midam, FALSE, missile[i]._mix, missile[i]._miy, FALSE); + if(missile[i]._miHitFlag == 1) { + missile[i]._miVar1 = 8; + missile[i]._mimfnum = 0; + missile[i]._mixoff = 0; + missile[i]._miyoff = 0; + SetMissAnim(i, MFILE_LGHNING); + missile[i]._mirange = missile[i]._miAnimLen; + GetMissilePos(i); + } + ChangeLight(missile[i]._mlid, missile[i]._mix, missile[i]._miy, missile[i]._miVar1); + } + if(missile[i]._mirange == 0) { + missile[i]._miDelFlag = 1; + AddUnLight(missile[i]._mlid); + } + + PutMissile(i); +} + +void MI_Hbolt(int i) +{ + int dam; + + /// ASSERT: assert((DWORD)i < MAXMISSILES); + missile[i]._mirange--; + + if(missile[i]._miAnimType != MFILE_HOLYEXPL) { + missile[i]._mitxoff += missile[i]._mixvel; + missile[i]._mityoff += missile[i]._miyvel; + GetMissilePos(i); + dam = missile[i]._midam; + if(missile[i]._mix != missile[i]._misx || missile[i]._miy != missile[i]._misy) { + CheckMissileCol(i, dam, dam, FALSE, missile[i]._mix, missile[i]._miy, FALSE); + } + if(missile[i]._mirange == 0) { + missile[i]._mitxoff -= missile[i]._mixvel; + missile[i]._mityoff -= missile[i]._miyvel; + GetMissilePos(i); + missile[i]._mimfnum = 0; + SetMissAnim(i, MFILE_HOLYEXPL); + missile[i]._mirange = missile[i]._miAnimLen - 1; + } else if(missile[i]._mix != missile[i]._miVar1 || missile[i]._miy != missile[i]._miVar2) { + missile[i]._miVar1 = missile[i]._mix; + missile[i]._miVar2 = missile[i]._miy; + ChangeLight(missile[i]._mlid, missile[i]._miVar1, missile[i]._miVar2, 8); + } + } else { + ChangeLight(missile[i]._mlid, missile[i]._mix, missile[i]._miy, missile[i]._miAnimFrame + 7); + if(missile[i]._mirange == 0) { + missile[i]._miDelFlag = 1; + AddUnLight(missile[i]._mlid); + } + } + + PutMissile(i); +} + +void MI_Element(int i) +{ + int mid, sd, dam, cx, cy, px, py, id; + + /// ASSERT: assert((DWORD)i < MAXMISSILES); + missile[i]._mirange--; + id = missile[i]._misource; + dam = missile[i]._midam; + + if(missile[i]._miAnimType == MFILE_BIGEXP) { + cx = missile[i]._mix; + cy = missile[i]._miy; + px = plr[id].WorldX; + py = plr[id].WorldY; + ChangeLight(missile[i]._mlid, cx, cy, missile[i]._miAnimFrame); + if(!CheckBlock(px, py, cx, cy)) { + CheckMissileCol(i, dam, dam, TRUE, cx, cy, TRUE); + } + if(!CheckBlock(px, py, cx, cy + 1)) { + CheckMissileCol(i, dam, dam, TRUE, cx, cy + 1, TRUE); + } + if(!CheckBlock(px, py, cx, cy - 1)) { + CheckMissileCol(i, dam, dam, TRUE, cx, cy - 1, TRUE); + } + if(!CheckBlock(px, py, cx + 1, cy)) { + CheckMissileCol(i, dam, dam, TRUE, cx + 1, cy, TRUE); + } + if(!CheckBlock(px, py, cx + 1, cy - 1)) { + CheckMissileCol(i, dam, dam, TRUE, cx + 1, cy - 1, TRUE); + } + if(!CheckBlock(px, py, cx + 1, cy + 1)) { + CheckMissileCol(i, dam, dam, TRUE, cx + 1, cy + 1, TRUE); + } + if(!CheckBlock(px, py, cx - 1, cy)) { + CheckMissileCol(i, dam, dam, TRUE, cx - 1, cy, TRUE); + } + if(!CheckBlock(px, py, cx - 1, cy + 1)) { + CheckMissileCol(i, dam, dam, TRUE, cx - 1, cy + 1, TRUE); + } + if(!CheckBlock(px, py, cx - 1, cy - 1)) { + CheckMissileCol(i, dam, dam, TRUE, cx - 1, cy - 1, TRUE); + } + if(missile[i]._mirange == 0) { + missile[i]._miDelFlag = 1; + AddUnLight(missile[i]._mlid); + } + } else { + missile[i]._mitxoff += missile[i]._mixvel; + missile[i]._mityoff += missile[i]._miyvel; + GetMissilePos(i); + cx = missile[i]._mix; + cy = missile[i]._miy; + CheckMissileCol(i, dam, dam, FALSE, cx, cy, FALSE); + if(missile[i]._miVar3 == 0 && cx == missile[i]._miVar4 && cy == missile[i]._miVar5) { + missile[i]._miVar3 = 1; + } + if(missile[i]._miVar3 == 1) { + missile[i]._miVar3 = 2; + missile[i]._mirange = 255; + mid = FindClosest(cx, cy, 19); + if(mid > 0) { + sd = GetDirection8(cx, cy, monster[mid]._mx, monster[mid]._my); + SetMissDir(i, sd); + GetMissileVel(i, cx, cy, monster[mid]._mx, monster[mid]._my, 16); + } else { + sd = plr[id]._pdir; + SetMissDir(i, sd); + GetMissileVel(i, cx, cy, cx + XDirAdd[sd], cy + YDirAdd[sd], 16); + } + } + if(cx != missile[i]._miVar1 || cy != missile[i]._miVar2) { + missile[i]._miVar1 = cx; + missile[i]._miVar2 = cy; + ChangeLight(missile[i]._mlid, missile[i]._miVar1, missile[i]._miVar2, 8); + } + if(missile[i]._mirange == 0) { + missile[i]._mimfnum = 0; + SetMissAnim(i, MFILE_BIGEXP); + missile[i]._mirange = missile[i]._miAnimLen - 1; + } + } + + PutMissile(i); +} + +void MI_Bonespirit(int i) +{ + int mid, sd, dam, cx, cy, id; + + /// ASSERT: assert((DWORD)i < MAXMISSILES); + missile[i]._mirange--; + dam = missile[i]._midam; + id = missile[i]._misource; + + if(missile[i]._mimfnum == 8) { + ChangeLight(missile[i]._mlid, missile[i]._mix, missile[i]._miy, missile[i]._miAnimFrame); + if(missile[i]._mirange == 0) { + missile[i]._miDelFlag = 1; + AddUnLight(missile[i]._mlid); + } + PutMissile(i); + return; + } + + missile[i]._mitxoff += missile[i]._mixvel; + missile[i]._mityoff += missile[i]._miyvel; + GetMissilePos(i); + cx = missile[i]._mix; + cy = missile[i]._miy; + CheckMissileCol(i, dam, dam, FALSE, cx, cy, FALSE); + + if(missile[i]._miVar3 == 0 && cx == missile[i]._miVar4 && cy == missile[i]._miVar5) { + missile[i]._miVar3 = 1; + } + if(missile[i]._miVar3 == 1) { + missile[i]._miVar3 = 2; + missile[i]._mirange = 255; + mid = FindClosest(cx, cy, 19); + if(mid > 0) { + missile[i]._midam = monster[mid]._mhitpoints >> 7; + sd = GetDirection8(cx, cy, monster[mid]._mx, monster[mid]._my); + SetMissDir(i, sd); + GetMissileVel(i, cx, cy, monster[mid]._mx, monster[mid]._my, 16); + } else { + sd = plr[id]._pdir; + SetMissDir(i, sd); + GetMissileVel(i, cx, cy, cx + XDirAdd[sd], cy + YDirAdd[sd], 16); + } + } + if(cx != missile[i]._miVar1 || cy != missile[i]._miVar2) { + missile[i]._miVar1 = cx; + missile[i]._miVar2 = cy; + ChangeLight(missile[i]._mlid, missile[i]._miVar1, missile[i]._miVar2, 8); + } + if(missile[i]._mirange == 0) { + SetMissDir(i, 8); + missile[i]._mirange = 7; + } + + PutMissile(i); +} + +void MI_ResurrectBeam(int i) +{ + /// ASSERT: assert((DWORD)i < MAXMISSILES); + missile[i]._mirange--; + + if(missile[i]._mirange == 0) { + missile[i]._miDelFlag = 1; + } + + PutMissile(i); +} + +void MI_Rportal(int i) +{ + int ExpLight[17] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15 }; + + /// ASSERT: assert((DWORD)i < MAXMISSILES); + if(missile[i]._mirange > 1) { + missile[i]._mirange--; + } + if(missile[i]._mirange == missile[i]._miVar1) { + SetMissDir(i, 1); + } + if(currlevel != 0 && missile[i]._mimfnum != 1 && missile[i]._mirange != 0) { + if(missile[i]._miVar2 == 0) { + missile[i]._mlid = AddLight(missile[i]._mix, missile[i]._miy, ExpLight[missile[i]._miVar2]); + } + ChangeLight(missile[i]._mlid, missile[i]._mix, missile[i]._miy, ExpLight[missile[i]._miVar2]); + missile[i]._miVar2++; + } + if(missile[i]._mirange == 0) { + missile[i]._miDelFlag = 1; + AddUnLight(missile[i]._mlid); + } + + PutMissile(i); +} + +void ProcessMissiles() +{ + int i, mi; + + for(i = 0; i < nummissiles; i++) { + mi = missileactive[i]; + dFlags[missile[mi]._mix][missile[mi]._miy] &= ~1; + dMissile[missile[mi]._mix][missile[mi]._miy] = 0; + } + + i = 0; + while(i < nummissiles) { + mi = missileactive[i]; + if(missile[mi]._miDelFlag) { + DeleteMissile(mi, i); + i = 0; + } else { + i++; + } + } + + MissilePreFlag = 0; + ManashieldFlag = 0; + + for(i = 0; i < nummissiles; i++) { + mi = missileactive[i]; + missiledata[missile[mi]._mitype].mProc(mi); + if(!(missile[mi]._miAnimFlags & 2)) { + missile[mi]._miAnimCnt++; + if(missile[mi]._miAnimCnt >= missile[mi]._miAnimDelay) { + missile[mi]._miAnimCnt = 0; + missile[mi]._miAnimFrame += missile[mi]._miAnimAdd; + if(missile[mi]._miAnimFrame > missile[mi]._miAnimLen) { + missile[mi]._miAnimFrame = 1; + } + if(missile[mi]._miAnimFrame < 1) { + missile[mi]._miAnimFrame = missile[mi]._miAnimLen; + } + } + } + } + + if(ManashieldFlag) { + for(i = 0; i < nummissiles; i++) { + mi = missileactive[i]; + if(missile[mi]._mitype == MIS_MANASHIELD) { + MI_Manashield(mi); + } + } + } + + i = 0; + while(i < nummissiles) { + mi = missileactive[i]; + if(missile[mi]._miDelFlag) { + DeleteMissile(mi, i); + i = 0; + } else { + i++; + } + } +} + +void missiles_process_charge() +{ + int i, mi; + MissileStruct *miss; + CMonster *monst; + AnimStruct *anim; + + for(i = 0; i < nummissiles; i++) { + /// ASSERT: assert((DWORD)i < MAXMISSILES); + mi = missileactive[i]; + /// ASSERT: assert((DWORD)mi < MAXMISSILES); + miss = &missile[mi]; + miss->_miAnimData = misfiledata[miss->_miAnimType].mAnimData[miss->_mimfnum]; + if(miss->_mitype == MIS_RHINO) { + monst = monster[miss->_misource].MType; + if(monst->mtype >= MT_HORNED && monst->mtype <= MT_OBLORD) { + anim = &monst->Anims[5]; + } else if(monst->mtype >= MT_NSNAKE && monst->mtype <= MT_GSNAKE) { + anim = &monst->Anims[2]; + } else { + anim = &monst->Anims[1]; + } + missile[mi]._miAnimData = anim->Frames[miss->_mimfnum]; + } + } +} + +void ClearMissileSpot(int mi) +{ + /// ASSERT: assert((DWORD)mi < MAXMISSILES); + dFlags[missile[mi]._mix][missile[mi]._miy] &= ~1; + dMissile[missile[mi]._mix][missile[mi]._miy] = 0; +} diff --git a/2020_03_31/Source/missiles.h b/2020_03_31/Source/missiles.h new file mode 100644 index 00000000..28991c32 --- /dev/null +++ b/2020_03_31/Source/missiles.h @@ -0,0 +1,154 @@ +//HEADER_GOES_HERE +#ifndef __MISSILES_H__ +#define __MISSILES_H__ + +extern int missileactive[MAXMISSILES]; +extern int missileavail[MAXMISSILES]; +extern MissileStruct missile[MAXMISSILES]; +extern int nummissiles; // idb +extern int ManashieldFlag; +extern ChainStruct chain[MAXMISSILES]; +extern int MissilePreFlag; // weak +extern int numchains; // weak + +void GetDamageAmt(int i, int *mind, int *maxd); +BOOL CheckBlock(int fx, int fy, int tx, int ty); +int FindClosest(int sx, int sy, int rad); +int GetSpellLevel(int id, int sn); +int GetDirection8(int x1, int y1, int x2, int y2); +int GetDirection16(int x1, int y1, int x2, int y2); +void DeleteMissile(int mi, int i); +void GetMissileVel(int i, int sx, int sy, int dx, int dy, int v); +void PutMissile(int i); +void GetMissilePos(int i); +void MoveMissilePos(int i); +BOOL MonsterTrapHit(int m, int mindam, int maxdam, int dist, int t, BOOLEAN shift); +BOOL MonsterMHit(int pnum, int m, int mindam, int maxdam, int dist, int t, BOOLEAN shift); +BOOL PlayerMHit(int pnum, int m, int dist, int mind, int maxd, int mtype, BOOLEAN shift, int earflag); +BOOL Plr2PlrMHit(int pnum, int p, int mindam, int maxdam, int dist, int mtype, BOOLEAN shift); +void CheckMissileCol(int i, int mindam, int maxdam, BOOLEAN shift, int mx, int my, BOOLEAN nodel); +void SetMissAnim(int mi, int animtype); +void SetMissDir(int mi, int dir); +void LoadMissileGFX(BYTE mi); +void InitMissileGFX(); +void FreeMissileGFX(int mi); +void FreeMissiles(); +void FreeMissiles2(); +void InitMissiles(); +void AddLArrow(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam); +void AddArrow(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam); +void GetVileMissPos(int mi, int dx, int dy); +void AddRndTeleport(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam); +void AddFirebolt(int mi, int sx, int sy, int dx, int dy, int midir, char micaster, int id, int dam); +void AddMagmaball(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam); +void miss_null_33(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam); +void AddTeleport(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam); +void AddLightball(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam); +void AddFirewall(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam); +void AddFireball(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam); +void AddLightctrl(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam); +void AddLightning(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam); +void AddMisexp(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam); +void AddWeapexp(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam); +BOOL CheckIfTrig(int x, int y); +void AddTown(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam); +void AddFlash(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam); +void AddFlash2(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam); +void AddManashield(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam); +void AddFiremove(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam); +void AddGuardian(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam); +void AddChain(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam); +void miss_null_11(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam); +void miss_null_12(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam); +void miss_null_13(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam); +void AddRhino(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam); +void miss_null_32(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam); +void AddFlare(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam); +void AddAcid(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam); +void miss_null_1D(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam); +void AddAcidpud(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam); +void AddStone(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam); +void AddGolem(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam); +void AddEtherealize(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam); +void miss_null_1F(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam); +void miss_null_23(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam); +void AddBoom(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam); +void AddHeal(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam); +void AddHealOther(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam); +void AddElement(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam); +void AddIdentify(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam); +void AddFirewallC(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam); +void AddInfra(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam); +void AddWave(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam); +void AddNova(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam); +void AddBlodboil(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam); +void AddRepair(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam); +void AddRecharge(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam); +void AddDisarm(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam); +void AddApoca(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam); +void AddFlame(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam); +void AddFlamec(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam); +void AddCbolt(int mi, int sx, int sy, int dx, int dy, int midir, char micaster, int id, int dam); +void AddHbolt(int mi, int sx, int sy, int dx, int dy, int midir, char micaster, int id, int dam); +void AddResurrect(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam); +void AddResurrectBeam(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam); +void AddTelekinesis(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam); +void AddBoneSpirit(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam); +void AddRportal(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam); +void AddDiabApoca(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam); +int AddMissile(int sx, int sy, int v1, int v2, int midir, int mitype, char micaster, int id, int v3, int spllvl); +int Sentfire(int i, int sx, int sy); +void MI_Dummy(int i); +void MI_Golem(int i); +void MI_SetManashield(int i); +void MI_LArrow(int i); +void MI_Arrow(int i); +void MI_Firebolt(int i); +void MI_Lightball(int i); +void mi_null_33(int i); +void MI_Acidpud(int i); +void MI_Firewall(int i); +void MI_Fireball(int i); +void MI_Lightctrl(int i); +void MI_Lightning(int i); +void MI_Town(int i); +void MI_Flash(int i); +void MI_Flash2(int i); +void MI_Manashield(int i); +void MI_Etherealize(int i); +void MI_Firemove(int i); +void MI_Guardian(int i); +void MI_Chain(int i); +void mi_null_11(int i); +void MI_Weapexp(int i); +void MI_Misexp(int i); +void MI_Acidsplat(int i); +void MI_Teleport(int i); +void MI_Stone(int i); +void MI_Boom(int i); +void MI_Rhino(int i); +void mi_null_32(int i); +void MI_FirewallC(int i); +void MI_Infra(int i); +void MI_Apoca(int i); +void MI_Wave(int i); +void MI_Nova(int i); +void MI_Blodboil(int i); +void MI_Flame(int i); +void MI_Flamec(int i); +void MI_Cbolt(int i); +void MI_Hbolt(int i); +void MI_Element(int i); +void MI_Bonespirit(int i); +void MI_ResurrectBeam(int i); +void MI_Rportal(int i); +void ProcessMissiles(); +void missiles_process_charge(); +void ClearMissileSpot(int mi); + +/* rdata */ + +extern int XDirAdd[8]; +extern int YDirAdd[8]; + +#endif /* __MISSILES_H__ */ diff --git a/2020_03_31/Source/monstdat.cpp b/2020_03_31/Source/monstdat.cpp new file mode 100644 index 00000000..241f55c4 --- /dev/null +++ b/2020_03_31/Source/monstdat.cpp @@ -0,0 +1,44 @@ +#include "diablo.h" + +MonsterData monsterdata[112] = +{ +#include "Data/xl_monst.cpp" +}; + +char MonstConvTbl[128] = +{ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 29, 30, + 31, 32, 34, 35, 36, 37, 38, 40, 39, 41, + 42, 43, 44, 45, 46, 47, 48, 49, 50, 52, + 53, 54, 55, 56, 57, 59, 58, 60, 61, 62, + 63, 64, 65, 66, 67, 68, 69, 70, 71, 0, + 0, 0, 0, 72, 73, 74, 75, 0, 0, 0, + 0, 77, 76, 78, 79, 81, 82, 83, 84, 85, + 86, 87, 88, 89, 90, 92, 91, 93, 94, 95, + 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, + 106, 107, 108, 0, 110, 0, 109, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 80, 111 +}; + +unsigned char MonstAvailTbl[112] = +{ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 0, 2, + 2, 2, 2, 0, 2, 2, 2, 2, 1, 1, + 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, + 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, + 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, + 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, + 0, 2, 2, 2, 2, 2, 2, 2, 2, 0, + 0, 0 +}; + +UniqMonstStruct UniqMonst[98] = +{ +#include "Data/xl_umon.cpp" +}; diff --git a/2020_03_31/Source/monstdat.h b/2020_03_31/Source/monstdat.h new file mode 100644 index 00000000..c15d9934 --- /dev/null +++ b/2020_03_31/Source/monstdat.h @@ -0,0 +1,10 @@ +//HEADER_GOES_HERE +#ifndef __MONSTDAT_H__ +#define __MONSTDAT_H__ + +extern MonsterData monsterdata[112]; +extern char MonstConvTbl[128]; +extern unsigned char MonstAvailTbl[112]; +extern UniqMonstStruct UniqMonst[98]; + +#endif /* __MONSTDAT_H__ */ diff --git a/2020_03_31/Source/monster.cpp b/2020_03_31/Source/monster.cpp new file mode 100644 index 00000000..7745f1fb --- /dev/null +++ b/2020_03_31/Source/monster.cpp @@ -0,0 +1,5901 @@ +#include "diablo.h" +#include "../3rdParty/Storm/Source/storm.h" + +int MissileFileFlag; // weak +int monstkills[MAXMONSTERS]; +int monstactive[MAXMONSTERS]; +int nummonsters; +BOOLEAN sgbSaveSoundOn; // weak +MonsterStruct monster[MAXMONSTERS]; +int totalmonsters; // weak +CMonster Monsters[16]; +BYTE GraphicTable[NUMLEVELS][MAX_LVLMTYPES]; /* unused */ +// int END_Monsters_17; // weak +int monstimgtot; // weak +int uniquetrans; +int nummtypes; + +/* data */ + +int MWVel[24][3] = +{ + { 256, 512, 1024 }, + { 128, 256, 512 }, + { 85, 170, 341 }, + { 64, 128, 256 }, + { 51, 102, 204 }, + { 42, 85, 170 }, + { 36, 73, 146 }, + { 32, 64, 128 }, + { 28, 56, 113 }, + { 26, 51, 102 }, + { 23, 46, 93 }, + { 21, 42, 85 }, + { 19, 39, 78 }, + { 18, 36, 73 }, + { 17, 34, 68 }, + { 16, 32, 64 }, + { 15, 30, 60 }, + { 14, 28, 57 }, + { 13, 26, 54 }, + { 12, 25, 51 }, + { 12, 24, 48 }, + { 11, 23, 46 }, + { 11, 22, 44 }, + { 10, 21, 42 } +}; +char animletter[7] = "nwahds"; +int left[8] = { 7, 0, 1, 2, 3, 4, 5, 6 }; +int right[8] = { 1, 2, 3, 4, 5, 6, 7, 0 }; +int opposite[8] = { 4, 5, 6, 7, 0, 1, 2, 3 }; +int offset_x[8] = { 1, 0, -1, -1, -1, 0, 1, 1 }; +int offset_y[8] = { 1, 1, 1, 0, -1, -1, -1, 0 }; + +/* unused */ +int rnd5[4] = { 5, 10, 15, 20 }; +int rnd10[4] = { 10, 15, 20, 30 }; +int rnd20[4] = { 20, 30, 40, 50 }; +int rnd60[4] = { 60, 70, 80, 90 }; +// + +void (*AiProc[])(int i) = +{ + &MAI_Zombie, + &MAI_Fat, + &MAI_SkelSd, + &MAI_SkelBow, + &MAI_Scav, + &MAI_Rhino, + &MAI_GoatMc, + &MAI_GoatBow, + &MAI_Fallen, + &MAI_Magma, + &MAI_SkelKing, + &MAI_Bat, + &MAI_Garg, + &MAI_Cleaver, + &MAI_Succ, + &MAI_Sneak, + &MAI_Storm, + &MAI_Fireman, + &MAI_Garbud, + &MAI_Acid, + &MAI_AcidUniq, + &MAI_Golum, + &MAI_Zhar, + &MAI_SnotSpil, + &MAI_Snake, + &MAI_Counselor, + &MAI_Mega, + &MAI_Diablo, + &MAI_Lazurus, + &MAI_Lazhelp, + &MAI_Lachdanan, + &MAI_Warlord +}; + +void InitMonsterTRN(int monst, BOOL special) +{ + int i, a, d; + BYTE *t; + + /// ASSERT: assert((DWORD)monst < MAX_LVLMTYPES); + + t = Monsters[monst].trans_file; + for(i = 256; i != 0; i--) { + if(*t == 255) { + *t = 0; + } + t++; + } + + if(special) { + a = 6; + } else { + a = 5; + } + for(i = 0; i < a; i++) { + if(i == 1 && Monsters[monst].mtype >= MT_COUNSLR && Monsters[monst].mtype <= MT_ADVOCATE) { + continue; + } + for(d = 0; d < 8; d++) { + Cl2ApplyTrans(Monsters[monst].Anims[i].Frames[d], Monsters[monst].trans_file, Monsters[monst].Anims[i].Rate); + } + } +} + +void InitLevelMonsters() +{ + int i; + + nummtypes = 0; + monstimgtot = 0; + MissileFileFlag = 0; + + for(i = 0; i < 16; i++) { + Monsters[i].mPlaceFlags = 0; + } + + ClrAllMonsters(); + nummonsters = 0; + totalmonsters = MAXMONSTERS; + + for(i = 0; i < MAXMONSTERS; i++) { + monstactive[i] = i; + } + + uniquetrans = 0; +} + +int AddMonsterType(int type, int placeflag) +{ + int i; + BOOL done; + + done = FALSE; + /// ASSERT: assert((DWORD)nummtypes <= MAX_LVLMTYPES); + for(i = 0; i < nummtypes && !done; i++) { + done = Monsters[i].mtype == type; + } + + i--; + if(!done) { + i = nummtypes++; + Monsters[i].mtype = type; + monstimgtot += monsterdata[type].mType; + InitMonsterGFX(i); + InitMonsterSND(i); + } + + Monsters[i].mPlaceFlags |= placeflag; + return i; +} + +void GetLevelMTypes() +{ + int i, minl, maxl, mt, nt, numskeltypes, rv; + int typelist[MAXMONSTERS]; + int skeltypes[111]; + char mamask; + + mamask = 3; + AddMonsterType(MT_GOLEM, 2); + + if(currlevel == 16) { + AddMonsterType(MT_ADVOCATE, 1); + AddMonsterType(MT_RBLACK, 1); + AddMonsterType(MT_DIABLO, 2); + return; + } + + if(!setlevel) { + if(QuestStatus(Q_BUTCHER)) { + AddMonsterType(MT_CLEAVER, 2); + } + if(QuestStatus(Q_GARBUD)) { + AddMonsterType(UniqMonst[0].mtype, 4); + } + if(QuestStatus(Q_ZHAR)) { + AddMonsterType(UniqMonst[2].mtype, 4); + } + if(QuestStatus(Q_LTBANNER)) { + AddMonsterType(UniqMonst[3].mtype, 4); + } + if(QuestStatus(Q_VEIL)) { + AddMonsterType(UniqMonst[7].mtype, 4); + } + if(QuestStatus(Q_WARLORD)) { + AddMonsterType(UniqMonst[8].mtype, 4); + } + if(gbMaxPlayers != 1 && currlevel == quests[Q_SKELKING]._qlevel) { + AddMonsterType(MT_SKING, 4); + numskeltypes = 0; + for(i = 8; i <= 27; i++) { + if(IsSkel(i)) { + minl = 15 * monsterdata[i].mMinDLvl / 30 + 1; + maxl = 15 * monsterdata[i].mMaxDLvl / 30 + 1; + if(currlevel >= minl && currlevel <= maxl && MonstAvailTbl[i] & mamask) { + skeltypes[numskeltypes++] = i; + } + } + } + AddMonsterType(skeltypes[random(88, numskeltypes)], 1); + } + nt = 0; + for(i = 0; i < 111; i++) { + minl = 15 * monsterdata[i].mMinDLvl / 30 + 1; + maxl = 15 * monsterdata[i].mMaxDLvl / 30 + 1; + if(currlevel >= minl && currlevel <= maxl && MonstAvailTbl[i] & mamask) { + typelist[nt++] = i; + } + } + if(monstdebug) { + for (i = 0; i < debugmonsttypes; i++) { + AddMonsterType(DebugMonsters[i], 1); + } + } else { + while(nt > 0 && nummtypes < 16 && monstimgtot < 4000) { + i = 0; + while(i < nt) { + mt = typelist[i]; + if(monsterdata[mt].mType > 4000 - monstimgtot) { + nt--; + typelist[i] = typelist[nt]; + } else { + i++; + } + } + if(nt != 0) { + rv = random(88, nt); + mt = typelist[rv]; + AddMonsterType(mt, 1); + nt--; + typelist[rv] = typelist[nt]; + } + } + } + } else { + if(setlvlnum == SL_SKELKING) { + AddMonsterType(MT_SKING, 4); + } + } +} + +void InitMonsterGFX(int monst) +{ + int i, anim, mtype; + char strBuff[256]; + BYTE *p; + + /// ASSERT: assert((DWORD)monst < MAX_LVLMTYPES); + mtype = Monsters[monst].mtype; + + for(anim = 0; anim < 6; anim++) { + if((animletter[anim] != 's' || monsterdata[mtype].has_special) && monsterdata[mtype].Frames[anim] > 0) { + sprintf(strBuff, monsterdata[mtype].GraphicType, animletter[anim]); + /// ASSERT: assert(! Monsters[monst].Anims[anim].CMem); + Monsters[monst].Anims[anim].CMem = DiabLoad(strBuff, NULL, 'MONS'); + p = Monsters[monst].Anims[anim].CMem; + if(Monsters[monst].mtype == MT_GOLEM && (animletter[anim] == 's' || animletter[anim] == 'd')) { + for(i = 0; i < 8; i++) { + Monsters[monst].Anims[anim].Frames[i] = p; + } + } else { + for(i = 0; i < 8; i++) { + Monsters[monst].Anims[anim].Frames[i] = &p[((DWORD *)p)[i]]; + } + } + } + Monsters[monst].Anims[anim].Rate = monsterdata[mtype].Frames[anim]; + Monsters[monst].Anims[anim].Delay = monsterdata[mtype].Rate[anim]; + } + + Monsters[monst].flags_1 = monsterdata[mtype].flags; + Monsters[monst].flags_2 = (monsterdata[mtype].flags - 64) >> 1; + Monsters[monst].mMinHP = monsterdata[mtype].mMinHP; + Monsters[monst].mMaxHP = monsterdata[mtype].mMaxHP; + Monsters[monst].has_special = monsterdata[mtype].has_special; + Monsters[monst].mAFNum = monsterdata[mtype].mAFNum; + Monsters[monst].MData = &monsterdata[mtype]; + + if(monsterdata[mtype].has_trans) { + Monsters[monst].trans_file = DiabLoad(monsterdata[mtype].TransFile, NULL, 'MONS'); + InitMonsterTRN(monst, monsterdata[mtype].has_special); + MemFreeDbg(Monsters[monst].trans_file); + } + + if(mtype >= MT_NMAGMA && mtype <= MT_WMAGMA && !(MissileFileFlag & 1)) { + MissileFileFlag |= 1; + LoadMissileGFX(MFILE_MAGBALL); + } + if(mtype >= MT_STORM && mtype <= MT_MAEL && !(MissileFileFlag & 2)) { + MissileFileFlag |= 2; + LoadMissileGFX(MFILE_THINLGHT); + } + if(mtype == MT_SUCCUBUS && !(MissileFileFlag & 4)) { + MissileFileFlag |= 4; + LoadMissileGFX(MFILE_FLARE); + LoadMissileGFX(MFILE_FLAREEXP); + } + if(mtype == MT_SNOWWICH && !(MissileFileFlag & 0x20)) { + MissileFileFlag |= 0x20; + LoadMissileGFX(MFILE_SCUBMISB); + LoadMissileGFX(MFILE_SCBSEXPB); + } + if(mtype == MT_HLSPWN && !(MissileFileFlag & 0x40)) { + MissileFileFlag |= 0x40; + LoadMissileGFX(MFILE_SCUBMISD); + LoadMissileGFX(MFILE_SCBSEXPD); + } + if(mtype == MT_SOLBRNR && !(MissileFileFlag & 0x80)) { + MissileFileFlag |= 0x80; + LoadMissileGFX(MFILE_SCUBMISC); + LoadMissileGFX(MFILE_SCBSEXPC); + } + if(mtype >= MT_INCIN && mtype <= MT_HELLBURN && !(MissileFileFlag & 8)) { + MissileFileFlag |= 8; + LoadMissileGFX(MFILE_KRULL); + } + if(mtype >= MT_NACID && mtype <= MT_XACID && !(MissileFileFlag & 0x10)) { + MissileFileFlag |= 0x10; + LoadMissileGFX(MFILE_ACIDBF); + LoadMissileGFX(MFILE_ACIDSPLA); + LoadMissileGFX(MFILE_ACIDPUD); + } + if(mtype == MT_DIABLO) { + LoadMissileGFX(MFILE_FIREPLAR); + } +} + +void ClearMVars(int i) +{ + /// ASSERT: assert((DWORD)i < MAXMONSTERS); + + monster[i]._mVar1 = 0; + monster[i]._mVar2 = 0; + monster[i]._mVar3 = 0; + monster[i]._mVar4 = 0; + monster[i]._mVar5 = 0; + monster[i]._mVar6 = 0; + monster[i]._mVar7 = 0; + monster[i]._mVar8 = 0; +} + +void InitMonster(int i, int rd, int mtype, int x, int y) +{ + CMonster *monst; + + /// ASSERT: assert((DWORD)i < MAXMONSTERS); + /// ASSERT: assert((DWORD)mtype < MAX_LVLMTYPES); + monst = &Monsters[mtype]; + /// ASSERT: assert(monst->MData != NULL); + + monster[i]._mdir = rd; + monster[i]._mx = x; + monster[i]._my = y; + monster[i]._mfutx = x; + monster[i]._mfuty = y; + monster[i]._moldx = x; + monster[i]._moldy = y; + monster[i]._mMTidx = mtype; + monster[i]._mmode = MM_STAND; + monster[i].mName = monst->MData->mName; + monster[i].MType = monst; + monster[i].MData = monst->MData; + monster[i]._mAnimData = monst->Anims[0].Frames[rd]; + monster[i]._mAnimDelay = monst->Anims[0].Delay; + monster[i]._mAnimCnt = random(88, monster[i]._mAnimDelay - 1); + monster[i]._mAnimLen = monst->Anims[0].Rate; + monster[i]._mAnimFrame = random(88, monster[i]._mAnimLen - 1) + 1; + if(monst->mtype == MT_DIABLO) { + monster[i]._mmaxhp = (random(88, 1) + 1666) << 6; + } else { + monster[i]._mmaxhp = (random(88, monst->mMaxHP - monst->mMinHP + 1) + monst->mMinHP) << 6; + } + if(gbMaxPlayers == 1) { + monster[i]._mmaxhp >>= 1; + if(monster[i]._mmaxhp < 64) { + monster[i]._mmaxhp = 64; + } + } + monster[i]._mhitpoints = monster[i]._mmaxhp; + monster[i]._mAi = monst->MData->mAi; + monster[i]._mint = monst->MData->mInt; + monster[i]._mgoal = 1; + monster[i]._mgoalvar1 = 0; + monster[i]._mgoalvar2 = 0; + monster[i]._mgoalvar3 = 0; + monster[i].field_18 = 0; + monster[i]._pathcount = 0; + monster[i]._mDelFlag = 0; + monster[i]._uniqtype = 0; + monster[i]._msquelch = 0; + monster[i]._mRndSeed = GetRndSeed(); + monster[i]._mAISeed = GetRndSeed(); + monster[i].mWhoHit = 0; + monster[i].mLevel = monst->MData->mLevel; + monster[i].mExp = monst->MData->mExp; + monster[i].mHit = monst->MData->mHit; + monster[i].mMinDamage = monst->MData->mMinDamage; + monster[i].mMaxDamage = monst->MData->mMaxDamage; + monster[i].mHit2 = monst->MData->mHit2; + monster[i].mMinDamage2 = monst->MData->mMinDamage2; + monster[i].mMaxDamage2 = monst->MData->mMaxDamage2; + monster[i].mArmorClass = monst->MData->mArmorClass; + monster[i].mMagicRes = monst->MData->mMagicRes; + monster[i].leader = 0; + monster[i].leaderflag = 0; + monster[i]._mFlags = monst->MData->mFlags; + monster[i].mtalkmsg = 0; + + if(monster[i]._mAi == AI_GARG) { + monster[i]._mAnimData = monst->Anims[5].Frames[rd]; + monster[i]._mAnimFrame = 1; + monster[i]._mFlags |= 4; + monster[i]._mmode = MM_SATTACK; + } + + if(gnDifficulty == DIFF_NIGHTMARE) { + monster[i]._mmaxhp = 3 * monster[i]._mmaxhp + 64; + monster[i]._mhitpoints = monster[i]._mmaxhp; + monster[i].mLevel += 15; + monster[i].mExp = 2 * (monster[i].mExp + 1000); + monster[i].mHit += 85; + monster[i].mMinDamage = 2 * (monster[i].mMinDamage + 2); + monster[i].mMaxDamage = 2 * (monster[i].mMaxDamage + 2); + monster[i].mHit2 += 85; + monster[i].mMinDamage2 = 2 * (monster[i].mMinDamage2 + 2); + monster[i].mMaxDamage2 = 2 * (monster[i].mMaxDamage2 + 2); + monster[i].mArmorClass += 50; + } + if(gnDifficulty == DIFF_HELL) { + monster[i]._mmaxhp = 4 * monster[i]._mmaxhp + 192; + monster[i]._mhitpoints = monster[i]._mmaxhp; + monster[i].mLevel += 30; + monster[i].mExp = 4 * (monster[i].mExp + 1000); + monster[i].mHit += 120; + monster[i].mMinDamage = 4 * monster[i].mMinDamage + 6; + monster[i].mMaxDamage = 4 * monster[i].mMaxDamage + 6; + monster[i].mHit2 += 120; + monster[i].mMinDamage2 = 4 * monster[i].mMinDamage2 + 6; + monster[i].mMaxDamage2 = 4 * monster[i].mMaxDamage2 + 6; + monster[i].mArmorClass += 80; + monster[i].mMagicRes = monst->MData->mMagicRes2; + } +} + +void ClrAllMonsters() +{ + int i; + /* MonsterStruct *Monst; */ + + for(i = 0; i < MAXMONSTERS; i++) { + ClearMVars(i); + monster[i].mName = "Invalid Monster"; + monster[i]._mgoal = 0; + monster[i]._mmode = 0; + monster[i]._mVar1 = 0; + monster[i]._mVar2 = 0; + monster[i]._mx = 0; + monster[i]._my = 0; + monster[i]._mfutx = 0; + monster[i]._mfuty = 0; + monster[i]._moldx = 0; + monster[i]._moldy = 0; + monster[i]._mdir = random(89, 8); + monster[i]._mxvel = 0; + monster[i]._myvel = 0; + monster[i]._mAnimData = 0; + monster[i]._mAnimDelay = 0; + monster[i]._mAnimCnt = 0; + monster[i]._mAnimLen = 0; + monster[i]._mAnimFrame = 0; + monster[i]._mFlags = 0; + monster[i]._mDelFlag = 0; + monster[i]._menemy = random(89, gbActivePlayers); + monster[i]._menemyx = plr[monster[i]._menemy]._px; + monster[i]._menemyy = plr[monster[i]._menemy]._py; + } +} + +BOOL MonstPlace(int xp, int yp) +{ + if(xp < 0 || xp >= MAXDUNX || yp < 0 || yp >= MAXDUNY) { + return FALSE; + } + if(dMonster[xp][yp] != 0) { + return FALSE; + } + if(dPlayer[xp][yp] != 0) { + return FALSE; + } + if(dFlags[xp][yp] & 2) { + return FALSE; + } + if(dFlags[xp][yp] & 8) { + return FALSE; + } + if(SolidLoc(xp, yp)) { + return FALSE; + } + + return TRUE; +} + +void PlaceMonster(int i, int mtype, int x, int y) +{ + int rd; + + dMonster[x][y] = i + 1; + rd = random(90, 8); + InitMonster(i, rd, mtype, x, y); +} + +void PlaceUniqueMonst(int uniqindex, int miniontype, int packsize) +{ + UniqMonstStruct *Uniq; + MonsterStruct *Monst; + int xp, yp, x, y, count, count2, uniqtype, i; + BOOL done, zharflag; + char filestr[64]; + + /// ASSERT: assert((DWORD)nummonsters < MAXMONSTERS); + Uniq = &UniqMonst[uniqindex]; + Monst = &monster[nummonsters]; + count = 0; + + if((uniquetrans << 8) + 4864 >= LIGHTSIZE) { + return; + } + + /// ASSERT: assert((DWORD)nummtypes <= MAX_LVLMTYPES); + for(uniqtype = 0; uniqtype < nummtypes; uniqtype++) { + if(Monsters[uniqtype].mtype == UniqMonst[uniqindex].mtype) { + break; + } + } + /// ASSERT: assert(uniqtype < nummtypes); + + while(1) { + x = random(91, 80) + 16; + y = random(91, 80) + 16; + count2 = 0; + for(xp = x - 3; xp < x + 3; xp++) { + for(yp = y - 3; yp < y + 3; yp++) { + if(yp >= 0 && yp < MAXDUNY && xp >= 0 && xp < MAXDUNX && MonstPlace(xp, yp)) { + count2++; + } + } + } + if(count2 < 9) { + count++; + if(count < 1000) { + continue; + } + } + if(MonstPlace(x, y)) { + break; + } + } + if(uniqindex == 3) { + x = 2 * setpc_x + 24; + y = 2 * setpc_y + 28; + } + if(uniqindex == 8) { + x = 2 * setpc_x + 22; + y = 2 * setpc_y + 23; + } + if(uniqindex == 2) { + zharflag = TRUE; + for(i = 0; i < themeCount; i++) { + if(i == zharlib && zharflag == TRUE) { + zharflag = FALSE; + x = 2 * themeLoc[i].x + 20; + y = 2 * themeLoc[i].y + 20; + } + } + } + if(gbMaxPlayers == 1) { + if(uniqindex == 4) { + x = 32; + y = 46; + } + if(uniqindex == 5) { + x = 40; + y = 45; + } + if(uniqindex == 6) { + x = 38; + y = 49; + } + if(uniqindex == 1) { + x = 35; + y = 47; + } + } else { + if(uniqindex == 4) { + x = 2 * setpc_x + 19; + y = 2 * setpc_y + 22; + } + if(uniqindex == 5) { + x = 2 * setpc_x + 21; + y = 2 * setpc_y + 19; + } + if(uniqindex == 6) { + x = 2 * setpc_x + 21; + y = 2 * setpc_y + 25; + } + } + if(uniqindex == 9) { + done = FALSE; + for(y = 0; y < MAXDUNY && !done; y++) { + for(x = 0; x < MAXDUNX && !done; x++) { + done = dPiece[x][y] == 367; + } + } + } + + PlaceMonster(nummonsters, uniqtype, x, y); + + Monst->_uniqtype = uniqindex + 1; + if(Uniq->mlevel) { + Monst->mLevel = 2 * Uniq->mlevel; + } else { + Monst->mLevel += 5; + } + Monst->mExp *= 2; + Monst->mName = Uniq->mName; + Monst->_mmaxhp = Uniq->mmaxhp << 6; + if(gbMaxPlayers == 1) { + Monst->_mmaxhp >>= 1; + if(Monst->_mmaxhp < 64) { + Monst->_mmaxhp = 64; + } + } + Monst->_mhitpoints = Monst->_mmaxhp; + Monst->_mAi = Uniq->mAi; + Monst->_mint = Uniq->mint; + Monst->mMinDamage = Uniq->mMinDamage; + Monst->mMaxDamage = Uniq->mMaxDamage; + Monst->mMinDamage2 = Uniq->mMinDamage; + Monst->mMaxDamage2 = Uniq->mMaxDamage; + Monst->mMagicRes = Uniq->mMagicRes; + Monst->mtalkmsg = Uniq->mtalkmsg; + Monst->mlid = AddLight(Monst->_mx, Monst->_my, 3); + + if(gbMaxPlayers == 1) { + if(Monst->mtalkmsg != 0) { + Monst->_mgoal = 6; + } + } else { + if(Monst->_mAi == AI_LAZHELP) { + Monst->mtalkmsg = 0; + } + if(Monst->_mAi == AI_LAZURUS && quests[Q_BETRAYER]._qvar1 > 3) { + Monst->_mgoal = 1; + } else if(Monst->mtalkmsg != 0) { + Monst->_mgoal = 6; + } + } + + if(gnDifficulty == DIFF_NIGHTMARE) { + Monst->_mmaxhp = 3 * Monst->_mmaxhp + 64; + Monst->_mhitpoints = Monst->_mmaxhp; + Monst->mLevel += 15; + Monst->mExp = 2 * (Monst->mExp + 1000); + Monst->mMinDamage = 2 * (Monst->mMinDamage + 2); + Monst->mMaxDamage = 2 * (Monst->mMaxDamage + 2); + Monst->mMinDamage2 = 2 * (Monst->mMinDamage2 + 2); + Monst->mMaxDamage2 = 2 * (Monst->mMaxDamage2 + 2); + } + if(gnDifficulty == DIFF_HELL) { + Monst->_mmaxhp = 4 * Monst->_mmaxhp + 192; + Monst->_mhitpoints = Monst->_mmaxhp; + Monst->mLevel += 30; + Monst->mExp = 4 * (Monst->mExp + 1000); + Monst->mMinDamage = 4 * Monst->mMinDamage + 6; + Monst->mMaxDamage = 4 * Monst->mMaxDamage + 6; + Monst->mMinDamage2 = 4 * Monst->mMinDamage2 + 6; + Monst->mMaxDamage2 = 4 * Monst->mMaxDamage2 + 6; + } + + sprintf(filestr, "Monsters\\Monsters\\%s.TRN", Uniq->mTrnName); + /// ASSERT: assert((uniquetrans << 8) + 4864 < LIGHTSIZE); + LoadFileWithMem(filestr, &pLightTbl[(uniquetrans << 8) + 4864]); + Monst->_uniqtrans = uniquetrans; + uniquetrans++; + + if(Uniq->mUnqAttr & 4) { + Monst->mHit = Uniq->mUnqVar1; + Monst->mHit2 = Uniq->mUnqVar1; + } + if(Uniq->mUnqAttr & 8) { + Monst->mArmorClass = Uniq->mUnqVar1; + } + + nummonsters++; + + if(Uniq->mUnqAttr & 1) { + PlaceGroup(miniontype, packsize, Uniq->mUnqAttr, nummonsters - 1); + } + + if(Monst->_mAi != AI_GARG) { + Monst->_mAnimData = Monst->MType->Anims[0].Frames[Monst->_mdir]; + Monst->_mAnimFrame = random(88, Monst->_mAnimLen - 1) + 1; + Monst->_mFlags &= ~4; + Monst->_mmode = MM_STAND; + } +} + +void PlaceQuestMonsters() +{ + int skeltype; + BYTE *setp; + + if(!setlevel) { + if(QuestStatus(Q_BUTCHER)) { + PlaceUniqueMonst(9, 0, 0); + } + if(currlevel == quests[Q_SKELKING]._qlevel && gbMaxPlayers != 1) { + /// ASSERT: assert((DWORD)nummtypes <= MAX_LVLMTYPES); + for(skeltype = 0; skeltype < nummtypes; skeltype++) { + if(IsSkel(Monsters[skeltype].mtype)) { + break; + } + } + /// ASSERT: assert(skeltype < nummtypes); + PlaceUniqueMonst(1, skeltype, 30); + } + if(QuestStatus(Q_LTBANNER)) { + setp = DiabLoad("Levels\\L1Data\\Banner1.DUN", NULL, 'MONS'); + SetMapMonsters(setp, 2 * setpc_x, 2 * setpc_y); + MemFreeDbg(setp); + } + if(QuestStatus(Q_BLOOD)) { + setp = DiabLoad("Levels\\L2Data\\Blood2.DUN", NULL, 'MONS'); + SetMapMonsters(setp, 2 * setpc_x, 2 * setpc_y); + MemFreeDbg(setp); + } + if(QuestStatus(Q_BLIND)) { + setp = DiabLoad("Levels\\L2Data\\Blind2.DUN", NULL, 'MONS'); + SetMapMonsters(setp, 2 * setpc_x, 2 * setpc_y); + MemFreeDbg(setp); + } + if(QuestStatus(Q_ANVIL)) { + setp = DiabLoad("Levels\\L3Data\\Anvil.DUN", NULL, 'MONS'); + SetMapMonsters(setp, 2 * setpc_x + 2, 2 * setpc_y + 2); + MemFreeDbg(setp); + } + if(QuestStatus(Q_WARLORD)) { + setp = DiabLoad("Levels\\L4Data\\Warlord.DUN", NULL, 'MONS'); + SetMapMonsters(setp, 2 * setpc_x, 2 * setpc_y); + MemFreeDbg(setp); + AddMonsterType(UniqMonst[8].mtype, 1); + } + if(QuestStatus(Q_VEIL)) { + AddMonsterType(UniqMonst[7].mtype, 1); + } + if(QuestStatus(Q_ZHAR) && zharlib == -1) { + quests[Q_ZHAR]._qactive = 0; + } + if(currlevel == quests[Q_BETRAYER]._qlevel && gbMaxPlayers != 1) { + AddMonsterType(UniqMonst[4].mtype, 4); + AddMonsterType(UniqMonst[5].mtype, 4); + PlaceUniqueMonst(4, 0, 0); + PlaceUniqueMonst(5, 0, 0); + PlaceUniqueMonst(6, 0, 0); + setp = DiabLoad("Levels\\L4Data\\Vile1.DUN", NULL, 'MONS'); + SetMapMonsters(setp, 2 * setpc_x, 2 * setpc_y); + MemFreeDbg(setp); + } + } else { + if(setlvlnum == SL_SKELKING) { + PlaceUniqueMonst(1, 0, 0); + } + } +} + +void PlaceGroup(int mtype, int num, int leaderf, int leader) +{ + int xp, yp, x1, y1, j, placed, try1, try2, rd; + + placed = 0; + try1 = 0; + /// ASSERT: assert((DWORD)leader < MAXMONSTERS); + do { + while(placed != 0) { + nummonsters--; + placed--; + /// ASSERT: assert((DWORD)nummonsters < MAXMONSTERS); + /// ASSERT: assert((DWORD)monster[nummonsters]._mx < MAXDUNX); + /// ASSERT: assert((DWORD)monster[nummonsters]._my < MAXDUNY); + dMonster[monster[nummonsters]._mx][monster[nummonsters]._my] = 0; + } + if(leaderf & 1) { + rd = random(92, 8); + x1 = xp = monster[leader]._mx + offset_x[rd]; + y1 = yp = monster[leader]._my + offset_y[rd]; + } else { + do { + x1 = xp = random(93, 80) + 16; + y1 = yp = random(93, 80) + 16; + } while(!MonstPlace(xp, yp)); + } + if(num + nummonsters > totalmonsters) { + num = totalmonsters - nummonsters; + } + j = 0; + try2 = 0; + while(j < num && try2 < 100) { + if(MonstPlace(xp, yp) + && dTransVal[xp][yp] == dTransVal[x1][y1] + && (!(leaderf & 2) || abs(xp - x1) < 4 && abs(yp - y1) < 4)) { + PlaceMonster(nummonsters, mtype, xp, yp); + if(leaderf & 1) { + monster[nummonsters]._mmaxhp *= 2; + monster[nummonsters]._mhitpoints = monster[nummonsters]._mmaxhp; + monster[nummonsters]._mint = monster[leader]._mint; + if(leaderf & 2) { + monster[nummonsters].leader = leader; + monster[nummonsters].leaderflag = 1; + monster[nummonsters]._mAi = monster[leader]._mAi; + } + if(monster[nummonsters]._mAi != AI_GARG) { + monster[nummonsters]._mAnimData = monster[nummonsters].MType->Anims[0].Frames[monster[nummonsters]._mdir]; + monster[nummonsters]._mAnimFrame = random(88, monster[nummonsters]._mAnimLen - 1) + 1; + monster[nummonsters]._mFlags &= ~4; + monster[nummonsters]._mmode = MM_STAND; + } + } + nummonsters++; + placed++; + j++; + } else { + try2++; + } + xp += offset_x[random(94, 8)]; + yp += offset_x[random(94, 8)]; /// BUGFIX: should use 'offset_y' + } + if(placed >= num) { + break; + } + try1++; + } while(try1 < 10); + + if(leaderf & 2) { + monster[leader].packsize = placed; + } +} + +void LoadDiabMonsts() +{ + BYTE *lpSetPiece; + + lpSetPiece = DiabLoad("Levels\\L4Data\\diab1.DUN", NULL, 'STPC'); + SetMapMonsters(lpSetPiece, 2 * diabquad1x, 2 * diabquad1y); + MemFreeDbg(lpSetPiece); + lpSetPiece = DiabLoad("Levels\\L4Data\\diab2a.DUN", NULL, 'STPC'); + SetMapMonsters(lpSetPiece, 2 * diabquad2x, 2 * diabquad2y); + MemFreeDbg(lpSetPiece); + lpSetPiece = DiabLoad("Levels\\L4Data\\diab3a.DUN", NULL, 'STPC'); + SetMapMonsters(lpSetPiece, 2 * diabquad3x, 2 * diabquad3y); + MemFreeDbg(lpSetPiece); + lpSetPiece = DiabLoad("Levels\\L4Data\\diab4a.DUN", NULL, 'STPC'); + SetMapMonsters(lpSetPiece, 2 * diabquad4x, 2 * diabquad4y); + MemFreeDbg(lpSetPiece); +} + +void InitMonsters() +{ + int i, j, mtype, na, nt, s, t, numscattypes, numplacemonsters; + int scattertypes[111]; + long fv; + + numscattypes = 0; + + if(gbMaxPlayers != 1) { + CheckDungeonClear(); + } + if(!setlevel) { + AddMonster(1, 0, 0, 0, 0); + AddMonster(1, 0, 0, 0, 0); + AddMonster(1, 0, 0, 0, 0); + AddMonster(1, 0, 0, 0, 0); + } + if(!setlevel && currlevel == 16) { + LoadDiabMonsts(); + } + + nt = numtrigs; + if(currlevel == 15) { + nt = 1; + } + + for(i = 0; i < nt; i++) { + for(s = -2; s < 2; s++) { + for(t = -2; t < 2; t++) { + DoVision(s + trigs[i]._tx, t + trigs[i]._ty, 15, 0, 0); + } + } + } + + PlaceQuestMonsters(); + + if(!setlevel) { + PlaceUniques(); + fv = 0; + for(i = 16; i < 96; i++) { + for(j = 16; j < 96; j++) { + if(!SolidLoc(i, j)) { + fv++; + } + } + } + na = fv / 30; + if(gbMaxPlayers != 1) { + na += na >> 1; + } + if(na + nummonsters > 190) { + na = 190 - nummonsters; + } + totalmonsters = na + nummonsters; + /// ASSERT: assert((DWORD)nummtypes <= MAX_LVLMTYPES); + for(i = 0; i < nummtypes; i++) { + if(Monsters[i].mPlaceFlags & 1) { + scattertypes[numscattypes++] = i; + } + } + while(nummonsters < totalmonsters) { + mtype = scattertypes[random(95, numscattypes)]; + if(currlevel != 1 && random(95, 2) != 0) { + if(currlevel == 2) { + numplacemonsters = random(95, 2) + 2; + } else { + numplacemonsters = random(95, 3) + 3; + } + } else { + numplacemonsters = 1; + } + PlaceGroup(mtype, numplacemonsters, 0, 0); + } + } + + for(i = 0; i < nt; i++) { + for(s = -2; s < 2; s++) { + for(t = -2; t < 2; t++) { + DoUnVision(s + trigs[i]._tx, t + trigs[i]._ty, 15); + } + } + } +} + +void PlaceUniques() +{ + int u, mt; + BOOL done; + + for(u = 0; UniqMonst[u].mtype != -1; u++) { +#ifdef _DEBUG + if(UniqMonst[u].mlevel == currlevel || UniqMonst[u].mlevel != 0 && debug_mode_key_d) { +#else + if(UniqMonst[u].mlevel == currlevel) { +#endif + done = FALSE; + /// ASSERT: assert((DWORD)nummtypes <= MAX_LVLMTYPES); + for(mt = 0; mt < nummtypes && !done; mt++) { + done = Monsters[mt].mtype == UniqMonst[u].mtype; + } + mt--; + if(u == 0 && quests[Q_GARBUD]._qactive == 0) { + done = FALSE; + } + if(u == 2 && quests[Q_ZHAR]._qactive == 0) { + done = FALSE; + } + if(u == 3 && quests[Q_LTBANNER]._qactive == 0) { + done = FALSE; + } + if(u == 7 && quests[Q_VEIL]._qactive == 0) { + done = FALSE; + } + if(u == 8 && quests[Q_WARLORD]._qactive == 0) { + done = FALSE; + } + if(done) { + PlaceUniqueMonst(u, mt, 8); + } + } + } +} + +void SetMapMonsters(BYTE *pMap, int startx, int starty) +{ + int i, j, mt, mx, my, mtype; + WORD rw, rh; + WORD *lm; + + AddMonsterType(MT_GOLEM, 2); + AddMonster(1, 0, 0, 0, 0); + AddMonster(1, 0, 0, 0, 0); + AddMonster(1, 0, 0, 0, 0); + AddMonster(1, 0, 0, 0, 0); + + if(setlevel && setlvlnum == SL_VILEBETRAYER) { + AddMonsterType(UniqMonst[4].mtype, 4); + AddMonsterType(UniqMonst[5].mtype, 4); + AddMonsterType(UniqMonst[6].mtype, 4); + PlaceUniqueMonst(4, 0, 0); + PlaceUniqueMonst(5, 0, 0); + PlaceUniqueMonst(6, 0, 0); + } + + lm = (WORD *)pMap; + rw = *lm; + lm++; + rh = *lm; + lm++; + lm += rw * rh; + rw <<= 1; + rh <<= 1; + lm += rw * rh; + + for(j = 0; j < rh; j++) { + for(i = 0; i < rw; i++) { + if(*lm != 0) { + mt = *lm; + mt = MonstConvTbl[mt - 1]; + mtype = AddMonsterType(mt, 2); + mx = i + startx + 16; + my = j + starty + 16; + PlaceMonster(nummonsters++, mtype, mx, my); + } + lm++; + } + } +} + +void DeleteMonster(int i) +{ + int temp; + + /// ASSERT: assert((DWORD)(nummonsters-1) < MAXMONSTERS); + /// ASSERT: assert((DWORD)i < MAXMONSTERS); + nummonsters--; + temp = monstactive[nummonsters]; + monstactive[nummonsters] = monstactive[i]; + monstactive[i] = temp; +} + +int AddMonster(int x, int y, int dir, int mtype, BOOL InMap) +{ + int i; + + if(nummonsters >= MAXMONSTERS) { + return -1; + } + + i = monstactive[nummonsters++]; + + if(InMap) { + dMonster[x][y] = i + 1; + } + + InitMonster(i, dir, mtype, x, y); + + return i; +} + +void NewMonsterAnim(int i, AnimStruct &anim, int md) +{ + MonsterStruct *Monst; + + /// ASSERT: assert((DWORD)i < MAXMONSTERS); + /// ASSERT: assert((DWORD)md < 8); + Monst = &monster[i]; + Monst->_mAnimData = anim.Frames[md]; + Monst->_mAnimLen = anim.Rate; + Monst->_mAnimFrame = 1; + Monst->_mAnimCnt = 0; + Monst->_mAnimDelay = anim.Delay; + Monst->_mdir = md; + Monst->_mFlags &= ~6; +} + +BOOL M_Ranged(int i) +{ + /// ASSERT: assert((DWORD)i < MAXMONSTERS); + return monster[i]._mAi == AI_SKELBOW + || monster[i]._mAi == AI_GOATBOW + || monster[i]._mAi == AI_SUCC + || monster[i]._mAi == AI_LAZHELP; +} + +BOOL M_Talker(int i) +{ + /// ASSERT: assert((DWORD)i < MAXMONSTERS); + return monster[i]._mAi == AI_LAZURUS + || monster[i]._mAi == AI_WARLORD + || monster[i]._mAi == AI_GARBUD + || monster[i]._mAi == AI_ZHAR + || monster[i]._mAi == AI_SNOTSPIL + || monster[i]._mAi == AI_LACHDAN + || monster[i]._mAi == AI_LAZHELP; +} + +void M_Enemy(int i) +{ + int j, mi, pnum, closest, dist, bestdist; + BYTE enemyx, enemyy; + BOOL sameroom, bestsameroom; + MonsterStruct *Monst; + + /// ASSERT: assert((DWORD)i < MAXMONSTERS); + Monst = &monster[i]; + + closest = -1; + bestdist = -1; + bestsameroom = FALSE; + + if(!(Monst->_mFlags & 0x20)) { + for(pnum = 0; pnum < MAX_PLRS; pnum++) { + if(!plr[pnum].plractive || currlevel != plr[pnum].plrlevel || plr[pnum]._pLvlChanging) { + continue; + } + if(plr[pnum]._pHitPoints == 0 && gbMaxPlayers != 1) { + continue; + } + sameroom = dTransVal[Monst->_mx][Monst->_my] == dTransVal[plr[pnum].WorldX][plr[pnum].WorldY]; + if(abs(Monst->_mx - plr[pnum].WorldX) > abs(Monst->_my - plr[pnum].WorldY)) { + dist = abs(Monst->_mx - plr[pnum].WorldX); + } else { + dist = abs(Monst->_my - plr[pnum].WorldY); + } + if(sameroom && !bestsameroom || (sameroom || !bestsameroom) && dist < bestdist || closest == -1) { + Monst->_mFlags &= ~0x10; + closest = pnum; + enemyx = plr[pnum]._px; + enemyy = plr[pnum]._py; + bestdist = dist; + bestsameroom = sameroom; + } + } + } + + /// ASSERT: assert((DWORD)nummonsters <= MAXMONSTERS); + for(j = 0; j < nummonsters; j++) { + mi = monstactive[j]; + if(mi == i) { + continue; + } + if(monster[mi]._mx == 1 && monster[mi]._my == 0) { + continue; + } + if(M_Talker(mi) && monster[mi].mtalkmsg != 0) { + continue; + } + if(!(Monst->_mFlags & 0x20) && (abs(monster[mi]._mx - Monst->_mx) >= 2 || abs(monster[mi]._my - Monst->_my) >= 2) && !M_Ranged(i)) { + continue; + } + if(!(Monst->_mFlags & 0x20) && !(monster[mi]._mFlags & 0x20)) { + continue; + } + sameroom = dTransVal[Monst->_mx][Monst->_my] == dTransVal[monster[mi]._mx][monster[mi]._my]; + if(abs(Monst->_mx - monster[mi]._mx) > abs(Monst->_my - monster[mi]._my)) { + dist = abs(Monst->_mx - monster[mi]._mx); + } else { + dist = abs(Monst->_my - monster[mi]._my); + } + if(sameroom && !bestsameroom || (sameroom || !bestsameroom) && dist < bestdist || closest == -1) { + Monst->_mFlags |= 0x10; + closest = mi; + enemyx = monster[mi]._mfutx; + enemyy = monster[mi]._mfuty; + bestdist = dist; + bestsameroom = sameroom; + } + } + + if(closest != -1) { + Monst->_mFlags &= ~0x400; + Monst->_menemy = closest; + Monst->_menemyx = enemyx; + Monst->_menemyy = enemyy; + } else { + Monst->_mFlags |= 0x400; + } +} + +int M_GetDir(int i) +{ + /// ASSERT: assert((DWORD)i < MAXMONSTERS); + return GetDirection(monster[i]._mx, monster[i]._my, monster[i]._menemyx, monster[i]._menemyy); +} + +void M_CheckEFlag(int i) +{ + int j, x, y, mt; + MICROS *pMap; + + /// ASSERT: assert((DWORD)i < MAXMONSTERS); + x = monster[i]._mx - 1; + y = monster[i]._my + 1; + mt = 0; + + pMap = &dpiece_defs_map_2[x][y]; + if(pMap < &dpiece_defs_map_2[0][0]) { + monster[i]._meflag = 0; + return; + } + + for(j = 2; j < 10; j++) { + mt |= pMap->mt[j]; + } + + if(dSpecial[x][y] | mt) { + monster[i]._meflag = 1; + } else { + monster[i]._meflag = 0; + } +} + +void M_StartStand(int i, int md) +{ + /// ASSERT: assert((DWORD)i < MAXMONSTERS); + /// ASSERT: assert(monster[i].MType != NULL); + ClearMVars(i); + + if(monster[i].MType->mtype == MT_GOLEM) { + NewMonsterAnim(i, monster[i].MType->Anims[1], md); + } else { + NewMonsterAnim(i, monster[i].MType->Anims[0], md); + } + + monster[i]._mVar1 = monster[i]._mmode; + monster[i]._mVar2 = 0; + monster[i]._mmode = MM_STAND; + monster[i]._mxoff = 0; + monster[i]._myoff = 0; + monster[i]._mfutx = monster[i]._mx; + monster[i]._mfuty = monster[i]._my; + monster[i]._moldx = monster[i]._mx; + monster[i]._moldy = monster[i]._my; + monster[i]._mdir = md; + M_CheckEFlag(i); + M_Enemy(i); +} + +void M_StartDelay(int i, int len) +{ + if(len <= 0) { + return; + } + + /// ASSERT: assert((DWORD)i < MAXMONSTERS); + if(monster[i]._mAi != AI_LAZURUS) { + monster[i]._mVar2 = len; + monster[i]._mmode = MM_DELAY; + } +} + +void M_StartSpStand(int i, int md) +{ + /// ASSERT: assert((DWORD)i < MAXMONSTERS); + /// ASSERT: assert(monster[i].MType != NULL); + NewMonsterAnim(i, monster[i].MType->Anims[5], md); + monster[i]._mmode = MM_SPSTAND; + monster[i]._mxoff = 0; + monster[i]._myoff = 0; + monster[i]._mfutx = monster[i]._mx; + monster[i]._mfuty = monster[i]._my; + monster[i]._moldx = monster[i]._mx; + monster[i]._moldy = monster[i]._my; + monster[i]._mdir = md; + M_CheckEFlag(i); +} + +void M_StartWalk(int i, int xvel, int yvel, int xadd, int yadd, int EndDir) +{ + long fx, fy; + + /// ASSERT: assert((DWORD)i < MAXMONSTERS); + /// ASSERT: assert(monster[i].MType != NULL); + fx = monster[i]._mx + xadd; + fy = monster[i]._my + yadd; + /// ASSERT: assert((DWORD)fx < MAXDUNX); + /// ASSERT: assert((DWORD)fy < MAXDUNY); + dMonster[fx][fy] = -(i + 1); + monster[i]._mmode = MM_WALK; + monster[i]._moldx = monster[i]._mx; + monster[i]._moldy = monster[i]._my; + monster[i]._mfutx = fx; + monster[i]._mfuty = fy; + monster[i]._mxvel = xvel; + monster[i]._myvel = yvel; + monster[i]._mVar1 = xadd; + monster[i]._mVar2 = yadd; + monster[i]._mVar3 = EndDir; + monster[i]._mdir = EndDir; + NewMonsterAnim(i, monster[i].MType->Anims[1], EndDir); + monster[i]._mVar6 = 0; + monster[i]._mVar7 = 0; + monster[i]._mVar8 = 0; + M_CheckEFlag(i); +} + +void M_StartWalk2(int i, int xvel, int yvel, int xoff, int yoff, int xadd, int yadd, int EndDir) +{ + long fx, fy; + + /// ASSERT: assert((DWORD)i < MAXMONSTERS); + /// ASSERT: assert(monster[i].MType != NULL); + fx = monster[i]._mx + xadd; + fy = monster[i]._my + yadd; + /// ASSERT: assert((DWORD)fx < MAXDUNX); + /// ASSERT: assert((DWORD)fy < MAXDUNY); + /// ASSERT: assert((DWORD)monster[i]._mx < MAXDUNX); + /// ASSERT: assert((DWORD)monster[i]._my < MAXDUNY); + dMonster[monster[i]._mx][monster[i]._my] = -(i + 1); + monster[i]._mVar1 = monster[i]._mx; + monster[i]._mVar2 = monster[i]._my; + monster[i]._moldx = monster[i]._mx; + monster[i]._moldy = monster[i]._my; + monster[i]._mx = fx; + monster[i]._my = fy; + monster[i]._mfutx = fx; + monster[i]._mfuty = fy; + dMonster[fx][fy] = i + 1; + if(monster[i]._uniqtype != 0) { + ChangeLightXY(monster[i].mlid, monster[i]._mx, monster[i]._my); + } + monster[i]._mxoff = xoff; + monster[i]._myoff = yoff; + monster[i]._mmode = MM_WALK2; + monster[i]._mxvel = xvel; + monster[i]._myvel = yvel; + monster[i]._mVar3 = EndDir; + monster[i]._mdir = EndDir; + NewMonsterAnim(i, monster[i].MType->Anims[1], EndDir); + monster[i]._mVar6 = 16 * xoff; + monster[i]._mVar7 = 16 * yoff; + monster[i]._mVar8 = 0; + M_CheckEFlag(i); +} + +void M_StartWalk3(int i, int xvel, int yvel, int xoff, int yoff, int xadd, int yadd, int mapx, int mapy, int EndDir) +{ + long fx, fy, x, y; + + /// ASSERT: assert((DWORD)i < MAXMONSTERS); + /// ASSERT: assert(monster[i].MType != NULL); + fx = monster[i]._mx + xadd; + fy = monster[i]._my + yadd; + x = monster[i]._mx + mapx; + y = monster[i]._my + mapy; + + if(monster[i]._uniqtype != 0) { + ChangeLightXY(monster[i].mlid, x, y); + } + + /// ASSERT: assert((DWORD)fx < MAXDUNX); + /// ASSERT: assert((DWORD)fy < MAXDUNY); + /// ASSERT: assert((DWORD)monster[i]._mx < MAXDUNX); + /// ASSERT: assert((DWORD)monster[i]._my < MAXDUNY); + dMonster[monster[i]._mx][monster[i]._my] = -(i + 1); + dMonster[fx][fy] = -(i + 1); + monster[i]._mVar4 = x; + monster[i]._mVar5 = y; + dFlags[x][y] |= 0x10; + monster[i]._moldx = monster[i]._mx; + monster[i]._moldy = monster[i]._my; + monster[i]._mfutx = fx; + monster[i]._mfuty = fy; + monster[i]._mxoff = xoff; + monster[i]._myoff = yoff; + monster[i]._mmode = MM_WALK3; + monster[i]._mxvel = xvel; + monster[i]._myvel = yvel; + monster[i]._mVar1 = fx; + monster[i]._mVar2 = fy; + monster[i]._mVar3 = EndDir; + monster[i]._mdir = EndDir; + NewMonsterAnim(i, monster[i].MType->Anims[1], EndDir); + monster[i]._mVar6 = 16 * xoff; + monster[i]._mVar7 = 16 * yoff; + monster[i]._mVar8 = 0; + M_CheckEFlag(i); +} + +void M_StartAttack(int i) +{ + int md; + + /// ASSERT: assert((DWORD)i < MAXMONSTERS); + /// ASSERT: assert(monster[i].MType != NULL); + md = M_GetDir(i); + NewMonsterAnim(i, monster[i].MType->Anims[2], md); + monster[i]._mmode = MM_ATTACK; + monster[i]._mxoff = 0; + monster[i]._myoff = 0; + monster[i]._mfutx = monster[i]._mx; + monster[i]._mfuty = monster[i]._my; + monster[i]._moldx = monster[i]._mx; + monster[i]._moldy = monster[i]._my; + monster[i]._mdir = md; + M_CheckEFlag(i); +} + +void M_StartRAttack(int i, int missile_type, int dam) +{ + int md; + + /// ASSERT: assert((DWORD)i < MAXMONSTERS); + /// ASSERT: assert(monster[i].MType != NULL); + md = M_GetDir(i); + NewMonsterAnim(i, monster[i].MType->Anims[2], md); + monster[i]._mmode = MM_RATTACK; + monster[i]._mVar1 = missile_type; + monster[i]._mVar2 = dam; + monster[i]._mxoff = 0; + monster[i]._myoff = 0; + monster[i]._mfutx = monster[i]._mx; + monster[i]._mfuty = monster[i]._my; + monster[i]._moldx = monster[i]._mx; + monster[i]._moldy = monster[i]._my; + monster[i]._mdir = md; + M_CheckEFlag(i); +} + +void M_StartRSpAttack(int i, int missile_type, int dam) +{ + int md; + + /// ASSERT: assert((DWORD)i < MAXMONSTERS); + /// ASSERT: assert(monster[i].MType != NULL); + md = M_GetDir(i); + NewMonsterAnim(i, monster[i].MType->Anims[5], md); + monster[i]._mmode = MM_RSPATTACK; + monster[i]._mVar1 = missile_type; + monster[i]._mVar2 = 0; + monster[i]._mVar3 = dam; + monster[i]._mxoff = 0; + monster[i]._myoff = 0; + monster[i]._mfutx = monster[i]._mx; + monster[i]._mfuty = monster[i]._my; + monster[i]._moldx = monster[i]._mx; + monster[i]._moldy = monster[i]._my; + monster[i]._mdir = md; + M_CheckEFlag(i); +} + +void M_StartSpAttack(int i) +{ + int md; + + /// ASSERT: assert((DWORD)i < MAXMONSTERS); + /// ASSERT: assert(monster[i].MType != NULL); + md = M_GetDir(i); + NewMonsterAnim(i, monster[i].MType->Anims[5], md); + monster[i]._mmode = MM_SATTACK; + monster[i]._mxoff = 0; + monster[i]._myoff = 0; + monster[i]._mfutx = monster[i]._mx; + monster[i]._mfuty = monster[i]._my; + monster[i]._moldx = monster[i]._mx; + monster[i]._moldy = monster[i]._my; + monster[i]._mdir = md; + M_CheckEFlag(i); +} + +void M_StartEat(int i) +{ + /// ASSERT: assert((DWORD)i < MAXMONSTERS); + /// ASSERT: assert(monster[i].MType != NULL); + NewMonsterAnim(i, monster[i].MType->Anims[5], monster[i]._mdir); + monster[i]._mmode = MM_SATTACK; + monster[i]._mxoff = 0; + monster[i]._myoff = 0; + monster[i]._mfutx = monster[i]._mx; + monster[i]._mfuty = monster[i]._my; + monster[i]._moldx = monster[i]._mx; + monster[i]._moldy = monster[i]._my; + M_CheckEFlag(i); +} + +void M_ClearSquares(int i) +{ + int mx, my, mt, mt2, x, y; + + /// ASSERT: assert((DWORD)i < MAXMONSTERS); + mx = monster[i]._moldx; + my = monster[i]._moldy; + /// ASSERT: assert((DWORD)(mx+1) < MAXDUNX); + /// ASSERT: assert((DWORD)(my+1) < MAXDUNY); + mt = -(i + 1); + mt2 = i + 1; + + for(y = my - 1; y <= my + 1; y++) { + if(y >= 0 && y < MAXDUNY) { + for(x = mx - 1; x <= mx + 1; x++) { + if(x >= 0 && x < MAXDUNX) { + if(dMonster[x][y] == mt || dMonster[x][y] == mt2) { + dMonster[x][y] = 0; + } + } + } + } + } + + if(mx + 1 < MAXDUNX) { + dFlags[mx + 1][my] &= ~0x10; + } + if(my + 1 < MAXDUNY) { + dFlags[mx][my + 1] &= ~0x10; + } +} + +void M_GetKnockback(int i) +{ + int d; + + /// ASSERT: assert((DWORD)i < MAXMONSTERS); + /// ASSERT: assert(monster[i].MType != NULL); + d = (monster[i]._mdir - 4) & 7; + if(!DirOK(i, d)) { + return; + } + + M_ClearSquares(i); + monster[i]._moldx += offset_x[d]; + monster[i]._moldy += offset_y[d]; + NewMonsterAnim(i, monster[i].MType->Anims[3], monster[i]._mdir); + monster[i]._mmode = MM_GOTHIT; + monster[i]._mxoff = 0; + monster[i]._myoff = 0; + monster[i]._mx = monster[i]._moldx; + monster[i]._my = monster[i]._moldy; + monster[i]._mfutx = monster[i]._mx; + monster[i]._mfuty = monster[i]._my; + monster[i]._moldx = monster[i]._mx; + monster[i]._moldy = monster[i]._my; + M_CheckEFlag(i); + M_ClearSquares(i); + /// ASSERT: assert((DWORD)monster[i]._mx < MAXDUNX); + /// ASSERT: assert((DWORD)monster[i]._my < MAXDUNY); + dMonster[monster[i]._mx][monster[i]._my] = i + 1; +} + +void M_StartHit(int i, int pnum, int dam) +{ + /// ASSERT: assert((DWORD)i < MAXMONSTERS); + /// ASSERT: assert(monster[i].MType != NULL); + if(pnum >= 0) { + monster[i].mWhoHit |= 1 << pnum; + } + if(pnum == myplr) { + delta_monster_hp(i, monster[i]._mhitpoints, currlevel); + NetSendCmdParam2(FALSE, CMD_MONSTDAMAGE, i, dam); + } + + PlayEffect(i, 1); + + if(monster[i].MType->mtype >= MT_SNEAK && monster[i].MType->mtype <= MT_ILLWEAV || dam >> 6 >= monster[i].mLevel + 3) { + if(pnum >= 0) { + monster[i]._menemy = pnum; + monster[i]._menemyx = plr[pnum]._px; + monster[i]._menemyy = plr[pnum]._py; + monster[i]._mFlags &= ~0x10; + monster[i]._mdir = M_GetDir(i); + } + if(monster[i].MType->mtype == MT_BLINK) { + M_Teleport(i); + } else if(monster[i].MType->mtype >= MT_NSCAV && monster[i].MType->mtype <= MT_YSCAV) { + monster[i]._mgoal = 1; + } + if(monster[i]._mmode != MM_STONE) { + NewMonsterAnim(i, monster[i].MType->Anims[3], monster[i]._mdir); + monster[i]._mmode = MM_GOTHIT; + monster[i]._mxoff = 0; + monster[i]._myoff = 0; + monster[i]._mx = monster[i]._moldx; + monster[i]._my = monster[i]._moldy; + monster[i]._mfutx = monster[i]._mx; + monster[i]._mfuty = monster[i]._my; + monster[i]._moldx = monster[i]._mx; + monster[i]._moldy = monster[i]._my; + M_CheckEFlag(i); + M_ClearSquares(i); + dMonster[monster[i]._mx][monster[i]._my] = i + 1; + } + } +} + +void M_DiabloDeath(int i, BOOL sendmsg) +{ + int steps, j, k; + MonsterStruct *Monst; + + Monst = &monster[i]; + + PlaySFX(USFX_DIABLOD); + quests[Q_DIABLO]._qactive = 3; + + if(sendmsg) { + NetSendCmdQuest(TRUE, Q_DIABLO); + } + + sgbSaveSoundOn = gbSoundOn; + gbProcessPlayers = 0; + + /// ASSERT: assert((DWORD)nummonsters <= MAXMONSTERS); + for(j = 0; j < nummonsters; j++) { + k = monstactive[j]; + if(k == i || monster[i]._msquelch == 0) { + continue; + } + NewMonsterAnim(k, monster[k].MType->Anims[4], monster[k]._mdir); + monster[k]._mmode = MM_DEATH; + monster[k]._mxoff = 0; + monster[k]._myoff = 0; + monster[k]._mVar1 = 0; + monster[k]._mx = monster[k]._moldx; + monster[k]._my = monster[k]._moldy; + monster[k]._mfutx = monster[k]._mx; + monster[k]._mfuty = monster[k]._my; + monster[k]._moldx = monster[k]._mx; + monster[k]._moldy = monster[k]._my; + M_CheckEFlag(k); + M_ClearSquares(k); + dMonster[monster[k]._mx][monster[k]._my] = k + 1; + } + + AddLight(Monst->_mx, Monst->_my, 8); + DoVision(Monst->_mx, Monst->_my, 8, 0, 1); + + if(abs(ViewX - Monst->_mx) > abs(ViewY - Monst->_my)) { + steps = abs(ViewX - Monst->_mx); + } else { + steps = abs(ViewY - Monst->_my); + } + if(steps > 20) { + steps = 20; + } + + Monst->_mVar3 = ViewX << 16; + Monst->_mVar4 = ViewY << 16; + Monst->_mVar5 = (double)(Monst->_mVar3 - (Monst->_mx << 16)) / (double)steps; + Monst->_mVar6 = (double)(Monst->_mVar4 - (Monst->_my << 16)) / (double)steps; +} + +void M2MStartHit(int mid, int i, int dam) +{ + if((DWORD)mid >= MAXMONSTERS) { + app_fatal("Invalid monster %d getting hit by monster", mid); + } + if(monster[mid].MType == NULL) { + app_fatal("Monster %d \"%s\" getting hit by monster: MType NULL", mid, monster[mid].mName); + } + + if(i >= 0) { + monster[i].mWhoHit |= 1 << i; + } + + delta_monster_hp(mid, monster[mid]._mhitpoints, currlevel); + NetSendCmdParam2(FALSE, CMD_MONSTDAMAGE, mid, dam); + PlayEffect(mid, 1); + + if(monster[mid].MType->mtype >= MT_SNEAK && monster[mid].MType->mtype <= MT_ILLWEAV || dam >> 6 >= monster[mid].mLevel + 3) { + if(i >= 0) { + monster[mid]._mdir = (monster[i]._mdir - 4) & 7; + } + if(monster[mid].MType->mtype == MT_BLINK) { + M_Teleport(mid); + } else if(monster[mid].MType->mtype >= MT_NSCAV && monster[mid].MType->mtype <= MT_YSCAV) { + monster[mid]._mgoal = 1; + } + if(monster[mid]._mmode != MM_STONE) { + if(monster[mid].MType->mtype != MT_GOLEM) { + NewMonsterAnim(mid, monster[mid].MType->Anims[3], monster[mid]._mdir); + monster[mid]._mmode = MM_GOTHIT; + } + monster[mid]._mxoff = 0; + monster[mid]._myoff = 0; + monster[mid]._mx = monster[mid]._moldx; + monster[mid]._my = monster[mid]._moldy; + monster[mid]._mfutx = monster[mid]._mx; + monster[mid]._mfuty = monster[mid]._my; + monster[mid]._moldx = monster[mid]._mx; + monster[mid]._moldy = monster[mid]._my; + M_CheckEFlag(mid); + M_ClearSquares(mid); + dMonster[monster[mid]._mx][monster[mid]._my] = mid + 1; + } + } +} + +void MonstStartKill(int i, int pnum, BOOL sendmsg) +{ + int md; + MonsterStruct *Monst; + + if((DWORD)i >= MAXMONSTERS) { + app_fatal("MonstStartKill: Invalid monster %d", i); + } + if(monster[i].MType == NULL) { + app_fatal("MonstStartKill: Monster %d \"%s\" MType NULL", i, monster[i].mName); + } + + Monst = &monster[i]; + + if(pnum >= 0) { + Monst->mWhoHit |= 1 << pnum; + } + if(pnum < MAX_PLRS && i > 4) { + AddPlrMonstExper(Monst->mLevel, Monst->mExp, Monst->mWhoHit); + } + + monstkills[Monst->MType->mtype]++; + Monst->_mhitpoints = 0; + SetRndSeed(Monst->_mRndSeed); + + if(QuestStatus(Q_GARBUD) && Monst->mName == UniqMonst[0].mName) { + CreateTypeItem(Monst->_mx + 1, Monst->_my + 1, TRUE, ITYPE_MACE, IMISC_NONE, TRUE, FALSE); + } else if(i > 3) { + SpawnItem(i, Monst->_mx, Monst->_my, sendmsg); + } + if(Monst->MType->mtype == MT_DIABLO) { + M_DiabloDeath(i, TRUE); + } else { + PlayEffect(i, 2); + } + if(pnum >= 0) { + md = M_GetDir(i); + } else { + md = Monst->_mdir; + } + + Monst->_mdir = md; + NewMonsterAnim(i, Monst->MType->Anims[4], md); + Monst->_mmode = MM_DEATH; + Monst->_mxoff = 0; + Monst->_myoff = 0; + Monst->_mVar1 = 0; + Monst->_mx = Monst->_moldx; + Monst->_my = Monst->_moldy; + Monst->_mfutx = Monst->_mx; + Monst->_mfuty = Monst->_my; + Monst->_moldx = Monst->_mx; + Monst->_moldy = Monst->_my; + M_CheckEFlag(i); + M_ClearSquares(i); + dMonster[Monst->_mx][Monst->_my] = i + 1; + CheckQuestKill(i, sendmsg); + M_FallenFear(Monst->_mx, Monst->_my); + + if(Monst->MType->mtype >= MT_NACID && Monst->MType->mtype <= MT_XACID) { + AddMissile(Monst->_mx, Monst->_my, 0, 0, 0, MIS_ACIDPUD, 1, i, Monst->_mint + 1, 0); + } +} + +void M2MStartKill(int i, int mid) +{ + int md; + + if((DWORD)i >= MAXMONSTERS) { + app_fatal("M2MStartKill: Invalid monster (attacker) %d", i); + } + if((DWORD)i >= MAXMONSTERS) { /// BUGFIX: should use `mid` + app_fatal("M2MStartKill: Invalid monster (killed) %d", mid); + } + if(monster[i].MType == NULL) { /// BUGFIX: should use `mid` + app_fatal("M2MStartKill: Monster %d \"%s\" MType NULL", mid, monster[mid].mName); + } + + delta_kill_monster(mid, monster[mid]._mx, monster[mid]._my, currlevel); + NetSendCmdLocParam1(FALSE, CMD_MONSTDEATH, monster[mid]._mx, monster[mid]._my, mid); + monster[mid].mWhoHit |= 1 << i; + + if(i < 4) { + AddPlrMonstExper(monster[mid].mLevel, monster[mid].mExp, monster[mid].mWhoHit); + } + + monstkills[monster[mid].MType->mtype]++; + monster[mid]._mhitpoints = 0; + SetRndSeed(monster[mid]._mRndSeed); + + if(mid >= 4) { + SpawnItem(mid, monster[mid]._mx, monster[mid]._my, TRUE); + } + if(monster[mid].MType->mtype == MT_DIABLO) { + M_DiabloDeath(mid, TRUE); + } else { + PlayEffect(i, 2); + } + + PlayEffect(mid, 2); + + md = (monster[i]._mdir - 4) & 7; + if(monster[mid].MType->mtype == MT_GOLEM) { + md = 0; + } + + monster[mid]._mdir = md; + NewMonsterAnim(mid, monster[mid].MType->Anims[4], md); + monster[mid]._mmode = MM_DEATH; + monster[mid]._mxoff = 0; + monster[mid]._myoff = 0; + monster[mid]._mx = monster[mid]._moldx; + monster[mid]._my = monster[mid]._moldy; + monster[mid]._mfutx = monster[mid]._mx; + monster[mid]._mfuty = monster[mid]._my; + monster[mid]._moldx = monster[mid]._mx; + monster[mid]._moldy = monster[mid]._my; + M_CheckEFlag(mid); + M_ClearSquares(mid); + dMonster[monster[mid]._mx][monster[mid]._my] = mid + 1; + CheckQuestKill(mid, TRUE); + M_FallenFear(monster[mid]._mx, monster[mid]._my); + + if(monster[mid].MType->mtype >= MT_NACID && monster[mid].MType->mtype <= MT_XACID) { + AddMissile(monster[mid]._mx, monster[mid]._my, 0, 0, 0, MIS_ACIDPUD, 1, mid, monster[mid]._mint + 1, 0); + } +} + +void M_StartKill(int i, int pnum) +{ + if((DWORD)i >= MAXMONSTERS) { + app_fatal("M_StartKill: Invalid monster %d", i); + } + + if(myplr == pnum) { + delta_kill_monster(i, monster[i]._mx, monster[i]._my, currlevel); + if(i != pnum) { + NetSendCmdLocParam1(FALSE, CMD_MONSTDEATH, monster[i]._mx, monster[i]._my, i); + } else { + NetSendCmdLocParam1(FALSE, CMD_KILLGOLEM, monster[i]._mx, monster[i]._my, currlevel); + } + } + + MonstStartKill(i, pnum, TRUE); +} + +void M_SyncStartKill(int i, int x, int y, int pnum) +{ + if((DWORD)i >= MAXMONSTERS) { + app_fatal("M_SyncStartKill: Invalid monster %d", i); + } + + if(monster[i]._mhitpoints == 0 || monster[i]._mmode == MM_DEATH) { + return; + } + + /// ASSERT: assert(pnum != myplr); + + if(dMonster[x][y] == 0) { + M_ClearSquares(i); + monster[i]._mx = x; + monster[i]._my = y; + monster[i]._moldx = x; + monster[i]._moldy = y; + } + + if(monster[i]._mmode == MM_STONE) { + MonstStartKill(i, pnum, FALSE); + monster[i]._mmode = MM_STONE; + } else { + MonstStartKill(i, pnum, FALSE); + } + + /// ASSERT: assert(dMonster[monster[i]._mx][monster[i]._my] == i+1 || dMonster[monster[i]._mx][monster[i]._my] == -(i+1)); +} + +void M_StartFadein(int i, int md, BOOL backwards) +{ + if((DWORD)i >= MAXMONSTERS) { + app_fatal("M_StartFadein: Invalid monster %d", i); + } + if(monster[i].MType == NULL) { + app_fatal("M_StartFadein: Monster %d \"%s\" MType NULL", i, monster[i].mName); + } + + NewMonsterAnim(i, monster[i].MType->Anims[5], md); + monster[i]._mmode = MM_FADEIN; + monster[i]._mxoff = 0; + monster[i]._myoff = 0; + monster[i]._mfutx = monster[i]._mx; + monster[i]._mfuty = monster[i]._my; + monster[i]._moldx = monster[i]._mx; + monster[i]._moldy = monster[i]._my; + M_CheckEFlag(i); + monster[i]._mdir = md; + monster[i]._mFlags &= ~1; + + if(backwards) { + monster[i]._mFlags |= 2; + monster[i]._mAnimFrame = monster[i]._mAnimLen; + } +} + +void M_StartFadeout(int i, int md, BOOL backwards) +{ + if((DWORD)i >= MAXMONSTERS) { + app_fatal("M_StartFadeout: Invalid monster %d", i); + } + if(monster[i].MType == NULL) { + app_fatal("M_StartFadeout: Monster %d \"%s\" MType NULL", i, monster[i].mName); + } + + NewMonsterAnim(i, monster[i].MType->Anims[5], md); + monster[i]._mmode = MM_FADEOUT; + monster[i]._mxoff = 0; + monster[i]._myoff = 0; + monster[i]._mfutx = monster[i]._mx; + monster[i]._mfuty = monster[i]._my; + monster[i]._moldx = monster[i]._mx; + monster[i]._moldy = monster[i]._my; + M_CheckEFlag(i); + monster[i]._mdir = md; + + if(backwards) { + monster[i]._mFlags |= 2; + monster[i]._mAnimFrame = monster[i]._mAnimLen; + } +} + +void M_StartHeal(int i) +{ + MonsterStruct *Monst; + + if((DWORD)i >= MAXMONSTERS) { + app_fatal("M_StartHeal: Invalid monster %d", i); + } + if(monster[i].MType == NULL) { + app_fatal("M_StartHeal: Monster %d \"%s\" MType NULL", i, monster[i].mName); + } + + Monst = &monster[i]; + Monst->_mAnimData = Monst->MType->Anims[5].Frames[Monst->_mdir]; + Monst->_mAnimFrame = Monst->MType->Anims[5].Rate; + Monst->_mFlags |= 2; + Monst->_mmode = MM_HEAL; + Monst->_mVar1 = Monst->_mmaxhp / (16 * (random(97, 5) + 4)); +} + +void M_ChangeLightOffset(int monst) +{ + int lx, ly, sign; + + if((DWORD)monst >= MAXMONSTERS) { + app_fatal("M_ChangeLightOffset: Invalid monster %d", monst); + } + + lx = 2 * monster[monst]._myoff + monster[monst]._mxoff; + ly = 2 * monster[monst]._myoff - monster[monst]._mxoff; + + if(lx < 0) { + sign = -1; + lx = -lx; + } else { + sign = 1; + } + lx >>= 3; + lx *= sign; + + if(ly < 0) { + sign = -1; + ly = -ly; + } else { + sign = 1; + } + ly >>= 3; + ly *= sign; + + ChangeLightOff(monster[monst].mlid, lx, ly); +} + +BOOL M_DoStand(int i) +{ + MonsterStruct *Monst; + + if((DWORD)i >= MAXMONSTERS) { + app_fatal("M_DoStand: Invalid monster %d", i); + } + if(monster[i].MType == NULL) { + app_fatal("M_DoStand: Monster %d \"%s\" MType NULL", i, monster[i].mName); + } + + Monst = &monster[i]; + if(Monst->MType->mtype == MT_GOLEM) { + Monst->_mAnimData = Monst->MType->Anims[1].Frames[Monst->_mdir]; + } else { + Monst->_mAnimData = Monst->MType->Anims[0].Frames[Monst->_mdir]; + } + + if(Monst->_mAnimFrame == Monst->_mAnimLen) { + M_Enemy(i); + } + + Monst->_mVar2++; + + return FALSE; +} + +BOOL M_DoWalk(int i) +{ + BOOL rv; + + if((DWORD)i >= MAXMONSTERS) { + app_fatal("M_DoWalk: Invalid monster %d", i); + } + if(monster[i].MType == NULL) { + app_fatal("M_DoWalk: Monster %d \"%s\" MType NULL", i, monster[i].mName); + } + + if(monster[i]._mVar8 == monster[i].MType->Anims[1].Rate) { + dMonster[monster[i]._mx][monster[i]._my] = 0; + monster[i]._mx += monster[i]._mVar1; + monster[i]._my += monster[i]._mVar2; + dMonster[monster[i]._mx][monster[i]._my] = i + 1; + if(monster[i]._uniqtype != 0) { + ChangeLightXY(monster[i].mlid, monster[i]._mx, monster[i]._my); + } + M_StartStand(i, monster[i]._mdir); + rv = TRUE; + } else { + if(monster[i]._mAnimCnt == 0) { + monster[i]._mVar8++; + monster[i]._mVar6 += monster[i]._mxvel; + monster[i]._mVar7 += monster[i]._myvel; + monster[i]._mxoff = monster[i]._mVar6 >> 4; + monster[i]._myoff = monster[i]._mVar7 >> 4; + } + rv = FALSE; + } + + if(monster[i]._uniqtype != 0) { + M_ChangeLightOffset(i); + } + + return rv; +} + +BOOL M_DoWalk2(int i) +{ + BOOL rv; + + if((DWORD)i >= MAXMONSTERS) { + app_fatal("M_DoWalk2: Invalid monster %d", i); + } + if(monster[i].MType == NULL) { + app_fatal("M_DoWalk2: Monster %d \"%s\" MType NULL", i, monster[i].mName); + } + + if(monster[i]._mVar8 == monster[i].MType->Anims[1].Rate) { + dMonster[monster[i]._mVar1][monster[i]._mVar2] = 0; + if(monster[i]._uniqtype != 0) { + ChangeLightXY(monster[i].mlid, monster[i]._mx, monster[i]._my); + } + M_StartStand(i, monster[i]._mdir); + rv = TRUE; + } else { + if(monster[i]._mAnimCnt == 0) { + monster[i]._mVar8++; + monster[i]._mVar6 += monster[i]._mxvel; + monster[i]._mVar7 += monster[i]._myvel; + monster[i]._mxoff = monster[i]._mVar6 >> 4; + monster[i]._myoff = monster[i]._mVar7 >> 4; + } + rv = FALSE; + } + + if(monster[i]._uniqtype != 0) { + M_ChangeLightOffset(i); + } + + return rv; +} + +BOOL M_DoWalk3(int i) +{ + BOOL rv; + + if((DWORD)i >= MAXMONSTERS) { + app_fatal("M_DoWalk3: Invalid monster %d", i); + } + if(monster[i].MType == NULL) { + app_fatal("M_DoWalk3: Monster %d \"%s\" MType NULL", i, monster[i].mName); + } + + if(monster[i]._mVar8 == monster[i].MType->Anims[1].Rate) { + dMonster[monster[i]._mx][monster[i]._my] = 0; + monster[i]._mx = monster[i]._mVar1; + monster[i]._my = monster[i]._mVar2; + dFlags[monster[i]._mVar4][monster[i]._mVar5] &= ~0x10; + dMonster[monster[i]._mx][monster[i]._my] = i + 1; + if(monster[i]._uniqtype != 0) { + ChangeLightXY(monster[i].mlid, monster[i]._mx, monster[i]._my); + } + M_StartStand(i, monster[i]._mdir); + rv = TRUE; + } else { + if(monster[i]._mAnimCnt == 0) { + monster[i]._mVar8++; + monster[i]._mVar6 += monster[i]._mxvel; + monster[i]._mVar7 += monster[i]._myvel; + monster[i]._mxoff = monster[i]._mVar6 >> 4; + monster[i]._myoff = monster[i]._mVar7 >> 4; + } + rv = FALSE; + } + + if(monster[i]._uniqtype != 0) { + M_ChangeLightOffset(i); + } + + return rv; +} + +void M_TryM2MHit(int i, int mid, int hper, int mind, int maxd) +{ + int hit, dam; + BOOL ret; + + if((DWORD)mid >= MAXMONSTERS) { + app_fatal("M_TryM2MHit: Invalid monster %d", mid); + } + if(monster[mid].MType == NULL) { + app_fatal("M_TryM2MHit: Monster %d \"%s\" MType NULL", mid, monster[mid].mName); + } + + if(monster[mid]._mhitpoints >> 6 <= 0) { + return; + } + if(monster[mid].MType->mtype == MT_ILLWEAV && monster[mid]._mgoal == 2) { + return; + } + + hit = random(4, 100); + if(monster[mid]._mmode == MM_STONE) { + hit = 0; + } + if(CheckMonsterHit(mid, ret)) { + return; + } + if(hit < hper) { + dam = (random(5, maxd - mind + 1) + mind) << 6; + monster[mid]._mhitpoints -= dam; + if(monster[mid]._mhitpoints >> 6 <= 0) { + if(monster[mid]._mmode == MM_STONE) { + M2MStartKill(i, mid); + monster[mid]._mmode = MM_STONE; + } else { + M2MStartKill(i, mid); + } + } else { + if(monster[mid]._mmode == MM_STONE) { + M2MStartHit(mid, i, dam); + monster[mid]._mmode = MM_STONE; + } else { + M2MStartHit(mid, i, dam); + } + } + } +} + +void M_TryH2HHit(int i, int pnum, int Hit, int MinDam, int MaxDam) +{ + int hit, hper, tac, dx, dy, blk, blkper, blkdir, mdam, newx, newy, j, k, mi; + long dam; + + if((DWORD)i >= MAXMONSTERS) { + app_fatal("M_TryH2HHit: Invalid monster %d", i); + } + if(monster[i].MType == NULL) { + app_fatal("M_TryH2HHit: Monster %d \"%s\" MType NULL", i, monster[i].mName); + } + + if(monster[i]._mFlags & 0x10) { + M_TryM2MHit(i, pnum, Hit, MinDam, MaxDam); + return; + } + /// ASSERT: assert((DWORD)pnum < MAX_PLRS); + if(plr[pnum]._pHitPoints >> 6 <= 0 || plr[pnum]._pInvincible || plr[pnum]._pSpellFlags & 1) { + return; + } + dx = abs(monster[i]._mx - plr[pnum].WorldX); + dy = abs(monster[i]._my - plr[pnum].WorldY); + if(dx >= 2 || dy >= 2) { + return; + } + + hit = random(98, 100); +#ifdef _DEBUG + if(debug_mode_dollar_sign || debug_mode_key_inverted_v) { + hit = 1000; + } +#endif + tac = plr[pnum]._pIAC + plr[pnum]._pIBonusAC + plr[pnum]._pDexterity / 5; + hper = Hit + 30 + ((monster[i].mLevel - plr[pnum]._pLevel) << 1) - tac; + if(hper < 15) { + hper = 15; + } + if(currlevel == 14 && hper < 20) { + hper = 20; + } + if(currlevel == 15 && hper < 25) { + hper = 25; + } + if(currlevel == 16 && hper < 30) { + hper = 30; + } + + if((plr[pnum]._pmode == PM_STAND || plr[pnum]._pmode == PM_ATTACK) && plr[pnum]._pBlockFlag) { + blk = random(98, 100); + } else { + blk = 100; + } + blkper = plr[pnum]._pBaseToBlk + plr[pnum]._pDexterity - ((monster[i].mLevel - plr[pnum]._pLevel) << 1); + if(blkper < 0) { + blkper = 0; + } + if(blkper > 100) { + blkper = 100; + } + + if(hit < hper) { + if(blk < blkper) { + blkdir = GetDirection(plr[pnum].WorldX, plr[pnum].WorldY, monster[i]._mx, monster[i]._my); + StartPlrBlock(pnum, blkdir); + return; + } + if(monster[i].MType->mtype == MT_YZOMBIE && pnum == myplr) { + mi = -1; + for(j = 0; j < nummissiles; j++) { + k = missileactive[j]; + if(missile[k]._mitype == MIS_MANASHIELD && missile[k]._misource == pnum) { + mi = k; + } + } + if(plr[pnum]._pMaxHP > 64 && plr[pnum]._pMaxHPBase > 64) { + plr[pnum]._pMaxHP -= 64; + if(plr[pnum]._pHitPoints > plr[pnum]._pMaxHP) { + plr[pnum]._pHitPoints = plr[pnum]._pMaxHP; + if(mi >= 0) { + missile[mi]._miVar1 = plr[pnum]._pMaxHP; + } + } + plr[pnum]._pMaxHPBase -= 64; + if(plr[pnum]._pHPBase > plr[pnum]._pMaxHPBase) { + plr[pnum]._pHPBase = plr[pnum]._pMaxHPBase; + if(mi >= 0) { + missile[mi]._miVar2 = plr[pnum]._pMaxHPBase; + } + } + } + } + dam = (MaxDam - MinDam + 1) << 6; + dam = random(99, dam) + (MinDam << 6); + dam += plr[pnum]._pIGetHit << 6; + if(dam < 64) { + dam = 64; + } + if(pnum == myplr) { + plr[pnum]._pHitPoints -= dam; + plr[pnum]._pHPBase -= dam; + } + if(plr[pnum]._pIFlags & ISPL_THORNS) { + mdam = (random(99, 3) + 1) << 6; + monster[i]._mhitpoints -= mdam; + if(monster[i]._mhitpoints >> 6 <= 0) { + M_StartKill(i, pnum); + } else { + M_StartHit(i, pnum, mdam); + } + } + if(!(monster[i]._mFlags & 0x1000) && monster[i].MType->mtype == MT_SKING && gbMaxPlayers != 1) { + monster[i]._mhitpoints += dam; + } + if(plr[pnum]._pHitPoints > plr[pnum]._pMaxHP) { + plr[pnum]._pHitPoints = plr[pnum]._pMaxHP; + plr[pnum]._pHPBase = plr[pnum]._pMaxHPBase; + } + if(plr[pnum]._pHitPoints >> 6 <= 0) { + SyncPlrKill(pnum, 0); + } else { + StartPlrHit(pnum, dam, FALSE); + if(monster[i]._mFlags & 0x80) { + if(plr[pnum]._pmode != PM_GOTHIT) { + StartPlrHit(pnum, 0, TRUE); + } + newx = plr[pnum].WorldX + offset_x[monster[i]._mdir]; + newy = plr[pnum].WorldY + offset_y[monster[i]._mdir]; + if(PosOkPlayer(pnum, newx, newy)) { + plr[pnum].WorldX = newx; + plr[pnum].WorldY = newy; + FixPlayerLocation(pnum, plr[pnum]._pdir); + FixPlrWalkTags(pnum); + dPlayer[newx][newy] = pnum + 1; + SetPlayerOld(pnum); + } + } + } + } +} + +BOOL M_DoAttack(int i) +{ + MonsterStruct *Monst; + + if((DWORD)i >= MAXMONSTERS) { + app_fatal("M_DoAttack: Invalid monster %d", i); + } + if(monster[i].MType == NULL) { + app_fatal("M_DoAttack: Monster %d \"%s\" MType NULL", i, monster[i].mName); + } + if(monster[i].MType == NULL) { /// BUGFIX: should check 'MData' + app_fatal("M_DoAttack: Monster %d \"%s\" MData NULL", i, monster[i].mName); + } + + Monst = &monster[i]; + if(Monst->_mAnimFrame == Monst->MData->mAFNum) { + M_TryH2HHit(i, Monst->_menemy, Monst->mHit, Monst->mMinDamage, Monst->mMaxDamage); + if(Monst->_mAi != AI_SNAKE) { + PlayEffect(i, 0); + } + } + if(Monst->MType->mtype >= MT_NMAGMA && Monst->MType->mtype <= MT_WMAGMA && Monst->_mAnimFrame == 9) { + M_TryH2HHit(i, Monst->_menemy, Monst->mHit + 10, Monst->mMinDamage - 2, Monst->mMaxDamage - 2); + PlayEffect(i, 0); + } + if(Monst->MType->mtype >= MT_STORM && Monst->MType->mtype <= MT_MAEL && Monst->_mAnimFrame == 13) { + M_TryH2HHit(i, Monst->_menemy, Monst->mHit - 20, Monst->mMinDamage + 4, Monst->mMaxDamage + 4); + PlayEffect(i, 0); + } + if(Monst->_mAi == AI_SNAKE && Monst->_mAnimFrame == 1) { + PlayEffect(i, 0); + } + + if(Monst->_mAnimFrame == Monst->_mAnimLen) { + M_StartStand(i, Monst->_mdir); + return TRUE; + } + + return FALSE; +} + +BOOL M_DoRAttack(int i) +{ + int multimissiles, mi; + + if((DWORD)i >= MAXMONSTERS) { + app_fatal("M_DoRAttack: Invalid monster %d", i); + } + if(monster[i].MType == NULL) { + app_fatal("M_DoRAttack: Monster %d \"%s\" MType NULL", i, monster[i].mName); + } + if(monster[i].MType == NULL) { /// BUGFIX: should check 'MData' + app_fatal("M_DoRAttack: Monster %d \"%s\" MData NULL", i, monster[i].mName); + } + + if(monster[i]._mAnimFrame == monster[i].MData->mAFNum) { + if(monster[i]._mVar1 != -1) { + if(monster[i]._mVar1 == MIS_CBOLT) { + multimissiles = 3; + } else { + multimissiles = 1; + } + for(mi = 0; mi < multimissiles; mi++) { + AddMissile( + monster[i]._mx, + monster[i]._my, + monster[i]._menemyx, + monster[i]._menemyy, + monster[i]._mdir, + monster[i]._mVar1, + 1, + i, + monster[i]._mVar2, + 0); + } + } + PlayEffect(i, 0); + } + + if(monster[i]._mAnimFrame == monster[i]._mAnimLen) { + M_StartStand(i, monster[i]._mdir); + return TRUE; + } + + return FALSE; +} + +BOOL M_DoRSpAttack(int i) +{ + if((DWORD)i >= MAXMONSTERS) { + app_fatal("M_DoRSpAttack: Invalid monster %d", i); + } + if(monster[i].MType == NULL) { + app_fatal("M_DoRSpAttack: Monster %d \"%s\" MType NULL", i, monster[i].mName); + } + if(monster[i].MType == NULL) { /// BUGFIX: should check 'MData' + app_fatal("M_DoRSpAttack: Monster %d \"%s\" MData NULL", i, monster[i].mName); + } + + if(monster[i]._mAnimFrame == monster[i].MData->mAFNum2 && monster[i]._mAnimCnt == 0) { + AddMissile( + monster[i]._mx, + monster[i]._my, + monster[i]._menemyx, + monster[i]._menemyy, + monster[i]._mdir, + monster[i]._mVar1, + 1, + i, + monster[i]._mVar3, + 0); + PlayEffect(i, 3); + } + if(monster[i]._mAi == AI_MEGA && monster[i]._mAnimFrame == 3) { + if(monster[i]._mVar2++ == 0) { + monster[i]._mFlags |= 4; + } else if(monster[i]._mVar2 == 15) { + monster[i]._mFlags &= ~4; + } + } + + if(monster[i]._mAnimFrame == monster[i]._mAnimLen) { + M_StartStand(i, monster[i]._mdir); + return TRUE; + } + + return FALSE; +} + +BOOL M_DoSAttack(int i) +{ + if((DWORD)i >= MAXMONSTERS) { + app_fatal("M_DoSAttack: Invalid monster %d", i); + } + if(monster[i].MType == NULL) { + app_fatal("M_DoSAttack: Monster %d \"%s\" MType NULL", i, monster[i].mName); + } + if(monster[i].MType == NULL) { /// BUGFIX: should check 'MData' + app_fatal("M_DoSAttack: Monster %d \"%s\" MData NULL", i, monster[i].mName); + } + + if(monster[i]._mAnimFrame == monster[i].MData->mAFNum2) { + M_TryH2HHit(i, monster[i]._menemy, monster[i].mHit2, monster[i].mMinDamage2, monster[i].mMaxDamage2); + } + + if(monster[i]._mAnimFrame == monster[i]._mAnimLen) { + M_StartStand(i, monster[i]._mdir); + return TRUE; + } + + return FALSE; +} + +BOOL M_DoFadein(int i) +{ + if((DWORD)i >= MAXMONSTERS) { + app_fatal("M_DoFadein: Invalid monster %d", i); + } + + if(monster[i]._mFlags & 2 && monster[i]._mAnimFrame == 1 + || !(monster[i]._mFlags & 2) && monster[i]._mAnimFrame == monster[i]._mAnimLen) { + M_StartStand(i, monster[i]._mdir); + monster[i]._mFlags &= ~2; + return TRUE; + } + + return FALSE; +} + +BOOL M_DoFadeout(int i) +{ + int mtype; + + if((DWORD)i >= MAXMONSTERS) { + app_fatal("M_DoFadeout: Invalid monster %d", i); + } + + if(monster[i]._mFlags & 2 && monster[i]._mAnimFrame == 1 + || !(monster[i]._mFlags & 2) && monster[i]._mAnimFrame == monster[i]._mAnimLen) { + /// ASSERT: assert(monster[i].MType != NULL); + mtype = monster[i].MType->mtype; + if(mtype >= MT_INCIN && mtype <= MT_HELLBURN) { + monster[i]._mFlags &= ~2; + } else { + monster[i]._mFlags &= ~2; + monster[i]._mFlags |= 1; + } + M_StartStand(i, monster[i]._mdir); + return TRUE; + } + + return FALSE; +} + +BOOL M_DoHeal(int i) +{ + MonsterStruct *Monst; + + if((DWORD)i >= MAXMONSTERS) { + app_fatal("M_DoHeal: Invalid monster %d", i); + } + + Monst = &monster[i]; + if(monster[i]._mFlags & 8) { + Monst->_mFlags &= ~4; + Monst->_mmode = MM_SATTACK; + return FALSE; + } + + if(Monst->_mAnimFrame == 1) { + Monst->_mFlags &= ~2; + Monst->_mFlags |= 4; + if(Monst->_mhitpoints + Monst->_mVar1 < Monst->_mmaxhp) { + Monst->_mhitpoints += Monst->_mVar1; + } else { + Monst->_mhitpoints = Monst->_mmaxhp; + Monst->_mFlags &= ~4; + Monst->_mmode = MM_SATTACK; + } + } + + return FALSE; +} + +BOOL M_DoTalk(int i) +{ + int tren; + MonsterStruct *Monst; + + if((DWORD)i >= MAXMONSTERS) { + app_fatal("M_DoTalk: Invalid monster %d", i); + } + + Monst = &monster[i]; + M_StartStand(i, monster[i]._mdir); + Monst->_mgoal = 7; + + if(effect_is_playing(alltext[monster[i].mtalkmsg].sfxnr)) { + return FALSE; + } + + InitQTextMsg(monster[i].mtalkmsg); + + if(monster[i].mName == UniqMonst[0].mName) { + if(monster[i].mtalkmsg == TEXT_GARBUD1) { + quests[Q_GARBUD]._qactive = 2; + } + quests[Q_GARBUD]._qlog = 1; + if(monster[i].mtalkmsg == TEXT_GARBUD2 && !(monster[i]._mFlags & 0x40)) { + SpawnItem(i, monster[i]._mx + 1, monster[i]._my + 1, TRUE); + monster[i]._mFlags |= 0x40; + } + } + if(monster[i].mName == UniqMonst[2].mName) { + if(monster[i].mtalkmsg == TEXT_ZHAR1 && !(monster[i]._mFlags & 0x40)) { + quests[Q_ZHAR]._qactive = 2; + quests[Q_ZHAR]._qlog = 1; + CreateTypeItem(monster[i]._mx + 1, monster[i]._my + 1, FALSE, ITYPE_MISC, IMISC_BOOK, TRUE, FALSE); + monster[i]._mFlags |= 0x40; + } + } + if(monster[i].mName == UniqMonst[3].mName) { + if(monster[i].mtalkmsg == TEXT_BANNER10 && !(monster[i]._mFlags & 0x40)) { + /// ASSERT: assert(setpc_x != 0); + ObjChangeMap(setpc_x, setpc_y, setpc_x + (setpc_w >> 1) + 2, setpc_y + (setpc_h >> 1) - 2); + tren = TransVal; + TransVal = 9; + DRLG_MRectTrans(setpc_x, setpc_y, setpc_x + (setpc_w >> 1) + 4, setpc_y + (setpc_h >> 1)); + TransVal = tren; + quests[Q_LTBANNER]._qvar1 = 2; + if(quests[Q_LTBANNER]._qactive == 1) { + quests[Q_LTBANNER]._qactive = 2; + } + monster[i]._mFlags |= 0x40; + } + if(quests[Q_LTBANNER]._qvar1 < 2) { + sprintf(tempstr, "SS Talk = %i, Flags = %i", monster[i].mtalkmsg, monster[i]._mFlags); + app_fatal(tempstr); + } + } + if(monster[i].mName == UniqMonst[7].mName) { + if(monster[i].mtalkmsg == TEXT_VEIL9) { + quests[Q_VEIL]._qactive = 2; + quests[Q_VEIL]._qlog = 1; + } + if(monster[i].mtalkmsg == TEXT_VEIL11 && !(monster[i]._mFlags & 0x40)) { + SpawnUnique(UITEM_STEELVEIL, monster[i]._mx + 1, monster[i]._my + 1); + monster[i]._mFlags |= 0x40; + } + } + if(monster[i].mName == UniqMonst[8].mName) { + /// ASSERT: assert(gbMaxPlayers == 1); + quests[Q_WARLORD]._qvar1 = 2; + } + if(monster[i].mName == UniqMonst[4].mName && gbMaxPlayers != 1) { + monster[i]._msquelch = 255; + monster[i].mtalkmsg = 0; + quests[Q_BETRAYER]._qvar1 = 6; + monster[i]._mgoal = 1; + } + + return FALSE; +} + +void M_Teleport(int i) +{ + int mulx, muly, x, y, a, b, px, py; + BOOL done; + MonsterStruct *Monst; + + if((DWORD)i >= MAXMONSTERS) { + app_fatal("M_Teleport: Invalid monster %d", i); + } + + Monst = &monster[i]; + done = FALSE; + + if(Monst->_mmode == MM_STONE) { + return; + } + + px = Monst->_menemyx; + py = Monst->_menemyy; + a = 2 * random(100, 2) - 1; + b = 2 * random(100, 2) - 1; + + for(mulx = -1; mulx <= 1 && !done; mulx++) { + for(muly = -1; muly < 1 && !done; muly++) { + if(mulx != 0 || muly != 0) { + x = px + a * mulx; + y = py + b * muly; + if(y >= 0 && y < MAXDUNY && x >= 0 && x < MAXDUNX && x != Monst->_mx && y != Monst->_my) { + if(PosOkMonst(i, x, y)) { + done = TRUE; + } + } + } + } + } + + if(done) { + M_ClearSquares(i); + /// ASSERT: assert((DWORD)Monst->_mx < MAXDUNX); + /// ASSERT: assert((DWORD)Monst->_my < MAXDUNY); + dMonster[Monst->_mx][Monst->_my] = 0; + dMonster[x][y] = i + 1; + Monst->_moldx = x; + Monst->_moldy = y; + Monst->_mdir = M_GetDir(i); + M_CheckEFlag(i); + } +} + +BOOL M_DoGotHit(int i) +{ + if((DWORD)i >= MAXMONSTERS) { + app_fatal("M_DoGotHit: Invalid monster %d", i); + } + if(monster[i].MType == NULL) { + app_fatal("M_DoGotHit: Monster %d \"%s\" MType NULL", i, monster[i].mName); + } + + if(monster[i]._mAnimFrame == monster[i]._mAnimLen) { + M_StartStand(i, monster[i]._mdir); + return TRUE; + } + + return FALSE; +} + +void M_UpdateLeader(int i) +{ + int x, tmp; + + if((DWORD)i >= MAXMONSTERS) { + app_fatal("M_UpdateLeader: Invalid monster %d", i); + } + + if(monster[i]._uniqtype != 0 && UniqMonst[monster[i]._uniqtype - 1].mUnqAttr & 2) { + /// ASSERT: assert((DWORD)nummonsters <= MAXMONSTERS); + } + + for(x = 0; x < nummonsters; x++) { + tmp = monstactive[x]; + if(monster[tmp].leaderflag == 1 && monster[tmp].leader == i) { + monster[tmp].leaderflag = 0; + } + } + + if(monster[i].leaderflag == 1) { + monster[monster[i].leader].packsize--; + } +} + +void DoEnding() +{ + BOOL bMusicOn; + long lVolume; + + if(gbMaxPlayers > 1) { + SNetLeaveGame(0x40000004); + } + + music_stop(); + + if(gbMaxPlayers > 1) { + Sleep(1000); + } + + if(plr[myplr]._pClass == PC_WARRIOR) { + play_movie("gendata\\DiabVic2.smk", FALSE); + } else if(plr[myplr]._pClass == PC_SORCERER) { + play_movie("gendata\\DiabVic1.smk", FALSE); + } else { + play_movie("gendata\\DiabVic3.smk", FALSE); + } + + play_movie("gendata\\Diabend.smk", FALSE); + bMusicOn = gbMusicOn; + gbMusicOn = 1; + lVolume = sound_get_or_set_music_volume(1); + sound_get_or_set_music_volume(0); + music_start(TMUSIC_L2); + loop_movie = TRUE; + play_movie("gendata\\loopdend.smk", TRUE); + loop_movie = FALSE; + music_stop(); + sound_get_or_set_music_volume(lVolume); + gbMusicOn = bMusicOn; +} + +void PrepDoEnding() +{ + int i, d; + DWORD k; + + gbSoundOn = sgbSaveSoundOn; + gbRunGame = 0; + deathflag = 0; + cineflag = 1; + + /// ASSERT: assert((DWORD)myplr < MAX_PLRS); + k = plr[myplr].pDiabloKillLevel; + d = gnDifficulty + 1; + if(k > d) { + d = k; + } + plr[myplr].pDiabloKillLevel = d; + + for(i = 0; i < MAX_PLRS; i++) { + plr[i]._pmode = PM_QUIT; + plr[i]._pInvincible = 1; + if(gbMaxPlayers > 1) { + if(plr[i]._pHitPoints >> 6 == 0) { + plr[i]._pHitPoints = 64; + } + if(plr[i]._pMana >> 6 == 0) { + plr[i]._pMana = 64; + } + } + } +} + +BOOL M_DoDeath(int i) +{ + int x, y; + + if((DWORD)i >= MAXMONSTERS) { + app_fatal("M_DoDeath: Invalid monster %d", i); + } + if(monster[i].MType == NULL) { + app_fatal("M_DoDeath: Monster %d \"%s\" MType NULL", i, monster[i].mName); + } + + monster[i]._mVar1++; + + if(monster[i].MType->mtype == MT_DIABLO) { + if(monster[i]._mx - ViewX < 0) { + x = -1; + } else if(monster[i]._mx - ViewX > 0) { + x = 1; + } else { + x = 0; + } + ViewX += x; + if(monster[i]._my - ViewY < 0) { + y = -1; + } else if(monster[i]._my - ViewY > 0) { + y = 1; + } else { + y = 0; + } + ViewY += y; + if(monster[i]._mVar1 == 140) { + PrepDoEnding(); + } + return FALSE; + } + + if(monster[i]._mAnimFrame == monster[i]._mAnimLen) { + if(monster[i]._uniqtype == 0) { + AddDead(monster[i]._mx, monster[i]._my, monster[i].MType->mdeadval, monster[i]._mdir); + } else { + AddDead(monster[i]._mx, monster[i]._my, monster[i]._udeadval, monster[i]._mdir); + } + /// ASSERT: assert(!(dFlags[monster[i]._mx+1][monster[i]._my] & BFLAG_MONSTLR) && !(dFlags[monster[i]._mx][monster[i]._my+1] & BFLAG_MONSTLR)); + dMonster[monster[i]._mx][monster[i]._my] = 0; + monster[i]._mDelFlag = 1; + M_UpdateLeader(i); + } + + return FALSE; +} + +BOOL M_DoSpStand(int i) +{ + if((DWORD)i >= MAXMONSTERS) { + app_fatal("M_DoSpStand: Invalid monster %d", i); + } + if(monster[i].MType == NULL) { + app_fatal("M_DoSpStand: Monster %d \"%s\" MType NULL", i, monster[i].mName); + } + + if(monster[i]._mAnimFrame == monster[i].MData->mAFNum2) { + PlayEffect(i, 3); + } + + if(monster[i]._mAnimFrame == monster[i]._mAnimLen) { + M_StartStand(i, monster[i]._mdir); + return TRUE; + } + + return FALSE; +} + +BOOL M_DoDelay(int i) +{ + int md, tmp; + + if((DWORD)i >= MAXMONSTERS) { + app_fatal("M_DoDelay: Invalid monster %d", i); + } + if(monster[i].MType == NULL) { + app_fatal("M_DoDelay: Monster %d \"%s\" MType NULL", i, monster[i].mName); + } + + md = M_GetDir(i); + monster[i]._mAnimData = monster[i].MType->Anims[0].Frames[md]; + + if(monster[i]._mAi == AI_LAZURUS && (monster[i]._mVar2 > 8 || monster[i]._mVar2 < 0)) { + monster[i]._mVar2 = 8; + } + + if(monster[i]._mVar2-- == 0) { + tmp = monster[i]._mAnimFrame; + M_StartStand(i, monster[i]._mdir); + monster[i]._mAnimFrame = tmp; + return TRUE; + } + + return FALSE; +} + +BOOL M_DoStone(int i) +{ + if((DWORD)i >= MAXMONSTERS) { + app_fatal("M_DoStone: Invalid monster %d", i); + } + + if(monster[i]._mhitpoints == 0) { + dMonster[monster[i]._mx][monster[i]._my] = 0; + monster[i]._mDelFlag = 1; + } + + return FALSE; +} + +void M_WalkDir(int i, int md) +{ + int mwi; + + if((DWORD)i >= MAXMONSTERS) { + app_fatal("M_WalkDir: Invalid monster %d", i); + } + + mwi = monster[i].MType->Anims[1].Rate - 1; + + switch(md) { + case DIR_N: + M_StartWalk(i, 0, -MWVel[mwi][1], -1, -1, 4); + break; + case DIR_NE: + M_StartWalk(i, MWVel[mwi][1], -MWVel[mwi][0], 0, -1, 5); + break; + case DIR_E: + M_StartWalk3(i, MWVel[mwi][2], 0, -32, -16, 1, -1, 1, 0, 6); + break; + case DIR_SE: + M_StartWalk2(i, MWVel[mwi][1], MWVel[mwi][0], -32, -16, 1, 0, 7); + break; + case DIR_S: + M_StartWalk2(i, 0, MWVel[mwi][1], 0, -32, 1, 1, 0); + break; + case DIR_SW: + M_StartWalk2(i, -MWVel[mwi][1], MWVel[mwi][0], 32, -16, 0, 1, 1); + break; + case DIR_W: + M_StartWalk3(i, -MWVel[mwi][2], 0, 32, -16, -1, 1, 0, 1, 2); + break; + case DIR_NW: + M_StartWalk(i, -MWVel[mwi][1], -MWVel[mwi][0], -1, 0, 3); + break; + } +} + +void GroupUnity(int i) +{ + int leader, tmp, m; + + if((DWORD)i >= MAXMONSTERS) { + app_fatal("GroupUnity: Invalid monster %d", i); + } + + if(monster[i].leaderflag != 0) { + leader = monster[i].leader; + tmp = LineClearF(CheckNoSolid, monster[i]._mx, monster[i]._my, monster[leader]._mfutx, monster[leader]._mfuty); + if(!tmp && monster[i].leaderflag == 1) { + monster[leader].packsize--; + monster[i].leaderflag = 2; + } else if(tmp && monster[i].leaderflag == 2) { + if(abs(monster[i]._mx - monster[leader]._mfutx) < 4 && abs(monster[i]._my - monster[leader]._mfuty) < 4) { + monster[leader].packsize++; + monster[i].leaderflag = 1; + } + } + } + + if(monster[i].leaderflag == 1) { + if(monster[i]._msquelch > monster[leader]._msquelch) { + monster[leader]._lastx = monster[i]._mx; + monster[leader]._lasty = monster[i]._my; + monster[leader]._msquelch = monster[i]._msquelch - 1; + } + if(monster[leader]._mAi == AI_GARG && monster[leader]._mFlags & 4) { + monster[leader]._mmode = MM_SATTACK; + monster[leader]._mFlags &= ~4; + } + } else if(monster[i]._uniqtype != 0 && UniqMonst[monster[i]._uniqtype - 1].mUnqAttr & 2) { + /// ASSERT: assert((DWORD)nummonsters <= MAXMONSTERS); + for(m = 0; m < nummonsters; m++) { + tmp = monstactive[m]; + if(monster[tmp].leaderflag == 1 && monster[tmp].leader == i) { + if(monster[i]._msquelch > monster[tmp]._msquelch) { + monster[tmp]._lastx = monster[i]._mx; + monster[tmp]._lasty = monster[i]._my; + monster[tmp]._msquelch = monster[i]._msquelch - 1; + } + if(monster[tmp]._mAi == AI_GARG && monster[tmp]._mFlags & 4) { + monster[tmp]._mmode = MM_SATTACK; + monster[tmp]._mFlags &= ~4; + } + } + } + } +} + +BOOL M_CallWalk(int i, int md) +{ + int mdtemp; + BOOL ok; + + mdtemp = md; + ok = DirOK(i, md); + + if(random(101, 2) != 0) { + ok = ok || (md = left[mdtemp], DirOK(i, md)) || (md = right[mdtemp], DirOK(i, md)); + } else { + ok = ok || (md = right[mdtemp], DirOK(i, md)) || (md = left[mdtemp], DirOK(i, md)); + } + if(random(102, 2) != 0) { + ok = ok || (md = right[right[mdtemp]], DirOK(i, md)) || (md = left[left[mdtemp]], DirOK(i, md)); + } else { + ok = ok || (md = left[left[mdtemp]], DirOK(i, md)) || (md = right[right[mdtemp]], DirOK(i, md)); + } + + if(ok) { + M_WalkDir(i, md); + } + + return ok; +} + +BOOL M_PathWalk(int i) +{ + static const char plr2monst[9] = { 0, 5, 3, 7, 1, 4, 6, 0, 2 }; + BOOL (*Check)(int, int, int); + char path[25]; + + if((DWORD)i >= MAXMONSTERS) { + app_fatal("M_PathWalk: Invalid monster %d", i); + } + + if(monster[i]._mFlags & 0x200) { + Check = PosOkMonst3; + } else { + Check = PosOkMonst; + } + + if(FindPath(Check, i, monster[i]._mx, monster[i]._my, monster[i]._menemyx, monster[i]._menemyy, path) != 0) { + M_CallWalk(i, plr2monst[path[0]]); + return TRUE; + } + + return FALSE; +} + +BOOL M_CallWalk2(int i, int md) +{ + int mdtemp; + BOOL ok; + + mdtemp = md; + ok = DirOK(i, md); + + if(random(101, 2) != 0) { + ok = ok || (md = left[mdtemp], DirOK(i, md)) || (md = right[mdtemp], DirOK(i, md)); + } else { + ok = ok || (md = right[mdtemp], DirOK(i, md)) || (md = left[mdtemp], DirOK(i, md)); + } + + if(ok) { + M_WalkDir(i, md); + } + + return ok; +} + +BOOL M_DumbWalk(int i, int md) +{ + BOOL ok; + + ok = DirOK(i, md); + if(ok) { + M_WalkDir(i, md); + } + + return ok; +} + +BOOL M_RoundWalk(int i, int md, int &dir) +{ + int mdtemp; + BOOL ok; + + if(dir != 0) { + md = left[left[md]]; + } else { + md = right[right[md]]; + } + + mdtemp = md; + ok = DirOK(i, md); + + if(!ok) { + if(dir != 0) { + ok = (md = right[mdtemp], DirOK(i, md)) || (md = right[right[mdtemp]], DirOK(i, md)); + } else { + ok = (md = left[mdtemp], DirOK(i, md)) || (md = left[left[mdtemp]], DirOK(i, md)); + } + } + + if(ok) { + M_WalkDir(i, md); + } else { + dir = dir == 0; + ok = M_CallWalk(i, opposite[mdtemp]); + } + + return ok; +} + +void MAI_Zombie(int i) +{ + int mx, my, md, v; + MonsterStruct *Monst; + + if((DWORD)i >= MAXMONSTERS) { + app_fatal("MAI_Zombie: Invalid monster %d", i); + } + + Monst = &monster[i]; + if(Monst->_mmode != MM_STAND) { + return; + } + + mx = Monst->_mx; + my = Monst->_my; + if(!(dFlags[mx][my] & 2)) { + return; + } + + mx -= Monst->_menemyx; + my -= Monst->_menemyy; + md = Monst->_mdir; + v = random(103, 100); + if(abs(mx) < 2 && abs(my) < 2) { + if(v < 2 * Monst->_mint + 10) { + M_StartAttack(i); + } + } else { + if(v < 2 * Monst->_mint + 10) { + if(abs(mx) < 2 * Monst->_mint + 4 && abs(my) < 2 * Monst->_mint + 4) { + md = M_GetDir(i); + M_CallWalk(i, md); + } else { + if(random(104, 100) < 2 * Monst->_mint + 20) { + md = random(104, 8); + } + M_DumbWalk(i, md); + } + } + } + + if(Monst->_mmode == MM_STAND) { + Monst->_mAnimData = Monst->MType->Anims[0].Frames[Monst->_mdir]; + } +} + +void MAI_SkelSd(int i) +{ + int mx, my, md; + MonsterStruct *Monst; + + if((DWORD)i >= MAXMONSTERS) { + app_fatal("MAI_SkelSd: Invalid monster %d", i); + } + + Monst = &monster[i]; + if(Monst->_mmode != MM_STAND || Monst->_msquelch == 0) { + return; + } + + mx = Monst->_mx - Monst->_menemyx; + my = Monst->_my - Monst->_menemyy; + md = GetDirection(Monst->_mx, Monst->_my, Monst->_lastx, Monst->_lasty); + Monst->_mdir = md; + if(abs(mx) < 2 && abs(my) < 2) { + if(Monst->_mVar1 == 13 || random(105, 100) < 2 * Monst->_mint + 20) { + M_StartAttack(i); + } else { + M_StartDelay(i, random(105, 10) + 10 - 2 * Monst->_mint); + } + } else { + if(Monst->_mVar1 != 13 && random(106, 100) < 35 - 4 * Monst->_mint) { + M_StartDelay(i, random(106, 10) + 15 - 2 * Monst->_mint); + } else { + M_CallWalk(i, md); + } + } + + if(Monst->_mmode == MM_STAND) { + Monst->_mAnimData = Monst->MType->Anims[0].Frames[md]; + } +} + +BOOL MAI_Path(int i) +{ + MonsterStruct *Monst; + + if((DWORD)i >= MAXMONSTERS) { + app_fatal("MAI_Path: Invalid monster %d", i); + } + + Monst = &monster[i]; + if(Monst->MType->mtype != MT_GOLEM) { + if(Monst->_msquelch == 0 || Monst->_mmode != MM_STAND) { + return FALSE; + } + if(Monst->_mgoal != 1 && Monst->_mgoal != 4 && Monst->_mgoal != 5) { + return FALSE; + } + if(Monst->_mx == 1 && Monst->_my == 0) { + return FALSE; + } + } + if(!LineClearF1(PosOkMonst2, i, Monst->_mx, Monst->_my, Monst->_menemyx, Monst->_menemyy) + || Monst->_pathcount >= 5 && Monst->_pathcount < 8) { + if(Monst->_mFlags & 0x200) { + MonstCheckDoors(i); + } + Monst->_pathcount++; + if(Monst->_pathcount < 5) { + return FALSE; + } + if(M_PathWalk(i)) { + return TRUE; + } + } + if(Monst->MType->mtype != MT_GOLEM) { + Monst->_pathcount = 0; + } + + return FALSE; +} + +void MAI_Snake(int i) +{ + MonsterStruct *Monst; + int fx, fy, mx, my, md, pnum, tmp; + + if((DWORD)i >= MAXMONSTERS) { + app_fatal("MAI_Snake: Invalid monster %d", i); + } + + char pattern[6] = { 1, 1, 0, -1, -1, 0 }; + Monst = &monster[i]; + pnum = Monst->_menemy; + if(Monst->_mmode != MM_STAND || Monst->_msquelch == 0) { + return; + } + + fx = Monst->_menemyx; + fy = Monst->_menemyy; + mx = Monst->_mx - fx; + my = Monst->_my - fy; + md = GetDirection(Monst->_mx, Monst->_my, Monst->_lastx, Monst->_lasty); + Monst->_mdir = md; + + if(abs(mx) < 2 && abs(my) < 2) { + if(Monst->_mVar1 == 13 || Monst->_mVar1 == 14 || random(105, 100) < Monst->_mint + 20) { + M_StartAttack(i); + } else { + M_StartDelay(i, random(105, 10) + 10 - Monst->_mint); + } + } else if(abs(mx) < 3 && abs(my) < 3 && LineClearF1(PosOkMonst, i, Monst->_mx, Monst->_my, fx, fy) && Monst->_mVar1 != 14) { + if(AddMissile(Monst->_mx, Monst->_my, fx, fy, md, MIS_RHINO, pnum, i, 0, 0) != -1) { + PlayEffect(i, 0); + dMonster[Monst->_mx][Monst->_my] = -(i + 1); + Monst->_mmode = MM_CHARGE; + } + } else if(Monst->_mVar1 != 13 && random(106, 100) < 35 - 2 * Monst->_mint) { + M_StartDelay(i, random(106, 10) + 15 - Monst->_mint); + } else { + if(md + pattern[Monst->_mgoalvar1] < 0) { + md = md + pattern[Monst->_mgoalvar1] + 8; + } else if(md + pattern[Monst->_mgoalvar1] >= 8) { + md = md + pattern[Monst->_mgoalvar1] - 8; + } else { + md = md + pattern[Monst->_mgoalvar1]; + } + Monst->_mgoalvar1++; + if(Monst->_mgoalvar1 > 5) { + Monst->_mgoalvar1 = 0; + } + tmp = md; + if(md - Monst->_mgoalvar2 < 0) { + md = md - Monst->_mgoalvar2 + 8; + } else if(md - Monst->_mgoalvar2 >= 8) { + md = md - Monst->_mgoalvar2 - 8; + } else { + md = md - Monst->_mgoalvar2; + } + if(md > 0) { + if(md < 4) { + if(Monst->_mgoalvar2 + 1 < 0) { + md = Monst->_mgoalvar2 + 1 + 8; + } else if(Monst->_mgoalvar2 + 1 >= 8) { + md = Monst->_mgoalvar2 + 1 - 8; + } else { + md = Monst->_mgoalvar2 + 1; + } + Monst->_mgoalvar2 = md; + } else if(md == 4) { + Monst->_mgoalvar2 = tmp; + } else { + if(Monst->_mgoalvar2 - 1 < 0) { + md = Monst->_mgoalvar2 - 1 + 8; + } else if(Monst->_mgoalvar2 - 1 >= 8) { + md = Monst->_mgoalvar2 - 1 - 8; + } else { + md = Monst->_mgoalvar2 - 1; + } + Monst->_mgoalvar2 = md; + } + } + /// ASSERT: assert(Monst->_mgoalvar2 >= 0 && Monst->_mgoalvar2 < 8); + if(!M_DumbWalk(i, Monst->_mgoalvar2)) { + M_CallWalk2(i, Monst->_mdir); + } + } + + if(Monst->_mmode == MM_STAND) { + Monst->_mAnimData = Monst->MType->Anims[0].Frames[Monst->_mdir]; + } +} + +void MAI_Bat(int i) +{ + MonsterStruct *Monst; + int mx, my, md, v, pnum, fx, fy; + + if((DWORD)i >= MAXMONSTERS) { + app_fatal("MAI_Bat: Invalid monster %d", i); + } + + Monst = &monster[i]; + pnum = Monst->_menemy; + if(Monst->_mmode != MM_STAND || Monst->_msquelch == 0) { + return; + } + + mx = Monst->_mx - Monst->_menemyx; + my = Monst->_my - Monst->_menemyy; + md = GetDirection(Monst->_mx, Monst->_my, Monst->_lastx, Monst->_lasty); + Monst->_mdir = md; + v = random(107, 100); + + if(Monst->_mgoal == 2) { + if(Monst->_mgoalvar1 == 0) { + M_CallWalk(i, opposite[md]); + Monst->_mgoalvar1++; + } else { + if(random(108, 2) != 0) { + M_CallWalk(i, left[md]); + } else { + M_CallWalk(i, right[md]); + } + Monst->_mgoal = 1; + } + return; + } + + fx = Monst->_menemyx; + fy = Monst->_menemyy; + + if(Monst->MType->mtype == MT_GLOOM + && (abs(mx) >= 5 || abs(my) >= 5) + && v < 4 * Monst->_mint + 33 + && LineClearF1(PosOkMonst, i, Monst->_mx, Monst->_my, fx, fy)) { + if(AddMissile(Monst->_mx, Monst->_my, fx, fy, md, MIS_RHINO, pnum, i, 0, 0) != -1) { + dMonster[Monst->_mx][Monst->_my] = -(i + 1); + Monst->_mmode = MM_CHARGE; + } + } else if(abs(mx) >= 2 || abs(my) >= 2) { + if(Monst->_mVar2 > 20 && v < Monst->_mint + 13 + || (Monst->_mVar1 == 1 || Monst->_mVar1 == 2 || Monst->_mVar1 == 3) && Monst->_mVar2 == 0 && v < Monst->_mint + 63) { + M_CallWalk(i, md); + } + } else if(v < 4 * Monst->_mint + 8) { + M_StartAttack(i); + Monst->_mgoal = 2; + Monst->_mgoalvar1 = 0; + if(Monst->MType->mtype == MT_FAMILIAR) { + AddMissile(Monst->_menemyx, Monst->_menemyy, Monst->_menemyx + 1, 0, -1, MIS_LIGHTNING, 1, i, random(109, 10) + 1, 0); + } + } + + if(Monst->_mmode == MM_STAND) { + Monst->_mAnimData = Monst->MType->Anims[0].Frames[md]; + } +} + +void MAI_SkelBow(int i) +{ + int mx, my, md, fx, fy, v; + BOOL walking; + MonsterStruct *Monst; + + walking = FALSE; + + if((DWORD)i >= MAXMONSTERS) { + app_fatal("MAI_SkelBow: Invalid monster %d", i); + } + + Monst = &monster[i]; + if(Monst->_mmode != MM_STAND || Monst->_msquelch == 0) { + return; + } + + mx = Monst->_mx - Monst->_menemyx; + my = Monst->_my - Monst->_menemyy; + md = M_GetDir(i); + Monst->_mdir = md; + v = random(110, 100); + + if(abs(mx) < 4 && abs(my) < 4) { + if(Monst->_mVar2 > 20 && v < 2 * Monst->_mint + 13 + || (Monst->_mVar1 == 1 || Monst->_mVar1 == 2 || Monst->_mVar1 == 3) && Monst->_mVar2 == 0 && v < 2 * Monst->_mint + 63) { + walking = M_DumbWalk(i, opposite[md]); + } + } + + fx = Monst->_menemyx; + fy = Monst->_menemyy; + + if(!walking && random(110, 100) < 2 * Monst->_mint + 3 && LineClear(Monst->_mx, Monst->_my, fx, fy)) { + M_StartRAttack(i, MIS_ARROW, 4); + } + + if(Monst->_mmode == MM_STAND) { + Monst->_mAnimData = Monst->MType->Anims[0].Frames[md]; + } +} + +void MAI_Fat(int i) +{ + int mx, my, md, v; + MonsterStruct *Monst; + + if((DWORD)i >= MAXMONSTERS) { + app_fatal("MAI_Fat: Invalid monster %d", i); + } + + Monst = &monster[i]; + if(Monst->_mmode != MM_STAND || Monst->_msquelch == 0) { + return; + } + + mx = Monst->_mx - Monst->_menemyx; + my = Monst->_my - Monst->_menemyy; + md = M_GetDir(i); + Monst->_mdir = md; + v = random(111, 100); + + if(abs(mx) >= 2 || abs(my) >= 2) { + if(Monst->_mVar2 > 20 && v < 4 * Monst->_mint + 20 + || (Monst->_mVar1 == 1 || Monst->_mVar1 == 2 || Monst->_mVar1 == 3) && Monst->_mVar2 == 0 && v < 4 * Monst->_mint + 70) { + M_CallWalk(i, md); + } + } else { + if(v < 4 * Monst->_mint + 15) { + M_StartAttack(i); + } else if(v < 4 * Monst->_mint + 20) { + M_StartSpAttack(i); + } + } + + if(Monst->_mmode == MM_STAND) { + Monst->_mAnimData = Monst->MType->Anims[0].Frames[md]; + } +} + +void MAI_Sneak(int i) +{ + int mx, my, md, v, dist; + MonsterStruct *Monst; + + if((DWORD)i >= MAXMONSTERS) { + app_fatal("MAI_Sneak: Invalid monster %d", i); + } + + Monst = &monster[i]; + if(Monst->_mmode != MM_STAND) { + return; + } + + mx = Monst->_mx; + my = Monst->_my; + if(dLight[mx][my] == lightmax) { + return; + } + + mx -= Monst->_menemyx; + my -= Monst->_menemyy; + md = M_GetDir(i); + dist = 5 - Monst->_mint; + + if(Monst->_mVar1 == 5) { + Monst->_mgoal = 2; + Monst->_mgoalvar1 = 0; + } else if(abs(mx) >= dist + 3 || abs(my) >= dist + 3 || Monst->_mgoalvar1 > 8) { + Monst->_mgoal = 1; + Monst->_mgoalvar1 = 0; + } + + if(Monst->_mgoal == 2) { + if(Monst->_mFlags & 0x10) { + md = GetDirection(Monst->_mx, Monst->_my, plr[Monst->_menemy]._pownerx, plr[Monst->_menemy]._pownery); + } + md = opposite[md]; + if(Monst->MType->mtype == MT_UNSEEN) { + if(random(112, 2) != 0) { + md = left[md]; + } else { + md = right[md]; + } + } + } + + Monst->_mdir = md; + v = random(112, 100); + + if(abs(mx) < dist && abs(my) < dist && Monst->_mFlags & 1) { + M_StartFadein(i, md, FALSE); + } else if((abs(mx) >= dist + 1 || abs(my) >= dist + 1) && !(Monst->_mFlags & 1)) { + M_StartFadeout(i, md, TRUE); + } else if(Monst->_mgoal == 2 + || (abs(mx) >= 2 || abs(my) >= 2) + && (Monst->_mVar2 > 20 && v < 4 * Monst->_mint + 14 + || (Monst->_mVar1 == 1 || Monst->_mVar1 == 2 || Monst->_mVar1 == 3) + && Monst->_mVar2 == 0 + && v < 4 * Monst->_mint + 64)) { + Monst->_mgoalvar1++; + M_CallWalk(i, md); + } + + if(Monst->_mmode == MM_STAND) { + if(abs(mx) < 2 && abs(my) < 2 && v < 4 * Monst->_mint + 10) { + M_StartAttack(i); + } else { + Monst->_mAnimData = Monst->MType->Anims[0].Frames[md]; + } + } +} + +void MAI_Fireman(int i) +{ + int mx, my, md, v, pnum, fx, fy; + MonsterStruct *Monst; + + if((DWORD)i >= MAXMONSTERS) { + app_fatal("MAI_Fireman: Invalid monster %d", i); + } + + Monst = &monster[i]; + if(Monst->_mmode != MM_STAND || Monst->_msquelch == 0) { + return; + } + + pnum = Monst->_menemy; + fx = Monst->_menemyx; + fy = Monst->_menemyy; + mx = Monst->_mx - fx; + my = Monst->_my - fy; + md = M_GetDir(i); + + if(Monst->_mgoal == 1) { + if(LineClear(Monst->_mx, Monst->_my, fx, fy) + && AddMissile(Monst->_mx, Monst->_my, fx, fy, md, MIS_NULL_32, pnum, i, 0, 0) != -1) { + Monst->_mmode = MM_CHARGE; + Monst->_mgoal = 5; + Monst->_mgoalvar1 = 0; + } + } else if(Monst->_mgoal == 5) { + if(Monst->_mgoalvar1 == 3) { + Monst->_mgoal = 1; + M_StartFadeout(i, md, TRUE); + } else if(LineClear(Monst->_mx, Monst->_my, fx, fy)) { + M_StartRAttack(i, MIS_NULL_33, 4); + Monst->_mgoalvar1++; + } else { + M_StartDelay(i, random(112, 10) + 5); + Monst->_mgoalvar1++; + } + } else if(Monst->_mgoal == 2) { + M_StartFadein(i, md, FALSE); + Monst->_mgoal = 5; + } + + Monst->_mdir = md; + v = random(112, 100); /* unused */ + + if(Monst->_mmode == MM_STAND) { + if(abs(mx) < 2 && abs(my) < 2 && Monst->_mgoal == 1) { + M_TryH2HHit(i, monster[i]._menemy, monster[i].mHit, monster[i].mMinDamage, monster[i].mMaxDamage); + Monst->_mgoal = 2; + if(!M_CallWalk(i, opposite[md])) { + M_StartFadein(i, md, FALSE); + Monst->_mgoal = 5; + } + } else if(!M_CallWalk(i, md) && (Monst->_mgoal == 1 || Monst->_mgoal == 2)) { + M_StartFadein(i, md, FALSE); + Monst->_mgoal = 5; + } + } +} + +void MAI_Fallen(int i) +{ + MonsterStruct *Monst; + int x, y, xpos, ypos, m, rad, mx, my, aitype; + + if((DWORD)i >= MAXMONSTERS) { + app_fatal("MAI_Fallen: Invalid monster %d", i); + } + + Monst = &monster[i]; + if(Monst->_mgoal == 5) { + if(Monst->_mgoalvar1 != 0) { + Monst->_mgoalvar1--; + } else { + Monst->_mgoal = 1; + } + } + + if(Monst->_mmode != MM_STAND || Monst->_msquelch == 0) { + return; + } + + if(Monst->_mgoal == 2 && Monst->_mgoalvar1-- == 0) { + Monst->_mgoal = 1; + M_StartStand(i, opposite[Monst->_mdir]); + } + + if(Monst->_mAnimFrame == Monst->_mAnimLen) { + if(random(113, 4) == 0) { + if(!(monster[i]._mFlags & 8)) { + M_StartSpStand(i, Monst->_mdir); + if(Monst->_mmaxhp - (2 * Monst->_mint + 2) >= Monst->_mhitpoints) { + Monst->_mhitpoints += 2 * Monst->_mint + 2; + } else { + Monst->_mhitpoints = Monst->_mmaxhp; + } + } + rad = 2 * Monst->_mint + 4; + for(y = -rad; y <= rad; y++) { + for(x = -rad; x <= rad; x++) { + xpos = x + Monst->_mx; + ypos = y + Monst->_my; + if(y >= 0 && y < MAXDUNY && x >= 0 && x < MAXDUNX) { + m = dMonster[xpos][ypos]; + if(m > 0) { + m--; + aitype = monster[m]._mAi; + if(aitype == AI_FALLEN) { + monster[m]._mgoal = 5; + monster[m]._mgoalvar1 = 5 * (6 * Monst->_mint + 21); + } + } + } + } + } + } + } else { + if(Monst->_mgoal == 2) { + M_CallWalk(i, Monst->_mdir); + } else if(Monst->_mgoal == 5) { + mx = Monst->_mx - Monst->_menemyx; + my = Monst->_my - Monst->_menemyy; + if(abs(mx) < 2 && abs(my) < 2) { + M_StartAttack(i); + } else { + M_CallWalk(i, M_GetDir(i)); + } + } else { + MAI_SkelSd(i); + } + } +} + +void MAI_Cleaver(int i) +{ + MonsterStruct *Monst; + int mx, my, md; + + if((DWORD)i >= MAXMONSTERS) { + app_fatal("MAI_Cleaver: Invalid monster %d", i); + } + + Monst = &monster[i]; + if(Monst->_mmode != MM_STAND || Monst->_msquelch == 0) { + return; + } + + mx = Monst->_mx - Monst->_menemyx; + my = Monst->_my - Monst->_menemyy; + md = GetDirection(Monst->_mx, Monst->_my, Monst->_lastx, Monst->_lasty); + Monst->_mdir = md; + + if(abs(mx) < 2 && abs(my) < 2) { + M_StartAttack(i); + } else { + M_CallWalk(i, md); + } + + if(Monst->_mmode == MM_STAND) { + Monst->_mAnimData = Monst->MType->Anims[0].Frames[md]; + } +} + +void MAI_Round(int i, BOOL special) +{ + int mx, my, md, v, fx, fy, dist; + MonsterStruct *Monst; + + if((DWORD)i >= MAXMONSTERS) { + app_fatal("MAI_Round: Invalid monster %d", i); + } + + Monst = &monster[i]; + if(Monst->_mmode != MM_STAND || Monst->_msquelch == 0) { + return; + } + + fx = Monst->_menemyx; + fy = Monst->_menemyy; + mx = Monst->_mx - fx; + my = Monst->_my - fy; + md = GetDirection(Monst->_mx, Monst->_my, Monst->_lastx, Monst->_lasty); + + if(Monst->_msquelch < 255) { + MonstCheckDoors(i); + } + + v = random(114, 100); + + if(abs(mx) < 2 && abs(my) < 2 || Monst->_msquelch != 255 || dTransVal[Monst->_mx][Monst->_my] != dTransVal[fx][fy]) { + Monst->_mgoal = 1; + } else if(Monst->_mgoal == 4 || (abs(mx) >= 4 || abs(my) >= 4) && random(115, 4) == 0) { + if(Monst->_mgoal != 4) { + Monst->_mgoalvar1 = 0; + Monst->_mgoalvar2 = random(116, 2); + } + Monst->_mgoal = 4; + if(abs(mx) > abs(my)) { + dist = abs(mx); + } else { + dist = abs(my); + } + if(Monst->_mgoalvar1++ >= 2 * dist && DirOK(i, md) || dTransVal[Monst->_mx][Monst->_my] != dTransVal[fx][fy]) { + Monst->_mgoal = 1; + } else if(!M_RoundWalk(i, md, Monst->_mgoalvar2)) { + M_StartDelay(i, random(125, 10) + 10); + } + } + + if(Monst->_mgoal == 1) { + if(abs(mx) < 2 && abs(my) < 2) { + if(v < 2 * Monst->_mint + 23) { + Monst->_mdir = md; + if(special && Monst->_mhitpoints < Monst->_mmaxhp >> 1 && random(117, 2)) { + M_StartSpAttack(i); + } else { + M_StartAttack(i); + } + } + } else if(Monst->_mVar2 > 20 && v < 2 * Monst->_mint + 28 + || (Monst->_mVar1 == 1 || Monst->_mVar1 == 2 || Monst->_mVar1 == 3) + && Monst->_mVar2 == 0 + && v < 2 * Monst->_mint + 78) { + M_CallWalk(i, md); + } + } + if(Monst->_mmode == MM_STAND) { + Monst->_mAnimData = Monst->MType->Anims[0].Frames[md]; + } +} + +void MAI_GoatMc(int i) +{ + MAI_Round(i, TRUE); +} + +void MAI_Ranged(int i, int missile_type, BOOL special) +{ + int fx, fy, mx, my, md; + MonsterStruct *Monst; + + if((DWORD)i >= MAXMONSTERS) { + app_fatal("MAI_Ranged: Invalid monster %d", i); + } + + Monst = &monster[i]; + if(Monst->_mmode != MM_STAND) { + return; + } + + if(Monst->_msquelch == 255 || monster[i]._mFlags & 0x10) { + fx = Monst->_menemyx; + fy = Monst->_menemyy; + mx = Monst->_mx - fx; + my = Monst->_my - fy; + md = M_GetDir(i); + if(Monst->_msquelch < 255) { + MonstCheckDoors(i); + } + Monst->_mdir = md; + if(Monst->_mVar1 == 10) { + M_StartDelay(i, random(118, 20)); + } else if(abs(mx) < 4 && abs(my) < 4) { + if(random(119, 100) < 10 * (Monst->_mint + 7)) { + M_CallWalk(i, opposite[md]); + } + } + if(Monst->_mmode == MM_STAND) { + if(LineClear(Monst->_mx, Monst->_my, fx, fy)) { + if(special) { + M_StartRSpAttack(i, missile_type, 4); + } else { + M_StartRAttack(i, missile_type, 4); + } + } else { + Monst->_mAnimData = Monst->MType->Anims[0].Frames[md]; + } + } + } else if(Monst->_msquelch != 0) { + mx = Monst->_lastx; + my = Monst->_lasty; + md = GetDirection(Monst->_mx, Monst->_my, mx, my); + M_CallWalk(i, md); + } +} + +void MAI_GoatBow(int i) +{ + MAI_Ranged(i, MIS_ARROW, FALSE); +} + +void MAI_Succ(int i) +{ + MAI_Ranged(i, MIS_FLARE, FALSE); +} + +void MAI_AcidUniq(int i) +{ + MAI_Ranged(i, MIS_ACID, TRUE); +} + +void MAI_Scav(int i) +{ + MonsterStruct *Monst; + int x, y; + BOOL done; + + if((DWORD)i >= MAXMONSTERS) { + app_fatal("MAI_Scav: Invalid monster %d", i); + } + + Monst = &monster[i]; + done = FALSE; + if(Monst->_mmode != MM_STAND) { + return; + } + + if(Monst->_mhitpoints < Monst->_mmaxhp >> 1 && Monst->_mgoal != 3) { + if(monster[i].leaderflag != 0) { + monster[monster[i].leader].packsize--; + monster[i].leaderflag = 0; + } + Monst->_mgoal = 3; + Monst->_mgoalvar3 = 10; + } + if(Monst->_mgoal == 3 && Monst->_mgoalvar3 != 0) { + Monst->_mgoalvar3--; + if(dDead[Monst->_mx][Monst->_my] != 0) { + M_StartEat(i); + if(!(monster[i]._mFlags & 8)) { + Monst->_mhitpoints += 64; + } + if(Monst->_mhitpoints >= (Monst->_mmaxhp >> 1) + (Monst->_mmaxhp >> 2)) { + Monst->_mgoal = 1; + Monst->_mgoalvar1 = 0; + Monst->_mgoalvar2 = 0; + } + } else { + if(Monst->_mgoalvar1 == 0) { + if(random(120, 2) != 0) { + for(y = -4; y <= 4 && !done; y++) { + for(x = -4; x <= 4 && !done; x++) { + if(y >= 0 && y < MAXDUNY && x >= 0 && x < MAXDUNX) { + done = dDead[x + Monst->_mx][y + Monst->_my] != 0 + && LineClearF(CheckNoSolid, Monst->_mx, Monst->_my, x + Monst->_mx, y + Monst->_my); + } + } + } + x--; + y--; + } else { + for(y = 4; y >= -4 && !done; y--) { + for(x = 4; x >= -4 && !done; x--) { + if(y >= 0 && y < MAXDUNY && x >= 0 && x < MAXDUNX) { + done = dDead[x + Monst->_mx][y + Monst->_my] != 0 + && LineClearF(CheckNoSolid, Monst->_mx, Monst->_my, x + Monst->_mx, y + Monst->_my); + } + } + } + x++; + y++; + } + if(done) { + Monst->_mgoalvar1 = Monst->_mx + x + 1; + Monst->_mgoalvar2 = Monst->_my + y + 1; + } + } + if(Monst->_mgoalvar1 != 0) { + x = Monst->_mgoalvar1 - 1; + y = Monst->_mgoalvar2 - 1; + Monst->_mdir = GetDirection(Monst->_mx, Monst->_my, x, y); + M_CallWalk(i, Monst->_mdir); + } + } + } + if(Monst->_mmode == MM_STAND) { + MAI_SkelSd(i); + } +} + +void MAI_Garg(int i) +{ + MonsterStruct *Monst; + int mx, my, md; + + if((DWORD)i >= MAXMONSTERS) { + app_fatal("MAI_Garg: Invalid monster %d", i); + } + + Monst = &monster[i]; + mx = Monst->_mx - Monst->_lastx; + my = Monst->_my - Monst->_lasty; + md = M_GetDir(i); + + if(Monst->_msquelch != 0 && Monst->_mFlags & 4) { + M_Enemy(i); + mx = Monst->_mx - Monst->_menemyx; + my = Monst->_my - Monst->_menemyy; + if(abs(mx) < Monst->_mint + 2 && abs(my) < Monst->_mint + 2) { + Monst->_mFlags &= ~4; + } + return; + } + + if(Monst->_mmode != MM_STAND || Monst->_msquelch == 0) { + return; + } + + if(Monst->_mhitpoints < Monst->_mmaxhp >> 1 && !(Monst->_mFlags & 8)) { + Monst->_mgoal = 2; + } + if(Monst->_mgoal == 2) { + if(abs(mx) < Monst->_mint + 2 && abs(my) < Monst->_mint + 2) { + if(!M_CallWalk(i, opposite[md])) { + Monst->_mgoal = 1; + } + } else { + Monst->_mgoal = 1; + M_StartHeal(i); + } + } + + MAI_Round(i, FALSE); +} + +void MAI_RoundRanged(int i, int missile_type, BOOL checkdoors, int dam, int lessmissiles) +{ + int fx, fy, mx, my, md, v, dist; + MonsterStruct *Monst; + + if((DWORD)i >= MAXMONSTERS) { + app_fatal("MAI_RoundRanged: Invalid monster %d", i); + } + + Monst = &monster[i]; + if(Monst->_mmode != MM_STAND || Monst->_msquelch == 0) { + return; + } + + fx = Monst->_menemyx; + fy = Monst->_menemyy; + mx = Monst->_mx - fx; + my = Monst->_my - fy; + md = GetDirection(Monst->_mx, Monst->_my, Monst->_lastx, Monst->_lasty); + + if(checkdoors && Monst->_msquelch < 255) { + MonstCheckDoors(i); + } + + v = random(121, 10000); + + if(abs(mx) < 2 && abs(my) < 2 || Monst->_msquelch != 255 || dTransVal[Monst->_mx][Monst->_my] != dTransVal[fx][fy]) { + Monst->_mgoal = 1; + } else if(Monst->_mgoal == 4 || (abs(mx) >= 3 || abs(my) >= 3) && random(122, 4 << lessmissiles) == 0) { + if(Monst->_mgoal != 4) { + Monst->_mgoalvar1 = 0; + Monst->_mgoalvar2 = random(123, 2); + } + Monst->_mgoal = 4; + if(abs(mx) > abs(my)) { + dist = abs(mx); + } else { + dist = abs(my); + } + if(Monst->_mgoalvar1++ >= 2 * dist && DirOK(i, md)) { + Monst->_mgoal = 1; + } else if(v < 500 * (Monst->_mint + 1) >> lessmissiles && LineClear(Monst->_mx, Monst->_my, fx, fy)) { + M_StartRSpAttack(i, missile_type, dam); + } else { + M_RoundWalk(i, md, Monst->_mgoalvar2); + } + } + + if(Monst->_mgoal == 1) { + if(((abs(mx) >= 3 || abs(my) >= 3) && v < 500 * (Monst->_mint + 2) >> lessmissiles + || v < 500 * (Monst->_mint + 1) >> lessmissiles) + && LineClear(Monst->_mx, Monst->_my, fx, fy)) { + M_StartRSpAttack(i, missile_type, dam); + } else if(abs(mx) < 2 && abs(my) < 2) { + if(v < 1000 * (Monst->_mint + 6)) { + Monst->_mdir = md; + M_StartAttack(i); + } + } else { + v = random(124, 100); + if(v < 1000 * (Monst->_mint + 5) + || (Monst->_mVar1 == 1 || Monst->_mVar1 == 2 || Monst->_mVar1 == 3) && Monst->_mVar2 == 0 && v < 1000 * (Monst->_mint + 8)) { + M_CallWalk(i, md); + } + } + } + if(Monst->_mmode == MM_STAND) { + M_StartDelay(i, random(125, 10) + 5); + } +} + +void MAI_Magma(int i) +{ + MAI_RoundRanged(i, MIS_MAGMABALL, TRUE, 4, 0); +} + +void MAI_Storm(int i) +{ + MAI_RoundRanged(i, MIS_LIGHTCTRL2, TRUE, 4, 0); +} + +void MAI_Acid(int i) +{ + MAI_RoundRanged(i, MIS_ACID, FALSE, 4, 1); +} + +void MAI_Diablo(int i) +{ + MAI_RoundRanged(i, MIS_DIABAPOCA, FALSE, 40, 0); +} + +void MAI_RR2(int i, int mistype, int dam) +{ + int fx, fy, mx, my, md, v, dist; + MonsterStruct *Monst; + + if((DWORD)i >= MAXMONSTERS) { + app_fatal("MAI_RR2: Invalid monster %d", i); + } + + Monst = &monster[i]; + mx = Monst->_mx - Monst->_menemyx; + my = Monst->_my - Monst->_menemyy; + if(abs(mx) >= 5 || abs(my) >= 5) { + MAI_SkelSd(i); + return; + } + if(Monst->_mmode != MM_STAND || Monst->_msquelch == 0) { + return; + } + + fx = Monst->_menemyx; + fy = Monst->_menemyy; + mx = Monst->_mx - fx; + my = Monst->_my - fy; + md = GetDirection(Monst->_mx, Monst->_my, Monst->_lastx, Monst->_lasty); + + if(Monst->_msquelch < 255) { + MonstCheckDoors(i); + } + + v = random(121, 100); + + if(abs(mx) < 2 && abs(my) < 2 || Monst->_msquelch != 255 || dTransVal[Monst->_mx][Monst->_my] != dTransVal[fx][fy]) { + Monst->_mgoal = 1; + } else if(Monst->_mgoal == 4 || abs(mx) >= 3 || abs(my) >= 3) { + if(Monst->_mgoal != 4) { + Monst->_mgoalvar1 = 0; + Monst->_mgoalvar2 = random(123, 2); + } + Monst->_mgoal = 4; + Monst->_mgoalvar3 = 4; + if(abs(mx) > abs(my)) { + dist = abs(mx); + } else { + dist = abs(my); + } + if(Monst->_mgoalvar1++ >= 2 * dist && DirOK(i, md)) { + Monst->_mgoal = 1; + } else if(v < 5 * (Monst->_mint + 16)) { + M_RoundWalk(i, md, Monst->_mgoalvar2); + } + } + + if(Monst->_mgoal == 1) { + if(((abs(mx) >= 3 || abs(my) >= 3) && v < 5 * (Monst->_mint + 2) || v < 5 * (Monst->_mint + 1) || Monst->_mgoalvar3 == 4) + && LineClear(Monst->_mx, Monst->_my, fx, fy)) { + M_StartRSpAttack(i, mistype, dam); + } else if(abs(mx) < 2 && abs(my) < 2) { + v = random(124, 100); + if(v < 10 * (Monst->_mint + 4)) { + Monst->_mdir = md; + if(random(124, 2) != 0) { + M_StartAttack(i); + } else { + M_StartRSpAttack(i, mistype, dam); + } + } + } else { + v = random(124, 100); + if(v < 2 * (5 * Monst->_mint + 25) + || (Monst->_mVar1 == 1 || Monst->_mVar1 == 2 || Monst->_mVar1 == 3) && Monst->_mVar2 == 0 && v < 2 * (5 * Monst->_mint + 40)) { + M_CallWalk(i, md); + } + } + Monst->_mgoalvar3 = 1; + } + if(Monst->_mmode == MM_STAND) { + M_StartDelay(i, random(125, 10) + 5); + } +} + +void MAI_Mega(int i) +{ + MAI_RR2(i, MIS_FLAMEC, 0); +} + +void MAI_Golum(int i) +{ + int j, k, mid, mx, my, md; + BOOL ok, have_enemy; + MonsterStruct *Monst; + + if((DWORD)i >= MAXMONSTERS) { + app_fatal("MAI_Golum: Invalid monster %d", i); + } + + Monst = &monster[i]; + if(Monst->_mx == 1 && Monst->_my == 0) { + return; + } + if(Monst->_mmode == MM_DEATH || Monst->_mmode == MM_SPSTAND) { + return; + } + if(Monst->_mmode >= MM_WALK && Monst->_mmode <= MM_WALK3) { + return; + } + + if(!(monster[i]._mFlags & 0x10)) { + M_Enemy(i); + } + + have_enemy = !(Monst->_mFlags & 0x400); + + if(Monst->_mmode == MM_ATTACK) { + return; + } + + mx = Monst->_mx - monster[Monst->_menemy]._mfutx; + my = Monst->_my - monster[Monst->_menemy]._mfuty; + md = GetDirection(Monst->_mx, Monst->_my, monster[Monst->_menemy]._mx, monster[Monst->_menemy]._my); + Monst->_mdir = md; + + if(abs(mx) < 2 && abs(my) < 2) { + if(have_enemy) { + Monst->_menemyx = monster[Monst->_menemy]._mx; + Monst->_menemyy = monster[Monst->_menemy]._my; + if(monster[Monst->_menemy]._msquelch == 0) { + monster[Monst->_menemy]._msquelch = 255; + monster[Monst->_menemy]._lastx = Monst->_mx; + monster[Monst->_menemy]._lasty = Monst->_my; + for(k = 0; k < 5; k++) { + for(j = 0; j < 5; j++) { + mid = dMonster[j + monster[i]._mx - 2][k + monster[i]._my - 2]; + if(mid > 0) { + monster[mid]._msquelch = 255; + } + } + } + } + M_StartAttack(i); + return; + } + } else if(have_enemy && MAI_Path(i)) { + return; + } + + Monst->_pathcount++; + if(Monst->_pathcount > 8) { + Monst->_pathcount = 5; + } + + ok = M_CallWalk(i, plr[i]._pdir); + if(!ok) { + md = (md - 1) & 7; + for(j = 0; j < 8 && !ok; j++) { + md = (md + 1) & 7; + ok = DirOK(i, md); + } + if(ok) { + M_WalkDir(i, md); + } + } +} + +void MAI_SkelKing(int i) +{ + int fx, fy, mx, my, md, v, dist, nx, ny, skel; + MonsterStruct *Monst; + + if((DWORD)i >= MAXMONSTERS) { + app_fatal("MAI_SkelKing: Invalid monster %d", i); + } + + Monst = &monster[i]; + if(Monst->_mmode != MM_STAND || Monst->_msquelch == 0) { + return; + } + + fx = Monst->_menemyx; + fy = Monst->_menemyy; + mx = Monst->_mx - fx; + my = Monst->_my - fy; + md = GetDirection(Monst->_mx, Monst->_my, Monst->_lastx, Monst->_lasty); + + if(Monst->_msquelch < 255) { + MonstCheckDoors(i); + } + + v = random(126, 100); + + if(abs(mx) < 2 && abs(my) < 2 || Monst->_msquelch != 255 || dTransVal[Monst->_mx][Monst->_my] != dTransVal[fx][fy]) { + Monst->_mgoal = 1; + } else if(Monst->_mgoal == 4 || (abs(mx) >= 3 || abs(my) >= 3) && random(127, 4) == 0) { + if(Monst->_mgoal != 4) { + Monst->_mgoalvar1 = 0; + Monst->_mgoalvar2 = random(128, 2); + } + Monst->_mgoal = 4; + if(abs(mx) > abs(my)) { + dist = abs(mx); + } else { + dist = abs(my); + } + if(Monst->_mgoalvar1++ >= 2 * dist && DirOK(i, md) || dTransVal[Monst->_mx][Monst->_my] != dTransVal[fx][fy]) { + Monst->_mgoal = 1; + } else if(!M_RoundWalk(i, md, Monst->_mgoalvar2)) { + M_StartDelay(i, random(125, 10) + 10); + } + } + + if(Monst->_mgoal == 1) { + if(gbMaxPlayers == 1 + && ((abs(mx) >= 3 || abs(my) >= 3) && v < 4 * Monst->_mint + 35 || v < 6) + && LineClear(Monst->_mx, Monst->_my, fx, fy)) { + nx = Monst->_mx + offset_x[md]; + ny = Monst->_my + offset_y[md]; + if(PosOkMonst(i, nx, ny) && nummonsters < MAXMONSTERS) { + skel = M_SpawnSkel(nx, ny, md); /// BUGFIX: was 'skel' to be used? + M_StartSpStand(i, md); + } + } else if(abs(mx) < 2 && abs(my) < 2) { + if(v < Monst->_mint + 20) { + Monst->_mdir = md; + M_StartAttack(i); + } + } else { + v = random(129, 100); + if(v < Monst->_mint + 25 + || (Monst->_mVar1 == 1 || Monst->_mVar1 == 2 || Monst->_mVar1 == 3) && Monst->_mVar2 == 0 && v < Monst->_mint + 75) { + M_CallWalk(i, md); + } else { + M_StartDelay(i, random(130, 10) + 10); + } + } + } + if(Monst->_mmode == MM_STAND) { + Monst->_mAnimData = Monst->MType->Anims[0].Frames[md]; + } +} + +void MAI_Rhino(int i) +{ + int fx, fy, mx, my, md, v, dist; + MonsterStruct *Monst; + + if((DWORD)i >= MAXMONSTERS) { + app_fatal("MAI_Rhino: Invalid monster %d", i); + } + + Monst = &monster[i]; + if(Monst->_mmode != MM_STAND || Monst->_msquelch == 0) { + return; + } + + fx = Monst->_menemyx; + fy = Monst->_menemyy; + mx = Monst->_mx - fx; + my = Monst->_my - fy; + md = GetDirection(Monst->_mx, Monst->_my, Monst->_lastx, Monst->_lasty); + + if(Monst->_msquelch < 255) { + MonstCheckDoors(i); + } + + v = random(131, 100); + + if(abs(mx) < 2 && abs(my) < 2) { + Monst->_mgoal = 1; + } else if(Monst->_mgoal == 4 || (abs(mx) >= 5 || abs(my) >= 5) && random(132, 4) != 0) { + if(Monst->_mgoal != 4) { + Monst->_mgoalvar1 = 0; + Monst->_mgoalvar2 = random(133, 2); + } + Monst->_mgoal = 4; + if(abs(mx) > abs(my)) { + dist = abs(mx); + } else { + dist = abs(my); + } + if(Monst->_mgoalvar1++ >= 2 * dist || dTransVal[Monst->_mx][Monst->_my] != dTransVal[fx][fy]) { + Monst->_mgoal = 1; + } else if(!M_RoundWalk(i, md, Monst->_mgoalvar2)) { + M_StartDelay(i, random(125, 10) + 10); + } + } + + if(Monst->_mgoal == 1) { + if((abs(mx) >= 5 || abs(my) >= 5) + && v < 2 * Monst->_mint + 43 + && LineClearF1(PosOkMonst, i, Monst->_mx, Monst->_my, fx, fy)) { + if(AddMissile(Monst->_mx, Monst->_my, fx, fy, md, MIS_RHINO, Monst->_menemy, i, 0, 0) != -1) { + if(Monst->MData->snd_special) { + PlayEffect(i, 3); + } + dMonster[Monst->_mx][Monst->_my] = -(i + 1); + Monst->_mmode = MM_CHARGE; + } + } else if(abs(mx) < 2 && abs(my) < 2) { + if(v < 2 * Monst->_mint + 28) { + Monst->_mdir = md; + M_StartAttack(i); + } + } else { + v = random(134, 100); + if(v < 2 * Monst->_mint + 33 + || (Monst->_mVar1 == 1 || Monst->_mVar1 == 2 || Monst->_mVar1 == 3) && Monst->_mVar2 == 0 && v < 2 * Monst->_mint + 83) { + M_CallWalk(i, md); + } else { + M_StartDelay(i, random(135, 10) + 10); + } + } + } + if(Monst->_mmode == MM_STAND) { + Monst->_mAnimData = Monst->MType->Anims[0].Frames[Monst->_mdir]; /// BUGFIX: use 'md'? + } +} + +void MAI_Counselor(int i) +{ + static const BYTE counsmiss[4] = { MIS_FIREBOLT, MIS_CBOLT, MIS_LIGHTCTRL, MIS_FIREBALL }; + int fx, fy, mx, my, md, v, dist; + MonsterStruct *Monst; + + if((DWORD)i >= MAXMONSTERS) { + app_fatal("MAI_Counselor: Invalid monster %d", i); + } + + Monst = &monster[i]; + if(Monst->_mmode != MM_STAND || Monst->_msquelch == 0) { + return; + } + + fx = Monst->_menemyx; + fy = Monst->_menemyy; + mx = Monst->_mx - fx; + my = Monst->_my - fy; + md = GetDirection(Monst->_mx, Monst->_my, Monst->_lastx, Monst->_lasty); + + if(Monst->_msquelch < 255) { + MonstCheckDoors(i); + } + + v = random(121, 100); + + if(Monst->_mgoal == 2) { + if(Monst->_mgoalvar1++ > 3) { + Monst->_mgoal = 1; + M_StartFadein(i, md, TRUE); + } else { + M_CallWalk(i, opposite[md]); + } + } else if(Monst->_mgoal == 4) { + if(abs(mx) > abs(my)) { + dist = abs(mx); + } else { + dist = abs(my); + } + if(abs(mx) < 2 && abs(my) < 2 || Monst->_msquelch != 255 || dTransVal[Monst->_mx][Monst->_my] != dTransVal[fx][fy]) { + Monst->_mgoal = 1; + M_StartFadein(i, md, TRUE); + } else if(Monst->_mgoalvar1++ >= 2 * dist && DirOK(i, md)) { + Monst->_mgoal = 1; + M_StartFadein(i, md, TRUE); + } else { + M_RoundWalk(i, md, Monst->_mgoalvar2); + } + } else if(Monst->_mgoal == 1) { + if(abs(mx) < 2 && abs(my) < 2) { + Monst->_mdir = md; + if(Monst->_mhitpoints < Monst->_mmaxhp >> 1) { + Monst->_mgoal = 2; + Monst->_mgoalvar1 = 0; + M_StartFadeout(i, md, FALSE); + } else if(Monst->_mVar1 == 13 || random(105, 100) < 2 * Monst->_mint + 20) { + M_StartRAttack(i, -1, 0); + AddMissile(monster[i]._mx, monster[i]._my, 0, 0, monster[i]._mdir, MIS_FLASH, 1, i, 4, 0); + AddMissile(monster[i]._mx, monster[i]._my, 0, 0, monster[i]._mdir, MIS_FLASH2, 1, i, 4, 0); + } else { + M_StartDelay(i, random(105, 10) + 2 * (5 - Monst->_mint)); + } + } else if(v < 5 * (Monst->_mint + 10) && LineClear(Monst->_mx, Monst->_my, fx, fy)) { + M_StartRAttack(i, counsmiss[Monst->_mint], random(77, Monst->mMaxDamage - Monst->mMinDamage + 1) + Monst->mMinDamage); + } else { + v = random(124, 100); + if(v < 30) { + Monst->_mgoal = 4; + Monst->_mgoalvar1 = 0; + M_StartFadeout(i, md, FALSE); + } else { + M_StartDelay(i, random(105, 10) + 2 * (5 - Monst->_mint)); + } + } + } + + if(Monst->_mmode == MM_STAND) { + M_StartDelay(i, random(125, 10) + 5); + } +} + +void MAI_Garbud(int i) +{ + int mx, my, md; + MonsterStruct *Monst; + + if((DWORD)i >= MAXMONSTERS) { + app_fatal("MAI_Garbud: Invalid monster %d", i); + } + + Monst = &monster[i]; + if(Monst->_mmode != MM_STAND) { + return; + } + + mx = Monst->_mx; + my = Monst->_my; + md = M_GetDir(i); + + if(Monst->mtalkmsg < TEXT_GARBUD4 && Monst->mtalkmsg > TEXT_GARBUD1 - 1 && !(dFlags[mx][my] & 2) && Monst->_mgoal == 7) { + Monst->mtalkmsg++; + Monst->_mgoal = 6; + } + if(dFlags[mx][my] & 2) { + if(Monst->mtalkmsg == TEXT_GARBUD4 && !effect_is_playing(USFX_GARBUD4) && Monst->_mgoal == 7) { + Monst->_mgoal = 1; + Monst->_msquelch = 255; + Monst->mtalkmsg = 0; + } + } + if(Monst->_mgoal == 1 || Monst->_mgoal == 4) { + MAI_Round(i, TRUE); + } + + monster[i]._mdir = md; + + if(Monst->_mmode == MM_STAND) { + Monst->_mAnimData = Monst->MType->Anims[0].Frames[md]; + } +} + +void MAI_Zhar(int i) +{ + int mx, my, md, dist; + MonsterStruct *Monst; + + if((DWORD)i >= MAXMONSTERS) { + app_fatal("MAI_Zhar: Invalid monster %d", i); + } + + Monst = &monster[i]; + if(Monst->_mmode != MM_STAND) { + return; + } + + mx = Monst->_mx; + my = Monst->_my; + md = M_GetDir(i); + + if(Monst->mtalkmsg == TEXT_ZHAR1 && !(dFlags[mx][my] & 2) && Monst->_mgoal == 7) { + Monst->mtalkmsg++; + Monst->_mgoal = 6; + } + if(dFlags[mx][my] & 2) { + mx = Monst->_mx - Monst->_menemyx; + my = Monst->_my - Monst->_menemyy; + if(abs(mx) > abs(my)) { /// BUGFIX: leftover unused code + dist = abs(mx); + } else { + dist = abs(my); + } + if(Monst->mtalkmsg == TEXT_ZHAR2 && !effect_is_playing(USFX_ZHAR2) && Monst->_mgoal == 7) { + Monst->_mgoal = 1; + Monst->_msquelch = 255; + Monst->mtalkmsg = 0; + } + } + if(Monst->_mgoal == 1 || Monst->_mgoal == 2 || Monst->_mgoal == 4) { + MAI_Counselor(i); + } + + monster[i]._mdir = md; + + if(Monst->_mmode == MM_STAND) { + Monst->_mAnimData = Monst->MType->Anims[0].Frames[md]; + } +} + +void MAI_SnotSpil(int i) +{ + int mx, my, md; + MonsterStruct *Monst; + + if((DWORD)i >= MAXMONSTERS) { + app_fatal("MAI_SnotSpil: Invalid monster %d", i); + } + + Monst = &monster[i]; + if(Monst->_mmode != MM_STAND) { + return; + } + + mx = Monst->_mx; + my = Monst->_my; + md = M_GetDir(i); + + if(Monst->mtalkmsg == TEXT_BANNER10 && !(dFlags[mx][my] & 2) && Monst->_mgoal == 7) { + Monst->mtalkmsg++; + Monst->_mgoal = 6; + } + if(Monst->mtalkmsg == TEXT_BANNER11 && quests[Q_LTBANNER]._qvar1 == 3) { + Monst->mtalkmsg = 0; + Monst->_mgoal = 1; + } + if(dFlags[mx][my] & 2) { + if(Monst->mtalkmsg == TEXT_BANNER12 && !effect_is_playing(USFX_SNOT3) && Monst->_mgoal == 7) { + ObjChangeMap(setpc_x, setpc_y, setpc_x + setpc_w + 1, setpc_y + setpc_h + 1); + quests[Q_LTBANNER]._qvar1 = 3; + RedoPlayerVision(); + Monst->_mgoal = 1; + Monst->_msquelch = 255; + Monst->mtalkmsg = 0; + } + if(quests[Q_LTBANNER]._qvar1 == 3) { + if(Monst->_mgoal == 1 || Monst->_mgoal == 5) { + MAI_Fallen(i); + } + } + } + + monster[i]._mdir = md; + + if(Monst->_mmode == MM_STAND) { + Monst->_mAnimData = Monst->MType->Anims[0].Frames[md]; + } +} + +void MAI_Lazurus(int i) +{ + int mx, my, md; + MonsterStruct *Monst; + + if((DWORD)i >= MAXMONSTERS) { + app_fatal("MAI_Lazurus: Invalid monster %d", i); + } + + Monst = &monster[i]; + if(Monst->_mmode != MM_STAND) { + return; + } + + mx = Monst->_mx; + my = Monst->_my; + md = M_GetDir(i); + + if(dFlags[mx][my] & 2) { + if(gbMaxPlayers == 1) { + if(Monst->mtalkmsg == TEXT_VILE13 && Monst->_mgoal == 6 && plr[myplr].WorldX == 35 && plr[myplr].WorldY == 46) { + PlayInGameMovie("gendata\\fprst3.smk"); + Monst->_mmode = MM_TALK; + quests[Q_BETRAYER]._qvar1 = 5; + } + if(Monst->mtalkmsg == TEXT_VILE13 && !effect_is_playing(USFX_LAZ1) && Monst->_mgoal == 7) { + ObjChangeMapResync(1, 18, 20, 24); + RedoPlayerVision(); + quests[Q_BETRAYER]._qvar1 = 6; + Monst->_mgoal = 1; + Monst->_msquelch = 255; + Monst->mtalkmsg = 0; + } + } + if(gbMaxPlayers != 1) { + if(Monst->mtalkmsg == TEXT_VILE13 && Monst->_mgoal == 6 && quests[Q_BETRAYER]._qvar1 <= 3) { + Monst->_mmode = MM_TALK; + } + } + } + if(Monst->_mgoal == 1 || Monst->_mgoal == 2 || Monst->_mgoal == 4) { + Monst->mtalkmsg = 0; + MAI_Counselor(i); + } + + monster[i]._mdir = md; + + if(Monst->_mmode == MM_STAND || Monst->_mmode == MM_TALK) { + Monst->_mAnimData = Monst->MType->Anims[0].Frames[md]; + } +} + +void MAI_Lazhelp(int i) +{ + int mx, my; + volatile int md; /* fix */ + MonsterStruct *Monst; + + if((DWORD)i >= MAXMONSTERS) { + app_fatal("MAI_Lazhelp: Invalid monster %d", i); + } + + Monst = &monster[i]; + if(Monst->_mmode != MM_STAND) { + return; + } + + mx = Monst->_mx; + my = Monst->_my; + md = M_GetDir(i); + + if(dFlags[mx][my] & 2) { + if(gbMaxPlayers == 1) { + if(quests[Q_BETRAYER]._qvar1 <= 5) { + Monst->_mgoal = 6; + } else { + Monst->_mgoal = 1; + Monst->mtalkmsg = 0; + } + } else { + Monst->_mgoal = 1; + } + } + if(Monst->_mgoal == 1) { + MAI_Succ(i); + } + + monster[i]._mdir = md; + + if(Monst->_mmode == MM_STAND) { + Monst->_mAnimData = Monst->MType->Anims[0].Frames[md]; + } +} + +void MAI_Lachdanan(int i) +{ + int mx, my, md; + MonsterStruct *Monst; + + if((DWORD)i >= MAXMONSTERS) { + app_fatal("MAI_Lachdanan: Invalid monster %d", i); + } + + Monst = &monster[i]; + if(Monst->_mmode != MM_STAND) { + return; + } + + mx = Monst->_mx; + my = Monst->_my; + md = M_GetDir(i); + + if(Monst->mtalkmsg == TEXT_VEIL9 && !(dFlags[mx][my] & 2) && Monst->_mgoal == 7) { + Monst->mtalkmsg++; + Monst->_mgoal = 6; + } + if(dFlags[mx][my] & 2) { + if(Monst->mtalkmsg == TEXT_VEIL11 && !effect_is_playing(USFX_LACH3) && Monst->_mgoal == 7) { + Monst->mtalkmsg = 0; + quests[Q_VEIL]._qactive = 3; + M_StartKill(i, -1); + } + } + + monster[i]._mdir = md; + + if(Monst->_mmode == MM_STAND) { + Monst->_mAnimData = Monst->MType->Anims[0].Frames[md]; + } +} + +void MAI_Warlord(int i) +{ + int mx, my, md; + MonsterStruct *Monst; + + if((DWORD)i >= MAXMONSTERS) { + app_fatal("MAI_Warlord: Invalid monster %d", i); + } + + Monst = &monster[i]; + if(Monst->_mmode != MM_STAND) { + return; + } + + mx = Monst->_mx; + my = Monst->_my; + md = M_GetDir(i); + + if(dFlags[mx][my] & 2) { + if(Monst->mtalkmsg == TEXT_WARLRD9 && Monst->_mgoal == 6) { + Monst->_mmode = MM_TALK; + } + if(Monst->mtalkmsg == TEXT_WARLRD9 && !effect_is_playing(USFX_WARLRD1) && Monst->_mgoal == 7) { + Monst->_mgoal = 1; + Monst->_msquelch = 255; + Monst->mtalkmsg = 0; + } + } + if(Monst->_mgoal == 1) { + MAI_SkelSd(i); + } + + monster[i]._mdir = md; + + if(Monst->_mmode == MM_STAND || Monst->_mmode == MM_TALK) { + Monst->_mAnimData = Monst->MType->Anims[0].Frames[md]; + } +} + +void DeleteMonsterList() +{ + int i, mi; + + for(i = 0; i < 4; i++) { + if(monster[i]._mDelFlag) { + monster[i]._mx = 1; + monster[i]._my = 0; + monster[i]._mfutx = 0; + monster[i]._mfuty = 0; + monster[i]._moldx = 0; + monster[i]._moldy = 0; + monster[i]._mDelFlag = 0; + } + } + + i = 4; + /// ASSERT: assert((DWORD)nummonsters <= MAXMONSTERS); + while(i < nummonsters) { + mi = monstactive[i]; + if(monster[mi]._mDelFlag) { + DeleteMonster(i); + i = 0; + } else { + i++; + } + } +} + +void ProcessMonsters() +{ + int i, mi, mx, my; + BOOL raflag; + MonsterStruct *Monst; + + DeleteMonsterList(); + + /// ASSERT: assert((DWORD)nummonsters <= MAXMONSTERS); + for(i = 0; i < nummonsters; i++) { + mi = monstactive[i]; + Monst = &monster[mi]; + raflag = FALSE; + if(gbMaxPlayers > 1) { + SetRndSeed(Monst->_mAISeed); + Monst->_mAISeed = GetRndSeed(); + } + if(!(monster[mi]._mFlags & 8) && Monst->_mhitpoints < Monst->_mmaxhp && Monst->_mhitpoints >> 6 > 0) { + if(Monst->mLevel <= 1) { + Monst->_mhitpoints += Monst->mLevel; + } else { + Monst->_mhitpoints += Monst->mLevel >> 1; + } + } + mx = Monst->_mx; + my = Monst->_my; + if(dFlags[mx][my] & 2 && Monst->_msquelch == 0 && Monst->MType->mtype == MT_CLEAVER) { + PlaySFX(USFX_CLEAVER); + } + if(Monst->_mFlags & 0x10) { + if((DWORD)Monst->_menemy >= MAXMONSTERS) { + app_fatal("Illegal enemy monster %d for monster \"%s\"", Monst->_menemy, Monst->mName); + } + Monst->_lastx = monster[Monst->_menemy]._mfutx; + Monst->_menemyx = Monst->_lastx; + Monst->_lasty = monster[Monst->_menemy]._mfuty; + Monst->_menemyy = Monst->_lasty; + } else { + if((DWORD)Monst->_menemy >= MAX_PLRS) { + app_fatal("Illegal enemy player %d for monster \"%s\"", Monst->_menemy, Monst->mName); + } + Monst->_menemyx = plr[Monst->_menemy]._px; + Monst->_menemyy = plr[Monst->_menemy]._py; + if(dFlags[mx][my] & 2) { + Monst->_msquelch = 255; + Monst->_lastx = plr[Monst->_menemy]._px; + Monst->_lasty = plr[Monst->_menemy]._py; + } else if(Monst->_msquelch != 0 && Monst->_mAi != MT_DIABLO) { /// BUGFIX: change '_mAi' to 'MType->mtype' + Monst->_msquelch--; + } + } + do { + if(!(Monst->_mFlags & 0x100)) { + AiProc[Monst->_mAi](mi); + } else if(!MAI_Path(mi)) { + AiProc[Monst->_mAi](mi); + } + switch(Monst->_mmode) { + case MM_STAND: + raflag = M_DoStand(mi); + break; + case MM_WALK: + raflag = M_DoWalk(mi); + break; + case MM_WALK2: + raflag = M_DoWalk2(mi); + break; + case MM_WALK3: + raflag = M_DoWalk3(mi); + break; + case MM_ATTACK: + raflag = M_DoAttack(mi); + break; + case MM_RATTACK: + raflag = M_DoRAttack(mi); + break; + case MM_GOTHIT: + raflag = M_DoGotHit(mi); + break; + case MM_DEATH: + raflag = M_DoDeath(mi); + break; + case MM_SATTACK: + raflag = M_DoSAttack(mi); + break; + case MM_FADEIN: + raflag = M_DoFadein(mi); + break; + case MM_FADEOUT: + raflag = M_DoFadeout(mi); + break; + case MM_SPSTAND: + raflag = M_DoSpStand(mi); + break; + case MM_RSPATTACK: + raflag = M_DoRSpAttack(mi); + break; + case MM_DELAY: + raflag = M_DoDelay(mi); + break; + case MM_CHARGE: + raflag = FALSE; + break; + case MM_STONE: + raflag = M_DoStone(mi); + break; + case MM_HEAL: + raflag = M_DoHeal(mi); + break; + case MM_TALK: + raflag = M_DoTalk(mi); + break; + } + if(raflag) { + GroupUnity(mi); + } + } while(raflag); + if(Monst->_mmode != MM_STONE) { + Monst->_mAnimCnt++; + if(!(Monst->_mFlags & 4) && Monst->_mAnimCnt >= Monst->_mAnimDelay) { + Monst->_mAnimCnt = 0; + if(Monst->_mFlags & 2) { + Monst->_mAnimFrame--; + if(Monst->_mAnimFrame == 0) { + Monst->_mAnimFrame = Monst->_mAnimLen; + } + } else { + Monst->_mAnimFrame++; + if(Monst->_mAnimFrame > Monst->_mAnimLen) { + Monst->_mAnimFrame = 1; + } + } + } + } + } + + DeleteMonsterList(); +} + +void FreeMonsters() +{ + int i, anim, mtype; + + /// ASSERT: assert((DWORD)nummtypes <= MAX_LVLMTYPES); + for(i = 0; i < nummtypes; i++) { + mtype = Monsters[i].mtype; + for(anim = 0; anim < 6; anim++) { + if(animletter[anim] != 's' || monsterdata[mtype].has_special) { + MemFreeDbg(Monsters[i].Anims[anim].CMem); + } + } + } + + FreeMissiles2(); +} + +BOOL DirOK(int i, int mdir) +{ + long fx, fy; + int tmp, mcount, x, y; + + if((DWORD)i >= MAXMONSTERS) { + app_fatal("DirOK: Invalid monster %d", i); + } + + fx = monster[i]._mx + offset_x[mdir]; + fy = monster[i]._my + offset_y[mdir]; + if(fy < 0 || fy >= MAXDUNY || fx < 0 || fx >= MAXDUNX) { + return FALSE; + } + if(!PosOkMonst(i, fx, fy)) { + return FALSE; + } + + if(mdir == 6) { + if(SolidLoc(fx, fy + 1)) { + return FALSE; + } + if(dFlags[fx][fy + 1] & 0x10) { + return FALSE; + } + } else if(mdir == 2) { + if(SolidLoc(fx + 1, fy)) { + return FALSE; + } + if(dFlags[fx + 1][fy] & 0x10) { + return FALSE; + } + } else if(mdir == 4) { + if(SolidLoc(fx + 1, fy)) { + return FALSE; + } + if(SolidLoc(fx, fy + 1)) { + return FALSE; + } + } else if(mdir == 0) { + if(SolidLoc(fx - 1, fy)) { + return FALSE; + } + if(SolidLoc(fx, fy - 1)) { + return FALSE; + } + } + + if(monster[i].leaderflag == 1) { + return abs(fx - monster[monster[i].leader]._mfutx) < 4 + && abs(fy - monster[monster[i].leader]._mfuty) < 4; + } + if(monster[i]._uniqtype == 0 || !(UniqMonst[monster[i]._uniqtype - 1].mUnqAttr & 2)) { + return TRUE; + } + + mcount = 0; + for(x = fx - 3; x <= fx + 3; x++) { + for(y = fy - 3; y <= fy + 3; y++) { + if(y >= 0 && y < MAXDUNY && x >= 0 && x < MAXDUNX) { + tmp = dMonster[x][y]; + if(tmp < 0) { + tmp = -tmp; + } + if(tmp != 0) { + tmp = tmp - 1; + } + /// ASSERT: assert(tmp >= 0); + if(monster[tmp].leaderflag == 1 + && monster[tmp].leader == i + && monster[tmp]._mfutx == x + && monster[tmp]._mfuty == y) { + mcount++; + } + } + } + } + + return mcount == monster[i].packsize; +} + +BOOL PosOkMissile(int x, int y) +{ + return !nMissileTable[dPiece[x][y]] && !(dFlags[x][y] & 0x10); +} + +BOOL CheckNoSolid(int x, int y) +{ + return !nSolidTable[dPiece[x][y]]; +} + +BOOL LineClearF(BOOL (*Clear)(int, int), int x1, int y1, int x2, int y2) +{ + int dx, dy, d, dincH, dincD, xincD, yincD, xorg, yorg, tmp; + BOOL done; + + done = FALSE; + xorg = x1; + yorg = y1; + dx = x2 - x1; + dy = y2 - y1; + + if(abs(dx) > abs(dy)) { + if(dx < 0) { + tmp = x1; + x1 = x2; + x2 = tmp; + tmp = y1; + y1 = y2; + y2 = tmp; + dx = -dx; + dy = -dy; + } + if(dy > 0) { + d = 2 * dy - dx; + dincH = 2 * dy; + dincD = 2 * (dy - dx); + yincD = 1; + } else { + d = 2 * dy + dx; + dincH = 2 * dy; + dincD = 2 * (dx + dy); + yincD = -1; + } + while(!done && (x1 != x2 || y1 != y2)) { + if((d <= 0) ^ (yincD < 0)) { + d += dincH; + } else { + d += dincD; + y1 += yincD; + } + x1++; + done = (x1 != xorg || y1 != yorg) && !Clear(x1, y1); + } + } else { + if(dy < 0) { + tmp = y1; + y1 = y2; + y2 = tmp; + tmp = x1; + x1 = x2; + x2 = tmp; + dy = -dy; + dx = -dx; + } + if(dx > 0) { + d = 2 * dx - dy; + dincH = 2 * dx; + dincD = 2 * (dx - dy); + xincD = 1; + } else { + d = 2 * dx + dy; + dincH = 2 * dx; + dincD = 2 * (dx + dy); + xincD = -1; + } + while(!done && (y1 != y2 || x1 != x2)) { + if((d <= 0) ^ (xincD < 0)) { + d += dincH; + } else { + d += dincD; + x1 += xincD; + } + y1++; + done = (y1 != yorg || x1 != xorg) && !Clear(x1, y1); + } + } + + return x1 == x2 && y1 == y2; +} + +BOOL LineClear(int x1, int y1, int x2, int y2) +{ + return LineClearF(PosOkMissile, x1, y1, x2, y2); +} + +BOOL LineClearF1(BOOL (*Clear)(int, int, int), int monst, int x1, int y1, int x2, int y2) +{ + int dx, dy, d, dincH, dincD, xincD, yincD, xorg, yorg, tmp; + BOOL done; + + done = FALSE; + xorg = x1; + yorg = y1; + dx = x2 - x1; + dy = y2 - y1; + + if(abs(dx) > abs(dy)) { + if(dx < 0) { + tmp = x1; + x1 = x2; + x2 = tmp; + tmp = y1; + y1 = y2; + y2 = tmp; + dx = -dx; + dy = -dy; + } + if(dy > 0) { + d = 2 * dy - dx; + dincH = 2 * dy; + dincD = 2 * (dy - dx); + yincD = 1; + } else { + d = 2 * dy + dx; + dincH = 2 * dy; + dincD = 2 * (dx + dy); + yincD = -1; + } + while(!done && (x1 != x2 || y1 != y2)) { + if((d <= 0) ^ (yincD < 0)) { + d += dincH; + } else { + d += dincD; + y1 += yincD; + } + x1++; + done = (x1 != xorg || y1 != yorg) && !Clear(monst, x1, y1); + } + } else { + if(dy < 0) { + tmp = y1; + y1 = y2; + y2 = tmp; + tmp = x1; + x1 = x2; + x2 = tmp; + dy = -dy; + dx = -dx; + } + if(dx > 0) { + d = 2 * dx - dy; + dincH = 2 * dx; + dincD = 2 * (dx - dy); + xincD = 1; + } else { + d = 2 * dx + dy; + dincH = 2 * dx; + dincD = 2 * (dx + dy); + xincD = -1; + } + while(!done && (y1 != y2 || x1 != x2)) { + if((d <= 0) ^ (xincD < 0)) { + d += dincH; + } else { + d += dincD; + x1 += xincD; + } + y1++; + done = (y1 != yorg || x1 != xorg) && !Clear(monst, x1, y1); + } + } + + return x1 == x2 && y1 == y2; +} + +void SyncMonsterAnim(int m) +{ + int md; + + if((DWORD)m >= MAXMONSTERS) { + app_fatal("SyncMonsterAnim: Invalid monster %d", m); + } + + /// ASSERT: assert((DWORD)monster[m]._mMTidx < MAX_LVLMTYPES); + monster[m].MType = &Monsters[monster[m]._mMTidx]; + monster[m].MData = Monsters[monster[m]._mMTidx].MData; + + if(monster[m]._uniqtype != 0) { + monster[m].mName = UniqMonst[monster[m]._uniqtype - 1].mName; + } else { + monster[m].mName = monster[m].MData->mName; + } + + md = monster[m]._mdir; + + switch(monster[m]._mmode) { + case MM_STAND: + monster[m]._mAnimData = monster[m].MType->Anims[0].Frames[md]; + break; + case MM_WALK: + monster[m]._mAnimData = monster[m].MType->Anims[1].Frames[md]; + break; + case MM_WALK2: + monster[m]._mAnimData = monster[m].MType->Anims[1].Frames[md]; + break; + case MM_WALK3: + monster[m]._mAnimData = monster[m].MType->Anims[1].Frames[md]; + break; + case MM_ATTACK: + monster[m]._mAnimData = monster[m].MType->Anims[2].Frames[md]; + break; + case MM_RATTACK: + monster[m]._mAnimData = monster[m].MType->Anims[2].Frames[md]; + break; + case MM_GOTHIT: + monster[m]._mAnimData = monster[m].MType->Anims[3].Frames[md]; + break; + case MM_DEATH: + monster[m]._mAnimData = monster[m].MType->Anims[4].Frames[md]; + break; + case MM_SATTACK: + monster[m]._mAnimData = monster[m].MType->Anims[5].Frames[md]; + break; + case MM_FADEIN: + monster[m]._mAnimData = monster[m].MType->Anims[5].Frames[md]; + break; + case MM_FADEOUT: + monster[m]._mAnimData = monster[m].MType->Anims[5].Frames[md]; + break; + case MM_SPSTAND: + monster[m]._mAnimData = monster[m].MType->Anims[5].Frames[md]; + break; + case MM_RSPATTACK: + monster[m]._mAnimData = monster[m].MType->Anims[5].Frames[md]; + break; + case MM_DELAY: + monster[m]._mAnimData = monster[m].MType->Anims[0].Frames[md]; + break; + case MM_HEAL: + monster[m]._mAnimData = monster[m].MType->Anims[5].Frames[md]; + break; + case MM_TALK: + monster[m]._mAnimData = monster[m].MType->Anims[0].Frames[md]; + break; + case MM_STONE: + monster[m]._mAnimData = monster[m].MType->Anims[0].Frames[md]; + monster[m]._mAnimFrame = 1; + monster[m]._mAnimLen = monster[m].MType->Anims[0].Rate; + break; + case MM_CHARGE: + monster[m]._mAnimData = monster[m].MType->Anims[2].Frames[md]; + monster[m]._mAnimFrame = 1; + monster[m]._mAnimLen = monster[m].MType->Anims[2].Rate; + break; + default: + monster[m]._mAnimData = monster[m].MType->Anims[0].Frames[md]; + monster[m]._mAnimFrame = 1; + monster[m]._mAnimLen = monster[m].MType->Anims[0].Rate; + break; + } +} + +void M_FallenFear(int x, int y) +{ + int i, mi, rundist, aitype; + + /// ASSERT: assert((DWORD)nummonsters <= MAXMONSTERS); + for(i = 0; i < nummonsters; i++) { + mi = monstactive[i]; + rundist = 0; + switch(monster[mi].MType->mtype) { + case MT_RFALLSP: + case MT_RFALLSD: + rundist = 7; + break; + case MT_DFALLSP: + case MT_DFALLSD: + rundist = 5; + break; + case MT_YFALLSP: + case MT_YFALLSD: + rundist = 3; + break; + case MT_BFALLSP: + case MT_BFALLSD: + rundist = 2; + break; + } + aitype = monster[mi]._mAi; + if(aitype != AI_FALLEN || rundist == 0) { + continue; + } + if(abs(x - monster[mi]._mx) < 5 && abs(y - monster[mi]._my) < 5 && monster[mi]._mhitpoints >> 6 > 0) { + monster[mi]._mgoal = 2; + monster[mi]._mgoalvar1 = rundist; + monster[mi]._mdir = GetDirection(x, y, monster[i]._mx, monster[i]._my); + } + } +} + +void PrintMonstHistory(int mt) +{ + int res, minhp, maxhp; + + sprintf(tempstr, "Total kills : %i", monstkills[mt]); + AddPanelString(tempstr, 1); + + if(monstkills[mt] >= 30) { + minhp = monsterdata[mt].mMinHP; + maxhp = monsterdata[mt].mMaxHP; + if(gbMaxPlayers == 1) { + minhp >>= 1; + maxhp >>= 1; + } + if(minhp < 1) { + minhp = 1; + } + if(maxhp < 1) { + maxhp = 1; + } + if(gnDifficulty == DIFF_NIGHTMARE) { + minhp = 3 * minhp + 1; + maxhp = 3 * maxhp + 1; + } + if(gnDifficulty == DIFF_HELL) { + minhp = 4 * minhp + 3; + maxhp = 4 * maxhp + 3; + } + sprintf(tempstr, "Hit Points : %i-%i", minhp, maxhp); + AddPanelString(tempstr, 1); + } + if(monstkills[mt] >= 15) { + if(gnDifficulty != DIFF_HELL) { + res = monsterdata[mt].mMagicRes; + } else { + res = monsterdata[mt].mMagicRes2; + } + res &= 0x3F; + if(res == 0) { + strcpy(tempstr, "No magic resistance"); + AddPanelString(tempstr, 1); + } else { + if(res & 7) { + strcpy(tempstr, "Resists : "); + if(res & 1) { + strcat(tempstr, "Magic "); + } + if(res & 2) { + strcat(tempstr, "Fire "); + } + if(res & 4) { + strcat(tempstr, "Lightning "); + } + tempstr[strlen(tempstr) - 1] = '\0'; + AddPanelString(tempstr, 1); + } + if(res & 0x38) { + strcpy(tempstr, "Immune : "); + if(res & 8) { + strcat(tempstr, "Magic "); + } + if(res & 0x10) { + strcat(tempstr, "Fire "); + } + if(res & 0x20) { + strcat(tempstr, "Lightning "); + } + tempstr[strlen(tempstr) - 1] = '\0'; + AddPanelString(tempstr, 1); + } + } + } + + pinfoflag = 1; +} + +void PrintUniqueHistory() +{ + int res; + + res = monster[pcursmonst].mMagicRes; + res &= 0x3F; + + if(res == 0) { + strcpy(tempstr, "No resistances"); + AddPanelString(tempstr, 1); + strcpy(tempstr, "No Immunities"); + AddPanelString(tempstr, 1); + } else { + if(res & 7) { + strcpy(tempstr, "Some Magic Resistances"); + } else { + strcpy(tempstr, "No resistances"); + } + AddPanelString(tempstr, 1); + if(res & 0x38) { + strcpy(tempstr, "Some Magic Immunities"); + } else { + strcpy(tempstr, "No Immunities"); + } + AddPanelString(tempstr, 1); + } + + pinfoflag = 1; +} + +void MissToMonst(int i, int x, int y) +{ + int oldx, oldy, newx, newy, m, pnum; + MissileStruct *Miss; + MonsterStruct *Monst; + + if((DWORD)i >= MAXMISSILES) { + app_fatal("MissToMonst: Invalid missile %d", i); + } + + Miss = &missile[i]; + m = Miss->_misource; + if((DWORD)m >= MAXMONSTERS) { + app_fatal("MissToMonst: Invalid monster %d", m); + } + + Monst = &monster[m]; + /// ASSERT: assert(Monst->_mmode == MM_MISSILE); + oldx = Miss->_mix; + oldy = Miss->_miy; + dMonster[x][y] = m + 1; + Monst->_mdir = Miss->_mimfnum; + Monst->_mx = x; + Monst->_my = y; + M_StartStand(m, Monst->_mdir); + + if(Monst->MType->mtype >= MT_INCIN && Monst->MType->mtype <= MT_HELLBURN) { + M_StartFadein(m, Monst->_mdir, FALSE); + } else if(!(Monst->_mFlags & 0x10)) { + M_StartHit(m, -1, 0); + } else { + M2MStartHit(m, -1, 0); + } + + if(!(Monst->_mFlags & 0x10)) { + pnum = dPlayer[oldx][oldy] - 1; + if(dPlayer[oldx][oldy] > 0) { + if(Monst->MType->mtype == MT_GLOOM) { + return; + } + if(Monst->MType->mtype >= MT_INCIN && Monst->MType->mtype <= MT_HELLBURN) { + return; + } + M_TryH2HHit(m, dPlayer[oldx][oldy] - 1, 500, Monst->mMinDamage2, Monst->mMaxDamage2); + if(pnum != dPlayer[oldx][oldy] - 1) { + return; + } + if(Monst->MType->mtype >= MT_NSNAKE && Monst->MType->mtype <= MT_GSNAKE) { + return; + } + if(plr[pnum]._pmode != PM_GOTHIT && plr[pnum]._pmode != PM_DEATH) { + StartPlrHit(pnum, 0, TRUE); + } + newx = oldx + offset_x[Monst->_mdir]; + newy = oldy + offset_y[Monst->_mdir]; + if(PosOkPlayer(pnum, newx, newy)) { + plr[pnum].WorldX = newx; + plr[pnum].WorldY = newy; + FixPlayerLocation(pnum, plr[pnum]._pdir); + FixPlrWalkTags(pnum); + dPlayer[newx][newy] = pnum + 1; + SetPlayerOld(pnum); + } + } + } else { + if(dMonster[oldx][oldy] > 0) { + if(Monst->MType->mtype == MT_GLOOM) { + return; + } + if(Monst->MType->mtype >= MT_INCIN && Monst->MType->mtype <= MT_HELLBURN) { + return; + } + M_TryM2MHit(m, dMonster[oldx][oldy] - 1, 500, Monst->mMinDamage2, Monst->mMaxDamage2); + if(Monst->MType->mtype >= MT_NSNAKE && Monst->MType->mtype <= MT_GSNAKE) { + return; + } + newx = oldx + offset_x[Monst->_mdir]; + newy = oldy + offset_y[Monst->_mdir]; + if(PosOkMonst(dMonster[oldx][oldy] - 1, newx, newy)) { + dMonster[newx][newy] = dMonster[oldx][oldy]; + m = dMonster[newx][newy]; + dMonster[oldx][oldy] = 0; + m--; + monster[m]._mx = newx; + monster[m]._mfutx = monster[m]._mx; + monster[m]._my = newy; + monster[m]._mfuty = monster[m]._my; + } + } + } +} + +BOOL PosOkMonst(int i, int x, int y) +{ + int oi, mi; + BOOL ret, fire; + + ret = TRUE; + fire = FALSE; + + ret = !SolidLoc(x, y) && dPlayer[x][y] == 0 && dMonster[x][y] == 0; + if(ret && dObject[x][y] != 0) { + oi = dObject[x][y] > 0 ? dObject[x][y] - 1 : -(dObject[x][y] + 1); + if(object[oi]._oSolidFlag) { + ret = FALSE; + } + } + if(ret && dMissile[x][y] != 0 && i >= 0) { + mi = dMissile[x][y]; + if(mi > 0) { + if(missile[mi]._mitype == MIS_FIREWALL) { + fire = TRUE; + } else { + for(mi = 0; mi < nummissiles; mi++) { + if(missile[missileactive[mi]]._mitype == MIS_FIREWALL) { + fire = TRUE; + } + } + } + } + if(fire && (!(monster[i].mMagicRes & 0x10) || monster[i].MType->mtype == MT_DIABLO)) { + ret = FALSE; + } + } + + return ret; +} + +BOOL PosOkMonst2(int i, int x, int y) +{ + int oi, mi; + BOOL ret, fire; + + ret = TRUE; + fire = FALSE; + + ret = !SolidLoc(x, y); + if(ret && dObject[x][y] != 0) { + oi = dObject[x][y] > 0 ? dObject[x][y] - 1 : -(dObject[x][y] + 1); + if(object[oi]._oSolidFlag) { + ret = FALSE; + } + } + if(ret && dMissile[x][y] != 0 && i >= 0) { + mi = dMissile[x][y]; + if(mi > 0) { + if(missile[mi]._mitype == MIS_FIREWALL) { + fire = TRUE; + } else { + for(mi = 0; mi < nummissiles; mi++) { + if(missile[missileactive[mi]]._mitype == MIS_FIREWALL) { + fire = TRUE; + } + } + } + } + if(fire && (!(monster[i].mMagicRes & 0x10) || monster[i].MType->mtype == MT_DIABLO)) { + ret = FALSE; + } + } + + return ret; +} + +BOOL PosOkMonst3(int i, int x, int y) +{ + int oi, objtype, mi; + BOOL ret, fire, isdoor; + + ret = TRUE; + fire = FALSE; + isdoor = FALSE; + + if(ret && dObject[x][y] != 0) { + oi = dObject[x][y] > 0 ? dObject[x][y] - 1 : -(dObject[x][y] + 1); + objtype = object[oi]._otype; + isdoor = objtype == OBJ_L1LDOOR || objtype == OBJ_L1RDOOR + || objtype == OBJ_L2LDOOR || objtype == OBJ_L2RDOOR + || objtype == OBJ_L3LDOOR || objtype == OBJ_L3RDOOR; + if(object[oi]._oSolidFlag && !isdoor) { + ret = FALSE; + } + } + if(ret) { + ret = (!SolidLoc(x, y) || isdoor) && dPlayer[x][y] == 0 && dMonster[x][y] == 0; + } + if(ret && dMissile[x][y] != 0 && i >= 0) { + mi = dMissile[x][y]; + if(mi > 0) { + if(missile[mi]._mitype == MIS_FIREWALL) { + fire = TRUE; + } else { + for(mi = 0; mi < nummissiles; mi++) { + if(missile[missileactive[mi]]._mitype == MIS_FIREWALL) { + fire = TRUE; + } + } + } + } + if(fire && (!(monster[i].mMagicRes & 0x10) || monster[i].MType->mtype == MT_DIABLO)) { + ret = FALSE; + } + } + + return ret; +} + +BOOL IsSkel(int mt) +{ + return mt >= MT_WSKELAX && mt <= MT_XSKELAX + || mt >= MT_WSKELBW && mt <= MT_XSKELBW + || mt >= MT_WSKELSD && mt <= MT_XSKELSD; +} + +BOOL IsGoat(int mt) +{ + return mt >= MT_NGOATMC && mt <= MT_GGOATMC + || mt >= MT_NGOATBW && mt <= MT_GGOATBW; +} + +int M_SpawnSkel(int x, int y, int dir) +{ + int i, j, skeltypes, skel; + + skeltypes = 0; + + /// ASSERT: assert((DWORD)nummtypes <= MAX_LVLMTYPES); + for(i = 0; i < nummtypes; i++) { + if(IsSkel(Monsters[i].mtype)) { + skeltypes++; + } + } + + if(skeltypes != 0) { + j = random(136, skeltypes); + skeltypes = 0; + for(i = 0; i < nummtypes && skeltypes <= j; i++) { + if(IsSkel(Monsters[i].mtype)) { + skeltypes++; + } + } + skel = AddMonster(x, y, dir, i - 1, TRUE); + if(skel != -1) { + M_StartSpStand(skel, dir); + } + return skel; + } else { + return -1; + } +} + +void ActivateSpawn(int i, int x, int y, int dir) +{ + dMonster[x][y] = i + 1; + monster[i]._mx = x; + monster[i]._my = y; + monster[i]._mfutx = x; + monster[i]._mfuty = y; + monster[i]._moldx = x; + monster[i]._moldy = y; + M_StartSpStand(i, dir); +} + +BOOL SpawnSkeleton(int ii, int x, int y) +{ + int monstok[3][3]; + int i, j, xx, yy, rs; + BOOL savail; + + if(ii == -1) { + return FALSE; + } + + if(PosOkMonst(-1, x, y)) { + ActivateSpawn(ii, x, y, GetDirection(x, y, x, y)); + return TRUE; + } + + savail = FALSE; + j = 0; + for(yy = y - 1; yy <= y + 1; yy++) { + i = 0; + for(xx = x - 1; xx <= x + 1; xx++) { + monstok[i][j] = PosOkMonst(-1, xx, yy); + savail |= monstok[i][j]; + i++; + } + j++; + } + + if(!savail) { + return FALSE; + } + + rs = random(137, 15) + 1; + i = 0; + j = 0; + while(rs > 0) { + if(monstok[i][j]) { + rs--; + } + if(rs > 0) { + i++; + if(i == 3) { + i = 0; + j++; + if(j == 3) { + j = 0; + } + } + } + } + + i += x - 1; + j += y - 1; + ActivateSpawn(ii, i, j, GetDirection(i, j, x, y)); + return TRUE; +} + +int PreSpawnSkeleton() +{ + int i, j, skeltypes, skel; + + skeltypes = 0; + + /// ASSERT: assert((DWORD)nummtypes <= MAX_LVLMTYPES); + for(i = 0; i < nummtypes; i++) { + if(IsSkel(Monsters[i].mtype)) { + skeltypes++; + } + } + + if(skeltypes != 0) { + j = random(136, skeltypes); + skeltypes = 0; + for(i = 0; i < nummtypes && skeltypes <= j; i++) { + if(IsSkel(Monsters[i].mtype)) { + skeltypes++; + } + } + skel = AddMonster(0, 0, 0, i - 1, FALSE); + if(skel != -1) { + M_StartStand(skel, 0); + } + return skel; + } else { + return -1; + } +} + +void TalktoMonster(int i) +{ + int pnum, itm; + MonsterStruct *Monst; + + if((DWORD)i >= MAXMONSTERS) { + app_fatal("TalktoMonster: Invalid monster %d", i); + } + + Monst = &monster[i]; + pnum = Monst->_menemy; + Monst->_mmode = MM_TALK; + + if(Monst->_mAi == AI_SNOTSPIL || Monst->_mAi == AI_LACHDAN) { + if(QuestStatus(Q_LTBANNER) && quests[Q_LTBANNER]._qvar1 == 2 && PlrHasItem(pnum, IDI_BANNER, itm)) { + RemoveInvItem(pnum, itm); + quests[Q_LTBANNER]._qactive = 3; + Monst->mtalkmsg = TEXT_BANNER12; + Monst->_mgoal = 6; + } + if(QuestStatus(Q_VEIL) && Monst->mtalkmsg >= TEXT_VEIL9 && PlrHasItem(pnum, IDI_GLDNELIX, itm)) { + RemoveInvItem(pnum, itm); + Monst->mtalkmsg = TEXT_VEIL11; + Monst->_mgoal = 6; + } + } +} + +void SpawnGolum(int i, int x, int y, int mi) +{ + if((DWORD)i >= MAXMONSTERS) { + app_fatal("SpawnGolum: Invalid monster %d", i); + } + + dMonster[x][y] = i + 1; + monster[i]._mx = x; + monster[i]._my = y; + monster[i]._mfutx = x; + monster[i]._mfuty = y; + monster[i]._moldx = x; + monster[i]._moldy = y; + monster[i]._pathcount = 0; + monster[i]._mmaxhp = 2 * (320 * missile[mi]._mispllvl + plr[i]._pMaxMana / 3); + monster[i]._mhitpoints = monster[i]._mmaxhp; + monster[i].mArmorClass = 25; + monster[i].mHit = 5 * (missile[mi]._mispllvl + 8) + 2 * plr[i]._pLevel; + monster[i].mMinDamage = 2 * (missile[mi]._mispllvl + 4); + monster[i].mMaxDamage = 2 * (missile[mi]._mispllvl + 8); + monster[i]._mFlags |= 0x20; + + M_StartSpStand(i, 0); + M_Enemy(i); + + if(i == myplr) { + NetSendCmdGolem(monster[i]._mx, monster[i]._my, monster[i]._mdir, monster[i]._menemy, monster[i]._mhitpoints, currlevel); + } +} + +BOOL CanTalkToMonst(int m) +{ + if((DWORD)m >= MAXMONSTERS) { + app_fatal("CanTalkToMonst: Invalid monster %d", m); + } + + if(monster[m]._mgoal == 6) { + return TRUE; + } + if(monster[m]._mgoal == 7) { + return TRUE; + } + + return FALSE; +} + +BOOL CheckMonsterHit(int m, BOOL &ret) +{ + if((DWORD)m >= MAXMONSTERS) { + app_fatal("CheckMonsterHit: Invalid monster %d", m); + } + + if(monster[m]._mAi == AI_GARG && monster[m]._mFlags & 4) { + monster[m]._mFlags &= ~4; + monster[m]._mmode = MM_SATTACK; + ret = TRUE; + return TRUE; + } + if(monster[m].MType->mtype >= MT_COUNSLR && monster[m].MType->mtype <= MT_ADVOCATE && monster[m]._mgoal != 1) { + ret = FALSE; + return TRUE; + } + + return FALSE; +} + +int encode_enemy(int m) +{ + if(!(monster[m]._mFlags & 0x10)) { + return monster[m]._menemy; + } else { + return monster[m]._menemy + 4; + } +} + +void decode_enemy(int m, int enemy) +{ + if(enemy < 4) { + monster[m]._mFlags &= ~0x10; + monster[m]._menemy = enemy; + monster[m]._menemyx = plr[enemy]._px; + monster[m]._menemyy = plr[enemy]._py; + } else { + enemy -= 4; + monster[m]._mFlags |= 0x10; + monster[m]._menemy = enemy; + monster[m]._menemyx = monster[enemy]._mfutx; + monster[m]._menemyy = monster[enemy]._mfuty; + } +} diff --git a/2020_03_31/Source/monster.h b/2020_03_31/Source/monster.h new file mode 100644 index 00000000..1cfe56de --- /dev/null +++ b/2020_03_31/Source/monster.h @@ -0,0 +1,184 @@ +//HEADER_GOES_HERE +#ifndef __MONSTER_H__ +#define __MONSTER_H__ + +extern int MissileFileFlag; // weak +extern int monstkills[MAXMONSTERS]; +extern int monstactive[MAXMONSTERS]; +extern int nummonsters; +extern BOOLEAN sgbSaveSoundOn; // weak +extern MonsterStruct monster[MAXMONSTERS]; +extern int totalmonsters; // weak +extern CMonster Monsters[16]; +extern BYTE GraphicTable[NUMLEVELS][MAX_LVLMTYPES]; /* unused */ +// int END_Monsters_17; // weak +extern int monstimgtot; // weak +extern int uniquetrans; +extern int nummtypes; + +void InitMonsterTRN(int monst, BOOL special); +void InitLevelMonsters(); +int AddMonsterType(int type, int placeflag); +void GetLevelMTypes(); +void InitMonsterGFX(int monst); +void ClearMVars(int i); +void InitMonster(int i, int rd, int mtype, int x, int y); +void ClrAllMonsters(); +BOOL MonstPlace(int xp, int yp); +void PlaceMonster(int i, int mtype, int x, int y); +void PlaceUniqueMonst(int uniqindex, int miniontype, int packsize); +void PlaceQuestMonsters(); +void PlaceGroup(int mtype, int num, int leaderf, int leader); +void LoadDiabMonsts(); +void InitMonsters(); +void PlaceUniques(); +void SetMapMonsters(BYTE *pMap, int startx, int starty); +void DeleteMonster(int i); +int AddMonster(int x, int y, int dir, int mtype, BOOL InMap); +void NewMonsterAnim(int i, AnimStruct &anim, int md); +BOOL M_Ranged(int i); +BOOL M_Talker(int i); +void M_Enemy(int i); +int M_GetDir(int i); +void M_CheckEFlag(int i); +void M_StartStand(int i, int md); +void M_StartDelay(int i, int len); +void M_StartSpStand(int i, int md); +void M_StartWalk(int i, int xvel, int yvel, int xadd, int yadd, int EndDir); +void M_StartWalk2(int i, int xvel, int yvel, int xoff, int yoff, int xadd, int yadd, int EndDir); +void M_StartWalk3(int i, int xvel, int yvel, int xoff, int yoff, int xadd, int yadd, int mapx, int mapy, int EndDir); +void M_StartAttack(int i); +void M_StartRAttack(int i, int missile_type, int dam); +void M_StartRSpAttack(int i, int missile_type, int dam); +void M_StartSpAttack(int i); +void M_StartEat(int i); +void M_ClearSquares(int i); +void M_GetKnockback(int i); +void M_StartHit(int i, int pnum, int dam); +void M_DiabloDeath(int i, BOOL sendmsg); +void M2MStartHit(int mid, int i, int dam); +void MonstStartKill(int i, int pnum, BOOL sendmsg); +void M2MStartKill(int i, int mid); +void M_StartKill(int i, int pnum); +void M_SyncStartKill(int i, int x, int y, int pnum); +void M_StartFadein(int i, int md, BOOL backwards); +void M_StartFadeout(int i, int md, BOOL backwards); +void M_StartHeal(int i); +void M_ChangeLightOffset(int monst); +BOOL M_DoStand(int i); +BOOL M_DoWalk(int i); +BOOL M_DoWalk2(int i); +BOOL M_DoWalk3(int i); +void M_TryM2MHit(int i, int mid, int hper, int mind, int maxd); +void M_TryH2HHit(int i, int pnum, int Hit, int MinDam, int MaxDam); +BOOL M_DoAttack(int i); +BOOL M_DoRAttack(int i); +BOOL M_DoRSpAttack(int i); +BOOL M_DoSAttack(int i); +BOOL M_DoFadein(int i); +BOOL M_DoFadeout(int i); +BOOL M_DoHeal(int i); +BOOL M_DoTalk(int i); +void M_Teleport(int i); +BOOL M_DoGotHit(int i); +void M_UpdateLeader(int i); +void DoEnding(); +void PrepDoEnding(); +BOOL M_DoDeath(int i); +BOOL M_DoSpStand(int i); +BOOL M_DoDelay(int i); +BOOL M_DoStone(int i); +void M_WalkDir(int i, int md); +void GroupUnity(int i); +BOOL M_CallWalk(int i, int md); +BOOL M_PathWalk(int i); +BOOL M_CallWalk2(int i, int md); +BOOL M_DumbWalk(int i, int md); +BOOL M_RoundWalk(int i, int md, int &dir); +void MAI_Zombie(int i); +void MAI_SkelSd(int i); +BOOL MAI_Path(int i); +void MAI_Snake(int i); +void MAI_Bat(int i); +void MAI_SkelBow(int i); +void MAI_Fat(int i); +void MAI_Sneak(int i); +void MAI_Fireman(int i); +void MAI_Fallen(int i); +void MAI_Cleaver(int i); +void MAI_Round(int i, BOOL special); +void MAI_GoatMc(int i); +void MAI_Ranged(int i, int missile_type, BOOL special); +void MAI_GoatBow(int i); +void MAI_Succ(int i); +void MAI_AcidUniq(int i); +void MAI_Scav(int i); +void MAI_Garg(int i); +void MAI_RoundRanged(int i, int missile_type, BOOL checkdoors, int dam, int lessmissiles); +void MAI_Magma(int i); +void MAI_Storm(int i); +void MAI_Acid(int i); +void MAI_Diablo(int i); +void MAI_RR2(int i, int mistype, int dam); +void MAI_Mega(int i); +void MAI_Golum(int i); +void MAI_SkelKing(int i); +void MAI_Rhino(int i); +void MAI_Counselor(int i); +void MAI_Garbud(int i); +void MAI_Zhar(int i); +void MAI_SnotSpil(int i); +void MAI_Lazurus(int i); +void MAI_Lazhelp(int i); +void MAI_Lachdanan(int i); +void MAI_Warlord(int i); +void DeleteMonsterList(); +void ProcessMonsters(); +void FreeMonsters(); +BOOL DirOK(int i, int mdir); +BOOL PosOkMissile(int x, int y); +BOOL CheckNoSolid(int x, int y); +BOOL LineClearF(BOOL (*Clear)(int, int), int x1, int y1, int x2, int y2); +BOOL LineClear(int x1, int y1, int x2, int y2); +BOOL LineClearF1(BOOL (*Clear)(int, int, int), int monst, int x1, int y1, int x2, int y2); +void SyncMonsterAnim(int m); +void M_FallenFear(int x, int y); +void PrintMonstHistory(int mt); +void PrintUniqueHistory(); +void MissToMonst(int i, int x, int y); +BOOL PosOkMonst(int i, int x, int y); +BOOL PosOkMonst2(int i, int x, int y); +BOOL PosOkMonst3(int i, int x, int y); +BOOL IsSkel(int mt); +BOOL IsGoat(int mt); +int M_SpawnSkel(int x, int y, int dir); +void ActivateSpawn(int i, int x, int y, int dir); +BOOL SpawnSkeleton(int ii, int x, int y); +int PreSpawnSkeleton(); +void TalktoMonster(int i); +void SpawnGolum(int i, int x, int y, int mi); +BOOL CanTalkToMonst(int m); +BOOL CheckMonsterHit(int m, BOOL &ret); +int encode_enemy(int m); +void decode_enemy(int m, int enemy); + +/* data */ + +extern int MWVel[24][3]; +extern char animletter[7]; +extern int left[8]; +extern int right[8]; +extern int opposite[8]; +extern int offset_x[8]; +extern int offset_y[8]; + +/* unused */ +extern int rnd5[4]; +extern int rnd10[4]; +extern int rnd20[4]; +extern int rnd60[4]; +// + +extern void (*AiProc[])(int i); + +#endif /* __MONSTER_H__ */ diff --git a/2020_03_31/Source/movie.cpp b/2020_03_31/Source/movie.cpp new file mode 100644 index 00000000..9df3529f --- /dev/null +++ b/2020_03_31/Source/movie.cpp @@ -0,0 +1,68 @@ +#include "diablo.h" +#include "../3rdParty/Storm/Source/storm.h" + +BOOLEAN movie_playing; +BOOL loop_movie; + +void play_movie(const char *pszMovie, BOOL bCanSkip) +{ + WNDPROC saveProc; + MSG msg; + HANDLE hVideo; + + if(!gbActive) { + return; + } + + /// ASSERT: assert(ghMainWnd); + saveProc = SetWindowProc(MovieWndProc); + InvalidateRect(ghMainWnd, NULL, FALSE); + UpdateWindow(ghMainWnd); + movie_playing = TRUE; + sound_disable_music(TRUE); + stream_stop(); + effects_play_sound("Sfx\\Misc\\blank.wav"); + SVidPlayBegin(pszMovie, 0, 0, 0, 0, loop_movie ? 0x100C0808 : 0x10280808, &hVideo); + + while(hVideo != NULL) { + if(!gbActive || bCanSkip && !movie_playing) { + break; + } + while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { + if(msg.message != WM_QUIT) { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + if(!SVidPlayContinue()) { + break; + } + } + if(hVideo != NULL) { + SVidPlayEnd(hVideo); + } + + saveProc = SetWindowProc(saveProc); + /// ASSERT: assert(saveProc == MovieWndProc); + sound_disable_music(FALSE); +} + +LRESULT CALLBACK MovieWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + switch(uMsg) { + case WM_KEYDOWN: + case WM_CHAR: + case WM_LBUTTONDOWN: + case WM_RBUTTONDOWN: + movie_playing = FALSE; + break; + case WM_SYSCOMMAND: + if(wParam == SC_CLOSE) { + movie_playing = FALSE; + return 0; + } + break; + } + + return MainWndProc(hWnd, uMsg, wParam, lParam); +} diff --git a/2020_03_31/Source/movie.h b/2020_03_31/Source/movie.h new file mode 100644 index 00000000..3276b87d --- /dev/null +++ b/2020_03_31/Source/movie.h @@ -0,0 +1,11 @@ +//HEADER_GOES_HERE +#ifndef __MOVIE_H__ +#define __MOVIE_H__ + +extern BOOLEAN movie_playing; +extern BOOL loop_movie; + +void play_movie(const char *pszMovie, BOOL bCanSkip); +LRESULT CALLBACK MovieWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); + +#endif /* __MOVIE_H__ */ diff --git a/2020_03_31/Source/mpqapi.cpp b/2020_03_31/Source/mpqapi.cpp new file mode 100644 index 00000000..24e186e9 --- /dev/null +++ b/2020_03_31/Source/mpqapi.cpp @@ -0,0 +1,795 @@ +#include "diablo.h" +#include "../3rdParty/Storm/Source/storm.h" + +int sgdwMpqOffset; // idb +char mpq_buf[4096]; +_HASHENTRY *sgpHashTbl; +_bool save_archive_modified; // weak +_BLOCKENTRY *sgpBlockTbl; +_bool save_archive_open; // weak + +//note: 32872 = 32768 + 104 (sizeof(_FILEHEADER)) + +/* data */ + +HANDLE sghArchive = (HANDLE)0xFFFFFFFF; // idb + +_bool mpqapi_set_hidden(char *pszArchive, _bool hidden) +{ + char *v2; // edi + BOOL v3; // esi + DWORD v4; // eax + _bool result; // al + DWORD v6; // esi + + v2 = pszArchive; + v3 = hidden; + v4 = GetFileAttributes(pszArchive); + if ( v4 == -1 ) + return GetLastError() == ERROR_FILE_NOT_FOUND; + v6 = v3 != 0 ? FILE_ATTRIBUTE_SYSTEM|FILE_ATTRIBUTE_HIDDEN : 0; + if ( v4 == v6 ) + result = 1; + else + result = SetFileAttributes(v2, v6); + return result; +} + +void mpqapi_store_creation_time(char *pszArchive, int dwChar) +{ + int v2; // esi + char *v3; // ebx + HANDLE v4; // eax + int v5; // esi + struct _WIN32_FIND_DATAA FindFileData; // [esp+8h] [ebp-1E0h] + char dst[160]; // [esp+148h] [ebp-A0h] + + v2 = dwChar; + v3 = pszArchive; + if ( gbMaxPlayers != 1 ) + { + mpqapi_reg_load_modification_time(dst, 160); + v4 = FindFirstFile(v3, &FindFileData); + if ( v4 != (HANDLE)-1 ) + { + FindClose(v4); + v5 = 16 * v2; + *(_DWORD *)&dst[v5] = FindFileData.ftCreationTime.dwLowDateTime; + *(_DWORD *)&dst[v5 + 4] = FindFileData.ftCreationTime.dwHighDateTime; + mpqapi_reg_store_modification_time(dst, 160); + } + } +} + +_bool mpqapi_reg_load_modification_time(char *dst, int size) +{ + unsigned int v2; // esi + char *v3; // edi + unsigned int v6; // esi + char *v7; // ecx + int nbytes_read; // [esp+8h] [ebp-4h] + + v2 = size; + v3 = dst; + memset(dst, 0, size); + if ( !SRegLoadData("Diablo", "Video Player ", 0, (unsigned char *)v3, v2, (unsigned long *)&nbytes_read) || nbytes_read != v2 ) + return 0; + if ( v2 >= 8 ) + { + v6 = v2 >> 3; + do + { + v7 = v3; + v3 += 8; + mpqapi_xor_buf(v7); + --v6; + } + while ( v6 ); + } + return 1; +} + +void mpqapi_xor_buf(char *pbData) +{ + signed int v1; // eax + char *v2; // esi + signed int v3; // edi + + v1 = 0xF0761AB; + v2 = pbData; + v3 = 8; + do + { + *v2 ^= v1; + ++v2; + v1 = _rotl(v1, 1); + --v3; + } + while ( v3 ); +} + +void mpqapi_store_default_time(DWORD dwChar) +{ +/* + DWORD idx; + char dst[160]; + + if(gbMaxPlayers == 1) { + return; + } + + /// ASSERT: assert(dwChar < MAX_CHARACTERS); + idx = 16 * dwChar; + mpqapi_reg_load_modification_time(dst, sizeof(dst)); + *(_DWORD *)&dst[idx + 4] = 0x78341348; // dwHighDateTime + mpqapi_reg_store_modification_time(dst, sizeof(dst)); +*/ +} + +_bool mpqapi_reg_store_modification_time(char *pbData, int dwLen) +{ + int v2; // ebx + char *v3; // ebp + char *v4; // edi + unsigned int v5; // esi + char *v6; // ecx + + v2 = dwLen; + v3 = pbData; + v4 = pbData; + if ( (unsigned int)dwLen >= 8 ) + { + v5 = (unsigned int)dwLen >> 3; + do + { + v6 = v4; + v4 += 8; + mpqapi_xor_buf(v6); + --v5; + } + while ( v5 ); + } + return SRegSaveData("Diablo", "Video Player ", 0, (unsigned char *)v3, v2); +} + +void mpqapi_remove_hash_entry(char *pszName) +{ + int v1; // eax + _HASHENTRY *v2; // ecx + _BLOCKENTRY *v3; // eax + int v4; // esi + int v5; // edi + + v1 = mpqapi_get_hash_index_of_path(pszName); + if ( v1 != -1 ) + { + v2 = &sgpHashTbl[v1]; + v3 = &sgpBlockTbl[v2->block]; + v2->block = -2; + v4 = v3->offset; + v5 = v3->sizealloc; + memset(v3, 0, 0x10u); + mpqapi_free_block(v4, v5); + save_archive_modified = 1; + } +} + +void mpqapi_free_block(int block_offset, int block_size) +{ + int v2; // esi + int v3; // edi + _BLOCKENTRY *v4; // eax + signed int v5; // edx + signed int v6; // ecx + int v7; // ecx + _bool v8; // zf + _BLOCKENTRY *v9; // eax + + v2 = block_size; + v3 = block_offset; +LABEL_2: + v4 = sgpBlockTbl; + v5 = 2048; + while ( 1 ) + { + v6 = v5--; + if ( !v6 ) + break; + v7 = v4->offset; + if ( v4->offset && !v4->flags && !v4->sizefile ) + { + if ( v7 + v4->sizealloc == v3 ) + { + v3 = v4->offset; +LABEL_11: + v2 += v4->sizealloc; + memset(v4, 0, 0x10u); + goto LABEL_2; + } + if ( v3 + v2 == v7 ) + goto LABEL_11; + } + ++v4; + } + v8 = v3 + v2 == sgdwMpqOffset; + if ( v3 + v2 > sgdwMpqOffset ) + { + app_fatal("MPQ free list error"); + v8 = v3 + v2 == sgdwMpqOffset; + } + if ( v8 ) + { + sgdwMpqOffset = v3; + } + else + { + v9 = mpqapi_new_block(0); + v9->offset = v3; + v9->sizealloc = v2; + v9->sizefile = 0; + v9->flags = 0; + } +} + +_BLOCKENTRY *mpqapi_new_block(int *block_index) +{ + _BLOCKENTRY *result; // eax + unsigned int v2; // edx + + result = sgpBlockTbl; + v2 = 0; + while ( result->offset || result->sizealloc || result->flags || result->sizefile ) + { + ++v2; + ++result; + if ( v2 >= 0x800 ) + { + app_fatal("Out of free block entries"); + return 0; + } + } + if ( block_index ) + *block_index = v2; + return result; +} + +int mpqapi_get_hash_index_of_path(char *pszName) // FetchHandle +{ + char *v1; // esi + int v2; // ST00_4 + int v3; // edi + short v4; // ax + + v1 = pszName; + v2 = Hash(pszName, 2); // MPQ_HASH_NAME_B + v3 = Hash(v1, 1); // MPQ_HASH_NAME_A + v4 = Hash(v1, 0); // MPQ_HASH_TABLE_INDEX + return mpqapi_get_hash_index(v4, v3, v2, 0); +} + +int mpqapi_get_hash_index(short index, int hash_a, int hash_b, int locale) +{ + int v4; // ecx + signed int v5; // eax + signed int v6; // edx + _HASHENTRY *v7; // ecx + int v8; // edi + int v10; // [esp+Ch] [ebp-8h] + int i; // [esp+10h] [ebp-4h] + + v4 = index & 0x7FF; + v10 = hash_a; + v5 = 2048; + for ( i = v4; ; i = (i + 1) & 0x7FF ) + { + v7 = &sgpHashTbl[v4]; + v8 = v7->block; + if ( v8 == -1 ) + return -1; + v6 = v5--; + if ( !v6 ) + return -1; + if ( v7->hashcheck[0] == v10 && v7->hashcheck[1] == hash_b && v7->lcid == locale && v8 != -2 ) + break; + v4 = (i + 1) & 0x7FF; + } + return i; +} + +void mpqapi_remove_hash_entries(_bool (__stdcall *fnGetName)(int, char *)) +{ + _bool (__stdcall *v1)(int, char *); // edi + signed int v2; // esi + int i; // eax + int v4; // eax + char v5[260]; // [esp+8h] [ebp-104h] + + v1 = fnGetName; + v2 = 1; + for ( i = fnGetName(0, v5); i; i = v1(v4, v5) ) + { + mpqapi_remove_hash_entry(v5); + v4 = v2++; + } +} + +_bool mpqapi_write_file(char *pszName, char *pbData, int dwLen) +{ + char *v3; // edi + char *v4; // esi + _BLOCKENTRY *v5; // eax + + v3 = pbData; + v4 = pszName; + save_archive_modified = 1; + mpqapi_remove_hash_entry(pszName); + v5 = mpqapi_add_file(v4, 0, 0); + if ( mpqapi_write_file_contents(v4, v3, dwLen, v5) ) + return 1; + mpqapi_remove_hash_entry(v4); + return 0; +} + +_BLOCKENTRY *mpqapi_add_file(char *pszName, _BLOCKENTRY *pBlk, int block_index) +{ + char *v3; // edi + short v4; // si + int v5; // ebx + signed int v6; // edx + int v7; // esi + int v8; // ecx + int v9; // esi + int v11; // [esp+Ch] [ebp-8h] + _BLOCKENTRY *v12; // [esp+10h] [ebp-4h] + + v12 = pBlk; + v3 = pszName; + v4 = Hash(pszName, 0); + v5 = Hash(v3, 1); + v11 = Hash(v3, 2); + if ( mpqapi_get_hash_index(v4, v5, v11, 0) != -1 ) + app_fatal("Hash collision between \"%s\" and existing file\n", v3); + v6 = 2048; + v7 = v4 & 0x7FF; + while ( 1 ) + { + --v6; + v8 = sgpHashTbl[v7].block; + if ( v8 == -1 || v8 == -2 ) + break; + v7 = (v7 + 1) & 0x7FF; + if ( !v6 ) + { + v6 = -1; + break; + } + } + if ( v6 < 0 ) + app_fatal("Out of hash space"); + if ( !v12 ) + v12 = mpqapi_new_block(&block_index); + v9 = v7; + sgpHashTbl[v9].hashcheck[0] = v5; + sgpHashTbl[v9].hashcheck[1] = v11; + sgpHashTbl[v9].lcid = 0; + sgpHashTbl[v9].block = block_index; + return v12; +} + +_bool mpqapi_write_file_contents(char *pszName, char *pbData, int dwLen, _BLOCKENTRY *pBlk) +{ + char *v4; // esi + char *v5; // eax + unsigned int destsize; // ebx + char *v7; // eax + unsigned int v8; // esi + _BLOCKENTRY *v9; // edi + int v10; // eax + signed int v11; // eax + unsigned int v13; // eax + unsigned int v14; // eax + int v15; // ecx + int size; // [esp+Ch] [ebp-10h] + char *v17; // [esp+10h] [ebp-Ch] + int v18; // [esp+14h] [ebp-8h] + DWORD nNumberOfBytesToWrite; // [esp+18h] [ebp-4h] + + v4 = pszName; + v17 = pbData; + v5 = strchr(pszName, ':'); + destsize = 0; + while ( v5 ) + { + v4 = v5 + 1; + v5 = strchr(v5 + 1, ':'); + } + while ( 1 ) + { + v7 = strchr(v4, '\\'); + if ( !v7 ) + break; + v4 = v7 + 1; + } + Hash(v4, 3); + v8 = dwLen; + v9 = pBlk; + size = 4 * ((unsigned int)(dwLen + 4095) >> 12) + 4; + nNumberOfBytesToWrite = 4 * ((unsigned int)(dwLen + 4095) >> 12) + 4; + v10 = mpqapi_find_free_block(size + dwLen, &pBlk->sizealloc); + v9->offset = v10; + v9->sizefile = v8; + v9->flags = 0x80000100; + if ( SetFilePointer(sghArchive, v10, NULL, FILE_BEGIN) == -1 ) + return 0; + pBlk = 0; + v18 = 0; + while ( v8 ) + { + v11 = 0; + do + mpq_buf[v11++] -= 86; + while ( v11 < 4096 ); + dwLen = v8; + if ( v8 >= 0x1000 ) + dwLen = 4096; + memcpy(mpq_buf, v17, dwLen); + v17 += dwLen; + dwLen = PkwareCompress(mpq_buf, dwLen); + if ( !v18 ) + { + nNumberOfBytesToWrite = size; + pBlk = (_BLOCKENTRY *)DiabloAllocPtr(size); + memset(pBlk, 0, nNumberOfBytesToWrite); + if ( !WriteFile(sghArchive, pBlk, nNumberOfBytesToWrite, &nNumberOfBytesToWrite, 0) ) + goto LABEL_25; + destsize += nNumberOfBytesToWrite; + } + *(&pBlk->offset + v18) = destsize; + if ( !WriteFile(sghArchive, mpq_buf, dwLen, (LPDWORD)&dwLen, 0) ) + goto LABEL_25; + ++v18; + if ( v8 <= 0x1000 ) + v8 = 0; + else + v8 -= 4096; + destsize += dwLen; + } + *(&pBlk->offset + v18) = destsize; + if ( SetFilePointer(sghArchive, -destsize, NULL, FILE_CURRENT) == -1 + || !WriteFile(sghArchive, pBlk, nNumberOfBytesToWrite, &nNumberOfBytesToWrite, 0) + || SetFilePointer(sghArchive, destsize - nNumberOfBytesToWrite, NULL, FILE_CURRENT) == -1 ) + { +LABEL_25: + if ( pBlk ) + mem_free_dbg(pBlk); + return 0; + } + mem_free_dbg(pBlk); + v13 = v9->sizealloc; + if ( destsize < v13 ) + { + v14 = v13 - destsize; + if ( v14 >= 0x400 ) + { + v15 = destsize + v9->offset; + v9->sizealloc = destsize; + mpqapi_free_block(v15, v14); + } + } + return 1; +} + +int mpqapi_find_free_block(int size, int *block_size) +{ + _BLOCKENTRY *v2; // eax + signed int v3; // esi + int result; // eax + int v5; // esi + _bool v6; // zf + + v2 = sgpBlockTbl; + v3 = 2048; + while ( 1 ) + { + --v3; + if ( v2->offset ) + { + if ( !v2->flags && !v2->sizefile && v2->sizealloc >= (unsigned int)size ) + break; + } + ++v2; + if ( !v3 ) + { + *block_size = size; + result = sgdwMpqOffset; + sgdwMpqOffset += size; + return result; + } + } + v5 = v2->offset; + *block_size = size; + v2->offset += size; + v6 = v2->sizealloc == size; + v2->sizealloc -= size; + if ( v6 ) + memset(v2, 0, 0x10u); + return v5; +} + +void mpqapi_rename(char *pszOld, char *pszNew) +{ + char *v2; // esi + int v3; // eax + _HASHENTRY *v4; // eax + int v5; // ST00_4 + _BLOCKENTRY *v6; // edx + + v2 = pszNew; + v3 = mpqapi_get_hash_index_of_path(pszOld); + if ( v3 != -1 ) + { + v4 = &sgpHashTbl[v3]; + v5 = v4->block; + v6 = &sgpBlockTbl[v5]; + v4->block = -2; + mpqapi_add_file(v2, v6, v5); + save_archive_modified = 1; + } +} + +_bool mpqapi_has_file(char *pszName) +{ + return mpqapi_get_hash_index_of_path(pszName) != -1; +} + +_bool mpqapi_open_archive(char *pszArchive, _bool hidden, int dwChar) // OpenMPQ +{ + char *v3; // ebp + BOOL v4; // esi + DWORD v6; // edi + int v8; // eax + int v10; // eax + char *lpFileName; // [esp+10h] [ebp-70h] + DWORD dwTemp; // [esp+14h] [ebp-6Ch] + _FILEHEADER fhdr; // [esp+18h] [ebp-68h] + + v3 = pszArchive; + v4 = hidden; + lpFileName = pszArchive; + InitHash(); + if ( !mpqapi_set_hidden(v3, v4) ) + return 0; + v6 = (unsigned char)gbMaxPlayers > 1u ? FILE_FLAG_WRITE_THROUGH : 0; + save_archive_open = 0; + sghArchive = CreateFile(v3, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, v6, NULL); + if ( sghArchive == (HANDLE)-1 ) + { + sghArchive = CreateFile(lpFileName, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, v6 | (v4 != 0 ? FILE_ATTRIBUTE_SYSTEM|FILE_ATTRIBUTE_HIDDEN : 0), NULL); + if ( sghArchive == (HANDLE)-1 ) + return 0; + save_archive_open = 1; + save_archive_modified = 1; + } + if ( !sgpBlockTbl || !sgpHashTbl ) + { + memset(&fhdr, 0, 0x68u); + if ( !mpqapi_parse_archive_header(&fhdr, &sgdwMpqOffset) ) + { +LABEL_15: + mpqapi_close_archive(lpFileName, 1, dwChar); + return 0; + } + sgpBlockTbl = (_BLOCKENTRY *)DiabloAllocPtr(0x8000); + memset(sgpBlockTbl, 0, 0x8000u); + if ( fhdr.blockcount ) + { + if ( SetFilePointer(sghArchive, 104, NULL, FILE_BEGIN) == -1 + || !ReadFile(sghArchive, sgpBlockTbl, 0x8000u, &dwTemp, NULL) ) + { + goto LABEL_15; + } + v8 = Hash("(block table)", 3); + Decrypt(sgpBlockTbl, 0x8000, v8); + } + sgpHashTbl = (_HASHENTRY *)DiabloAllocPtr(0x8000); + memset(sgpHashTbl, 255, 0x8000u); + if ( fhdr.hashcount ) + { + if ( SetFilePointer(sghArchive, 32872, NULL, FILE_BEGIN) == -1 + || !ReadFile(sghArchive, sgpHashTbl, 0x8000u, &dwTemp, NULL) ) + { + goto LABEL_15; + } + v10 = Hash("(hash table)", 3); + Decrypt(sgpHashTbl, 0x8000, v10); + } + } + return 1; +} + +_bool mpqapi_parse_archive_header(_FILEHEADER *pHdr, int *pdwNextFileStart) // ParseMPQHeader +{ + int *v2; // ebp + _FILEHEADER *v3; // esi + DWORD v4; // eax + DWORD v5; // edi + DWORD NumberOfBytesRead; // [esp+10h] [ebp-4h] + + v2 = pdwNextFileStart; + v3 = pHdr; + v4 = GetFileSize(sghArchive, 0); + v5 = v4; + *v2 = v4; + if ( v4 == -1 + || v4 < 0x68 + || !ReadFile(sghArchive, v3, 0x68u, &NumberOfBytesRead, NULL) + || NumberOfBytesRead != 104 + || v3->signature != '\x1AQPM' + || v3->headersize != 32 + || v3->version > 0u + || v3->sectorsizeid != 3 + || v3->filesize != v5 + || v3->hashoffset != 32872 + || v3->blockoffset != 104 + || v3->hashcount != 2048 + || v3->blockcount != 2048 ) + { + if ( SetFilePointer(sghArchive, 0, NULL, FILE_BEGIN) == -1 || !SetEndOfFile(sghArchive) ) + return 0; + memset(v3, 0, 0x68u); + v3->signature = '\x1AQPM'; + v3->headersize = 32; + v3->sectorsizeid = 3; + v3->version = 0; + *v2 = 0x10068; + save_archive_modified = 1; + save_archive_open = 1; + } + return 1; +} + +void mpqapi_close_archive(char *pszArchive, _bool bFree, int dwChar) // CloseMPQ +{ + char *v3; // esi + _BLOCKENTRY *v4; // ecx + _HASHENTRY *v5; // ecx + + v3 = pszArchive; + if ( bFree ) + { + v4 = sgpBlockTbl; + sgpBlockTbl = 0; + mem_free_dbg(v4); + v5 = sgpHashTbl; + sgpHashTbl = 0; + mem_free_dbg(v5); + } + if ( sghArchive != (HANDLE)-1 ) + { + CloseHandle(sghArchive); + sghArchive = (HANDLE)-1; + } + if ( save_archive_modified ) + { + save_archive_modified = 0; + mpqapi_store_modified_time(v3, dwChar); + } + if ( save_archive_open ) + { + save_archive_open = 0; + mpqapi_store_creation_time(v3, dwChar); + } +} + +void mpqapi_store_modified_time(char *pszArchive, int dwChar) +{ + int v2; // esi + char *v3; // ebx + HANDLE v4; // eax + int v5; // esi + struct _WIN32_FIND_DATAA FindFileData; // [esp+8h] [ebp-1E0h] + char dst[160]; // [esp+148h] [ebp-A0h] + + v2 = dwChar; + v3 = pszArchive; + if ( gbMaxPlayers != 1 ) + { + mpqapi_reg_load_modification_time(dst, 160); + v4 = FindFirstFile(v3, &FindFileData); + if ( v4 != (HANDLE)-1 ) + { + FindClose(v4); + v5 = 16 * v2; + *(_DWORD *)&dst[v5 + 8] = FindFileData.ftLastWriteTime.dwLowDateTime; + *(_DWORD *)&dst[v5 + 12] = FindFileData.ftLastWriteTime.dwHighDateTime; + mpqapi_reg_store_modification_time(dst, 160); + } + } +} + +void mpqapi_flush_and_close(char *pszArchive, _bool bFree, int dwChar) +{ + if ( sghArchive != (HANDLE)-1 ) + { + if ( save_archive_modified ) + { + if ( mpqapi_can_seek() ) + { + if ( mpqapi_write_header() ) + { + if ( mpqapi_write_block_table() ) + mpqapi_write_hash_table(); + } + } + } + } + mpqapi_close_archive(pszArchive, bFree, dwChar); +} + +_bool mpqapi_write_header() // WriteMPQHeader +{ + _bool result; // al + _FILEHEADER fhdr; // [esp+8h] [ebp-6Ch] + DWORD NumberOfBytesWritten; // [esp+70h] [ebp-4h] + + memset(&fhdr, 0, 0x68u); + fhdr.signature = '\x1AQPM'; + fhdr.headersize = 32; + fhdr.filesize = GetFileSize(sghArchive, 0); + fhdr.version = 0; + fhdr.sectorsizeid = 3; + fhdr.hashoffset = 32872; + fhdr.blockoffset = 104; + fhdr.hashcount = 2048; + fhdr.blockcount = 2048; + if ( SetFilePointer(sghArchive, 0, NULL, FILE_BEGIN) != -1 && WriteFile(sghArchive, &fhdr, 0x68u, &NumberOfBytesWritten, 0) ) + result = NumberOfBytesWritten == 104; + else + result = 0; + return result; +} + +_bool mpqapi_write_block_table() +{ + int v1; // eax + BOOL v2; // ebx + int v3; // eax + DWORD NumberOfBytesWritten; // [esp+4h] [ebp-4h] + + if ( SetFilePointer(sghArchive, 104, NULL, FILE_BEGIN) == -1 ) + return 0; + v1 = Hash("(block table)", 3); + Encrypt(sgpBlockTbl, 0x8000, v1); + v2 = WriteFile(sghArchive, sgpBlockTbl, 0x8000u, &NumberOfBytesWritten, 0); + v3 = Hash("(block table)", 3); + Decrypt(sgpBlockTbl, 0x8000, v3); + return v2 && NumberOfBytesWritten == 0x8000; +} + +_bool mpqapi_write_hash_table() +{ + int v1; // eax + BOOL v2; // ebx + int v3; // eax + DWORD NumberOfBytesWritten; // [esp+4h] [ebp-4h] + + if ( SetFilePointer(sghArchive, 32872, NULL, FILE_BEGIN) == -1 ) + return 0; + v1 = Hash("(hash table)", 3); + Encrypt(sgpHashTbl, 0x8000, v1); + v2 = WriteFile(sghArchive, sgpHashTbl, 0x8000u, &NumberOfBytesWritten, 0); + v3 = Hash("(hash table)", 3); + Decrypt(sgpHashTbl, 0x8000, v3); + return v2 && NumberOfBytesWritten == 0x8000; +} + +_bool mpqapi_can_seek() +{ + _bool result; // al + + if ( SetFilePointer(sghArchive, sgdwMpqOffset, NULL, FILE_BEGIN) == -1 ) + result = 0; + else + result = SetEndOfFile(sghArchive); + return result; +} diff --git a/2020_03_31/Source/mpqapi.h b/2020_03_31/Source/mpqapi.h new file mode 100644 index 00000000..db3ecea5 --- /dev/null +++ b/2020_03_31/Source/mpqapi.h @@ -0,0 +1,45 @@ +//HEADER_GOES_HERE +#ifndef __MPQAPI_H__ +#define __MPQAPI_H__ + +extern int sgdwMpqOffset; // idb +extern char mpq_buf[4096]; +extern _HASHENTRY *sgpHashTbl; +extern _bool save_archive_modified; // weak +extern _BLOCKENTRY *sgpBlockTbl; +extern _bool save_archive_open; // weak + +_bool mpqapi_set_hidden(char *pszArchive, _bool hidden); +void mpqapi_store_creation_time(char *pszArchive, int dwChar); +_bool mpqapi_reg_load_modification_time(char *dst, int size); +void mpqapi_xor_buf(char *pbData); +void mpqapi_store_default_time(DWORD dwChar); +_bool mpqapi_reg_store_modification_time(char *pbData, int dwLen); +_BLOCKENTRY *j_mpqapi_remove_hash_entry(char *pszName); +void mpqapi_remove_hash_entry(char *pszName); +void mpqapi_free_block(int block_offset, int block_size); +_BLOCKENTRY *mpqapi_new_block(int *block_index); +int mpqapi_get_hash_index_of_path(char *pszName); +int mpqapi_get_hash_index(short index, int hash_a, int hash_b, int locale); +void mpqapi_remove_hash_entries(_bool (__stdcall *fnGetName)(int, char *)); +_bool mpqapi_write_file(char *pszName, char *pbData, int dwLen); +_BLOCKENTRY *mpqapi_add_file(char *pszName, _BLOCKENTRY *pBlk, int block_index); +_bool mpqapi_write_file_contents(char *pszName, char *pbData, int dwLen, _BLOCKENTRY *pBlk); +int mpqapi_find_free_block(int size, int *block_size); +void mpqapi_rename(char *pszOld, char *pszNew); +_bool mpqapi_has_file(char *pszName); +_bool mpqapi_open_archive(char *pszArchive, _bool hidden, int dwChar); +_bool mpqapi_parse_archive_header(_FILEHEADER *pHdr, int *pdwNextFileStart); +void mpqapi_close_archive(char *pszArchive, _bool bFree, int dwChar); +void mpqapi_store_modified_time(char *pszArchive, int dwChar); +void mpqapi_flush_and_close(char *pszArchive, _bool bFree, int dwChar); +_bool mpqapi_write_header(); +_bool mpqapi_write_block_table(); +_bool mpqapi_write_hash_table(); +_bool mpqapi_can_seek(); + +/* data */ + +extern HANDLE sghArchive; // idb + +#endif /* __MPQAPI_H__ */ diff --git a/2020_03_31/Source/msg.cpp b/2020_03_31/Source/msg.cpp new file mode 100644 index 00000000..32399790 --- /dev/null +++ b/2020_03_31/Source/msg.cpp @@ -0,0 +1,3096 @@ +#include "diablo.h" +#include "../3rdParty/Storm/Source/storm.h" +#include "../DiabloUI/diabloui.h" + +int sgdwOwnerWait; // weak +int sgdwRecvOffset; // idb +int sgnCurrMegaPlayer; // weak +DLevel sgLevels[NUMLEVELS]; +TMegaPkt *sgpCurrPkt; +BYTE sgRecvBuf[4722]; +unsigned char sgbRecvCmd; // idb +LocalLevel sgLocals[NUMLEVELS]; +DJunk sgJunk; +TMegaPkt *sgpMegaPkt; +char sgbDeltaChanged; // weak +BYTE sgbDeltaChunks; // weak +int deltaload; // weak +char gbBufferMsgs; // weak +int dwRecCount; // weak +int msg_err_timer; // weak + +void msg_send_drop_pkt(int pnum, DWORD reason) +{ + TFakeDropPlr cmd; + + cmd.bCmd = FAKE_CMD_DROPID; + cmd.bPlr = pnum; + cmd.dwReason = reason; + msg_send_packet(pnum, &cmd, sizeof(cmd)); +} + +void msg_send_packet(int pnum, const void *pMsg, DWORD dwLen) +{ + TFakeCmdPlr cmd; + + /// ASSERT: assert((DWORD) pnum < MAX_PLRS); + /// ASSERT: assert(pMsg); + /// ASSERT: assert(dwLen <= gdwLargestMsgSize); + if(pnum != sgnCurrMegaPlayer) { + sgnCurrMegaPlayer = pnum; + cmd.bCmd = FAKE_CMD_SETID; + cmd.bPlr = pnum; + msg_send_packet(pnum, &cmd, sizeof(cmd)); + } + + /// ASSERT: assert(sgpCurrPkt); + if(sgpCurrPkt->dwSpaceLeft < dwLen) { + msg_get_next_packet(); + /// ASSERT: assert(sgpCurrPkt->dwSpaceLeft >= dwLen); + } + + memcpy((char *)&sgpCurrPkt[1] - sgpCurrPkt->dwSpaceLeft, pMsg, dwLen); + sgpCurrPkt->dwSpaceLeft -= dwLen; +} + +void msg_get_next_packet() +{ + TMegaPkt *p; + + sgpCurrPkt = (TMegaPkt *)DiabloAllocPtr(sizeof(*sgpCurrPkt)); + sgpCurrPkt->pNext = NULL; + sgpCurrPkt->dwSpaceLeft = sizeof(sgpCurrPkt->data); + + p = (TMegaPkt *)&sgpMegaPkt; + while(p->pNext != NULL) { + p = p->pNext; + } + p->pNext = sgpCurrPkt; +} + +BOOL msg_wait_resync() +{ + BOOL bSuccess; + + /// ASSERT: assert(ghMainWnd); + /// ASSERT: assert(! sgpMegaPkt); + /// ASSERT: assert(! sgpCurrPkt); + + msg_get_next_packet(); + sgbDeltaChunks = 0; + sgnCurrMegaPlayer = -1; + sgbRecvCmd = CMD_DLEVEL_END; + gbBufferMsgs = 1; + sgdwOwnerWait = GetTickCount(); + bSuccess = UiProgressDialog(ghMainWnd, "Waiting for game data...", 1, msg_wait_for_turns, 20); + gbBufferMsgs = 0; + + if(!bSuccess) { + msg_free_packets(); + return FALSE; + } + if(gbGameDestroyed) { + DrawDlg("The game ended"); + msg_free_packets(); + return FALSE; + } + if(sgbDeltaChunks != 21) { + DrawDlg("Unable to get level data"); + msg_free_packets(); + return FALSE; + } + + return TRUE; +} + +void msg_free_packets() +{ + while(sgpMegaPkt != NULL) { + sgpCurrPkt = sgpMegaPkt->pNext; + MemFreeDbg(sgpMegaPkt); + sgpMegaPkt = sgpCurrPkt; + } +} + +int msg_wait_for_turns() +{ + DWORD dwTurns; + BOOL fSendAsync; + + if(sgbDeltaChunks == 0) { + nthread_send_and_recv_turn(0, 0); + if(!SNetGetOwnerTurnsWaiting(&dwTurns) && SErrGetLastError() == STORM_ERROR_NOT_IN_GAME) { + return 100; + } + if(GetTickCount() - sgdwOwnerWait <= 2000 && dwTurns < gdwTurnsInTransit) { + return 0; + } + sgbDeltaChunks++; + } + + multi_process_network_packets(); + nthread_send_and_recv_turn(0, 0); + + if(nthread_has_500ms_passed(FALSE)) { + nthread_recv_turns(&fSendAsync); + } + if(gbGameDestroyed) { + return 100; + } + if(gbDeltaSender >= 4) { + sgbDeltaChunks = 0; + sgbRecvCmd = CMD_DLEVEL_END; + gbDeltaSender = myplr; + nthread_set_turn_upper_bit(); + } + if(sgbDeltaChunks == 20) { + sgbDeltaChunks++; + return 99; + } + + return 100 * sgbDeltaChunks / 21; +} + +void run_delta_info() +{ + if(gbMaxPlayers == 1) { + return; + } + + /// ASSERT: assert(currlevel == 0); + /// ASSERT: assert(plr[myplr].plrlevel == 0); + + gbBufferMsgs = 2; + msg_pre_packet(); + gbBufferMsgs = 0; + msg_free_packets(); +} + +void msg_pre_packet() +{ + int nPlayer; + DWORD dwLen, dwSize; + TMegaPkt *p; + BYTE *pbMsg; + TFakeCmdPlr *pFake; + TFakeDropPlr *pDrop; + TCmd *pCmd; + + nPlayer = -1; + for(p = sgpMegaPkt; p != NULL; p = p->pNext) { + pbMsg = p->data; + dwLen = sizeof(p->data); + while(dwLen != p->dwSpaceLeft) { + if(*pbMsg == FAKE_CMD_SETID) { + pFake = (TFakeCmdPlr *)pbMsg; + pbMsg += sizeof(*pFake); + dwLen -= sizeof(*pFake); + nPlayer = pFake->bPlr; + } else if(*pbMsg == FAKE_CMD_DROPID) { + pDrop = (TFakeDropPlr *)pbMsg; + pbMsg += sizeof(*pDrop); + dwLen -= sizeof(*pDrop); + multi_player_left(pDrop->bPlr, pDrop->dwReason); + } else { + /// ASSERT: assert((DWORD) nPlayer < MAX_PLRS); + pCmd = (TCmd *)pbMsg; + dwSize = ParseCmd(nPlayer, pCmd); + pbMsg += dwSize; + dwLen -= dwSize; + } + } + } +} + +void DeltaExportData(int pnum) +{ + int i; + DWORD dwLen; + BYTE bSrc; + BYTE *p, *dst; + + if(sgbDeltaChanged) { + p = DiabloAllocPtr(sizeof(*sgLevels) + 1); + for(i = 0; i < NUMLEVELS; i++) { + dst = p + 1; + dst = DeltaExportItem(dst, sgLevels[i].item); + dst = DeltaExportObject(dst, sgLevels[i].object); + dst = DeltaExportMonster(dst, sgLevels[i].monster); + dwLen = msg_comp_level(p, dst); + dthread_send_delta(pnum, i + CMD_DLEVEL_0, p, dwLen); + } + dst = DeltaExportJunk(p + 1); + dwLen = msg_comp_level(p, dst); + dthread_send_delta(pnum, CMD_DLEVEL_JUNK, p, dwLen); + MemFreeDbg(p); + } + + bSrc = 0; + dthread_send_delta(pnum, CMD_DLEVEL_END, &bSrc, sizeof(bSrc)); +} + +BYTE *DeltaExportItem(BYTE *dst, TCmdPItem *src) +{ + int i; + + i = 0; + while(i < MAXITEMS) { + if(src->bCmd == 255) { + *dst = 255; + dst++; + } else { + memcpy(dst, src, sizeof(*src)); + dst += sizeof(*src); + } + i++; + src++; + } + + return dst; +} + +BYTE *DeltaExportObject(BYTE *dst, DObjectStr *src) +{ + memcpy(dst, src, sizeof(*src) * MAXOBJECTS); + return dst + sizeof(*src) * MAXOBJECTS; +} + +BYTE *DeltaExportMonster(BYTE *dst, DMonsterStr *src) +{ + int i; + + i = 0; + while(i < MAXMONSTERS) { + if(src->_mx == 255) { + *dst = 255; + dst++; + } else { + memcpy(dst, src, sizeof(*src)); + dst += sizeof(*src); + } + i++; + src++; + } + + return dst; +} + +BYTE *DeltaExportJunk(BYTE *dst) +{ + int i, deltaq; + + for(i = 0; i < MAXPORTAL; i++) { + if(sgJunk.portal[i].x == 255) { + *dst = 255; + dst++; + } else { + memcpy(dst, &sgJunk.portal[i], sizeof(*sgJunk.portal)); + dst += sizeof(*sgJunk.portal); + } + } + + deltaq = 0; + for(i = 0; i < MAXQUESTS; i++) { + if(questlist[i]._qflags & 1) { + sgJunk.quests[deltaq].qlog = quests[i]._qlog; + sgJunk.quests[deltaq].qstate = quests[i]._qactive; + sgJunk.quests[deltaq].qvar1 = quests[i]._qvar1; + memcpy(dst, &sgJunk.quests[deltaq], sizeof(*sgJunk.quests)); + dst += sizeof(*sgJunk.quests); + deltaq++; + } + } + + return dst; +} + +DWORD msg_comp_level(BYTE *p, BYTE *dst) +{ + DWORD dwSize, dwLen; + + dwSize = dst - p - 1; + dwLen = PkwareCompress(p + 1, dwSize); + *p = dwSize != dwLen; + dwLen++; + return dwLen; +} + +void delta_init() +{ + sgbDeltaChanged = 0; + memset(&sgJunk, 255, sizeof(sgJunk)); + memset(&sgLevels, 255, sizeof(sgLevels)); + memset(&sgLocals, 0, sizeof(sgLocals)); + deltaload = 0; +} + +void delta_kill_monster(int mi, BYTE x, BYTE y, BYTE bLevel) +{ + DMonsterStr *p; + + if(gbMaxPlayers == 1) { + return; + } + + /// ASSERT: assert((DWORD)mi < MAXMONSTERS); + /// ASSERT: assert(x < DMAXX); + /// ASSERT: assert(y < DMAXY); + /// ASSERT: assert(bLevel < NUMLEVELS); + + sgbDeltaChanged = 1; + p = &sgLevels[bLevel].monster[mi]; + p->_mx = x; + p->_my = y; + p->_mdir = monster[mi]._mdir; + p->_mhitpoints = 0; +} + +void delta_monster_hp(int mi, long hp, BYTE bLevel) +{ + DMonsterStr *p; + + if(gbMaxPlayers == 1) { + return; + } + + /// ASSERT: assert((DWORD)mi < MAXMONSTERS); + /// ASSERT: assert(bLevel < NUMLEVELS); + + sgbDeltaChanged = 1; + p = &sgLevels[bLevel].monster[mi]; + if(p->_mhitpoints > hp) { + p->_mhitpoints = hp; + } +} + +void delta_sync_monster(const TSyncMonster *pSync, BYTE bLevel) +{ + DMonsterStr *pD; + + if(gbMaxPlayers == 1) { + return; + } + + /// ASSERT: assert(pSync != NULL); + /// ASSERT: assert(bLevel < NUMLEVELS); + + sgbDeltaChanged = 1; + pD = &sgLevels[bLevel].monster[pSync->_mndx]; + if(pD->_mhitpoints != 0) { + pD->_mx = pSync->_mx; + pD->_my = pSync->_my; + pD->_mactive = 255; + pD->_menemy = pSync->_menemy; + } +} + +void delta_sync_golem(const TCmdGolem *pG, int pnum, BYTE bLevel) +{ + DMonsterStr *pD; + + if(gbMaxPlayers == 1) { + return; + } + + /// ASSERT: assert(bLevel < NUMLEVELS); + /// ASSERT: assert(bLevel != 0); + + sgbDeltaChanged = 1; + pD = &sgLevels[bLevel].monster[pnum]; + pD->_mx = pG->_mx; + pD->_my = pG->_my; + pD->_mactive = 255; + pD->_menemy = pG->_menemy; + pD->_mdir = pG->_mdir; + pD->_mhitpoints = pG->_mhitpoints; +} + +void delta_leave_sync(BYTE bLevel) +{ + int i, ii; + DMonsterStr *pD; + + if(gbMaxPlayers == 1) { + return; + } + + if(currlevel == 0) { + glSeedTbl[0] = GetRndSeed(); + } + if(currlevel <= 0) { + return; + } + + /// ASSERT: assert(bLevel < NUMLEVELS); + + for(i = 0; i < nummonsters; i++) { + ii = monstactive[i]; + if(monster[ii]._mhitpoints != 0) { + sgbDeltaChanged = 1; + pD = &sgLevels[bLevel].monster[ii]; + pD->_mx = monster[ii]._mx; + pD->_my = monster[ii]._my; + pD->_mdir = monster[ii]._mdir; + pD->_menemy = encode_enemy(ii); + pD->_mhitpoints = monster[ii]._mhitpoints; + pD->_mactive = monster[ii]._msquelch; + } + } + + memcpy(sgLocals[bLevel].automapsv, automapview, sizeof(automapview)); +} + +BOOL delta_portal_inited(int i) +{ + /// ASSERT: assert((DWORD)i < MAXPORTAL); + return sgJunk.portal[i].x == 255; +} + +BOOL delta_quest_inited(int i) +{ + /// ASSERT: assert((DWORD)i < MAXMULTIQUESTS); + return sgJunk.quests[i].qstate != 255; +} + +void DeltaAddItem(int ii) +{ + int i; + TCmdPItem *pD; + + if(gbMaxPlayers == 1) { + return; + } + + /// ASSERT: assert((DWORD)ii < MAXITEMS); + + pD = sgLevels[currlevel].item; + i = 0; + while(i < MAXITEMS) { + if(pD->bCmd != 255) { + if(pD->wIndx == item[ii].IDidx + && pD->wCI == item[ii]._iCreateInfo + && pD->dwSeed == item[ii]._iSeed + && (pD->bCmd == CMD_WALKXY || pD->bCmd == CMD_STAND)) { + return; + } + } + i++; + pD++; + } + + pD = sgLevels[currlevel].item; + i = 0; + while(i < MAXITEMS) { + if(pD->bCmd == 255) { + sgbDeltaChanged = 1; + pD->bCmd = CMD_STAND; + pD->x = item[ii]._ix; + pD->y = item[ii]._iy; + pD->wIndx = item[ii].IDidx; + pD->wCI = item[ii]._iCreateInfo; + pD->dwSeed = item[ii]._iSeed; + pD->bId = item[ii]._iIdentified; + pD->bDur = item[ii]._iDurability; + pD->bMDur = item[ii]._iMaxDur; + pD->bCh = item[ii]._iCharges; + pD->bMCh = item[ii]._iMaxCharges; + pD->wValue = item[ii]._ivalue; + return; + } + i++; + pD++; + } +} + +void DeltaSaveLevel() +{ + int i; + + if(gbMaxPlayers == 1) { + return; + } + + for(i = 0; i < MAX_PLRS; i++) { + if(i != myplr) { + plr[i]._pGFXLoad = 0; + } + } + + /// ASSERT: assert((DWORD) currlevel < NUMLEVELS); + plr[myplr]._pLvlVisited[currlevel] = 1; + delta_leave_sync(currlevel); +} + +void DeltaLoadLevel() +{ + int i, ii, ox, oy, xx, iz, yy, j, l; + BOOL done; + + if(gbMaxPlayers == 1) { + return; + } + + deltaload = 1; + + if(currlevel != 0) { + for(i = 0; i < nummonsters; i++) { + if(sgLevels[currlevel].monster[i]._mx == 255) { + continue; + } + M_ClearSquares(i); + monster[i]._mx = sgLevels[currlevel].monster[i]._mx; + monster[i]._my = sgLevels[currlevel].monster[i]._my; + monster[i]._moldx = monster[i]._mx; + monster[i]._moldy = monster[i]._my; + monster[i]._mfutx = monster[i]._mx; + monster[i]._mfuty = monster[i]._my; + if(sgLevels[currlevel].monster[i]._mhitpoints != -1) { + monster[i]._mhitpoints = sgLevels[currlevel].monster[i]._mhitpoints; + } + if(sgLevels[currlevel].monster[i]._mhitpoints == 0) { + monster[i]._moldx = sgLevels[currlevel].monster[i]._mx; /// BUGFIX: leftover, already set oldx/y above, remove + monster[i]._moldy = sgLevels[currlevel].monster[i]._my; + M_ClearSquares(i); + if(monster[i]._mAi != AI_DIABLO) { + if(monster[i]._uniqtype == 0) { + /// ASSERT: assert(monster[i].MType != NULL); + AddDead(monster[i]._mx, monster[i]._my, monster[i].MType->mdeadval, monster[i]._mdir); + } else { + AddDead(monster[i]._mx, monster[i]._my, monster[i]._udeadval, monster[i]._mdir); + } + } + monster[i]._mDelFlag = 1; + M_UpdateLeader(i); + } else { + decode_enemy(i, sgLevels[currlevel].monster[i]._menemy); + if(monster[i]._mx != 0 && monster[i]._mx != 1 || monster[i]._my != 0) { + dMonster[monster[i]._mx][monster[i]._my] = i + 1; + } + if(i < 4) { + MAI_Golum(i); + monster[i]._mFlags |= 0x30; + } else { + M_StartStand(i, monster[i]._mdir); + } + monster[i]._msquelch = sgLevels[currlevel].monster[i]._mactive; + } + } + memcpy(automapview, sgLocals[currlevel].automapsv, sizeof(automapview)); + } + + for(i = 0; i < MAXITEMS; i++) { + if(sgLevels[currlevel].item[i].bCmd == 255) { + continue; + } + if(sgLevels[currlevel].item[i].bCmd == CMD_WALKXY) { + ii = FindGetItem( + sgLevels[currlevel].item[i].wIndx, + sgLevels[currlevel].item[i].wCI, + sgLevels[currlevel].item[i].dwSeed); + if(ii != -1) { + if(dItem[item[ii]._ix][item[ii]._iy] == ii + 1) { + dItem[item[ii]._ix][item[ii]._iy] = 0; + } + DeleteItem(ii, i); + } + } + if(sgLevels[currlevel].item[i].bCmd == CMD_ACK_PLRINFO) { + ii = itemavail[0]; + itemavail[0] = itemavail[MAXITEMS - numitems - 1]; + itemactive[numitems] = ii; + if(sgLevels[currlevel].item[i].wIndx == IDI_EAR) { + RecreateEar( + ii, + sgLevels[currlevel].item[i].wCI, + sgLevels[currlevel].item[i].dwSeed, + sgLevels[currlevel].item[i].bId, + sgLevels[currlevel].item[i].bDur, + sgLevels[currlevel].item[i].bMDur, + sgLevels[currlevel].item[i].bCh, + sgLevels[currlevel].item[i].bMCh, + sgLevels[currlevel].item[i].wValue, + sgLevels[currlevel].item[i].dwBuff); + } else { + RecreateItem( + ii, + sgLevels[currlevel].item[i].wIndx, + sgLevels[currlevel].item[i].wCI, + sgLevels[currlevel].item[i].dwSeed, + sgLevels[currlevel].item[i].wValue); + if(sgLevels[currlevel].item[i].bId) { + item[ii]._iIdentified = 1; + } + item[ii]._iDurability = sgLevels[currlevel].item[i].bDur; + item[ii]._iMaxDur = sgLevels[currlevel].item[i].bMDur; + item[ii]._iCharges = sgLevels[currlevel].item[i].bCh; + item[ii]._iMaxCharges = sgLevels[currlevel].item[i].bMCh; + } + ox = sgLevels[currlevel].item[i].x; + oy = sgLevels[currlevel].item[i].y; + if(!CanPut(ox, oy)) { + done = FALSE; + for(l = 1; l < 50 && !done; l++) { + for(j = -l; j <= l && !done; j++) { + yy = j + oy; + for(iz = -l; iz <= l && !done; iz++) { + xx = iz + ox; + if(CanPut(xx, yy)) { + done = TRUE; + ox = xx; + oy = yy; + } + } + } + } + } + item[ii]._ix = ox; + item[ii]._iy = oy; + dItem[item[ii]._ix][item[ii]._iy] = ii + 1; + RespawnItem(ii, FALSE); + numitems++; + } + } + + if(currlevel != 0) { + for(i = 0; i < MAXOBJECTS; i++) { + switch(sgLevels[currlevel].object[i].bCmd) { + case 255: + break; + case CMD_OPENDOOR: + case CMD_CLOSEDOOR: + case CMD_OPERATEOBJ: + case CMD_PLROPOBJ: + SyncOpObject(-1, sgLevels[currlevel].object[i].bCmd, i); + break; + case CMD_BREAKOBJ: + SyncBreakObj(-1, i); + break; + } + } + for(i = 0; i < nobjects; i++) { + ii = objectactive[i]; + if(object[ii]._otype == OBJ_TRAPL || object[ii]._otype == OBJ_TRAPR) { + Obj_Trap(ii); + } + } + } + + deltaload = 0; +} + +void NetSendCmd(BOOL bHiPri, BYTE bCmd) +{ + TCmd cmd; + + cmd.bCmd = bCmd; + + if(bHiPri) { + NetSendHiPri((BYTE *)&cmd, sizeof(cmd)); + } else { + NetSendLoPri((BYTE *)&cmd, sizeof(cmd)); + } +} + +void NetSendCmdGolem(BYTE mx, BYTE my, BYTE dir, BYTE menemy, long hp, BYTE cl) +{ + TCmdGolem cmd; + + /// ASSERT: assert(mx < DMAXX); + /// ASSERT: assert(my < DMAXY); + cmd.bCmd = CMD_AWAKEGOLEM; + cmd._mx = mx; + cmd._my = my; + cmd._mdir = dir; + cmd._menemy = menemy; + cmd._mhitpoints = hp; + cmd._currlevel = cl; + + NetSendLoPri((BYTE *)&cmd, sizeof(cmd)); +} + +void NetSendCmdLoc(BOOL bHiPri, BYTE bCmd, BYTE x, BYTE y) +{ + __declspec(align(1)) TCmdLoc cmd; + + /// ASSERT: assert(x < DMAXX); + /// ASSERT: assert(y < DMAXY); + cmd.bCmd = bCmd; + cmd.x = x; + cmd.y = y; + + if(bHiPri) { + NetSendHiPri((BYTE *)&cmd, sizeof(cmd)); + } else { + NetSendLoPri((BYTE *)&cmd, sizeof(cmd)); + } +} + +void NetSendCmdLocParam1(BOOL bHiPri, BYTE bCmd, BYTE x, BYTE y, WORD wParam1) +{ + TCmdLocParam1 cmd; + + /// ASSERT: assert(x < DMAXX); + /// ASSERT: assert(y < DMAXY); + cmd.bCmd = bCmd; + cmd.x = x; + cmd.y = y; + cmd.wParam1 = wParam1; + + if(bHiPri) { + NetSendHiPri((BYTE *)&cmd, sizeof(cmd)); + } else { + NetSendLoPri((BYTE *)&cmd, sizeof(cmd)); + } +} + +void NetSendCmdLocParam2(BOOL bHiPri, BYTE bCmd, BYTE x, BYTE y, WORD wParam1, WORD wParam2) +{ + TCmdLocParam2 cmd; + + /// ASSERT: assert(x < DMAXX); + /// ASSERT: assert(y < DMAXY); + cmd.bCmd = bCmd; + cmd.x = x; + cmd.y = y; + cmd.wParam1 = wParam1; + cmd.wParam2 = wParam2; + + if(bHiPri) { + NetSendHiPri((BYTE *)&cmd, sizeof(cmd)); + } else { + NetSendLoPri((BYTE *)&cmd, sizeof(cmd)); + } +} + +void NetSendCmdLocParam3(BOOL bHiPri, BYTE bCmd, BYTE x, BYTE y, WORD wParam1, WORD wParam2, WORD wParam3) +{ + TCmdLocParam3 cmd; + + /// ASSERT: assert(x < DMAXX); + /// ASSERT: assert(y < DMAXY); + cmd.bCmd = bCmd; + cmd.x = x; + cmd.y = y; + cmd.wParam1 = wParam1; + cmd.wParam2 = wParam2; + cmd.wParam3 = wParam3; + + if(bHiPri) { + NetSendHiPri((BYTE *)&cmd, sizeof(cmd)); + } else { + NetSendLoPri((BYTE *)&cmd, sizeof(cmd)); + } +} + +void NetSendCmdParam1(BOOL bHiPri, BYTE bCmd, WORD wParam1) +{ + __declspec(align(1)) TCmdParam1 cmd; + + cmd.bCmd = bCmd; + cmd.wParam1 = wParam1; + + if(bHiPri) { + NetSendHiPri((BYTE *)&cmd, sizeof(cmd)); + } else { + NetSendLoPri((BYTE *)&cmd, sizeof(cmd)); + } +} + +void NetSendCmdParam2(BOOL bHiPri, BYTE bCmd, WORD wParam1, WORD wParam2) +{ + TCmdParam2 cmd; + + cmd.bCmd = bCmd; + cmd.wParam1 = wParam1; + cmd.wParam2 = wParam2; + + if(bHiPri) { + NetSendHiPri((BYTE *)&cmd, sizeof(cmd)); + } else { + NetSendLoPri((BYTE *)&cmd, sizeof(cmd)); + } +} + +void NetSendCmdParam3(BOOL bHiPri, BYTE bCmd, WORD wParam1, WORD wParam2, WORD wParam3) +{ + TCmdParam3 cmd; + + cmd.bCmd = bCmd; + cmd.wParam1 = wParam1; + cmd.wParam2 = wParam2; + cmd.wParam3 = wParam3; + + if(bHiPri) { + NetSendHiPri((BYTE *)&cmd, sizeof(cmd)); + } else { + NetSendLoPri((BYTE *)&cmd, sizeof(cmd)); + } +} + +void NetSendCmdQuest(BOOL bHiPri, BYTE q) +{ + TCmdQuest cmd; + + cmd.bCmd = CMD_SYNCQUEST; + cmd.q = q; + cmd.qstate = quests[q]._qactive; + cmd.qlog = quests[q]._qlog; + cmd.qvar1 = quests[q]._qvar1; + + if(bHiPri) { + NetSendHiPri((BYTE *)&cmd, sizeof(cmd)); + } else { + NetSendLoPri((BYTE *)&cmd, sizeof(cmd)); + } +} + +void NetSendCmdGItem(BOOL bHiPri, BYTE bCmd, BYTE mast, BYTE pnum, BYTE ii) +{ + TCmdGItem cmd; + + /// ASSERT: assert(ii < MAXITEMS); + /// ASSERT: assert(pnum < MAX_PLRS); + cmd.bCmd = bCmd; + cmd.bPnum = pnum; + cmd.bMaster = mast; + cmd.bLevel = currlevel; + cmd.bCursitem = ii; + cmd.dwTime = 0; + cmd.x = item[ii]._ix; + cmd.y = item[ii]._iy; + cmd.wIndx = item[ii].IDidx; + + if(item[ii].IDidx == IDI_EAR) { + cmd.wCI = item[ii]._iName[7] << 8 | item[ii]._iName[8]; + cmd.dwSeed = item[ii]._iName[9] << 24 | item[ii]._iName[10] << 16 | item[ii]._iName[11] << 8 | item[ii]._iName[12]; + cmd.bId = item[ii]._iName[13]; + cmd.bDur = item[ii]._iName[14]; + cmd.bMDur = item[ii]._iName[15]; + cmd.bCh = item[ii]._iName[16]; + cmd.bMCh = item[ii]._iName[17]; + cmd.wValue = item[ii]._ivalue | item[ii]._iName[18] << 8 | ((item[ii]._iCurs - 19) << 6); + cmd.dwBuff = item[ii]._iName[19] << 24 | item[ii]._iName[20] << 16 | item[ii]._iName[21] << 8 | item[ii]._iName[22]; + } else { + cmd.wCI = item[ii]._iCreateInfo; + cmd.dwSeed = item[ii]._iSeed; + cmd.bId = item[ii]._iIdentified; + cmd.bDur = item[ii]._iDurability; + cmd.bMDur = item[ii]._iMaxDur; + cmd.bCh = item[ii]._iCharges; + cmd.bMCh = item[ii]._iMaxCharges; + cmd.wValue = item[ii]._ivalue; + } + + if(bHiPri) { + NetSendHiPri((BYTE *)&cmd, sizeof(cmd)); + } else { + NetSendLoPri((BYTE *)&cmd, sizeof(cmd)); + } +} + +void NetSendCmdGItem2(BOOL usonly, BYTE bCmd, BYTE mast, BYTE pnum, const TCmdGItem *p) +{ + int nTicks; + TCmdGItem cmd; + + /// ASSERT: assert(pnum < MAX_PLRS); + /// ASSERT: assert(p != NULL); + memcpy(&cmd, p, sizeof(cmd)); + cmd.bCmd = bCmd; + cmd.bPnum = pnum; + cmd.bMaster = mast; + + if(!usonly) { + cmd.dwTime = 0; + NetSendHiPri((BYTE *)&cmd, sizeof(cmd)); + return; + } + + nTicks = GetTickCount(); + if(cmd.dwTime == 0) { + cmd.dwTime = nTicks; + } else if(nTicks - cmd.dwTime > 5000) { + return; + } + + multi_msg_add((BYTE *)&cmd, sizeof(cmd)); +} + +BOOL NetSendCmdReq2(BYTE bCmd, BYTE mast, BYTE pnum, const TCmdGItem *p) +{ + int nTicks; + TCmdGItem cmd; + + /// ASSERT: assert(pnum < MAX_PLRS); + /// ASSERT: assert(p != NULL); + memcpy(&cmd, p, sizeof(cmd)); + cmd.bCmd = bCmd; + cmd.bPnum = pnum; + cmd.bMaster = mast; + + nTicks = GetTickCount(); + if(cmd.dwTime == 0) { + cmd.dwTime = nTicks; + } else if(nTicks - cmd.dwTime > 5000) { + return FALSE; + } + + multi_msg_add((BYTE *)&cmd, sizeof(cmd)); + return TRUE; +} + +void NetSendCmdExtra(const TCmdGItem *p) +{ + TCmdGItem cmd; + + /// ASSERT: assert(p != NULL); + memcpy(&cmd, p, sizeof(cmd)); + cmd.bCmd = CMD_ITEMEXTRA; + cmd.dwTime = 0; + + NetSendHiPri((BYTE *)&cmd, sizeof(cmd)); +} + +void NetSendCmdPItem(BOOL bHiPri, BYTE bCmd, BYTE x, BYTE y) +{ + TCmdPItem cmd; + + /// ASSERT: assert(x < DMAXX); + /// ASSERT: assert(y < DMAXY); + cmd.bCmd = bCmd; + cmd.x = x; + cmd.y = y; + cmd.wIndx = plr[myplr].HoldItem.IDidx; + + if(plr[myplr].HoldItem.IDidx == IDI_EAR) { + cmd.wCI = plr[myplr].HoldItem._iName[7] << 8 | plr[myplr].HoldItem._iName[8]; + cmd.dwSeed = plr[myplr].HoldItem._iName[9] << 24 + | plr[myplr].HoldItem._iName[10] << 16 + | plr[myplr].HoldItem._iName[11] << 8 + | plr[myplr].HoldItem._iName[12]; + cmd.bId = plr[myplr].HoldItem._iName[13]; + cmd.bDur = plr[myplr].HoldItem._iName[14]; + cmd.bMDur = plr[myplr].HoldItem._iName[15]; + cmd.bCh = plr[myplr].HoldItem._iName[16]; + cmd.bMCh = plr[myplr].HoldItem._iName[17]; + cmd.wValue = plr[myplr].HoldItem._ivalue | plr[myplr].HoldItem._iName[18] << 8 | ((plr[myplr].HoldItem._iCurs - 19) << 6); + cmd.dwBuff = plr[myplr].HoldItem._iName[19] << 24 + | plr[myplr].HoldItem._iName[20] << 16 + | plr[myplr].HoldItem._iName[21] << 8 + | plr[myplr].HoldItem._iName[22]; + } else { + cmd.wCI = plr[myplr].HoldItem._iCreateInfo; + cmd.dwSeed = plr[myplr].HoldItem._iSeed; + cmd.bId = plr[myplr].HoldItem._iIdentified; + cmd.bDur = plr[myplr].HoldItem._iDurability; + cmd.bMDur = plr[myplr].HoldItem._iMaxDur; + cmd.bCh = plr[myplr].HoldItem._iCharges; + cmd.bMCh = plr[myplr].HoldItem._iMaxCharges; + cmd.wValue = plr[myplr].HoldItem._ivalue; + } + + if(bHiPri) { + NetSendHiPri((BYTE *)&cmd, sizeof(cmd)); + } else { + NetSendLoPri((BYTE *)&cmd, sizeof(cmd)); + } +} + +void NetSendCmdChItem(BOOL bHiPri, BYTE bLoc) +{ + TCmdChItem cmd; + + cmd.bCmd = CMD_CHANGEPLRITEMS; + cmd.bLoc = bLoc; + cmd.wIndx = plr[myplr].HoldItem.IDidx; + cmd.wCI = plr[myplr].HoldItem._iCreateInfo; + cmd.dwSeed = plr[myplr].HoldItem._iSeed; + cmd.bId = plr[myplr].HoldItem._iIdentified; + + if(bHiPri) { + NetSendHiPri((BYTE *)&cmd, sizeof(cmd)); + } else { + NetSendLoPri((BYTE *)&cmd, sizeof(cmd)); + } +} + +void NetSendCmdDelItem(BOOL bHiPri, BYTE bLoc) +{ + TCmdDelItem cmd; + + cmd.bCmd = CMD_DELPLRITEMS; + cmd.bLoc = bLoc; + + if(bHiPri) { + NetSendHiPri((BYTE *)&cmd, sizeof(cmd)); + } else { + NetSendLoPri((BYTE *)&cmd, sizeof(cmd)); + } +} + +void NetSendCmdDItem(BOOL bHiPri, int ii) +{ + TCmdPItem cmd; + + /// ASSERT: assert((DWORD)ii < MAXITEMS); + cmd.bCmd = CMD_DROPITEM; + cmd.x = item[ii]._ix; + cmd.y = item[ii]._iy; + cmd.wIndx = item[ii].IDidx; + + if(item[ii].IDidx == IDI_EAR) { + cmd.wCI = item[ii]._iName[7] << 8 | item[ii]._iName[8]; + cmd.dwSeed = item[ii]._iName[9] << 24 | item[ii]._iName[10] << 16 | item[ii]._iName[11] << 8 | item[ii]._iName[12]; + cmd.bId = item[ii]._iName[13]; + cmd.bDur = item[ii]._iName[14]; + cmd.bMDur = item[ii]._iName[15]; + cmd.bCh = item[ii]._iName[16]; + cmd.bMCh = item[ii]._iName[17]; + cmd.wValue = item[ii]._ivalue | item[ii]._iName[18] << 8 | ((item[ii]._iCurs - 19) << 6); + cmd.dwBuff = item[ii]._iName[19] << 24 | item[ii]._iName[20] << 16 | item[ii]._iName[21] << 8 | item[ii]._iName[22]; + } else { + cmd.wCI = item[ii]._iCreateInfo; + cmd.dwSeed = item[ii]._iSeed; + cmd.bId = item[ii]._iIdentified; + cmd.bDur = item[ii]._iDurability; + cmd.bMDur = item[ii]._iMaxDur; + cmd.bCh = item[ii]._iCharges; + cmd.bMCh = item[ii]._iMaxCharges; + cmd.wValue = item[ii]._ivalue; + } + + if(bHiPri) { + NetSendHiPri((BYTE *)&cmd, sizeof(cmd)); + } else { + NetSendLoPri((BYTE *)&cmd, sizeof(cmd)); + } +} + +void NetSendCmdDamage(BOOL bHiPri, BYTE bPlr, DWORD dwDam) +{ + TCmdDamage cmd; + + /// ASSERT: assert(bPlr < MAX_PLRS); + cmd.bCmd = CMD_PLRDAMAGE; + cmd.bPlr = bPlr; + cmd.dwDam = dwDam; + + if(bHiPri) { + NetSendHiPri((BYTE *)&cmd, sizeof(cmd)); + } else { + NetSendLoPri((BYTE *)&cmd, sizeof(cmd)); + } +} + +void NetSendCmdString(int msk, const char *pszStr) +{ + DWORD dwStrLen; + TCmdString cmd; + + /// ASSERT: assert(pszStr); + dwStrLen = strlen(pszStr); + /// ASSERT: assert(dwStrLen < sizeof(cmd.str)); + cmd.bCmd = CMD_STRING; + strcpy(cmd.str, pszStr); + + multi_send_msg_packet(msk, (BYTE *)&cmd, dwStrLen + 2); +} + +void delta_close_portal(int pnum) +{ + /// ASSERT: assert((DWORD)pnum < MAX_PLRS); + memset(&sgJunk.portal[pnum], 255, sizeof(sgJunk.portal[pnum])); + sgbDeltaChanged = 1; +} + +DWORD ParseCmd(int pnum, const TCmd *pCmd) +{ + static BYTE sbLastCmd; + + /// ASSERT: assert((DWORD)pnum < MAX_PLRS); + /// ASSERT: assert(pCmd != NULL); + + sbLastCmd = pCmd->bCmd; + + if(sgwPackPlrOffsetTbl[pnum] != 0 && sbLastCmd != CMD_ACK_PLRINFO && sbLastCmd != CMD_SEND_PLRINFO) { + return 0; + } + + switch(pCmd->bCmd) { + case CMD_SYNCDATA: + return On_SYNCDATA(pCmd, pnum); + case CMD_WALKXY: + return On_WALKXY(pCmd, pnum); + case CMD_ADDSTR: + return On_ADDSTR(pCmd, pnum); + case CMD_ADDDEX: + return On_ADDDEX(pCmd, pnum); + case CMD_ADDMAG: + return On_ADDMAG(pCmd, pnum); + case CMD_ADDVIT: + return On_ADDVIT(pCmd, pnum); + case CMD_SBSPELL: + return On_SBSPELL(pCmd, pnum); + case CMD_GOTOGETITEM: + return On_GOTOGETITEM(pCmd, pnum); + case CMD_REQUESTGITEM: + return On_REQUESTGITEM(pCmd, pnum); + case CMD_GETITEM: + return On_GETITEM(pCmd, pnum); + case CMD_GOTOAGETITEM: + return On_GOTOAGETITEM(pCmd, pnum); + case CMD_REQUESTAGITEM: + return On_REQUESTAGITEM(pCmd, pnum); + case CMD_AGETITEM: + return On_AGETITEM(pCmd, pnum); + case CMD_ITEMEXTRA: + return On_ITEMEXTRA(pCmd, pnum); + case CMD_PUTITEM: + return On_PUTITEM(pCmd, pnum); + case CMD_SYNCPUTITEM: + return On_SYNCPUTITEM(pCmd, pnum); + case CMD_RESPAWNITEM: + return On_RESPAWNITEM(pCmd, pnum); + case CMD_ATTACKXY: + return On_ATTACKXY(pCmd, pnum); + case CMD_SATTACKXY: + return On_SATTACKXY(pCmd, pnum); + case CMD_RATTACKXY: + return On_RATTACKXY(pCmd, pnum); + case CMD_SPELLXYD: + return On_SPELLXYD(pCmd, pnum); + case CMD_SPELLXY: + return On_SPELLXY(pCmd, pnum); + case CMD_TSPELLXY: + return On_TSPELLXY(pCmd, pnum); + case CMD_OPOBJXY: + return On_OPOBJXY(pCmd, pnum); + case CMD_DISARMXY: + return On_DISARMXY(pCmd, pnum); + case CMD_OPOBJT: + return On_OPOBJT(pCmd, pnum); + case CMD_ATTACKID: + return On_ATTACKID(pCmd, pnum); + case CMD_ATTACKPID: + return On_ATTACKPID(pCmd, pnum); + case CMD_RATTACKID: + return On_RATTACKID(pCmd, pnum); + case CMD_RATTACKPID: + return On_RATTACKPID(pCmd, pnum); + case CMD_SPELLID: + return On_SPELLID(pCmd, pnum); + case CMD_SPELLPID: + return On_SPELLPID(pCmd, pnum); + case CMD_TSPELLID: + return On_TSPELLID(pCmd, pnum); + case CMD_TSPELLPID: + return On_TSPELLPID(pCmd, pnum); + case CMD_KNOCKBACK: + return On_KNOCKBACK(pCmd, pnum); + case CMD_RESURRECT: + return On_RESURRECT(pCmd, pnum); + case CMD_HEALOTHER: + return On_HEALOTHER(pCmd, pnum); + case CMD_TALKXY: + return On_TALKXY(pCmd, pnum); + case CMD_DEBUG: + return On_DEBUG(pCmd, pnum); + case CMD_NEWLVL: + return On_NEWLVL(pCmd, pnum); + case CMD_WARP: + return On_WARP(pCmd, pnum); + case CMD_MONSTDEATH: + return On_MONSTDEATH(pCmd, pnum); + case CMD_KILLGOLEM: + return On_KILLGOLEM(pCmd, pnum); + case CMD_AWAKEGOLEM: + return On_AWAKEGOLEM(pCmd, pnum); + case CMD_MONSTDAMAGE: + return On_MONSTDAMAGE(pCmd, pnum); + case CMD_PLRDEAD: + return On_PLRDEAD(pCmd, pnum); + case CMD_PLRDAMAGE: + return On_PLRDAMAGE(pCmd, pnum); + case CMD_OPENDOOR: + return On_OPENDOOR(pCmd, pnum); + case CMD_CLOSEDOOR: + return On_CLOSEDOOR(pCmd, pnum); + case CMD_OPERATEOBJ: + return On_OPERATEOBJ(pCmd, pnum); + case CMD_PLROPOBJ: + return On_PLROPOBJ(pCmd, pnum); + case CMD_BREAKOBJ: + return On_BREAKOBJ(pCmd, pnum); + case CMD_CHANGEPLRITEMS: + return On_CHANGEPLRITEMS(pCmd, pnum); + case CMD_DELPLRITEMS: + return On_DELPLRITEMS(pCmd, pnum); + case CMD_PLRLEVEL: + return On_PLRLEVEL(pCmd, pnum); + case CMD_DROPITEM: + return On_DROPITEM(pCmd, pnum); + case CMD_ACK_PLRINFO: + return On_ACK_PLRINFO(pCmd, pnum); + case CMD_SEND_PLRINFO: + return On_SEND_PLRINFO(pCmd, pnum); + case CMD_PLAYER_JOINLEVEL: + return On_PLAYER_JOINLEVEL(pCmd, pnum); + case CMD_ACTIVATEPORTAL: + return On_ACTIVATEPORTAL(pCmd, pnum); + case CMD_DEACTIVATEPORTAL: + return On_DEACTIVATEPORTAL(pCmd, pnum); + case CMD_RETOWN: + return On_RETOWN(pCmd, pnum); + case CMD_SETSTR: + return On_SETSTR(pCmd, pnum); + case CMD_SETMAG: + return On_SETMAG(pCmd, pnum); + case CMD_SETDEX: + return On_SETDEX(pCmd, pnum); + case CMD_SETVIT: + return On_SETVIT(pCmd, pnum); + case CMD_STRING: + return On_STRING(pCmd, pnum); + case CMD_SYNCQUEST: + return On_SYNCQUEST(pCmd, pnum); + case CMD_ENDSHIELD: + return On_ENDSHIELD(pCmd, pnum); + case CMD_CHEAT_EXPERIENCE: + return On_CHEAT_EXPERIENCE(pCmd, pnum); + case CMD_CHEAT_SPELL_LEVEL: + return On_CHEAT_SPELL_LEVEL(pCmd, pnum); + case CMD_NOVA: + return On_NOVA(pCmd, pnum); + case CMD_SETSHIELD: + return On_SETSHIELD(pCmd, pnum); + case CMD_REMSHIELD: + return On_REMSHIELD(pCmd, pnum); + } + + if(pCmd->bCmd >= CMD_DLEVEL_0 && pCmd->bCmd <= CMD_DLEVEL_END) { + return On_DLEVEL(pnum, pCmd); + } + + SNetDropPlayer(pnum, 0x40000006); + return 0; +} + +DWORD On_DLEVEL(int pnum, const TCmd *pCmd) +{ + TCmdPlrInfoHdr *p; + + p = (TCmdPlrInfoHdr *)pCmd; + + if(gbDeltaSender != pnum) { + if(p->bCmd == CMD_DLEVEL_END) { + gbDeltaSender = pnum; + sgbRecvCmd = CMD_DLEVEL_END; + } else if(p->bCmd == CMD_DLEVEL_0 && p->wOffset == 0) { + gbDeltaSender = pnum; + sgbRecvCmd = CMD_DLEVEL_END; + } else { + return p->wBytes + sizeof(*p); + } + } + if(sgbRecvCmd == CMD_DLEVEL_END) { + if(p->bCmd == CMD_DLEVEL_END) { + sgbDeltaChunks = 20; + return p->wBytes + sizeof(*p); + } else if(p->bCmd == CMD_DLEVEL_0 && p->wOffset == 0) { + sgdwRecvOffset = 0; + sgbRecvCmd = p->bCmd; + } else { + return p->wBytes + sizeof(*p); + } + } else if(sgbRecvCmd != p->bCmd) { + DeltaImportData(sgbRecvCmd, sgdwRecvOffset); + if(p->bCmd == CMD_DLEVEL_END) { + sgbDeltaChunks = 20; + sgbRecvCmd = CMD_DLEVEL_END; + return p->wBytes + sizeof(*p); + } else { + sgdwRecvOffset = 0; + sgbRecvCmd = p->bCmd; + } + } + + /// ASSERT: assert(p->wOffset == sgdwRecvOffset); + memcpy(&sgRecvBuf[p->wOffset], &p[1], p->wBytes); + sgdwRecvOffset += p->wBytes; + return p->wBytes + sizeof(*p); +} + +void DeltaImportData(BYTE bCmd, DWORD dwReceive) +{ + BYTE bLevel; + BYTE *p; + + if(sgRecvBuf[0] != 0) { + PkwareDecompress(&sgRecvBuf[1], dwReceive, sizeof(sgRecvBuf) - 1); + } + + p = &sgRecvBuf[1]; + if(bCmd == CMD_DLEVEL_JUNK) { + DeltaImportJunk(p); + } else if(bCmd >= CMD_DLEVEL_0 && bCmd <= CMD_DLEVEL_16) { + bLevel = bCmd - CMD_DLEVEL_0; + p = DeltaImportItem(p, sgLevels[bLevel].item); + p = DeltaImportObject(p, sgLevels[bLevel].object); + p = DeltaImportMonster(p, sgLevels[bLevel].monster); + } else { + app_fatal("msg:1"); + } + + sgbDeltaChanged = 1; + sgbDeltaChunks++; +} + +BYTE *DeltaImportItem(BYTE *src, TCmdPItem *dst) +{ + int i; + + i = 0; + while(i < MAXITEMS) { + if(*src == 255) { + memset(dst, 255, sizeof(*dst)); + src++; + } else { + memcpy(dst, src, sizeof(*dst)); + src += sizeof(*dst); + } + i++; + dst++; + } + + return src; +} + +BYTE *DeltaImportObject(BYTE *src, DObjectStr *dst) +{ + memcpy(dst, src, sizeof(*dst) * MAXOBJECTS); + return src + sizeof(*dst) * MAXOBJECTS; +} + +BYTE *DeltaImportMonster(BYTE *src, DMonsterStr *dst) +{ + int i; + + i = 0; + while(i < MAXMONSTERS) { + if(*src == 255) { + memset(dst, 255, sizeof(*dst)); + src++; + } else { + memcpy(dst, src, sizeof(*dst)); + src += sizeof(*dst); + } + i++; + dst++; + } + + return src; +} + +void DeltaImportJunk(BYTE *src) +{ + int i, deltaq; + + for(i = 0; i < MAXPORTAL; i++) { + if(*src == 255) { + memset(&sgJunk.portal[i], 255, sizeof(sgJunk.portal[i])); + src++; + SetPortalStats(i, FALSE, 0, 0, 0, 0); + } else { + memcpy(&sgJunk.portal[i], src, sizeof(sgJunk.portal[i])); + src += sizeof(sgJunk.portal[i]); + SetPortalStats(i, TRUE, sgJunk.portal[i].x, sgJunk.portal[i].y, sgJunk.portal[i].level, sgJunk.portal[i].ltype); + } + } + + deltaq = 0; + for(i = 0; i < MAXQUESTS; i++) { + if(questlist[i]._qflags & 1) { + memcpy(&sgJunk.quests[deltaq], src, sizeof(sgJunk.quests[deltaq])); + quests[i]._qlog = sgJunk.quests[deltaq].qlog; + quests[i]._qactive = sgJunk.quests[deltaq].qstate; + quests[i]._qvar1 = sgJunk.quests[deltaq].qvar1; + src += sizeof(sgJunk.quests[deltaq]); + deltaq++; + } + } +} + +DWORD On_SYNCDATA(const TCmd *pCmd, int pnum) +{ + return sync_update(pnum, (const BYTE *)pCmd); +} + +DWORD On_WALKXY(const TCmd *pCmd, int pnum) +{ + TCmdLoc *p; + + /// ASSERT: assert(gbBufferMsgs != BUFFER_PROCESS); + + if(gbBufferMsgs != 1 && currlevel == plr[pnum].plrlevel) { + p = (TCmdLoc *)pCmd; + ClrPlrPath(pnum); + MakePlrPath(pnum, p->x, p->y, TRUE); + plr[pnum].destAction = -1; + } + + return sizeof(*p); +} + +DWORD On_ADDSTR(const TCmd *pCmd, int pnum) +{ + TCmdParam1 *p; + + if(gbBufferMsgs == 1) { + msg_send_packet(pnum, pCmd, sizeof(*p)); + } else { + p = (TCmdParam1 *)pCmd; + if(p->wParam1 <= 256) { + ModifyPlrStr(pnum, p->wParam1); + } + } + + return sizeof(*p); +} + +DWORD On_ADDMAG(const TCmd *pCmd, int pnum) +{ + TCmdParam1 *p; + + if(gbBufferMsgs == 1) { + msg_send_packet(pnum, pCmd, sizeof(*p)); + } else { + p = (TCmdParam1 *)pCmd; + if(p->wParam1 <= 256) { + ModifyPlrMag(pnum, p->wParam1); + } + } + + return sizeof(*p); +} + +DWORD On_ADDDEX(const TCmd *pCmd, int pnum) +{ + TCmdParam1 *p; + + if(gbBufferMsgs == 1) { + msg_send_packet(pnum, pCmd, sizeof(*p)); + } else { + p = (TCmdParam1 *)pCmd; + if(p->wParam1 <= 256) { + ModifyPlrDex(pnum, p->wParam1); + } + } + + return sizeof(*p); +} + +DWORD On_ADDVIT(const TCmd *pCmd, int pnum) +{ + TCmdParam1 *p; + + if(gbBufferMsgs == 1) { + msg_send_packet(pnum, pCmd, sizeof(*p)); + } else { + p = (TCmdParam1 *)pCmd; + if(p->wParam1 <= 256) { + ModifyPlrVit(pnum, p->wParam1); + } + } + + return sizeof(*p); +} + +DWORD On_SBSPELL(const TCmd *pCmd, int pnum) +{ + TCmdParam1 *p; + + /// ASSERT: assert(gbBufferMsgs != BUFFER_PROCESS); + + if(gbBufferMsgs != 1) { + p = (TCmdParam1 *)pCmd; + if(currlevel != 0 || spelldata[p->wParam1].sTownSpell) { + plr[pnum]._pSpell = p->wParam1; + plr[pnum]._pSplType = plr[pnum]._pSBkSplType; + plr[pnum]._pSplFrom = 1; + plr[pnum].destAction = 12; + } else { + msg_errorf("%s has cast an illegal spell.", plr[pnum]._pName); + } + } + + return sizeof(*p); +} + +void __cdecl msg_errorf(const char *pszFmt, ...) +{ + DWORD dwTicks; + char szStr[256]; + va_list va; + + va_start(va, pszFmt); + + dwTicks = GetTickCount(); + if(dwTicks - msg_err_timer >= 5000) { + msg_err_timer = dwTicks; + vsprintf(szStr, pszFmt, va); + ErrorPlrMsg(szStr); + } +} + +DWORD On_GOTOGETITEM(const TCmd *pCmd, int pnum) +{ + TCmdLocParam1 *p; + + /// ASSERT: assert(gbBufferMsgs != BUFFER_PROCESS); + + if(gbBufferMsgs != 1 && currlevel == plr[pnum].plrlevel) { + p = (TCmdLocParam1 *)pCmd; + MakePlrPath(pnum, p->x, p->y, FALSE); + plr[pnum].destAction = 15; + plr[pnum].destParam1 = p->wParam1; + } + + return sizeof(*p); +} + +DWORD On_REQUESTGITEM(const TCmd *pCmd, int pnum) +{ + int ii; + TCmdGItem *p; + + /// ASSERT: assert(gbBufferMsgs != BUFFER_PROCESS); + + if(gbBufferMsgs != 1) { + p = (TCmdGItem *)pCmd; + if(i_own_level(plr[pnum].plrlevel)) { + /// ASSERT: assert(currlevel == plr[myplr].plrlevel); + if(GetItemRecord(p->dwSeed, p->wCI, p->wIndx)) { + ii = FindGetItem(p->wIndx, p->wCI, p->dwSeed); + if(ii != -1) { + NetSendCmdGItem2(FALSE, CMD_GETITEM, myplr, p->bPnum, p); + if(p->bPnum != myplr) { + SyncGetItem(p->x, p->y, p->wIndx, p->wCI, p->dwSeed); + } else { + InvGetItem(myplr, ii); + } + SetItemRecord(p->dwSeed, p->wCI, p->wIndx); + } else if(!NetSendCmdReq2(CMD_REQUESTGITEM, myplr, p->bPnum, p)) { + NetSendCmdExtra(p); + } + } + } + } + + return sizeof(*p); +} + +BOOL i_own_level(int nReqLevel) +{ + int i; + + for(i = 0; i < MAX_PLRS; i++) { + if(!plr[i].plractive || plr[i]._pLvlChanging || plr[i].plrlevel != nReqLevel) { + continue; + } + if(i != myplr || gbBufferMsgs == 0) { + break; + } + } + + return i == myplr; +} + +DWORD On_GETITEM(const TCmd *pCmd, int pnum) +{ + int nIndex, hitem; + TCmdGItem *p; + + if(gbBufferMsgs == 1) { + msg_send_packet(pnum, pCmd, sizeof(*p)); + } else { + p = (TCmdGItem *)pCmd; + nIndex = FindGetItem(p->wIndx, p->wCI, p->dwSeed); + if(delta_get_item(p, p->bLevel)) { + if((currlevel == p->bLevel || p->bPnum == myplr) && p->bMaster != myplr) { + if(p->bPnum == myplr) { + if(currlevel != p->bLevel) { + hitem = SyncPutItem( + myplr, + plr[myplr].WorldX, + plr[myplr].WorldY, + p->wIndx, + p->wCI, + p->dwSeed, + p->bId, + p->bDur, + p->bMDur, + p->bCh, + p->bMCh, + p->wValue, + p->dwBuff); + if(hitem != -1) { + InvGetItem(myplr, hitem); + } + } else { + InvGetItem(myplr, nIndex); + } +#if 0 + item_droplog_debug( + "%d: local plr get at (%d,%d) ndx %d ci %d seed %d\r\n", + myplr, + p->x, + p->y, + p->wIndx, + p->wCI, + p->dwSeed); +#endif + } else { + SyncGetItem(p->x, p->y, p->wIndx, p->wCI, p->dwSeed); +#if 0 + item_droplog_debug( + "%d: remote plr %d get at (%d,%d) ndx %d ci %d seed %d\r\n", + myplr, + p->bPnum, + p->x, + p->y, + p->wIndx, + p->wCI, + p->dwSeed); +#endif + } + } + } else { + NetSendCmdGItem2(TRUE, CMD_GETITEM, p->bMaster, p->bPnum, p); +#if 0 + item_droplog_debug( + "%d: repost get at (%d,%d) ndx %d ci %d seed %d master\r\n", + myplr, + p->x, + p->y, + p->wIndx, + p->wCI, + p->dwSeed, + p->bMaster); +#endif + } + } + + return sizeof(*p); +} + +BOOL delta_get_item(const TCmdGItem *pI, BYTE bLevel) +{ + int i; + TCmdPItem *pD; + + if(gbMaxPlayers == 1) { + return TRUE; + } + + /// ASSERT: assert(pI != NULL); + /// ASSERT: assert(bLevel < NUMLEVELS); + + pD = sgLevels[bLevel].item; + i = 0; + while(i < MAXITEMS) { + if(pD->bCmd != 255 && pD->wIndx == pI->wIndx && pD->wCI == pI->wCI && pD->dwSeed == pI->dwSeed) { + if(pD->bCmd == CMD_WALKXY) { + return TRUE; + } else if(pD->bCmd == CMD_STAND) { + sgbDeltaChanged = 1; + pD->bCmd = CMD_WALKXY; + return TRUE; + } else if(pD->bCmd == CMD_ACK_PLRINFO) { + sgbDeltaChanged = 1; + pD->bCmd = 255; + return TRUE; + } else { + app_fatal("delta:1"); + } + break; + } + i++; + pD++; + } + + if(!(pI->wCI & 0x8000)) { + return FALSE; + } + + pD = sgLevels[bLevel].item; + i = 0; + while(i < MAXITEMS) { + if(pD->bCmd == 255) { + sgbDeltaChanged = 1; + pD->bCmd = CMD_WALKXY; + pD->x = pI->x; + pD->y = pI->y; + pD->wIndx = pI->wIndx; + pD->wCI = pI->wCI; + pD->dwSeed = pI->dwSeed; + pD->bId = pI->bId; + pD->bDur = pI->bDur; + pD->bMDur = pI->bMDur; + pD->bCh = pI->bCh; + pD->bMCh = pI->bMCh; + pD->wValue = pI->wValue; + pD->dwBuff = pI->dwBuff; + return TRUE; + } + i++; + pD++; + } + + return TRUE; +} + +DWORD On_GOTOAGETITEM(const TCmd *pCmd, int pnum) +{ + TCmdLocParam1 *p; + + /// ASSERT: assert(gbBufferMsgs != BUFFER_PROCESS); + + if(gbBufferMsgs != 1 && currlevel == plr[pnum].plrlevel) { + p = (TCmdLocParam1 *)pCmd; + MakePlrPath(pnum, p->x, p->y, FALSE); + plr[pnum].destAction = 16; + plr[pnum].destParam1 = p->wParam1; + } + + return sizeof(*p); +} + +DWORD On_REQUESTAGITEM(const TCmd *pCmd, int pnum) +{ + int ii; + TCmdGItem *p; + + /// ASSERT: assert(gbBufferMsgs != BUFFER_PROCESS); + + if(gbBufferMsgs != 1) { + p = (TCmdGItem *)pCmd; + if(i_own_level(plr[pnum].plrlevel)) { + /// ASSERT: assert(currlevel == plr[myplr].plrlevel); + if(GetItemRecord(p->dwSeed, p->wCI, p->wIndx)) { + ii = FindGetItem(p->wIndx, p->wCI, p->dwSeed); + if(ii != -1) { + NetSendCmdGItem2(FALSE, CMD_AGETITEM, myplr, p->bPnum, p); + if(p->bPnum != myplr) { + SyncGetItem(p->x, p->y, p->wIndx, p->wCI, p->dwSeed); + } else { + AutoGetItem(myplr, p->bCursitem); + } + SetItemRecord(p->dwSeed, p->wCI, p->wIndx); + } else if(!NetSendCmdReq2(CMD_REQUESTAGITEM, myplr, p->bPnum, p)) { + NetSendCmdExtra(p); + } + } + } + } + + return sizeof(*p); +} + +DWORD On_AGETITEM(const TCmd *pCmd, int pnum) +{ + int nIndex, hitem; + TCmdGItem *p; + + if(gbBufferMsgs == 1) { + msg_send_packet(pnum, pCmd, sizeof(*p)); + } else { + p = (TCmdGItem *)pCmd; + nIndex = FindGetItem(p->wIndx, p->wCI, p->dwSeed); /// BUGFIX: useless call, remove + if(delta_get_item(p, p->bLevel)) { + if((currlevel == p->bLevel || p->bPnum == myplr) && p->bMaster != myplr) { + if(p->bPnum == myplr) { + if(currlevel != p->bLevel) { + hitem = SyncPutItem( + myplr, + plr[myplr].WorldX, + plr[myplr].WorldY, + p->wIndx, + p->wCI, + p->dwSeed, + p->bId, + p->bDur, + p->bMDur, + p->bCh, + p->bMCh, + p->wValue, + p->dwBuff); + if(hitem != -1) { + AutoGetItem(myplr, hitem); + } + } else { + AutoGetItem(myplr, p->bCursitem); + } + } else { + SyncGetItem(p->x, p->y, p->wIndx, p->wCI, p->dwSeed); + } + } + } else { + NetSendCmdGItem2(TRUE, CMD_AGETITEM, p->bMaster, p->bPnum, p); + } + } + + return sizeof(*p); +} + +DWORD On_ITEMEXTRA(const TCmd *pCmd, int pnum) +{ + TCmdGItem *p; + + if(gbBufferMsgs == 1) { + msg_send_packet(pnum, pCmd, sizeof(*p)); + } else { + p = (TCmdGItem *)pCmd; + delta_get_item(p, p->bLevel); + if(currlevel == plr[pnum].plrlevel) { + SyncGetItem(p->x, p->y, p->wIndx, p->wCI, p->dwSeed); + } + } + + return sizeof(*p); +} + +DWORD On_PUTITEM(const TCmd *pCmd, int pnum) +{ + int ii; + TCmdPItem *p; + + if(gbBufferMsgs == 1) { + msg_send_packet(pnum, pCmd, sizeof(*p)); + } else { + p = (TCmdPItem *)pCmd; + if(currlevel == plr[pnum].plrlevel) { + if(pnum == myplr) { + ii = InvPutItem(pnum, p->x, p->y); + } else { + ii = SyncPutItem( + pnum, + p->x, + p->y, + p->wIndx, + p->wCI, + p->dwSeed, + p->bId, + p->bDur, + p->bMDur, + p->bCh, + p->bMCh, + p->wValue, + p->dwBuff); + } + if(ii != -1) { + PutItemRecord(p->dwSeed, p->wCI, p->wIndx); + delta_put_item(p, item[ii]._ix, item[ii]._iy, plr[pnum].plrlevel); + check_update_plr(pnum); + } + return sizeof(*p); + } + PutItemRecord(p->dwSeed, p->wCI, p->wIndx); + delta_put_item(p, p->x, p->y, plr[pnum].plrlevel); + check_update_plr(pnum); + } + + return sizeof(*p); +} + +void delta_put_item(const TCmdPItem *pI, int x, int y, BYTE bLevel) +{ + int i; + TCmdPItem *pD; + + if(gbMaxPlayers == 1) { + return; + } + + /// ASSERT: assert(pI != NULL); + /// ASSERT: assert(x < DMAXX); + /// ASSERT: assert(y < DMAXY); + /// ASSERT: assert(bLevel < NUMLEVELS); + + pD = sgLevels[bLevel].item; + i = 0; + while(i < MAXITEMS) { + if(pD->bCmd != CMD_WALKXY && pD->bCmd != 255) { + if(pD->wIndx == pI->wIndx && pD->wCI == pI->wCI && pD->dwSeed == pI->dwSeed) { + if(pD->bCmd == CMD_ACK_PLRINFO) { + return; + } + app_fatal("Trying to drop a floor item?"); + } + } + i++; + pD++; + } + + pD = sgLevels[bLevel].item; + i = 0; + while(i < MAXITEMS) { + if(pD->bCmd == 255) { + sgbDeltaChanged = 1; + memcpy(pD, pI, sizeof(*pI)); + pD->bCmd = CMD_ACK_PLRINFO; + pD->x = x; + pD->y = y; + return; + } + i++; + pD++; + } +} + +void check_update_plr(int pnum) +{ + if(gbMaxPlayers == 1) { + return; + } + + /// ASSERT: assert((DWORD)pnum < MAX_PLRS); + if(pnum == myplr) { + pfile_update(TRUE); + } +} + +DWORD On_SYNCPUTITEM(const TCmd *pCmd, int pnum) +{ + int ii; + TCmdPItem *p; + + if(gbBufferMsgs == 1) { + msg_send_packet(pnum, pCmd, sizeof(*p)); + } else { + p = (TCmdPItem *)pCmd; + if(currlevel == plr[pnum].plrlevel) { + ii = SyncPutItem( + pnum, + p->x, + p->y, + p->wIndx, + p->wCI, + p->dwSeed, + p->bId, + p->bDur, + p->bMDur, + p->bCh, + p->bMCh, + p->wValue, + p->dwBuff); + if(ii != -1) { + PutItemRecord(p->dwSeed, p->wCI, p->wIndx); + delta_put_item(p, item[ii]._ix, item[ii]._iy, plr[pnum].plrlevel); + check_update_plr(pnum); + } + return sizeof(*p); + } + PutItemRecord(p->dwSeed, p->wCI, p->wIndx); + delta_put_item(p, p->x, p->y, plr[pnum].plrlevel); + check_update_plr(pnum); + } + + return sizeof(*p); +} + +DWORD On_RESPAWNITEM(const TCmd *pCmd, int pnum) +{ + int ii; + TCmdPItem *p; + + if(gbBufferMsgs == 1) { + msg_send_packet(pnum, pCmd, sizeof(*p)); + } else { + p = (TCmdPItem *)pCmd; + if(currlevel == plr[pnum].plrlevel && pnum != myplr) { + ii = SyncPutItem( + pnum, + p->x, + p->y, + p->wIndx, + p->wCI, + p->dwSeed, + p->bId, + p->bDur, + p->bMDur, + p->bCh, + p->bMCh, + p->wValue, + p->dwBuff); + } + PutItemRecord(p->dwSeed, p->wCI, p->wIndx); + delta_put_item(p, p->x, p->y, plr[pnum].plrlevel); + } + + return sizeof(*p); +} + +DWORD On_ATTACKXY(const TCmd *pCmd, int pnum) +{ + TCmdLoc *p; + + /// ASSERT: assert(gbBufferMsgs != BUFFER_PROCESS); + + if(gbBufferMsgs != 1 && currlevel == plr[pnum].plrlevel) { + p = (TCmdLoc *)pCmd; + MakePlrPath(pnum, p->x, p->y, FALSE); + plr[pnum].destAction = 9; + plr[pnum].destParam1 = p->x; + plr[pnum].destParam2 = p->y; + } + + return sizeof(*p); +} + +DWORD On_SATTACKXY(const TCmd *pCmd, int pnum) +{ + TCmdLoc *p; + + /// ASSERT: assert(gbBufferMsgs != BUFFER_PROCESS); + + if(gbBufferMsgs != 1 && currlevel == plr[pnum].plrlevel) { + p = (TCmdLoc *)pCmd; + ClrPlrPath(pnum); + plr[pnum].destAction = 9; + plr[pnum].destParam1 = p->x; + plr[pnum].destParam2 = p->y; + } + + return sizeof(*p); +} + +DWORD On_RATTACKXY(const TCmd *pCmd, int pnum) +{ + TCmdLoc *p; + + /// ASSERT: assert(gbBufferMsgs != BUFFER_PROCESS); + + if(gbBufferMsgs != 1 && currlevel == plr[pnum].plrlevel) { + p = (TCmdLoc *)pCmd; + ClrPlrPath(pnum); + plr[pnum].destAction = 10; + plr[pnum].destParam1 = p->x; + plr[pnum].destParam2 = p->y; + } + + return sizeof(*p); +} + +DWORD On_SPELLXYD(const TCmd *pCmd, int pnum) +{ + TCmdLocParam3 *p; + + /// ASSERT: assert(gbBufferMsgs != BUFFER_PROCESS); + + if(gbBufferMsgs != 1 && currlevel == plr[pnum].plrlevel) { + p = (TCmdLocParam3 *)pCmd; + if(currlevel != 0 || spelldata[p->wParam1].sTownSpell) { + ClrPlrPath(pnum); + plr[pnum].destAction = 26; + plr[pnum].destParam1 = p->x; + plr[pnum].destParam2 = p->y; + plr[pnum].destParam3 = p->wParam2; + plr[pnum].destParam4 = p->wParam3; + plr[pnum]._pSpell = p->wParam1; + plr[pnum]._pSplType = plr[pnum]._pRSplType; + plr[pnum]._pSplFrom = 0; + } else { + msg_errorf("%s has cast an illegal spell.", plr[pnum]._pName); + } + } + + return sizeof(*p); +} + +DWORD On_SPELLXY(const TCmd *pCmd, int pnum) +{ + TCmdLocParam2 *p; + + /// ASSERT: assert(gbBufferMsgs != BUFFER_PROCESS); + + if(gbBufferMsgs != 1 && currlevel == plr[pnum].plrlevel) { + p = (TCmdLocParam2 *)pCmd; + if(currlevel != 0 || spelldata[p->wParam1].sTownSpell) { + ClrPlrPath(pnum); + plr[pnum].destAction = 12; + plr[pnum].destParam1 = p->x; + plr[pnum].destParam2 = p->y; + plr[pnum].destParam3 = p->wParam2; + plr[pnum]._pSpell = p->wParam1; + plr[pnum]._pSplType = plr[pnum]._pRSplType; + plr[pnum]._pSplFrom = 0; + } else { + msg_errorf("%s has cast an illegal spell.", plr[pnum]._pName); + } + } + + return sizeof(*p); +} + +DWORD On_TSPELLXY(const TCmd *pCmd, int pnum) +{ + TCmdLocParam2 *p; + + /// ASSERT: assert(gbBufferMsgs != BUFFER_PROCESS); + + if(gbBufferMsgs != 1 && currlevel == plr[pnum].plrlevel) { + p = (TCmdLocParam2 *)pCmd; + if(currlevel != 0 || spelldata[p->wParam1].sTownSpell) { + ClrPlrPath(pnum); + plr[pnum].destAction = 12; + plr[pnum].destParam1 = p->x; + plr[pnum].destParam2 = p->y; + plr[pnum].destParam3 = p->wParam2; + plr[pnum]._pSpell = p->wParam1; + plr[pnum]._pSplType = plr[pnum]._pTSplType; + plr[pnum]._pSplFrom = 2; + } else { + msg_errorf("%s has cast an illegal spell.", plr[pnum]._pName); + } + } + + return sizeof(*p); +} + +DWORD On_OPOBJXY(const TCmd *pCmd, int pnum) +{ + TCmdLocParam1 *p; + + /// ASSERT: assert(gbBufferMsgs != BUFFER_PROCESS); + + if(gbBufferMsgs != 1 && currlevel == plr[pnum].plrlevel) { + p = (TCmdLocParam1 *)pCmd; + if(!object[p->wParam1]._oSolidFlag && !object[p->wParam1]._oDoorFlag) { + MakePlrPath(pnum, p->x, p->y, TRUE); + } else { + MakePlrPath(pnum, p->x, p->y, FALSE); + } + plr[pnum].destAction = 13; + plr[pnum].destParam1 = p->wParam1; + } + + return sizeof(*p); +} + +DWORD On_DISARMXY(const TCmd *pCmd, int pnum) +{ + TCmdLocParam1 *p; + + /// ASSERT: assert(gbBufferMsgs != BUFFER_PROCESS); + + if(gbBufferMsgs != 1 && currlevel == plr[pnum].plrlevel) { + p = (TCmdLocParam1 *)pCmd; + if(!object[p->wParam1]._oSolidFlag && !object[p->wParam1]._oDoorFlag) { + MakePlrPath(pnum, p->x, p->y, TRUE); + } else { + MakePlrPath(pnum, p->x, p->y, FALSE); + } + plr[pnum].destAction = 14; + plr[pnum].destParam1 = p->wParam1; + } + + return sizeof(*p); +} + +DWORD On_OPOBJT(const TCmd *pCmd, int pnum) +{ + TCmdParam1 *p; + + /// ASSERT: assert(gbBufferMsgs != BUFFER_PROCESS); + + if(gbBufferMsgs != 1 && currlevel == plr[pnum].plrlevel) { + p = (TCmdParam1 *)pCmd; + plr[pnum].destAction = 18; + plr[pnum].destParam1 = p->wParam1; + } + + return sizeof(*p); +} + +DWORD On_ATTACKID(const TCmd *pCmd, int pnum) +{ + int dx, dy; + TCmdParam1 *p; + + /// ASSERT: assert(gbBufferMsgs != BUFFER_PROCESS); + + if(gbBufferMsgs != 1 && currlevel == plr[pnum].plrlevel) { + p = (TCmdParam1 *)pCmd; + dx = abs(plr[pnum].WorldX - monster[p->wParam1]._mfutx); + dy = abs(plr[pnum].WorldY - monster[p->wParam1]._mfuty); + if(dx > 1 || dy > 1) { + MakePlrPath(pnum, monster[p->wParam1]._mfutx, monster[p->wParam1]._mfuty, FALSE); + } + plr[pnum].destAction = 20; + plr[pnum].destParam1 = p->wParam1; + } + + return sizeof(*p); +} + +DWORD On_ATTACKPID(const TCmd *pCmd, int pnum) +{ + TCmdParam1 *p; + + /// ASSERT: assert(gbBufferMsgs != BUFFER_PROCESS); + + if(gbBufferMsgs != 1 && currlevel == plr[pnum].plrlevel) { + p = (TCmdParam1 *)pCmd; + MakePlrPath(pnum, plr[p->wParam1]._px, plr[p->wParam1]._py, FALSE); + plr[pnum].destAction = 21; + plr[pnum].destParam1 = p->wParam1; + } + + return sizeof(*p); +} + +DWORD On_RATTACKID(const TCmd *pCmd, int pnum) +{ + TCmdParam1 *p; + + /// ASSERT: assert(gbBufferMsgs != BUFFER_PROCESS); + + if(gbBufferMsgs != 1 && currlevel == plr[pnum].plrlevel) { + p = (TCmdParam1 *)pCmd; + ClrPlrPath(pnum); + plr[pnum].destAction = 22; + plr[pnum].destParam1 = p->wParam1; + } + + return sizeof(*p); +} + +DWORD On_RATTACKPID(const TCmd *pCmd, int pnum) +{ + TCmdParam1 *p; + + /// ASSERT: assert(gbBufferMsgs != BUFFER_PROCESS); + + if(gbBufferMsgs != 1 && currlevel == plr[pnum].plrlevel) { + p = (TCmdParam1 *)pCmd; + ClrPlrPath(pnum); + plr[pnum].destAction = 23; + plr[pnum].destParam1 = p->wParam1; + } + + return sizeof(*p); +} + +DWORD On_SPELLID(const TCmd *pCmd, int pnum) +{ + TCmdParam3 *p; + + /// ASSERT: assert(gbBufferMsgs != BUFFER_PROCESS); + + if(gbBufferMsgs != 1 && currlevel == plr[pnum].plrlevel) { + p = (TCmdParam3 *)pCmd; + if(currlevel != 0 || spelldata[p->wParam2].sTownSpell) { + ClrPlrPath(pnum); + plr[pnum].destAction = 24; + plr[pnum].destParam1 = p->wParam1; + plr[pnum].destParam2 = p->wParam3; + plr[pnum]._pSpell = p->wParam2; + plr[pnum]._pSplType = plr[pnum]._pRSplType; + plr[pnum]._pSplFrom = 0; + } else { + msg_errorf("%s has cast an illegal spell.", plr[pnum]._pName); + } + } + + return sizeof(*p); +} + +DWORD On_SPELLPID(const TCmd *pCmd, int pnum) +{ + TCmdParam3 *p; + + /// ASSERT: assert(gbBufferMsgs != BUFFER_PROCESS); + + if(gbBufferMsgs != 1 && currlevel == plr[pnum].plrlevel) { + p = (TCmdParam3 *)pCmd; + if(currlevel != 0 || spelldata[p->wParam2].sTownSpell) { + ClrPlrPath(pnum); + plr[pnum].destAction = 25; + plr[pnum].destParam1 = p->wParam1; + plr[pnum].destParam2 = p->wParam3; + plr[pnum]._pSpell = p->wParam2; + plr[pnum]._pSplType = plr[pnum]._pRSplType; + plr[pnum]._pSplFrom = 0; + } else { + msg_errorf("%s has cast an illegal spell.", plr[pnum]._pName); + } + } + + return sizeof(*p); +} + +DWORD On_TSPELLID(const TCmd *pCmd, int pnum) +{ + TCmdParam3 *p; + + /// ASSERT: assert(gbBufferMsgs != BUFFER_PROCESS); + + if(gbBufferMsgs != 1 && currlevel == plr[pnum].plrlevel) { + p = (TCmdParam3 *)pCmd; + if(currlevel != 0 || spelldata[p->wParam2].sTownSpell) { + ClrPlrPath(pnum); + plr[pnum].destAction = 24; + plr[pnum].destParam1 = p->wParam1; + plr[pnum].destParam2 = p->wParam3; + plr[pnum]._pSpell = p->wParam2; + plr[pnum]._pSplType = plr[pnum]._pTSplType; + plr[pnum]._pSplFrom = 2; + } else { + msg_errorf("%s has cast an illegal spell.", plr[pnum]._pName); + } + } + + return sizeof(*p); +} + +DWORD On_TSPELLPID(const TCmd *pCmd, int pnum) +{ + TCmdParam3 *p; + + /// ASSERT: assert(gbBufferMsgs != BUFFER_PROCESS); + + if(gbBufferMsgs != 1 && currlevel == plr[pnum].plrlevel) { + p = (TCmdParam3 *)pCmd; + if(currlevel != 0 || spelldata[p->wParam2].sTownSpell) { + ClrPlrPath(pnum); + plr[pnum].destAction = 25; + plr[pnum].destParam1 = p->wParam1; + plr[pnum].destParam2 = p->wParam3; + plr[pnum]._pSpell = p->wParam2; + plr[pnum]._pSplType = plr[pnum]._pTSplType; + plr[pnum]._pSplFrom = 2; + } else { + msg_errorf("%s has cast an illegal spell.", plr[pnum]._pName); + } + } + + return sizeof(*p); +} + +DWORD On_KNOCKBACK(const TCmd *pCmd, int pnum) +{ + TCmdParam1 *p; + + if(gbBufferMsgs != 1) { + p = (TCmdParam1 *)pCmd; + if(currlevel == plr[pnum].plrlevel) { + M_GetKnockback(p->wParam1); + M_StartHit(p->wParam1, pnum, 0); + } + } + + return sizeof(*p); +} + +DWORD On_RESURRECT(const TCmd *pCmd, int pnum) +{ + TCmdParam1 *p; + + if(gbBufferMsgs == 1) { + msg_send_packet(pnum, pCmd, sizeof(*p)); + } else { + p = (TCmdParam1 *)pCmd; + DoResurrect(pnum, p->wParam1); + check_update_plr(pnum); + } + + return sizeof(*p); +} + +DWORD On_HEALOTHER(const TCmd *pCmd, int pnum) +{ + TCmdParam1 *p; + + if(gbBufferMsgs != 1 && currlevel == plr[pnum].plrlevel) { + p = (TCmdParam1 *)pCmd; + DoHealOther(pnum, p->wParam1); + } + + return sizeof(*p); +} + +DWORD On_TALKXY(const TCmd *pCmd, int pnum) +{ + TCmdLocParam1 *p; + + /// ASSERT: assert(gbBufferMsgs != BUFFER_PROCESS); + + if(gbBufferMsgs != 1 && currlevel == plr[pnum].plrlevel) { + p = (TCmdLocParam1 *)pCmd; + MakePlrPath(pnum, p->x, p->y, FALSE); + plr[pnum].destAction = 17; + plr[pnum].destParam1 = p->wParam1; + } + + return sizeof(*p); +} + +DWORD On_NEWLVL(const TCmd *pCmd, int pnum) +{ + TCmdParam2 *p; + + if(gbBufferMsgs == 1) { + msg_send_packet(pnum, pCmd, sizeof(*p)); + } else if(pnum != myplr) { + p = (TCmdParam2 *)pCmd; + StartNewLvl(pnum, p->wParam1, p->wParam2); + } + + return sizeof(*p); +} + +DWORD On_WARP(const TCmd *pCmd, int pnum) +{ + TCmdParam1 *p; + + if(gbBufferMsgs == 1) { + msg_send_packet(pnum, pCmd, sizeof(*p)); + } else { + p = (TCmdParam1 *)pCmd; + StartWarpLvl(pnum, p->wParam1); + if(pnum == myplr && pcurs >= CURSOR_FIRSTITEM) { + item[MAXITEMS] = plr[myplr].HoldItem; + AutoGetItem(myplr, MAXITEMS); + } + } + + return sizeof(*p); +} + +DWORD On_MONSTDEATH(const TCmd *pCmd, int pnum) +{ + TCmdLocParam1 *p; + + if(gbBufferMsgs == 1) { + msg_send_packet(pnum, pCmd, sizeof(*p)); + } else if(pnum != myplr) { + p = (TCmdLocParam1 *)pCmd; + if(currlevel == plr[pnum].plrlevel) { + M_SyncStartKill(p->wParam1, p->x, p->y, pnum); + } + delta_kill_monster(p->wParam1, p->x, p->y, plr[pnum].plrlevel); + } + + return sizeof(*p); +} + +DWORD On_KILLGOLEM(const TCmd *pCmd, int pnum) +{ + TCmdLocParam1 *p; + + if(gbBufferMsgs == 1) { + msg_send_packet(pnum, pCmd, sizeof(*p)); + } else if(pnum != myplr) { + p = (TCmdLocParam1 *)pCmd; + if(currlevel == p->wParam1) { + M_SyncStartKill(pnum, p->x, p->y, pnum); + } + delta_kill_monster(pnum, p->x, p->y, plr[pnum].plrlevel); + } + + return sizeof(*p); +} + +DWORD On_AWAKEGOLEM(const TCmd *pCmd, int pnum) +{ + int i, mi; + BOOL addok; + TCmdGolem *p; + + if(gbBufferMsgs == 1) { + msg_send_packet(pnum, pCmd, sizeof(*p)); + } else { + p = (TCmdGolem *)pCmd; + if(currlevel != plr[pnum].plrlevel) { + delta_sync_golem(p, pnum, p->_currlevel); + } else if(pnum != myplr) { + addok = TRUE; + for(i = 0; i < nummissiles; i++) { + mi = missileactive[i]; + if(missile[mi]._mitype == MIS_GOLEM && missile[mi]._misource == pnum) { + addok = FALSE; + } + } + if(addok) { + AddMissile(plr[pnum].WorldX, plr[pnum].WorldY, p->_mx, p->_my, p->_mdir, MIS_GOLEM, 0, pnum, 0, 1); + } + } + } + + return sizeof(*p); +} + +DWORD On_MONSTDAMAGE(const TCmd *pCmd, int pnum) +{ + TCmdParam2 *p; + + if(gbBufferMsgs == 1) { + msg_send_packet(pnum, pCmd, sizeof(*p)); + } else if(pnum != myplr) { + p = (TCmdParam2 *)pCmd; + if(currlevel == plr[pnum].plrlevel) { + monster[p->wParam1].mWhoHit |= 1 << pnum; + if(monster[p->wParam1]._mhitpoints != 0) { + monster[p->wParam1]._mhitpoints -= p->wParam2; + if(monster[p->wParam1]._mhitpoints >> 6 < 1) { + monster[p->wParam1]._mhitpoints = 64; + } + delta_monster_hp(p->wParam1, monster[p->wParam1]._mhitpoints, plr[pnum].plrlevel); + } + } + } + + return sizeof(*p); +} + +DWORD On_PLRDEAD(const TCmd *pCmd, int pnum) +{ + TCmdParam1 *p; + + if(gbBufferMsgs == 1) { + msg_send_packet(pnum, pCmd, sizeof(*p)); + } else { + p = (TCmdParam1 *)pCmd; + if(pnum != myplr) { + StartPlayerKill(pnum, p->wParam1); + } else { + check_update_plr(pnum); + } + } + + return sizeof(*p); +} + +DWORD On_PLRDAMAGE(const TCmd *pCmd, int pnum) +{ + TCmdDamage *p; + + /// ASSERT: assert(gbBufferMsgs != BUFFER_PROCESS); + + p = (TCmdDamage *)pCmd; + if(p->bPlr == myplr && currlevel != 0 && gbBufferMsgs != 1) { + if(currlevel == plr[pnum].plrlevel && p->dwDam <= 192000 && plr[myplr]._pHitPoints >> 6 > 0) { + drawhpflag = 1; + plr[myplr]._pHitPoints -= p->dwDam; + plr[myplr]._pHPBase -= p->dwDam; + if(plr[myplr]._pHitPoints > plr[myplr]._pMaxHP) { + plr[myplr]._pHitPoints = plr[myplr]._pMaxHP; + plr[myplr]._pHPBase = plr[myplr]._pMaxHPBase; + } + if(plr[myplr]._pHitPoints >> 6 <= 0) { + SyncPlrKill(myplr, 1); + } + } + } + + return sizeof(*p); +} + +DWORD On_OPENDOOR(const TCmd *pCmd, int pnum) +{ + TCmdParam1 *p; + + if(gbBufferMsgs == 1) { + msg_send_packet(pnum, pCmd, sizeof(*p)); + } else { + p = (TCmdParam1 *)pCmd; + if(currlevel == plr[pnum].plrlevel) { + SyncOpObject(pnum, CMD_OPENDOOR, p->wParam1); + } + delta_sync_object(p->wParam1, CMD_OPENDOOR, plr[pnum].plrlevel); + } + + return sizeof(*p); +} + +void delta_sync_object(int oi, BYTE bCmd, BYTE bLevel) +{ + DObjectStr *p; + + if(gbMaxPlayers == 1) { + return; + } + + /// ASSERT: assert((DWORD)oi < MAXOBJECTS); + /// ASSERT: assert(bLevel < NUMLEVELS); + + sgbDeltaChanged = 1; + p = &sgLevels[bLevel].object[oi]; + p->bCmd = bCmd; +} + +DWORD On_CLOSEDOOR(const TCmd *pCmd, int pnum) +{ + TCmdParam1 *p; + + if(gbBufferMsgs == 1) { + msg_send_packet(pnum, pCmd, sizeof(*p)); + } else { + p = (TCmdParam1 *)pCmd; + if(currlevel == plr[pnum].plrlevel) { + SyncOpObject(pnum, CMD_CLOSEDOOR, p->wParam1); + } + delta_sync_object(p->wParam1, CMD_CLOSEDOOR, plr[pnum].plrlevel); + } + + return sizeof(*p); +} + +DWORD On_OPERATEOBJ(const TCmd *pCmd, int pnum) +{ + TCmdParam1 *p; + + if(gbBufferMsgs == 1) { + msg_send_packet(pnum, pCmd, sizeof(*p)); + } else { + p = (TCmdParam1 *)pCmd; + if(currlevel == plr[pnum].plrlevel) { + SyncOpObject(pnum, CMD_OPERATEOBJ, p->wParam1); + } + delta_sync_object(p->wParam1, CMD_OPERATEOBJ, plr[pnum].plrlevel); + } + + return sizeof(*p); +} + +DWORD On_PLROPOBJ(const TCmd *pCmd, int pnum) +{ + TCmdParam2 *p; + + if(gbBufferMsgs == 1) { + msg_send_packet(pnum, pCmd, sizeof(*p)); + } else { + p = (TCmdParam2 *)pCmd; + if(currlevel == plr[pnum].plrlevel) { + SyncOpObject(p->wParam1, CMD_PLROPOBJ, p->wParam2); + } + delta_sync_object(p->wParam2, CMD_PLROPOBJ, plr[pnum].plrlevel); + } + + return sizeof(*p); +} + +DWORD On_BREAKOBJ(const TCmd *pCmd, int pnum) +{ + TCmdParam2 *p; + + if(gbBufferMsgs == 1) { + msg_send_packet(pnum, pCmd, sizeof(*p)); + } else { + p = (TCmdParam2 *)pCmd; + if(currlevel == plr[pnum].plrlevel) { + SyncBreakObj(p->wParam1, p->wParam2); + } + delta_sync_object(p->wParam2, CMD_BREAKOBJ, plr[pnum].plrlevel); + } + + return sizeof(*p); +} + +DWORD On_CHANGEPLRITEMS(const TCmd *pCmd, int pnum) +{ + TCmdChItem *p; + + if(gbBufferMsgs == 1) { + msg_send_packet(pnum, pCmd, sizeof(*p)); + } else { + p = (TCmdChItem *)pCmd; + if(pnum != myplr) { + CheckInvSwap(pnum, p->bLoc, p->wIndx, p->wCI, p->dwSeed, p->bId); + } + } + + return sizeof(*p); +} + +DWORD On_DELPLRITEMS(const TCmd *pCmd, int pnum) +{ + TCmdDelItem *p; + + if(gbBufferMsgs == 1) { + msg_send_packet(pnum, pCmd, sizeof(*p)); + } else { + p = (TCmdDelItem *)pCmd; + if(pnum != myplr) { + inv_update_rem_item(pnum, p->bLoc); + } + } + + return sizeof(*p); +} + +DWORD On_PLRLEVEL(const TCmd *pCmd, int pnum) +{ + TCmdParam1 *p; + + if(gbBufferMsgs == 1) { + msg_send_packet(pnum, pCmd, sizeof(*p)); + } else { + p = (TCmdParam1 *)pCmd; + if(p->wParam1 <= 51 && pnum != myplr) { + plr[pnum]._pLevel = p->wParam1; + } + } + + return sizeof(*p); +} + +DWORD On_DROPITEM(const TCmd *pCmd, int pnum) +{ + TCmdPItem *p; + + if(gbBufferMsgs == 1) { + msg_send_packet(pnum, pCmd, sizeof(*p)); + } else { + p = (TCmdPItem *)pCmd; + delta_put_item(p, p->x, p->y, plr[pnum].plrlevel); + } + + return sizeof(*p); +} + +DWORD On_SEND_PLRINFO(const TCmd *pCmd, int pnum) +{ + TCmdPlrInfoHdr *p; + + p = (TCmdPlrInfoHdr *)pCmd; + if(gbBufferMsgs == 1) { + msg_send_packet(pnum, pCmd, p->wBytes + sizeof(*p)); + } else { + recv_plrinfo(pnum, p, p->bCmd == CMD_ACK_PLRINFO); + } + + return p->wBytes + sizeof(*p); +} + +DWORD On_ACK_PLRINFO(const TCmd *pCmd, int pnum) +{ + return On_SEND_PLRINFO(pCmd, pnum); +} + +DWORD On_PLAYER_JOINLEVEL(const TCmd *pCmd, int pnum) +{ + TCmdLocParam1 *p; + + if(gbBufferMsgs == 1) { + msg_send_packet(pnum, pCmd, sizeof(*p)); + } else { + /// ASSERT: assert((DWORD)pnum < MAX_PLRS); + plr[pnum]._pLvlChanging = 0; + if(plr[pnum]._pName[0] == '\0') { +#ifdef _DEBUG + dumphist("(%d) received %d joinlevel before plrdata", myplr, pnum); +#endif + } else if(!plr[pnum].plractive) { + plr[pnum].plractive = 1; + gbActivePlayers++; + EventPlrMsg("Player '%s' (level %d) just joined the game", plr[pnum]._pName, plr[pnum]._pLevel); +#ifdef _DEBUG + dumphist("(%d) activating %d on joinlevel", myplr, pnum); +#endif + } + if(plr[pnum].plractive && myplr != pnum) { + p = (TCmdLocParam1 *)pCmd; + plr[pnum].WorldX = p->x; + plr[pnum].WorldY = p->y; + plr[pnum].plrlevel = p->wParam1; + plr[pnum]._pGFXLoad = 0; + if(currlevel == plr[pnum].plrlevel) { + LoadPlrGFX(pnum, 1); + SyncInitPlr(pnum); + if(plr[pnum]._pHitPoints >> 6 > 0) { + StartStand(pnum, 0); + } else { + plr[pnum]._pgfxnum = 0; + LoadPlrGFX(pnum, 128); + plr[pnum]._pmode = PM_DEATH; + NewPlrAnim(pnum, plr[pnum]._pDAnim[0], plr[pnum]._pDFrames, 1, plr[pnum]._pDWidth); + plr[pnum]._pAnimFrame = plr[pnum]._pAnimLen - 1; + plr[pnum]._pVar8 = 2 * plr[pnum]._pAnimLen; + dFlags[plr[pnum].WorldX][plr[pnum].WorldY] |= 4; + } + plr[pnum]._pvid = AddVision(plr[pnum].WorldX, plr[pnum].WorldY, plr[pnum]._pLightRad, pnum == myplr); + plr[pnum]._plid = -1; + } + } + } + + return sizeof(*p); +} + +DWORD On_ACTIVATEPORTAL(const TCmd *pCmd, int pnum) +{ + int i, mi; + BOOL addok; + TCmdLocParam3 *p; + + if(gbBufferMsgs == 1) { + msg_send_packet(pnum, pCmd, sizeof(*p)); + } else { + p = (TCmdLocParam3 *)pCmd; + ActivatePortal(pnum, p->x, p->y, p->wParam1, p->wParam2, p->wParam3); + if(pnum != myplr) { + if(currlevel == 0) { + AddInTownPortal(pnum); + } else if(currlevel == plr[pnum].plrlevel) { + addok = TRUE; + for(i = 0; i < nummissiles; i++) { + mi = missileactive[i]; + if(missile[mi]._mitype == MIS_TOWN && missile[mi]._misource == pnum) { + addok = FALSE; + } + } + if(addok) { + AddWarpMissile(pnum, p->x, p->y); + } + } else { + RemovePortalMissile(pnum); + } + } + delta_open_portal(pnum, p->x, p->y, p->wParam1, p->wParam2, p->wParam3); + } + + return sizeof(*p); +} + +void delta_open_portal(int pnum, BYTE x, BYTE y, BYTE bLevel, BYTE bLType, BYTE bSetLvl) +{ + /// ASSERT: assert((DWORD)pnum < MAX_PLRS); + /// ASSERT: assert(x < DMAXX); + /// ASSERT: assert(y < DMAXY); + /// ASSERT: assert(bLevel < NUMLEVELS); + + sgJunk.portal[pnum].x = x; + sgJunk.portal[pnum].y = y; + sgJunk.portal[pnum].level = bLevel; + sgJunk.portal[pnum].ltype = bLType; + sgJunk.portal[pnum].setlvl = bSetLvl; + sgbDeltaChanged = 1; +} + +DWORD On_DEACTIVATEPORTAL(const TCmd *pCmd, int pnum) +{ + if(gbBufferMsgs == 1) { + msg_send_packet(pnum, pCmd, sizeof(*pCmd)); + } else { + if(PortalOnLevel(pnum)) { + RemovePortalMissile(pnum); + } + DeactivatePortal(pnum); + delta_close_portal(pnum); + } + + return sizeof(*pCmd); +} + +DWORD On_RETOWN(const TCmd *pCmd, int pnum) +{ + if(gbBufferMsgs == 1) { + msg_send_packet(pnum, pCmd, sizeof(*pCmd)); + } else { + if(pnum == myplr) { + deathflag = 0; + gamemenu_off(); + } + RestartTownLvl(pnum); + } + + return sizeof(*pCmd); +} + +DWORD On_SETSTR(const TCmd *pCmd, int pnum) +{ + TCmdParam1 *p; + + if(gbBufferMsgs == 1) { + msg_send_packet(pnum, pCmd, sizeof(*p)); + } else { + p = (TCmdParam1 *)pCmd; + if(p->wParam1 <= 750 && pnum != myplr) { + SetPlrStr(pnum, p->wParam1); + } + } + + return sizeof(*p); +} + +DWORD On_SETDEX(const TCmd *pCmd, int pnum) +{ + TCmdParam1 *p; + + if(gbBufferMsgs == 1) { + msg_send_packet(pnum, pCmd, sizeof(*p)); + } else { + p = (TCmdParam1 *)pCmd; + if(p->wParam1 <= 750 && pnum != myplr) { + SetPlrDex(pnum, p->wParam1); + } + } + + return sizeof(*p); +} + +DWORD On_SETMAG(const TCmd *pCmd, int pnum) +{ + TCmdParam1 *p; + + if(gbBufferMsgs == 1) { + msg_send_packet(pnum, pCmd, sizeof(*p)); + } else { + p = (TCmdParam1 *)pCmd; + if(p->wParam1 <= 750 && pnum != myplr) { + SetPlrMag(pnum, p->wParam1); + } + } + + return sizeof(*p); +} + +DWORD On_SETVIT(const TCmd *pCmd, int pnum) +{ + TCmdParam1 *p; + + if(gbBufferMsgs == 1) { + msg_send_packet(pnum, pCmd, sizeof(*p)); + } else { + p = (TCmdParam1 *)pCmd; + if(p->wParam1 <= 750 && pnum != myplr) { + SetPlrVit(pnum, p->wParam1); + } + } + + return sizeof(*p); +} + +DWORD On_STRING(const TCmd *pCmd, int pnum) +{ + TCmdString *p; + + p = (TCmdString *)pCmd; + return On_STRING2(pnum, p); +} + +DWORD On_STRING2(int pnum, const TCmdString *p) +{ + int len; + + /// ASSERT: assert((DWORD)pnum < MAX_PLRS); + /// ASSERT: assert(p != NULL); + + len = strlen(p->str); + if(gbBufferMsgs == 0) { + SendPlrMsg(pnum, p->str); + } + + return len + 2; +} + +DWORD On_SYNCQUEST(const TCmd *pCmd, int pnum) +{ + TCmdQuest *p; + + if(gbBufferMsgs == 1) { + msg_send_packet(pnum, pCmd, sizeof(*p)); + } else { + p = (TCmdQuest *)pCmd; + if(pnum != myplr) { + SetMultiQuest(p->q, p->qstate, p->qlog, p->qvar1); + } + sgbDeltaChanged = 1; + } + + return sizeof(*p); +} + +DWORD On_ENDSHIELD(const TCmd *pCmd, int pnum) +{ + int i, mi; + + if(gbBufferMsgs != 1 && pnum != myplr && currlevel == plr[pnum].plrlevel) { + for(i = 0; i < nummissiles; i++) { + mi = missileactive[i]; + if(missile[mi]._mitype == MIS_MANASHIELD && missile[mi]._misource == pnum) { + ClearMissileSpot(mi); + DeleteMissile(mi, i); + } + } + } + + return sizeof(*pCmd); +} + +DWORD On_CHEAT_EXPERIENCE(const TCmd *pCmd, int pnum) +{ +#ifdef _DEBUG + if(gbBufferMsgs == 1) { + msg_send_packet(pnum, pCmd, sizeof(*pCmd)); + } else if(plr[pnum]._pLevel < 50) { + plr[pnum]._pExperience = plr[pnum]._pNextExper; + NextPlrLevel(pnum); + } +#endif + return sizeof(*pCmd); +} + +DWORD On_CHEAT_SPELL_LEVEL(const TCmd *pCmd, int pnum) +{ +#ifdef _DEBUG + if(gbBufferMsgs == 1) { + msg_send_packet(pnum, pCmd, sizeof(*pCmd)); + } else { + plr[pnum]._pSplLvl[plr[pnum]._pRSpell]++; + } +#endif + return sizeof(*pCmd); +} + +DWORD On_DEBUG(const TCmd *pCmd, int pnum) +{ + return sizeof(*pCmd); +} + +DWORD On_NOVA(const TCmd *pCmd, int pnum) +{ + TCmdLoc *p; + + if(gbBufferMsgs != 1 && currlevel == plr[pnum].plrlevel && pnum != myplr) { + p = (TCmdLoc *)pCmd; + ClrPlrPath(pnum); + plr[pnum]._pSpell = SPL_NOVA; + plr[pnum]._pSplType = 4; + plr[pnum]._pSplFrom = 3; + plr[pnum].destAction = 12; + plr[pnum].destParam1 = p->x; + plr[pnum].destParam2 = p->y; + } + + return sizeof(*p); +} + +DWORD On_SETSHIELD(const TCmd *pCmd, int pnum) +{ + if(gbBufferMsgs != 1) { + plr[pnum].pManaShield = 1; + } + + return sizeof(*pCmd); +} + +DWORD On_REMSHIELD(const TCmd *pCmd, int pnum) +{ + if(gbBufferMsgs != 1) { + plr[pnum].pManaShield = 0; + } + + return sizeof(*pCmd); +} diff --git a/2020_03_31/Source/msg.h b/2020_03_31/Source/msg.h new file mode 100644 index 00000000..1b48bba6 --- /dev/null +++ b/2020_03_31/Source/msg.h @@ -0,0 +1,158 @@ +//HEADER_GOES_HERE +#ifndef __MSG_H__ +#define __MSG_H__ + +extern int sgdwOwnerWait; // weak +extern int sgdwRecvOffset; // idb +extern int sgnCurrMegaPlayer; // weak +extern DLevel sgLevels[NUMLEVELS]; +extern TMegaPkt *sgpCurrPkt; +extern BYTE sgRecvBuf[4722]; +extern unsigned char sgbRecvCmd; // idb +extern LocalLevel sgLocals[NUMLEVELS]; +extern DJunk sgJunk; +extern TMegaPkt *sgpMegaPkt; +extern char sgbDeltaChanged; // weak +extern BYTE sgbDeltaChunks; // weak +extern int deltaload; // weak +extern char gbBufferMsgs; // weak +extern int dwRecCount; // weak +extern int msg_err_timer; // weak + +void msg_send_drop_pkt(int pnum, DWORD reason); +void msg_send_packet(int pnum, const void *pMsg, DWORD dwLen); +void msg_get_next_packet(); +BOOL msg_wait_resync(); +void msg_free_packets(); +int msg_wait_for_turns(); +void run_delta_info(); +void msg_pre_packet(); +void DeltaExportData(int pnum); +BYTE *DeltaExportItem(BYTE *dst, TCmdPItem *src); +BYTE *DeltaExportObject(BYTE *dst, DObjectStr *src); +BYTE *DeltaExportMonster(BYTE *dst, DMonsterStr *src); +BYTE *DeltaExportJunk(BYTE *dst); +DWORD msg_comp_level(BYTE *p, BYTE *dst); +void delta_init(); +void delta_kill_monster(int mi, BYTE x, BYTE y, BYTE bLevel); +void delta_monster_hp(int mi, long hp, BYTE bLevel); +void delta_sync_monster(const TSyncMonster *pSync, BYTE bLevel); +void delta_sync_golem(const TCmdGolem *pG, int pnum, BYTE bLevel); +void delta_leave_sync(BYTE bLevel); +BOOL delta_portal_inited(int i); +BOOL delta_quest_inited(int i); +void DeltaAddItem(int ii); +void DeltaSaveLevel(); +void DeltaLoadLevel(); +void NetSendCmd(BOOL bHiPri, BYTE bCmd); +void NetSendCmdGolem(BYTE mx, BYTE my, BYTE dir, BYTE menemy, long hp, BYTE cl); +void NetSendCmdLoc(BOOL bHiPri, BYTE bCmd, BYTE x, BYTE y); +void NetSendCmdLocParam1(BOOL bHiPri, BYTE bCmd, BYTE x, BYTE y, WORD wParam1); +void NetSendCmdLocParam2(BOOL bHiPri, BYTE bCmd, BYTE x, BYTE y, WORD wParam1, WORD wParam2); +void NetSendCmdLocParam3(BOOL bHiPri, BYTE bCmd, BYTE x, BYTE y, WORD wParam1, WORD wParam2, WORD wParam3); +void NetSendCmdParam1(BOOL bHiPri, BYTE bCmd, WORD wParam1); +void NetSendCmdParam2(BOOL bHiPri, BYTE bCmd, WORD wParam1, WORD wParam2); +void NetSendCmdParam3(BOOL bHiPri, BYTE bCmd, WORD wParam1, WORD wParam2, WORD wParam3); +void NetSendCmdQuest(BOOL bHiPri, BYTE q); +void NetSendCmdGItem(BOOL bHiPri, BYTE bCmd, BYTE mast, BYTE pnum, BYTE ii); +void NetSendCmdGItem2(BOOL usonly, BYTE bCmd, BYTE mast, BYTE pnum, const TCmdGItem *p); +BOOL NetSendCmdReq2(BYTE bCmd, BYTE mast, BYTE pnum, const TCmdGItem *p); +void NetSendCmdExtra(const TCmdGItem *p); +void NetSendCmdPItem(BOOL bHiPri, BYTE bCmd, BYTE x, BYTE y); +void NetSendCmdChItem(BOOL bHiPri, BYTE bLoc); +void NetSendCmdDelItem(BOOL bHiPri, BYTE bLoc); +void NetSendCmdDItem(BOOL bHiPri, int ii); +void NetSendCmdDamage(BOOL bHiPri, BYTE bPlr, DWORD dwDam); +void NetSendCmdString(int msk, const char *pszStr); +void delta_close_portal(int pnum); +DWORD ParseCmd(int pnum, const TCmd *pCmd); +DWORD On_DLEVEL(int pnum, const TCmd *pCmd); +void DeltaImportData(BYTE bCmd, DWORD dwReceive); +BYTE *DeltaImportItem(BYTE *src, TCmdPItem *dst); +BYTE *DeltaImportObject(BYTE *src, DObjectStr *dst); +BYTE *DeltaImportMonster(BYTE *src, DMonsterStr *dst); +void DeltaImportJunk(BYTE *src); +DWORD On_SYNCDATA(const TCmd *pCmd, int pnum); +DWORD On_WALKXY(const TCmd *pCmd, int pnum); +DWORD On_ADDSTR(const TCmd *pCmd, int pnum); +DWORD On_ADDMAG(const TCmd *pCmd, int pnum); +DWORD On_ADDDEX(const TCmd *pCmd, int pnum); +DWORD On_ADDVIT(const TCmd *pCmd, int pnum); +DWORD On_SBSPELL(const TCmd *pCmd, int pnum); +void __cdecl msg_errorf(const char *pszFmt, ...); +DWORD On_GOTOGETITEM(const TCmd *pCmd, int pnum); +DWORD On_REQUESTGITEM(const TCmd *pCmd, int pnum); +BOOL i_own_level(int nReqLevel); +DWORD On_GETITEM(const TCmd *pCmd, int pnum); +BOOL delta_get_item(const TCmdGItem *pI, BYTE bLevel); +DWORD On_GOTOAGETITEM(const TCmd *pCmd, int pnum); +DWORD On_REQUESTAGITEM(const TCmd *pCmd, int pnum); +DWORD On_AGETITEM(const TCmd *pCmd, int pnum); +DWORD On_ITEMEXTRA(const TCmd *pCmd, int pnum); +DWORD On_PUTITEM(const TCmd *pCmd, int pnum); +void delta_put_item(const TCmdPItem *pI, int x, int y, BYTE bLevel); +void check_update_plr(int pnum); +DWORD On_SYNCPUTITEM(const TCmd *pCmd, int pnum); +DWORD On_RESPAWNITEM(const TCmd *pCmd, int pnum); +DWORD On_ATTACKXY(const TCmd *pCmd, int pnum); +DWORD On_SATTACKXY(const TCmd *pCmd, int pnum); +DWORD On_RATTACKXY(const TCmd *pCmd, int pnum); +DWORD On_SPELLXYD(const TCmd *pCmd, int pnum); +DWORD On_SPELLXY(const TCmd *pCmd, int pnum); +DWORD On_TSPELLXY(const TCmd *pCmd, int pnum); +DWORD On_OPOBJXY(const TCmd *pCmd, int pnum); +DWORD On_DISARMXY(const TCmd *pCmd, int pnum); +DWORD On_OPOBJT(const TCmd *pCmd, int pnum); +DWORD On_ATTACKID(const TCmd *pCmd, int pnum); +DWORD On_ATTACKPID(const TCmd *pCmd, int pnum); +DWORD On_RATTACKID(const TCmd *pCmd, int pnum); +DWORD On_RATTACKPID(const TCmd *pCmd, int pnum); +DWORD On_SPELLID(const TCmd *pCmd, int pnum); +DWORD On_SPELLPID(const TCmd *pCmd, int pnum); +DWORD On_TSPELLID(const TCmd *pCmd, int pnum); +DWORD On_TSPELLPID(const TCmd *pCmd, int pnum); +DWORD On_KNOCKBACK(const TCmd *pCmd, int pnum); +DWORD On_RESURRECT(const TCmd *pCmd, int pnum); +DWORD On_HEALOTHER(const TCmd *pCmd, int pnum); +DWORD On_TALKXY(const TCmd *pCmd, int pnum); +DWORD On_NEWLVL(const TCmd *pCmd, int pnum); +DWORD On_WARP(const TCmd *pCmd, int pnum); +DWORD On_MONSTDEATH(const TCmd *pCmd, int pnum); +DWORD On_KILLGOLEM(const TCmd *pCmd, int pnum); +DWORD On_AWAKEGOLEM(const TCmd *pCmd, int pnum); +DWORD On_MONSTDAMAGE(const TCmd *pCmd, int pnum); +DWORD On_PLRDEAD(const TCmd *pCmd, int pnum); +DWORD On_PLRDAMAGE(const TCmd *pCmd, int pnum); +DWORD On_OPENDOOR(const TCmd *pCmd, int pnum); +void delta_sync_object(int oi, BYTE bCmd, BYTE bLevel); +DWORD On_CLOSEDOOR(const TCmd *pCmd, int pnum); +DWORD On_OPERATEOBJ(const TCmd *pCmd, int pnum); +DWORD On_PLROPOBJ(const TCmd *pCmd, int pnum); +DWORD On_BREAKOBJ(const TCmd *pCmd, int pnum); +DWORD On_CHANGEPLRITEMS(const TCmd *pCmd, int pnum); +DWORD On_DELPLRITEMS(const TCmd *pCmd, int pnum); +DWORD On_PLRLEVEL(const TCmd *pCmd, int pnum); +DWORD On_DROPITEM(const TCmd *pCmd, int pnum); +DWORD On_SEND_PLRINFO(const TCmd *pCmd, int pnum); +DWORD On_ACK_PLRINFO(const TCmd *pCmd, int pnum); +DWORD On_PLAYER_JOINLEVEL(const TCmd *pCmd, int pnum); +DWORD On_ACTIVATEPORTAL(const TCmd *pCmd, int pnum); +void delta_open_portal(int pnum, BYTE x, BYTE y, BYTE bLevel, BYTE bLType, BYTE bSetLvl); +DWORD On_DEACTIVATEPORTAL(const TCmd *pCmd, int pnum); +DWORD On_RETOWN(const TCmd *pCmd, int pnum); +DWORD On_SETSTR(const TCmd *pCmd, int pnum); +DWORD On_SETDEX(const TCmd *pCmd, int pnum); +DWORD On_SETMAG(const TCmd *pCmd, int pnum); +DWORD On_SETVIT(const TCmd *pCmd, int pnum); +DWORD On_STRING(const TCmd *pCmd, int pnum); +DWORD On_STRING2(int pnum, const TCmdString *p); +DWORD On_SYNCQUEST(const TCmd *pCmd, int pnum); +DWORD On_ENDSHIELD(const TCmd *pCmd, int pnum); +DWORD On_CHEAT_EXPERIENCE(const TCmd *pCmd, int pnum); +DWORD On_CHEAT_SPELL_LEVEL(const TCmd *pCmd, int pnum); +DWORD On_DEBUG(const TCmd *pCmd, int pnum); +DWORD On_NOVA(const TCmd *pCmd, int pnum); +DWORD On_SETSHIELD(const TCmd *pCmd, int pnum); +DWORD On_REMSHIELD(const TCmd *pCmd, int pnum); + +#endif /* __MSG_H__ */ diff --git a/2020_03_31/Source/msgcmd.cpp b/2020_03_31/Source/msgcmd.cpp new file mode 100644 index 00000000..25e3c7d3 --- /dev/null +++ b/2020_03_31/Source/msgcmd.cpp @@ -0,0 +1,58 @@ +#include "diablo.h" +#include "list.h" + +#define COMMAND_LEN 128 + +struct EXTERNMESSAGE { + LIST_LINK(EXTERNMESSAGE) m_Link; + char command[COMMAND_LEN]; + ~EXTERNMESSAGE() + { + // BUGFIX: this is already called by m_Link's destructor + m_Link.Unlink(); + } + static void operator delete(void *p) { + if (p) + SMemFree(p, "delete", SLOG_FUNCTION, 0); + } +}; + +static TList sgChat_Cmd; + +void msgcmd_cmd_cleanup() +{ + sgChat_Cmd.DeleteAll(); +} + +void msgcmd_send_chat() +{ + DWORD tick; + struct EXTERNMESSAGE *msg = sgChat_Cmd.Head(); + + if (msg) { + static DWORD sgdwMsgCmdTimer; + tick = GetTickCount(); + if (tick - sgdwMsgCmdTimer >= 2000) { + sgdwMsgCmdTimer = tick; + SNetSendServerChatCommand(msg->command); + sgChat_Cmd.Remove(msg); + } + } +} + +BOOL msgcmd_add_server_cmd_W(const char *chat_message) +{ + if (chat_message[0] != '/') + return FALSE; + msgcmd_add_server_cmd(chat_message); + return TRUE; +} + +void msgcmd_add_server_cmd(const char *command) +{ + size_t len = strlen(command); + if (len && ++len <= COMMAND_LEN) { + struct EXTERNMESSAGE *msg = sgChat_Cmd.Create(); + memcpy(msg->command, command, len); + } +} diff --git a/2020_03_31/Source/msgcmd.h b/2020_03_31/Source/msgcmd.h new file mode 100644 index 00000000..81135941 --- /dev/null +++ b/2020_03_31/Source/msgcmd.h @@ -0,0 +1,10 @@ +//HEADER_GOES_HERE +#ifndef __MSGCMD_H__ +#define __MSGCMD_H__ + +void msgcmd_cmd_cleanup(); +void msgcmd_send_chat(); +BOOL msgcmd_add_server_cmd_W(const char *chat_message); +void msgcmd_add_server_cmd(const char *command); + +#endif /* __MSGCMD_H__ */ diff --git a/2020_03_31/Source/multi.cpp b/2020_03_31/Source/multi.cpp new file mode 100644 index 00000000..27a73dc5 --- /dev/null +++ b/2020_03_31/Source/multi.cpp @@ -0,0 +1,1109 @@ +#include "diablo.h" +#include "../3rdParty/Storm/Source/storm.h" +#include "../DiabloUI/diabloui.h" + +char gbSomebodyWonGameKludge; // weak +#ifdef _DEBUG +DWORD gdwHistTicks; +#endif +TBuffer sgHiPriBuf; +char szPlayerDescript[128]; +WORD sgwPackPlrOffsetTbl[MAX_PLRS]; +PkPlayerStruct netplr[MAX_PLRS]; +BYTE sgbPlayerTurnBitTbl[MAX_PLRS]; +char sgbPlayerLeftGameTbl[MAX_PLRS]; +int sgbSentThisCycle; // idb +int dword_678628; // weak +char gbActivePlayers; // weak +char gbGameDestroyed; // weak +char sgbSendDeltaTbl[MAX_PLRS]; +_gamedata sgGameInitInfo; +char gbSelectProvider; // weak +int sglTimeoutStart; // weak +int sgdwPlayerLeftReasonTbl[MAX_PLRS]; +TBuffer sgLoPriBuf; +unsigned int sgdwGameLoops; // idb +unsigned char gbMaxPlayers; // weak +char sgbTimeout; // weak +char szPlayerName[128]; +BYTE gbDeltaSender; // weak +int sgbNetInited; // weak +DWORD player_state[MAX_PLRS]; + +const int event_types[3] = +{ + EVENT_TYPE_PLAYER_LEAVE_GAME, + EVENT_TYPE_PLAYER_CREATE_GAME, + EVENT_TYPE_PLAYER_MESSAGE +}; + +#ifdef _DEBUG +void __cdecl dumphist(const char *pszFmt, ...) +{ + static FILE *sgpHistFile = NULL; + DWORD dwTicks; + va_list va; + + va_start(va, pszFmt); + + if(sgpHistFile == NULL) { + sgpHistFile = fopen("c:\\dumphist.txt", "wb"); + if(sgpHistFile == NULL) { + return; + } + } + + dwTicks = GetTickCount(); + fprintf(sgpHistFile, "%4u.%02u ", (dwTicks - gdwHistTicks) / 1000, (dwTicks - gdwHistTicks) % 1000 / 10); + vfprintf(sgpHistFile, pszFmt, va); + fprintf( + sgpHistFile, + "\r\n (%d,%d)(%d,%d)(%d,%d)(%d,%d)\r\n", + plr[0].plractive, + player_state[0], + plr[1].plractive, + player_state[1], + plr[2].plractive, + player_state[2], + plr[3].plractive, + player_state[3]); + fflush(sgpHistFile); +} +#endif + +void multi_msg_add(const BYTE *pbMsg, BYTE bLen) +{ + /// ASSERT: assert(sgbNetInited); + + if(pbMsg != NULL && bLen != 0) { + /// ASSERT: assert(bLen <= gdwNormalMsgSize - sizeof(TPktHdr)); + tmsg_add(pbMsg, bLen); + } +} + +void NetSendLoPri(const BYTE *pbMsg, BYTE bLen) +{ + /// ASSERT: assert(sgbNetInited); + + if(pbMsg != NULL && bLen != 0) { + /// ASSERT: assert(bLen <= gdwNormalMsgSize - sizeof(TPktHdr)); + multi_copy_packet(&sgLoPriBuf, pbMsg, bLen); + multi_send_packet(pbMsg, bLen); + } +} + +void multi_copy_packet(TBuffer *pBuf, const BYTE *pbMsg, BYTE bLen) +{ + BYTE *p; + + if(pBuf->dwNextWriteOffset + bLen + 2 > sizeof(pBuf->bData)) { +#ifdef _DEBUG + app_fatal("msg buffer failure"); +#endif + return; + } + + p = &pBuf->bData[pBuf->dwNextWriteOffset]; + pBuf->dwNextWriteOffset += bLen + 1; + *p = bLen; + p++; + memcpy(p, pbMsg, bLen); + p += bLen; + *p = 0; +} + +void multi_send_packet(const BYTE *pbMsg, BYTE bLen) +{ + TPkt pkt; + + /// ASSERT: assert(sgbNetInited); + /// ASSERT: assert(pbMsg); + /// ASSERT: assert(bLen); + /// ASSERT: assert(bLen <= gdwNormalMsgSize - sizeof(TPktHdr)); + + NetRecvPlrData(&pkt); + pkt.hdr.wLen = bLen + sizeof(TPktHdr); + memcpy(pkt.body, pbMsg, bLen); + + if(!SNetSendMessage(myplr, &pkt.hdr, pkt.hdr.wLen)) { + nthread_terminate_game("SNetSendMessage0"); + } +#if 0 + debug_plr_tbl[myplr]++; +#endif +} + +void NetRecvPlrData(TPkt *pkt) +{ + /// ASSERT: assert(pkt); + pkt->hdr.wCheck = 'ip'; + pkt->hdr.px = plr[myplr].WorldX; + pkt->hdr.py = plr[myplr].WorldY; + pkt->hdr.targx = plr[myplr]._ptargx; + pkt->hdr.targy = plr[myplr]._ptargy; + pkt->hdr.php = plr[myplr]._pHitPoints; + pkt->hdr.pmhp = plr[myplr]._pMaxHP; + pkt->hdr.bstr = plr[myplr]._pBaseStr; + pkt->hdr.bmag = plr[myplr]._pBaseMag; + pkt->hdr.bdex = plr[myplr]._pBaseDex; +} + +void NetSendHiPri(const BYTE *pbMsg, BYTE bLen) +{ + DWORD dwLeft, dwLen; + BYTE *p; + TPkt pkt; + + /// ASSERT: assert(sgbNetInited); + + if(pbMsg != NULL && bLen != 0) { + /// ASSERT: assert(bLen <= gdwNormalMsgSize - sizeof(TPktHdr)); + multi_copy_packet(&sgHiPriBuf, pbMsg, bLen); + multi_send_packet(pbMsg, bLen); + } + + if(dword_678628) { + return; + } + + dword_678628 = 1; + /// ASSERT: assert((DWORD) myplr < MAX_PLRS); + NetRecvPlrData(&pkt); + dwLeft = gdwNormalMsgSize - sizeof(TPktHdr); + p = multi_recv_packet(&sgHiPriBuf, pkt.body, &dwLeft); + p = multi_recv_packet(&sgLoPriBuf, p, &dwLeft); + dwLeft = sync_all_monsters(p, dwLeft); + dwLen = gdwNormalMsgSize - dwLeft; + pkt.hdr.wLen = dwLen; + + if(!SNetSendMessage(SNPLAYER_OTHERS, &pkt.hdr, dwLen)) { + nthread_terminate_game("SNetSendMessage"); + } +#if 0 + if(myplr != 0) { + debug_plr_tbl[0]++; + } + if(myplr != 1) { + debug_plr_tbl[1]++; + } + if(myplr != 2) { + debug_plr_tbl[2]++; + } + if(myplr != 3) { + debug_plr_tbl[3]++; + } +#endif +} + +BYTE *multi_recv_packet(TBuffer *pBuf, BYTE *p, DWORD *dwSize) +{ + BYTE bLen; + BYTE *pbMsg; + + if(pBuf->dwNextWriteOffset == 0) { + return p; + } + + pbMsg = pBuf->bData; + while(1) { + bLen = *pbMsg; + if(bLen == 0 || bLen > *dwSize) { + break; + } + pbMsg++; + memcpy(p, pbMsg, bLen); + pbMsg += bLen; + p += bLen; + *dwSize -= bLen; + } + + memcpy(pBuf->bData, pbMsg, pBuf->dwNextWriteOffset - (pbMsg - pBuf->bData) + 1); + pBuf->dwNextWriteOffset -= pbMsg - pBuf->bData; + return p; +} + +void multi_send_msg_packet(int msk, const BYTE *pbMsg, BYTE bLen) +{ + int m, pnum; + DWORD dwSendBytes; + TPkt pkt; + + /// ASSERT: assert(sgbNetInited); + /// ASSERT: assert(pbMsg); + /// ASSERT: assert(bLen); + + NetRecvPlrData(&pkt); + + dwSendBytes = bLen + sizeof(TPktHdr); + /// ASSERT: assert(dwSendBytes < gdwNormalMsgSize); + pkt.hdr.wLen = dwSendBytes; + memcpy(pkt.body, pbMsg, bLen); + + m = 1; + pnum = 0; + while((DWORD)pnum < MAX_PLRS) { + if(m & msk) { + if(SNetSendMessage(pnum, &pkt.hdr, dwSendBytes)) { +#if 0 + debug_plr_tbl[pnum]++; +#endif + } else if(SErrGetLastError() != STORM_ERROR_INVALID_PLAYER) { + nthread_terminate_game("SNetSendMessage"); + return; + } + } + pnum++; + m <<= 1; + } +} + +void multi_msg_countdown() +{ + int i; + + for(i = 0; i < MAX_PLRS; i++) { + if(player_state[i] & 0x20000) { + /// ASSERT: assert(glpMsgTbl[i]); + if(gdwMsgLenTbl[i] == sizeof(DWORD)) { + multi_parse_turn(i, *glpMsgTbl[i]); + } + } + } +} + +void multi_parse_turn(int pnum, DWORD turn) +{ + if(turn & 0x80000000) { + multi_handle_turn_upper_bit(pnum); + } + + turn &= ~0x80000000; + + if(sgbSentThisCycle < gdwTurnsInTransit + turn) { + if(turn >= ~0x80000000) { + turn &= 0xFFFF; + } + sgbSentThisCycle = turn + gdwTurnsInTransit; + turn *= gbDeltaTurnsSec; + turn <<= 2; + sgdwGameLoops = turn; + } +} + +void multi_handle_turn_upper_bit(int pnum) +{ + int i; + + for(i = 0; i < MAX_PLRS; i++) { + if(player_state[i] & 0x10000 && i != pnum) { + break; + } + } + + if(myplr == i) { + sgbSendDeltaTbl[pnum] = 1; + } else if(myplr == pnum) { + gbDeltaSender = i; + } +} + +void multi_player_left(int pnum, DWORD reason) +{ + sgbPlayerLeftGameTbl[pnum] = 1; + sgdwPlayerLeftReasonTbl[pnum] = reason; + multi_clear_left_tbl(); +} + +void multi_clear_left_tbl() +{ + int i; + + for(i = 0; i < MAX_PLRS; i++) { + if(sgbPlayerLeftGameTbl[i]) { + if(gbBufferMsgs == 1) { +#ifdef _DEBUG + dumphist("(%d) buffering -- player %d left game due to %d", myplr, i, sgdwPlayerLeftReasonTbl[i]); +#endif + msg_send_drop_pkt(i, sgdwPlayerLeftReasonTbl[i]); + } else { +#ifdef _DEBUG + dumphist("(%d) player %d left game due to %d", myplr, i, sgdwPlayerLeftReasonTbl[i]); +#endif + multi_player_left_msg(i, TRUE); + } + sgbPlayerLeftGameTbl[i] = 0; + sgdwPlayerLeftReasonTbl[i] = 0; + } + } +} + +void multi_player_left_msg(int pnum, BOOL left) +{ + char *pszLeft; + + if(!plr[pnum].plractive) { + return; + } + +#ifdef _DEBUG + dumphist("(%d) player %d --> inactive", myplr, pnum); +#endif + RemovePlrFromMap(pnum); + RemovePortalMissile(pnum); + DeactivatePortal(pnum); + delta_close_portal(pnum); + RemovePlrMissiles(pnum); + + if(left) { + pszLeft = "Player '%s' just left the game"; + switch(sgdwPlayerLeftReasonTbl[pnum]) { + case 0x40000006: + pszLeft = "Player '%s' dropped due to timeout"; + break; + case 0x40000004: + pszLeft = "Player '%s' killed Diablo and left the game!"; + gbSomebodyWonGameKludge = 1; + break; + } + EventPlrMsg(pszLeft, plr[pnum]._pName); + } + + plr[pnum].plractive = 0; + plr[pnum]._pName[0] = '\0'; + gbActivePlayers--; +} + +void multi_net_ping() +{ + sgbTimeout = 1; + sglTimeoutStart = GetTickCount(); +} + +BOOL multi_handle_delta() +{ + int i; + BOOL fSendAsync; + + /// ASSERT: assert(sgbNetInited); + + if(gbGameDestroyed) { + gbRunGame = 0; + return FALSE; + } + + for(i = 0; i < MAX_PLRS; i++) { + if(sgbSendDeltaTbl[i]) { + sgbSendDeltaTbl[i] = 0; + DeltaExportData(i); + } + } + + sgbSentThisCycle = nthread_send_and_recv_turn(sgbSentThisCycle, 1); + + if(!nthread_recv_turns(&fSendAsync)) { + multi_begin_timeout(); + return FALSE; + } + + sgbTimeout = 0; + + if(fSendAsync) { + if(!dword_678628) { + NetSendHiPri(NULL, 0); + dword_678628 = 0; + } else { + dword_678628 = 0; + if(!multi_check_pkt_valid(&sgHiPriBuf)) { + NetSendHiPri(NULL, 0); + } + } + } + + multi_mon_seeds(); + return TRUE; +} + +BOOL multi_check_pkt_valid(TBuffer *pBuf) +{ + return pBuf->dwNextWriteOffset == 0; +} + +void multi_mon_seeds() +{ + int i; + DWORD s; + + sgdwGameLoops++; + s = _rotr(sgdwGameLoops, 8); + + for(i = 0; i < MAXMONSTERS; i++) { + monster[i]._mAISeed = i + s; + } +} + +void multi_begin_timeout() +{ + int i, nTicks, nState, nLowestActive, nLowestPlayer; + BYTE bGroupPlayers, bGroupCount; + + if(!sgbTimeout) { + return; + } +#ifdef _DEBUG + if(debug_mode_key_i) { + return; + } +#endif + + nTicks = GetTickCount() - sglTimeoutStart; + if(nTicks > 20000) { + gbRunGame = FALSE; + return; + } + if(nTicks < 10000) { + return; + } + + nLowestActive = -1; + nLowestPlayer = -1; + bGroupPlayers = 0; + bGroupCount = 0; + for(i = 0; i < MAX_PLRS; i++) { + nState = player_state[i]; + if(nState & 0x10000) { + if(nLowestPlayer == -1) { + nLowestPlayer = i; + } + if(nState & 0x40000) { + bGroupPlayers++; + if(nLowestActive == -1) { + nLowestActive = i; + } + } else { + bGroupCount++; + } + } + } + + /// ASSERT: assert(bGroupPlayers); + /// ASSERT: assert(nLowestActive != -1); + /// ASSERT: assert(nLowestPlayer != -1); + +#ifdef _DEBUG + dumphist( + "(%d) grp:%d ngrp:%d lowp:%d lowa:%d", + myplr, + bGroupPlayers, + bGroupCount, + nLowestPlayer, + nLowestActive); +#endif + + if(bGroupPlayers < bGroupCount) { + gbGameDestroyed = TRUE; + } else if(bGroupPlayers == bGroupCount) { + if(nLowestPlayer != nLowestActive) { + gbGameDestroyed = TRUE; + } else if(nLowestActive == myplr) { + multi_check_drop_player(); + } + } else if(nLowestActive == myplr) { + multi_check_drop_player(); + } +} + +void multi_check_drop_player() +{ + int i; + + for(i = 0; i < MAX_PLRS; i++) { + if(!(player_state[i] & 0x40000) && player_state[i] & 0x10000) { +#ifdef _DEBUG + dumphist("(%d) dropping player %d state %d", myplr, i, player_state[i]); +#endif + SNetDropPlayer(i, 0x40000006); + } + } +} + +void multi_process_network_packets() +{ + int dx, dy; + DWORD dwID, dwMsgSize; + char *p; + TPkt *pkt; + + multi_clear_left_tbl(); + multi_process_tmsgs(); + + /// ASSERT: assert(sgbNetInited); + + while(SNetReceiveMessage(&dwID, &p, &dwMsgSize)) { + dwRecCount++; /* unused, probably debug to track total packets received */ + multi_clear_left_tbl(); + pkt = (TPkt *)p; + /// ASSERT: assert(dwMsgSize >= sizeof(TPktHdr)); + /// ASSERT: assert(dwID < MAX_PLRS); + /// ASSERT: assert(pkt->hdr.wCheck == 0x6970); + /// ASSERT: assert(pkt->hdr.wLen == dwMsgSize); + if(dwMsgSize < sizeof(TPktHdr)) { + continue; + } + if(dwID >= MAX_PLRS) { + continue; + } + if(pkt->hdr.wCheck != 'ip') { + continue; + } + if(pkt->hdr.wLen != dwMsgSize) { + continue; + } + plr[dwID]._pownerx = pkt->hdr.px; + plr[dwID]._pownery = pkt->hdr.py; +#if 0 + debug_act_plrs[dwID]++; +#endif + if(dwID != myplr) { + /// ASSERT: assert(gbBufferMsgs != BUFFER_PROCESS); + plr[dwID]._pHitPoints = pkt->hdr.php; + plr[dwID]._pMaxHP = pkt->hdr.pmhp; + plr[dwID]._pBaseStr = pkt->hdr.bstr; + plr[dwID]._pBaseMag = pkt->hdr.bmag; + plr[dwID]._pBaseDex = pkt->hdr.bdex; + if(gbBufferMsgs != 1 && plr[dwID].plractive && plr[dwID]._pHitPoints != 0) { + if(currlevel == plr[dwID].plrlevel && !plr[dwID]._pLvlChanging) { + dx = abs(plr[dwID].WorldX - pkt->hdr.px); + dy = abs(plr[dwID].WorldY - pkt->hdr.py); + if((dx > 3 || dy > 3) && dPlayer[pkt->hdr.px][pkt->hdr.py] == 0) { + FixPlrWalkTags(dwID); + plr[dwID]._poldx = plr[dwID].WorldX; + plr[dwID]._poldy = plr[dwID].WorldY; + FixPlrWalkTags(dwID); + plr[dwID].WorldX = pkt->hdr.px; + plr[dwID].WorldY = pkt->hdr.py; + plr[dwID]._px = pkt->hdr.px; + plr[dwID]._py = pkt->hdr.py; + dPlayer[plr[dwID].WorldX][plr[dwID].WorldY] = dwID + 1; + } + dx = abs(plr[dwID]._px - plr[dwID].WorldX); + dy = abs(plr[dwID]._py - plr[dwID].WorldY); + if(dx > 1 || dy > 1) { + plr[dwID]._px = plr[dwID].WorldX; + plr[dwID]._py = plr[dwID].WorldY; + } + MakePlrPath(dwID, pkt->hdr.targx, pkt->hdr.targy, TRUE); + } else { + plr[dwID].WorldX = pkt->hdr.px; + plr[dwID].WorldY = pkt->hdr.py; + plr[dwID]._px = pkt->hdr.px; + plr[dwID]._py = pkt->hdr.py; + plr[dwID]._ptargx = pkt->hdr.targx; + plr[dwID]._ptargy = pkt->hdr.targy; + } + } + } + multi_handle_all_packets(dwID, pkt->body, dwMsgSize - sizeof(TPktHdr)); + } + + if(SErrGetLastError() != STORM_ERROR_NO_MESSAGES_WAITING) { + nthread_terminate_game("SNetReceiveMsg"); + } +} + +void multi_handle_all_packets(int pnum, BYTE *pData, DWORD dwSize) +{ + DWORD dwLen; + + while(dwSize != 0) { + dwLen = ParseCmd(pnum, (TCmd *)pData); + if(dwLen == 0) { + break; + } + pData += dwLen; + dwSize -= dwLen; + } +} + +void multi_process_tmsgs() +{ + DWORD dwSize; + TPkt pkt; + + while(dwSize = tmsg_get((BYTE *)&pkt, sizeof(pkt))) { + multi_handle_all_packets(myplr, (BYTE *)&pkt, dwSize); + } +} + +void multi_send_zero_packet(int pnum, BYTE bCmd, BYTE *pbSrc, DWORD dwLen) +{ + DWORD dwOffset, dwBody, dwMsg; + TCmdPlrInfoHdr *p; + TPkt pkt; + + /// ASSERT: assert(pnum != myplr); + /// ASSERT: assert(pbSrc); + /// ASSERT: assert(dwLen <= 0x0ffff); + + dwOffset = 0; + while(dwLen != 0) { + pkt.hdr.wCheck = 'ip'; + pkt.hdr.px = 0; + pkt.hdr.py = 0; + pkt.hdr.targx = 0; + pkt.hdr.targy = 0; + pkt.hdr.php = 0; + pkt.hdr.pmhp = 0; + pkt.hdr.bstr = 0; + pkt.hdr.bmag = 0; + pkt.hdr.bdex = 0; + p = (TCmdPlrInfoHdr *)pkt.body; + p->bCmd = bCmd; + p->wOffset = dwOffset; + dwBody = gdwLargestMsgSize - sizeof(TPktHdr) - sizeof(*p); + if(dwLen < dwBody) { + dwBody = dwLen; + } + /// ASSERT: assert(dwBody <= 0x0ffff); + p->wBytes = dwBody; + memcpy(&pkt.body[sizeof(*p)], pbSrc, p->wBytes); + dwMsg = sizeof(TPktHdr); + dwMsg += sizeof(*p); + dwMsg += p->wBytes; + pkt.hdr.wLen = dwMsg; + if(!SNetSendMessage(pnum, &pkt, dwMsg)) { + nthread_terminate_game("SNetSendMessage2"); + return; + } +#if 0 + if((DWORD)pnum < MAX_PLRS) { + debug_plr_tbl[pnum]++; + } else { + if(myplr != 0) { + debug_plr_tbl[0]++; + } + if(myplr != 1) { + debug_plr_tbl[1]++; + } + if(myplr != 2) { + debug_plr_tbl[2]++; + } + if(myplr != 3) { + debug_plr_tbl[3]++; + } + } +#endif + pbSrc += p->wBytes; + dwLen -= p->wBytes; + dwOffset += p->wBytes; + } +} + +void NetClose() +{ + if(sgbNetInited) { + sgbNetInited = 0; + nthread_cleanup(); + dthread_cleanup(); + tmsg_cleanup(); + multi_event_handler(FALSE); + SNetLeaveGame(3); + msgcmd_cmd_cleanup(); +#ifdef _DEBUG + dumphist("(%d) NetClose", myplr); +#endif + if(gbMaxPlayers > 1) { + Sleep(2000); + } + } +} + +void multi_event_handler(BOOL reg) +{ + int i; + BOOL (__stdcall *func)(int, void (__stdcall *)(_SNETEVENT *)); + + if(reg) { + func = SNetRegisterEventHandler; + } else { + func = SNetUnregisterEventHandler; + } + + for(i = 0; (DWORD)i < 3; i++) { + if(!func(event_types[i], multi_handle_events) && reg) { + app_fatal("SNetRegisterEventHandler:\n%s", TraceLastError()); + } + } +} + +void __stdcall multi_handle_events(_SNETEVENT *pEvt) +{ + DWORD reason; + _gamedata *pGame; + + switch(pEvt->eventid) { + case EVENT_TYPE_PLAYER_CREATE_GAME: + /// ASSERT: assert(pEvt->data); + /// ASSERT: assert(pEvt->databytes >= sizeof(DWORD)); + pGame = (_gamedata *)pEvt->data; + sgGameInitInfo.dwSeed = pGame->dwSeed; + sgGameInitInfo.bDiff = pGame->bDiff; + sgbPlayerTurnBitTbl[pEvt->playerid] = 1; + break; + case EVENT_TYPE_PLAYER_LEAVE_GAME: + /// ASSERT: assert(pEvt->playerid >= 0 && pEvt->playerid < MAX_PLRS); + sgbPlayerLeftGameTbl[pEvt->playerid] = 1; + sgbPlayerTurnBitTbl[pEvt->playerid] = 0; + reason = 0; + if(pEvt->data != NULL && pEvt->databytes >= 4) { + reason = ((DWORD *)pEvt->data)[0]; + } + sgdwPlayerLeftReasonTbl[pEvt->playerid] = reason; + if(reason == 0x40000004) { + gbSomebodyWonGameKludge = 1; + } + sgbSendDeltaTbl[pEvt->playerid] = 0; + dthread_remove_player(pEvt->playerid); + if(gbDeltaSender == pEvt->playerid) { + gbDeltaSender = 4; + } +#ifdef _DEBUG + dumphist("(%d) callback: player %d left game due to %d", myplr, pEvt->playerid, reason); +#endif + break; + case EVENT_TYPE_PLAYER_MESSAGE: + /// ASSERT: assert(pEvt->data); + ErrorPlrMsg((char *)pEvt->data); + break; + } +} + +BOOL NetInit(BOOL bSinglePlayer, BOOL *pfExitProgram) +{ + int i; + DWORD dwBytes; + _SNETPROGRAMDATA progdata; + _SNETPLAYERDATA plrdata; + _SNETUIDATA uidata; + + while(1) { + /// ASSERT: assert(pfExitProgram); + *pfExitProgram = FALSE; + SetRndSeed(0); + sgGameInitInfo.dwSeed = time(NULL); + sgGameInitInfo.bDiff = gnDifficulty; + memset(&progdata, 0, sizeof(progdata)); + progdata.size = sizeof(progdata); + progdata.programname = "Diablo Retail"; + progdata.programdescription = gszVersionNumber; + progdata.programid = 'DRTL'; + progdata.versionid = 42; + progdata.maxplayers = MAX_PLRS; + progdata.initdata = &sgGameInitInfo; + progdata.initdatabytes = sizeof(sgGameInitInfo); + progdata.optcategorybits = 15; + progdata.lcid = MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT); + memset(&plrdata, 0, sizeof(plrdata)); + plrdata.size = sizeof(plrdata); + memset(&uidata, 0, sizeof(uidata)); + uidata.size = sizeof(uidata); + uidata.parentwindow = SDrawGetFrameWindow(0); + uidata.artcallback = (void (*)())UiArtCallback; + uidata.createcallback = (void (*)())UiCreateGameCallback; + uidata.drawdesccallback = (void (*)())UiDrawDescCallback; + uidata.messageboxcallback = (void (*)())UiMessageBoxCallback; + uidata.soundcallback = (void (*)())UiSoundCallback; + uidata.authcallback = (void (*)())UiAuthCallback; + uidata.getdatacallback = (void (*)())UiGetDataCallback; + uidata.categorycallback = (void (*)())UiCategoryCallback; + uidata.selectnamecallback = (void (*)())mainmenu_select_hero_dialog; + uidata.changenamecallback = (void (*)())mainmenu_create_hero; + uidata.profilebitmapcallback = (void (*)())UiProfileDraw; + uidata.profilecallback = (void (*)())UiProfileCallback; + uidata.profilefields = UiProfileGetString(); + memset(sgbPlayerTurnBitTbl, 0, sizeof(sgbPlayerTurnBitTbl)); + gbGameDestroyed = 0; + memset(sgbPlayerLeftGameTbl, 0, sizeof(sgbPlayerLeftGameTbl)); + memset(sgdwPlayerLeftReasonTbl, 0, sizeof(sgdwPlayerLeftReasonTbl)); + memset(sgbSendDeltaTbl, 0, sizeof(sgbSendDeltaTbl)); + memset(plr, 0, sizeof(plr)); + memset(sgwPackPlrOffsetTbl, 0, sizeof(sgwPackPlrOffsetTbl)); + SNetSetBasePlayer(0); + if(bSinglePlayer) { + if(!multi_init_single(&progdata, &plrdata, &uidata)) { + return FALSE; + } + } else { + if(!multi_init_multi(&progdata, &plrdata, &uidata, pfExitProgram)) { + return FALSE; + } + } +#ifdef _DEBUG + gdwHistTicks = GetTickCount(); + dumphist("(%d) new game started", myplr); +#endif + sgbNetInited = 1; + sgbTimeout = 0; + delta_init(); + InitPlrMsg(); + buffer_init(&sgHiPriBuf); + buffer_init(&sgLoPriBuf); + dword_678628 = 0; + sync_init(); + nthread_start(sgbPlayerTurnBitTbl[myplr]); + dthread_start(); + tmsg_start(); + sgdwGameLoops = 0; + sgbSentThisCycle = 0; + gbDeltaSender = myplr; + gbSomebodyWonGameKludge = 0; + nthread_send_and_recv_turn(0, 0); + SetupLocalCoords(); + multi_send_pinfo(SNPLAYER_OTHERS, CMD_SEND_PLRINFO); + plr[myplr].plractive = 1; + gbActivePlayers = 1; + if(sgbPlayerTurnBitTbl[myplr] == 0 || msg_wait_resync()) { + break; + } + NetClose(); + gbSelectProvider = 0; + } + + gnDifficulty = sgGameInitInfo.bDiff; + SetRndSeed(sgGameInitInfo.dwSeed); + + for(i = 0; i < NUMLEVELS; i++) { + glSeedTbl[i] = GetRndSeed(); + gnLevelTypeTbl[i] = InitLevelType(i); + } + + if(!SNetGetGameInfo(GAMEINFO_NAME, szPlayerName, sizeof(szPlayerName), &dwBytes)) { + nthread_terminate_game("SNetGetGameInfo1"); + } + if(!SNetGetGameInfo(GAMEINFO_PASSWORD, szPlayerDescript, sizeof(szPlayerDescript), &dwBytes)) { + nthread_terminate_game("SNetGetGameInfo2"); + } + + return TRUE; +} + +void buffer_init(TBuffer *pBuf) +{ + pBuf->dwNextWriteOffset = 0; + pBuf->bData[0] = 0; +} + +void multi_send_pinfo(int pnum, BYTE cmd) +{ + PkPlayerStruct pkplr; + + PackPlayer(&pkplr, myplr, TRUE); + dthread_send_delta(pnum, cmd, (BYTE *)&pkplr, sizeof(pkplr)); +} + +int InitLevelType(int l) +{ + if(l == 0) { + return DTYPE_TOWN; + } + if(l >= 1 && l <= 4) { + return DTYPE_CATHEDRAL; + } + if(l >= 5 && l <= 8) { + return DTYPE_CATACOMBS; + } + if(l >= 9 && l <= 12) { + return DTYPE_CAVES; + } + + return DTYPE_HELL; +} + +void SetupLocalCoords() +{ + int x, y; + + if(!leveldebug || gbMaxPlayers > 1) { + currlevel = 0; + leveltype = 0; + setlevel = 0; + } + + x = 75; + y = 68; +#ifdef _DEBUG + if(debug_mode_key_inverted_v || debug_mode_key_d) { + x = 49; + y = 23; + } +#endif + x += plrxoff[myplr]; + y += plryoff[myplr]; + + plr[myplr].WorldX = x; + plr[myplr].WorldY = y; + plr[myplr]._px = x; + plr[myplr]._py = y; + plr[myplr]._ptargx = x; + plr[myplr]._ptargy = y; + plr[myplr].plrlevel = currlevel; + plr[myplr]._pLvlChanging = 1; + plr[myplr].pLvlLoad = 0; + plr[myplr]._pmode = PM_NEWLVL; + plr[myplr].destAction = -1; +} + +BOOL multi_init_single(_SNETPROGRAMDATA *progdata, _SNETPLAYERDATA *plrdata, _SNETUIDATA *uidata) +{ + DWORD dwID; + + if(!SNetInitializeProvider(0, progdata, plrdata, uidata, &fileinfo)) { + SErrGetLastError(); + return FALSE; + } + + dwID = 0; + if(!SNetCreateGame("local", "local", "local", 0, &sgGameInitInfo, sizeof(sgGameInitInfo), 1, "local", "local", &dwID)) { + app_fatal("SNetCreateGame1:\n%s", TraceLastError()); + } + /// ASSERT: assert(dwID == 0); + + myplr = 0; + gbMaxPlayers = 1; + return TRUE; +} + +BOOL multi_init_multi(_SNETPROGRAMDATA *progdata, _SNETPLAYERDATA *plrdata, _SNETUIDATA *uidata, BOOL *pfExitProgram) +{ + DWORD dwProvider, dwID; + BOOL fUpgrade; + + fUpgrade = TRUE; + while(1) { + dwProvider = 0; + if(gbSelectProvider) { + if(!UiSelectProvider(0, progdata, plrdata, uidata, &fileinfo, &dwProvider)) { + if(!fUpgrade) { + return FALSE; + } + if(SErrGetLastError() != STORM_ERROR_REQUIRES_UPGRADE) { + return FALSE; + } + if(!multi_upgrade(pfExitProgram)) { + return FALSE; + } + } + if(dwProvider == 'BNET') { + plr[0].pBattleNet = 1; + } + } + multi_event_handler(TRUE); + if(UiSelectGame(1, progdata, plrdata, uidata, &fileinfo, &dwID)) { + break; + } + /// ASSERT: assert(! *pfExitProgram); + gbSelectProvider = 1; + fUpgrade = FALSE; + } + + if(dwID >= MAX_PLRS) { + return FALSE; + } else { + myplr = dwID; + gbMaxPlayers = MAX_PLRS; + pfile_read_player_from_save(); + if(dwProvider == 'BNET') { + plr[myplr].pBattleNet = 1; + } + return TRUE; + } +} + +BOOL multi_upgrade(BOOL *pfExitProgram) +{ + DWORD dwStatus; + + SNetPerformUpgrade(&dwStatus); + + switch(dwStatus) { + case 0xFFFFFFFF: + DrawDlg("Network upgrade failed"); + break; + case 0: + return TRUE; + case 1: + return TRUE; + case 2: + *pfExitProgram = TRUE; + break; + } + + return FALSE; +} + +void recv_plrinfo(int pnum, TCmdPlrInfoHdr *p, BOOL recv) +{ + char *szEvent; + + if(myplr == pnum) { + return; + } + /// ASSERT: assert((DWORD)pnum < MAX_PLRS); + + if(sgwPackPlrOffsetTbl[pnum] != p->wOffset) { + sgwPackPlrOffsetTbl[pnum] = 0; + if(p->wOffset != 0) { + return; + } + } + if(!recv && sgwPackPlrOffsetTbl[pnum] == 0) { + multi_send_pinfo(pnum, CMD_ACK_PLRINFO); + } + + memcpy((char *)&netplr[pnum] + p->wOffset, &p[1], p->wBytes); /* todo: cast? */ + sgwPackPlrOffsetTbl[pnum] += p->wBytes; + if(sgwPackPlrOffsetTbl[pnum] != sizeof(*netplr)) { + return; + } + + sgwPackPlrOffsetTbl[pnum] = 0; + multi_player_left_msg(pnum, 0); + plr[pnum]._pGFXLoad = 0; + UnPackPlayer(&netplr[pnum], pnum, 1); + + if(!recv) { +#ifdef _DEBUG + dumphist("(%d) received all %d plrinfo", myplr, pnum); +#endif + return; + } + + plr[pnum].plractive = 1; + gbActivePlayers++; + + if(sgbPlayerTurnBitTbl[pnum] != 0) { + szEvent = "Player '%s' (level %d) just joined the game"; + } else { + szEvent = "Player '%s' (level %d) is already in the game"; + } + EventPlrMsg(szEvent, plr[pnum]._pName, plr[pnum]._pLevel); + + LoadPlrGFX(pnum, 1); + SyncInitPlr(pnum); + + if(plr[pnum].plrlevel == currlevel) { + if(plr[pnum]._pHitPoints >> 6 > 0) { + StartStand(pnum, 0); + } else { + plr[pnum]._pgfxnum = 0; + LoadPlrGFX(pnum, 128); + plr[pnum]._pmode = PM_DEATH; + NewPlrAnim(pnum, plr[pnum]._pDAnim[0], plr[pnum]._pDFrames, 1, plr[pnum]._pDWidth); + plr[pnum]._pAnimFrame = plr[pnum]._pAnimLen - 1; + plr[pnum]._pVar8 = 2 * plr[pnum]._pAnimLen; + dFlags[plr[pnum].WorldX][plr[pnum].WorldY] |= 4; + } + } +#ifdef _DEBUG + dumphist("(%d) making %d active -- recv_plrinfo", myplr, pnum); +#endif +} diff --git a/2020_03_31/Source/multi.h b/2020_03_31/Source/multi.h new file mode 100644 index 00000000..92e91a42 --- /dev/null +++ b/2020_03_31/Source/multi.h @@ -0,0 +1,77 @@ +//HEADER_GOES_HERE +#ifndef __MULTI_H__ +#define __MULTI_H__ + +extern char gbSomebodyWonGameKludge; // weak +#ifdef _DEBUG +extern DWORD gdwHistTicks; +#endif +extern TBuffer sgHiPriBuf; +extern char szPlayerDescript[128]; +extern WORD sgwPackPlrOffsetTbl[MAX_PLRS]; +extern PkPlayerStruct netplr[MAX_PLRS]; +extern BYTE sgbPlayerTurnBitTbl[MAX_PLRS]; +extern char sgbPlayerLeftGameTbl[MAX_PLRS]; +extern int sgbSentThisCycle; // idb +extern int dword_678628; // weak +extern char gbActivePlayers; // weak +extern char gbGameDestroyed; // weak +extern char sgbSendDeltaTbl[MAX_PLRS]; +extern _gamedata sgGameInitInfo; +extern char gbSelectProvider; // weak +extern int sglTimeoutStart; // weak +extern int sgdwPlayerLeftReasonTbl[MAX_PLRS]; +extern TBuffer sgLoPriBuf; +extern unsigned int sgdwGameLoops; // idb +extern unsigned char gbMaxPlayers; // weak +extern char sgbTimeout; // weak +extern char szPlayerName[128]; +extern BYTE gbDeltaSender; // weak +extern int sgbNetInited; // weak +extern DWORD player_state[MAX_PLRS]; + +#ifdef _DEBUG +void __cdecl dumphist(const char *pszFmt, ...); +#endif +void multi_msg_add(const BYTE *pbMsg, BYTE bLen); +void NetSendLoPri(const BYTE *pbMsg, BYTE bLen); +void multi_copy_packet(TBuffer *pBuf, const BYTE *pbMsg, BYTE bLen); +void multi_send_packet(const BYTE *pbMsg, BYTE bLen); +void NetRecvPlrData(TPkt *pkt); +void NetSendHiPri(const BYTE *pbMsg, BYTE bLen); +BYTE *multi_recv_packet(TBuffer *pBuf, BYTE *p, DWORD *dwSize); +void multi_send_msg_packet(int msk, const BYTE *pbMsg, BYTE bLen); +void multi_msg_countdown(); +void multi_parse_turn(int pnum, DWORD turn); +void multi_handle_turn_upper_bit(int pnum); +void multi_player_left(int pnum, DWORD reason); +void multi_clear_left_tbl(); +void multi_player_left_msg(int pnum, BOOL left); +void multi_net_ping(); +BOOL multi_handle_delta(); +BOOL multi_check_pkt_valid(TBuffer *pBuf); +void multi_mon_seeds(); +void multi_begin_timeout(); +void multi_check_drop_player(); +void multi_process_network_packets(); +void multi_handle_all_packets(int pnum, BYTE *pData, DWORD dwSize); +void multi_process_tmsgs(); +void multi_send_zero_packet(int pnum, BYTE bCmd, BYTE *pbSrc, DWORD dwLen); +void NetClose(); +void multi_event_handler(BOOL reg); +void __stdcall multi_handle_events(_SNETEVENT *pEvt); +BOOL NetInit(BOOL bSinglePlayer, BOOL *pfExitProgram); +void buffer_init(TBuffer *pBuf); +void multi_send_pinfo(int pnum, BYTE cmd); +int InitLevelType(int l); +void SetupLocalCoords(); +BOOL multi_init_single(_SNETPROGRAMDATA *progdata, _SNETPLAYERDATA *plrdata, _SNETUIDATA *uidata); +BOOL multi_init_multi(_SNETPROGRAMDATA *progdata, _SNETPLAYERDATA *plrdata, _SNETUIDATA *uidata, BOOL *pfExitProgram); +BOOL multi_upgrade(BOOL *pfExitProgram); +void recv_plrinfo(int pnum, TCmdPlrInfoHdr *p, BOOL recv); + +/* rdata */ + +extern const int event_types[3]; + +#endif /* __MULTI_H__ */ diff --git a/2020_03_31/Source/nthread.cpp b/2020_03_31/Source/nthread.cpp new file mode 100644 index 00000000..750f46f6 --- /dev/null +++ b/2020_03_31/Source/nthread.cpp @@ -0,0 +1,266 @@ +#include "diablo.h" +#include "../3rdParty/Storm/Source/storm.h" + +BYTE gbDeltaTurnsSec; // weak +DWORD gdwMsgLenTbl[4]; +static CCritSect sgMemCrit; +int gdwDeltaBytesSec; // weak +static BOOLEAN sgbThreadIsActive; // weak +DWORD gdwTurnsInTransit; // weak +DWORD *glpMsgTbl[4]; +static unsigned int sgnThreadId; +char sgbSyncCountdown; // weak +int dword_679754; // weak +char byte_679758; // weak +char sgbPacketCountdown; // weak +char sgbThreadIsRunning; // weak +int gdwLargestMsgSize; // weak +int gdwNormalMsgSize; // weak +int dword_679764; // weak + +/* data */ +static HANDLE sghThread = INVALID_HANDLE_VALUE; // idb + +void nthread_terminate_game(const char *pszFcn) +{ + DWORD dwError; + + /// ASSERT: assert(pszFcn); + + dwError = SErrGetLastError(); + + if(dwError == STORM_ERROR_INVALID_PLAYER) { + return; + } + + if(dwError == STORM_ERROR_GAME_TERMINATED) { + gbGameDestroyed = 1; + } else if(dwError == STORM_ERROR_NOT_IN_GAME) { + gbGameDestroyed = 1; + } else { + app_fatal("%s:\n%s", pszFcn, TraceLastError()); + } +} + +DWORD nthread_send_and_recv_turn(DWORD cur_turn, int turn_delta) +{ + DWORD dwCount, dwTurn; + + if(!SNetGetTurnsInTransit(&dwCount)) { + nthread_terminate_game("SNetGetTurnsInTransit"); + return 0; + } + + /// ASSERT: assert(gdwTurnsInTransit); + while(dwCount++ < gdwTurnsInTransit) { + dwTurn = dword_679754 | cur_turn & 0x7FFFFFFF; + dword_679754 = 0; + if(!SNetSendTurn(&dwTurn, sizeof(dwTurn))) { + nthread_terminate_game("SNetSendTurn"); + return 0; + } + cur_turn += turn_delta; + if(cur_turn >= 0x7FFFFFFF) { + cur_turn &= 0xFFFF; + } + } + + return cur_turn; +} + +BOOL nthread_recv_turns(BOOL *pfSendAsync) +{ + /// ASSERT: assert(pfSendAsync); + *pfSendAsync = FALSE; + +#if 0 + if(is_debug_nthread) { + nthread_debug_413D97(); + } +#endif + + /// ASSERT: assert(sgbPacketCountdown); + sgbPacketCountdown--; + if(sgbPacketCountdown != 0) { + dword_679764 += 50; + return TRUE; + } + sgbPacketCountdown = gbDeltaTurnsSec; + + /// ASSERT: assert(sgbSyncCountdown); + sgbSyncCountdown--; + if(sgbSyncCountdown == 0) { + if(!SNetReceiveTurns(0, 4, &glpMsgTbl, &gdwMsgLenTbl, &player_state)) { + if(SErrGetLastError() != STORM_ERROR_NO_MESSAGES_WAITING) { + nthread_terminate_game("SNetReceiveTurns"); + } + sgbSyncCountdown = 1; + sgbPacketCountdown = sgbSyncCountdown; + byte_679758 = FALSE; + return FALSE; + } + if(!byte_679758) { + byte_679758 = TRUE; + dword_679764 = GetTickCount(); + } + sgbSyncCountdown = 4; + multi_msg_countdown(); + } + + *pfSendAsync = TRUE; + dword_679764 += 50; + return TRUE; +} + +void nthread_set_turn_upper_bit() +{ + dword_679754 = 0x80000000; +} + +void nthread_start(BOOL set_turn_upper_bit) +{ + _SNETCAPS caps; + + dword_679764 = GetTickCount(); + sgbPacketCountdown = 1; + sgbSyncCountdown = 1; + byte_679758 = TRUE; + + if(set_turn_upper_bit) { + nthread_set_turn_upper_bit(); + } else { + dword_679754 = 0; + } + + caps.size = sizeof(caps); + if(!SNetGetProviderCaps(&caps)) { + app_fatal("SNetGetProviderCaps:\n%s", TraceLastError()); + } + + if(caps.defaultturnsintransit != 0) { + gdwTurnsInTransit = caps.defaultturnsintransit; + } else { + gdwTurnsInTransit = 1; + } + + if(caps.defaultturnssec > 20 || caps.defaultturnssec == 0) { + gbDeltaTurnsSec = 1; + } else { + gbDeltaTurnsSec = 20 / caps.defaultturnssec; + } + + gdwLargestMsgSize = caps.maxmessagesize < 512 ? caps.maxmessagesize : 512; + /// ASSERT: assert(gdwLargestMsgSize >= MIN_MSG_SIZE); + + gdwNormalMsgSize = caps.bytessec * gbDeltaTurnsSec / 20; + gdwDeltaBytesSec = caps.bytessec >> 2; + + gdwNormalMsgSize *= 3; + gdwNormalMsgSize >>= 2; + + /// ASSERT: assert(caps.maxplayers); + if(caps.maxplayers > 4) { + caps.maxplayers = 4; + } + + gdwNormalMsgSize /= caps.maxplayers; + + while(gdwNormalMsgSize < MIN_MSG_SIZE) { + gdwNormalMsgSize <<= 1; + gbDeltaTurnsSec <<= 1; + } + + if(gdwNormalMsgSize > gdwLargestMsgSize) { + gdwNormalMsgSize = gdwLargestMsgSize; + } + + if(gbMaxPlayers > 1) { + sgbThreadIsRunning = FALSE; + sgMemCrit.Enter(); + sgbThreadIsActive = TRUE; + /// ASSERT: assert(sghThread == INVALID_HANDLE_VALUE); + sghThread = (HANDLE)_beginthreadex(NULL, 0, nthread_handler, NULL, 0, &sgnThreadId); + if(sghThread == INVALID_HANDLE_VALUE) { + app_fatal("nthread2:\n%s", TraceLastError()); + } + SetThreadPriority(sghThread, THREAD_PRIORITY_HIGHEST); + } +} + +unsigned int __stdcall nthread_handler(void *dummy) +{ + int nTicks; + BOOL fSendAsync; + + while(sgbThreadIsActive) { + sgMemCrit.Enter(); + if(!sgbThreadIsActive) { + sgMemCrit.Leave(); + return 0; + } + nthread_send_and_recv_turn(0, 0); + if(nthread_recv_turns(&fSendAsync)) { + nTicks = dword_679764 - GetTickCount(); + } else { + nTicks = 50; + } + sgMemCrit.Leave(); + if(nTicks > 0) { + Sleep(nTicks); + } + } + + return 0; +} + +void nthread_cleanup() +{ + sgbThreadIsActive = FALSE; + gdwTurnsInTransit = 0; + gdwNormalMsgSize = 0; + gdwLargestMsgSize = 0; + + if(sghThread != INVALID_HANDLE_VALUE && sgnThreadId != GetCurrentThreadId()) { + if(!sgbThreadIsRunning) { + sgMemCrit.Leave(); + } + if(WaitForSingleObject(sghThread, INFINITE) == WAIT_FAILED) { + app_fatal("nthread3:\n(%s)", TraceLastError()); + } + CloseHandle(sghThread); + sghThread = INVALID_HANDLE_VALUE; + } +} + +void nthread_ignore_mutex(BOOL bStart) +{ + if(sghThread == INVALID_HANDLE_VALUE) { + return; + } + + /// ASSERT: assert(sgbThreadIsRunning != bStart); + + if(bStart) { + sgMemCrit.Leave(); + } else { + sgMemCrit.Enter(); + } + + sgbThreadIsRunning = bStart; +} + +BOOL nthread_has_500ms_passed(BOOL unused) +{ + int nPassed; + DWORD dwTicks; + + dwTicks = GetTickCount(); + nPassed = dwTicks - dword_679764; + + if(gbMaxPlayers == 1 && nPassed > 500) { + dword_679764 = dwTicks; + nPassed = 0; + } + + return nPassed >= 0; +} diff --git a/2020_03_31/Source/nthread.h b/2020_03_31/Source/nthread.h new file mode 100644 index 00000000..3f8c42d1 --- /dev/null +++ b/2020_03_31/Source/nthread.h @@ -0,0 +1,29 @@ +//HEADER_GOES_HERE +#ifndef __NTHREAD_H__ +#define __NTHREAD_H__ + +extern BYTE gbDeltaTurnsSec; // weak +extern DWORD gdwMsgLenTbl[4]; +extern int gdwDeltaBytesSec; // weak +extern DWORD gdwTurnsInTransit; // weak +extern DWORD *glpMsgTbl[4]; +extern char sgbSyncCountdown; // weak +extern int dword_679754; // weak +extern char byte_679758; // weak +extern char sgbPacketCountdown; // weak +extern char sgbThreadIsRunning; // weak +extern int gdwLargestMsgSize; // weak +extern int gdwNormalMsgSize; // weak +extern int dword_679764; // weak + +void nthread_terminate_game(const char *pszFcn); +DWORD nthread_send_and_recv_turn(DWORD cur_turn, int turn_delta); +BOOL nthread_recv_turns(BOOL *pfSendAsync); +void nthread_set_turn_upper_bit(); +void nthread_start(BOOL set_turn_upper_bit); +unsigned int __stdcall nthread_handler(void *dummy); +void nthread_cleanup(); +void nthread_ignore_mutex(BOOL bStart); +BOOL nthread_has_500ms_passed(BOOL unused); + +#endif /* __NTHREAD_H__ */ diff --git a/2020_03_31/Source/objdat.cpp b/2020_03_31/Source/objdat.cpp new file mode 100644 index 00000000..60b47c92 --- /dev/null +++ b/2020_03_31/Source/objdat.cpp @@ -0,0 +1,183 @@ +#include "diablo.h" + +int ObjTypeConv[113] = +{ + 0, + 4, + 20, + 21, + 22, + 24, + 11, + 12, + 13, + 0, + 0, + 0, + 0, + 0, + 25, + 41, + 26, + 0, + 8, + 9, + 10, + 80, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 49, + 0, + 0, + 0, + 0, + 0, + 84, + 85, + 3, + 14, + 15, + 16, + 17, + 18, + 19, + 0, + 0, + 0, + 0, + 0, + 0, + 28, + 0, + 53, + 54, + 36, + 37, + 38, + 39, + 40, + 0, + 0, + 0, + 0, + 0, + 27, + 0, + 0, + 0, + 0, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 5, + 5, + 5, + 6, + 6, + 6, + 7, + 7, + 7, + 0, + 0, + 0, + 0, + 0, + 73, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 83, + 0, + 0, + 89, + 90, + 47, + 46, + 94 +}; + +ObjDataStruct AllObjects[99] = +{ +#include "Data/xl_obj.cpp" +}; + +char *ObjMasterLoadList[56] = +{ + "L1Braz", + "L1Doors", + "Lever", + "Chest1", + "Chest2", + "Banner", + "SkulPile", + "SkulFire", + "SkulStik", + "CruxSk1", + "CruxSk2", + "CruxSk3", + "Book1", + "Book2", + "Rockstan", + "Angel", + "Chest3", + "Burncros", + "Candle2", + "Nude2", + "Switch4", + "TNudeM", + "TNudeW", + "TSoul", + "L2Doors", + "WTorch4", + "WTorch3", + "Sarc", + "Flame1", + "Prsrplt1", + "Traphole", + "MiniWatr", + "WTorch2", + "WTorch1", + "BCase", + "BShelf", + "WeapStnd", + "Barrel", + "Barrelex", + "LShrineG", + "RShrineG", + "Bloodfnt", + "Decap", + "Pedistl", + "L3Doors", + "PFountn", + "Armstand", + "Goatshrn", + "Cauldren", + "MFountn", + "TFountn", + "Altboy", + "Mcirl", + "Bkslbrnt", + "Mushptch", + "LzStand" +}; diff --git a/2020_03_31/Source/objdat.h b/2020_03_31/Source/objdat.h new file mode 100644 index 00000000..9a949bb6 --- /dev/null +++ b/2020_03_31/Source/objdat.h @@ -0,0 +1,9 @@ +//HEADER_GOES_HERE +#ifndef __OBJDAT_H__ +#define __OBJDAT_H__ + +extern int ObjTypeConv[113]; +extern ObjDataStruct AllObjects[99]; +extern char *ObjMasterLoadList[56]; + +#endif /* __OBJDAT_H__ */ diff --git a/2020_03_31/Source/objects.cpp b/2020_03_31/Source/objects.cpp new file mode 100644 index 00000000..a463b62f --- /dev/null +++ b/2020_03_31/Source/objects.cpp @@ -0,0 +1,4981 @@ +#include "diablo.h" + +int trapid; // weak +int trapdir; // weak +unsigned char *pObjCels[40]; +char ObjFileList[40]; +int objectactive[MAXOBJECTS]; +int nobjects; // idb +int leverid; // idb +int objectavail[MAXOBJECTS]; +ObjectStruct object[MAXOBJECTS]; +int InitObjFlag; // weak +int numobjfiles; // weak + +int bxadd[8] = { -1, 0, 1, -1, 1, -1, 0, 1 }; +int byadd[8] = { -1, -1, -1, 0, 0, 1, 1, 1 }; +char *shrinestrs[26] = +{ + "Mysterious", + "Hidden", + "Gloomy", + "Weird", + "Magical", + "Stone", + "Religious", + "Enchanted", + "Thaumaturgic", + "Fascinating", + "Cryptic", + "Magical", + "Eldritch", + "Eerie", + "Divine", + "Holy", + "Sacred", + "Spiritual", + "Spooky", + "Abandoned", + "Creepy", + "Quiet", + "Secluded", + "Ornate", + "Glimmering", + "Tainted" +}; +char shrinemin[26] = +{ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1 +}; +char shrinemax[26] = +{ + 16, 16, 16, 16, 16, 16, 16, 8, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16 +}; +// 0 - sp+mp, 1 - sp only, 2 - mp only +char shrineavail[26] = +{ + 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, + 0, 0, 0, 0, 0, 2 +}; +char *StoryBookName[9] = +{ + "The Great Conflict", + "The Wages of Sin are War", + "The Tale of the Horadrim", + "The Dark Exile", + "The Sin War", + "The Binding of the Three", + "The Realms Beyond", + "Tale of the Three", + "The Black King" +}; +int StoryText[3][3] = +{ + { TEXT_BOOK11, TEXT_BOOK12, TEXT_BOOK13 }, + { TEXT_BOOK21, TEXT_BOOK22, TEXT_BOOK23 }, + { TEXT_BOOK31, TEXT_BOOK32, TEXT_BOOK33 } +}; + +void InitObjectGFX() +{ + int i, t; + BOOLEAN fileload[56]; + char filestr[32]; + + memset(fileload, 0, sizeof(fileload)); + + for(i = 0; AllObjects[i].oload != -1; i++) { + if(AllObjects[i].oload == 1 && currlevel >= AllObjects[i].ominlvl && currlevel <= AllObjects[i].omaxlvl) { + fileload[AllObjects[i].ofindex] = TRUE; + } + if(AllObjects[i].otheme != -1) { + for(t = 0; t < numthemes; t++) { + if(themes[t].ttype == AllObjects[i].otheme) { + fileload[AllObjects[i].ofindex] = TRUE; + } + } + } + if(AllObjects[i].oquest != -1 && QuestStatus(AllObjects[i].oquest)) { + fileload[AllObjects[i].ofindex] = TRUE; + } + } + + /// ASSERT: assert(numobjfiles == 0); + for(i = 0; i < (int)sizeof(fileload); i++) { + if(fileload[i]) { + ObjFileList[numobjfiles] = i; + sprintf(filestr, "Objects\\%s.CEL", ObjMasterLoadList[i]); + /// ASSERT: assert(! pObjCels[numobjfiles]); + pObjCels[numobjfiles] = DiabLoad(filestr, NULL, 'OGFX'); + numobjfiles++; + } + } +} + +void FreeObjectGFX() +{ + int i; + + for(i = 0; i < numobjfiles; i++) { + MemFreeDbg(pObjCels[i]); + } + + numobjfiles = 0; +} + +BOOL RndLocOk(int xp, int yp) +{ + if(dMonster[xp][yp] != 0) { + return FALSE; + } + if(dPlayer[xp][yp] != 0) { + return FALSE; + } + if(dObject[xp][yp] != 0) { + return FALSE; + } + if(dFlags[xp][yp] & 8) { + return FALSE; + } + if(nSolidTable[dPiece[xp][yp]]) { + return FALSE; + } + if(leveltype == DTYPE_CATHEDRAL && dPiece[xp][yp] > 126 && dPiece[xp][yp] < 144) { + return FALSE; + } + + return TRUE; +} + +void InitRndLocObj(int min, int max, int objtype) +{ + int i, xp, yp, numobjs; + + numobjs = random(139, max - min) + min; + + for(i = 0; i < numobjs; i++) { + while(1) { + xp = random(139, 80) + 16; + yp = random(139, 80) + 16; + if(RndLocOk(xp - 1, yp - 1) + && RndLocOk(xp, yp - 1) + && RndLocOk(xp + 1, yp - 1) + && RndLocOk(xp - 1, yp) + && RndLocOk(xp, yp) + && RndLocOk(xp + 1, yp) + && RndLocOk(xp - 1, yp + 1) + && RndLocOk(xp, yp + 1) + && RndLocOk(xp + 1, yp + 1)) { + AddObject(objtype, xp, yp); + break; + } + } + } +} + +void InitRndLocBigObj(int min, int max, int objtype) +{ + int i, xp, yp, numobjs; + + numobjs = random(140, max - min) + min; + + for(i = 0; i < numobjs; i++) { + while(1) { + xp = random(140, 80) + 16; + yp = random(140, 80) + 16; + if(RndLocOk(xp - 1, yp - 2) + && RndLocOk(xp, yp - 2) + && RndLocOk(xp + 1, yp - 2) + && RndLocOk(xp - 1, yp - 1) + && RndLocOk(xp, yp - 1) + && RndLocOk(xp + 1, yp - 1) + && RndLocOk(xp - 1, yp) + && RndLocOk(xp, yp) + && RndLocOk(xp + 1, yp) + && RndLocOk(xp - 1, yp + 1) + && RndLocOk(xp, yp + 1) + && RndLocOk(xp + 1, yp + 1)) { + AddObject(objtype, xp, yp); + break; + } + } + } +} + +void InitRndLocObj5x5(int min, int max, int objtype) +{ + int i, xp, yp, xx, yy, cnt, numobjs; + BOOL done; + + numobjs = random(139, max - min) + min; + + for(i = 0; i < numobjs; i++) { + cnt = 0; + done = FALSE; + while(!done) { + done = TRUE; + xp = random(139, 80) + 16; + yp = random(139, 80) + 16; + for(yy = -2; yy <= 2; yy++) { + for(xx = -2; xx <= 2; xx++) { + if(!RndLocOk(xx + xp, yy + yp)) { + done = FALSE; + } + } + } + if(!done) { + cnt++; + if(cnt > 20000) { + return; + } + } + } + AddObject(objtype, xp, yp); + } +} + +void ClrAllObjects() +{ + int i; + + for(i = 0; i < MAXOBJECTS; i++) { + object[i]._ox = 0; + object[i]._oy = 0; + object[i]._oAnimData = NULL; + object[i]._oAnimDelay = 0; + object[i]._oAnimCnt = 0; + object[i]._oAnimLen = 0; + object[i]._oAnimFrame = 0; + object[i]._oDelFlag = 0; + object[i]._oVar1 = 0; + object[i]._oVar2 = 0; + object[i]._oVar3 = 0; + object[i]._oVar4 = 0; + } + + nobjects = 0; + + for(i = 0; i < MAXOBJECTS; i++) { + objectavail[i] = i; + objectactive[i] = 0; + } + + trapid = 1; + trapdir = 0; + leverid = 1; +} + +void AddTortures() +{ + int xp, yp; + + for(yp = 0; yp < MAXDUNY; yp++) { + for(xp = 0; xp < MAXDUNX; xp++) { + if(dPiece[xp][yp] == 367) { + AddObject(OBJ_TORTURE1, xp, yp + 1); + AddObject(OBJ_TORTURE3, xp + 2, yp - 1); + AddObject(OBJ_TORTURE2, xp, yp + 3); + AddObject(OBJ_TORTURE4, xp + 4, yp - 1); + AddObject(OBJ_TORTURE5, xp, yp + 5); + AddObject(OBJ_TNUDEM1, xp + 1, yp + 3); + AddObject(OBJ_TNUDEM2, xp + 4, yp + 5); + AddObject(OBJ_TNUDEM3, xp + 2, yp); + AddObject(OBJ_TNUDEM4, xp + 3, yp + 2); + AddObject(OBJ_TNUDEW1, xp + 2, yp + 4); + AddObject(OBJ_TNUDEW2, xp + 2, yp + 1); + AddObject(OBJ_TNUDEW3, xp + 4, yp + 2); + } + } + } +} + +void AddCandles() +{ + int xp, yp; + + xp = quests[Q_PWATER]._qtx; + yp = quests[Q_PWATER]._qty; + AddObject(OBJ_STORYCANDLE, xp - 2, yp + 1); + AddObject(OBJ_STORYCANDLE, xp + 3, yp + 1); + AddObject(OBJ_STORYCANDLE, xp - 1, yp + 2); + AddObject(OBJ_STORYCANDLE, xp + 2, yp + 2); +} + +void AddBookLever(int lx1, int ly1, int lx2, int ly2, int x1, int y1, int x2, int y2, int msg) +{ + int i, xp, yp, xx, yy, cnt; + BOOL done; + + cnt = 0; + done = FALSE; + while(!done) { + done = TRUE; + xp = random(139, 80) + 16; + yp = random(139, 80) + 16; + for(yy = -2; yy <= 2; yy++) { + for(xx = -2; xx <= 2; xx++) { + if(!RndLocOk(xx + xp, yy + yp)) { + done = FALSE; + } + } + } + if(!done) { + cnt++; + if(cnt > 20000) { + return; + } + } + } + + if(QuestStatus(Q_BLIND)) { + AddObject(OBJ_BLINDBOOK, xp, yp); + } + if(QuestStatus(Q_WARLORD)) { + AddObject(OBJ_STEELTOME, xp, yp); + } + if(QuestStatus(Q_BLOOD)) { + xp = 2 * setpc_x + 25; + yp = 2 * setpc_y + 40; + AddObject(OBJ_BLOODBOOK, xp, yp); + } + + /// ASSERT: assert((DWORD)xp < MAXDUNX); + /// ASSERT: assert((DWORD)yp < MAXDUNY); + i = dObject[xp][yp] - 1; + /// ASSERT: assert((DWORD)i < MAXOBJECTS); + SetObjMapRange(i, x1, y1, x2, y2, leverid); + SetBookMsg(i, msg); + leverid++; + object[i]._oVar6 = object[i]._oAnimFrame + 1; +} + +void InitRndBarrels() +{ + int i, xp, yp, o, c, t, d, numobjs; + BOOL found; + + numobjs = random(143, 5) + 3; + + for(i = 0; i < numobjs; i++) { + do { + xp = random(143, 80) + 16; + yp = random(143, 80) + 16; + } while(!RndLocOk(xp, yp)); + if(random(143, 4) != 0) { + o = OBJ_BARREL; + } else { + o = OBJ_BARRELEX; + } + AddObject(o, xp, yp); + c = 1; + found = TRUE; + while(random(143, c >> 1) == 0 && found) { + t = 0; + found = FALSE; + while(!found && t < 3) { + d = random(143, 8); + xp += bxadd[d]; + yp += byadd[d]; + found = RndLocOk(xp, yp); + t++; + } + if(found) { + if(random(143, 5) != 0) { + o = OBJ_BARREL; + } else { + o = OBJ_BARRELEX; + } + AddObject(o, xp, yp); + c++; + } + } + } +} + +void AddL1Objs(int x1, int y1, int x2, int y2) +{ + int i, j, pn; + + for(j = y1; j < y2; j++) { + for(i = x1; i < x2; i++) { + pn = dPiece[i][j]; + if(pn == 270) { + AddObject(OBJ_L1LIGHT, i, j); + } + if(pn == 44 || pn == 51 || pn == 214) { + AddObject(OBJ_L1LDOOR, i, j); + } + if(pn == 46 || pn == 56) { + AddObject(OBJ_L1RDOOR, i, j); + } + } + } +} + +void AddL2Objs(int x1, int y1, int x2, int y2) +{ + int i, j, pn; + + for(j = y1; j < y2; j++) { + for(i = x1; i < x2; i++) { + pn = dPiece[i][j]; + if(pn == 13 || pn == 541) { + AddObject(OBJ_L2LDOOR, i, j); + } + if(pn == 17 || pn == 542) { + AddObject(OBJ_L2RDOOR, i, j); + } + } + } +} + +void AddL3Objs(int x1, int y1, int x2, int y2) +{ + int i, j, pn; + + for(j = y1; j < y2; j++) { + for(i = x1; i < x2; i++) { + pn = dPiece[i][j]; + if(pn == 531) { + AddObject(OBJ_L3LDOOR, i, j); + } + if(pn == 534) { + AddObject(OBJ_L3RDOOR, i, j); + } + } + } +} + +BOOL WallTrapLocOk(int xp, int yp) +{ + if(dFlags[xp][yp] & 8) { + return FALSE; + } + + return TRUE; +} + +void AddL2Torches() +{ + int i, j, pn; + + for(j = 0; j < MAXDUNY; j++) { + for(i = 0; i < MAXDUNX; i++) { + if(WallTrapLocOk(i, j)) { + pn = dPiece[i][j]; + if(pn == 1 && random(145, 3) == 0) { + AddObject(OBJ_TORCHL2, i, j); + } + if(pn == 5 && random(145, 3) == 0) { + AddObject(OBJ_TORCHR2, i, j); + } + if(pn == 37 && random(145, 10) == 0 && dObject[i - 1][j] == 0) { + AddObject(OBJ_TORCHL, i - 1, j); + } + if(pn == 41 && random(145, 10) == 0 && dObject[i][j - 1] == 0) { + AddObject(OBJ_TORCHR, i, j - 1); + } + } + } + } +} + +BOOL TorchLocOK(int xp, int yp) +{ + if(dFlags[xp][yp] & 8) { + return FALSE; + } + if(!nTrapTable[dPiece[xp][yp]]) { + return FALSE; + } + + return TRUE; +} + +void AddObjTraps() +{ + int i, j, x, y, rndv; + char oi, oti; + + if(currlevel == 1) { + rndv = 10; + } + if(currlevel >= 2) { + rndv = 15; + } + if(currlevel >= 5) { + rndv = 20; + } + if(currlevel >= 7) { + rndv = 25; + } + + for(j = 0; j < MAXDUNY; j++) { + for(i = 0; i < MAXDUNX; i++) { + if(dObject[i][j] > 0 && random(144, 100) < rndv) { + oi = dObject[i][j] - 1; + if(AllObjects[object[oi]._otype].oTrapFlag) { + x = i; + y = j; + if(random(144, 2) == 0) { + x--; + while(!nSolidTable[dPiece[x][y]]) { + x--; + } + if(TorchLocOK(x, y) && i - x > 1) { + AddObject(OBJ_TRAPL, x, y); + oti = dObject[x][y] - 1; + object[oti]._oVar1 = i; + object[oti]._oVar2 = j; + object[oi]._oTrapFlag = 1; + } + } else { + y--; + while(!nSolidTable[dPiece[x][y]]) { + y--; + } + if(TorchLocOK(x, y) && j - y > 1) { + AddObject(OBJ_TRAPR, x, y); + oti = dObject[x][y] - 1; + object[oti]._oVar1 = i; + object[oti]._oVar2 = j; + object[oi]._oTrapFlag = 1; + } + } + } + } + } + } +} + +void AddChestTraps() +{ + int i, j; + char oi; + + for(j = 0; j < MAXDUNY; j++) { + for(i = 0; i < MAXDUNX; i++) { + if(dObject[i][j] > 0) { + oi = dObject[i][j] - 1; + if(object[oi]._otype >= OBJ_CHEST1 && object[oi]._otype <= OBJ_CHEST3 && !object[oi]._oTrapFlag && random(0, 100) < 10) { + object[oi]._otype += OBJ_TCHEST1 - OBJ_CHEST1; + object[oi]._oTrapFlag = 1; + if(leveltype == DTYPE_CATACOMBS) { + object[oi]._oVar4 = random(0, 2); + } else { + object[oi]._oVar4 = random(0, 3); + } + } + } + } + } +} + +void LoadMapObjects(BYTE *pMap, int startx, int starty, int x1, int y1, int w, int h, int leveridx) +{ + int i, j, rw, rh, ot, ox, oy, oi; + long mapoff; + BYTE *lm; + + InitObjFlag = 1; + + lm = pMap; + rw = *lm; + lm += 2; + rh = *lm; + mapoff = 2 * rw * rh + 2; + rw <<= 1; + rh <<= 1; + mapoff += 4 * rw * rh; + lm += mapoff; + + for(j = 0; j < rh; j++) { + for(i = 0; i < rw; i++) { + if(*lm != 0) { + ot = *lm; + ox = i + startx + 16; + oy = j + starty + 16; + AddObject(ObjTypeConv[ot], ox, oy); + oi = ObjIndex(ox, oy); + SetObjMapRange(oi, x1, y1, x1 + w, y1 + h, leveridx); + } + lm += 2; + } + } + + InitObjFlag = 0; +} + +void LoadMapObjs(BYTE *pMap, int startx, int starty) +{ + int i, j, rw, rh, ot, ox, oy; + long mapoff; + BYTE *lm; + + InitObjFlag = 1; + + lm = pMap; + rw = *lm; + lm += 2; + rh = *lm; + mapoff = 2 * rw * rh + 2; + rw <<= 1; + rh <<= 1; + mapoff += 4 * rw * rh; + lm += mapoff; + + for(j = 0; j < rh; j++) { + for(i = 0; i < rw; i++) { + if(*lm != 0) { + ot = *lm; + ox = i + startx + 16; + oy = j + starty + 16; + AddObject(ObjTypeConv[ot], ox, oy); + } + lm += 2; + } + } + + InitObjFlag = 0; +} + +void AddDiabObjs() +{ + BYTE *lpSetPiece; + + lpSetPiece = DiabLoad("Levels\\L4Data\\diab1.DUN", NULL, 'STPC'); + LoadMapObjects(lpSetPiece, 2 * diabquad1x, 2 * diabquad1y, diabquad2x, diabquad2y, 11, 12, 1); + MemFreeDbg(lpSetPiece); + lpSetPiece = DiabLoad("Levels\\L4Data\\diab2a.DUN", NULL, 'STPC'); + LoadMapObjects(lpSetPiece, 2 * diabquad2x, 2 * diabquad2y, diabquad3x, diabquad3y, 11, 11, 2); + MemFreeDbg(lpSetPiece); + lpSetPiece = DiabLoad("Levels\\L4Data\\diab3a.DUN", NULL, 'STPC'); + LoadMapObjects(lpSetPiece, 2 * diabquad3x, 2 * diabquad3y, diabquad4x, diabquad4y, 9, 9, 3); + MemFreeDbg(lpSetPiece); +} + +void AddStoryBooks() +{ + int xp, yp, xx, yy, cnt; + BOOL done; + + cnt = 0; + done = FALSE; + while(!done) { + done = TRUE; + xp = random(139, 80) + 16; + yp = random(139, 80) + 16; + for(yy = -2; yy <= 2; yy++) { + for(xx = -3; xx <= 3; xx++) { + if(!RndLocOk(xx + xp, yy + yp)) { + done = FALSE; + } + } + } + if(!done) { + cnt++; + if(cnt > 20000) { + return; + } + } + } + + AddObject(OBJ_STORYBOOK, xp, yp); + AddObject(OBJ_STORYCANDLE, xp - 2, yp + 1); + AddObject(OBJ_STORYCANDLE, xp - 2, yp); + AddObject(OBJ_STORYCANDLE, xp - 1, yp - 1); + AddObject(OBJ_STORYCANDLE, xp + 1, yp - 1); + AddObject(OBJ_STORYCANDLE, xp + 2, yp); + AddObject(OBJ_STORYCANDLE, xp + 2, yp + 1); +} + +void AddHookedBodies(int freq) +{ + int i, j, ii, jj; + + for(j = 0; j < DMAXY; j++) { + jj = 2 * j + 16; + for(i = 0; i < DMAXX; i++) { + ii = 2 * i + 16; + if(dungeon[i][j] == 1 || dungeon[i][j] == 2) { + if(random(0, freq) == 0 && SkipThemeRoom(i, j)) { + if(dungeon[i][j] == 1 && dungeon[i + 1][j] == 6) { + switch(random(0, 3)) { + case 0: + AddObject(OBJ_TORTURE1, ii + 1, jj); + break; + case 1: + AddObject(OBJ_TORTURE2, ii + 1, jj); + break; + case 2: + AddObject(OBJ_TORTURE5, ii + 1, jj); + break; + } + } else if(dungeon[i][j] == 2 && dungeon[i][j + 1] == 6) { + switch(random(0, 2)) { + case 0: + AddObject(OBJ_TORTURE3, ii, jj); + break; + case 1: + AddObject(OBJ_TORTURE4, ii, jj); + break; + } + } + } + } + } + } +} + +void AddL4Goodies() +{ + AddHookedBodies(6); + InitRndLocObj(2, 6, OBJ_TNUDEM1); + InitRndLocObj(2, 6, OBJ_TNUDEM2); + InitRndLocObj(2, 6, OBJ_TNUDEM3); + InitRndLocObj(2, 6, OBJ_TNUDEM4); + InitRndLocObj(2, 6, OBJ_TNUDEW1); + InitRndLocObj(2, 6, OBJ_TNUDEW2); + InitRndLocObj(2, 6, OBJ_TNUDEW3); + InitRndLocObj(2, 6, OBJ_DECAP); + InitRndLocObj(1, 3, OBJ_CAULDRON); +} + +void AddLazStand() +{ + int xp, yp, xx, yy, cnt; + BOOL done; + + cnt = 0; + done = FALSE; + while(!done) { + done = TRUE; + xp = random(139, 80) + 16; + yp = random(139, 80) + 16; + for(yy = -3; yy <= 3; yy++) { + for(xx = -2; xx <= 3; xx++) { + if(!RndLocOk(xx + xp, yy + yp)) { + done = FALSE; + } + } + } + if(!done) { + cnt++; + if(cnt > 10000) { + InitRndLocObj(1, 1, OBJ_LAZSTAND); + return; + } + } + } + + AddObject(OBJ_LAZSTAND, xp, yp); + AddObject(OBJ_TNUDEM2, xp, yp + 2); + AddObject(OBJ_STORYCANDLE, xp + 1, yp + 2); + AddObject(OBJ_TNUDEM3, xp + 2, yp + 2); + AddObject(OBJ_TNUDEW1, xp, yp - 2); + AddObject(OBJ_STORYCANDLE, xp + 1, yp - 2); + AddObject(OBJ_TNUDEW2, xp + 2, yp - 2); + AddObject(OBJ_STORYCANDLE, xp - 1, yp - 1); + AddObject(OBJ_TNUDEW3, xp - 1, yp); + AddObject(OBJ_STORYCANDLE, xp - 1, yp + 1); +} + +void InitObjects() +{ + int textdef; + BYTE *setp; + + ClrAllObjects(); + + if(currlevel == 16) { + AddDiabObjs(); + return; + } + + InitObjFlag = 1; + GetRndSeed(); + + if(currlevel == 9 && gbMaxPlayers == 1) { + AddSlainHero(); + } + if(currlevel == quests[Q_MUSHROOM]._qlevel && quests[Q_MUSHROOM]._qactive == 1) { + AddMushPatch(); + } + if(currlevel == 4) { + AddStoryBooks(); + } + if(currlevel == 8) { + AddStoryBooks(); + } + if(currlevel == 12) { + AddStoryBooks(); + } + + if(leveltype == DTYPE_CATHEDRAL) { + if(QuestStatus(Q_BUTCHER)) { + AddTortures(); + } + if(QuestStatus(Q_PWATER)) { + AddCandles(); + } + if(QuestStatus(Q_LTBANNER)) { + AddObject(OBJ_SIGNCHEST, 2 * setpc_x + 26, 2 * setpc_y + 19); + } + InitRndLocBigObj(10, 15, OBJ_SARC); + AddL1Objs(0, 0, 112, 112); + InitRndBarrels(); + } + if(leveltype == DTYPE_CATACOMBS) { + if(QuestStatus(Q_ROCK)) { + InitRndLocObj5x5(1, 1, OBJ_STAND); + } + if(QuestStatus(Q_SCHAMB)) { + InitRndLocObj5x5(1, 1, OBJ_BOOK2R); + } + AddL2Objs(0, 0, 112, 112); + AddL2Torches(); + if(QuestStatus(Q_BLIND)) { + if(plr[myplr]._pClass == PC_WARRIOR) { + textdef = TEXT_BLINDING; + } else if(plr[myplr]._pClass == PC_ROGUE) { + textdef = TEXT_RBLINDING; + } else if(plr[myplr]._pClass == PC_SORCERER) { + textdef = TEXT_MBLINDING; + } + quests[Q_BLIND]._qmsg = textdef; + AddBookLever(0, 0, 112, 112, setpc_x, setpc_y, setpc_x + setpc_w + 1, setpc_y + setpc_h + 1, textdef); + setp = DiabLoad("Levels\\L2Data\\Blind2.DUN", NULL, 'STPC'); + LoadMapObjs(setp, 2 * setpc_x, 2 * setpc_y); + MemFreeDbg(setp); + } + if(QuestStatus(Q_BLOOD)) { + if(plr[myplr]._pClass == PC_WARRIOR) { + textdef = TEXT_BLOODY; + } else if(plr[myplr]._pClass == PC_ROGUE) { + textdef = TEXT_RBLOODY; + } else if(plr[myplr]._pClass == PC_SORCERER) { + textdef = TEXT_MBLOODY; + } + quests[Q_BLOOD]._qmsg = textdef; + AddBookLever(0, 0, 112, 112, setpc_x, setpc_y + 3, setpc_x + 2, setpc_y + 7, textdef); + AddObject(OBJ_PEDISTAL, 2 * setpc_x + 25, 2 * setpc_y + 32); + } + InitRndBarrels(); + } + if(leveltype == DTYPE_CAVES) { + AddL3Objs(0, 0, 112, 112); + InitRndBarrels(); + } + if(leveltype == DTYPE_HELL) { + if(QuestStatus(Q_WARLORD)) { + if(plr[myplr]._pClass == PC_WARRIOR) { + textdef = TEXT_BLOODWAR; + } else if(plr[myplr]._pClass == PC_ROGUE) { + textdef = TEXT_RBLOODWAR; + } else if(plr[myplr]._pClass == PC_SORCERER) { + textdef = TEXT_MBLOODWAR; + } + quests[Q_WARLORD]._qmsg = textdef; + AddBookLever(0, 0, 112, 112, setpc_x, setpc_y, setpc_x + setpc_w, setpc_y + setpc_h, textdef); + setp = DiabLoad("Levels\\L4Data\\Warlord.DUN", NULL, 'STPC'); + LoadMapObjs(setp, 2 * setpc_x, 2 * setpc_y); + MemFreeDbg(setp); + } + if(QuestStatus(Q_BETRAYER) && gbMaxPlayers == 1) { + AddLazStand(); + } + InitRndBarrels(); + AddL4Goodies(); + } + + InitRndLocObj(5, 10, 5); + InitRndLocObj(3, 6, 6); + InitRndLocObj(1, 5, 7); + + if(leveltype != DTYPE_HELL) { + AddObjTraps(); + } + if(leveltype > DTYPE_CATHEDRAL) { + AddChestTraps(); + } + + InitObjFlag = 0; +} + +void SetMapObjects(BYTE *pMap, int startx, int starty) +{ + int i, j, rw, rh, ot, ox, oy; + long mapoff; + BYTE *lm, *h; + BOOL fileload[56]; + char filestr[32]; + + ClrAllObjects(); + InitObjFlag = 1; + + for(i = 0; i < sizeof(fileload) / sizeof(fileload[0]); i++) { + fileload[i] = FALSE; + } + + for(i = 0; AllObjects[i].oload != -1; i++) { + if(AllObjects[i].oload == 1 && leveltype == AllObjects[i].olvltype) { + fileload[AllObjects[i].ofindex] = TRUE; + } + } + + lm = pMap; + rw = *lm; + lm += 2; + rh = *lm; + mapoff = 2 * rw * rh + 2; + rw <<= 1; + rh <<= 1; + mapoff += 4 * rw * rh; + lm += mapoff; + h = lm; + + for(j = 0; j < rh; j++) { + for(i = 0; i < rw; i++) { + if(*lm != 0) { + ot = *lm; + ot = ObjTypeConv[ot]; + fileload[AllObjects[ot].ofindex] = TRUE; + } + lm += 2; + } + } + + /// ASSERT: assert(numobjfiles == 0); + for(i = 0; i < (int)(sizeof(fileload) / sizeof(fileload[0])); i++) { + if(fileload[i]) { + ObjFileList[numobjfiles] = i; + sprintf(filestr, "Objects\\%s.CEL", ObjMasterLoadList[i]); + /// ASSERT: assert(! pObjCels[numobjfiles]); + pObjCels[numobjfiles] = DiabLoad(filestr, NULL, 'OGFX'); + numobjfiles++; + } + } + + lm = h; + for(j = 0; j < rh; j++) { + for(i = 0; i < rw; ++i) { + if(*lm != 0) { + ot = *lm; + ox = i + startx + 16; + oy = j + starty + 16; + AddObject(ObjTypeConv[ot], ox, oy); + } + lm += 2; + } + } + + InitObjFlag = 0; +} + +void DeleteObject_(int oi, int i) +{ + int ox, oy; + + /// ASSERT: assert((DWORD)oi < MAXOBJECTS); + ox = object[oi]._ox; + oy = object[oi]._oy; + dObject[ox][oy] = 0; + objectavail[MAXOBJECTS - nobjects] = oi; + nobjects--; + + if(nobjects > 0 && i != nobjects) { + objectactive[i] = objectactive[nobjects]; + } +} + +void SetupObject(int i, int x, int y, int ot) +{ + int ai, j; + + /// ASSERT: assert((DWORD)i < MAXOBJECTS); + object[i]._otype = ot; + object[i]._ox = x; + object[i]._oy = y; + + ai = AllObjects[ot].ofindex; + j = 0; + while(ObjFileList[j] != ai) { + j++; + } + + object[i]._oAnimData = pObjCels[j]; + object[i]._oAnimFlag = AllObjects[ot].oAnimFlag; + + if(object[i]._oAnimFlag != 0) { + object[i]._oAnimDelay = AllObjects[ot].oAnimDelay; + object[i]._oAnimCnt = random(146, AllObjects[ot].oAnimDelay); + object[i]._oAnimLen = AllObjects[ot].oAnimLen; + object[i]._oAnimFrame = random(146, AllObjects[ot].oAnimLen - 1) + 1; + } else { + object[i]._oAnimDelay = 1000; + object[i]._oAnimCnt = 0; + object[i]._oAnimLen = AllObjects[ot].oAnimLen; + object[i]._oAnimFrame = AllObjects[ot].oAnimDelay; + } + + object[i]._oAnimWidth = AllObjects[ot].oAnimWidth; + object[i]._oSolidFlag = AllObjects[ot].oSolidFlag; + object[i]._oMissFlag = AllObjects[ot].oMissFlag; + object[i]._oLight = AllObjects[ot].oLightFlag; + object[i]._oDelFlag = 0; + object[i]._oBreak = AllObjects[ot].oBreak; + object[i]._oSelFlag = AllObjects[ot].oSelFlag; + object[i]._oPreFlag = 0; + object[i]._oTrapFlag = 0; + object[i]._oDoorFlag = 0; +} + +void SetObjMapRange(int i, int x1, int y1, int x2, int y2, int v) +{ + /// ASSERT: assert((DWORD)i < MAXOBJECTS); + object[i]._oVar1 = x1; + object[i]._oVar2 = y1; + object[i]._oVar3 = x2; + object[i]._oVar4 = y2; + object[i]._oVar8 = v; +} + +void SetBookMsg(int i, int msg) +{ + /// ASSERT: assert((DWORD)i < MAXOBJECTS); + object[i]._oVar7 = msg; +} + +void AddL1Door(int i, int x, int y, int ot) +{ + /// ASSERT: assert((DWORD)i < MAXOBJECTS); + object[i]._oDoorFlag = 1; + + if(ot == OBJ_L1LDOOR) { + object[i]._oVar1 = dPiece[x][y]; + object[i]._oVar2 = dPiece[x][y - 1]; + } else { + object[i]._oVar1 = dPiece[x][y]; + object[i]._oVar2 = dPiece[x - 1][y]; + } + + object[i]._oVar4 = 0; +} + +void AddSCambBook(int i) +{ + /// ASSERT: assert((DWORD)i < MAXOBJECTS); + object[i]._oVar1 = setpc_x; + object[i]._oVar2 = setpc_y; + object[i]._oVar3 = setpc_x + setpc_w + 1; + object[i]._oVar4 = setpc_y + setpc_h + 1; + object[i]._oVar6 = object[i]._oAnimFrame + 1; +} + +void AddChest(int i, int t) +{ + /// ASSERT: assert((DWORD)i < MAXOBJECTS); + + if(random(147, 2) == 0) { + object[i]._oAnimFrame += 3; + } + + object[i]._oRndSeed = GetRndSeed(); + + switch(t) { + case OBJ_CHEST1: + case OBJ_TCHEST1: + if(setlevel) { + object[i]._oVar1 = 1; + } else { + object[i]._oVar1 = random(147, 2); + } + break; + case OBJ_CHEST2: + case OBJ_TCHEST2: + if(setlevel) { + object[i]._oVar1 = 2; + } else { + object[i]._oVar1 = random(147, 3); + } + break; + case OBJ_CHEST3: + case OBJ_TCHEST3: + if(setlevel) { + object[i]._oVar1 = 3; + } else { + object[i]._oVar1 = random(147, 4); + } + break; + } + + object[i]._oVar2 = random(147, 8); +} + +void AddL2Door(int i, int x, int y, int ot) +{ + /// ASSERT: assert((DWORD)i < MAXOBJECTS); + object[i]._oDoorFlag = 1; + + if(ot == OBJ_L2LDOOR) { + ObjSetMicro(x, y, 538); + } else { + ObjSetMicro(x, y, 540); + } + + object[i]._oVar4 = 0; +} + +void AddL3Door(int i, int x, int y, int ot) +{ + /// ASSERT: assert((DWORD)i < MAXOBJECTS); + object[i]._oDoorFlag = 1; + + if(ot == OBJ_L3LDOOR) { + ObjSetMicro(x, y, 531); + } else { + ObjSetMicro(x, y, 534); + } + + object[i]._oVar4 = 0; +} + +void AddSarc(int i) +{ + int x, y; + + /// ASSERT: assert((DWORD)i < MAXOBJECTS); + x = object[i]._ox; + y = object[i]._oy - 1; + dObject[x][y] = -(i + 1); + object[i]._oVar1 = random(153, 10); + object[i]._oRndSeed = GetRndSeed(); + + if(object[i]._oVar1 >= 8) { + object[i]._oVar2 = PreSpawnSkeleton(); + } +} + +void AddFlameTrap(int i) +{ + /// ASSERT: assert((DWORD)i < MAXOBJECTS); + object[i]._oVar1 = trapid; + object[i]._oVar2 = 0; + object[i]._oVar3 = trapdir; + object[i]._oVar4 = 0; +} + +void AddFlameLvr(int i) +{ + /// ASSERT: assert((DWORD)i < MAXOBJECTS); + object[i]._oVar1 = trapid; + object[i]._oVar2 = OBJ_FLAMEHOLE; /* check, might be missile */ +} + +void AddTrap(int i, int ot) +{ + int mt, c; + + c = currlevel / 3 + 1; + mt = random(148, c); + + /// ASSERT: assert((DWORD)i < MAXOBJECTS); + if(mt == 0) { + object[i]._oVar3 = MIS_ARROW; + } + if(mt == 1) { + object[i]._oVar3 = MIS_FIREBOLT; + } + if(mt == 2) { + object[i]._oVar3 = MIS_LIGHTCTRL; + } + + object[i]._oVar4 = 0; +} + +void AddObjLight(int i, int r) +{ + /// ASSERT: assert((DWORD)i < MAXOBJECTS); + if(InitObjFlag) { + DoLighting(object[i]._ox, object[i]._oy, r, -1); + object[i]._oVar1 = -1; + } else { + object[i]._oVar1 = 0; + } +} + +void AddBarrel(int i, int ot) +{ + /// ASSERT: assert((DWORD)i < MAXOBJECTS); + object[i]._oVar1 = 0; + object[i]._oRndSeed = GetRndSeed(); + object[i]._oVar2 = random(149, 10); + object[i]._oVar3 = random(149, 3); + + if(object[i]._oVar2 >= 8) { + object[i]._oVar4 = PreSpawnSkeleton(); + } +} + +void AddShrine(int i) +{ + int st; + BOOL slist[26]; + + /// ASSERT: assert((DWORD)i < MAXOBJECTS); + object[i]._oPreFlag = 1; + + for(st = 0; st < 26; st++) { + if(currlevel >= shrinemin[st] && currlevel <= shrinemax[st]) { + slist[st] = TRUE; + } else { + slist[st] = FALSE; + } + if(gbMaxPlayers != 1 && shrineavail[st] == 1) { + slist[st] = FALSE; + } + if(gbMaxPlayers == 1 && shrineavail[st] == 2) { + slist[st] = FALSE; + } + } + + do { + st = random(150, 26); + } while(!slist[st]); + + object[i]._oVar1 = st; + + if(random(150, 2) != 0) { + object[i]._oAnimFrame = 12; + object[i]._oAnimLen = 22; + } +} + +void AddBookcase(int i) +{ + /// ASSERT: assert((DWORD)i < MAXOBJECTS); + object[i]._oRndSeed = GetRndSeed(); + object[i]._oPreFlag = 1; +} + +void AddBookstand(int i) +{ + /// ASSERT: assert((DWORD)i < MAXOBJECTS); + object[i]._oRndSeed = GetRndSeed(); +} + +void AddBloodFtn(int i) +{ + /// ASSERT: assert((DWORD)i < MAXOBJECTS); + object[i]._oRndSeed = GetRndSeed(); +} + +void AddPurifyingFountain(int i) +{ + int x, y; + + /// ASSERT: assert((DWORD)i < MAXOBJECTS); + x = object[i]._ox; + y = object[i]._oy; + dObject[x][y - 1] = -(i + 1); + dObject[x - 1][y] = -(i + 1); + dObject[x - 1][y - 1] = -(i + 1); + object[i]._oRndSeed = GetRndSeed(); +} + +void AddArmorStand(int i) +{ + /// ASSERT: assert((DWORD)i < MAXOBJECTS); + if(!armorFlag) { + object[i]._oAnimFlag = 2; + object[i]._oSelFlag = 0; + } + + object[i]._oRndSeed = GetRndSeed(); +} + +void AddGoatShrine(int i) +{ + /// ASSERT: assert((DWORD)i < MAXOBJECTS); + object[i]._oRndSeed = GetRndSeed(); +} + +void AddCauldron(int i) +{ + /// ASSERT: assert((DWORD)i < MAXOBJECTS); + object[i]._oRndSeed = GetRndSeed(); +} + +void AddMurkyFountain(int i) +{ + int x, y; + + /// ASSERT: assert((DWORD)i < MAXOBJECTS); + x = object[i]._ox; + y = object[i]._oy; + dObject[x][y - 1] = -(i + 1); + dObject[x - 1][y] = -(i + 1); + dObject[x - 1][y - 1] = -(i + 1); + object[i]._oRndSeed = GetRndSeed(); +} + +void AddTearFountain(int i) +{ + /// ASSERT: assert((DWORD)i < MAXOBJECTS); + object[i]._oRndSeed = GetRndSeed(); +} + +void AddDecap(int i) +{ + /// ASSERT: assert((DWORD)i < MAXOBJECTS); + object[i]._oRndSeed = GetRndSeed(); + object[i]._oAnimFrame = random(151, 8) + 1; + object[i]._oPreFlag = 1; +} + +void AddVilebook(int i) +{ + if(setlevel && setlvlnum == SL_VILEBETRAYER) { + /// ASSERT: assert((DWORD)i < MAXOBJECTS); + object[i]._oAnimFrame = 4; + } +} + +void AddMagicCircle(int i) +{ + /// ASSERT: assert((DWORD)i < MAXOBJECTS); + object[i]._oRndSeed = GetRndSeed(); + object[i]._oPreFlag = 1; + object[i]._oVar6 = 0; + object[i]._oVar5 = 1; +} + +void AddBrnCross(int i) +{ + /// ASSERT: assert((DWORD)i < MAXOBJECTS); + object[i]._oRndSeed = GetRndSeed(); +} + +void AddPedistal(int i) +{ + /// ASSERT: assert((DWORD)i < MAXOBJECTS); + object[i]._oVar1 = setpc_x; + object[i]._oVar2 = setpc_y; + object[i]._oVar3 = setpc_x + setpc_w; + object[i]._oVar4 = setpc_y + setpc_h; +} + +void AddStoryBook(int i) +{ + SetRndSeed(glSeedTbl[16]); + /// ASSERT: assert((DWORD)i < MAXOBJECTS); + object[i]._oVar1 = random(0, 3); + + if(currlevel == 4) { + object[i]._oVar2 = StoryText[object[i]._oVar1][0]; + } + if(currlevel == 8) { + object[i]._oVar2 = StoryText[object[i]._oVar1][1]; + } + if(currlevel == 12) { + object[i]._oVar2 = StoryText[object[i]._oVar1][2]; + } + + object[i]._oVar3 = (currlevel >> 2) + 3 * object[i]._oVar1 - 1; + object[i]._oAnimFrame = 5 - 2 * object[i]._oVar1; + object[i]._oVar4 = object[i]._oAnimFrame + 1; +} + +void AddWeaponRack(int i) +{ + /// ASSERT: assert((DWORD)i < MAXOBJECTS); + if(!weaponFlag) { + object[i]._oAnimFlag = 2; + object[i]._oSelFlag = 0; + } + + object[i]._oRndSeed = GetRndSeed(); +} + +void AddTorturedBody(int i) +{ + /// ASSERT: assert((DWORD)i < MAXOBJECTS); + object[i]._oRndSeed = GetRndSeed(); + object[i]._oAnimFrame = random(0, 4) + 1; + object[i]._oPreFlag = 1; +} + +void GetRndObjLoc(int randarea, int &xx, int &yy) +{ + int i, j, tries; + BOOL failed; + + if(randarea == 0) { + return; + } + + tries = 0; + + while(1) { + tries++; + if(tries > 1000 && randarea > 1) { + randarea--; + } + xx = random(0, MAXDUNX); + yy = random(0, MAXDUNY); + failed = FALSE; + for(i = 0; i < randarea && !failed; i++) { + for(j = 0; j < randarea && !failed; j++) { + failed = !RndLocOk(i + xx, j + yy); + } + } + if(!failed) { + break; + } + } +} + +void AddMushPatch() +{ + int i, x, y; + + if(nobjects >= MAXOBJECTS) { + return; + } + + i = objectavail[0]; + GetRndObjLoc(5, x, y); + dObject[x + 1][y + 1] = -(i + 1); + dObject[x + 2][y + 1] = -(i + 1); + dObject[x + 1][y + 2] = -(i + 1); + AddObject(OBJ_MUSHPATCH, x + 2, y + 2); +} + +void AddSlainHero() +{ + int x, y; + + GetRndObjLoc(5, x, y); + AddObject(OBJ_SLAINHERO, x + 2, y + 2); +} + +void AddObject(int ot, int ox, int oy) +{ + int oi; + + if(nobjects >= MAXOBJECTS) { + return; + } + + oi = objectavail[0]; + objectavail[0] = objectavail[MAXOBJECTS - nobjects - 1]; + objectactive[nobjects] = oi; + dObject[ox][oy] = oi + 1; + SetupObject(oi, ox, oy, ot); + + switch(ot) { + case OBJ_L1LIGHT: + AddObjLight(oi, 5); + break; + case OBJ_SKFIRE: + case OBJ_CANDLE1: + case OBJ_CANDLE2: + case OBJ_BOOKCANDLE: + AddObjLight(oi, 5); + break; + case OBJ_STORYCANDLE: + AddObjLight(oi, 3); + break; + case OBJ_TORCHL: + case OBJ_TORCHR: + case OBJ_TORCHL2: + case OBJ_TORCHR2: + AddObjLight(oi, 8); + break; + case OBJ_L1LDOOR: + case OBJ_L1RDOOR: + AddL1Door(oi, ox, oy, ot); + break; + case OBJ_L2LDOOR: + case OBJ_L2RDOOR: + AddL2Door(oi, ox, oy, ot); + break; + case OBJ_L3LDOOR: + case OBJ_L3RDOOR: + AddL3Door(oi, ox, oy, ot); + break; + case OBJ_BOOK2R: + AddSCambBook(oi); + break; + case OBJ_CHEST1: + case OBJ_CHEST2: + case OBJ_CHEST3: + case OBJ_TCHEST1: + case OBJ_TCHEST2: + case OBJ_TCHEST3: + AddChest(oi, ot); + break; + case OBJ_SARC: + AddSarc(oi); + break; + case OBJ_FLAMEHOLE: + AddFlameTrap(oi); + break; + case OBJ_FLAMELVR: + AddFlameLvr(oi); + break; + case OBJ_WATER: + /// ASSERT: assert((DWORD)oi < MAXOBJECTS); + object[oi]._oAnimFrame = 1; + break; + case OBJ_TRAPL: + case OBJ_TRAPR: + AddTrap(oi, ot); + break; + case OBJ_BARREL: + case OBJ_BARRELEX: + AddBarrel(oi, ot); + break; + case OBJ_SHRINEL: + case OBJ_SHRINER: + AddShrine(oi); + break; + case OBJ_BOOKCASEL: + case OBJ_BOOKCASER: + AddBookcase(oi); + break; + case OBJ_SKELBOOK: + case OBJ_BOOKSTAND: + AddBookstand(oi); + break; + case OBJ_BLOODFTN: + AddBloodFtn(oi); + break; + case OBJ_DECAP: + AddDecap(oi); + break; + case OBJ_PURIFYINGFTN: + AddPurifyingFountain(oi); + break; + case OBJ_ARMORSTAND: + case OBJ_WARARMOR: + AddArmorStand(oi); + break; + case OBJ_GOATSHRINE: + AddGoatShrine(oi); + break; + case OBJ_CAULDRON: + AddCauldron(oi); + break; + case OBJ_MURKYFTN: + AddMurkyFountain(oi); + break; + case OBJ_TEARFTN: + AddTearFountain(oi); + break; + case OBJ_BOOK2L: + AddVilebook(oi); + break; + case OBJ_MCIRCLE1: + case OBJ_MCIRCLE2: + AddMagicCircle(oi); + break; + case OBJ_STORYBOOK: + AddStoryBook(oi); + break; + case OBJ_BCROSS: + case OBJ_TBCROSS: + AddBrnCross(oi); + AddObjLight(oi, 5); + break; + case OBJ_PEDISTAL: + AddPedistal(oi); + break; + case OBJ_WARWEAP: + case OBJ_WEAPONRACK: + AddWeaponRack(oi); + break; + case OBJ_TNUDEM2: + AddTorturedBody(oi); + break; + } + + /// ASSERT: assert((DWORD)oi < MAXOBJECTS); + object[oi]._oAnimWidth2 = (object[oi]._oAnimWidth - 64) >> 1; + nobjects++; +} + +void Obj_Light(int i, int lr) +{ + int ox, oy, dx, dy, p, tr; + BOOL turnon; + + /// ASSERT: assert((DWORD)i < MAXOBJECTS); + if(object[i]._oVar1 == -1) { + return; + } + + ox = object[i]._ox; + oy = object[i]._oy; + tr = lr + 10; + turnon = FALSE; + + if(!lightflag) { + for(p = 0; p < MAX_PLRS && !turnon; p++) { + if(plr[p].plractive && currlevel == plr[p].plrlevel) { + dx = abs(plr[p].WorldX - ox); + dy = abs(plr[p].WorldY - oy); + if(dx < tr && dy < tr) { + turnon = TRUE; + } + } + } + } + + if(turnon) { + if(object[i]._oVar1 == 0) { + object[i]._olid = AddLight(ox, oy, lr); + } + object[i]._oVar1 = 1; + } else { + if(object[i]._oVar1 == 1) { + AddUnLight(object[i]._olid); + } + object[i]._oVar1 = 0; + } +} + +void Obj_Circle(int i) +{ + int px, py, ox, oy; + + /// ASSERT: assert((DWORD)i < MAXOBJECTS); + ox = object[i]._ox; + oy = object[i]._oy; + px = plr[myplr].WorldX; + py = plr[myplr].WorldY; + + if(px == ox && py == oy) { + if(object[i]._otype == OBJ_MCIRCLE1) { + object[i]._oAnimFrame = 2; + } + if(object[i]._otype == OBJ_MCIRCLE2) { + object[i]._oAnimFrame = 4; + } + if(ox == 45 && oy == 47) { + object[i]._oVar6 = 2; + } else if(ox == 26 && oy == 46) { + object[i]._oVar6 = 1; + } else { + object[i]._oVar6 = 0; + } + if(ox == 35 && oy == 36 && object[i]._oVar5 == 3) { + object[i]._oVar6 = 4; + ObjChangeMapResync(object[i]._oVar1, object[i]._oVar2, object[i]._oVar3, object[i]._oVar4); + if(quests[Q_BETRAYER]._qactive == 2) { + quests[Q_BETRAYER]._qvar1 = 4; + } + AddMissile(plr[myplr].WorldX, plr[myplr].WorldY, 35, 46, plr[myplr]._pdir, MIS_RNDTELEPORT, 0, myplr, 0, 0); + track_repeat_walk(0); + sgbMouseDown = 0; + ReleaseCapture(); + ClrPlrPath(myplr); + StartStand(myplr, 0); + } + } else { + if(object[i]._otype == OBJ_MCIRCLE1) { + object[i]._oAnimFrame = 1; + } + if(object[i]._otype == OBJ_MCIRCLE2) { + object[i]._oAnimFrame = 3; + } + object[i]._oVar6 = 0; + } +} + +void Obj_StopAnim(int i) +{ + /// ASSERT: assert((DWORD)i < MAXOBJECTS); + if(object[i]._oAnimFrame == object[i]._oAnimLen) { + object[i]._oAnimCnt = 0; + object[i]._oAnimDelay = 1000; + } +} + +void Obj_Door(int i) +{ + int dx, dy; + BOOL dok; + + /// ASSERT: assert((DWORD)i < MAXOBJECTS); + if(object[i]._oVar4 == 0) { + object[i]._oSelFlag = 3; + object[i]._oMissFlag = 0; + } else { + dx = object[i]._ox; + dy = object[i]._oy; + dok = dMonster[dx][dy] == 0; + dok &= dItem[dx][dy] == 0; + dok &= dDead[dx][dy] == 0; + dok &= dPlayer[dx][dy] == 0; + object[i]._oSelFlag = 2; + if(dok) { + object[i]._oVar4 = 1; + } else { + object[i]._oVar4 = 2; + } + object[i]._oMissFlag = 1; + } +} + +void Obj_Sarc(int i) +{ + /// ASSERT: assert((DWORD)i < MAXOBJECTS); + if(object[i]._oAnimFrame == object[i]._oAnimLen) { + object[i]._oAnimFlag = 0; + } +} + +void ActivateTrapLine(int ttype, int tid) +{ + int i, oi; + + for(i = 0; i < nobjects; i++) { + oi = objectactive[i]; + if(object[oi]._otype == ttype && object[oi]._oVar1 == tid) { + object[oi]._oVar4 = 1; + object[oi]._oAnimFlag = 1; + object[oi]._oAnimDelay = 1; + object[oi]._olid = AddLight(object[oi]._ox, object[oi]._oy, 1); + } + } +} + +void Obj_FlameTrap(int i) +{ + int xp, yp, j; + + /// ASSERT: assert((DWORD)i < MAXOBJECTS); + if(object[i]._oVar2 != 0) { + if(object[i]._oVar4 != 0) { + object[i]._oAnimFrame--; + if(object[i]._oAnimFrame == 1) { + object[i]._oVar4 = 0; + AddUnLight(object[i]._olid); + } else if(object[i]._oAnimFrame <= 4) { + ChangeLightRadius(object[i]._olid, object[i]._oAnimFrame); + } + } + } else if(object[i]._oVar4 == 0) { + if(object[i]._oVar3 == 2) { + xp = object[i]._ox - 2; + yp = object[i]._oy; + for(j = 0; j < 5; j++) { + if(dPlayer[xp][yp] != 0 || dMonster[xp][yp] != 0) { + object[i]._oVar4 = 1; + } + xp++; + } + } else { + xp = object[i]._ox; + yp = object[i]._oy - 2; + for(j = 0; j < 5; j++) { + if(dPlayer[xp][yp] != 0 || dMonster[xp][yp] != 0) { + object[i]._oVar4 = 1; + } + yp++; + } + } + if(object[i]._oVar4 != 0) { + ActivateTrapLine(object[i]._otype, object[i]._oVar1); + } + } else { + if(object[i]._oAnimFrame == object[i]._oAnimLen) { + object[i]._oAnimFrame = 11; + } + if(object[i]._oAnimFrame <= 5) { + ChangeLightRadius(object[i]._olid, object[i]._oAnimFrame); + } + } +} + +void Obj_Trap(int i) +{ + int oti, sx, sy, dx, dy, x, y, ax, ay, dir; + BOOL otrig; + + otrig = FALSE; + /// ASSERT: assert((DWORD)i < MAXOBJECTS); + if(object[i]._oVar4 != 0) { + return; + } + + oti = dObject[object[i]._oVar1][object[i]._oVar2] - 1; + switch(object[oti]._otype) { + case OBJ_LEVER: + case OBJ_CHEST1: + case OBJ_CHEST2: + case OBJ_CHEST3: + case OBJ_SWITCHSKL: + case OBJ_SARC: + if(object[oti]._oSelFlag == 0) { + otrig = TRUE; + } + break; + case OBJ_L1LDOOR: + case OBJ_L1RDOOR: + case OBJ_L2LDOOR: + case OBJ_L2RDOOR: + case OBJ_L3LDOOR: + case OBJ_L3RDOOR: + if(object[oti]._oVar4 != 0) { + otrig = TRUE; + } + break; + } + + if(otrig) { + object[i]._oVar4 = 1; + sx = object[i]._ox; + sy = object[i]._oy; + dx = object[oti]._ox; + dy = object[oti]._oy; + ax = dx; + ay = dy; + for(y = ay - 1; y <= ay + 1; y++) { + for(x = ax - 1; x <= ax + 1; x++) { + if(dPlayer[x][y] != 0) { + dx = x; + dy = y; + } + } + } + if(!deltaload) { + dir = GetDirection(sx, sy, dx, dy); + AddMissile(sx, sy, dx, dy, dir, object[i]._oVar3, 1, -1, 0, 0); + PlaySfxLoc(IS_TRAP, object[oti]._ox, object[oti]._oy); + } + object[oti]._oTrapFlag = 0; + } +} + +void Obj_BCrossDamage(int i) +{ + int resist; + int damage[4] = { 6, 8, 10, 12 }; + + if(plr[myplr]._pmode == PM_DEATH) { + return; + } + + resist = plr[myplr]._pFireResist; + if(resist > 0) { + damage[leveltype - 1] -= resist * damage[leveltype - 1] / 100; + } + + /// ASSERT: assert((DWORD)i < MAXOBJECTS); + if(plr[myplr].WorldX != object[i]._ox || plr[myplr].WorldY != object[i]._oy - 1) { + return; + } + + plr[myplr]._pHitPoints -= damage[leveltype - 1]; + plr[myplr]._pHPBase -= damage[leveltype - 1]; + + if(plr[myplr]._pHitPoints >> 6 <= 0) { + SyncPlrKill(myplr, 0); + } else { + if(plr[myplr]._pClass == PC_WARRIOR) { + PlaySfxLoc(PS_WARR68, plr[myplr].WorldX, plr[myplr].WorldY); + } 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); + } + } + + drawhpflag = 1; +} + +void ProcessObjects() +{ + int i, oi; + + for(i = 0; i < nobjects; i++) { + oi = objectactive[i]; + /// ASSERT: assert((DWORD)oi < MAXOBJECTS); + switch(object[oi]._otype) { + case OBJ_L1LIGHT: + Obj_Light(oi, 10); + break; + case OBJ_SKFIRE: + case OBJ_CANDLE2: + case OBJ_BOOKCANDLE: + Obj_Light(oi, 5); + break; + case OBJ_STORYCANDLE: + Obj_Light(oi, 3); + break; + case OBJ_CRUX1: + case OBJ_CRUX2: + case OBJ_CRUX3: + case OBJ_BARREL: + case OBJ_BARRELEX: + case OBJ_SHRINEL: + case OBJ_SHRINER: + Obj_StopAnim(oi); + break; + case OBJ_L1LDOOR: + case OBJ_L1RDOOR: + case OBJ_L2LDOOR: + case OBJ_L2RDOOR: + case OBJ_L3LDOOR: + case OBJ_L3RDOOR: + Obj_Door(oi); + break; + case OBJ_TORCHL: + case OBJ_TORCHR: + case OBJ_TORCHL2: + case OBJ_TORCHR2: + Obj_Light(oi, 8); + break; + case OBJ_SARC: + Obj_Sarc(oi); + break; + case OBJ_FLAMEHOLE: + Obj_FlameTrap(oi); + break; + case OBJ_TRAPL: + case OBJ_TRAPR: + Obj_Trap(oi); + break; + case OBJ_MCIRCLE1: + case OBJ_MCIRCLE2: + Obj_Circle(oi); + break; + case OBJ_BCROSS: + case OBJ_TBCROSS: + Obj_Light(oi, 10); + Obj_BCrossDamage(oi); + break; + } + if(object[oi]._oAnimFlag != 0) { + object[oi]._oAnimCnt++; + if(object[oi]._oAnimCnt >= object[oi]._oAnimDelay) { + object[oi]._oAnimCnt = 0; + object[oi]._oAnimFrame++; + if(object[oi]._oAnimFrame > object[oi]._oAnimLen) { + object[oi]._oAnimFrame = 1; + } + } + } + } + + i = 0; + while(i < nobjects) { + oi = objectactive[i]; + if(object[oi]._oDelFlag) { + DeleteObject_(oi, i); + i = 0; + } else { + i++; + } + } +} + +void ObjSetMicro(int dx, int dy, int pn) +{ + int i; + WORD *pPiece; + MICROS *pMap; + + dPiece[dx][dy] = pn; + pn--; + pMap = &dpiece_defs_map_1[IsometricCoord(dx, dy)]; + + if(leveltype != DTYPE_HELL) { + pPiece = (WORD *)&pLevelPieces[20 * pn]; + for(i = 0; i < 10; i++) { + pMap->mt[i] = pPiece[(i & 1) + 10 - 2 - (i & 0xE)]; + } + } else { + pPiece = (WORD *)&pLevelPieces[32 * pn]; + for(i = 0; i < 16; i++) { + pMap->mt[i] = pPiece[(i & 1) + 16 - 2 - (i & 0xE)]; + } + } +} + +void objects_set_door_piece(int x, int y) +{ + long v1, v2, lv, lc, rc; + + lv = dPiece[x][y] - 1; + +#ifdef USE_ASM + __asm { + mov esi, pLevelPieces + xor eax, eax + mov ax, word ptr lv + mov ebx, 20 + mul ebx + add esi, eax + add esi, 16 + xor eax, eax + lodsw + mov word ptr v1, ax + lodsw + mov word ptr v2, ax + } +#else + v1 = ((WORD *)&pLevelPieces[20 * lv + 16])[0]; + v2 = ((WORD *)&pLevelPieces[20 * lv + 16])[1]; +#endif + + lc = IsometricCoord(x, y); + dpiece_defs_map_1[lc].mt[0] = v1; + rc = IsometricCoord(x, y); + dpiece_defs_map_1[rc].mt[1] = v2; +} + +void ObjSetMini(int x, int y, int v) +{ + int xx, yy; + long v1, v2, v3, v4; + +#ifdef USE_ASM + __asm { + mov esi, pMegaTiles + xor eax, eax + mov ax, word ptr v + dec eax + shl eax, 3 + add esi, eax + xor eax, eax + lodsw + inc eax + mov v1, eax + lodsw + inc eax + mov v2, eax + lodsw + inc eax + mov v3, eax + lodsw + inc eax + mov v4, eax + } +#else + v--; + v1 = ((WORD *)&pMegaTiles[v << 3])[0] + 1; + v2 = ((WORD *)&pMegaTiles[v << 3])[1] + 1; + v3 = ((WORD *)&pMegaTiles[v << 3])[2] + 1; + v4 = ((WORD *)&pMegaTiles[v << 3])[3] + 1; +#endif + + xx = 2 * x + 16; + yy = 2 * y + 16; + ObjSetMicro(xx, yy, v1); + ObjSetMicro(xx + 1, yy, v2); + ObjSetMicro(xx, yy + 1, v3); + ObjSetMicro(xx + 1, yy + 1, v4); +} + +void ObjL1Special(int x1, int y1, int x2, int y2) +{ + int i, j; + + for(j = y1; j <= y2; j++) { + for(i = x1; i <= x2; i++) { + dSpecial[i][j] = 0; + if(dPiece[i][j] == 12) { + dSpecial[i][j] = 1; + } + if(dPiece[i][j] == 11) { + dSpecial[i][j] = 2; + } + if(dPiece[i][j] == 71) { + dSpecial[i][j] = 1; + } + if(dPiece[i][j] == 259) { + dSpecial[i][j] = 5; + } + if(dPiece[i][j] == 249) { + dSpecial[i][j] = 2; + } + if(dPiece[i][j] == 325) { + dSpecial[i][j] = 2; + } + if(dPiece[i][j] == 321) { + dSpecial[i][j] = 1; + } + if(dPiece[i][j] == 255) { + dSpecial[i][j] = 4; + } + if(dPiece[i][j] == 211) { + dSpecial[i][j] = 1; + } + if(dPiece[i][j] == 344) { + dSpecial[i][j] = 2; + } + if(dPiece[i][j] == 341) { + dSpecial[i][j] = 1; + } + if(dPiece[i][j] == 331) { + dSpecial[i][j] = 2; + } + if(dPiece[i][j] == 418) { + dSpecial[i][j] = 1; + } + if(dPiece[i][j] == 421) { + dSpecial[i][j] = 2; + } + } + } +} + +void ObjL2Special(int x1, int y1, int x2, int y2) +{ + int i, j; + + for(j = y1; j <= y2; j++) { + for(i = x1; i <= x2; i++) { + dSpecial[i][j] = 0; + if(dPiece[i][j] == 541) { + dSpecial[i][j] = 5; + } + if(dPiece[i][j] == 178) { + dSpecial[i][j] = 5; + } + if(dPiece[i][j] == 551) { + dSpecial[i][j] = 5; + } + if(dPiece[i][j] == 542) { + dSpecial[i][j] = 6; + } + if(dPiece[i][j] == 553) { + dSpecial[i][j] = 6; + } + if(dPiece[i][j] == 13) { + dSpecial[i][j] = 5; + } + if(dPiece[i][j] == 17) { + dSpecial[i][j] = 6; + } + } + } + for(j = y1; j <= y2; j++) { + for(i = x1; i <= x2; i++) { + if(dPiece[i][j] == 132) { + dSpecial[i][j + 1] = 2; + dSpecial[i][j + 2] = 1; + } + if(dPiece[i][j] == 135 || dPiece[i][j] == 139) { + dSpecial[i + 1][j] = 3; + dSpecial[i + 2][j] = 4; + } + } + } +} + +void DoorSet(int oi, int dx, int dy) +{ + int pn; + + /// ASSERT: assert((DWORD)oi < MAXOBJECTS); + + pn = dPiece[dx][dy]; + if(pn == 43) { + ObjSetMicro(dx, dy, 392); + } + if(pn == 45) { + ObjSetMicro(dx, dy, 394); + } + if(pn == 50 && object[oi]._otype == OBJ_L1LDOOR) { + ObjSetMicro(dx, dy, 411); + } + if(pn == 50 && object[oi]._otype == OBJ_L1RDOOR) { + ObjSetMicro(dx, dy, 412); + } + if(pn == 54) { + ObjSetMicro(dx, dy, 397); + } + if(pn == 55) { + ObjSetMicro(dx, dy, 398); + } + if(pn == 61) { + ObjSetMicro(dx, dy, 399); + } + if(pn == 67) { + ObjSetMicro(dx, dy, 400); + } + if(pn == 68) { + ObjSetMicro(dx, dy, 401); + } + if(pn == 69) { + ObjSetMicro(dx, dy, 403); + } + if(pn == 70) { + ObjSetMicro(dx, dy, 404); + } + if(pn == 72) { + ObjSetMicro(dx, dy, 406); + } + if(pn == 212) { + ObjSetMicro(dx, dy, 407); + } + if(pn == 354) { + ObjSetMicro(dx, dy, 409); + } + if(pn == 355) { + ObjSetMicro(dx, dy, 410); + } + if(pn == 411) { + ObjSetMicro(dx, dy, 396); + } + if(pn == 412) { + ObjSetMicro(dx, dy, 396); + } +} + +void RedoPlayerVision() +{ + int p; + + for(p = 0; p < MAX_PLRS; p++) { + if(plr[p].plractive && currlevel == plr[p].plrlevel) { + ChangeVisionXY(plr[p]._pvid, plr[p].WorldX, plr[p].WorldY); + } + } +} + +void OperateL1RDoor(int pnum, int oi, BOOL sendflag) +{ + int dx, dy; + BOOL dok; + + /// ASSERT: assert((DWORD)oi < MAXOBJECTS); + if(object[oi]._oVar4 == 2) { + if(!deltaload) { + PlaySfxLoc(IS_DOORCLOS, object[oi]._ox, object[oi]._oy); + } + return; + } + + dx = object[oi]._ox; + dy = object[oi]._oy; + if(object[oi]._oVar4 == 0) { + if(pnum == myplr && sendflag) { + NetSendCmdParam1(TRUE, CMD_OPENDOOR, oi); + } + if(!deltaload) { + PlaySfxLoc(IS_DOOROPEN, object[oi]._ox, object[oi]._oy); + } + ObjSetMicro(dx, dy, 395); + dSpecial[dx][dy] = 8; + objects_set_door_piece(dx, dy - 1); + dx--; + object[oi]._oAnimFrame += 2; + object[oi]._oPreFlag = 1; + DoorSet(oi, dx, dy); + object[oi]._oVar4 = 1; + object[oi]._oSelFlag = 2; + RedoPlayerVision(); + } else { + if(!deltaload) { + PlaySfxLoc(IS_DOORCLOS, object[oi]._ox, object[oi]._oy); + } + dok = dMonster[dx][dy] == 0; + dok &= dItem[dx][dy] == 0; + dok &= dDead[dx][dy] == 0; + if(dok) { + if(pnum == myplr && sendflag) { + NetSendCmdParam1(TRUE, CMD_CLOSEDOOR, oi); + } + object[oi]._oVar4 = 0; + object[oi]._oSelFlag = 3; + ObjSetMicro(dx, dy, object[oi]._oVar1); + if(object[oi]._oVar2 != 50) { + ObjSetMicro(dx - 1, dy, object[oi]._oVar2); + } else if(dPiece[dx - 1][dy] == 396) { + ObjSetMicro(dx - 1, dy, 411); + } else { + ObjSetMicro(dx - 1, dy, object[oi]._oVar2); + } + object[oi]._oAnimFrame -= 2; + object[oi]._oPreFlag = 0; + RedoPlayerVision(); + } else { + object[oi]._oVar4 = 2; + } + } +} + +void OperateL1LDoor(int pnum, int oi, BOOL sendflag) +{ + int dx, dy; + BOOL dok; + + /// ASSERT: assert((DWORD)oi < MAXOBJECTS); + if(object[oi]._oVar4 == 2) { + if(!deltaload) { + PlaySfxLoc(IS_DOORCLOS, object[oi]._ox, object[oi]._oy); + } + return; + } + + dx = object[oi]._ox; + dy = object[oi]._oy; + if(object[oi]._oVar4 == 0) { + if(pnum == myplr && sendflag) { + NetSendCmdParam1(TRUE, CMD_OPENDOOR, oi); + } + if(!deltaload) { + PlaySfxLoc(IS_DOOROPEN, object[oi]._ox, object[oi]._oy); + } + if(object[oi]._oVar1 == 214) { + ObjSetMicro(dx, dy, 408); + } else { + ObjSetMicro(dx, dy, 393); + } + dSpecial[dx][dy] = 7; + objects_set_door_piece(dx - 1, dy); + dy--; + object[oi]._oAnimFrame += 2; + object[oi]._oPreFlag = 1; + DoorSet(oi, dx, dy); + object[oi]._oVar4 = 1; + object[oi]._oSelFlag = 2; + RedoPlayerVision(); + } else { + if(!deltaload) { + PlaySfxLoc(IS_DOORCLOS, object[oi]._ox, object[oi]._oy); + } + dok = dMonster[dx][dy] == 0; + dok &= dItem[dx][dy] == 0; + dok &= dDead[dx][dy] == 0; + if(dok) { + if(pnum == myplr && sendflag) { + NetSendCmdParam1(TRUE, CMD_CLOSEDOOR, oi); + } + object[oi]._oVar4 = 0; + object[oi]._oSelFlag = 3; + ObjSetMicro(dx, dy, object[oi]._oVar1); + if(object[oi]._oVar2 != 50) { + ObjSetMicro(dx, dy - 1, object[oi]._oVar2); + } else if(dPiece[dx][dy - 1] == 396) { + ObjSetMicro(dx, dy - 1, 412); + } else { + ObjSetMicro(dx, dy - 1, object[oi]._oVar2); + } + object[oi]._oAnimFrame -= 2; + object[oi]._oPreFlag = 0; + RedoPlayerVision(); + } else { + object[oi]._oVar4 = 2; + } + } +} + +void OperateL2RDoor(int pnum, int oi, BOOL sendflag) +{ + int dx, dy; + BOOL dok; + + /// ASSERT: assert((DWORD)oi < MAXOBJECTS); + if(object[oi]._oVar4 == 2) { + if(!deltaload) { + PlaySfxLoc(IS_DOORCLOS, object[oi]._ox, object[oi]._oy); + } + return; + } + + dx = object[oi]._ox; + dy = object[oi]._oy; + if(object[oi]._oVar4 == 0) { + if(pnum == myplr && sendflag) { + NetSendCmdParam1(TRUE, CMD_OPENDOOR, oi); + } + if(!deltaload) { + PlaySfxLoc(IS_DOOROPEN, object[oi]._ox, object[oi]._oy); + } + ObjSetMicro(dx, dy, 17); + object[oi]._oAnimFrame += 2; + object[oi]._oPreFlag = 1; + object[oi]._oVar4 = 1; + object[oi]._oSelFlag = 2; + RedoPlayerVision(); + } else { + if(!deltaload) { + PlaySfxLoc(IS_DOORCLOS, object[oi]._ox, object[oi]._oy); + } + dok = dMonster[dx][dy] == 0; + dok &= dItem[dx][dy] == 0; + dok &= dDead[dx][dy] == 0; + if(dok) { + if(pnum == myplr && sendflag) { + NetSendCmdParam1(TRUE, CMD_CLOSEDOOR, oi); + } + object[oi]._oVar4 = 0; + object[oi]._oSelFlag = 3; + ObjSetMicro(dx, dy, 540); + object[oi]._oAnimFrame -= 2; + object[oi]._oPreFlag = 0; + RedoPlayerVision(); + } else { + object[oi]._oVar4 = 2; + } + } +} + +void OperateL2LDoor(int pnum, int oi, BOOL sendflag) +{ + int dx, dy; + BOOL dok; + + /// ASSERT: assert((DWORD)oi < MAXOBJECTS); + if(object[oi]._oVar4 == 2) { + if(!deltaload) { + PlaySfxLoc(IS_DOORCLOS, object[oi]._ox, object[oi]._oy); + } + return; + } + + dx = object[oi]._ox; + dy = object[oi]._oy; + if(object[oi]._oVar4 == 0) { + if(pnum == myplr && sendflag) { + NetSendCmdParam1(TRUE, CMD_OPENDOOR, oi); + } + if(!deltaload) { + PlaySfxLoc(IS_DOOROPEN, object[oi]._ox, object[oi]._oy); + } + ObjSetMicro(dx, dy, 13); + object[oi]._oAnimFrame += 2; + object[oi]._oPreFlag = 1; + object[oi]._oVar4 = 1; + object[oi]._oSelFlag = 2; + RedoPlayerVision(); + } else { + if(!deltaload) { + PlaySfxLoc(IS_DOORCLOS, object[oi]._ox, object[oi]._oy); + } + dok = dMonster[dx][dy] == 0; + dok &= dItem[dx][dy] == 0; + dok &= dDead[dx][dy] == 0; + if(dok) { + if(pnum == myplr && sendflag) { + NetSendCmdParam1(TRUE, CMD_CLOSEDOOR, oi); + } + object[oi]._oVar4 = 0; + object[oi]._oSelFlag = 3; + ObjSetMicro(dx, dy, 538); + object[oi]._oAnimFrame -= 2; + object[oi]._oPreFlag = 0; + RedoPlayerVision(); + } else { + object[oi]._oVar4 = 2; + } + } +} + +void OperateL3RDoor(int pnum, int oi, BOOL sendflag) +{ + int dx, dy; + BOOL dok; + + /// ASSERT: assert((DWORD)oi < MAXOBJECTS); + if(object[oi]._oVar4 == 2) { + if(!deltaload) { + PlaySfxLoc(IS_DOORCLOS, object[oi]._ox, object[oi]._oy); + } + return; + } + + dx = object[oi]._ox; + dy = object[oi]._oy; + if(object[oi]._oVar4 == 0) { + if(pnum == myplr && sendflag) { + NetSendCmdParam1(TRUE, CMD_OPENDOOR, oi); + } + if(!deltaload) { + PlaySfxLoc(IS_DOOROPEN, object[oi]._ox, object[oi]._oy); + } + ObjSetMicro(dx, dy, 541); + object[oi]._oAnimFrame += 2; + object[oi]._oPreFlag = 1; + object[oi]._oVar4 = 1; + object[oi]._oSelFlag = 2; + RedoPlayerVision(); + } else { + if(!deltaload) { + PlaySfxLoc(IS_DOORCLOS, object[oi]._ox, object[oi]._oy); + } + dok = dMonster[dx][dy] == 0; + dok &= dItem[dx][dy] == 0; + dok &= dDead[dx][dy] == 0; + if(dok) { + if(pnum == myplr && sendflag) { + NetSendCmdParam1(TRUE, CMD_CLOSEDOOR, oi); + } + object[oi]._oVar4 = 0; + object[oi]._oSelFlag = 3; + ObjSetMicro(dx, dy, 534); + object[oi]._oAnimFrame -= 2; + object[oi]._oPreFlag = 0; + RedoPlayerVision(); + } else { + object[oi]._oVar4 = 2; + } + } +} + +void OperateL3LDoor(int pnum, int oi, BOOL sendflag) +{ + int dx, dy; + BOOL dok; + + /// ASSERT: assert((DWORD)oi < MAXOBJECTS); + if(object[oi]._oVar4 == 2) { + if(!deltaload) { + PlaySfxLoc(IS_DOORCLOS, object[oi]._ox, object[oi]._oy); + } + return; + } + + dx = object[oi]._ox; + dy = object[oi]._oy; + if(object[oi]._oVar4 == 0) { + if(pnum == myplr && sendflag) { + NetSendCmdParam1(TRUE, CMD_OPENDOOR, oi); + } + if(!deltaload) { + PlaySfxLoc(IS_DOOROPEN, object[oi]._ox, object[oi]._oy); + } + ObjSetMicro(dx, dy, 538); + object[oi]._oAnimFrame += 2; + object[oi]._oPreFlag = 1; + object[oi]._oVar4 = 1; + object[oi]._oSelFlag = 2; + RedoPlayerVision(); + } else { + if(!deltaload) { + PlaySfxLoc(IS_DOORCLOS, object[oi]._ox, object[oi]._oy); + } + dok = dMonster[dx][dy] == 0; + dok &= dItem[dx][dy] == 0; + dok &= dDead[dx][dy] == 0; + if(dok) { + if(pnum == myplr && sendflag) { + NetSendCmdParam1(TRUE, CMD_CLOSEDOOR, oi); + } + object[oi]._oVar4 = 0; + object[oi]._oSelFlag = 3; + ObjSetMicro(dx, dy, 531); + object[oi]._oAnimFrame -= 2; + object[oi]._oPreFlag = 0; + RedoPlayerVision(); + } else { + object[oi]._oVar4 = 2; + } + } +} + +void MonstCheckDoors(int m) +{ + int i, oi, dpx, dpy, mx, my; + + mx = monster[m]._mx; + my = monster[m]._my; + + if(dObject[mx - 1][my - 1] == 0 + && dObject[mx][my - 1] == 0 + && dObject[mx + 1][my - 1] == 0 + && dObject[mx - 1][my] == 0 + && dObject[mx + 1][my] == 0 + && dObject[mx - 1][my + 1] == 0 + && dObject[mx][my + 1] == 0 + && dObject[mx + 1][my + 1] == 0) { + return; + } + + for(i = 0; i < nobjects; i++) { + oi = objectactive[i]; + /// ASSERT: assert((DWORD)oi < MAXOBJECTS); + if((object[oi]._otype == OBJ_L1LDOOR || object[oi]._otype == OBJ_L1RDOOR) && object[oi]._oVar4 == 0) { + dpx = abs(object[oi]._ox - mx); + dpy = abs(object[oi]._oy - my); + if(dpx == 1 && dpy <= 1 && object[oi]._otype == OBJ_L1LDOOR) { + OperateL1LDoor(myplr, oi, TRUE); + } + if(dpx <= 1 && dpy == 1 && object[oi]._otype == OBJ_L1RDOOR) { + OperateL1RDoor(myplr, oi, TRUE); + } + } + if((object[oi]._otype == OBJ_L2LDOOR || object[oi]._otype == OBJ_L2RDOOR) && object[oi]._oVar4 == 0) { + dpx = abs(object[oi]._ox - mx); + dpy = abs(object[oi]._oy - my); + if(dpx == 1 && dpy <= 1 && object[oi]._otype == OBJ_L2LDOOR) { + OperateL2LDoor(myplr, oi, TRUE); + } + if(dpx <= 1 && dpy == 1 && object[oi]._otype == OBJ_L2RDOOR) { + OperateL2RDoor(myplr, oi, TRUE); + } + } + if((object[oi]._otype == OBJ_L3LDOOR || object[oi]._otype == OBJ_L3RDOOR) && object[oi]._oVar4 == 0) { + dpx = abs(object[oi]._ox - mx); + dpy = abs(object[oi]._oy - my); + if(dpx == 1 && dpy <= 1 && object[oi]._otype == OBJ_L3RDOOR) { + OperateL3RDoor(myplr, oi, TRUE); + } + if(dpx <= 1 && dpy == 1 && object[oi]._otype == OBJ_L3LDOOR) { + OperateL3LDoor(myplr, oi, TRUE); + } + } + } +} + +void ObjChangeMap(int x1, int y1, int x2, int y2) +{ + int i, j; + + for(j = y1; j <= y2; j++) { + for(i = x1; i <= x2; i++) { + ObjSetMini(i, j, pdungeon[i][j]); + dungeon[i][j] = pdungeon[i][j]; + } + } + + if(leveltype == DTYPE_CATHEDRAL) { + ObjL1Special(2 * x1 + 16, 2 * y1 + 16, 2 * x2 + 17, 2 * y2 + 17); + AddL1Objs(2 * x1 + 16, 2 * y1 + 16, 2 * x2 + 17, 2 * y2 + 17); + } + if(leveltype == DTYPE_CATACOMBS) { + ObjL2Special(2 * x1 + 16, 2 * y1 + 16, 2 * x2 + 17, 2 * y2 + 17); + AddL2Objs(2 * x1 + 16, 2 * y1 + 16, 2 * x2 + 17, 2 * y2 + 17); + } +} + +void ObjChangeMapResync(int x1, int y1, int x2, int y2) +{ + int i, j; + + for(j = y1; j <= y2; j++) { + for(i = x1; i <= x2; i++) { + ObjSetMini(i, j, pdungeon[i][j]); + dungeon[i][j] = pdungeon[i][j]; + } + } + + if(leveltype == DTYPE_CATHEDRAL) { + ObjL1Special(2 * x1 + 16, 2 * y1 + 16, 2 * x2 + 17, 2 * y2 + 17); + } + if(leveltype == DTYPE_CATACOMBS) { + ObjL2Special(2 * x1 + 16, 2 * y1 + 16, 2 * x2 + 17, 2 * y2 + 17); + } +} + +void OperateL1Door(int pnum, int i, BOOL sendflag) +{ + int dpx, dpy; + + /// ASSERT: assert((DWORD)i < MAXOBJECTS); + dpx = abs(object[i]._ox - plr[pnum].WorldX); + dpy = abs(object[i]._oy - plr[pnum].WorldY); + if(dpx == 1 && dpy <= 1 && object[i]._otype == OBJ_L1LDOOR) { + OperateL1LDoor(pnum, i, sendflag); + } + if(dpx <= 1 && dpy == 1 && object[i]._otype == OBJ_L1RDOOR) { + OperateL1RDoor(pnum, i, sendflag); + } +} + +void OperateLever(int pnum, int i) +{ + int j, oi, ot; + BOOL mapflag; + + /// ASSERT: assert((DWORD)i < MAXOBJECTS); + if(object[i]._oSelFlag == 0) { + return; + } + + if(!deltaload) { + PlaySfxLoc(IS_LEVER, object[i]._ox, object[i]._oy); + } + + object[i]._oSelFlag = 0; + object[i]._oAnimFrame++; + + mapflag = TRUE; + if(currlevel == 16) { + for(j = 0; j < nobjects; j++) { + oi = objectactive[j]; + ot = object[oi]._otype; + if(ot == OBJ_SWITCHSKL && object[i]._oVar8 == object[oi]._oVar8 && object[oi]._oSelFlag != 0) { + mapflag = FALSE; + } + } + } + + if(mapflag) { + ObjChangeMap(object[i]._oVar1, object[i]._oVar2, object[i]._oVar3, object[i]._oVar4); + } + if(pnum == myplr) { + NetSendCmdParam1(FALSE, CMD_OPERATEOBJ, i); + } +} + +void OperateBook(int pnum, int i) +{ + int v1, v2, j, oi, ot /* itm */; + BOOL found, dowarp; + + /// ASSERT: assert((DWORD)i < MAXOBJECTS); + if(object[i]._oSelFlag == 0) { + return; + } + + if(setlevel && setlvlnum == SL_VILEBETRAYER) { + found = FALSE; + dowarp = FALSE; + for(j = 0; j < nobjects; j++) { + oi = objectactive[j]; + ot = object[oi]._otype; + if(ot == OBJ_MCIRCLE2 && object[oi]._oVar6 == 1) { + v1 = 27; + v2 = 29; + object[oi]._oVar6 = 4; + dowarp = TRUE; + } + if(ot == OBJ_MCIRCLE2 && object[oi]._oVar6 == 2) { + v1 = 43; + v2 = 29; + object[oi]._oVar6 = 4; + dowarp = TRUE; + } + if(dowarp) { + object[dObject[35][36] - 1]._oVar5++; + AddMissile(plr[pnum].WorldX, plr[pnum].WorldY, v1, v2, plr[pnum]._pdir, MIS_RNDTELEPORT, 0, pnum, 0, 0); + found = TRUE; + dowarp = FALSE; + } + } + if(!found) { + return; + } + } + + object[i]._oSelFlag = 0; + object[i]._oAnimFrame++; + + if(setlevel && setlvlnum == SL_BONECHAMB) { + plr[myplr]._pMemSpells64 |= (__int64)1 << (SPL_GUARDIAN - 1); /// BUGFIX: `pnum` instead of `myplr` here and below + if(plr[pnum]._pSplLvl[SPL_GUARDIAN] < 15) { + plr[myplr]._pSplLvl[SPL_GUARDIAN]++; + } + quests[Q_SCHAMB]._qactive = 3; + if(!deltaload) { + PlaySfxLoc(IS_QUESTDN, object[i]._ox, object[i]._oy); + } + InitDiabloMsg(43); + AddMissile(plr[myplr].WorldX, plr[myplr].WorldY, object[i]._ox - 2, object[i]._oy - 4, plr[myplr]._pdir, MIS_GUARDIAN, 0, myplr, 0, 0); + } + if(setlevel && setlvlnum == SL_VILEBETRAYER) { + ObjChangeMapResync(object[i]._oVar1, object[i]._oVar2, object[i]._oVar3, object[i]._oVar4); + for(j = 0; j < nobjects; j++) { + SyncObjectAnim(objectactive[j]); + } + } +} + +void OperateBookLever(int pnum, int i) +{ + int x, y, tren; + + /// ASSERT: assert(gbMaxPlayers == 1); + x = 2 * setpc_x + 16; + y = 2 * setpc_y + 16; + /// ASSERT: assert((DWORD)i < MAXOBJECTS); + if(object[i]._oSelFlag == 0) { + return; + } + if(qtextflag) { + return; + } + + if(object[i]._otype == OBJ_BLINDBOOK && quests[Q_BLIND]._qvar1 == 0) { + quests[Q_BLIND]._qactive = 2; + quests[Q_BLIND]._qlog = 1; + quests[Q_BLIND]._qvar1 = 1; + } + if(object[i]._otype == OBJ_BLOODBOOK && quests[Q_BLOOD]._qvar1 == 0) { + quests[Q_BLOOD]._qactive = 2; + quests[Q_BLOOD]._qlog = 1; + quests[Q_BLOOD]._qvar1 = 1; + SpawnQuestItem(IDI_BLDSTONE, 2 * setpc_x + 19, 2 * setpc_y + 26, 0, 1); + SpawnQuestItem(IDI_BLDSTONE, 2 * setpc_x + 31, 2 * setpc_y + 26, 0, 1); + SpawnQuestItem(IDI_BLDSTONE, 2 * setpc_x + 25, 2 * setpc_y + 33, 0, 1); + } + if(object[i]._otype == OBJ_STEELTOME && quests[Q_WARLORD]._qvar1 == 0) { + quests[Q_WARLORD]._qactive = 2; + quests[Q_WARLORD]._qlog = 1; + quests[Q_WARLORD]._qvar1 = 1; + } + if(object[i]._oAnimFrame != object[i]._oVar6) { + if(object[i]._otype != OBJ_BLOODBOOK) { + ObjChangeMap(object[i]._oVar1, object[i]._oVar2, object[i]._oVar3, object[i]._oVar4); + } + if(object[i]._otype == OBJ_BLINDBOOK) { + CreateItem(UITEM_OPTAMULET, x + 5, y + 5); + tren = TransVal; + TransVal = 9; + DRLG_MRectTrans(object[i]._oVar1, object[i]._oVar2, object[i]._oVar3, object[i]._oVar4); + TransVal = tren; + } + } + + object[i]._oAnimFrame = object[i]._oVar6; + InitQTextMsg(object[i]._oVar7); + + if(pnum == myplr) { + NetSendCmdParam1(FALSE, CMD_OPERATEOBJ, i); + } +} + +void OperateSChambBk(int pnum, int i) +{ + int textdef, j; + + /// ASSERT: assert((DWORD)i < MAXOBJECTS); + if(object[i]._oSelFlag == 0) { + return; + } + if(qtextflag) { + return; + } + + if(object[i]._oAnimFrame != object[i]._oVar6) { + ObjChangeMapResync(object[i]._oVar1, object[i]._oVar2, object[i]._oVar3, object[i]._oVar4); + for(j = 0; j < nobjects; j++) { + SyncObjectAnim(objectactive[j]); + } + } + object[i]._oAnimFrame = object[i]._oVar6; + + if(quests[Q_SCHAMB]._qactive == 1) { + quests[Q_SCHAMB]._qactive = 2; + quests[Q_SCHAMB]._qlog = 1; + } + + if(plr[myplr]._pClass == PC_WARRIOR) { /// BUGFIX: `pnum` instead of `myplr` here and below + textdef = TEXT_BONER; + } else if(plr[myplr]._pClass == PC_ROGUE) { + textdef = TEXT_RBONER; + } else if(plr[myplr]._pClass == PC_SORCERER) { + textdef = TEXT_MBONER; + } + quests[Q_SCHAMB]._qmsg = textdef; + InitQTextMsg(textdef); +} + +void OperateChest(int pnum, int i, BOOL sendmsg) +{ + int j, mdir, mtype; + + /// ASSERT: assert((DWORD)i < MAXOBJECTS); + if(object[i]._oSelFlag == 0) { + return; + } + + if(!deltaload) { + PlaySfxLoc(IS_CHEST, object[i]._ox, object[i]._oy); + } + + object[i]._oSelFlag = 0; + object[i]._oAnimFrame += 2; + + if(deltaload) { + return; + } + + SetRndSeed(object[i]._oRndSeed); + + if(setlevel) { + for(j = 0; j < object[i]._oVar1; j++) { + CreateRndItem(object[i]._ox, object[i]._oy, TRUE, sendmsg, FALSE); + } + } else { + for(j = 0; j < object[i]._oVar1; j++) { + if(object[i]._oVar2 != 0) { + CreateRndItem(object[i]._ox, object[i]._oy, FALSE, sendmsg, FALSE); + } else { + CreateRndUseful(pnum, object[i]._ox, object[i]._oy, sendmsg); + } + } + } + + if(object[i]._oTrapFlag && object[i]._otype >= OBJ_TCHEST1 && object[i]._otype <= OBJ_TCHEST3) { + mdir = GetDirection(object[i]._ox, object[i]._oy, plr[pnum].WorldX, plr[pnum].WorldY); + switch(object[i]._oVar4) { + case 0: + mtype = MIS_ARROW; + break; + case 1: + mtype = MIS_FARROW; + break; + case 2: + mtype = MIS_NOVA; + break; + } + AddMissile(object[i]._ox, object[i]._oy, plr[pnum].WorldX, plr[pnum].WorldY, mdir, mtype, 1, -1, 0, 0); + object[i]._oTrapFlag = 0; + } + if(pnum == myplr) { + NetSendCmdParam2(FALSE, CMD_PLROPOBJ, pnum, i); + } +} + +void OperateMushPatch(int pnum, int i) +{ + int x, y; + + if(quests[Q_MUSHROOM]._qactive != 2 || quests[Q_MUSHROOM]._qvar1 < 2) { + if(deltaload || pnum != myplr) { + return; + } + if(plr[myplr]._pClass == PC_WARRIOR) { + PlaySFX(PS_WARR13); + } else if(plr[myplr]._pClass == PC_ROGUE) { + PlaySFX(PS_ROGUE13); + } else if(plr[myplr]._pClass == PC_SORCERER) { + PlaySFX(PS_MAGE13); + } + } else { + /// ASSERT: assert((DWORD)i < MAXOBJECTS); + if(object[i]._oSelFlag == 0) { + return; + } + if(!deltaload) { + PlaySfxLoc(IS_CHEST, object[i]._ox, object[i]._oy); + } + object[i]._oSelFlag = 0; + object[i]._oAnimFrame++; + if(deltaload) { + return; + } + GetSuperItemLoc(object[i]._ox, object[i]._oy, x, y); + SpawnQuestItem(IDI_MUSHROOM, x, y, 0, 0); + quests[Q_MUSHROOM]._qvar1 = 3; + } +} + +void OperateInnSignChest(int pnum, int i) +{ + int x, y; + + if(quests[Q_LTBANNER]._qvar1 != 2) { + if(deltaload || pnum != myplr) { + return; + } + if(plr[myplr]._pClass == PC_WARRIOR) { + PlaySFX(PS_WARR24); + } else if(plr[myplr]._pClass == PC_ROGUE) { + PlaySFX(PS_ROGUE24); + } else if(plr[myplr]._pClass == PC_SORCERER) { + PlaySFX(PS_MAGE24); + } + } else { + if(object[i]._oSelFlag == 0) { + return; + } + if(!deltaload) { + PlaySfxLoc(IS_CHEST, object[i]._ox, object[i]._oy); + } + object[i]._oSelFlag = 0; + object[i]._oAnimFrame += 2; + if(deltaload) { + return; + } + GetSuperItemLoc(object[i]._ox, object[i]._oy, x, y); + SpawnQuestItem(IDI_BANNER, x, y, 0, 0); + } +} + +void OperateSlainHero(int pnum, int i, BOOL sendmsg) +{ + /// ASSERT: assert((DWORD)i < MAXOBJECTS); + if(object[i]._oSelFlag == 0) { + return; + } + + object[i]._oSelFlag = 0; + + if(deltaload) { + return; + } + + if(plr[pnum]._pClass == PC_WARRIOR) { + CreateMagicArmor(object[i]._ox, object[i]._oy, ITYPE_HARMOR, 153, FALSE, TRUE); + PlaySfxLoc(PS_WARR9, plr[myplr].WorldX, plr[myplr].WorldY); + } else if(plr[pnum]._pClass == PC_ROGUE) { + CreateMagicWeapon(object[i]._ox, object[i]._oy, ITYPE_BOW, 119, FALSE, TRUE); + PlaySfxLoc(PS_ROGUE9, plr[myplr].WorldX, plr[myplr].WorldY); + } else if(plr[pnum]._pClass == PC_SORCERER) { + CreateSpellBook(object[i]._ox, object[i]._oy, SPL_LIGHTNING, FALSE, TRUE); + PlaySfxLoc(PS_MAGE9, plr[myplr].WorldX, plr[myplr].WorldY); + } + + if(pnum == myplr) { + NetSendCmdParam1(FALSE, CMD_OPERATEOBJ, i); + } +} + +void OperateTrapLvr(int i) +{ + int j, oi; + + /// ASSERT: assert((DWORD)i < MAXOBJECTS); + if(object[i]._oAnimFrame == 1) { + object[i]._oAnimFrame++; + for(j = 0; j < nobjects; j++) { + oi = objectactive[j]; + if(object[oi]._otype == object[i]._oVar2 && object[oi]._oVar1 == object[i]._oVar1) { + object[oi]._oVar2 = 1; + object[oi]._oAnimFlag = 0; + } + } + } else { + object[i]._oAnimFrame--; + for(j = 0; j < nobjects; j++) { + oi = objectactive[j]; + if(object[oi]._otype == object[i]._oVar2 && object[oi]._oVar1 == object[i]._oVar1) { + object[oi]._oVar2 = 0; + if(object[oi]._oVar4 != 0) { + object[oi]._oAnimFlag = 1; + } + } + } + } +} + +void OperateSarc(int pnum, int i, BOOL sendmsg) +{ + /// ASSERT: assert((DWORD)i < MAXOBJECTS); + if(object[i]._oSelFlag == 0) { + return; + } + + if(!deltaload) { + PlaySfxLoc(IS_SARC, object[i]._ox, object[i]._oy); + } + + object[i]._oSelFlag = 0; + + if(deltaload) { + object[i]._oAnimFrame = object[i]._oAnimLen; + return; + } + + object[i]._oAnimFlag = 1; + object[i]._oAnimDelay = 3; + SetRndSeed(object[i]._oRndSeed); + + if(object[i]._oVar1 <= 2) { + CreateRndItem(object[i]._ox, object[i]._oy, FALSE, sendmsg, FALSE); + } + if(object[i]._oVar1 >= 8) { + SpawnSkeleton(object[i]._oVar2, object[i]._ox, object[i]._oy); + } + if(pnum == myplr) { + NetSendCmdParam1(FALSE, CMD_OPERATEOBJ, i); + } +} + +void OperateL2Door(int pnum, int i, BOOL sendflag) +{ + int dpx, dpy; + + /// ASSERT: assert((DWORD)i < MAXOBJECTS); + dpx = abs(object[i]._ox - plr[pnum].WorldX); + dpy = abs(object[i]._oy - plr[pnum].WorldY); + if(dpx == 1 && dpy <= 1 && object[i]._otype == OBJ_L2LDOOR) { + OperateL2LDoor(pnum, i, sendflag); + } + if(dpx <= 1 && dpy == 1 && object[i]._otype == OBJ_L2RDOOR) { + OperateL2RDoor(pnum, i, sendflag); + } +} + +void OperateL3Door(int pnum, int i, BOOL sendflag) +{ + int dpx, dpy; + + /// ASSERT: assert((DWORD)i < MAXOBJECTS); + dpx = abs(object[i]._ox - plr[pnum].WorldX); + dpy = abs(object[i]._oy - plr[pnum].WorldY); + if(dpx == 1 && dpy <= 1 && object[i]._otype == OBJ_L3RDOOR) { + OperateL3RDoor(pnum, i, sendflag); + } + if(dpx <= 1 && dpy == 1 && object[i]._otype == OBJ_L3LDOOR) { + OperateL3LDoor(pnum, i, sendflag); + } +} + +void OperatePedistal(int pnum, int i) +{ + int jstn; + BYTE *setp; + + /// ASSERT: assert((DWORD)i < MAXOBJECTS); + if(object[i]._oVar6 == 3) { + return; + } + + if(PlrHasItem(pnum, IDI_BLDSTONE, jstn) != NULL) { + RemoveInvItem(pnum, jstn); + object[i]._oAnimFrame++; + object[i]._oVar6++; + } + if(object[i]._oVar6 == 1) { + if(!deltaload) { + PlaySfxLoc(LS_PUDDLE, object[i]._ox, object[i]._oy); + } + ObjChangeMap(setpc_x, setpc_y + 3, setpc_x + 2, setpc_y + 7); + } + if(object[i]._oVar6 == 2) { + if(!deltaload) { + PlaySfxLoc(LS_PUDDLE, object[i]._ox, object[i]._oy); + } + ObjChangeMap(setpc_x + 6, setpc_y + 3, setpc_x + setpc_w, setpc_y + 7); + } + if(object[i]._oVar6 == 3) { + if(!deltaload) { + PlaySfxLoc(LS_BLODSTAR, object[i]._ox, object[i]._oy); + } + ObjChangeMap(object[i]._oVar1, object[i]._oVar2, object[i]._oVar3, object[i]._oVar4); + setp = DiabLoad("Levels\\L2Data\\Blood2.DUN", NULL, 'STPC'); + LoadMapObjs(setp, 2 * setpc_x, 2 * setpc_y); + MemFreeDbg(setp); + CreateItem(UITEM_ARMOFVAL, 2 * setpc_x + 25, 2 * setpc_y + 19); + object[i]._oSelFlag = 0; + } +} + +void TryDisarm(int pnum, int i) +{ + int j, oi, oti, trapdisper; + BOOL checkflag; + + if(pnum == myplr) { + SetCursor_(CURSOR_HAND); + } + + /// ASSERT: assert((DWORD)i < MAXOBJECTS); + if(!object[i]._oTrapFlag) { + return; + } + + trapdisper = 2 * plr[pnum]._pDexterity - 5 * currlevel; + if(random(154, 100) > trapdisper) { + return; + } + + for(j = 0; j < nobjects; j++) { + oi = objectactive[j]; + checkflag = FALSE; + if(object[oi]._otype == OBJ_TRAPL) { + checkflag = TRUE; + } + if(object[oi]._otype == OBJ_TRAPR) { + checkflag = TRUE; + } + if(checkflag) { + oti = dObject[object[oi]._oVar1][object[oi]._oVar2] - 1; + if(oti == i) { + object[oi]._oVar4 = 1; + object[i]._oTrapFlag = 0; + } + } + } + + if(object[i]._otype >= OBJ_TCHEST1 && object[i]._otype <= OBJ_TCHEST3) { + object[i]._oTrapFlag = 0; + } +} + +int ItemMiscIdIdx(int imiscid) +{ + int i; + + i = 0; + while(AllItemsList[i].iRnd == IDROP_NEVER || AllItemsList[i].iMiscId != imiscid) { + i++; + } + + return i; +} + +void OperateShrine(int pnum, int i, int sType) +{ + int v1, v2, v3, v4; + int v12; // edx + int v21; // eax + int v60; // ebx + int j; // edi + int v72; // edi + int v88; // ebx + int v107; // ST38_4 + int v108; // ST34_4 + int v133; // eax + int xx, yy; + int min, max; + unsigned __int64 spell, spells; + + if(dropGoldFlag) { + dropGoldFlag = 0; + dropGoldValue = 0; + } + + /// ASSERT: assert((DWORD)i < MAXOBJECTS); + + if(!object[i]._oSelFlag) + return; + + SetRndSeed(object[i]._oRndSeed); + object[i]._oSelFlag = 0; + + if(!deltaload) { + PlaySfxLoc(sType, object[i]._ox, object[i]._oy); + object[i]._oAnimFlag = 1; + object[i]._oAnimDelay = 1; + } else { + object[i]._oAnimFlag = 0; + object[i]._oAnimFrame = object[i]._oAnimLen; + } + + switch(object[i]._oVar1) { + case 0: + if(deltaload || pnum != myplr) + return; + ModifyPlrStr(pnum, -1); + ModifyPlrMag(pnum, -1); + ModifyPlrDex(pnum, -1); + ModifyPlrVit(pnum, -1); + switch(random(0, 4)) { + case 0: + ModifyPlrStr(pnum, 6); + break; + case 1: + ModifyPlrMag(pnum, 6); + break; + case 2: + ModifyPlrDex(pnum, 6); + break; + case 3: + ModifyPlrVit(pnum, 6); + break; + } + CheckStats(pnum); + InitDiabloMsg(12); + break; + case 1: + v12 = 0; + if(deltaload || pnum != myplr) + return; + for(j = 0; j < 7; j++) { + if(plr[pnum].InvBody[j]._itype != -1) + v12++; + } + if(v12 > 0) { + for(j = 0; j < 7; j++) { + if(plr[pnum].InvBody[j]._itype != -1 + && plr[pnum].InvBody[j]._iMaxDur != 255 + && plr[pnum].InvBody[j]._iMaxDur) + { + plr[pnum].InvBody[j]._iDurability += 10; + plr[pnum].InvBody[j]._iMaxDur += 10; + if(plr[pnum].InvBody[j]._iDurability > plr[pnum].InvBody[j]._iMaxDur) + plr[pnum].InvBody[j]._iDurability = plr[pnum].InvBody[j]._iMaxDur; + } + } + while(1) { + v12 = 0; + for(j = 0; j < 7; j++) { + if(plr[pnum].InvBody[j]._itype != -1 + && plr[pnum].InvBody[j]._iMaxDur != 255 + && plr[pnum].InvBody[j]._iMaxDur) + v12++; + } + if(v12 == 0) + break; + v21 = random(0, 7); + if(plr[pnum].InvBody[v21]._itype == -1 || plr[pnum].InvBody[v21]._iMaxDur == 255 || !plr[pnum].InvBody[v21]._iMaxDur) + continue; + plr[pnum].InvBody[v21]._iDurability -= 20; + plr[pnum].InvBody[v21]._iMaxDur -= 20; + if(plr[pnum].InvBody[v21]._iDurability <= 0) + plr[pnum].InvBody[v21]._iDurability = 1; + if(plr[pnum].InvBody[v21]._iMaxDur <= 0) + plr[pnum].InvBody[v21]._iMaxDur = 1; + break; + } + } + InitDiabloMsg(13); + break; + case 2: + if(deltaload) + return; + if(pnum == myplr) { + if(plr[pnum].InvBody[0]._itype != ITYPE_NONE) + plr[pnum].InvBody[0]._iAC += 2; + if(plr[pnum].InvBody[6]._itype != ITYPE_NONE) + plr[pnum].InvBody[6]._iAC += 2; + if(plr[pnum].InvBody[4]._itype != ITYPE_NONE) { + if(plr[pnum].InvBody[4]._itype == ITYPE_SHIELD) { + plr[pnum].InvBody[4]._iAC += 2; + } else { + plr[pnum].InvBody[4]._iMaxDam--; + if(plr[pnum].InvBody[4]._iMaxDam < plr[pnum].InvBody[4]._iMinDam) + plr[pnum].InvBody[4]._iMaxDam = plr[pnum].InvBody[4]._iMinDam; + } + } + if(plr[pnum].InvBody[5]._itype != ITYPE_NONE) { + if(plr[pnum].InvBody[5]._itype == ITYPE_SHIELD) { + plr[pnum].InvBody[5]._iAC += 2; + } else { + plr[pnum].InvBody[5]._iMaxDam--; + if(plr[pnum].InvBody[5]._iMaxDam < plr[pnum].InvBody[5]._iMinDam) + plr[pnum].InvBody[5]._iMaxDam = plr[pnum].InvBody[5]._iMinDam; + } + } + for(j = 0; j < plr[pnum]._pNumInv; j++) { + switch(plr[pnum].InvList[j]._itype) { + case 1: + case 2: + case 3: + case 4: + case 10: + plr[pnum].InvList[j]._iMaxDam--; + if(plr[pnum].InvList[j]._iMaxDam < plr[pnum].InvList[j]._iMinDam) + plr[pnum].InvList[j]._iMaxDam = plr[pnum].InvList[j]._iMinDam; + break; + case 5: + case 6: + case 7: + case 8: + case 9: + plr[pnum].InvList[j]._iAC += 2; + break; + } + } + InitDiabloMsg(14); + } + break; + case 3: + if(deltaload) + return; + if(pnum == myplr) { + if(plr[pnum].InvBody[4]._itype != ITYPE_NONE && plr[pnum].InvBody[4]._itype != ITYPE_SHIELD) + plr[pnum].InvBody[4]._iMaxDam++; + if(plr[pnum].InvBody[5]._itype != ITYPE_NONE && plr[pnum].InvBody[5]._itype != ITYPE_SHIELD) + plr[pnum].InvBody[5]._iMaxDam++; + for(j = 0; j < plr[pnum]._pNumInv; j++) { + switch(plr[pnum].InvList[j]._itype) { + case 1: + case 2: + case 3: + case 4: + case 10: + plr[pnum].InvList[j]._iMaxDam++; + break; + } + } + InitDiabloMsg(15); + } + break; + case 4: + case 11: + if(deltaload) + return; + AddMissile( + plr[pnum].WorldX, + plr[pnum].WorldY, + plr[pnum].WorldX, + plr[pnum].WorldY, + plr[pnum]._pdir, + MIS_MANASHIELD, + -1, + pnum, + 0, + 2 * (unsigned char)leveltype); + if(pnum != myplr) + return; + InitDiabloMsg(16); + break; + case 5: + if(deltaload) + return; + if(pnum == myplr) { + for(j = 0; j < 7; j++) { + if(plr[pnum].InvBody[j]._itype == 10) + plr[pnum].InvBody[j]._iCharges = plr[pnum].InvBody[j]._iMaxCharges; + } + for(j = 0; j < plr[pnum]._pNumInv; j++) { + if(plr[pnum].InvList[j]._itype == 10) + plr[pnum].InvList[j]._iCharges = plr[pnum].InvList[j]._iMaxCharges; + } + for(j = 0; j < 8; j++) { + if(plr[pnum].SpdList[j]._itype == 10) + plr[pnum].SpdList[j]._iCharges = plr[pnum].SpdList[j]._iMaxCharges; // belt items don't have charges? + } + InitDiabloMsg(17); + } + break; + case 6: + if(deltaload) + return; + if(pnum == myplr) { + for(j = 0; j < 7; j++) + plr[pnum].InvBody[j]._iDurability = plr[pnum].InvBody[j]._iMaxDur; + for(j = 0; j < plr[pnum]._pNumInv; j++) + plr[pnum].InvList[j]._iDurability = plr[pnum].InvList[j]._iMaxDur; + for(j = 0; j < 8; j++) + plr[pnum].SpdList[j]._iDurability = plr[pnum].SpdList[j]._iMaxDur; // belt items don't have durability? + InitDiabloMsg(18); + } + break; + case 7: + if(deltaload || pnum != myplr) + return; + v12 = 0; + spell = 1; + spells = plr[pnum]._pMemSpells64; + for(j = 1; j <= 37; j++) { + if(spells & spell) + v12++; + spell <<= 1; + } + if(v12 > 1) { + spell = 1; + for(j = 1; j <= 37; j++) { + if(plr[pnum]._pMemSpells64 & spell) { + if(plr[pnum]._pSplLvl[j] < 15) + plr[pnum]._pSplLvl[j]++; + } + spell <<= 1; + } + do { + v60 = random(0, 37); + } + while(!(plr[pnum]._pMemSpells64 & ((__int64)1 << v60))); + if(plr[pnum]._pSplLvl[v60] >= 2) + plr[pnum]._pSplLvl[v60] -= 2; + else + plr[pnum]._pSplLvl[v60] = 0; + } + InitDiabloMsg(19); + break; + case 8: + for(j = 0; j < nobjects; j++) { + v1 = objectactive[j]; + /// ASSERT: assert((DWORD)v1 < MAXOBJECTS); + if((object[v1]._otype == OBJ_CHEST1 + || object[v1]._otype == OBJ_CHEST2 + || object[v1]._otype == OBJ_CHEST3) + && !object[v1]._oSelFlag) + { + object[v1]._oRndSeed = GetRndSeed(); + object[v1]._oSelFlag = 1; + object[v1]._oAnimFrame -= 2; + } + } + if(deltaload) + return; + if(pnum == myplr) + InitDiabloMsg(20); + break; + case 9: + if(deltaload || pnum != myplr) + return; + plr[pnum]._pMemSpells64 |= (__int64)1 << (SPL_FIREBOLT-1); + if(plr[pnum]._pSplLvl[SPL_FIREBOLT] < 15) + plr[pnum]._pSplLvl[SPL_FIREBOLT]++; + if(plr[pnum]._pSplLvl[SPL_FIREBOLT] < 15) + plr[pnum]._pSplLvl[SPL_FIREBOLT]++; + v72 = plr[pnum]._pMaxManaBase / 10; + min = plr[pnum]._pMana - plr[pnum]._pManaBase; + max = plr[pnum]._pMaxMana - plr[pnum]._pMaxManaBase; + plr[pnum]._pManaBase -= v72; + plr[pnum]._pMana -= v72; + plr[pnum]._pMaxMana -= v72; + plr[pnum]._pMaxManaBase -= v72; + if((signed int)(plr[pnum]._pMana & 0xFFFFFFC0) <= 0) { + plr[pnum]._pMana = min; + plr[pnum]._pManaBase = 0; + } + if((signed int)(plr[pnum]._pMaxMana & 0xFFFFFFC0) <= 0) { + plr[pnum]._pMaxMana = max; + plr[pnum]._pMaxManaBase = 0; + } + InitDiabloMsg(21); + break; + case 10: + if(deltaload) + return; + AddMissile( + plr[pnum].WorldX, + plr[pnum].WorldY, + plr[pnum].WorldX, + plr[pnum].WorldY, + plr[pnum]._pdir, + MIS_NOVA, + -1, + pnum, + 0, + 2 * (unsigned char)leveltype); + if(pnum != myplr) + return; + plr[pnum]._pMana = plr[pnum]._pMaxMana; + plr[pnum]._pManaBase = plr[pnum]._pMaxManaBase; + InitDiabloMsg(22); + break; + case 12: /// BUGFIX: change `plr[pnum].HoldItem` to use a temporary buffer to prevent deleting item in hand + if(deltaload) + return; + if(pnum == myplr) { + for(j = 0; j < plr[pnum]._pNumInv; j++) { + if(!plr[pnum].InvList[j]._itype) { + if(plr[pnum].InvList[j]._iMiscId == IMISC_HEAL + || plr[pnum].InvList[j]._iMiscId == IMISC_MANA) + { + SetPlrHandItem(&plr[pnum].HoldItem, ItemMiscIdIdx(IMISC_REJUV)); + GetPlrHandSeed(&plr[pnum].HoldItem); + plr[pnum].HoldItem._iStatFlag = 1; + plr[pnum].InvList[j] = plr[pnum].HoldItem; + } + if(plr[pnum].InvList[j]._iMiscId == IMISC_FULLHEAL + || plr[pnum].InvList[j]._iMiscId == IMISC_FULLMANA) + { + SetPlrHandItem(&plr[pnum].HoldItem, ItemMiscIdIdx(IMISC_FULLREJUV)); + GetPlrHandSeed(&plr[pnum].HoldItem); + plr[pnum].HoldItem._iStatFlag = 1; + plr[pnum].InvList[j] = plr[pnum].HoldItem; + } + } + } + for(j = 0; j < 8; j++) { + if(!plr[pnum].SpdList[j]._itype) { + if(plr[pnum].SpdList[j]._iMiscId == IMISC_HEAL + || plr[pnum].SpdList[j]._iMiscId == IMISC_MANA) + { + SetPlrHandItem(&plr[pnum].HoldItem, ItemMiscIdIdx(IMISC_REJUV)); + GetPlrHandSeed(&plr[pnum].HoldItem); + plr[pnum].HoldItem._iStatFlag = 1; + plr[pnum].SpdList[j] = plr[pnum].HoldItem; + } + if(plr[pnum].SpdList[j]._iMiscId == IMISC_FULLHEAL + || plr[pnum].SpdList[j]._iMiscId == IMISC_FULLMANA) + { + SetPlrHandItem(&plr[pnum].HoldItem, ItemMiscIdIdx(IMISC_FULLREJUV)); + GetPlrHandSeed(&plr[pnum].HoldItem); + plr[pnum].HoldItem._iStatFlag = 1; + plr[pnum].SpdList[j] = plr[pnum].HoldItem; + } + } + } + InitDiabloMsg(24); + } + break; + case 13: + if(deltaload || pnum != myplr) + return; + ModifyPlrMag(pnum, 2); + CheckStats(pnum); + InitDiabloMsg(25); + break; + case 14: + if(deltaload || pnum != myplr) + return; + if(2 * currlevel < 7) { + CreateTypeItem(object[i]._ox, object[i]._oy, 0, ITYPE_MISC, IMISC_FULLMANA, 0, 1); + CreateTypeItem(object[i]._ox, object[i]._oy, 0, ITYPE_MISC, IMISC_FULLHEAL, 0, 1); + } else { + CreateTypeItem(object[i]._ox, object[i]._oy, 0, ITYPE_MISC, IMISC_FULLREJUV, 0, 1); + CreateTypeItem(object[i]._ox, object[i]._oy, 0, ITYPE_MISC, IMISC_FULLREJUV, 0, 1); + } + plr[pnum]._pMana = plr[pnum]._pMaxMana; + plr[pnum]._pManaBase = plr[pnum]._pMaxManaBase; + plr[pnum]._pHitPoints = plr[pnum]._pMaxHP; + plr[pnum]._pHPBase = plr[pnum]._pMaxHPBase; + InitDiabloMsg(26); + break; + case 15: + if(deltaload) + return; + v88 = 0; + do { + xx = random(159, MAXDUNX); + yy = random(159, MAXDUNY); + v88++; + } + while(v88 <= MAXDUNX*MAXDUNY && (nSolidTable[dPiece[xx][yy]] || dObject[xx][yy] || dMonster[xx][yy])); + AddMissile(plr[pnum].WorldX, plr[pnum].WorldY, xx, yy, plr[pnum]._pdir, MIS_RNDTELEPORT, -1, pnum, 0, 2 * (unsigned char)leveltype); + if(pnum != myplr) + return; + InitDiabloMsg(27); + break; + case 16: + if(deltaload || pnum != myplr) + return; + plr[pnum]._pMemSpells64 |= (__int64)1 << (SPL_CBOLT-1); + if(plr[pnum]._pSplLvl[SPL_CBOLT] < 15) + plr[pnum]._pSplLvl[SPL_CBOLT]++; + if(plr[pnum]._pSplLvl[SPL_CBOLT] < 15) + plr[pnum]._pSplLvl[SPL_CBOLT]++; + v72 = plr[pnum]._pMaxManaBase / 10; + min = plr[pnum]._pMana - plr[pnum]._pManaBase; + max = plr[pnum]._pMaxMana - plr[pnum]._pMaxManaBase; + plr[pnum]._pManaBase -= v72; + plr[pnum]._pMana -= v72; + plr[pnum]._pMaxMana -= v72; + plr[pnum]._pMaxManaBase -= v72; + if((signed int)(plr[pnum]._pMana & 0xFFFFFFC0) <= 0) { + plr[pnum]._pMana = min; + plr[pnum]._pManaBase = 0; + } + if((signed int)(plr[pnum]._pMaxMana & 0xFFFFFFC0) <= 0) { + plr[pnum]._pMaxMana = max; + plr[pnum]._pMaxManaBase = 0; + } + InitDiabloMsg(28); + break; + case 17: + if(deltaload || pnum != myplr) + return; + for(j = 0; j < 40; j++) { + if(!plr[pnum].InvGrid[j]) { + v107 = 5 * (unsigned char)leveltype + random(160, 10 * (unsigned char)leveltype); + v108 = plr[pnum]._pNumInv; // check + plr[pnum].InvList[v108] = golditem; + plr[pnum].InvList[v108]._iSeed = GetRndSeed(); + plr[pnum]._pNumInv++; + plr[pnum].InvGrid[j] = plr[pnum]._pNumInv; + plr[pnum].InvList[v108]._ivalue = v107; + plr[pnum]._pGold += v107; + SetGoldCurs(pnum, v108); + } + } + InitDiabloMsg(29); + break; + case 18: + if(deltaload) + return; + if(pnum == myplr) { + InitDiabloMsg(30); + } else { + InitDiabloMsg(31); + plr[myplr]._pHitPoints = plr[myplr]._pMaxHP; + plr[myplr]._pHPBase = plr[myplr]._pMaxHPBase; + plr[myplr]._pMana = plr[myplr]._pMaxMana; + plr[myplr]._pManaBase = plr[myplr]._pMaxManaBase; + } + break; + case 19: + if(deltaload || pnum != myplr) + return; + ModifyPlrDex(pnum, 2); + CheckStats(pnum); + if(pnum == myplr) + InitDiabloMsg(32); + break; + case 20: + if(deltaload || pnum != myplr) + return; + ModifyPlrStr(pnum, 2); + CheckStats(pnum); + if(pnum == myplr) + InitDiabloMsg(33); + break; + case 21: + if(deltaload || pnum != myplr) + return; + ModifyPlrVit(pnum, 2); + CheckStats(pnum); + if(pnum == myplr) + InitDiabloMsg(34); + break; + case 22: + if(deltaload) + return; + if(pnum == myplr) { + for(yy = 0; yy < DMAXY; yy++) { + for(xx = 0; xx < DMAXX; xx++) { + automapview[xx][yy] = 1; + } + } + InitDiabloMsg(35); + } + break; + case 23: + if(deltaload || pnum != myplr) + return; + plr[pnum]._pMemSpells64 |= (__int64)1 << (SPL_HBOLT-1); + if(plr[pnum]._pSplLvl[SPL_HBOLT] < 15) + plr[pnum]._pSplLvl[SPL_HBOLT]++; + if(plr[pnum]._pSplLvl[SPL_HBOLT] < 15) + plr[pnum]._pSplLvl[SPL_HBOLT]++; + v72 = plr[pnum]._pMaxManaBase / 10; + min = plr[pnum]._pMana - plr[pnum]._pManaBase; + max = plr[pnum]._pMaxMana - plr[pnum]._pMaxManaBase; + plr[pnum]._pManaBase -= v72; + plr[pnum]._pMana -= v72; + plr[pnum]._pMaxMana -= v72; + plr[pnum]._pMaxManaBase -= v72; + if((signed int)(plr[pnum]._pMana & 0xFFFFFFC0) <= 0) { + plr[pnum]._pMana = min; + plr[pnum]._pManaBase = 0; + } + if((signed int)(plr[pnum]._pMaxMana & 0xFFFFFFC0) <= 0) { + plr[pnum]._pMaxMana = max; + plr[pnum]._pMaxManaBase = 0; + } + InitDiabloMsg(36); + break; + case 24: + if(deltaload || pnum != myplr) + return; + for(j = 0; j < 7; j++) { + if(plr[pnum].InvBody[j]._iMagical && !plr[pnum].InvBody[j]._iIdentified) + plr[pnum].InvBody[j]._iIdentified = 1; + } + for(j = 0; j < plr[pnum]._pNumInv; j++) { + if(plr[pnum].InvList[j]._iMagical && !plr[pnum].InvList[j]._iIdentified) + plr[pnum].InvList[j]._iIdentified = 1; + } + for(j = 0; j < 8; j++) { + if(plr[pnum].SpdList[j]._iMagical && !plr[pnum].SpdList[j]._iIdentified) + plr[pnum].SpdList[j]._iIdentified = 1; // belt items can't be magical? + } + InitDiabloMsg(37); + break; + case 25: + if(deltaload) + return; + if(pnum == myplr) { + InitDiabloMsg(38); + } else { + InitDiabloMsg(39); + v133 = random(155, 4); + if(v133 != 0) + v1 = -1; + else + v1 = 1; + if(v133 != 1) + v2 = -1; + else + v2 = 1; + if(v133 == 2) + v3 = 1; + else + v3 = -1; + if(v133 == 3) + v4 = 1; + else + v4 = -1; + ModifyPlrStr(myplr, v1); + ModifyPlrMag(myplr, v2); + ModifyPlrDex(myplr, v3); + ModifyPlrVit(myplr, v4); + CheckStats(myplr); + } + break; + } + + CalcPlrInv(pnum, 1); + force_redraw = 255; + + if(pnum == myplr) + NetSendCmdParam2(0, CMD_PLROPOBJ, pnum, i); +} + +void OperateSkelBook(int pnum, int i, BOOL sendmsg) +{ + /// ASSERT: assert((DWORD)i < MAXOBJECTS); + if(object[i]._oSelFlag == 0) { + return; + } + + if(!deltaload) { + PlaySfxLoc(IS_ISCROL, object[i]._ox, object[i]._oy); + } + + object[i]._oSelFlag = 0; + object[i]._oAnimFrame += 2; + + if(deltaload) { + return; + } + + SetRndSeed(object[i]._oRndSeed); + + if(random(161, 5) != 0) { + CreateTypeItem(object[i]._ox, object[i]._oy, FALSE, ITYPE_MISC, IMISC_SCROLL, sendmsg, FALSE); + } else { + CreateTypeItem(object[i]._ox, object[i]._oy, FALSE, ITYPE_MISC, IMISC_BOOK, sendmsg, FALSE); + } + + if(pnum == myplr) { + NetSendCmdParam1(FALSE, CMD_OPERATEOBJ, i); + } +} + +void OperateBookCase(int pnum, int i, BOOL sendmsg) +{ + /// ASSERT: assert((DWORD)i < MAXOBJECTS); + if(object[i]._oSelFlag == 0) { + return; + } + + if(!deltaload) { + PlaySfxLoc(IS_ISCROL, object[i]._ox, object[i]._oy); + } + + object[i]._oSelFlag = 0; + object[i]._oAnimFrame -= 2; + + if(deltaload) { + return; + } + + SetRndSeed(object[i]._oRndSeed); + CreateTypeItem(object[i]._ox, object[i]._oy, FALSE, ITYPE_MISC, IMISC_BOOK, sendmsg, FALSE); + + if(QuestStatus(Q_ZHAR) && monster[4].mName == UniqMonst[2].mName && monster[4]._msquelch == 255 && monster[4]._mhitpoints != 0) { + monster[4].mtalkmsg = TEXT_ZHAR2; + M_StartStand(0, monster[4]._mdir); + monster[4]._mgoal = 5; + monster[4]._mmode = MM_TALK; + } + + if(pnum == myplr) { + NetSendCmdParam1(FALSE, CMD_OPERATEOBJ, i); + } +} + +void OperateDecap(int pnum, int i, BOOL sendmsg) +{ + /// ASSERT: assert((DWORD)i < MAXOBJECTS); + if(object[i]._oSelFlag == 0) { + return; + } + + object[i]._oSelFlag = 0; + + if(deltaload) { + return; + } + + SetRndSeed(object[i]._oRndSeed); + CreateRndItem(object[i]._ox, object[i]._oy, FALSE, sendmsg, FALSE); + + if(pnum == myplr) { + NetSendCmdParam1(FALSE, CMD_OPERATEOBJ, i); + } +} + +void OperateArmorStand(int pnum, int i, BOOL sendmsg) +{ + int uniqueRnd; + + /// ASSERT: assert((DWORD)i < MAXOBJECTS); + if(object[i]._oSelFlag == 0) { + return; + } + + object[i]._oSelFlag = 0; + object[i]._oAnimFrame++; + + if(deltaload) { + return; + } + + SetRndSeed(object[i]._oRndSeed); + + uniqueRnd = random(0, 2); + if(currlevel <= 5) { + CreateTypeItem(object[i]._ox, object[i]._oy, TRUE, ITYPE_LARMOR, IMISC_NONE, sendmsg, FALSE); + } else if(currlevel >= 6 && currlevel <= 9) { + CreateTypeItem(object[i]._ox, object[i]._oy, uniqueRnd, ITYPE_MARMOR, IMISC_NONE, sendmsg, FALSE); + } else if(currlevel >= 10 && currlevel <= 12) { + CreateTypeItem(object[i]._ox, object[i]._oy, FALSE, ITYPE_HARMOR, IMISC_NONE, sendmsg, FALSE); + } else if(currlevel >= 13 && currlevel <= 16) { + CreateTypeItem(object[i]._ox, object[i]._oy, TRUE, ITYPE_HARMOR, IMISC_NONE, sendmsg, FALSE); + } + + if(pnum == myplr) { + NetSendCmdParam1(FALSE, CMD_OPERATEOBJ, i); + } +} + +int FindValidShrine(int i) +{ + int rv; + BOOL done; + + do { + done = FALSE; + do { + rv = random(0, 26); + if(currlevel >= shrinemin[rv] && currlevel <= shrinemax[rv] && rv != 8) { + done = TRUE; + } + } while(!done); + if(gbMaxPlayers != 1 && shrineavail[rv] == 1) { + done = FALSE; + continue; + } + if(gbMaxPlayers == 1 && shrineavail[rv] == 2) { + done = FALSE; + continue; + } + done = TRUE; + } while(!done); + + return rv; +} + +void OperateGoatShrine(int pnum, int i, int sType) +{ + /// ASSERT: assert((DWORD)i < MAXOBJECTS); + SetRndSeed(object[i]._oRndSeed); + object[i]._oVar1 = FindValidShrine(i); + OperateShrine(pnum, i, sType); + object[i]._oAnimDelay = 2; + force_redraw = 255; +} + +void OperateCauldron(int pnum, int i, int sType) +{ + /// ASSERT: assert((DWORD)i < MAXOBJECTS); + SetRndSeed(object[i]._oRndSeed); + object[i]._oVar1 = FindValidShrine(i); + OperateShrine(pnum, i, sType); + object[i]._oAnimFrame = 3; + object[i]._oAnimFlag = 0; + force_redraw = 255; +} + +BOOL OperateFountains(int pnum, int i) +{ + int ii, rndVal, statVal, saveRnd; + BOOL rv, status; + + rv = FALSE; + /// ASSERT: assert((DWORD)i < MAXOBJECTS); + SetRndSeed(object[i]._oRndSeed); + + switch(object[i]._otype) { + case OBJ_PURIFYINGFTN: + if(deltaload) { + return FALSE; + } + if(pnum != myplr) { + return FALSE; + } + if(plr[pnum]._pMana < plr[pnum]._pMaxMana) { + PlaySfxLoc(LS_FOUNTAIN, object[i]._ox, object[i]._oy); + plr[pnum]._pMana += 64; + plr[pnum]._pManaBase += 64; + if(plr[pnum]._pMana > plr[pnum]._pMaxMana) { + plr[pnum]._pMana = plr[pnum]._pMaxMana; + plr[pnum]._pManaBase = plr[pnum]._pMaxManaBase; + } + rv = TRUE; + } else if(!deltaload) { + PlaySfxLoc(LS_FOUNTAIN, object[i]._ox, object[i]._oy); + } + break; + case OBJ_BLOODFTN: + if(deltaload) { + return FALSE; + } + if(pnum != myplr) { + return FALSE; + } + if(plr[pnum]._pHitPoints < plr[pnum]._pMaxHP) { + PlaySfxLoc(LS_FOUNTAIN, object[i]._ox, object[i]._oy); + plr[pnum]._pHitPoints += 64; + plr[pnum]._pHPBase += 64; + if(plr[pnum]._pHitPoints > plr[pnum]._pMaxHP) { + plr[pnum]._pHitPoints = plr[pnum]._pMaxHP; + plr[pnum]._pHPBase = plr[pnum]._pMaxHPBase; + } + rv = TRUE; + } else if(!deltaload) { + PlaySfxLoc(LS_FOUNTAIN, object[i]._ox, object[i]._oy); + } + break; + case OBJ_MURKYFTN: + if(object[i]._oSelFlag == 0) { + break; + } + if(!deltaload) { + PlaySfxLoc(LS_FOUNTAIN, object[i]._ox, object[i]._oy); + } + object[i]._oSelFlag = 0; + if(deltaload) { + return FALSE; + } + AddMissile( + plr[pnum].WorldX, + plr[pnum].WorldY, + plr[pnum].WorldX, + plr[pnum].WorldY, + plr[pnum]._pdir, + MIS_INFRA, + -1, + pnum, + 0, + 2 * leveltype); + rv = TRUE; + if(pnum == myplr) { + NetSendCmdParam1(FALSE, CMD_OPERATEOBJ, i); + } + break; + case OBJ_TEARFTN: + if(object[i]._oSelFlag == 0) { + break; + } + saveRnd = -1; + statVal = -1; + status = FALSE; + ii = 0; + if(!deltaload) { + PlaySfxLoc(LS_FOUNTAIN, object[i]._ox, object[i]._oy); + } + object[i]._oSelFlag = 0; + if(deltaload) { + return FALSE; + } + if(pnum != myplr) { + return FALSE; + } + while(!status) { + rndVal = random(0, 4); + if(rndVal != saveRnd) { + switch(rndVal) { + case 0: + ModifyPlrStr(pnum, statVal); + break; + case 1: + ModifyPlrMag(pnum, statVal); + break; + case 2: + ModifyPlrDex(pnum, statVal); + break; + case 3: + ModifyPlrVit(pnum, statVal); + break; + } + saveRnd = rndVal; + statVal = 1; + ii++; + } + if(ii > 1) { + status = TRUE; + } + } + CheckStats(pnum); + rv = TRUE; + if(pnum == myplr) { + NetSendCmdParam1(FALSE, CMD_OPERATEOBJ, i); + } + break; + } + + force_redraw = 255; + + return rv; +} + +void OperateWeaponRack(int pnum, int i, BOOL sendmsg) +{ + int weaponType; + + /// ASSERT: assert((DWORD)i < MAXOBJECTS); + if(object[i]._oSelFlag == 0) { + return; + } + + SetRndSeed(object[i]._oRndSeed); + + switch(random(0, 4) + 1) { + case 1: + weaponType = ITYPE_SWORD; + break; + case 2: + weaponType = ITYPE_AXE; + break; + case 3: + weaponType = ITYPE_BOW; + break; + case 4: + weaponType = ITYPE_MACE; + break; + } + + object[i]._oSelFlag = 0; + object[i]._oAnimFrame++; + + if(deltaload) { + return; + } + + if(leveltype > DTYPE_CATHEDRAL) { + CreateTypeItem(object[i]._ox, object[i]._oy, TRUE, weaponType, IMISC_NONE, sendmsg, FALSE); + } else { + CreateTypeItem(object[i]._ox, object[i]._oy, FALSE, weaponType, IMISC_NONE, sendmsg, FALSE); + } + + if(pnum == myplr) { + NetSendCmdParam1(FALSE, CMD_OPERATEOBJ, i); + } +} + +void OperateStoryBook(int pnum, int i) +{ + /// ASSERT: assert((DWORD)i < MAXOBJECTS); + if(object[i]._oSelFlag == 0) { + return; + } + if(deltaload || qtextflag || pnum != myplr) { + return; + } + + object[i]._oAnimFrame = object[i]._oVar4; + PlaySfxLoc(IS_ISCROL, object[i]._ox, object[i]._oy); + InitQTextMsg(object[i]._oVar2); + NetSendCmdParam1(FALSE, CMD_OPERATEOBJ, i); +} + +void OperateLazStand(int pnum, int i) +{ + int x, y; + + /// ASSERT: assert((DWORD)i < MAXOBJECTS); + if(object[i]._oSelFlag == 0) { + return; + } + if(deltaload || qtextflag || pnum != myplr) { + return; + } + + object[i]._oAnimFrame++; + object[i]._oSelFlag = 0; + GetSuperItemLoc(object[i]._ox, object[i]._oy, x, y); + SpawnQuestItem(IDI_LAZSTAFF, x, y, 0, 0); +} + +void OperateObject(int pnum, int i, BOOL TeleFlag) +{ + BOOL senditemmsg; + + senditemmsg = pnum == myplr; + + /// ASSERT: assert((DWORD)i < MAXOBJECTS); + switch(object[i]._otype) { + case OBJ_L1LDOOR: + case OBJ_L1RDOOR: + if(TeleFlag) { + if(object[i]._otype == OBJ_L1LDOOR) { + OperateL1LDoor(pnum, i, TRUE); + } + if(object[i]._otype == OBJ_L1RDOOR) { + OperateL1RDoor(pnum, i, TRUE); + } + } else if(pnum == myplr) { + OperateL1Door(pnum, i, TRUE); + } + break; + case OBJ_L2LDOOR: + case OBJ_L2RDOOR: + if(TeleFlag) { + if(object[i]._otype == OBJ_L2LDOOR) { + OperateL2LDoor(pnum, i, TRUE); + } + if(object[i]._otype == OBJ_L2RDOOR) { + OperateL2RDoor(pnum, i, TRUE); + } + } else if(pnum == myplr) { + OperateL2Door(pnum, i, TRUE); + } + break; + case OBJ_L3LDOOR: + case OBJ_L3RDOOR: + if(TeleFlag) { + if(object[i]._otype == OBJ_L3LDOOR) { + OperateL3LDoor(pnum, i, TRUE); + } + if(object[i]._otype == OBJ_L3RDOOR) { + OperateL3RDoor(pnum, i, TRUE); + } + } else if(pnum == myplr) { + OperateL3Door(pnum, i, TRUE); + } + break; + case OBJ_LEVER: + case OBJ_SWITCHSKL: + OperateLever(pnum, i); + break; + case OBJ_BOOK2L: + OperateBook(pnum, i); + break; + case OBJ_BOOK2R: + OperateSChambBk(pnum, i); + break; + case OBJ_CHEST1: + case OBJ_CHEST2: + case OBJ_CHEST3: + case OBJ_TCHEST1: + case OBJ_TCHEST2: + case OBJ_TCHEST3: + OperateChest(pnum, i, senditemmsg); + break; + case OBJ_SARC: + OperateSarc(pnum, i, senditemmsg); + break; + case OBJ_FLAMELVR: + OperateTrapLvr(i); + break; + case OBJ_BLINDBOOK: + case OBJ_BLOODBOOK: + case OBJ_STEELTOME: + OperateBookLever(pnum, i); + break; + case OBJ_SHRINEL: + case OBJ_SHRINER: + OperateShrine(pnum, i, IS_MAGIC); + break; + case OBJ_SKELBOOK: + case OBJ_BOOKSTAND: + OperateSkelBook(pnum, i, senditemmsg); + break; + case OBJ_BOOKCASEL: + case OBJ_BOOKCASER: + OperateBookCase(pnum, i, senditemmsg); + break; + case OBJ_DECAP: + OperateDecap(pnum, i, senditemmsg); + break; + case OBJ_ARMORSTAND: + case OBJ_WARARMOR: + OperateArmorStand(pnum, i, senditemmsg); + break; + case OBJ_GOATSHRINE: + OperateGoatShrine(pnum, i, LS_GSHRINE); + break; + case OBJ_CAULDRON: + OperateCauldron(pnum, i, LS_CALDRON); + break; + case OBJ_BLOODFTN: + case OBJ_PURIFYINGFTN: + case OBJ_MURKYFTN: + case OBJ_TEARFTN: + OperateFountains(pnum, i); + break; + case OBJ_STORYBOOK: + OperateStoryBook(pnum, i); + break; + case OBJ_PEDISTAL: + OperatePedistal(pnum, i); + break; + case OBJ_WARWEAP: + case OBJ_WEAPONRACK: + OperateWeaponRack(pnum, i, senditemmsg); + break; + case OBJ_MUSHPATCH: + OperateMushPatch(pnum, i); + break; + case OBJ_LAZSTAND: + OperateLazStand(pnum, i); + break; + case OBJ_SLAINHERO: + OperateSlainHero(pnum, i, senditemmsg); + break; + case OBJ_SIGNCHEST: + OperateInnSignChest(pnum, i); + break; + } +} + +void SyncOpL1Door(int pnum, int cmd, int i) +{ + BOOL opok; + + if(pnum == myplr) { + return; + } + + opok = FALSE; + /// ASSERT: assert((DWORD)i < MAXOBJECTS); + if(cmd == CMD_OPENDOOR && object[i]._oVar4 == 0) { + opok = TRUE; + } + if(cmd == CMD_CLOSEDOOR && object[i]._oVar4 == 1) { + opok = TRUE; + } + if(opok) { + if(object[i]._otype == OBJ_L1LDOOR) { + OperateL1LDoor(-1, i, FALSE); + } + if(object[i]._otype == OBJ_L1RDOOR) { + OperateL1RDoor(-1, i, FALSE); + } + } +} + +void SyncOpL2Door(int pnum, int cmd, int i) +{ + BOOL opok; + + if(pnum == myplr) { + return; + } + + opok = FALSE; + /// ASSERT: assert((DWORD)i < MAXOBJECTS); + if(cmd == CMD_OPENDOOR && object[i]._oVar4 == 0) { + opok = TRUE; + } + if(cmd == CMD_CLOSEDOOR && object[i]._oVar4 == 1) { + opok = TRUE; + } + if(opok) { + if(object[i]._otype == OBJ_L2LDOOR) { + OperateL2LDoor(-1, i, FALSE); + } + if(object[i]._otype == OBJ_L2RDOOR) { + OperateL2RDoor(-1, i, FALSE); + } + } +} + +void SyncOpL3Door(int pnum, int cmd, int i) +{ + BOOL opok; + + if(pnum == myplr) { + return; + } + + opok = FALSE; + /// ASSERT: assert((DWORD)i < MAXOBJECTS); + if(cmd == CMD_OPENDOOR && object[i]._oVar4 == 0) { + opok = TRUE; + } + if(cmd == CMD_CLOSEDOOR && object[i]._oVar4 == 1) { + opok = TRUE; + } + if(opok) { + if(object[i]._otype == OBJ_L3LDOOR) { + OperateL3LDoor(-1, i, FALSE); + } + if(object[i]._otype == OBJ_L3RDOOR) { + OperateL3RDoor(-1, i, FALSE); + } + } +} + +void SyncOpObject(int pnum, int cmd, int i) +{ + /// ASSERT: assert((DWORD)i < MAXOBJECTS); + switch(object[i]._otype) { + case OBJ_L1LDOOR: + case OBJ_L1RDOOR: + SyncOpL1Door(pnum, cmd, i); + break; + case OBJ_L2LDOOR: + case OBJ_L2RDOOR: + SyncOpL2Door(pnum, cmd, i); + break; + case OBJ_L3LDOOR: + case OBJ_L3RDOOR: + SyncOpL3Door(pnum, cmd, i); + break; + case OBJ_LEVER: + case OBJ_SWITCHSKL: + OperateLever(pnum, i); + break; + case OBJ_CHEST1: + case OBJ_CHEST2: + case OBJ_CHEST3: + case OBJ_TCHEST1: + case OBJ_TCHEST2: + case OBJ_TCHEST3: + OperateChest(pnum, i, FALSE); + break; + case OBJ_SARC: + OperateSarc(pnum, i, FALSE); + break; + case OBJ_BLINDBOOK: + case OBJ_BLOODBOOK: + case OBJ_STEELTOME: + OperateBookLever(pnum, i); + break; + case OBJ_SHRINEL: + case OBJ_SHRINER: + OperateShrine(pnum, i, IS_MAGIC); + break; + case OBJ_SKELBOOK: + case OBJ_BOOKSTAND: + OperateSkelBook(pnum, i, FALSE); + break; + case OBJ_BOOKCASEL: + case OBJ_BOOKCASER: + OperateBookCase(pnum, i, FALSE); + break; + case OBJ_DECAP: + OperateDecap(pnum, i, FALSE); + break; + case OBJ_ARMORSTAND: + case OBJ_WARARMOR: + OperateArmorStand(pnum, i, FALSE); + break; + case OBJ_GOATSHRINE: + OperateGoatShrine(pnum, i, LS_GSHRINE); + break; + case OBJ_CAULDRON: + OperateCauldron(pnum, i, LS_CALDRON); + break; + case OBJ_MURKYFTN: + case OBJ_TEARFTN: + OperateFountains(pnum, i); + break; + case OBJ_STORYBOOK: + OperateStoryBook(pnum, i); + break; + case OBJ_PEDISTAL: + OperatePedistal(pnum, i); + break; + case OBJ_WARWEAP: + case OBJ_WEAPONRACK: + OperateWeaponRack(pnum, i, FALSE); + break; + case OBJ_MUSHPATCH: + OperateMushPatch(pnum, i); + break; + case OBJ_SLAINHERO: + OperateSlainHero(pnum, i, FALSE); + break; + case OBJ_SIGNCHEST: + OperateInnSignChest(pnum, i); + break; + } +} + +void BreakCrux(int i) +{ + int j, ot, oi; + BOOL mapflag; + + /// ASSERT: assert((DWORD)i < MAXOBJECTS); + object[i]._oAnimFlag = 1; + object[i]._oAnimFrame = 1; + object[i]._oAnimDelay = 1; + object[i]._oSolidFlag = 1; + object[i]._oMissFlag = 1; + object[i]._oBreak = -1; + object[i]._oSelFlag = 0; + + mapflag = TRUE; + for(j = 0; j < nobjects; j++) { + oi = objectactive[j]; + ot = object[oi]._otype; + if((ot == OBJ_CRUX1 || ot == OBJ_CRUX2 || ot == OBJ_CRUX3) && object[i]._oVar8 == object[oi]._oVar8 && object[oi]._oBreak != -1) { + mapflag = FALSE; + } + } + + if(mapflag) { + if(!deltaload) { + PlaySfxLoc(IS_LEVER, object[i]._ox, object[i]._oy); + } + ObjChangeMap(object[i]._oVar1, object[i]._oVar2, object[i]._oVar3, object[i]._oVar4); + } +} + +void BreakBarrel(int pnum, int i, int dam, BOOL forcebreak, BOOL sendmsg) +{ + int x, y, oi; + + /// ASSERT: assert((DWORD)i < MAXOBJECTS); + if(object[i]._oSelFlag == 0) { + return; + } + + if(forcebreak) { + object[i]._oVar1 = 0; + } else { + object[i]._oVar1 -= dam; + if(pnum != myplr && object[i]._oVar1 <= 0) { + object[i]._oVar1 = 1; + } + } + + if(object[i]._oVar1 > 0) { + if(!deltaload) { + PlaySfxLoc(IS_IBOW, object[i]._ox, object[i]._oy); + } + return; + } + + object[i]._oVar1 = 0; + object[i]._oAnimFlag = 1; + object[i]._oAnimFrame = 1; + object[i]._oAnimDelay = 1; + object[i]._oSolidFlag = 0; + object[i]._oMissFlag = 1; + object[i]._oBreak = -1; + object[i]._oSelFlag = 0; + object[i]._oPreFlag = 1; + + if(deltaload) { + object[i]._oAnimFrame = object[i]._oAnimLen; + object[i]._oAnimCnt = 0; + object[i]._oAnimDelay = 1000; + return; + } + + if(object[i]._otype == OBJ_BARRELEX) { + PlaySfxLoc(IS_BARLFIRE, object[i]._ox, object[i]._oy); + for(y = object[i]._oy - 1; y <= object[i]._oy + 1; y++) { + for(x = object[i]._ox - 1; x <= object[i]._ox + 1; x++) { + if(dMonster[x][y] > 0) { + MonsterTrapHit(dMonster[x][y] - 1, 1, 4, 0, 1, FALSE); + } + if(dPlayer[x][y] > 0) { + PlayerMHit(dPlayer[x][y] - 1, -1, 0, 8, 16, 1, FALSE, 0); + } + if(dObject[x][y] > 0) { + oi = dObject[x][y] - 1; + if(object[oi]._otype == OBJ_BARRELEX && object[oi]._oBreak != -1) { + BreakBarrel(pnum, oi, dam, TRUE, sendmsg); + } + } + } + } + } else { + PlaySfxLoc(IS_BARREL, object[i]._ox, object[i]._oy); + SetRndSeed(object[i]._oRndSeed); + if(object[i]._oVar2 <= 1) { + if(object[i]._oVar3 == 0) { + CreateRndUseful(pnum, object[i]._ox, object[i]._oy, sendmsg); + } else { + CreateRndItem(object[i]._ox, object[i]._oy, FALSE, sendmsg, FALSE); + } + } + if(object[i]._oVar2 >= 8) { + SpawnSkeleton(object[i]._oVar4, object[i]._ox, object[i]._oy); + } + } + + if(pnum == myplr) { + NetSendCmdParam2(FALSE, CMD_BREAKOBJ, pnum, i); + } +} + +void BreakObject(int pnum, int oi) +{ + int objdam, mind, maxd; + + if(pnum != -1) { + mind = plr[pnum]._pIMinDam; + maxd = plr[pnum]._pIMaxDam; + objdam = random(163, maxd - mind + 1) + mind; + objdam += objdam * plr[pnum]._pIBonusDam / 100; + objdam += plr[pnum]._pDamageMod + plr[pnum]._pIBonusDamMod; + } else { + objdam = 10; + } + + /// ASSERT: assert((DWORD)oi < MAXOBJECTS); + switch(object[oi]._otype) { + case OBJ_CRUX1: + case OBJ_CRUX2: + case OBJ_CRUX3: + BreakCrux(oi); + break; + case OBJ_BARREL: + case OBJ_BARRELEX: + BreakBarrel(pnum, oi, objdam, FALSE, TRUE); + break; + } +} + +void SyncBreakObj(int pnum, int oi) +{ + /// ASSERT: assert((DWORD)oi < MAXOBJECTS); + switch(object[oi]._otype) { + case OBJ_BARREL: + case OBJ_BARRELEX: + BreakBarrel(pnum, oi, 0, TRUE, FALSE); + break; + } +} + +void SyncL1Doors(int i) +{ + int dx, dy; + + /// ASSERT: assert((DWORD)i < MAXOBJECTS); + if(object[i]._oVar4 == 0) { + object[i]._oMissFlag = 0; + return; + } + + object[i]._oMissFlag = 1; + dx = object[i]._ox; + dy = object[i]._oy; + object[i]._oSelFlag = 2; + + if(object[i]._otype == OBJ_L1LDOOR) { + if(object[i]._oVar1 == 214) { + ObjSetMicro(dx, dy, 408); + } else { + ObjSetMicro(dx, dy, 393); + } + dSpecial[dx][dy] = 7; + objects_set_door_piece(dx - 1, dy); + dy--; + } else { + ObjSetMicro(dx, dy, 395); + dSpecial[dx][dy] = 8; + objects_set_door_piece(dx, dy - 1); + dx--; + } + + DoorSet(i, dx, dy); +} + +void SyncCrux(int i) +{ + int j, ot, oi; + BOOL mapflag; + + mapflag = TRUE; + for(j = 0; j < nobjects; j++) { + oi = objectactive[j]; + /// ASSERT: assert((DWORD)oi < MAXOBJECTS); + ot = object[oi]._otype; + if((ot == OBJ_CRUX1 || ot == OBJ_CRUX2 || ot == OBJ_CRUX3) && object[i]._oVar8 == object[oi]._oVar8 && object[oi]._oBreak != -1) { + mapflag = FALSE; + } + } + + if(mapflag) { + ObjChangeMap(object[i]._oVar1, object[i]._oVar2, object[i]._oVar3, object[i]._oVar4); + } +} + +void SyncLever(int i) +{ + /// ASSERT: assert((DWORD)i < MAXOBJECTS); + if(object[i]._oSelFlag == 0) { + ObjChangeMap(object[i]._oVar1, object[i]._oVar2, object[i]._oVar3, object[i]._oVar4); + } +} + +void SyncQSTLever(int i) +{ + int tren; + + /// ASSERT: assert((DWORD)i < MAXOBJECTS); + if(object[i]._oAnimFrame == object[i]._oVar6) { + ObjChangeMapResync(object[i]._oVar1, object[i]._oVar2, object[i]._oVar3, object[i]._oVar4); + if(object[i]._otype == OBJ_BLINDBOOK) { + tren = TransVal; + TransVal = 9; + DRLG_MRectTrans(object[i]._oVar1, object[i]._oVar2, object[i]._oVar3, object[i]._oVar4); + TransVal = tren; + } + } +} + +void SyncPedistal(int i) +{ + BYTE *setp; + + /// ASSERT: assert((DWORD)i < MAXOBJECTS); + if(object[i]._oVar6 == 1) { + ObjChangeMapResync(setpc_x, setpc_y + 3, setpc_x + 2, setpc_y + 7); + } + if(object[i]._oVar6 == 2) { + ObjChangeMapResync(setpc_x, setpc_y + 3, setpc_x + 2, setpc_y + 7); + ObjChangeMapResync(setpc_x + 6, setpc_y + 3, setpc_x + setpc_w, setpc_y + 7); + } + if(object[i]._oVar6 == 3) { + ObjChangeMapResync(object[i]._oVar1, object[i]._oVar2, object[i]._oVar3, object[i]._oVar4); + setp = DiabLoad("Levels\\L2Data\\Blood2.DUN", NULL, 'STPC'); + LoadMapObjs(setp, 2 * setpc_x, 2 * setpc_y); + MemFreeDbg(setp); + } +} + +void SyncL2Doors(int i) +{ + int dx, dy; + + /// ASSERT: assert((DWORD)i < MAXOBJECTS); + if(object[i]._oVar4 == 0) { + object[i]._oMissFlag = 0; + } else { + object[i]._oMissFlag = 1; + } + + dx = object[i]._ox; + dy = object[i]._oy; + object[i]._oSelFlag = 2; + + if(object[i]._otype == OBJ_L2LDOOR && object[i]._oVar4 == 0) { + ObjSetMicro(dx, dy, 538); + return; + } + if(object[i]._otype == OBJ_L2LDOOR && (object[i]._oVar4 == 1 || object[i]._oVar4 == 2)) { + ObjSetMicro(dx, dy, 13); + return; + } + if(object[i]._otype == OBJ_L2RDOOR && object[i]._oVar4 == 0) { + ObjSetMicro(dx, dy, 540); + return; + } + if(object[i]._otype == OBJ_L2RDOOR && (object[i]._oVar4 == 1 || object[i]._oVar4 == 2)) { + ObjSetMicro(dx, dy, 17); + return; + } +} + +void SyncL3Doors(int i) +{ + int dx, dy; + + /// ASSERT: assert((DWORD)i < MAXOBJECTS); + object[i]._oMissFlag = 1; + dx = object[i]._ox; + dy = object[i]._oy; + object[i]._oSelFlag = 2; + + if(object[i]._otype == OBJ_L3LDOOR && object[i]._oVar4 == 0) { + ObjSetMicro(dx, dy, 531); + return; + } + if(object[i]._otype == OBJ_L3LDOOR && (object[i]._oVar4 == 1 || object[i]._oVar4 == 2)) { + ObjSetMicro(dx, dy, 538); + return; + } + if(object[i]._otype == OBJ_L3RDOOR && object[i]._oVar4 == 0) { + ObjSetMicro(dx, dy, 534); + return; + } + if(object[i]._otype == OBJ_L3RDOOR && (object[i]._oVar4 == 1 || object[i]._oVar4 == 2)) { + ObjSetMicro(dx, dy, 541); + return; + } +} + +void SyncObjectAnim(int o) +{ + int ai, ot, j; + + /// ASSERT: assert((DWORD)o < MAXOBJECTS); + ot = object[o]._otype; + ai = AllObjects[ot].ofindex; + j = 0; + while(ObjFileList[j] != ai) { + j++; + } + object[o]._oAnimData = pObjCels[j]; + + switch(object[o]._otype) { + case OBJ_L1LDOOR: + case OBJ_L1RDOOR: + SyncL1Doors(o); + break; + case OBJ_L2LDOOR: + case OBJ_L2RDOOR: + SyncL2Doors(o); + break; + case OBJ_L3LDOOR: + case OBJ_L3RDOOR: + SyncL3Doors(o); + break; + case OBJ_CRUX1: + case OBJ_CRUX2: + case OBJ_CRUX3: + SyncCrux(o); + break; + case OBJ_LEVER: + case OBJ_BOOK2L: + case OBJ_SWITCHSKL: + SyncLever(o); + break; + case OBJ_BOOK2R: + case OBJ_BLINDBOOK: + case OBJ_STEELTOME: + SyncQSTLever(o); + break; + case OBJ_PEDISTAL: + SyncPedistal(o); + break; + } +} + +void GetObjectStr(int i) +{ + /// ASSERT: assert((DWORD)i < MAXOBJECTS); + switch(object[i]._otype) { + case OBJ_CRUX1: + case OBJ_CRUX2: + case OBJ_CRUX3: + strcpy(infostr, "Crucified Skeleton"); + break; + case OBJ_LEVER: + case OBJ_FLAMELVR: + strcpy(infostr, "Lever"); + break; + case OBJ_L1LDOOR: + case OBJ_L1RDOOR: + case OBJ_L2LDOOR: + case OBJ_L2RDOOR: + case OBJ_L3LDOOR: + case OBJ_L3RDOOR: + if(object[i]._oVar4 == 1) { + strcpy(infostr, "Open Door"); + } + if(object[i]._oVar4 == 0) { + strcpy(infostr, "Closed Door"); + } + if(object[i]._oVar4 == 2) { + strcpy(infostr, "Blocked Door"); + } + break; + case OBJ_BOOK2L: + if(setlevel) { + if(setlvlnum == SL_BONECHAMB) { + strcpy(infostr, "Ancient Tome"); + } else if(setlvlnum == SL_VILEBETRAYER) { + strcpy(infostr, "Book of Vileness"); + } + } + break; + case OBJ_SWITCHSKL: + strcpy(infostr, "Skull Lever"); + break; + case OBJ_BOOK2R: + strcpy(infostr, "Mythical Book"); + break; + case OBJ_CHEST1: + case OBJ_TCHEST1: + strcpy(infostr, "Small Chest"); + break; + case OBJ_CHEST2: + case OBJ_TCHEST2: + strcpy(infostr, "Chest"); + break; + case OBJ_CHEST3: + case OBJ_TCHEST3: + case OBJ_SIGNCHEST: + strcpy(infostr, "Large Chest"); + break; + case OBJ_SARC: + strcpy(infostr, "Sarcophagus"); + break; + case OBJ_BOOKSHELF: + strcpy(infostr, "Bookshelf"); + break; + case OBJ_BOOKCASEL: + case OBJ_BOOKCASER: + strcpy(infostr, "Bookcase"); + break; + case OBJ_BARREL: + case OBJ_BARRELEX: + strcpy(infostr, "Barrel"); + break; + case OBJ_SHRINEL: + case OBJ_SHRINER: + sprintf(tempstr, "%s Shrine", shrinestrs[object[i]._oVar1]); + strcpy(infostr, tempstr); + break; + case OBJ_SKELBOOK: + strcpy(infostr, "Skeleton Tome"); + break; + case OBJ_BOOKSTAND: + strcpy(infostr, "Library Book"); + break; + case OBJ_BLOODFTN: + strcpy(infostr, "Blood Fountain"); + break; + case OBJ_DECAP: + strcpy(infostr, "Decapitated Body"); + break; + case OBJ_BLINDBOOK: + strcpy(infostr, "Book of the Blind"); + break; + case OBJ_STEELTOME: + strcpy(infostr, "Steel Tome"); + break; + case OBJ_BLOODBOOK: + strcpy(infostr, "Book of Blood"); + break; + case OBJ_PURIFYINGFTN: + strcpy(infostr, "Purifying Spring"); + break; + case OBJ_ARMORSTAND: + case OBJ_WARARMOR: + strcpy(infostr, "Armor"); + break; + case OBJ_WARWEAP: + strcpy(infostr, "Weapon Rack"); + break; + case OBJ_GOATSHRINE: + strcpy(infostr, "Goat Shrine"); + break; + case OBJ_CAULDRON: + strcpy(infostr, "Cauldron"); + break; + case OBJ_MURKYFTN: + strcpy(infostr, "Murky Pool"); + break; + case OBJ_TEARFTN: + strcpy(infostr, "Fountain of Tears"); + break; + case OBJ_PEDISTAL: + strcpy(infostr, "Pedestal of Blood"); + break; + case OBJ_STORYBOOK: + strcpy(infostr, StoryBookName[object[i]._oVar3]); + break; + case OBJ_WEAPONRACK: + strcpy(infostr, "Weapon Rack"); + break; + case OBJ_MUSHPATCH: + strcpy(infostr, "Mushroom Patch"); + break; + case OBJ_LAZSTAND: + strcpy(infostr, "Vile Stand"); + break; + case OBJ_SLAINHERO: + strcpy(infostr, "Slain Hero"); + break; + } + + if(plr[myplr]._pClass == PC_ROGUE && object[i]._oTrapFlag) { + sprintf(tempstr, "Trapped %s", infostr); + strcpy(infostr, tempstr); + infoclr = COL_RED; + } +} diff --git a/2020_03_31/Source/objects.h b/2020_03_31/Source/objects.h new file mode 100644 index 00000000..a7071b1e --- /dev/null +++ b/2020_03_31/Source/objects.h @@ -0,0 +1,166 @@ +//HEADER_GOES_HERE +#ifndef __OBJECTS_H__ +#define __OBJECTS_H__ + +extern int trapid; // weak +extern int trapdir; // weak +extern unsigned char *pObjCels[40]; +extern char ObjFileList[40]; +extern int objectactive[MAXOBJECTS]; +extern int nobjects; // idb +extern int leverid; // idb +extern int objectavail[MAXOBJECTS]; +extern ObjectStruct object[MAXOBJECTS]; +extern int InitObjFlag; // weak +extern int numobjfiles; // weak + +void InitObjectGFX(); +void FreeObjectGFX(); +BOOL RndLocOk(int xp, int yp); +void InitRndLocObj(int min, int max, int objtype); +void InitRndLocBigObj(int min, int max, int objtype); +void InitRndLocObj5x5(int min, int max, int objtype); +void ClrAllObjects(); +void AddTortures(); +void AddCandles(); +void AddBookLever(int lx1, int ly1, int lx2, int ly2, int x1, int y1, int x2, int y2, int msg); +void InitRndBarrels(); +void AddL1Objs(int x1, int y1, int x2, int y2); +void AddL2Objs(int x1, int y1, int x2, int y2); +void AddL3Objs(int x1, int y1, int x2, int y2); +BOOL WallTrapLocOk(int xp, int yp); +void AddL2Torches(); +BOOL TorchLocOK(int xp, int yp); +void AddObjTraps(); +void AddChestTraps(); +void LoadMapObjects(BYTE *pMap, int startx, int starty, int x1, int y1, int w, int h, int leveridx); +void LoadMapObjs(BYTE *pMap, int startx, int starty); +void AddDiabObjs(); +void AddStoryBooks(); +void AddHookedBodies(int freq); +void AddL4Goodies(); +void AddLazStand(); +void InitObjects(); +void SetMapObjects(BYTE *pMap, int startx, int starty); +void DeleteObject_(int oi, int i); +void SetupObject(int i, int x, int y, int ot); +void SetObjMapRange(int i, int x1, int y1, int x2, int y2, int v); +void SetBookMsg(int i, int msg); +void AddL1Door(int i, int x, int y, int ot); +void AddSCambBook(int i); +void AddChest(int i, int t); +void AddL2Door(int i, int x, int y, int ot); +void AddL3Door(int i, int x, int y, int ot); +void AddSarc(int i); +void AddFlameTrap(int i); +void AddFlameLvr(int i); +void AddTrap(int i, int ot); +void AddObjLight(int i, int r); +void AddBarrel(int i, int ot); +void AddShrine(int i); +void AddBookcase(int i); +void AddBookstand(int i); +void AddBloodFtn(int i); +void AddPurifyingFountain(int i); +void AddArmorStand(int i); +void AddGoatShrine(int i); +void AddCauldron(int i); +void AddMurkyFountain(int i); +void AddTearFountain(int i); +void AddDecap(int i); +void AddVilebook(int i); +void AddMagicCircle(int i); +void AddBrnCross(int i); +void AddPedistal(int i); +void AddStoryBook(int i); +void AddWeaponRack(int i); +void AddTorturedBody(int i); +void GetRndObjLoc(int randarea, int &xx, int &yy); +void AddMushPatch(); +void AddSlainHero(); +void AddObject(int ot, int ox, int oy); +void Obj_Light(int i, int lr); +void Obj_Circle(int i); +void Obj_StopAnim(int i); +void Obj_Door(int i); +void Obj_Sarc(int i); +void ActivateTrapLine(int ttype, int tid); +void Obj_FlameTrap(int i); +void Obj_Trap(int i); +void Obj_BCrossDamage(int i); +void ProcessObjects(); +void ObjSetMicro(int dx, int dy, int pn); +void objects_set_door_piece(int x, int y); +void ObjSetMini(int x, int y, int v); +void ObjL1Special(int x1, int y1, int x2, int y2); +void ObjL2Special(int x1, int y1, int x2, int y2); +void DoorSet(int oi, int dx, int dy); +void RedoPlayerVision(); +void OperateL1RDoor(int pnum, int oi, BOOL sendflag); +void OperateL1LDoor(int pnum, int oi, BOOL sendflag); +void OperateL2RDoor(int pnum, int oi, BOOL sendflag); +void OperateL2LDoor(int pnum, int oi, BOOL sendflag); +void OperateL3RDoor(int pnum, int oi, BOOL sendflag); +void OperateL3LDoor(int pnum, int oi, BOOL sendflag); +void MonstCheckDoors(int m); +void ObjChangeMap(int x1, int y1, int x2, int y2); +void ObjChangeMapResync(int x1, int y1, int x2, int y2); +void OperateL1Door(int pnum, int i, BOOL sendflag); +void OperateLever(int pnum, int i); +void OperateBook(int pnum, int i); +void OperateBookLever(int pnum, int i); +void OperateSChambBk(int pnum, int i); +void OperateChest(int pnum, int i, BOOL sendmsg); +void OperateMushPatch(int pnum, int i); +void OperateInnSignChest(int pnum, int i); +void OperateSlainHero(int pnum, int i, BOOL sendmsg); +void OperateTrapLvr(int i); +void OperateSarc(int pnum, int i, BOOL sendmsg); +void OperateL2Door(int pnum, int i, BOOL sendflag); +void OperateL3Door(int pnum, int i, BOOL sendflag); +void OperatePedistal(int pnum, int i); +void TryDisarm(int pnum, int i); +int ItemMiscIdIdx(int imiscid); +void OperateShrine(int pnum, int i, int sType); +void OperateSkelBook(int pnum, int i, BOOL sendmsg); +void OperateBookCase(int pnum, int i, BOOL sendmsg); +void OperateDecap(int pnum, int i, BOOL sendmsg); +void OperateArmorStand(int pnum, int i, BOOL sendmsg); +int FindValidShrine(int i); +void OperateGoatShrine(int pnum, int i, int sType); +void OperateCauldron(int pnum, int i, int sType); +BOOL OperateFountains(int pnum, int i); +void OperateWeaponRack(int pnum, int i, BOOL sendmsg); +void OperateStoryBook(int pnum, int i); +void OperateLazStand(int pnum, int i); +void OperateObject(int pnum, int i, BOOL TeleFlag); +void SyncOpL1Door(int pnum, int cmd, int i); +void SyncOpL2Door(int pnum, int cmd, int i); +void SyncOpL3Door(int pnum, int cmd, int i); +void SyncOpObject(int pnum, int cmd, int i); +void BreakCrux(int i); +void BreakBarrel(int pnum, int i, int dam, BOOL forcebreak, BOOL sendmsg); +void BreakObject(int pnum, int oi); +void SyncBreakObj(int pnum, int oi); +void SyncL1Doors(int i); +void SyncCrux(int i); +void SyncLever(int i); +void SyncQSTLever(int i); +void SyncPedistal(int i); +void SyncL2Doors(int i); +void SyncL3Doors(int i); +void SyncObjectAnim(int o); +void GetObjectStr(int i); + +/* rdata */ + +extern int bxadd[8]; +extern int byadd[8]; +extern char *shrinestrs[26]; +extern char shrinemin[26]; +extern char shrinemax[26]; +extern char shrineavail[26]; +extern char *StoryBookName[9]; +extern int StoryText[3][3]; + +#endif /* __OBJECTS_H__ */ diff --git a/2020_03_31/Source/pack.cpp b/2020_03_31/Source/pack.cpp new file mode 100644 index 00000000..d77bf76b --- /dev/null +++ b/2020_03_31/Source/pack.cpp @@ -0,0 +1,273 @@ +#include "diablo.h" +#include "../3rdParty/Storm/Source/storm.h" + +static void PackItem(PkItemStruct *id, ItemStruct *is) +{ + short v2; // ax + short v3; // bx + + if ( is->_itype == -1 ) + { + id->idx = -1; + } + else + { + id->idx = is->IDidx; + if ( is->IDidx == IDI_EAR ) + { + _LOBYTE(v2) = 0; + _LOBYTE(v3) = 0; + _HIBYTE(v2) = is->_iName[7]; + id->iCreateInfo = is->_iName[8] | v2; + id->iSeed = is->_iName[12] | ((is->_iName[11] | ((is->_iName[10] | (is->_iName[9] << 8)) << 8)) << 8); + id->bId = is->_iName[13]; + id->bDur = is->_iName[14]; + id->bMDur = is->_iName[15]; + id->bCh = is->_iName[16]; + id->bMCh = is->_iName[17]; + _HIBYTE(v3) = is->_iName[18]; + id->wValue = _LOWORD(is->_ivalue) | v3 | ((_LOWORD(is->_iCurs) - 19) << 6); + id->dwBuff = is->_iName[22] | ((is->_iName[21] | ((is->_iName[20] | (is->_iName[19] << 8)) << 8)) << 8); + } + else + { + id->iSeed = is->_iSeed; + id->iCreateInfo = is->_iCreateInfo; + id->bId = _LOBYTE(is->_iIdentified) + 2 * is->_iMagical; + id->bDur = is->_iDurability; + id->bMDur = is->_iMaxDur; + id->bCh = is->_iCharges; + id->bMCh = is->_iMaxCharges; + if ( !is->IDidx ) + id->wValue = is->_ivalue; + } + } +} + +void PackPlayer(PkPlayerStruct *pPack, int pnum, _bool manashield) +{ + PlayerStruct *pPlayer; // edi + int i; // [esp+8h] [ebp-Ch] + ItemStruct *pi; // [esp+Ch] [ebp-8h] + PkItemStruct *pki; // [esp+10h] [ebp-4h] + + memset(pPack, 0, 0x4F2); + pPlayer = &plr[pnum]; + pPack->destAction = pPlayer->destAction; + pPack->destParam1 = pPlayer->destParam1; + pPack->destParam2 = pPlayer->destParam2; + pPack->plrlevel = pPlayer->plrlevel; + pPack->px = pPlayer->WorldX; + pPack->py = pPlayer->WorldY; + pPack->targx = pPlayer->_ptargx; + pPack->targy = pPlayer->_ptargy; + strcpy(pPack->pName, pPlayer->_pName); + pPack->pClass = pPlayer->_pClass; + pPack->pBaseStr = pPlayer->_pBaseStr; + pPack->pBaseMag = pPlayer->_pBaseMag; + pPack->pBaseDex = pPlayer->_pBaseDex; + pPack->pBaseVit = pPlayer->_pBaseVit; + pPack->pLevel = pPlayer->_pLevel; + pPack->pStatPts = pPlayer->_pStatPts; + pPack->pExperience = pPlayer->_pExperience; + pPack->pGold = pPlayer->_pGold; + pPack->pHPBase = pPlayer->_pHPBase; + pPack->pMaxHPBase = pPlayer->_pMaxHPBase; + pPack->pManaBase = pPlayer->_pManaBase; + pPack->pMaxManaBase = pPlayer->_pMaxManaBase; + pPack->pMemSpells = pPlayer->_pMemSpells[0]; + pPack->pMemSpells2 = pPlayer->_pMemSpells[1]; + + for(i = 0; i < 37; i++) + pPack->pSplLvl[i] = pPlayer->_pSplLvl[i]; + + pki = pPack->InvBody; + pi = pPlayer->InvBody; + + for(i = 0; i < 7; i++) + PackItem(pki++, pi++); + + pki = pPack->InvList; + pi = pPlayer->InvList; + + for(i = 0; i < 40; i++) + PackItem(pki++, pi++); + + for(i = 0; i < 40; i++) + pPack->InvGrid[i] = pPlayer->InvGrid[i]; + + pPack->_pNumInv = pPlayer->_pNumInv; + pki = pPack->SpdList; + pi = pPlayer->SpdList; + + for(i = 0; i < 8; i++) + PackItem(pki++, pi++); + + pPack->pDiabloKillLevel = pPlayer->pDiabloKillLevel; + + if ( gbMaxPlayers == 1 || manashield ) + pPack->pManaShield = pPlayer->pManaShield; + else + pPack->pManaShield = 0; +} + +// Note: last slot of item[MAXITEMS+1] used as temporary buffer +// find real name reference below, possibly [sizeof(item[])/sizeof(ItemStruct)] +static void UnPackItem(PkItemStruct *is, ItemStruct *id) +{ + PkItemStruct *v2; // esi + ItemStruct *v3; // edi + int v5; // ecx + + v2 = is; + v3 = id; + + if ( is->idx == -1 ) + { + id->_itype = -1; + } + else + { + if ( is->idx == IDI_EAR ) + { + RecreateEar( + MAXITEMS, + is->iCreateInfo, + is->iSeed, + is->bId, + (unsigned char)is->bDur, + (unsigned char)is->bMDur, + (unsigned char)is->bCh, + (unsigned char)is->bMCh, + (unsigned short)is->wValue, + is->dwBuff); + } + else + { + v5 = (unsigned short)is->wValue; + _LOWORD(v5) = v2->iCreateInfo; + RecreateItem(MAXITEMS, is->idx, v5, v2->iSeed, (unsigned short)v2->wValue); + item[MAXITEMS]._iMagical = (unsigned char)v2->bId >> 1; + item[MAXITEMS]._iIdentified = v2->bId & 1; + item[MAXITEMS]._iDurability = (unsigned char)v2->bDur; + item[MAXITEMS]._iMaxDur = (unsigned char)v2->bMDur; + item[MAXITEMS]._iCharges = (unsigned char)v2->bCh; + item[MAXITEMS]._iMaxCharges = (unsigned char)v2->bMCh; + } + qmemcpy(v3, &item[MAXITEMS], sizeof(ItemStruct)); + } +} + +void VerifyGoldSeeds(PlayerStruct *pPlayer) +{ + int i; // ebp + int j; // ecx + + for(i = 0; i < pPlayer->_pNumInv; i++) + { + if ( pPlayer->InvList[i].IDidx == IDI_GOLD && pPlayer->_pNumInv > 0 ) + { + for(j = 0; j < pPlayer->_pNumInv; j++) + { + if ( i != j ) + { + if ( pPlayer->InvList[j].IDidx == IDI_GOLD && pPlayer->InvList[i]._iSeed == pPlayer->InvList[j]._iSeed ) + { + pPlayer->InvList[i]._iSeed = GetRndSeed(); + j = -1; + } + } + } + } + } +} + +void UnPackPlayer(PkPlayerStruct *pPack, int pnum, _bool killok) +{ + PlayerStruct *pPlayer; // esi + signed int v6; // eax + int i; // [esp+10h] [ebp-8h] + ItemStruct *pi; // [esp+14h] [ebp-4h] + PkItemStruct *pki; // [esp+20h] [ebp+8h] + + pPlayer = &plr[pnum]; + ClearPlrRVars(&plr[pnum]); + pPlayer->WorldX = (unsigned char)pPack->px; + pPlayer->WorldY = (unsigned char)pPack->py; + pPlayer->_px = (unsigned char)pPack->px; + pPlayer->_py = (unsigned char)pPack->py; + pPlayer->_ptargx = (unsigned char)pPack->targx; + pPlayer->_ptargy = (unsigned char)pPack->targy; + pPlayer->plrlevel = (unsigned char)pPack->plrlevel; + ClrPlrPath(pnum); + pPlayer->destAction = -1; + strcpy(pPlayer->_pName, pPack->pName); + _LOBYTE(pPlayer->_pClass) = pPack->pClass; + InitPlayer(pnum, 1); + pPlayer->_pBaseStr = (unsigned char)pPack->pBaseStr; + pPlayer->_pStrength = (unsigned char)pPack->pBaseStr; + pPlayer->_pBaseMag = (unsigned char)pPack->pBaseMag; + pPlayer->_pMagic = (unsigned char)pPack->pBaseMag; + pPlayer->_pBaseDex = (unsigned char)pPack->pBaseDex; + pPlayer->_pDexterity = (unsigned char)pPack->pBaseDex; + pPlayer->_pBaseVit = (unsigned char)pPack->pBaseVit; + pPlayer->_pVitality = (unsigned char)pPack->pBaseVit; + pPlayer->_pLevel = pPack->pLevel; + pPlayer->_pStatPts = (unsigned char)pPack->pStatPts; + pPlayer->_pExperience = pPack->pExperience; + pPlayer->_pGold = pPack->pGold; + pPlayer->_pMaxHPBase = pPack->pMaxHPBase; + v6 = pPack->pHPBase; + pPlayer->_pHPBase = v6; + if ( !killok ) + { + _LOBYTE(v6) = v6 & 0xC0; + if ( v6 < 64 ) + pPlayer->_pHPBase = 64; + } + pPlayer->_pMaxManaBase = pPack->pMaxManaBase; + pPlayer->_pManaBase = pPack->pManaBase; + pPlayer->_pMemSpells[0] = pPack->pMemSpells; + pPlayer->_pMemSpells[1] = pPack->pMemSpells2; + + for(i = 0; i < 37; i++) + pPlayer->_pSplLvl[i] = pPack->pSplLvl[i]; + + pki = pPack->InvBody; + pi = pPlayer->InvBody; + + for(i = 0; i < 7; i++) + UnPackItem(pki++, pi++); + + pki = pPack->InvList; + pi = pPlayer->InvList; + + for(i = 0; i < 40; i++) + UnPackItem(pki++, pi++); + + for(i = 0; i < 40; i++) + pPlayer->InvGrid[i] = pPack->InvGrid[i]; + + pPlayer->_pNumInv = (unsigned char)pPack->_pNumInv; + VerifyGoldSeeds(pPlayer); + + pki = pPack->SpdList; + pi = pPlayer->SpdList; + + for(i = 0; i < 8; i++) + UnPackItem(pki++, pi++); + + if ( pnum == myplr ) + { + for(i = 0; i < 20; i++) + witchitem[i]._itype = -1; + } + + CalcPlrInv(pnum, 0); + pPlayer->pTownWarps = 0; + pPlayer->pDungMsgs = 0; + pPlayer->pLvlLoad = 0; + pPlayer->pDiabloKillLevel = pPack->pDiabloKillLevel; + pPlayer->pBattleNet = pPack->pBattleNet; + pPlayer->pManaShield = pPack->pManaShield; +} diff --git a/2020_03_31/Source/pack.h b/2020_03_31/Source/pack.h new file mode 100644 index 00000000..f96d6ef9 --- /dev/null +++ b/2020_03_31/Source/pack.h @@ -0,0 +1,9 @@ +//HEADER_GOES_HERE +#ifndef __PACK_H__ +#define __PACK_H__ + +void PackPlayer(PkPlayerStruct *pPack, int pnum, _bool manashield); +void VerifyGoldSeeds(PlayerStruct *pPlayer); +void UnPackPlayer(PkPlayerStruct *pPack, int pnum, _bool killok); + +#endif /* __PACK_H__ */ diff --git a/2020_03_31/Source/palette.cpp b/2020_03_31/Source/palette.cpp new file mode 100644 index 00000000..eed1adc8 --- /dev/null +++ b/2020_03_31/Source/palette.cpp @@ -0,0 +1,312 @@ +#include "diablo.h" +#include "../3rdParty/Storm/Source/storm.h" + +PALETTEENTRY logical_palette[256]; +PALETTEENTRY system_palette[256]; +PALETTEENTRY orig_palette[256]; +int gdwPalEntries; + +const char szKeyGamma[] = "Gamma Correction"; +const char szKeyCycle[] = "Color Cycling"; + +/* data */ + +int gamma_correction = 100; // idb +BOOL color_cycling_enabled = TRUE; // idb +BOOLEAN sgbFadedIn = TRUE; + +static void palette_update() +{ + int first, count; + + if(lpDDPalette == NULL) { + return; + } + + first = 0; + count = 256; + if(!fullscreen) { + first = gdwPalEntries; + count = 256 - 2 * gdwPalEntries; + } + SDrawUpdatePalette(first, count, &system_palette[first], 0); +} + +static void ApplyGamma(PALETTEENTRY *dst, PALETTEENTRY *src, int n) +{ + int i; + double g; + + g = gamma_correction / 100.0; + + for(i = 0; i < n; i++) { + dst->peRed = pow(src->peRed / 256.0, g) * 256.0; + dst->peGreen = pow(src->peGreen / 256.0, g) * 256.0; + dst->peBlue = pow(src->peBlue / 256.0, g) * 256.0; + dst++; + src++; + } +} + +void SaveGamma() +{ + SRegSaveValue("Diablo", szKeyGamma, 0, gamma_correction); + SRegSaveValue("Diablo", szKeyCycle, 0, color_cycling_enabled); +} + +static void LoadGamma() +{ + DWORD val; + + val = gamma_correction; + if(!SRegLoadValue("Diablo", szKeyGamma, 0, &val)) { + val = 100; + } + gamma_correction = val; + + if(gamma_correction < 30) { + gamma_correction = 30; + } else if(gamma_correction > 100) { + gamma_correction = 100; + } + gamma_correction -= gamma_correction % 5; + + if(!SRegLoadValue("Diablo", szKeyCycle, 0, &val)) { + val = TRUE; + } + color_cycling_enabled = val; +} + +static void LoadSysPal() +{ + int i; + HDC hDC; + + for(i = 0; i < 256; i++) { + system_palette[i].peFlags = PC_NOCOLLAPSE | PC_RESERVED; + } + + if(fullscreen) { + return; + } + + hDC = GetDC(NULL); + gdwPalEntries = GetDeviceCaps(hDC, NUMRESERVED) / 2; + GetSystemPaletteEntries(hDC, 0, gdwPalEntries, system_palette); + for(i = 0; i < gdwPalEntries; i++) { + system_palette[i].peFlags = 0; + } + i = 256 - gdwPalEntries; + GetSystemPaletteEntries(hDC, i, gdwPalEntries, &system_palette[i]); + while(i < 256) { + system_palette[i++].peFlags = 0; + } + ReleaseDC(NULL, hDC); +} + +void palette_init() +{ + HRESULT hDDVal; + + LoadGamma(); + memcpy(system_palette, orig_palette, sizeof(orig_palette)); + LoadSysPal(); + + hDDVal = lpDDInterface->CreatePalette(DDPCAPS_ALLOW256 | DDPCAPS_8BIT, system_palette, &lpDDPalette, NULL); + if(hDDVal != DD_OK) { + ErrDlg(IDD_DIALOG8, hDDVal, "C:\\Src\\Diablo\\Source\\PALETTE.CPP", 143); + } + + hDDVal = lpDDSPrimary->SetPalette(lpDDPalette); +#ifndef RGBMODE + if(hDDVal != DD_OK) { + ErrDlg(IDD_DIALOG8, hDDVal, "C:\\Src\\Diablo\\Source\\PALETTE.CPP", 146); + } +#endif +} + +void LoadPalette(const char *pszFileName) +{ + int i; + void *pBuf; + BYTE PalData[256][3]; + + /// ASSERT: assert(pszFileName); + + WOpenFile((char *)pszFileName, &pBuf, 0); + WReadFile(pBuf, (char *)PalData, sizeof(PalData)); + WCloseFile(pBuf); + + for(i = 0; i < 256; i++) { + orig_palette[i].peRed = PalData[i][0]; + orig_palette[i].peGreen = PalData[i][1]; + orig_palette[i].peBlue = PalData[i][2]; + orig_palette[i].peFlags = 0; + } +} + +void LoadRndLvlPal(int l) +{ + char szFileName[MAX_PATH]; + + if(l == DTYPE_TOWN) { + LoadPalette("Levels\\TownData\\Town.pal"); + } else { + sprintf(szFileName, "Levels\\L%iData\\L%i_%i.PAL", l, l, random(0, 4) + 1); + LoadPalette(szFileName); + } +} + +void ResetPal() +{ + if(lpDDSPrimary != NULL) { + if(lpDDSPrimary->IsLost() == DDERR_SURFACELOST) { + if(lpDDSPrimary->Restore() != DD_OK) { + return; + } + } + } + + SDrawRealizePalette(); +} + +void IncreaseGamma() +{ + if(gamma_correction >= 100) { + return; + } + + gamma_correction += 5; + if(gamma_correction > 100) { + gamma_correction = 100; + } + + ApplyGamma(system_palette, logical_palette, 256); + palette_update(); +} + +void DecreaseGamma() +{ + if(gamma_correction <= 30) { + return; + } + + gamma_correction -= 5; + if(gamma_correction < 30) { + gamma_correction = 30; + } + + ApplyGamma(system_palette, logical_palette, 256); + palette_update(); +} + +int UpdateGamma(int gamma) +{ + if(gamma != 0) { + gamma_correction = 100 - gamma + 30; + ApplyGamma(system_palette, logical_palette, 256); + palette_update(); + } + + return 100 - gamma_correction + 30; +} + +static void SetFadeLevel(int fadeval) +{ + int i, nval; + + if(lpDDInterface == NULL) { + return; + } + + for(i = 0; i < 255; i++) { + nval = fadeval * logical_palette[i].peRed; + system_palette[i].peRed = (DWORD)nval >> 8; + nval = fadeval * logical_palette[i].peGreen; + system_palette[i].peGreen = (DWORD)nval >> 8; + nval = fadeval * logical_palette[i].peBlue; + system_palette[i].peBlue = (DWORD)nval >> 8; + } + + Sleep(3); + lpDDInterface->WaitForVerticalBlank(DDWAITVB_BLOCKBEGIN, NULL); + palette_update(); +} + +void BlackPalette() +{ + SetFadeLevel(0); +} + +void PaletteFadeIn(int fr) +{ + int i; + + ApplyGamma(logical_palette, orig_palette, 256); + + for(i = 0; i < 256; i += fr) { + SetFadeLevel(i); + } + + SetFadeLevel(256); + memcpy(logical_palette, orig_palette, sizeof(orig_palette)); + sgbFadedIn = TRUE; +} + +void PaletteFadeOut(int fr) +{ + int i; + + if(!sgbFadedIn) { + return; + } + + for(i = 256; i > 0; i -= fr) { + SetFadeLevel(i); + } + + SetFadeLevel(0); + sgbFadedIn = FALSE; +} + +void palette_update_caves() +{ + int i; + PALETTEENTRY col; + + col = system_palette[1]; + for(i = 1; i < 31; i++) { + system_palette[i].peRed = system_palette[i + 1].peRed; + system_palette[i].peGreen = system_palette[i + 1].peGreen; + system_palette[i].peBlue = system_palette[i + 1].peBlue; + } + system_palette[i].peRed = col.peRed; + system_palette[i].peGreen = col.peGreen; + system_palette[i].peBlue = col.peBlue; + + palette_update(); +} + +void Lava2Water(int n) +{ + int i; + + for(i = 32 - n; i >= 0; i--) { + logical_palette[i] = orig_palette[i]; + } + + ApplyGamma(system_palette, logical_palette, 32); + palette_update(); +} + +BOOL palette_get_colour_cycling() +{ + return color_cycling_enabled; +} + +BOOL palette_set_color_cycling(BOOL bEnable) +{ + color_cycling_enabled = bEnable; + + return color_cycling_enabled; +} diff --git a/2020_03_31/Source/palette.h b/2020_03_31/Source/palette.h new file mode 100644 index 00000000..d7cbe9b2 --- /dev/null +++ b/2020_03_31/Source/palette.h @@ -0,0 +1,32 @@ +//HEADER_GOES_HERE +#ifndef __PALETTE_H__ +#define __PALETTE_H__ + +extern PALETTEENTRY logical_palette[256]; +extern PALETTEENTRY system_palette[256]; +extern PALETTEENTRY orig_palette[256]; +extern int gdwPalEntries; + +void SaveGamma(); +void palette_init(); +void LoadPalette(const char *pszFileName); +void LoadRndLvlPal(int l); +void ResetPal(); +void IncreaseGamma(); +void DecreaseGamma(); +int UpdateGamma(int gamma); +void BlackPalette(); +void PaletteFadeIn(int fr); +void PaletteFadeOut(int fr); +void palette_update_caves(); +void Lava2Water(int n); +BOOL palette_get_colour_cycling(); +BOOL palette_set_color_cycling(BOOL bEnable); + +/* data */ + +extern int gamma_correction; // idb +extern BOOL color_cycling_enabled; // idb +extern BOOLEAN sgbFadedIn; + +#endif /* __PALETTE_H__ */ diff --git a/2020_03_31/Source/path.cpp b/2020_03_31/Source/path.cpp new file mode 100644 index 00000000..5769b2f3 --- /dev/null +++ b/2020_03_31/Source/path.cpp @@ -0,0 +1,359 @@ +#include "diablo.h" + +// preallocated nodes, search is terminated after 300 nodes are visited +PATHNODE path_nodes[300]; +// size of the pnode_tblptr stack +int gdwCurPathStep; +// the number of in-use nodes in path_nodes +int gdwCurNodes; +/* for reconstructing the path after the A* search is done. The longest + * possible path is actually 24 steps, even though we can fit 25 + */ +int pnode_vals[25]; +// a linked list of all visited nodes +PATHNODE *pnode_ptr; +// a stack for recursively searching nodes +PATHNODE *pnode_tblptr[300]; +// a linked list of the A* frontier, sorted by distance +PATHNODE *path_2_nodes; +PATHNODE path_unusednodes[300]; + +// for iterating over the 8 possible movement directions +const char pathxdir[8] = { -1, -1, 1, 1, -1, 0, 1, 0 }; +const char pathydir[8] = { -1, 1, -1, 1, 0, -1, 0, 1 }; + +/* data */ + +/* each step direction is assigned a number like this: + * dx + * -1 0 1 + * +----- + * -1|5 1 6 + * dy 0|2 0 3 + * 1|8 4 7 + */ +char path_directions[9] = { 5, 1, 6, 2, 0, 3, 8, 4, 7 }; + +/* find the shortest path from (sx,sy) to (dx,dy), using PosOk(PosOkArg,x,y) to + * check that each step is a valid position. Store the step directions (see + * path_directions) in path, which must have room for 24 steps + */ +int FindPath(BOOL (*PosOk)(int, int, int), int PosOkArg, int sx, int sy, int dx, int dy, char *path) +{ + int i, steps; + PATHNODE *pNext, *pPath; + + gdwCurNodes = 0; + path_2_nodes = path_new_step(); + pnode_ptr = path_new_step(); + gdwCurPathStep = 0; + + pNext = path_new_step(); + pNext->g = 0; + pNext->h = path_get_h_cost(sx, sy, dx, dy); + pNext->f = pNext->h + pNext->g; + pNext->x = sx; + pNext->y = sy; + path_2_nodes->NextNode = pNext; + + while(pPath = GetNextPath()) { + if(pPath->x == dx && pPath->y == dy) { + pNext = pPath; + steps = 0; + while(pNext->Parent != NULL && steps < 25) { + pnode_vals[steps] = path_directions[3 * (pNext->y - pNext->Parent->y) + 3 - pNext->Parent->x + 1 + pNext->x]; + steps++; + pNext = pNext->Parent; + } + if(steps == 25) { + return 0; + } + for(i = 0; i < steps; i++) { + path[i] = pnode_vals[steps - i - 1]; + } + return i; + } + if(!path_get_path(PosOk, PosOkArg, pPath, dx, dy)) { + return 0; + } + } + + return 0; +} + +/* heuristic, estimated cost from (sx,sy) to (dx,dy) */ +int path_get_h_cost(int x1, int y1, int x2, int y2) +{ + int dx, dy, minc, maxc; + + dx = abs(x1 - x2); + dy = abs(y1 - y2); + + minc = dx < dy ? dx : dy; + maxc = dx > dy ? dx : dy; + + return 2 * (minc + maxc); +} + +/* return 2 if pPath is horizontally/vertically aligned with (dx,dy), else 3 + * + * This approximates that diagonal movement on a square grid should have a cost + * of sqrt(2). That's approximately 1.5, so they multiply all step costs by 2, + * except diagonal steps which are times 3 + */ +int path_check_equal(PATHNODE *pPath, int dx, int dy) +{ + if(pPath->x == dx || pPath->y == dy) { + return 2; + } + + return 3; +} + +/* get the next node on the A* frontier to explore (estimated to be closest to + * the goal), mark it as visited, and return it + */ +PATHNODE *GetNextPath() +{ + PATHNODE *pNext; + + if(path_2_nodes->NextNode == NULL) { + return NULL; + } + + pNext = path_2_nodes->NextNode; + path_2_nodes->NextNode = pNext->NextNode; + pNext->NextNode = pnode_ptr->NextNode; + pnode_ptr->NextNode = pNext; + return pNext; +} + +/* check if stepping from pPath to (dx,dy) cuts a corner. If you step from A to + * B, both Xs need to be clear: + * + * AX + * XB + * + * return true if step is allowed + */ +BOOL path_solid_pieces(PATHNODE *pPath, int dx, int dy) +{ + BOOL rv; + + rv = TRUE; + + switch(path_directions[3 * (dy - pPath->y) + 3 - pPath->x + 1 + dx]) { + case 5: + rv = !nSolidTable[dPiece[dx][dy + 1]] && !nSolidTable[dPiece[dx + 1][dy]]; + break; + case 6: + rv = !nSolidTable[dPiece[dx][dy + 1]] && !nSolidTable[dPiece[dx - 1][dy]]; + break; + case 7: + rv = !nSolidTable[dPiece[dx][dy - 1]] && !nSolidTable[dPiece[dx - 1][dy]]; + break; + case 8: + rv = !nSolidTable[dPiece[dx + 1][dy]] && !nSolidTable[dPiece[dx][dy - 1]]; + break; + } + + return rv; +} + +/* perform a single step of A* bread-first search by trying to step in every + * possible direction from pPath with goal (x,y). Check each step with PosOk + * + * return 0 if we ran out of preallocated nodes to use, else 1 + */ +BOOL path_get_path(BOOL (*PosOk)(int, int, int), int PosOkArg, PATHNODE *pPath, int x, int y) +{ + int i, dx, dy; + BOOL ok; + + for(i = 0; i < 8; i++) { + dx = pPath->x + pathxdir[i]; + dy = pPath->y + pathydir[i]; + ok = PosOk(PosOkArg, dx, dy); + if(ok && path_solid_pieces(pPath, dx, dy) || !ok && dx == x && dy == y) { + if(!path_parent_path(pPath, dx, dy, x, y)) { + return FALSE; + } + } + } + + return TRUE; +} + +/* add a step from pPath to (dx,dy), return 1 if successful, and update the + * frontier/visited nodes accordingly + * + * return 1 if step successfully added, 0 if we ran out of nodes to use + */ +BOOL path_parent_path(PATHNODE *pPath, int dx, int dy, int sx, int sy) +{ + int i, steps; + PATHNODE *pNext, *pNew; + + steps = pPath->g + path_check_equal(pPath, dx, dy); + + if(pNext = path_get_node1(dx, dy)) { + for(i = 0; i < 8; i++) { + if(pPath->Child[i] == NULL) { + break; + } + } + pPath->Child[i] = pNext; + if(steps < pNext->g && path_solid_pieces(pPath, dx, dy)) { + pNext->Parent = pPath; + pNext->g = steps; + pNext->f = steps + pNext->h; + } + } else if(pNext = path_get_node2(dx, dy)) { + for(i = 0; i < 8; i++) { + if(pPath->Child[i] == NULL) { + break; + } + } + pPath->Child[i] = pNext; + if(steps < pNext->g && path_solid_pieces(pPath, dx, dy)) { + pNext->Parent = pPath; + pNext->g = steps; + pNext->f = steps + pNext->h; + path_set_coords(pNext); + } + } else { + pNew = path_new_step(); + if(pNew == NULL) { + return FALSE; + } + pNew->Parent = pPath; + pNew->g = steps; + pNew->h = path_get_h_cost(dx, dy, sx, sy); + pNew->f = steps + pNew->h; + pNew->x = dx; + pNew->y = dy; + path_next_node(pNew); + for(i = 0; i < 8; i++) { + if(pPath->Child[i] == NULL) { + break; + } + } + pPath->Child[i] = pNew; + } + + return TRUE; +} + +/* return a node for (dx,dy) on the frontier, or NULL if not found */ +PATHNODE *path_get_node1(int dx, int dy) +{ + PATHNODE *pPath; + + pPath = path_2_nodes->NextNode; + while(pPath != NULL) { + if(pPath->x == dx && pPath->y == dy) { + return pPath; + } + pPath = pPath->NextNode; + } + + return NULL; +} + +/* return a node for (dx,dy) if it was visited, or NULL if not found */ +PATHNODE *path_get_node2(int dx, int dy) +{ + PATHNODE *pPath; + + pPath = pnode_ptr->NextNode; + while(pPath != NULL) { + if(pPath->x == dx && pPath->y == dy) { + return pPath; + } + pPath = pPath->NextNode; + } + + return NULL; +} + +/* insert pPath into the frontier (keeping the frontier sorted by total + * distance) */ +void path_next_node(PATHNODE *pPath) +{ + int f; + PATHNODE *pOld, *pNext; + + if(path_2_nodes->NextNode == NULL) { + path_2_nodes->NextNode = pPath; + return; + } + + f = pPath->f; + pOld = path_2_nodes; + pNext = path_2_nodes->NextNode; + + while(pNext != NULL && pNext->f < f) { + pOld = pNext; + pNext = pNext->NextNode; + } + + pPath->NextNode = pNext; + pOld->NextNode = pPath; +} + +/* update all path costs using depth-first search starting at pPath */ +void path_set_coords(PATHNODE *pPath) +{ + int i; + PATHNODE *pOld, *pCur; + + path_push_active_step(pPath); + + while(gdwCurPathStep != 0) { + pOld = path_pop_active_step(); + for(i = 0; i < 8; i++) { + pCur = pOld->Child[i]; + if(pCur == NULL) { + break; + } + if(pOld->g + path_check_equal(pOld, pCur->x, pCur->y) < pCur->g) { + if(path_solid_pieces(pOld, pCur->x, pCur->y)) { + pCur->Parent = pOld; + pCur->g = pOld->g + path_check_equal(pOld, pCur->x, pCur->y); + pCur->f = pCur->h + pCur->g; + path_push_active_step(pCur); + } + } + } + } +} + +/* push pPath onto the pnode_tblptr stack */ +void path_push_active_step(PATHNODE *pPath) +{ + pnode_tblptr[gdwCurPathStep] = pPath; + gdwCurPathStep++; +} + +/* pop and return a node from the pnode_tblptr stack */ +PATHNODE *path_pop_active_step() +{ + gdwCurPathStep--; + return pnode_tblptr[gdwCurPathStep]; +} + +/* zero one of the preallocated nodes and return a pointer to it, or NULL if + * none are available */ +PATHNODE *path_new_step() +{ + PATHNODE *pPath; + + if(gdwCurNodes == 300) { + return NULL; + } + + pPath = &path_nodes[gdwCurNodes]; + gdwCurNodes++; + memset(pPath, 0, sizeof(*pPath)); + return pPath; +} diff --git a/2020_03_31/Source/path.h b/2020_03_31/Source/path.h new file mode 100644 index 00000000..6e40268e --- /dev/null +++ b/2020_03_31/Source/path.h @@ -0,0 +1,37 @@ +//HEADER_GOES_HERE +#ifndef __PATH_H__ +#define __PATH_H__ + +extern PATHNODE path_nodes[300]; +extern int gdwCurPathStep; +extern int gdwCurNodes; +extern int pnode_vals[25]; +extern PATHNODE *pnode_ptr; +extern PATHNODE *pnode_tblptr[300]; +extern PATHNODE *path_2_nodes; +extern PATHNODE path_unusednodes[300]; + +int FindPath(BOOL (*PosOk)(int, int, int), int PosOkArg, int sx, int sy, int dx, int dy, char *path); +int path_get_h_cost(int x1, int y1, int x2, int y2); +int path_check_equal(PATHNODE *pPath, int dx, int dy); +PATHNODE *GetNextPath(); +BOOL path_solid_pieces(PATHNODE *pPath, int dx, int dy); +BOOL path_get_path(BOOL (*PosOk)(int, int, int), int PosOkArg, PATHNODE *pPath, int x, int y); +BOOL path_parent_path(PATHNODE *pPath, int dx, int dy, int sx, int sy); +PATHNODE *path_get_node1(int dx, int dy); +PATHNODE *path_get_node2(int dx, int dy); +void path_next_node(PATHNODE *pPath); +void path_set_coords(PATHNODE *pPath); +void path_push_active_step(PATHNODE *pPath); +PATHNODE *path_pop_active_step(); +PATHNODE *path_new_step(); + +/* rdata */ + +extern const char pathxdir[8]; +extern const char pathydir[8]; + +/* data */ +extern char path_directions[9]; + +#endif /* __PATH_H__ */ diff --git a/2020_03_31/Source/pfile.cpp b/2020_03_31/Source/pfile.cpp new file mode 100644 index 00000000..16cf2f1d --- /dev/null +++ b/2020_03_31/Source/pfile.cpp @@ -0,0 +1,885 @@ +#include "diablo.h" +#include "../3rdParty/Storm/Source/storm.h" +#include "../DiabloUI/diabloui.h" + +char hero_names[MAX_CHARACTERS][PLR_NAME_LEN]; +BOOL gbValidSaveFile; // idb +int save_prev_tc; // weak + +void pfile_init_save_directory() +{ + char Buffer[260]; // [esp+4h] [ebp-104h] + + if ( GetWindowsDirectory(Buffer, 0x104u) + && (pfile_check_available_space(Buffer), GetModuleFileName(ghInst, Buffer, 0x104u)) ) + { + pfile_check_available_space(Buffer); + } + else + { + app_fatal("Unable to initialize save directory"); + } +} + +void pfile_check_available_space(char *pszDir) +{ + char *v1; // edi + char *v2; // eax + char v3; // cl + BOOL v4; // esi + DWORD TotalNumberOfClusters; // [esp+8h] [ebp-10h] + DWORD NumberOfFreeClusters; // [esp+Ch] [ebp-Ch] + DWORD BytesPerSector; // [esp+10h] [ebp-8h] + DWORD SectorsPerCluster; // [esp+14h] [ebp-4h] + + v1 = pszDir; + v2 = pszDir; + while ( 1 ) + { + v3 = *v2; + if ( !*v2 ) + break; + ++v2; + if ( v3 == '\\' ) + { + *v2 = '\0'; + break; + } + } + v4 = GetDiskFreeSpace(v1, &SectorsPerCluster, &BytesPerSector, &NumberOfFreeClusters, &TotalNumberOfClusters); + if ( !v4 ) + goto LABEL_12; + if ( (signed __int64)(BytesPerSector * (unsigned __int64)SectorsPerCluster * NumberOfFreeClusters) < 0xA00000 ) + v4 = 0; + if ( !v4 ) +LABEL_12: + DiskFreeDlg(v1); +} + +void pfile_write_hero() +{ + int v0; // eax + int v1; // esi + //int v2; // eax + PkPlayerStruct pkplr; // [esp+4h] [ebp-4F4h] + + v0 = pfile_get_save_num_from_name(plr[myplr]._pName); + v1 = v0; + //_LOBYTE(v2) = pfile_open_archive(1, v0); + if ( pfile_open_archive(1, v0) ) + { + PackPlayer(&pkplr, myplr, gbMaxPlayers == 1); + pfile_encode_hero(&pkplr); + pfile_flush(gbMaxPlayers == 1, v1); + } +} + +int pfile_get_save_num_from_name(char *name) +{ + char *v1; // ebx + unsigned int v2; // esi + + v1 = name; + v2 = 0; + do + { + if ( !_strcmpi(hero_names[v2], v1) ) + break; + ++v2; + } + while ( v2 < MAX_CHARACTERS ); + return v2; +} + +void pfile_encode_hero(PkPlayerStruct *pPack) +{ + int v1; // ebx + void *v2; // edi + char password[16]; // [esp+Ch] [ebp-14h] + void *v4; // [esp+1Ch] [ebp-4h] + + strcpy(password, "xrgyrkj1"); + *(_DWORD *)&password[9] = 0; + *(_WORD *)&password[13] = 0; + v4 = pPack; + password[15] = 0; + if ( (unsigned char)gbMaxPlayers > 1u ) + strcpy(password, "szqnlsk1"); + v1 = codec_get_encoded_len(1266); + v2 = DiabloAllocPtr(v1); + memcpy(v2, v4, 0x4F2u); + codec_encode((BYTE *)v2, 1266, v1, password); + mpqapi_write_file("hero", (char *)v2, v1); + mem_free_dbg(v2); +} + +_bool pfile_open_archive(_bool a1, int save_num) +{ + int v2; // esi + BOOL v3; // edi + //int v4; // eax + char FileName[260]; // [esp+8h] [ebp-104h] + + v2 = save_num; + v3 = a1; + pfile_get_save_path(FileName, 260, save_num); + //_LOBYTE(v4) = mpqapi_open_archive(FileName, 0, v2); + if ( mpqapi_open_archive(FileName, 0, v2) ) + return 1; + if ( v3 ) + { + if ( (unsigned char)gbMaxPlayers > 1u ) + mpqapi_store_default_time(v2); + } + return 0; +} + +void pfile_get_save_path(char *pszBuf, int dwBufSize, int save_num) +{ + char *v3; // esi + const char *v4; // ebx + DWORD v5; // edi + char *v6; // eax + char v7[260]; // [esp+8h] [ebp-104h] + + v3 = pszBuf; + v4 = "\\multi_%d.sv"; + if ( (unsigned char)gbMaxPlayers <= 1u ) + v4 = "\\single_%d.sv"; + v5 = GetModuleFileName(ghInst, pszBuf, 0x104u); + v6 = strrchr(v3, '\\'); + if ( v6 ) + *v6 = 0; + if ( !v5 ) + app_fatal("Unable to get save directory"); + sprintf(v7, v4, save_num); + strcat(v3, v7); + _strlwr(v3); +} + +void pfile_flush(_bool is_single_player, int save_num) +{ + int v2; // esi + _bool v3; // di + char FileName[260]; // [esp+8h] [ebp-104h] + + v2 = save_num; + v3 = is_single_player; + pfile_get_save_path(FileName, 260, save_num); + mpqapi_flush_and_close(FileName, v3, v2); +} + +_bool pfile_create_player_description(char *dst, int len) +{ + int v2; // edi + char *v3; // ebx + int v4; // eax + char src[128]; // [esp+Ch] [ebp-ACh] + _uiheroinfo hero_info; // [esp+8Ch] [ebp-2Ch] + + myplr = 0; + v2 = len; + v3 = dst; + pfile_read_player_from_save(); + game_2_ui_player(plr, &hero_info, gbValidSaveFile); + UiSetupPlayerInfo(gszHero, &hero_info, 'DRTL'); + if ( !v3 || !v2 ) + goto LABEL_5; + v4 = UiCreatePlayerDescription(&hero_info, 'DRTL', src); + if ( v4 ) + { + SStrCopy(v3, src, v2); +LABEL_5: + v4 = 1; + } + return v4; +} + +int pfile_create_save_file(char *name_1, char *name_2) +{ + char *v2; // edi + char *v3; // ebp + int v4; // esi + int v5; // eax + char *v7; // [esp+20h] [ebp-30h] + _uiheroinfo heroinfo; // [esp+24h] [ebp-2Ch] + + v2 = name_2; + v3 = name_1; + if ( pfile_get_save_num_from_name(name_2) != MAX_CHARACTERS ) + return 0; + v4 = 0; + v7 = plr[0]._pName; + while ( _strcmpi(v3, v7) ) + { + v7 += 21720; + ++v4; + if ( v7 == plr[4]._pName ) + return 0; + } + v5 = pfile_get_save_num_from_name(v3); + if ( v5 == MAX_CHARACTERS ) + return 0; + SStrCopy(hero_names[v5], v2, 32); + SStrCopy(plr[v4]._pName, v2, 32); + if ( !_strcmpi(gszHero, v3) ) + SStrCopy(gszHero, v2, 16); + game_2_ui_player(plr, &heroinfo, gbValidSaveFile); + UiSetupPlayerInfo(gszHero, &heroinfo, 'DRTL'); + pfile_write_hero(); + return 1; +} + +void pfile_flush_W() +{ + int v0; // eax + + v0 = pfile_get_save_num_from_name(plr[myplr]._pName); + pfile_flush(1, v0); +} + +void game_2_ui_player(PlayerStruct *p, _uiheroinfo *heroinfo, BOOL bHasSaveFile) +{ + _uiheroinfo *v3; // esi + PlayerStruct *v4; // edi + char v5; // al + + v3 = heroinfo; + v4 = p; + memset(heroinfo, 0, 0x2Cu); + strncpy(v3->name, v4->_pName, 0xFu); + v3->name[15] = 0; + v3->level = v4->_pLevel; + v3->heroclass = game_2_ui_class(v4); + v3->strength = v4->_pStrength; + v3->magic = v4->_pMagic; + v3->dexterity = v4->_pDexterity; + v3->vitality = v4->_pVitality; + v3->gold = v4->_pGold; + v3->hassaved = bHasSaveFile; + v5 = v4->pDiabloKillLevel; + v3->spawned = 0; + v3->herorank = v5; +} + +char game_2_ui_class(PlayerStruct *p) +{ + char result; // al + + result = p->_pClass; + if ( result ) + result = (result != 1) + 1; + return result; +} + +BOOL __stdcall pfile_ui_set_hero_infos(BOOL (__stdcall *ui_add_hero_info)(_uiheroinfo *)) +{ + char *v1; // esi + //int v2; // eax + int v3; // eax + DWORD v4; // eax + unsigned int v5; // esi + void *v7; // eax + void *v8; // edi + //int v9; // eax + _bool v10; // al + PkPlayerStruct pkplr; // [esp+Ch] [ebp-7BCh] + struct _OFSTRUCT ReOpenBuff; // [esp+500h] [ebp-2C8h] + char FileName[260]; // [esp+588h] [ebp-240h] + char NewFileName[260]; // [esp+68Ch] [ebp-13Ch] + _uiheroinfo hero_info; // [esp+790h] [ebp-38h] + int unused; // [esp+7BCh] [ebp-Ch] + LPCSTR lpSrcStr; // [esp+7C0h] [ebp-8h] + int save_num; // [esp+7C4h] [ebp-4h] + + memset(hero_names, 0, 0x140u); + if ( (unsigned char)gbMaxPlayers > 1u ) + { + lpSrcStr = 0; + save_num = 0; + do + { + if ( (unsigned int)save_num >= MAX_CHARACTERS ) + break; + GetSaveDirectory(FileName, 260, (int)lpSrcStr); + v1 = strrchr(FileName, '\\') + 1; + if ( v1 != (char *)1 && OpenFile(FileName, &ReOpenBuff, 0x4000u) != -1 ) + { + if ( !SRegLoadString("Diablo\\Converted", (const char *)v1, 0, NewFileName, 260) ) + { + while ( 1 ) + { + v3 = save_num++; + pfile_get_save_path(NewFileName, 260, v3); + if ( OpenFile(NewFileName, &ReOpenBuff, 0x4000u) == -1 ) + break; + if ( (unsigned int)save_num >= MAX_CHARACTERS ) + goto LABEL_13; + } + if ( CopyFile(FileName, NewFileName, 1) ) + { + SRegSaveString("Diablo\\Converted", v1, 0, NewFileName); + v4 = GetFileAttributes(NewFileName); + if ( v4 != -1 ) + { + _LOBYTE(v4) = v4 & 0xF9; + SetFileAttributes(NewFileName, v4); + } + } + } + } +LABEL_13: + ++lpSrcStr; + } + while ( (unsigned int)lpSrcStr < MAX_CHARACTERS ); + } + unused = 1; + v5 = 0; + do + { + v7 = pfile_open_save_archive(&unused, v5); + v8 = v7; + if ( v7 ) + { + if ( pfile_read_hero(v7, &pkplr) ) + { + strcpy(hero_names[v5], pkplr.pName); + UnPackPlayer(&pkplr, 0, 0); + v10 = pfile_archive_contains_game(v8); + game_2_ui_player(plr, &hero_info, v10); + ui_add_hero_info(&hero_info); + } + pfile_SFileCloseArchive(v8); + } + ++v5; + } + while ( v5 < MAX_CHARACTERS ); + return 1; +} + +char *GetSaveDirectory(char *dst, int dst_size, int save_num) +{ + char *v3; // esi + const char *v4; // ebx + DWORD v5; // edi + char *v6; // eax + char path_buf[260]; // [esp+Ch] [ebp-104h] + + v3 = dst; + if ( (unsigned char)gbMaxPlayers <= 1u ) + { + v4 = "\\single_%d.sv"; + v5 = GetModuleFileName(ghInst, dst, 0x104u); + v6 = strrchr(v3, '\\'); + if ( v6 ) + *v6 = '\0'; + } + else + { + v4 = "\\dlinfo_%d.drv"; + v5 = GetWindowsDirectory(dst, 0x104u); + } + if ( !v5 ) + app_fatal("Unable to get save directory"); + sprintf(path_buf, v4, save_num); + strcat(v3, path_buf); + return _strlwr(v3); +} + +_bool pfile_read_hero(void *archive, PkPlayerStruct *pPack) +{ + BOOL v2; // eax + int dwSize; // eax + int v4; // edi + char *v5; // eax + char *v6; // esi + //int v7; // eax + //int v8; // eax + char password[16]; // [esp+4h] [ebp-24h] + void *v11; // [esp+14h] [ebp-14h] + DWORD nSize; // [esp+18h] [ebp-10h] + int v13; // [esp+1Ch] [ebp-Ch] + int dwBytes; // [esp+20h] [ebp-8h] + void *file; // [esp+24h] [ebp-4h] + + v11 = pPack; + v2 = SFileOpenFileEx(archive, "hero", 0, &file); + if ( v2 ) + { + strcpy(password, "xrgyrkj1"); + v13 = 0; + *(_DWORD *)&password[9] = 0; + *(_WORD *)&password[13] = 0; + password[15] = 0; + nSize = 16; + if ( (unsigned char)gbMaxPlayers > 1u ) + strcpy(password, "szqnlsk1"); + dwSize = SFileGetFileSize((int *)file, 0); + v4 = dwSize; + if ( !dwSize ) + goto LABEL_15; + v5 = (char *)DiabloAllocPtr(dwSize); + v6 = v5; + //_LOBYTE(v7) = SFileReadFile(file, v5, v4, (unsigned long *)&dwBytes, 0); + if ( SFileReadFile(file, v5, v4, (unsigned long *)&dwBytes, 0) ) + { + dwBytes = codec_decode((BYTE *)v6, v4, password); + if ( dwBytes ) + goto LABEL_11; + if ( (unsigned char)gbMaxPlayers > 1u ) + { + GetComputerName(password, &nSize); + if ( !SFileSetFilePointer(file, 0, 0, 0) ) + { + //_LOBYTE(v8) = SFileReadFile(file, v6, v4, (unsigned long *)&dwBytes, 0); + if ( SFileReadFile(file, v6, v4, (unsigned long *)&dwBytes, 0) ) + { + dwBytes = codec_decode((BYTE *)v6, v4, password); +LABEL_11: + if ( dwBytes == 1266 ) + { + memcpy(v11, v6, 0x4F2u); + v13 = 1; + } + goto LABEL_13; + } + } + } + } +LABEL_13: + if ( v6 ) + mem_free_dbg(v6); +LABEL_15: + SFileCloseFile(file); + v2 = v13; + } + return v2; +} + +void *pfile_open_save_archive(int *unused, int save_num) +{ + //int v2; // eax + char SrcStr[260]; // [esp+0h] [ebp-108h] + void *archive; // [esp+104h] [ebp-4h] + + pfile_get_save_path(SrcStr, 260, save_num); + //_LOBYTE(v2) = SFileOpenArchive(SrcStr, 0x7000, 0, &archive); + return SFileOpenArchive(SrcStr, 0x7000, 0, &archive) != 0 ? archive : NULL; +} + +void pfile_SFileCloseArchive(void *hsArchive) +{ + SFileCloseArchive(hsArchive); +} + +BOOL pfile_archive_contains_game(void *hsArchive) +{ + //int v1; // eax + void *file; // [esp+0h] [ebp-4h] + + file = hsArchive; + if ( gbMaxPlayers != 1 ) + return FALSE; + //_LOBYTE(v1) = SFileOpenFileEx(hsArchive, "game", 0, &file); + if ( !SFileOpenFileEx(hsArchive, "game", 0, &file) ) + return FALSE; + SFileCloseFile(file); + return TRUE; +} + +BOOL __stdcall pfile_ui_set_class_stats(int player_class_nr, _uidefaultstats *class_stats) +{ + int v2; // eax + + v2 = (char)pfile_get_player_class(player_class_nr); + class_stats->strength = StrengthTbl[v2]; + class_stats->magic = MagicTbl[v2]; + class_stats->dexterity = DexterityTbl[v2]; + class_stats->vitality = VitalityTbl[v2]; + return 1; +} + +int pfile_get_player_class(int player_class_nr) +{ + int result; // eax + + if ( player_class_nr ) + _LOBYTE(result) = (player_class_nr != 1) + 1; + else + _LOBYTE(result) = 0; + return result; +} + +BOOL __stdcall pfile_ui_save_create(_uiheroinfo *heroinfo) +{ + unsigned int v1; // edi + //int v3; // eax + char v5; // al + PkPlayerStruct pkplr; // [esp+8h] [ebp-4F4h] + + v1 = pfile_get_save_num_from_name(heroinfo->name); + if ( v1 == MAX_CHARACTERS ) + { + v1 = 0; + do + { + if ( !*hero_names[v1] ) + break; + ++v1; + } + while ( v1 < MAX_CHARACTERS ); + if ( v1 == MAX_CHARACTERS ) + return 0; + } + //_LOBYTE(v3) = pfile_open_archive(0, v1); + if ( !pfile_open_archive(0, v1) ) + return 0; + mpqapi_remove_hash_entries(pfile_get_file_name); + strncpy(hero_names[v1], heroinfo->name, 0x20u); + hero_names[v1][31] = 0; + v5 = pfile_get_player_class((unsigned char)heroinfo->heroclass); + CreatePlayer(0, v5); + strncpy(plr[0]._pName, heroinfo->name, 0x20u); + plr[0]._pName[31] = 0; + PackPlayer(&pkplr, 0, 1); + pfile_encode_hero(&pkplr); + game_2_ui_player(plr, heroinfo, 0); + pfile_flush(1, v1); + return 1; +} + +_bool __stdcall pfile_get_file_name(int lvl, char *dst) +{ + int v2; // ecx + _bool v3; // zf + const char *v4; // eax + + v2 = lvl; + if ( (unsigned char)gbMaxPlayers > 1u ) + { + v3 = lvl == 0; + goto LABEL_10; + } + if ( (unsigned int)lvl < 0x11 ) + { + v4 = "perml%02d"; +LABEL_12: + sprintf(dst, v4, v2); + return 1; + } + if ( (unsigned int)lvl < 0x22 ) + { + v2 = lvl - 17; + v4 = "perms%02d"; + goto LABEL_12; + } + if ( lvl == 34 ) + { + v4 = "game"; + goto LABEL_12; + } + v3 = lvl == 35; +LABEL_10: + if ( v3 ) + { + v4 = "hero"; + goto LABEL_12; + } + return 0; +} + +BOOL __stdcall pfile_delete_save(_uiheroinfo *hero_info) +{ + unsigned int v1; // eax + char FileName[260]; // [esp+0h] [ebp-104h] + + v1 = pfile_get_save_num_from_name(hero_info->name); + if ( v1 < MAX_CHARACTERS ) + { + hero_names[v1][0] = 0; + pfile_get_save_path(FileName, 260, v1); + DeleteFile(FileName); + } + return 1; +} + +void pfile_read_player_from_save() +{ + int dwChar; // edi + void *v1; // esi + //int v2; // eax + PkPlayerStruct pkplr; // [esp+8h] [ebp-4F4h] + + dwChar = pfile_get_save_num_from_name(gszHero); + v1 = pfile_open_save_archive(0, dwChar); + if ( !v1 ) + app_fatal("Unable to open archive"); + //_LOBYTE(v2) = pfile_read_hero(v1, &pkplr); + if ( !pfile_read_hero(v1, &pkplr) ) + app_fatal("Unable to load character"); + UnPackPlayer(&pkplr, myplr, 0); + gbValidSaveFile = pfile_archive_contains_game(v1); + pfile_SFileCloseArchive(v1); +} + +void GetTempLevelNames(char *szTemp) +{ + char *v1; // esi + + v1 = szTemp; + pfile_get_save_num_from_name(plr[myplr]._pName); + if ( setlevel ) + sprintf(v1, "temps%02d", (unsigned char)setlvlnum); + else + sprintf(v1, "templ%02d", currlevel); +} + +void GetPermLevelNames(char *szPerm) +{ + char *v1; // esi + int v2; // ebx + //int v3; // eax + //int v4; // eax + int v5; // edi + + v1 = szPerm; + v2 = pfile_get_save_num_from_name(plr[myplr]._pName); + GetTempLevelNames(v1); + //_LOBYTE(v3) = pfile_open_archive(0, v2); + if ( !pfile_open_archive(0, v2) ) + app_fatal("Unable to read to save file archive"); + //_LOBYTE(v4) = mpqapi_has_file(v1); + v5 = mpqapi_has_file(v1); + pfile_flush(1, v2); + if ( !v5 ) + { + if ( setlevel ) + sprintf(v1, "perms%02d", (unsigned char)setlvlnum); + else + sprintf(v1, "perml%02d", currlevel); + } +} + +void pfile_get_game_name(char *dst) +{ + char *v1; // esi + + v1 = dst; + pfile_get_save_num_from_name(plr[myplr]._pName); + strcpy(v1, "game"); +} + +void pfile_remove_temp_files() +{ + int v0; // eax + int v1; // esi + //int v2; // eax + + if ( (unsigned char)gbMaxPlayers <= 1u ) + { + v0 = pfile_get_save_num_from_name(plr[myplr]._pName); + v1 = v0; + //_LOBYTE(v2) = pfile_open_archive(0, v0); + if ( !pfile_open_archive(0, v0) ) + app_fatal("Unable to write to save file archive"); + mpqapi_remove_hash_entries(GetTempSaveNames); + pfile_flush(1, v1); + } +} + +_bool __stdcall GetTempSaveNames(int dwIndex, char *szTemp) +{ + int v2; // eax + const char *v3; // ecx + + v2 = dwIndex; + if ( (unsigned int)dwIndex < 0x11 ) + { + v3 = "templ%02d"; +LABEL_5: + sprintf(szTemp, v3, v2); + return 1; + } + if ( (unsigned int)dwIndex < 0x22 ) + { + v2 = dwIndex - 17; + v3 = "temps%02d"; + goto LABEL_5; + } + return 0; +} + +void pfile_rename_temp_to_perm() +{ + int v0; // eax + int v1; // edi + //int v2; // eax + int v3; // esi + //int v4; // eax + //int v5; // eax + //int v6; // eax + char v7[260]; // [esp+8h] [ebp-208h] + char v8[260]; // [esp+10Ch] [ebp-104h] + + v0 = pfile_get_save_num_from_name(plr[myplr]._pName); + v1 = v0; + //_LOBYTE(v2) = pfile_open_archive(0, v0); + if ( !pfile_open_archive(0, v0) ) + app_fatal("Unable to write to save file archive"); + v3 = 0; + while ( 1 ) + { + //_LOBYTE(v6) = GetTempSaveNames(v3, v7); + if ( !GetTempSaveNames(v3, v7) ) + break; + GetPermSaveNames(v3++, v8); + //_LOBYTE(v4) = mpqapi_has_file(v7); + if ( mpqapi_has_file(v7) ) + { + //_LOBYTE(v5) = mpqapi_has_file(v8); + if ( mpqapi_has_file(v8) ) + mpqapi_remove_hash_entry(v8); + mpqapi_rename(v7, v8); + } + } + GetPermSaveNames(v3, v8); + pfile_flush(1, v1); +} + +_bool __stdcall GetPermSaveNames(int dwIndex, char *szPerm) +{ + int v2; // eax + const char *v3; // ecx + + v2 = dwIndex; + if ( (unsigned int)dwIndex < 0x11 ) + { + v3 = "perml%02d"; +LABEL_5: + sprintf(szPerm, v3, v2); + return 1; + } + if ( (unsigned int)dwIndex < 0x22 ) + { + v2 = dwIndex - 17; + v3 = "perms%02d"; + goto LABEL_5; + } + return 0; +} + +void pfile_write_save_file(char *pszName, void *pbData, int dwLen, int qwLen) +{ + void *v4; // ebx + int v5; // eax + //int v6; // eax + char file_name[260]; // [esp+Ch] [ebp-118h] + char password[16]; // [esp+110h] [ebp-14h] + int v9; // [esp+120h] [ebp-4h] + + v4 = pbData; + pfile_strcpy(file_name, pszName); + v5 = pfile_get_save_num_from_name(plr[myplr]._pName); + strcpy(password, "xrgyrkj1"); + v9 = v5; + *(_DWORD *)&password[9] = 0; + *(_WORD *)&password[13] = 0; + password[15] = 0; + if ( (unsigned char)gbMaxPlayers > 1u ) + strcpy(password, "szqnlsk1"); + codec_encode((BYTE *)v4, dwLen, qwLen, password); + //_LOBYTE(v6) = pfile_open_archive(0, v9); + if ( !pfile_open_archive(0, v9) ) + app_fatal("Unable to write to save file archive"); + mpqapi_write_file(file_name, (char *)v4, qwLen); + pfile_flush(1, v9); +} + +void pfile_strcpy(char *dst, char *src) +{ + strcpy(dst, src); +} + +char *pfile_read(char *pszName, int *pdwLen) +{ + int *v2; // ebx + int v3; // eax + void *v4; // edi + //int v5; // eax + int v6; // eax + void *v7; // eax + //int v8; // eax + char *v9; // esi + int v10; // eax + //int v11; // eax + char v13[260]; // [esp+Ch] [ebp-124h] + char password[16]; // [esp+110h] [ebp-20h] + void *src_dst; // [esp+120h] [ebp-10h] + int nread; // [esp+124h] [ebp-Ch] + DWORD nSize; // [esp+128h] [ebp-8h] + void *file; // [esp+12Ch] [ebp-4h] + + v2 = pdwLen; + pfile_strcpy(v13, pszName); + v3 = pfile_get_save_num_from_name(plr[myplr]._pName); + v4 = pfile_open_save_archive(0, v3); + if ( !v4 ) + app_fatal("Unable to open save file archive"); + //_LOBYTE(v5) = SFileOpenFileEx(v4, v13, 0, &file); + if ( !SFileOpenFileEx(v4, v13, 0, &file) ) + app_fatal("Unable to open save file"); + v6 = SFileGetFileSize((int *)file, 0); + *v2 = v6; + if ( !v6 ) + app_fatal("Invalid save file"); + v7 = DiabloAllocPtr(*v2); + src_dst = v7; + //_LOBYTE(v8) = SFileReadFile(file, (char *)v7, *v2, (unsigned long *)&nread, 0); + if ( !SFileReadFile(file, (char *)v7, *v2, (unsigned long *)&nread, 0) ) + app_fatal("Unable to read save file"); + SFileCloseFile(file); + pfile_SFileCloseArchive(v4); + strcpy(password, "xrgyrkj1"); + nSize = 16; + *(_DWORD *)&password[9] = 0; + *(_WORD *)&password[13] = 0; + password[15] = 0; + if ( (unsigned char)gbMaxPlayers > 1u ) + strcpy(password, "szqnlsk1"); + v9 = (char *)src_dst; + v10 = codec_decode((BYTE *)src_dst, *v2, password); + *v2 = v10; + if ( !v10 ) + { + if ( (unsigned char)gbMaxPlayers > 1u ) + { + GetComputerName(password, &nSize); + if ( SFileSetFilePointer(file, 0, 0, 0) ) + app_fatal("Unable to read save file"); + //_LOBYTE(v11) = SFileReadFile(file, v9, *v2, (unsigned long *)&nread, 0); + if ( !SFileReadFile(file, v9, *v2, (unsigned long *)&nread, 0) ) + app_fatal("Unable to read save file"); + *v2 = codec_decode((BYTE *)v9, *v2, password); + } + if ( !*v2 ) + app_fatal("Invalid save file"); + } + return v9; +} + +void pfile_update(BOOL force_save) +{ + BOOL v1; // esi + DWORD v2; // eax + + v1 = force_save; + if ( gbMaxPlayers != 1 ) + { + v2 = GetTickCount(); + if ( v1 || (signed int)(v2 - save_prev_tc) > 60000 ) + { + save_prev_tc = v2; + pfile_write_hero(); + } + } +} diff --git a/2020_03_31/Source/pfile.h b/2020_03_31/Source/pfile.h new file mode 100644 index 00000000..29d4fbd2 --- /dev/null +++ b/2020_03_31/Source/pfile.h @@ -0,0 +1,46 @@ +//HEADER_GOES_HERE +#ifndef __PFILE_H__ +#define __PFILE_H__ + +extern char hero_names[MAX_CHARACTERS][PLR_NAME_LEN]; +extern BOOL gbValidSaveFile; // idb +extern int save_prev_tc; // weak + +void pfile_init_save_directory(); +void pfile_check_available_space(char *pszDir); +void pfile_write_hero(); +int pfile_get_save_num_from_name(char *name); +void pfile_encode_hero(PkPlayerStruct *pPack); +_bool pfile_open_archive(_bool a1, int save_num); +void pfile_get_save_path(char *pszBuf, int dwBufSize, int save_num); +void pfile_flush(_bool is_single_player, int save_num); +_bool pfile_create_player_description(char *dst, int len); +int pfile_create_save_file(char *name_1, char *name_2); +void pfile_flush_W(); +void game_2_ui_player(PlayerStruct *p, _uiheroinfo *heroinfo, BOOL bHasSaveFile); +char game_2_ui_class(PlayerStruct *p); +BOOL __stdcall pfile_ui_set_hero_infos(BOOL (__stdcall *ui_add_hero_info)(_uiheroinfo *)); +char *GetSaveDirectory(char *dst, int dst_size, int save_num); +_bool pfile_read_hero(void *archive, PkPlayerStruct *pPack); +void *pfile_open_save_archive(int *unused, int save_num); +void pfile_SFileCloseArchive(void *hsArchive); +BOOL pfile_archive_contains_game(void *hsArchive); +BOOL __stdcall pfile_ui_set_class_stats(int player_class_nr, _uidefaultstats *class_stats); +int pfile_get_player_class(int player_class_nr); +BOOL __stdcall pfile_ui_save_create(_uiheroinfo *heroinfo); +_bool __stdcall pfile_get_file_name(int lvl, char *dst); +BOOL __stdcall pfile_delete_save(_uiheroinfo *hero_info); +void pfile_read_player_from_save(); +void GetTempLevelNames(char *szTemp); +void GetPermLevelNames(char *szPerm); +void pfile_get_game_name(char *dst); +void pfile_remove_temp_files(); +_bool __stdcall GetTempSaveNames(int dwIndex, char *szTemp); +void pfile_rename_temp_to_perm(); +_bool __stdcall GetPermSaveNames(int dwIndex, char *szPerm); +void pfile_write_save_file(char *pszName, void *pbData, int dwLen, int qwLen); +void pfile_strcpy(char *dst, char *src); +char *pfile_read(char *pszName, int *pdwLen); +void pfile_update(BOOL force_save); + +#endif /* __PFILE_H__ */ diff --git a/2020_03_31/Source/player.cpp b/2020_03_31/Source/player.cpp new file mode 100644 index 00000000..13af0beb --- /dev/null +++ b/2020_03_31/Source/player.cpp @@ -0,0 +1,4964 @@ +#include "diablo.h" +#include "../3rdParty/Storm/Source/storm.h" + +int plr_lframe_size; // idb +int plr_wframe_size; // idb +BYTE plr_gfx_flag; // weak +int plr_aframe_size; // idb +int myplr; +PlayerStruct plr[MAX_PLRS]; +int plr_fframe_size; // idb +int plr_qframe_size; // idb +int deathflag; // idb +int plr_hframe_size; // idb +int plr_bframe_size; // idb +char plr_gfx_bflag; // weak +int plr_sframe_size; // idb +int deathdelay; // weak +int plr_dframe_size; // idb + +const char ArmourChar[4] = { 'L', 'M', 'H', 0 }; +const char WepChar[10] = { 'N', 'U', 'S', 'D', 'B', 'A', 'M', 'H', 'T', 0 }; +const char CharChar[4] = { 'W', 'R', 'S', 0 }; + +/* data */ + +int plrxoff[9] = { 0, 2, 0, 2, 1, 0, 1, 2, 1 }; +int plryoff[9] = { 0, 2, 2, 0, 1, 1, 0, 1, 2 }; +int plrxoff2[9] = { 0, 1, 0, 1, 2, 0, 1, 2, 2 }; +int plryoff2[9] = { 0, 0, 1, 1, 0, 2, 2, 1, 2 }; +char PlrGFXAnimLens[3][11] = +{ + { 10, 16, 8, 2, 20, 20, 6, 20, 8, 9, 14 }, + { 8, 18, 8, 4, 20, 16, 7, 20, 8, 10, 12 }, + { 8, 16, 8, 6, 20, 12, 8, 20, 8, 12, 8 } +}; +int PWVel[3][3] = { { 2048, 1024, 512 }, { 2048, 1024, 512 }, { 2048, 1024, 512 } }; +int WalkAnimTbl[3] = { 8, 8, 8 }; +int StrengthTbl[3] = { 30, 20, 15 }; +int MagicTbl[3] = { 10, 15, 35 }; +int DexterityTbl[3] = { 20, 30, 15 }; +int VitalityTbl[3] = { 25, 20, 20 }; +int ToBlkTbl[3] = { 30, 20, 10 }; +char *ClassStrTblOld[3] = { "Warrior", "Rogue", "Sorceror" }; // unused +int MaxStats[3][4] = { { 250, 50, 60, 100 }, { 55, 70, 250, 80 }, { 45, 250, 85, 80 } }; +int ExpLvlsTbl[51] = +{ + 0, + 2000, + 4620, + 8040, + 12489, + 18258, + 25712, + 35309, + 47622, + 63364, + 83419, + 108879, + 141086, + 181683, + 231075, + 313656, + 424067, + 571190, + 766569, + 1025154, + 1366227, + 1814568, + 2401895, + 3168651, + 4166200, + 5459523, + 7130496, + 9281874, + 12042092, + 15571031, + 20066900, + 25774405, + 32994399, + 42095202, + 53525811, + 67831218, + 85670061, + 107834823, + 135274799, + 169122009, + 210720231, + 261657253, + 323800420, + 399335440, + 490808349, + 601170414, + 733825617, + 892680222, + 1082908612, + 1310707109, + 1583495809 +}; +char *ClassStrTbl[3] = { "Warrior", "Rogue", "Sorceror" }; + +void SetPlayerGPtrs(BYTE *pData, BYTE **pAnim) +{ + int i; + DWORD *pFrameTable; + + pFrameTable = (DWORD *)pData; + + for(i = 0; i < 8; i++) { + pAnim[i] = &pData[pFrameTable[i]]; + } +} + +void LoadPlrGFX(int pnum, DWORD dwMask) +{ + PlayerStruct *pPlayer; + DWORD i; + const char *c, *Suffix; + BYTE *pData, **pAnim; + char FileName[256]; + char Type[16]; + + if((DWORD)pnum >= MAX_PLRS) { + app_fatal("LoadPlrGFX: illegal player %d", pnum); + } + + pPlayer = &plr[pnum]; + /// ASSERT: assert((DWORD) pPlayer->_pClass <= NUM_CLASSES); + sprintf(Type, "%c%c%c", CharChar[pPlayer->_pClass], ArmourChar[pPlayer->_pgfxnum >> 4], WepChar[pPlayer->_pgfxnum & 0xF]); + + c = ClassStrTbl[pPlayer->_pClass]; + + for(i = 1; i <= 0x17F; i <<= 1) { + if(!(i & dwMask)) { + continue; + } + switch(i) { + case 1: + Suffix = "AS"; + if(leveltype == DTYPE_TOWN) { + Suffix = "ST"; + } + pData = pPlayer->_pNData; + pAnim = pPlayer->_pNAnim; + break; + case 2: + Suffix = "AW"; + if(leveltype == DTYPE_TOWN) { + Suffix = "WL"; + } + pData = pPlayer->_pWData; + pAnim = pPlayer->_pWAnim; + break; + case 4: + if(leveltype == DTYPE_TOWN) { + continue; + } + Suffix = "AT"; + pData = pPlayer->_pAData; + pAnim = pPlayer->_pAAnim; + break; + case 8: + if(leveltype == DTYPE_TOWN) { + continue; + } + Suffix = "HT"; + pData = pPlayer->_pHData; + pAnim = pPlayer->_pHAnim; + break; + case 0x10: + if(leveltype == DTYPE_TOWN) { + continue; + } + Suffix = "LM"; + pData = pPlayer->_pLData; + pAnim = pPlayer->_pLAnim; + break; + case 0x20: + if(leveltype == DTYPE_TOWN) { + continue; + } + Suffix = "FM"; + pData = pPlayer->_pFData; + pAnim = pPlayer->_pFAnim; + break; + case 0x40: + if(leveltype == DTYPE_TOWN) { + continue; + } + Suffix = "QM"; + pData = pPlayer->_pTData; + pAnim = pPlayer->_pTAnim; + break; + case 0x80: + if(pPlayer->_pgfxnum & 0xF) { + continue; + } + Suffix = "DT"; + pData = pPlayer->_pDData; + pAnim = pPlayer->_pDAnim; + break; + case 0x100: + if(leveltype == DTYPE_TOWN || !pPlayer->_pBlockFlag) { + continue; + } + Suffix = "BL"; + pData = pPlayer->_pBData; + pAnim = pPlayer->_pBAnim; + break; + default: + app_fatal("PLR:2"); + break; + } + sprintf(FileName, "PlrGFX\\%s\\%s\\%s%s.CL2", c, Type, Type, Suffix); + /// ASSERT: assert(pData); + LoadFileWithMem(FileName, pData); + SetPlayerGPtrs(pData, pAnim); + pPlayer->_pGFXLoad |= i; + } +} + +void InitPlayerGFX(int pnum) +{ + if((DWORD)pnum >= MAX_PLRS) { + app_fatal("InitPlayerGFX: illegal player %d", pnum); + } + + if(plr[pnum]._pHitPoints >> 6 == 0) { + plr[pnum]._pgfxnum = 0; + LoadPlrGFX(pnum, 0x80); + } else { + LoadPlrGFX(pnum, 0x17F); + } +} + +void InitPlrGFXMem(int pnum) +{ + if((DWORD)pnum >= MAX_PLRS) { + app_fatal("InitPlrGFXMem: illegal player %d", pnum); + } + /// ASSERT: assert(! plr[pnum]._pNData); + + if(!(plr_gfx_flag & 1)) { + plr_gfx_flag |= 1; + if(GetPlrGFXSize("AS") > GetPlrGFXSize("ST")) { + plr_sframe_size = GetPlrGFXSize("AS"); + } else { + plr_sframe_size = GetPlrGFXSize("ST"); + } + } + plr[pnum]._pNData = DiabloAllocPtr(plr_sframe_size); + + if(!(plr_gfx_flag & 2)) { + plr_gfx_flag |= 2; + if(GetPlrGFXSize("AW") > GetPlrGFXSize("WL")) { + plr_wframe_size = GetPlrGFXSize("AW"); + } else { + plr_wframe_size = GetPlrGFXSize("WL"); + } + } + plr[pnum]._pWData = DiabloAllocPtr(plr_wframe_size); + + if(!(plr_gfx_flag & 4)) { + plr_gfx_flag |= 4; + plr_aframe_size = GetPlrGFXSize("AT"); + } + plr[pnum]._pAData = DiabloAllocPtr(plr_aframe_size); + + if(!(plr_gfx_flag & 8)) { + plr_gfx_flag |= 8; + plr_hframe_size = GetPlrGFXSize("HT"); + } + plr[pnum]._pHData = DiabloAllocPtr(plr_hframe_size); + + if(!(plr_gfx_flag & 0x10)) { + plr_gfx_flag |= 0x10; + plr_lframe_size = GetPlrGFXSize("LM"); + } + plr[pnum]._pLData = DiabloAllocPtr(plr_lframe_size); + + if(!(plr_gfx_flag & 0x20)) { + plr_gfx_flag |= 0x20; + plr_fframe_size = GetPlrGFXSize("FM"); + } + plr[pnum]._pFData = DiabloAllocPtr(plr_fframe_size); + + if(!(plr_gfx_flag & 0x40)) { + plr_gfx_flag |= 0x40; + plr_qframe_size = GetPlrGFXSize("QM"); + } + plr[pnum]._pTData = DiabloAllocPtr(plr_qframe_size); + + if(!(plr_gfx_flag & 0x80)) { + plr_gfx_flag |= 0x80; + plr_dframe_size = GetPlrGFXSize("DT"); + } + plr[pnum]._pDData = DiabloAllocPtr(plr_dframe_size); + + if(!(plr_gfx_bflag & 1)) { + plr_gfx_bflag |= 1; + plr_bframe_size = GetPlrGFXSize("BL"); + } + plr[pnum]._pBData = DiabloAllocPtr(plr_bframe_size); + + plr[pnum]._pGFXLoad = 0; +} + +DWORD GetPlrGFXSize(char *szCel) +{ + int i, a, w; + DWORD dwSize, dwMaxSize; + HANDLE hsFile; + char FileName[256]; + char Type[16]; + + dwMaxSize = 0; + + for(i = 0; (DWORD)i < NUM_CLASSES; i++) { + for(a = 0; ArmourChar[a] != '\0'; a++) { + for(w = 0; WepChar[w] != '\0'; w++) { + sprintf(Type, "%c%c%c", CharChar[i], ArmourChar[a], WepChar[w]); + sprintf(FileName, "PlrGFX\\%s\\%s\\%s%s.CL2", ClassStrTbl[i], Type, Type, szCel); + if(WOpenFile(FileName, &hsFile, 1)) { + /// ASSERT: assert(hsFile); + dwSize = WGetFileSize(hsFile, NULL); + WCloseFile(hsFile); + if(dwMaxSize <= dwSize) { + dwMaxSize = dwSize; + } + } + } + } + } + + return dwMaxSize; +} + +void FreePlayerGFX(int pnum) +{ + if((DWORD)pnum >= MAX_PLRS) { + app_fatal("FreePlayerGFX: illegal player %d", pnum); + } + + MemFreeDbg(plr[pnum]._pNData); + MemFreeDbg(plr[pnum]._pWData); + MemFreeDbg(plr[pnum]._pAData); + MemFreeDbg(plr[pnum]._pHData); + MemFreeDbg(plr[pnum]._pLData); + MemFreeDbg(plr[pnum]._pFData); + MemFreeDbg(plr[pnum]._pTData); + MemFreeDbg(plr[pnum]._pDData); + MemFreeDbg(plr[pnum]._pBData); + + plr[pnum]._pGFXLoad = 0; +} + +void NewPlrAnim(int pnum, unsigned char *Peq, int numFrames, int Delay, int width) +{ + if((DWORD)pnum >= MAX_PLRS) { + app_fatal("NewPlrAnim: illegal player %d", pnum); + } + + plr[pnum]._pAnimData = Peq; + plr[pnum]._pAnimLen = numFrames; + plr[pnum]._pAnimFrame = 1; + plr[pnum]._pAnimCnt = 0; + plr[pnum]._pAnimDelay = Delay; + plr[pnum]._pAnimWidth = width; + plr[pnum]._pAnimWidth2 = (width - 64) >> 1; +} + +void ClearPlrPVars(int pnum) +{ + if((DWORD)pnum >= MAX_PLRS) { + app_fatal("ClearPlrPVars: illegal player %d", pnum); + } + + plr[pnum]._pVar1 = 0; + plr[pnum]._pVar2 = 0; + plr[pnum]._pVar3 = 0; + plr[pnum]._pVar4 = 0; + plr[pnum]._pVar5 = 0; + plr[pnum]._pVar6 = 0; + plr[pnum]._pVar7 = 0; + plr[pnum]._pVar8 = 0; +} + +void SetPlrAnims(int pnum) +{ + int gn, pc; + + if((DWORD)pnum >= MAX_PLRS) { + app_fatal("SetPlrAnims: illegal player %d", pnum); + } + + plr[pnum]._pNWidth = 96; + plr[pnum]._pWWidth = 96; + plr[pnum]._pAWidth = 128; + plr[pnum]._pHWidth = 96; + plr[pnum]._pSWidth = 96; + plr[pnum]._pDWidth = 128; + plr[pnum]._pBWidth = 96; + + pc = plr[pnum]._pClass; + + if(leveltype == DTYPE_TOWN) { + plr[pnum]._pNFrames = PlrGFXAnimLens[pc][7]; + plr[pnum]._pWFrames = PlrGFXAnimLens[pc][8]; + plr[pnum]._pDFrames = PlrGFXAnimLens[pc][4]; + plr[pnum]._pSFrames = PlrGFXAnimLens[pc][5]; + plr[pnum]._pSFNum = PlrGFXAnimLens[pc][10]; + } else { + plr[pnum]._pNFrames = PlrGFXAnimLens[pc][0]; + plr[pnum]._pWFrames = PlrGFXAnimLens[pc][2]; + plr[pnum]._pAFrames = PlrGFXAnimLens[pc][1]; + plr[pnum]._pHFrames = PlrGFXAnimLens[pc][6]; + plr[pnum]._pSFrames = PlrGFXAnimLens[pc][5]; + plr[pnum]._pDFrames = PlrGFXAnimLens[pc][4]; + plr[pnum]._pBFrames = PlrGFXAnimLens[pc][3]; + plr[pnum]._pAFNum = PlrGFXAnimLens[pc][9]; + plr[pnum]._pSFNum = PlrGFXAnimLens[pc][10]; + } + + gn = plr[pnum]._pgfxnum & 0xF; + + if(pc == PC_WARRIOR) { + if(gn == 4) { + if(leveltype != DTYPE_TOWN) { + plr[pnum]._pNFrames = 8; + } + plr[pnum]._pAWidth = 96; + plr[pnum]._pAFNum = 11; + } else if(gn == 5) { + plr[pnum]._pAFrames = 20; + plr[pnum]._pAFNum = 10; + } else if(gn == 8) { + plr[pnum]._pAFrames = 16; + plr[pnum]._pAFNum = 11; + } + } else if(pc == PC_ROGUE) { + if(gn == 5) { + plr[pnum]._pAFrames = 22; + plr[pnum]._pAFNum = 13; + } else if(gn == 4) { + plr[pnum]._pAFrames = 12; + plr[pnum]._pAFNum = 7; + } else if(gn == 8) { + plr[pnum]._pAFrames = 16; + plr[pnum]._pAFNum = 11; + } + } else if(pc == PC_SORCERER) { + plr[pnum]._pSWidth = 128; + if(gn == 0) { + plr[pnum]._pAFrames = 20; + } else if(gn == 1) { + plr[pnum]._pAFNum = 9; + } else if(gn == 4) { + plr[pnum]._pAFrames = 20; + plr[pnum]._pAFNum = 16; + } else if(gn == 5) { + plr[pnum]._pAFrames = 24; + plr[pnum]._pAFNum = 16; + } + } +} + +void ClearPlrRVars(PlayerStruct *p) +{ + /// ASSERT: assert(p != NULL); + + p->bReserved[0] = 0; + p->bReserved[1] = 0; + p->bReserved[2] = 0; + p->wReserved[0] = 0; + p->wReserved[1] = 0; + p->wReserved[2] = 0; + p->wReserved[3] = 0; + p->wReserved[4] = 0; + p->wReserved[5] = 0; + p->wReserved[6] = 0; + p->wReserved[7] = 0; + p->dwReserved[0] = 0; + p->dwReserved[1] = 0; + p->dwReserved[2] = 0; + p->dwReserved[3] = 0; + p->dwReserved[4] = 0; + p->dwReserved[5] = 0; + p->dwReserved[6] = 0; +} + +void CreatePlayer(int pnum, char c) +{ + int i; + char vc; + + ClearPlrRVars(&plr[pnum]); + SetRndSeed(GetTickCount()); + + if((DWORD)pnum >= MAX_PLRS) { + app_fatal("CreatePlayer: illegal player %d", pnum); + } + + plr[pnum]._pClass = c; + + vc = StrengthTbl[c]; + if(vc < 0) { + vc = 0; + } + plr[pnum]._pStrength = vc; + plr[pnum]._pBaseStr = vc; + vc = MagicTbl[c]; + if(vc < 0) { + vc = 0; + } + plr[pnum]._pMagic = vc; + plr[pnum]._pBaseMag = vc; + vc = DexterityTbl[c]; + if(vc < 0) { + vc = 0; + } + plr[pnum]._pDexterity = vc; + plr[pnum]._pBaseDex = vc; + vc = VitalityTbl[c]; + if(vc < 0) { + vc = 0; + } + plr[pnum]._pVitality = vc; + plr[pnum]._pBaseVit = vc; + + plr[pnum]._pStatPts = 0; + plr[pnum].pTownWarps = 0; + plr[pnum].pDungMsgs = 0; + plr[pnum].pLvlLoad = 0; + plr[pnum].pDiabloKillLevel = 0; + + if(plr[pnum]._pClass == PC_ROGUE) { + plr[pnum]._pDamageMod = plr[pnum]._pLevel * (plr[pnum]._pStrength + plr[pnum]._pDexterity) / 200; + } else { + plr[pnum]._pDamageMod = plr[pnum]._pLevel * plr[pnum]._pStrength / 100; + } + + plr[pnum]._pBaseToBlk = ToBlkTbl[c]; + plr[pnum]._pHitPoints = (plr[pnum]._pVitality + 10) << 6; + if(plr[pnum]._pClass == PC_WARRIOR) { + plr[pnum]._pHitPoints *= 2; + } + if(plr[pnum]._pClass == PC_ROGUE) { + plr[pnum]._pHitPoints += plr[pnum]._pHitPoints >> 1; + } + + plr[pnum]._pMaxHP = plr[pnum]._pHitPoints; + plr[pnum]._pHPBase = plr[pnum]._pHitPoints; + plr[pnum]._pMaxHPBase = plr[pnum]._pHitPoints; + + plr[pnum]._pMana = plr[pnum]._pMagic << 6; + if(plr[pnum]._pClass == PC_SORCERER) { + plr[pnum]._pMana *= 2; + } + if(plr[pnum]._pClass == PC_ROGUE) { + plr[pnum]._pMana += plr[pnum]._pMana >> 1; + } + + plr[pnum]._pMaxMana = plr[pnum]._pMana; + plr[pnum]._pManaBase = plr[pnum]._pMana; + plr[pnum]._pMaxManaBase = plr[pnum]._pMana; + + plr[pnum]._pLevel = 1; + plr[pnum]._pMaxLvl = plr[pnum]._pLevel; + plr[pnum]._pExperience = 0; + plr[pnum]._pMaxExp = plr[pnum]._pExperience; + plr[pnum]._pNextExper = ExpLvlsTbl[1]; + plr[pnum]._pArmorClass = 0; + plr[pnum]._pMagResist = 0; + plr[pnum]._pFireResist = 0; + plr[pnum]._pLghtResist = 0; + plr[pnum]._pLightRad = 10; + plr[pnum]._pInfraFlag = 0; + + if(c == PC_WARRIOR) { + plr[pnum]._pAblSpells64 = (__int64)1 << (SPL_REPAIR - 1); + } else if(c == PC_ROGUE) { + plr[pnum]._pAblSpells64 = (__int64)1 << (SPL_DISARM - 1); + } else if(c == PC_SORCERER) { + plr[pnum]._pAblSpells64 = (__int64)1 << (SPL_RECHARGE - 1); + } + + if(c == PC_SORCERER) { + plr[pnum]._pMemSpells64 = (__int64)1 << (SPL_FIREBOLT - 1); + } else { + plr[pnum]._pMemSpells64 = 0; + } + + for(i = 0; i < 64; i++) { + plr[pnum]._pSplLvl[i] = 0; + } + + plr[pnum]._pSpellFlags = 0; + + if(plr[pnum]._pClass == PC_SORCERER) { + plr[pnum]._pSplLvl[SPL_FIREBOLT] = 2; + } + + for(i = 0; i < 3; i++) { /// BUGFIX: clear all 4 hotkeys instead of 3 (demo leftover) + plr[pnum]._pSplHotKey[i] = -1; + } + + if(c == PC_WARRIOR) { + plr[pnum]._pgfxnum = 3; + } else if(c == PC_ROGUE) { + plr[pnum]._pgfxnum = 4; + } else if(c == PC_SORCERER) { + plr[pnum]._pgfxnum = 8; + } + + for(i = 0; i < NUMLEVELS; i++) { + plr[pnum]._pLvlVisited[i] = 0; + } + + for(i = 0; i < 10; i++) { /// BUGFIX: clear all 17 bytes + plr[pnum]._pSLvlVisited[i] = 0; + } + + plr[pnum]._pLvlChanging = 0; + plr[pnum].pTownWarps = 0; + plr[pnum].pLvlLoad = 0; + plr[pnum].pBattleNet = 0; + plr[pnum].pManaShield = 0; + InitDungMsgs(pnum); + CreatePlrItems(pnum); + SetRndSeed(0); +} + +int CalcStatDiff(int pnum) +{ + int c, d; + + c = plr[pnum]._pClass; + d = MaxStats[c][ATTRIB_STR] - plr[pnum]._pBaseStr; + d += MaxStats[c][ATTRIB_MAG] - plr[pnum]._pBaseMag; + d += MaxStats[c][ATTRIB_DEX] - plr[pnum]._pBaseDex; + d += MaxStats[c][ATTRIB_VIT] - plr[pnum]._pBaseVit; + + return d; +} + +void NextPlrLevel(int pnum) +{ + long l; + + if((DWORD)pnum >= MAX_PLRS) { + app_fatal("NextPlrLevel: illegal player %d", pnum); + } + + plr[pnum]._pLevel++; + plr[pnum]._pMaxLvl++; + + if(CalcStatDiff(pnum) < 5) { + plr[pnum]._pStatPts = CalcStatDiff(pnum); + } else { + plr[pnum]._pStatPts += 5; + } + + plr[pnum]._pNextExper = ExpLvlsTbl[plr[pnum]._pLevel]; + + l = plr[pnum]._pClass == PC_SORCERER ? 64 : 128; + if(gbMaxPlayers == 1) { + l++; + } + plr[pnum]._pMaxHP += l; + plr[pnum]._pHitPoints = plr[pnum]._pMaxHP; + plr[pnum]._pMaxHPBase += l; + plr[pnum]._pHPBase = plr[pnum]._pMaxHPBase; + + if(pnum == myplr) { + drawhpflag = 1; + } + + l = plr[pnum]._pClass == PC_WARRIOR ? 64 : 128; + if(gbMaxPlayers == 1) { + l++; + } + plr[pnum]._pMaxMana += l; + plr[pnum]._pMaxManaBase += l; + + if(!(plr[pnum]._pIFlags & ISPL_NOMANA)) { + plr[pnum]._pMana = plr[pnum]._pMaxMana; + plr[pnum]._pManaBase = plr[pnum]._pMaxManaBase; + } + if(pnum == myplr) { + drawmanaflag = 1; + } +} + +void AddPlrExperience(int pnum, int lvl, long exp) +{ + int i, l; /* omp */ + long e, lLevel, lMax; + + if(pnum != myplr) { + return; + } + if((DWORD)myplr >= MAX_PLRS) { + app_fatal("AddPlrExperience: illegal player %d", myplr); + } + if(plr[myplr]._pHitPoints <= 0) { + return; + } + + e = exp * (((double)lvl - (double)plr[pnum]._pLevel) / 10 + 1); + if(e < 0) { + e = 0; + } + if(gbMaxPlayers > 1) { + lLevel = plr[pnum]._pLevel < 0 ? 0 : plr[pnum]._pLevel; + if(lLevel >= 50) { + lLevel = 50; + } + lMax = ExpLvlsTbl[lLevel] / 20; + if(e >= lMax) { + e = lMax; + } + lMax = 200 * lLevel; + if(e >= lMax) { + e = lMax; + } + } + plr[pnum]._pExperience += e; + if((DWORD)plr[pnum]._pExperience > MAXEXP) { + plr[pnum]._pExperience = MAXEXP; + } + + if(plr[pnum]._pExperience >= ExpLvlsTbl[49]) { + plr[pnum]._pLevel = 50; + } else { + l = 0; + while(plr[pnum]._pExperience >= ExpLvlsTbl[l]) { + l++; + } + if(l != plr[pnum]._pLevel) { + for(i = l - plr[pnum]._pLevel; i > 0; i--) { + NextPlrLevel(pnum); + } + } + NetSendCmdParam1(FALSE, CMD_PLRLEVEL, plr[myplr]._pLevel); + } +} + +void AddPlrMonstExper(int lvl, long exp, char pmask) +{ + int totplrs, i; + + totplrs = 0; + for(i = 0; i < MAX_PLRS; i++) { + if(pmask & (1 << i)) { + totplrs++; + } + } + if(totplrs != 0 && pmask & (1 << myplr)) { + AddPlrExperience(myplr, lvl, exp / totplrs); + } +} + +void InitPlayer(int pnum, BOOL FirstTime) +{ + int i; + + if((DWORD)pnum >= MAX_PLRS) { + app_fatal("InitPlayer: illegal player %d", pnum); + } + + ClearPlrRVars(&plr[pnum]); + + if(FirstTime) { + plr[pnum]._pRSplType = RSPLTYPE_INVALID; + plr[pnum]._pRSpell = -1; + plr[pnum]._pSBkSpell = -1; + plr[pnum]._pSpell = plr[pnum]._pRSpell; + plr[pnum]._pSplType = plr[pnum]._pRSplType; + if((plr[pnum]._pgfxnum & 0xF) == 4) { + plr[pnum]._pwtype = 1; + } else { + plr[pnum]._pwtype = 0; + } + plr[pnum].pManaShield = 0; + } + if(plr[pnum].plrlevel == currlevel || leveldebug) { + SetPlrAnims(pnum); + plr[pnum]._pxoff = 0; + plr[pnum]._pyoff = 0; + plr[pnum]._pxvel = 0; + plr[pnum]._pyvel = 0; + ClearPlrPVars(pnum); + if(plr[pnum]._pHitPoints >> 6 > 0) { + plr[pnum]._pmode = PM_STAND; + NewPlrAnim(pnum, plr[pnum]._pNAnim[0], plr[pnum]._pNFrames, 3, plr[pnum]._pNWidth); + plr[pnum]._pAnimFrame = random(2, plr[pnum]._pNFrames - 1) + 1; + plr[pnum]._pAnimCnt = random(2, 3); + } else { + plr[pnum]._pmode = PM_DEATH; + NewPlrAnim(pnum, plr[pnum]._pDAnim[0], plr[pnum]._pDFrames, 1, plr[pnum]._pDWidth); + plr[pnum]._pAnimFrame = plr[pnum]._pAnimLen - 1; + plr[pnum]._pVar8 = 2 * plr[pnum]._pAnimLen; + } + plr[pnum]._pdir = 0; + plr[pnum]._peflag = 0; + if(pnum == myplr) { + if(!FirstTime || currlevel != 0) { + plr[pnum].WorldX = ViewX; + plr[pnum].WorldY = ViewY; + } + plr[pnum]._ptargx = plr[pnum].WorldX; + plr[pnum]._ptargy = plr[pnum].WorldY; + } else { + plr[pnum]._ptargx = plr[pnum].WorldX; + plr[pnum]._ptargy = plr[pnum].WorldY; + for(i = 0; (DWORD)i < 8; i++) { + if(PosOkPlayer(pnum, plr[pnum].WorldX + plrxoff2[i], plr[pnum].WorldY + plryoff2[i])) { + break; + } + } + plr[pnum].WorldX += plrxoff2[i]; + plr[pnum].WorldY += plryoff2[i]; + } + plr[pnum]._px = plr[pnum].WorldX; + plr[pnum]._py = plr[pnum].WorldY; + plr[pnum].walkpath[0] = -1; + plr[pnum].destAction = -1; + if(pnum == myplr) { + plr[pnum]._plid = AddLight(plr[pnum].WorldX, plr[pnum].WorldY, plr[pnum]._pLightRad); + } else { + plr[pnum]._plid = -1; + } + plr[pnum]._pvid = AddVision(plr[pnum].WorldX, plr[pnum].WorldY, plr[pnum]._pLightRad, pnum == myplr); + } + + if(plr[pnum]._pClass == PC_WARRIOR) { + plr[pnum]._pAblSpells64 = (__int64)1 << (SPL_REPAIR - 1); + } else if(plr[pnum]._pClass == PC_ROGUE) { + plr[pnum]._pAblSpells64 = (__int64)1 << (SPL_DISARM - 1); + } else if(plr[pnum]._pClass == PC_SORCERER) { + plr[pnum]._pAblSpells64 = (__int64)1 << (SPL_RECHARGE - 1); + } + +#ifdef _DEBUG + if(debug_mode_dollar_sign && FirstTime) { + plr[pnum]._pMemSpells64 |= (__int64)1 << SPL_TELEPORT; /// BUGFIX: `(SPL_TELEPORT - 1)` + if(plr[myplr]._pSplLvl[SPL_TELEPORT] == 0) { /// BUGFIX: use `pnum` instead of `myplr` + plr[myplr]._pSplLvl[SPL_TELEPORT] = 1; + } + } + if(debug_mode_key_inverted_v && FirstTime) { + plr[pnum]._pMemSpells64 = 0xFFFFFFFFFFFFFFF; /// BUGFIX: `0xFFFFFFFFFFFFFFFF` + } +#endif + + plr[pnum]._pNextExper = ExpLvlsTbl[plr[pnum]._pLevel]; + plr[pnum]._pInvincible = 0; + + if(pnum == myplr) { + deathdelay = 0; + deathflag = 0; + ScrollInfo._sxoff = 0; + ScrollInfo._syoff = 0; + ScrollInfo._sdir = 0; + } +} + +void InitMultiView() +{ + if((DWORD)myplr >= MAX_PLRS) { + app_fatal("InitPlayer: illegal player %d", myplr); /// BUGFIX: wrong function name in string + } + + ViewX = plr[myplr].WorldX; + ViewY = plr[myplr].WorldY; +} + +void CheckEFlag(int pnum, BOOL flag) +{ + int i, x, y, m; + MICROS *pMicro; + + if((DWORD)pnum >= MAX_PLRS) { + app_fatal("InitPlayer: illegal player %d", pnum); /// BUGFIX: wrong function name in string + } + + x = plr[pnum].WorldX - 1; + y = plr[pnum].WorldY + 1; + m = 0; + pMicro = &dpiece_defs_map_1[IsometricCoord(x, y)]; + + for(i = 2; i < 10; i++) { + m |= pMicro->mt[i]; + } + + if(m | dSpecial[x][y] | nSolidTable[dPiece[x][y]]) { + plr[pnum]._peflag = 1; + } else { + plr[pnum]._peflag = 0; + } + + if(flag == TRUE && plr[pnum]._peflag == 1) { + x = plr[pnum].WorldX; + y = plr[pnum].WorldY + 2; + m = 0; + pMicro = &dpiece_defs_map_1[IsometricCoord(x, y)]; + + for(i = 2; i < 10; i++) { + m |= pMicro->mt[i]; + } + + if(!(m | dSpecial[x][y])) { + x = plr[pnum].WorldX - 2; + y = plr[pnum].WorldY + 1; + m = 0; + pMicro = &dpiece_defs_map_1[IsometricCoord(x, y)]; + + for(i = 2; i < 10; i++) { + m |= pMicro->mt[i]; + } + + if(m | dSpecial[x][y]) { + plr[pnum]._peflag = 2; + } + } + } +} + +BOOL SolidLoc(int x, int y) +{ + if(x < 0 || y < 0 || x >= MAXDUNX || y >= MAXDUNY) { + return FALSE; + } + + return nSolidTable[dPiece[x][y]]; +} + +BOOL PlrDirOK(int pnum, int dir) +{ + int px, py; + BOOL rv; + + if((DWORD)pnum >= MAX_PLRS) { + app_fatal("PlrDirOK: illegal player %d", pnum); + } + + px = plr[pnum].WorldX + offset_x[dir]; + py = plr[pnum].WorldY + offset_y[dir]; + + if(px < 0) { + return FALSE; + } + if(dPiece[px][py] == 0) { + return FALSE; + } + if(!PosOkPlayer(pnum, px, py)) { + return FALSE; + } + + rv = TRUE; + if(rv && dir == DIR_E) { + rv = !SolidLoc(px, py + 1) && !(dFlags[px][py + 1] & 0x20); + } + if(rv && dir == DIR_W) { + rv = !SolidLoc(px + 1, py) && !(dFlags[px + 1][py] & 0x20); + } + + return rv; +} + +void PlrClrTrans(int x, int y) +{ + int i, j; + char v; + + for(j = y - 1; j <= y + 1; j++) { + for(i = x - 1; i <= x + 1; i++) { + v = dTransVal[i][j]; + TransList[v] = 0; + } + } +} + +void PlrDoTrans(int x, int y) +{ + int i, j; + char v; + + if(leveltype != DTYPE_CATHEDRAL && leveltype != DTYPE_CATACOMBS) { + TransList[1] = 1; + } else { + for(j = y - 1; j <= y + 1; j++) { + for(i = x - 1; i <= x + 1; i++) { + if(!nSolidTable[dPiece[i][j]]) { + v = dTransVal[i][j]; + if(v != 0) { + TransList[v] = 1; + } + } + } + } + } +} + +void SetPlayerOld(int pnum) +{ + if((DWORD)pnum >= MAX_PLRS) { + app_fatal("SetPlayerOld: illegal player %d", pnum); + } + + plr[pnum]._poldx = plr[pnum].WorldX; + plr[pnum]._poldy = plr[pnum].WorldY; +} + +void FixPlayerLocation(int pnum, int bDir) +{ + if((DWORD)pnum >= MAX_PLRS) { + app_fatal("FixPlayerLocation: illegal player %d", pnum); + } + + plr[pnum]._px = plr[pnum].WorldX; + plr[pnum]._py = plr[pnum].WorldY; + plr[pnum]._ptargx = plr[pnum].WorldX; + plr[pnum]._ptargy = plr[pnum].WorldY; + plr[pnum]._pxoff = 0; + plr[pnum]._pyoff = 0; + CheckEFlag(pnum, FALSE); + plr[pnum]._pdir = bDir; + + if(pnum == myplr) { + ScrollInfo._sxoff = 0; + ScrollInfo._syoff = 0; + ScrollInfo._sdir = 0; + ViewX = plr[pnum].WorldX; + ViewY = plr[pnum].WorldY; + } +} + +void StartStand(int pnum, int dir) +{ + if((DWORD)pnum >= MAX_PLRS) { + app_fatal("StartStand: illegal player %d", pnum); + } + + if(!plr[pnum]._pInvincible || plr[pnum]._pHitPoints != 0 || pnum != myplr) { + if(!(plr[pnum]._pGFXLoad & 1)) { + LoadPlrGFX(pnum, 1); + } + NewPlrAnim(pnum, plr[pnum]._pNAnim[dir], plr[pnum]._pNFrames, 3, plr[pnum]._pNWidth); + plr[pnum]._pmode = PM_STAND; + FixPlayerLocation(pnum, dir); + FixPlrWalkTags(pnum); + dPlayer[plr[pnum].WorldX][plr[pnum].WorldY] = pnum + 1; + SetPlayerOld(pnum); + } else { + SyncPlrKill(pnum, -1); + } +} + +void StartWalkStand(int pnum) +{ + if((DWORD)pnum >= MAX_PLRS) { + app_fatal("StartWalkStand: illegal player %d", pnum); + } + + plr[pnum]._pmode = PM_STAND; + plr[pnum]._px = plr[pnum].WorldX; + plr[pnum]._py = plr[pnum].WorldY; + plr[pnum]._pxoff = 0; + plr[pnum]._pyoff = 0; + CheckEFlag(pnum, FALSE); + + if(pnum == myplr) { + ScrollInfo._sxoff = 0; + ScrollInfo._syoff = 0; + ScrollInfo._sdir = 0; + ViewX = plr[pnum].WorldX; + ViewY = plr[pnum].WorldY; + } +} + +void PM_ChangeLightOff(int pnum) +{ + int x, y, xmul, ymul, px, py, lx, ly; + LightListStruct *l; + static unsigned char fix[9] = { 0, 0, 3, 3, 3, 6, 6, 6, 8 }; + + if((DWORD)pnum >= MAX_PLRS) { + app_fatal("PM_ChangeLightOff: illegal player %d", pnum); + } + + l = &LightList[plr[pnum]._plid]; + x = 2 * plr[pnum]._pyoff + plr[pnum]._pxoff; + y = 2 * plr[pnum]._pyoff - plr[pnum]._pxoff; + + if(x < 0) { + xmul = -1; + x = -x; + } else { + xmul = 1; + } + + if(y < 0) { + ymul = -1; + y = -y; + } else { + ymul = 1; + } + + x >>= 3; + y >>= 3; + x *= xmul; + y *= ymul; + px = (l->_lx << 3) + x; + py = (l->_ly << 3) + y; + lx = (l->_lx << 3) + l->_xoff; + ly = (l->_ly << 3) + l->_yoff; + + if(abs(px - lx) >= 3 || abs(py - ly) >= 3) { + ChangeLightOff(plr[pnum]._plid, x, y); + } +} + +void PM_ChangeOffset(int pnum) +{ + int px, py; + + if((DWORD)pnum >= MAX_PLRS) { + app_fatal("PM_ChangeOffset: illegal player %d", pnum); + } + + plr[pnum]._pVar8++; + px = plr[pnum]._pVar6 >> 8; + py = plr[pnum]._pVar7 >> 8; + plr[pnum]._pVar6 += plr[pnum]._pxvel; + plr[pnum]._pVar7 += plr[pnum]._pyvel; + plr[pnum]._pxoff = plr[pnum]._pVar6 >> 8; + plr[pnum]._pyoff = plr[pnum]._pVar7 >> 8; + px -= plr[pnum]._pVar6 >> 8; + py -= plr[pnum]._pVar7 >> 8; + + if(pnum == myplr && ScrollInfo._sdir != 0) { + ScrollInfo._sxoff += px; + ScrollInfo._syoff += py; + } + + PM_ChangeLightOff(pnum); +} + +void StartWalk(int pnum, int xvel, int yvel, int xadd, int yadd, int EndDir, int sdir) +{ + int px, py; + + if((DWORD)pnum >= MAX_PLRS) { + app_fatal("StartWalk: illegal player %d", pnum); + } + + if(plr[pnum]._pInvincible && plr[pnum]._pHitPoints == 0 && pnum == myplr) { + SyncPlrKill(pnum, -1); + return; + } + + SetPlayerOld(pnum); + px = xadd + plr[pnum].WorldX; + py = yadd + plr[pnum].WorldY; + + if(!PlrDirOK(pnum, EndDir)) { + return; + } + + plr[pnum]._px = px; + plr[pnum]._py = py; + + if(pnum == myplr) { + ScrollInfo._sdx = plr[pnum].WorldX - ViewX; + ScrollInfo._sdy = plr[pnum].WorldY - ViewY; + } + + dPlayer[px][py] = -(pnum + 1); + plr[pnum]._pmode = PM_WALK; + plr[pnum]._pxvel = xvel; + plr[pnum]._pyvel = yvel; + plr[pnum]._pxoff = 0; + plr[pnum]._pyoff = 0; + plr[pnum]._pVar1 = xadd; + plr[pnum]._pVar2 = yadd; + plr[pnum]._pVar3 = EndDir; + + if(!(plr[pnum]._pGFXLoad & 2)) { + LoadPlrGFX(pnum, 2); + } + + NewPlrAnim(pnum, plr[pnum]._pWAnim[EndDir], plr[pnum]._pWFrames, 0, plr[pnum]._pWWidth); + plr[pnum]._pdir = EndDir; + plr[pnum]._pVar6 = 0; + plr[pnum]._pVar7 = 0; + plr[pnum]._pVar8 = 0; + CheckEFlag(pnum, FALSE); + + if(pnum == myplr) { + if(zoomflag) { + if(abs(ScrollInfo._sdx) >= 3 || abs(ScrollInfo._sdy) >= 3) { + ScrollInfo._sdir = 0; + } else { + ScrollInfo._sdir = sdir; + } + } else { + if(abs(ScrollInfo._sdx) >= 2 || abs(ScrollInfo._sdy) >= 2) { + ScrollInfo._sdir = 0; + } else { + ScrollInfo._sdir = sdir; + } + } + } +} + +void StartWalk2(int pnum, int xvel, int yvel, int xoff, int yoff, int xadd, int yadd, int EndDir, int sdir) +{ + int v9; // edi + int v10; // esi + int v11; // ebx + int v12; // edi + _bool v13; // zf + int v14; // eax + int v15; // ecx + int v16; // ecx + int v17; // ecx + int v18; // ST08_4 + _bool v19; // edx + int v20; // eax + _bool v21; // sf + unsigned char v22; // of + int v23; // eax + int v24; // [esp+Ch] [ebp-8h] + int arglist; // [esp+10h] [ebp-4h] + int x; // [esp+28h] [ebp+14h] + + v9 = pnum; + v24 = xvel; + arglist = pnum; + if ( (unsigned int)pnum >= MAX_PLRS ) + app_fatal("StartWalk2: illegal player %d", pnum); + v10 = v9; + if ( plr[v9]._pInvincible && !plr[v10]._pHitPoints && v9 == myplr ) + { + SyncPlrKill(v9, -1); + return; + } + SetPlayerOld(v9); + v11 = xadd + plr[v10].WorldX; + v12 = yadd + plr[v10].WorldY; + x = xadd + plr[v10].WorldX; + if ( PlrDirOK(arglist, EndDir) ) + { + plr[v10]._px = v11; + v13 = arglist == myplr; + plr[v10]._py = v12; + if ( v13 ) + { + ScrollInfo._sdx = plr[v10].WorldX - ViewX; + ScrollInfo._sdy = plr[v10].WorldY - ViewY; + } + v14 = plr[v10].WorldY; + v15 = plr[v10].WorldX; + plr[v10]._pVar2 = v14; + dPlayer[v15][v14] = -1 - arglist; + v16 = plr[v10].WorldX; + plr[v10].WorldX = v11; + dPlayer[v11][v12] = arglist + 1; + plr[v10]._pVar1 = v16; + v17 = plr[v10]._plid; + plr[v10].WorldY = v12; + plr[v10]._pxoff = xoff; + plr[v10]._pyoff = yoff; + ChangeLightXY(v17, x, v12); + PM_ChangeLightOff(arglist); + plr[v10]._pxvel = v24; + plr[v10]._pyvel = yvel; + plr[v10]._pVar6 = xoff << 8; + v13 = (plr[v10]._pGFXLoad & 2) == 0; + plr[v10]._pmode = PM_WALK2; + plr[v10]._pVar7 = yoff << 8; + plr[v10]._pVar3 = EndDir; + if ( v13 ) + LoadPlrGFX(arglist, PM_WALK2); + v18 = plr[v10]._pWWidth; + NewPlrAnim(arglist, plr[0]._pWAnim[EndDir + 5430 * arglist], plr[v10]._pWFrames, 0, v18); + plr[v10]._pVar8 = 0; + v19 = 0; + plr[v10]._pdir = EndDir; + if ( EndDir == 7 ) + v19 = 1; + CheckEFlag(arglist, v19); + if ( arglist == myplr ) + { + if ( zoomflag ) + { + if ( abs(ScrollInfo._sdx) < 3 ) + { + v20 = abs(ScrollInfo._sdy); + v22 = __OFSUB__(v20, 3); + v21 = v20 - 3 < 0; + goto LABEL_20; + } + } + else if ( abs(ScrollInfo._sdx) < PM_WALK2 ) + { + v23 = abs(ScrollInfo._sdy); + v22 = __OFSUB__(v23, 2); + v21 = v23 - PM_WALK2 < 0; +LABEL_20: + if ( v21 ^ v22 ) + { + ScrollInfo._sdir = sdir; + return; + } + goto LABEL_22; + } +LABEL_22: + ScrollInfo._sdir = 0; + return; + } + } +} + +void StartWalk3(int pnum, int xvel, int yvel, int xoff, int yoff, int xadd, int yadd, int mapx, int mapy, int EndDir, int sdir) +{ + int v11; // edi + int v12; // esi + int v13; // eax + int v14; // ecx + int v15; // ebx + int v16; // edi + _bool v17; // zf + int v18; // edx + int v19; // ecx + int v20; // ST08_4 + int v21; // eax + _bool v22; // sf + unsigned char v23; // of + int v24; // eax + int v25; // [esp+10h] [ebp-8h] + int arglist; // [esp+14h] [ebp-4h] + int a6; // [esp+2Ch] [ebp+14h] + int x; // [esp+30h] [ebp+18h] + int y; // [esp+34h] [ebp+1Ch] + + v11 = pnum; + v25 = xvel; + arglist = pnum; + if ( (unsigned int)pnum >= MAX_PLRS ) + app_fatal("StartWalk3: illegal player %d", pnum); + v12 = v11; + if ( plr[v11]._pInvincible && !plr[v12]._pHitPoints && v11 == myplr ) + { + SyncPlrKill(v11, -1); + return; + } + SetPlayerOld(v11); + v13 = plr[v12].WorldX; + a6 = v13 + xadd; + v14 = plr[v12].WorldY; + v15 = v14 + yadd; + x = mapx + v13; + v16 = v14 + mapy; + y = v14 + mapy; + if ( PlrDirOK(arglist, EndDir) ) + { + v17 = arglist == myplr; + plr[v12]._px = a6; + plr[v12]._py = v15; + if ( v17 ) + { + ScrollInfo._sdx = plr[v12].WorldX - ViewX; + ScrollInfo._sdy = plr[v12].WorldY - ViewY; + } + v18 = plr[v12].WorldY; + v19 = plr[v12].WorldX; + plr[v12]._pVar5 = v16; + dPlayer[v19][v18] = -1 - arglist; + dPlayer[a6][v15] = -1 - arglist; + plr[v12]._pVar4 = x; + plr[v12]._pyoff = yoff; + dFlags[x][v16] |= 0x20u; + v17 = leveltype == DTYPE_TOWN; + plr[v12]._pxoff = xoff; + if ( !v17 ) + { + ChangeLightXY(plr[v12]._plid, x, y); + PM_ChangeLightOff(arglist); + } + plr[v12]._pmode = PM_WALK3; + plr[v12]._pxvel = v25; + plr[v12]._pyvel = yvel; + plr[v12]._pVar1 = a6; + plr[v12]._pVar6 = xoff << 8; + v17 = (plr[v12]._pGFXLoad & 2) == 0; + plr[v12]._pVar7 = yoff << 8; + plr[v12]._pVar2 = v15; + plr[v12]._pVar3 = EndDir; + if ( v17 ) + LoadPlrGFX(arglist, 2); + v20 = plr[v12]._pWWidth; + NewPlrAnim(arglist, plr[0]._pWAnim[EndDir + 5430 * arglist], plr[v12]._pWFrames, 0, v20); + plr[v12]._pdir = EndDir; + plr[v12]._pVar8 = 0; + CheckEFlag(arglist, 0); + if ( arglist == myplr ) + { + if ( zoomflag ) + { + if ( abs(ScrollInfo._sdx) < 3 ) + { + v21 = abs(ScrollInfo._sdy); + v23 = __OFSUB__(v21, 3); + v22 = v21 - 3 < 0; + goto LABEL_20; + } + } + else if ( abs(ScrollInfo._sdx) < 2 ) + { + v24 = abs(ScrollInfo._sdy); + v23 = __OFSUB__(v24, 2); + v22 = v24 - 2 < 0; +LABEL_20: + if ( v22 ^ v23 ) + { + ScrollInfo._sdir = sdir; + return; + } + goto LABEL_22; + } +LABEL_22: + ScrollInfo._sdir = 0; + return; + } + } +} + +void StartAttack(int pnum, int d) +{ + int v2; // edi + int v3; // ebp + int v4; // esi + int v5; // ST08_4 + + v2 = pnum; + v3 = d; + if ( (unsigned int)pnum >= MAX_PLRS ) + app_fatal("StartAttack: illegal player %d", pnum); + v4 = v2; + if ( !plr[v2]._pInvincible || plr[v4]._pHitPoints || v2 != myplr ) + { + if ( !(plr[v4]._pGFXLoad & 4) ) + LoadPlrGFX(v2, 4); + v5 = plr[v4]._pAWidth; + NewPlrAnim(v2, plr[0]._pAAnim[v3 + 5430 * v2], plr[v4]._pAFrames, 0, v5); + plr[v4]._pmode = 4; + FixPlayerLocation(v2, v3); + SetPlayerOld(v2); + } + else + { + SyncPlrKill(v2, -1); + } +} + +void StartRangeAttack(int pnum, int d, int cx, int cy) +{ + int v4; // edi + int v5; // esi + int v6; // ST08_4 + int a2a; // [esp+8h] [ebp-4h] + + v4 = pnum; + a2a = d; + if ( (unsigned int)pnum >= MAX_PLRS ) + app_fatal("StartRangeAttack: illegal player %d", pnum); + v5 = v4; + if ( !plr[v4]._pInvincible || plr[v5]._pHitPoints || v4 != myplr ) + { + if ( !(plr[v5]._pGFXLoad & 4) ) + LoadPlrGFX(v4, 4); + v6 = plr[v5]._pAWidth; + NewPlrAnim(v4, plr[0]._pAAnim[a2a + 5430 * v4], plr[v5]._pAFrames, 0, v6); + plr[v5]._pmode = PM_RATTACK; + FixPlayerLocation(v4, a2a); + SetPlayerOld(v4); + plr[v5]._pVar1 = cx; + plr[v5]._pVar2 = cy; + } + else + { + SyncPlrKill(v4, -1); + } +} + +void StartPlrBlock(int pnum, int dir) +{ + int v2; // edi + int v3; // ebx + int v4; // esi + int v5; // ST08_4 + + v2 = pnum; + v3 = dir; + if ( (unsigned int)pnum >= MAX_PLRS ) + app_fatal("StartPlrBlock: illegal player %d", pnum); + v4 = v2; + if ( !plr[v2]._pInvincible || plr[v4]._pHitPoints || v2 != myplr ) + { + PlaySfxLoc(IS_ISWORD, plr[v4].WorldX, plr[v4].WorldY); + if ( !(plr[v4]._pGFXLoad & 0x100) ) + LoadPlrGFX(v2, 256); + v5 = plr[v4]._pBWidth; + NewPlrAnim(v2, plr[0]._pBAnim[v3 + 5430 * v2], plr[v4]._pBFrames, 2, v5); + plr[v4]._pmode = PM_BLOCK; + FixPlayerLocation(v2, v3); + SetPlayerOld(v2); + } + else + { + SyncPlrKill(v2, -1); + } +} + +void StartSpell(int pnum, int d, int cx, int cy) +{ + int v4; // edi + int v5; // esi + unsigned char *v6; // edx + int v7; // ST08_4 + int v8; // edx + int a2; // [esp+Ch] [ebp-4h] + + v4 = pnum; + a2 = d; + if ( (unsigned int)pnum >= MAX_PLRS ) + app_fatal("StartSpell: illegal player %d", pnum); + v5 = v4; + if ( plr[v4]._pInvincible && !plr[v5]._pHitPoints && v4 == myplr ) + { + SyncPlrKill(v4, -1); + return; + } + if ( leveltype ) + { + switch ( spelldata[plr[v5]._pSpell].sType ) + { + case STYPE_FIRE: + if ( !(plr[v5]._pGFXLoad & 0x20) ) + LoadPlrGFX(v4, 32); + v6 = plr[0]._pFAnim[a2 + 5430 * v4]; + goto LABEL_20; + case STYPE_LIGHTNING: + if ( !(plr[v5]._pGFXLoad & 0x10) ) + LoadPlrGFX(v4, 16); + v6 = plr[0]._pLAnim[a2 + 5430 * v4]; + goto LABEL_20; + case STYPE_MAGIC: + if ( !(plr[v5]._pGFXLoad & 0x40) ) + LoadPlrGFX(v4, 64); + v6 = plr[0]._pTAnim[a2 + 5430 * v4]; +LABEL_20: + v7 = plr[v5]._pSWidth; + NewPlrAnim(v4, v6, plr[v5]._pSFrames, 0, v7); + break; + } + } + PlaySfxLoc((unsigned char)spelldata[plr[v5]._pSpell].sSFX, plr[v5].WorldX, plr[v5].WorldY); + plr[v5]._pmode = PM_SPELL; + FixPlayerLocation(v4, a2); + SetPlayerOld(v4); + v8 = plr[v5]._pSpell; + plr[v5]._pVar1 = cx; + plr[v5]._pVar2 = cy; + plr[v5]._pVar4 = GetSpellLevel(v4, v8); + plr[v5]._pVar8 = 1; +} + +void FixPlrWalkTags(int pnum) +{ + int v1; // esi + int v2; // edx + int v3; // ecx + int v4; // eax + int v5; // esi + int v6; // edi + int v7; // ebx + int v8; // edi + _bool v9; // zf + _bool v10; // sf + unsigned char v11; // of + int v12; // eax + int v13; // [esp+8h] [ebp-Ch] + int v14; // [esp+Ch] [ebp-8h] + char *v15; // [esp+10h] [ebp-4h] + + v1 = pnum; + if ( (unsigned int)pnum >= MAX_PLRS ) + app_fatal("FixPlrWalkTags: illegal player %d", pnum); + v13 = v1 + 1; + v2 = -1 - v1; + v3 = plr[v1]._poldx; + v4 = plr[v1]._poldy; + v5 = v4 - 1; + if ( (unsigned char)(__OFSUB__(v4 - 1, v4 + 1) ^ 1) | (v4 - 1 == v4 + 1) ) + { + v6 = v3 + 1; + do + { + v7 = v3 - 1; + v14 = v3 - 1; + if ( v3 - 1 <= v6 ) + { + v15 = &dPlayer[v7][v5]; + do + { + if ( v7 >= 0 && v7 < 112 && v5 >= 0 && v5 < 112 ) + { + v8 = *v15; + if ( v8 == v13 || v8 == v2 ) + *v15 = 0; + } + v15 += 112; + v7 = v14 + 1; + v6 = v3 + 1; + v11 = __OFSUB__(v14 + 1, v3 + 1); + v9 = v14 + 1 == v3 + 1; + v10 = v14++ - v3 < 0; + } + while ( (unsigned char)(v10 ^ v11) | v9 ); + } + ++v5; + } + while ( v5 <= v4 + 1 ); + } + if ( v3 >= 0 && v3 < 111 && v4 >= 0 && v4 < 111 ) + { + v12 = 112 * v3 + v4; + dFlags[1][v12] &= 0xDFu; + dFlags[0][v12 + 1] &= 0xDFu; + } +} + +void RemovePlrFromMap(int pnum) +{ + int v1; // esi + signed int v2; // edi + signed int v3; // edx + signed int v4; // ebx + char v5; // al + signed int v6; // edx + _BYTE *v7; // eax + signed int v8; // edi + int v9; // ecx + int v10; // [esp+Ch] [ebp-4h] + + v1 = -1 - pnum; + v10 = pnum + 1; + v2 = 1; + do + { + v3 = v2; + v4 = 111; + do + { + if ( dPlayer[0][v3 + 111] == v1 || dPlayer[0][v3] == v1 ) + { + v5 = dFlags[1][v3]; + if ( v5 & 0x20 ) + dFlags[1][v3] = v5 & 0xDF; + } + v3 += 112; + --v4; + } + while ( v4 ); + ++v2; + } + while ( v2 < 112 ); + v6 = 0; + do + { + v7 = (unsigned char *)dPlayer + v6; + v8 = 112; + do + { + v9 = (char)*v7; + if ( v9 == v10 || v9 == v1 ) + *v7 = 0; + v7 += 112; + --v8; + } + while ( v8 ); + ++v6; + } + while ( v6 < 112 ); +} + +void StartPlrHit(int pnum, int dam, unsigned char forcehit) +{ + int v3; // ebx + int v4; // edi + int v5; // esi + char v6; // al + int v7; // ecx + int v8; // eax + int v9; // edi + int v10; // ST08_4 + + v3 = pnum; + v4 = dam; + if ( (unsigned int)pnum >= MAX_PLRS ) + app_fatal("StartPlrHit: illegal player %d", pnum); + v5 = v3; + if ( plr[v3]._pInvincible && !plr[v5]._pHitPoints && v3 == myplr ) + { + SyncPlrKill(v3, -1); + return; + } + v6 = plr[v5]._pClass; + switch ( v6 ) + { + case UI_WARRIOR: + v7 = PS_WARR69; +LABEL_13: + PlaySfxLoc(v7, plr[v5].WorldX, plr[v5].WorldY); + break; + case UI_ROGUE: + v7 = PS_ROGUE69; + goto LABEL_13; + case UI_SORCERER: + v7 = PS_MAGE69; + goto LABEL_13; + } + v8 = plr[v5]._pLevel; + drawhpflag = 1; + if ( v4 >> 6 >= v8 || forcehit ) + { + v9 = plr[v5]._pdir; + if ( !(plr[v5]._pGFXLoad & 8) ) + LoadPlrGFX(v3, 8); + v10 = plr[v5]._pHWidth; + NewPlrAnim(v3, plr[0]._pHAnim[v9 + 5430 * v3], plr[v5]._pHFrames, 0, v10); + plr[v5]._pmode = PM_GOTHIT; + FixPlayerLocation(v3, v9); + plr[v5]._pVar8 = 1; + FixPlrWalkTags(v3); + dPlayer[plr[v5].WorldX][plr[v5].WorldY] = v3 + 1; + SetPlayerOld(v3); + } +} + +void RespawnDeadItem(ItemStruct *itm, int x, int y) +{ + int ii; + + if(numitems >= MAXITEMS) { + return; + } + + if(FindGetItem(itm->IDidx, itm->_iCreateInfo, itm->_iSeed) >= 0) { + DrawInvMsg("A duplicate item has been detected. Destroying duplicate..."); + SyncGetItem(x, y, itm->IDidx, itm->_iCreateInfo, itm->_iSeed); + } + + ii = itemavail[0]; + dItem[x][y] = ii + 1; + itemavail[0] = itemavail[MAXITEMS - numitems - 1]; + itemactive[numitems] = ii; + item[ii] = *itm; + item[ii]._ix = x; + item[ii]._iy = y; + RespawnItem(ii, TRUE); + numitems++; + itm->_itype = -1; +} + +void StartPlayerKill(int pnum, int earflag) +{ + unsigned int v2; // edi + unsigned int v3; // esi + char v4; // al + int v5; // ecx + int v6; // ST0C_4 + _bool v7; // zf + int *v8; // eax + signed int v9; // ecx + char *v10; // eax + char v11; // al + short v12; // cx + short v13; // ax + int v14; // ecx + int v15; // eax + signed int v17; // ebx + int v18; // eax + ItemStruct ear; // [esp+Ch] [ebp-178h] + BOOL v20; // [esp+17Ch] [ebp-8h] + struct ItemStruct *itm; // [esp+180h] [ebp-4h] + + v2 = pnum; + v3 = 21720 * pnum; + itm = (struct ItemStruct *)earflag; + if ( plr[pnum]._pHitPoints <= 0 && plr[v3 / 0x54D8]._pmode == PM_DEATH ) + return; + if ( myplr == pnum ) + NetSendCmdParam1(1u, CMD_PLRDEAD, earflag); + v20 = (unsigned char)gbMaxPlayers > 1u && plr[v3 / 0x54D8].plrlevel == 16; + if ( v2 >= 4 ) + app_fatal("StartPlayerKill: illegal player %d", v2); + v4 = plr[v3 / 0x54D8]._pClass; + if ( v4 ) + { + if ( v4 == 1 ) + { + v5 = PS_ROGUE71; + } + else + { + if ( v4 != 2 ) + goto LABEL_18; + v5 = PS_MAGE71; + } + PlaySfxLoc(v5, plr[v3 / 0x54D8].WorldX, plr[v3 / 0x54D8].WorldY); + goto LABEL_18; + } + PlaySfxLoc(PS_DEAD, plr[v3 / 0x54D8].WorldX, plr[v3 / 0x54D8].WorldY); /// BUGFIX: should use `PS_WARR71` like other classes +LABEL_18: + if ( plr[v3 / 0x54D8]._pgfxnum ) + { + plr[v3 / 0x54D8]._pgfxnum = 0; + plr[v3 / 0x54D8]._pGFXLoad = 0; + SetPlrAnims(v2); + } + if ( SLOBYTE(plr[v3 / 0x54D8]._pGFXLoad) >= 0 ) + LoadPlrGFX(v2, 128); + v6 = plr[v3 / 0x54D8]._pDWidth; + NewPlrAnim(v2, plr[0]._pDAnim[plr[v3 / 0x54D8]._pdir + v3 / 4], plr[v3 / 0x54D8]._pDFrames, 1, v6); + plr[v3 / 0x54D8]._pBlockFlag = 0; + plr[v3 / 0x54D8]._pmode = PM_DEATH; + plr[v3 / 0x54D8]._pInvincible = 1; + SetPlayerHitPoints(v2, 0); + v7 = v2 == myplr; + plr[v3 / 0x54D8]._pVar8 = 1; + if ( !v7 && !itm && !v20 ) + { + v8 = &plr[v3 / 0x54D8].InvBody[0]._itype; + v9 = 7; + do + { + *v8 = -1; + v8 += 92; + --v9; + } + while ( v9 ); + CalcPlrInv(v2, 0); + } + if ( plr[v3 / 0x54D8].plrlevel == currlevel ) + { + FixPlayerLocation(v2, plr[v3 / 0x54D8]._pdir); + RemovePlrFromMap(v2); + v10 = &dFlags[plr[v3 / 0x54D8].WorldX][plr[v3 / 0x54D8].WorldY]; + *v10 |= 4u; + SetPlayerOld(v2); + if ( v2 == myplr ) + { + drawhpflag = 1; + deathdelay = 30; + if ( pcurs >= CURSOR_FIRSTITEM ) + { + PlrDeadItem(v2, &plr[v3 / 0x54D8].HoldItem, 0, 0); + SetCursor_(CURSOR_HAND); + } + if ( !v20 ) + { + DropHalfPlayersGold(v2); + if ( itm != (struct ItemStruct *)-1 ) + { + if ( itm ) + { + SetPlrHandItem(&ear, IDI_EAR); + sprintf(ear._iName, "Ear of %s", plr[v3 / 0x54D8]._pName); + v11 = plr[v3 / 0x54D8]._pClass; + if ( v11 == 2 ) + { + ear._iCurs = 19; + } + else if ( v11 ) + { + if ( v11 == 1 ) + ear._iCurs = 21; + } + else + { + ear._iCurs = 20; + } + _LOBYTE(v12) = 0; + _HIBYTE(v12) = plr[v3 / 0x54D8]._pName[0]; + v13 = v12 | plr[v3 / 0x54D8]._pName[1]; + v14 = plr[v3 / 0x54D8]._pName[3]; + ear._iCreateInfo = v13; + v15 = plr[v3 / 0x54D8]._pName[5] | ((plr[v3 / 0x54D8]._pName[4] | ((v14 | (plr[v3 / 0x54D8]._pName[2] << 8)) << 8)) << 8); + ear._ivalue = plr[v3 / 0x54D8]._pLevel; + ear._iSeed = v15; + if ( FindGetItem(IDI_EAR, *(int *)&ear._iCreateInfo, v15) == -1 ) + PlrDeadItem(v2, &ear, 0, 0); + } + else + { + itm = plr[v3 / 0x54D8].InvBody; + v17 = 7; + do + { + v18 = ((_BYTE)--v17 + (unsigned char)plr[v3 / 0x54D8]._pdir) & 7; + PlrDeadItem(v2, itm, offset_x[v18], offset_y[v18]); + ++itm; + } + while ( v17 ); + CalcPlrInv(v2, 0); + } + } + } + } + } + SetPlayerHitPoints(v2, 0); +} + +void PlrDeadItem(int pnum, ItemStruct *itm, int xx, int yy) +{ + int i, j, l, x, y; + + if(itm->_itype == -1) { + return; + } + if((DWORD)pnum >= MAX_PLRS) { + app_fatal("PlrDeadItem: illegal player %d", pnum); + } + + x = xx + plr[pnum].WorldX; + y = yy + plr[pnum].WorldY; + if((xx != 0 || yy != 0) && ItemSpaceOk(x, y)) { + RespawnDeadItem(itm, x, y); + plr[pnum].HoldItem = *itm; + NetSendCmdPItem(FALSE, CMD_RESPAWNITEM, x, y); + } else { + for(l = 1; l < 50; l++) { + for(j = -l; j <= l; j++) { + y = j + plr[pnum].WorldY; + for(i = -l; i <= l; i++) { + x = i + plr[pnum].WorldX; + if(ItemSpaceOk(x, y)) { + RespawnDeadItem(itm, x, y); + plr[pnum].HoldItem = *itm; + NetSendCmdPItem(FALSE, CMD_RESPAWNITEM, x, y); + return; + } + } + } + } + } +} + +void DropHalfPlayersGold(int pnum) +{ + int v1; // ebx + int v2; // esi + int v3; // edi + int v4; // ecx + int v5; // eax + int v6; // ecx + int v7; // eax + int v8; // edx + int v9; // ecx + int v10; // eax + int v11; // edx + int v12; // ecx + int v13; // eax + int v14; // [esp+Ch] [ebp-8h] + int v15; // [esp+Ch] [ebp-8h] + int v16; // [esp+Ch] [ebp-8h] + int v17; // [esp+Ch] [ebp-8h] + signed int i; // [esp+10h] [ebp-4h] + signed int ia; // [esp+10h] [ebp-4h] + signed int ib; // [esp+10h] [ebp-4h] + signed int ic; // [esp+10h] [ebp-4h] + + v1 = pnum; + if ( (unsigned int)pnum >= MAX_PLRS ) + app_fatal("DropHalfPlayersGold: illegal player %d", pnum); + v2 = v1; + v3 = plr[v1]._pGold >> 1; + i = 0; + while ( v3 > 0 ) + { + v4 = 368 * i + v2 * 21720; + v14 = v4; + if ( *(int *)((char *)&plr[0].SpdList[0]._itype + v4) == ITYPE_GOLD ) + { + v5 = *(int *)((char *)&plr[0].SpdList[0]._ivalue + v4); + if ( v5 != 5000 ) + { + if ( v3 >= v5 ) + { + v3 -= v5; + RemoveSpdBarItem(v1, i); + SetPlrHandItem(&plr[v2].HoldItem, IDI_GOLD); + GetGoldSeed(v1, &plr[v2].HoldItem); + SetPlrHandGoldCurs(&plr[v2].HoldItem); + plr[v2].HoldItem._ivalue = *(int *)((char *)&plr[0].SpdList[0]._ivalue + v14); + PlrDeadItem(v1, &plr[v2].HoldItem, 0, 0); + i = -1; + } + else + { + *(int *)((char *)&plr[0].SpdList[0]._ivalue + v4) = v5 - v3; + SetSpdbarGoldCurs(v1, i); + SetPlrHandItem(&plr[v2].HoldItem, IDI_GOLD); + GetGoldSeed(v1, &plr[v2].HoldItem); + SetPlrHandGoldCurs(&plr[v2].HoldItem); + plr[v2].HoldItem._ivalue = v3; + v3 = 0; + PlrDeadItem(v1, &plr[v2].HoldItem, 0, 0); + } + } + } + if ( ++i >= 8 ) + { + if ( v3 > 0 ) + { + ia = 0; + do + { + if ( v3 <= 0 ) + break; + v6 = 368 * ia + v2 * 21720; + v15 = v6; + if ( *(int *)((char *)&plr[0].SpdList[0]._itype + v6) == ITYPE_GOLD ) + { + v7 = *(int *)((char *)&plr[0].SpdList[0]._ivalue + v6); + if ( v3 >= v7 ) + { + v3 -= v7; + RemoveSpdBarItem(v1, ia); + SetPlrHandItem(&plr[v2].HoldItem, IDI_GOLD); + GetGoldSeed(v1, &plr[v2].HoldItem); + SetPlrHandGoldCurs(&plr[v2].HoldItem); + plr[v2].HoldItem._ivalue = *(int *)((char *)&plr[0].SpdList[0]._ivalue + v15); + PlrDeadItem(v1, &plr[v2].HoldItem, 0, 0); + ia = -1; + } + else + { + *(int *)((char *)&plr[0].SpdList[0]._ivalue + v6) = v7 - v3; + SetSpdbarGoldCurs(v1, ia); + SetPlrHandItem(&plr[v2].HoldItem, IDI_GOLD); + GetGoldSeed(v1, &plr[v2].HoldItem); + SetPlrHandGoldCurs(&plr[v2].HoldItem); + plr[v2].HoldItem._ivalue = v3; + v3 = 0; + PlrDeadItem(v1, &plr[v2].HoldItem, 0, 0); + } + } + ++ia; + } + while ( ia < 8 ); + } + break; + } + } + v8 = 0; + force_redraw = 255; + if ( v3 > 0 ) + { + ib = 0; + if ( plr[v2]._pNumInv <= 0 ) + { +LABEL_28: + if ( v3 > 0 ) + { + v11 = 0; + for ( ic = 0; ic < plr[v2]._pNumInv; v11 = ic++ + 1 ) + { + if ( v3 <= 0 ) + break; + v12 = 368 * v11 + v2 * 21720; + v17 = v12; + if ( *(int *)((char *)&plr[0].InvList[0]._itype + v12) == ITYPE_GOLD ) + { + v13 = *(int *)((char *)&plr[0].InvList[0]._ivalue + v12); + if ( v3 >= v13 ) + { + v3 -= v13; + RemoveInvItem(v1, v11); + SetPlrHandItem(&plr[v2].HoldItem, IDI_GOLD); + GetGoldSeed(v1, &plr[v2].HoldItem); + SetPlrHandGoldCurs(&plr[v2].HoldItem); + plr[v2].HoldItem._ivalue = *(int *)((char *)&plr[0].InvList[0]._ivalue + v17); + PlrDeadItem(v1, &plr[v2].HoldItem, 0, 0); + ic = -1; + } + else + { + *(int *)((char *)&plr[0].InvList[0]._ivalue + v12) = v13 - v3; + SetGoldCurs(v1, v11); + SetPlrHandItem(&plr[v2].HoldItem, IDI_GOLD); + GetGoldSeed(v1, &plr[v2].HoldItem); + SetPlrHandGoldCurs(&plr[v2].HoldItem); + plr[v2].HoldItem._ivalue = v3; + v3 = 0; + PlrDeadItem(v1, &plr[v2].HoldItem, 0, 0); + } + } + } + } + } + else + { + while ( v3 > 0 ) + { + v9 = 368 * v8 + v2 * 21720; + v16 = v9; + if ( *(int *)((char *)&plr[0].InvList[0]._itype + v9) == ITYPE_GOLD ) + { + v10 = *(int *)((char *)&plr[0].InvList[0]._ivalue + v9); + if ( v10 != 5000 ) + { + if ( v3 >= v10 ) + { + v3 -= v10; + RemoveInvItem(v1, v8); + SetPlrHandItem(&plr[v2].HoldItem, IDI_GOLD); + GetGoldSeed(v1, &plr[v2].HoldItem); + SetPlrHandGoldCurs(&plr[v2].HoldItem); + plr[v2].HoldItem._ivalue = *(int *)((char *)&plr[0].InvList[0]._ivalue + v16); + PlrDeadItem(v1, &plr[v2].HoldItem, 0, 0); + ib = -1; + } + else + { + *(int *)((char *)&plr[0].InvList[0]._ivalue + v9) = v10 - v3; + SetGoldCurs(v1, v8); + SetPlrHandItem(&plr[v2].HoldItem, IDI_GOLD); + GetGoldSeed(v1, &plr[v2].HoldItem); + SetPlrHandGoldCurs(&plr[v2].HoldItem); + plr[v2].HoldItem._ivalue = v3; + v3 = 0; + PlrDeadItem(v1, &plr[v2].HoldItem, 0, 0); + } + } + } + v8 = ib++ + 1; + if ( ib >= plr[v2]._pNumInv ) + goto LABEL_28; + } + } + } + plr[v2]._pGold = CalculateGold(v1); +} + +void SyncPlrKill(int pnum, int earflag) +{ + int i, mx; + + if(plr[pnum]._pHitPoints == 0 && currlevel == 0) { + SetPlayerHitPoints(pnum, 64); + return; + } + + for(i = 0; i < nummissiles; i++) { + mx = missileactive[i]; + if(missile[mx]._mitype == MIS_MANASHIELD && missile[mx]._misource == pnum && !missile[mx]._miDelFlag) { + if(earflag != -1) { + missile[mx]._miVar8 = earflag; + } + return; + } + } + + SetPlayerHitPoints(pnum, 0); + StartPlayerKill(pnum, earflag); +} + +void RemovePlrMissiles(int pnum) +{ + int i, mx; + + if(currlevel != 0 && pnum == myplr && (monster[myplr]._mx != 1 || monster[myplr]._my != 0)) { + M_StartKill(myplr, myplr); + AddDead(monster[myplr]._mx, monster[myplr]._my, monster[myplr].MType->mdeadval, monster[myplr]._mdir); + dMonster[monster[myplr]._mx][monster[myplr]._my] = 0; + monster[myplr]._mDelFlag = 1; + DeleteMonsterList(); + } + for(i = 0; i < nummissiles; i++) { + mx = missileactive[i]; + if(missile[mx]._mitype == MIS_STONE && missile[mx]._misource == pnum) { + monster[missile[mx]._miVar2]._mmode = missile[mx]._miVar1; + } + if(missile[mx]._mitype == MIS_MANASHIELD && missile[mx]._misource == pnum) { + ClearMissileSpot(mx); + DeleteMissile(mx, i); + } + if(missile[mx]._mitype == MIS_ETHEREALIZE && missile[mx]._misource == pnum) { + ClearMissileSpot(mx); + DeleteMissile(mx, i); + } + } +} + +void InitLevelChange(int pnum) +{ + RemovePlrMissiles(pnum); + + if(pnum == myplr && qtextflag) { + qtextflag = 0; + stream_stop(); + } + + RemovePlrFromMap(pnum); + SetPlayerOld(pnum); + + if(pnum == myplr) { + dPlayer[plr[myplr].WorldX][plr[myplr].WorldY] = myplr + 1; + } else { + plr[pnum]._pLvlVisited[plr[pnum].plrlevel] = 1; + } + + ClrPlrPath(pnum); + plr[pnum].destAction = -1; + plr[pnum]._pLvlChanging = 1; + + if(pnum == myplr) { + plr[pnum].pLvlLoad = 10; + } +} + +void StartNewLvl(int pnum, int fom, int lvl) +{ + InitLevelChange(pnum); + + if((DWORD)pnum >= MAX_PLRS) { + app_fatal("StartNewLvl: illegal player %d", pnum); + } + + switch(fom) { + case WM_DIABNEXTLVL: + case WM_DIABPREVLVL: + case WM_DIABTOWNWARP: + plr[pnum].plrlevel = lvl; + break; + case WM_DIABTWARPUP: + plr[myplr].pTownWarps |= 1 << (leveltype - 2); + plr[pnum].plrlevel = lvl; + break; + case WM_DIABRETOWN: + break; + case WM_DIABRTNLVL: + /// ASSERT: assert(gbMaxPlayers == 1); + plr[pnum].plrlevel = lvl; + break; + case WM_DIABSETLVL: + setlvlnum = lvl; + /// ASSERT: assert(gbMaxPlayers == 1); + break; + default: + app_fatal("StartNewLvl"); + break; + } + + if(pnum == myplr) { + plr[pnum]._pmode = PM_NEWLVL; + plr[pnum]._pInvincible = 1; + PostMessage(ghMainWnd, fom, 0, 0); + if(gbMaxPlayers > 1) { + NetSendCmdParam2(TRUE, CMD_NEWLVL, fom, lvl); + } + } +} + +void RestartTownLvl(int pnum) +{ + InitLevelChange(pnum); + + if((DWORD)pnum >= MAX_PLRS) { + app_fatal("RestartTownLvl: illegal player %d", pnum); + } + + plr[pnum].plrlevel = 0; + plr[pnum]._pInvincible = 0; + SetPlayerHitPoints(pnum, 64); + plr[pnum]._pMana = 0; + plr[pnum]._pManaBase = plr[pnum]._pMaxManaBase - plr[pnum]._pMaxMana; + CalcPlrInv(pnum, FALSE); + + if(pnum == myplr) { + plr[pnum]._pmode = PM_NEWLVL; + plr[pnum]._pInvincible = 1; + PostMessage(ghMainWnd, WM_DIABRETOWN, 0, 0); + } +} + +void StartWarpLvl(int pnum, int pidx) +{ + InitLevelChange(pnum); + + if(gbMaxPlayers != 1) { + if(plr[pnum].plrlevel != 0) { + plr[pnum].plrlevel = 0; + } else { + plr[pnum].plrlevel = portal[pidx].level; + } + } + if(pnum == myplr) { + SetCurrentPortal(pidx); + plr[pnum]._pmode = PM_NEWLVL; + plr[pnum]._pInvincible = 1; + PostMessage(ghMainWnd, WM_DIABWARPLVL, 0, 0); + } +} + +int PM_DoStand(int pnum) +{ + return FALSE; +} + +int PM_DoWalk(int pnum) +{ + int l; + BOOL rv; + + if((DWORD)pnum >= MAX_PLRS) { + app_fatal("PM_DoWalk: illegal player %d", pnum); + } + + if(plr[pnum]._pAnimFrame == 3 + || plr[pnum]._pWFrames == 8 && plr[pnum]._pAnimFrame == 7 + || plr[pnum]._pWFrames != 8 && plr[pnum]._pAnimFrame == 4) { + PlaySfxLoc(PS_WALK1, plr[pnum].WorldX, plr[pnum].WorldY); + } + + l = 8; + if(currlevel != 0) { + l = WalkAnimTbl[plr[pnum]._pClass]; + } + if(plr[pnum]._pVar8 == l) { + dPlayer[plr[pnum].WorldX][plr[pnum].WorldY] = 0; + plr[pnum].WorldX += plr[pnum]._pVar1; + plr[pnum].WorldY += plr[pnum]._pVar2; + dPlayer[plr[pnum].WorldX][plr[pnum].WorldY] = pnum + 1; + if(leveltype != DTYPE_TOWN) { + ChangeLightXY(plr[pnum]._plid, plr[pnum].WorldX, plr[pnum].WorldY); + ChangeVisionXY(plr[pnum]._pvid, plr[pnum].WorldX, plr[pnum].WorldY); + } + if(pnum == myplr && ScrollInfo._sdir != 0) { + ViewX = plr[pnum].WorldX - ScrollInfo._sdx; + ViewY = plr[pnum].WorldY - ScrollInfo._sdy; + } + if(plr[pnum].walkpath[0] != -1) { + StartWalkStand(pnum); + } else { + StartStand(pnum, plr[pnum]._pVar3); + } + ClearPlrPVars(pnum); + if(leveltype != DTYPE_TOWN) { + ChangeLightOff(plr[pnum]._plid, 0, 0); + } + rv = TRUE; + } else { + PM_ChangeOffset(pnum); + rv = FALSE; + } + + return rv; +} + +int PM_DoWalk2(int pnum) +{ + int l; + BOOL rv; + + if((DWORD)pnum >= MAX_PLRS) { + app_fatal("PM_DoWalk2: illegal player %d", pnum); + } + + if(plr[pnum]._pAnimFrame == 3 + || plr[pnum]._pWFrames == 8 && plr[pnum]._pAnimFrame == 7 + || plr[pnum]._pWFrames != 8 && plr[pnum]._pAnimFrame == 4) { + PlaySfxLoc(PS_WALK1, plr[pnum].WorldX, plr[pnum].WorldY); + } + + l = 8; + if(currlevel != 0) { + l = WalkAnimTbl[plr[pnum]._pClass]; + } + if(plr[pnum]._pVar8 == l) { + dPlayer[plr[pnum]._pVar1][plr[pnum]._pVar2] = 0; + if(leveltype != DTYPE_TOWN) { + ChangeLightXY(plr[pnum]._plid, plr[pnum].WorldX, plr[pnum].WorldY); + ChangeVisionXY(plr[pnum]._pvid, plr[pnum].WorldX, plr[pnum].WorldY); + } + if(pnum == myplr && ScrollInfo._sdir != 0) { + ViewX = plr[pnum].WorldX - ScrollInfo._sdx; + ViewY = plr[pnum].WorldY - ScrollInfo._sdy; + } + if(plr[pnum].walkpath[0] != -1) { + StartWalkStand(pnum); + } else { + StartStand(pnum, plr[pnum]._pVar3); + } + ClearPlrPVars(pnum); + if(leveltype != DTYPE_TOWN) { + ChangeLightOff(plr[pnum]._plid, 0, 0); + } + rv = TRUE; + } else { + PM_ChangeOffset(pnum); + rv = FALSE; + } + + return rv; +} + +int PM_DoWalk3(int pnum) +{ + int l; + BOOL rv; + + if((DWORD)pnum >= MAX_PLRS) { + app_fatal("PM_DoWalk3: illegal player %d", pnum); + } + + if(plr[pnum]._pAnimFrame == 3 + || plr[pnum]._pWFrames == 8 && plr[pnum]._pAnimFrame == 7 + || plr[pnum]._pWFrames != 8 && plr[pnum]._pAnimFrame == 4) { + PlaySfxLoc(PS_WALK1, plr[pnum].WorldX, plr[pnum].WorldY); + } + + l = 8; + if(currlevel != 0) { + l = WalkAnimTbl[plr[pnum]._pClass]; + } + if(plr[pnum]._pVar8 == l) { + dPlayer[plr[pnum].WorldX][plr[pnum].WorldY] = 0; + dFlags[plr[pnum]._pVar4][plr[pnum]._pVar5] &= ~0x20; + plr[pnum].WorldX = plr[pnum]._pVar1; + plr[pnum].WorldY = plr[pnum]._pVar2; + dPlayer[plr[pnum].WorldX][plr[pnum].WorldY] = pnum + 1; + if(leveltype != DTYPE_TOWN) { + ChangeLightXY(plr[pnum]._plid, plr[pnum].WorldX, plr[pnum].WorldY); + ChangeVisionXY(plr[pnum]._pvid, plr[pnum].WorldX, plr[pnum].WorldY); + } + if(pnum == myplr && ScrollInfo._sdir != 0) { + ViewX = plr[pnum].WorldX - ScrollInfo._sdx; + ViewY = plr[pnum].WorldY - ScrollInfo._sdy; + } + if(plr[pnum].walkpath[0] != -1) { + StartWalkStand(pnum); + } else { + StartStand(pnum, plr[pnum]._pVar3); + } + ClearPlrPVars(pnum); + if(leveltype != DTYPE_TOWN) { + ChangeLightOff(plr[pnum]._plid, 0, 0); + } + rv = TRUE; + } else { + PM_ChangeOffset(pnum); + rv = FALSE; + } + + return rv; +} + +BOOL WeaponDur(int pnum, int durrnd) +{ + if(pnum != myplr) { + return FALSE; + } + if(random(3, durrnd) != 0) { + return FALSE; + } + + if((DWORD)pnum >= MAX_PLRS) { + app_fatal("WeaponDur: illegal player %d", pnum); + } + + if(plr[pnum].InvBody[4]._itype != -1 && plr[pnum].InvBody[4]._iClass == ICLASS_WEAPON) { + if(plr[pnum].InvBody[4]._iDurability == 255) { + return FALSE; + } + plr[pnum].InvBody[4]._iDurability--; + if(plr[pnum].InvBody[4]._iDurability == 0) { + NetSendCmdDelItem(TRUE, 4); + plr[pnum].InvBody[4]._itype = -1; + CalcPlrInv(pnum, TRUE); + return TRUE; + } + } + if(plr[pnum].InvBody[5]._itype != -1 && plr[pnum].InvBody[5]._iClass == ICLASS_WEAPON) { + if(plr[pnum].InvBody[5]._iDurability == 255) { + return FALSE; + } + plr[pnum].InvBody[5]._iDurability--; + if(plr[pnum].InvBody[5]._iDurability == 0) { + NetSendCmdDelItem(TRUE, 5); + plr[pnum].InvBody[5]._itype = -1; + CalcPlrInv(pnum, TRUE); + return TRUE; + } + } + if(plr[pnum].InvBody[4]._itype == -1 && plr[pnum].InvBody[5]._itype == ITYPE_SHIELD) { + if(plr[pnum].InvBody[5]._iDurability == 255) { + return FALSE; + } + plr[pnum].InvBody[5]._iDurability--; + if(plr[pnum].InvBody[5]._iDurability == 0) { + NetSendCmdDelItem(TRUE, 5); + plr[pnum].InvBody[5]._itype = -1; + CalcPlrInv(pnum, TRUE); + return TRUE; + } + } + if(plr[pnum].InvBody[5]._itype == -1 && plr[pnum].InvBody[4]._itype == ITYPE_SHIELD) { + if(plr[pnum].InvBody[4]._iDurability == 255) { + return FALSE; + } + plr[pnum].InvBody[4]._iDurability--; + if(plr[pnum].InvBody[4]._iDurability == 0) { + NetSendCmdDelItem(TRUE, 4); + plr[pnum].InvBody[4]._itype = -1; + CalcPlrInv(pnum, TRUE); + return TRUE; + } + } + + return FALSE; +} + +BOOL PlrHitMonst(int pnum, int m) +{ + int v2; // ebx + unsigned int v3; // esi + //int v4; // ST04_4 + int v5; // ebx + //int v7; // ST04_4 + int v8; // eax + unsigned int v9; // esi + int v10; // ecx + int v11; // eax + int v12; // edi + int v13; // edi + //int v14; // eax + int v16; // edx + int v17; // eax + int v18; // ecx + int v19; // edi + int v20; // eax + int v21; // eax + char v22; // dl + _bool v23; // zf + int v24; // eax + int v25; // ecx + int v26; // edi + int v27; // eax + int v28; // edx + int *v29; // ecx + int v30; // edx + int *v31; // ecx + int v32; // ecx + int v33; // edx + int *v34; // ecx + int v35; // edx + int *v36; // ecx + int v37; // edx + int *v38; // ecx + int *v39; // ecx + int v40; // esi + BOOL ret; // [esp+Ch] [ebp-18h] + _bool v42; // [esp+10h] [ebp-14h] + int v48; + int v43; // [esp+14h] [ebp-10h] + int pnuma; // [esp+18h] [ebp-Ch] + int arglist; // [esp+1Ch] [ebp-8h] + int v46; // [esp+20h] [ebp-4h] + + v2 = m; + v3 = pnum; + arglist = m; + pnuma = pnum; + if ( (unsigned int)m >= 0xC8 ) + { + app_fatal("PlrHitMonst: illegal monster %d", m); + //pnum = v4; + } + v5 = 228 * v2; + v43 = v5; + if ( (signed int)(*(int *)((_BYTE *)&monster[0]._mhitpoints + v5) & 0xFFFFFFC0) <= 0 + || **(_BYTE **)((char *)&monster[0].MType + v5) == MT_ILLWEAV && *((_BYTE *)&monster[0]._mgoal + v5) == 2 + || *(MON_MODE *)((char *)&monster[0]._mmode + v5) == MM_CHARGE ) + { + return 0; + } + if ( v3 >= 4 ) + { + app_fatal("PlrHitMonst: illegal player %d", v3); + //pnum = v7; + } + v42 = 0; + v8 = random(4, 100); + v23 = *(MON_MODE *)((char *)&monster[0]._mmode + v5) == MM_STONE; + v46 = v8; + if ( v23 ) + v46 = 0; + v9 = v3; + v10 = plr[v9]._pLevel; + v11 = plr[v9]._pIEnAc + (plr[v9]._pDexterity >> 1) - *((unsigned char *)&monster[0].mArmorClass + v5); + v12 = v11 + v10 + 50; + if ( !_LOBYTE(plr[v9]._pClass) ) + v12 = v11 + v10 + 70; + v13 = plr[v9]._pIBonusToHit + v12; + if ( v13 < 5 ) + v13 = 5; + if ( v13 > 95 ) + v13 = 95; + if ( CheckMonsterHit(arglist, ret) ) + return ret; +#ifdef _DEBUG + if ( (signed int)v46 < v13 || debug_mode_key_inverted_v || debug_mode_dollar_sign ) +#else + if ( (signed int)v46 < v13 ) +#endif + { + v16 = plr[v9]._pIMaxDam - plr[v9]._pIMinDam + 1; + v48 = plr[v9]._pIMinDam; + v17 = random(5, v16); + v18 = 100; + v19 = plr[v9]._pIBonusDamMod + plr[v9]._pDamageMod + (v48 + v17) * plr[v9]._pIBonusDam / 100 + v48 + v17; + if ( !_LOBYTE(plr[v9]._pClass) ) + { + v48 = plr[v9]._pLevel; + v20 = random(6, 100); + if ( v20 < v48 ) + v19 *= 2; + } + v21 = plr[v9].InvBody[4]._itype; + v46 = -1; + if ( v21 == 1 || plr[v9].InvBody[5]._itype == 1 ) + v46 = 1; + if ( v21 == ITYPE_MACE || plr[v9].InvBody[5]._itype == ITYPE_MACE ) + v46 = ITYPE_MACE; + v22 = (*(MonsterData **)((char *)&monster[0].MData + v5))->mMonstClass; + if ( v22 ) + { + if ( v22 != 2 ) + goto LABEL_40; + if ( v46 == ITYPE_MACE ) + v19 -= v19 >> 1; + v23 = v46 == 1; + } + else + { + if ( v46 == 1 ) + v19 -= v19 >> 1; + v23 = v46 == ITYPE_MACE; + } + if ( v23 ) + v19 += v19 >> 1; +LABEL_40: + v24 = plr[v9]._pIFlags; + if ( v24 & 0x40000000 && v22 == 1 ) + v19 *= 3; + v25 = pnuma; + v26 = v19 << 6; + if ( pnuma == myplr ) + *(int *)((char *)&monster[0]._mhitpoints + v5) -= v26; + if ( v24 & 2 ) + { + v27 = random(7, v26 >> 3); + v28 = plr[v9]._pMaxHP; + v29 = &plr[v9]._pHitPoints; + *v29 += v27; + if ( plr[v9]._pHitPoints > v28 ) + *v29 = v28; + v30 = plr[v9]._pMaxHPBase; + v31 = &plr[v9]._pHPBase; + *v31 += v27; + if ( plr[v9]._pHPBase > v30 ) + *v31 = v30; + v5 = v43; + drawhpflag = 1; + } + else + { + v27 = ret; + } + v46 = plr[v9]._pIFlags; + v32 = v46; + if ( v32 & 0x6000 && !(v46 & 0x8000000) ) + { + if ( v32 & 0x2000 ) + v27 = 3 * v26 / 100; + if ( v32 & 0x4000 ) + v27 = 5 * v26 / 100; + v33 = plr[v9]._pMaxMana; + v34 = &plr[v9]._pMana; + *v34 += v27; + if ( plr[v9]._pMana > v33 ) + *v34 = v33; + v35 = plr[v9]._pMaxManaBase; + v36 = &plr[v9]._pManaBase; + *v36 += v27; + if ( plr[v9]._pManaBase > v35 ) + *v36 = v35; + v5 = v43; + v32 = v46; + drawmanaflag = 1; + } + if ( v32 & 0x18000 ) + { + if ( (v32 & 0x8000) != 0 ) + v27 = 3 * v26 / 100; + if ( v32 & 0x10000 ) + v27 = 5 * v26 / 100; + v37 = plr[v9]._pMaxHP; + v38 = &plr[v9]._pHitPoints; + *v38 += v27; + if ( plr[v9]._pHitPoints > v37 ) + *v38 = v37; + v39 = &plr[v9]._pHPBase; + v40 = plr[v9]._pMaxHPBase; + *v39 += v27; + if ( *v39 > v40 ) + *v39 = v40; + BYTE1(v32) = BYTE1(v46); + v5 = v43; + drawhpflag = 1; + } + if ( v32 & 0x100 ) + *(int *)((char *)&monster[0]._mFlags + v5) |= 8u; +#ifdef _DEBUG + if ( debug_mode_dollar_sign || debug_mode_key_inverted_v ) + monster[m]._mhitpoints = 0; /* double check */ +#endif + if ( (signed int)(*(int *)((_BYTE *)&monster[0]._mhitpoints + v5) & 0xFFFFFFC0) > 0 ) + { + if ( *(MON_MODE *)((char *)&monster[0]._mmode + v5) != MM_STONE ) + { + if ( v32 & 0x800 ) + M_GetKnockback(arglist); + M_StartHit(arglist, pnuma, v26); + goto LABEL_85; + } + M_StartHit(arglist, pnuma, v26); + } + else + { + if ( *(MON_MODE *)((char *)&monster[0]._mmode + v5) != MM_STONE ) + { + M_StartKill(arglist, pnuma); + goto LABEL_85; + } + M_StartKill(arglist, pnuma); + } + *(MON_MODE *)((char *)&monster[0]._mmode + v5) = MM_STONE; +LABEL_85: + v42 = 1; + } + return v42; +} + +BOOL PlrHitPlr(int pnum, char p) +{ + char v2; // bl + unsigned int v3; // esi + //int v4; // ST04_4 + int v5; // edi + //int v7; // ST04_4 + unsigned int v8; // esi + int v9; // ecx + int v10; // eax + int v11; // ebx + int v12; // ebx + int v13; // eax + int v14; // eax + int v15; // ecx + int v16; // eax + int v17; // ebx + int v18; // eax + int v19; // ecx + int v20; // edi + int v21; // ebx + signed int v22; // edi + int v23; // eax + int v24; // edx + int *v25; // ecx + int *v26; // ecx + int v27; // esi + int v28; // [esp+Ch] [ebp-14h] + int v29; // [esp+10h] [ebp-10h] + BOOL v30; // [esp+14h] [ebp-Ch] + int arglist; // [esp+18h] [ebp-8h] + char bPlr; // [esp+1Ch] [ebp-4h] + + v2 = p; + v3 = pnum; + bPlr = p; + v28 = pnum; + if ( (unsigned char)p >= 4u ) + { + app_fatal("PlrHitPlr: illegal target player %d", p); + //pnum = v4; + } + arglist = v2; + v5 = v2; + v30 = 0; + if ( plr[v5]._pInvincible || plr[v5]._pSpellFlags & 1 ) + return 0; + if ( v3 >= 4 ) + { + app_fatal("PlrHitPlr: illegal attacking player %d", v3); + //pnum = v7; + } + v8 = v3; + v29 = random(4, 100); + v9 = (plr[v8]._pDexterity >> 1) - plr[v5]._pIBonusAC - plr[v5]._pIAC - plr[v5]._pDexterity / 5; + v10 = plr[v8]._pLevel; + v11 = v9 + v10 + 50; + if ( !_LOBYTE(plr[v8]._pClass) ) + v11 = v9 + v10 + 70; + v12 = plr[v8]._pIBonusToHit + v11; + if ( v12 < 5 ) + v12 = 5; + if ( v12 > 95 ) + v12 = 95; + v13 = plr[v5]._pmode; + if ( v13 && v13 != 4 || !plr[v5]._pBlockFlag ) + { + v14 = 100; + } + else + { + v14 = random(5, 100); + } + v15 = plr[v5]._pDexterity + plr[v5]._pBaseToBlk + 2 * plr[v5]._pLevel - 2 * plr[v8]._pLevel; + if ( v15 < 0 ) + v15 = 0; + if ( v15 > 100 ) + v15 = 100; + if ( v29 < v12 ) + { + if ( v14 >= v15 ) + { + v17 = plr[v8]._pIMinDam; + v18 = random(5, plr[v8]._pIMaxDam - v17 + 1); + v19 = 100; + v20 = plr[v8]._pIBonusDamMod + plr[v8]._pDamageMod + (v17 + v18) * plr[v8]._pIBonusDam / 100 + v17 + v18; + if ( !_LOBYTE(plr[v8]._pClass) ) + { + v21 = plr[v8]._pLevel; + if ( random(6, 100) < v21 ) + v20 *= 2; + } + v22 = v20 << 6; + if ( plr[v8]._pIFlags & 2 ) + { + v23 = random(7, v22 >> 3); + v24 = plr[v8]._pMaxHP; + v25 = &plr[v8]._pHitPoints; + *v25 += v23; + if ( plr[v8]._pHitPoints > v24 ) + *v25 = v24; + v26 = &plr[v8]._pHPBase; + v27 = plr[v8]._pMaxHPBase; + *v26 += v23; + if ( *v26 > v27 ) + *v26 = v27; + drawhpflag = 1; + } + if ( v28 == myplr ) + NetSendCmdDamage(1u, bPlr, v22); + StartPlrHit(arglist, v22, 0); + } + else + { + v16 = GetDirection(plr[v5].WorldX, plr[v5].WorldY, plr[v8].WorldX, plr[v8].WorldY); + StartPlrBlock(arglist, v16); + } + v30 = 1; + } + return v30; +} + +BOOL PlrHitObj(int pnum, int mx, int my) +{ + int oi; // edx + + if ( dObject[mx][my] <= 0 ) + oi = -1 - dObject[mx][my]; + else + oi = dObject[mx][my] - 1; + + if ( object[oi]._oBreak != 1 ) + return 0; + + BreakObject(pnum, oi); + return 1; +} + +int PM_DoAttack(int pnum) +{ + int dx, dy, m, frame; + char p; + BOOL didhit; + + if((DWORD)pnum >= MAX_PLRS) { + app_fatal("PM_DoAttack: illegal player %d", pnum); + } + + frame = plr[pnum]._pAnimFrame; + if(plr[pnum]._pIFlags & ISPL_QUICKATTACK && frame == 1) { + plr[pnum]._pAnimFrame++; + } + if(plr[pnum]._pIFlags & ISPL_FASTATTACK && (frame == 1 || frame == 3)) { + plr[pnum]._pAnimFrame++; + } + if(plr[pnum]._pIFlags & ISPL_FASTERATTACK && (frame == 1 || frame == 3 || frame == 5)) { + plr[pnum]._pAnimFrame++; + } + if(plr[pnum]._pIFlags & ISPL_FASTESTATTACK && (frame == 1 || frame == 4)) { + plr[pnum]._pAnimFrame += 2; + } + + if(plr[pnum]._pAnimFrame == plr[pnum]._pAFNum - 1) { + PlaySfxLoc(PS_SWING, plr[pnum].WorldX, plr[pnum].WorldY); + } + + if(plr[pnum]._pAnimFrame == plr[pnum]._pAFNum) { + dx = plr[pnum].WorldX + offset_x[plr[pnum]._pdir]; + dy = plr[pnum].WorldY + offset_y[plr[pnum]._pdir]; + if(dMonster[dx][dy] != 0) { + m = dMonster[dx][dy] > 0 ? dMonster[dx][dy] - 1 : -(dMonster[dx][dy] + 1); + if(CanTalkToMonst(m)) { + plr[pnum]._pVar1 = 0; + return FALSE; + } + } + if(plr[pnum]._pIFlags & ISPL_FIREDAM) { + AddMissile(dx, dy, 1, 0, 0, MIS_WEAPEXP, 0, pnum, 0, 0); + } + if(plr[pnum]._pIFlags & ISPL_LIGHTDAM) { + AddMissile(dx, dy, 2, 0, 0, MIS_WEAPEXP, 0, pnum, 0, 0); + } + didhit = FALSE; + if(dMonster[dx][dy] != 0) { + m = dMonster[dx][dy] > 0 ? dMonster[dx][dy] - 1 : -(dMonster[dx][dy] + 1); + didhit = PlrHitMonst(pnum, m); + } else if(dPlayer[dx][dy] != 0 && !FriendlyMode) { + p = dPlayer[dx][dy] > 0 ? dPlayer[dx][dy] - 1 : -(dPlayer[dx][dy] + 1); + didhit = PlrHitPlr(pnum, p); + } else if(dObject[dx][dy] > 0) { + didhit = PlrHitObj(pnum, dx, dy); + } + if(didhit && WeaponDur(pnum, 30)) { + StartStand(pnum, plr[pnum]._pdir); + ClearPlrPVars(pnum); + return TRUE; + } + } + if(plr[pnum]._pAnimFrame == plr[pnum]._pAFrames) { + StartStand(pnum, plr[pnum]._pdir); + ClearPlrPVars(pnum); + return TRUE; + } else { + return FALSE; + } +} + +int PM_DoRangeAttack(int pnum) +{ + int mistype, frame; + + if((DWORD)pnum >= MAX_PLRS) { + app_fatal("PM_DoRangeAttack: illegal player %d", pnum); + } + + frame = plr[pnum]._pAnimFrame; + if(plr[pnum]._pIFlags & ISPL_QUICKATTACK && frame == 1) { + plr[pnum]._pAnimFrame++; + } + if(plr[pnum]._pIFlags & ISPL_FASTATTACK && (frame == 1 || frame == 3)) { + plr[pnum]._pAnimFrame++; + } + + if(plr[pnum]._pAnimFrame == plr[pnum]._pAFNum) { + mistype = MIS_ARROW; + if(plr[pnum]._pIFlags & ISPL_FIRE_ARROWS) { + mistype = MIS_FARROW; + } + if(plr[pnum]._pIFlags & ISPL_LIGHT_ARROWS) { + mistype = MIS_LARROW; + } + AddMissile(plr[pnum].WorldX, plr[pnum].WorldY, plr[pnum]._pVar1, plr[pnum]._pVar2, plr[pnum]._pdir, mistype, 0, pnum, 4, 0); + PlaySfxLoc(PS_BFIRE, plr[pnum].WorldX, plr[pnum].WorldY); + if(WeaponDur(pnum, 40)) { + StartStand(pnum, plr[pnum]._pdir); + ClearPlrPVars(pnum); + return TRUE; + } + } + if(plr[pnum]._pAnimFrame >= plr[pnum]._pAFrames) { + StartStand(pnum, plr[pnum]._pdir); + ClearPlrPVars(pnum); + return TRUE; + } else { + return FALSE; + } +} + +void ShieldDur(int pnum) +{ + if(pnum != myplr) { + return; + } + + if((DWORD)pnum >= MAX_PLRS) { + app_fatal("ShieldDur: illegal player %d", pnum); + } + + if(plr[pnum].InvBody[4]._itype == ITYPE_SHIELD) { + if(plr[pnum].InvBody[4]._iDurability == 255) { + return; + } + plr[pnum].InvBody[4]._iDurability--; + if(plr[pnum].InvBody[4]._iDurability == 0) { + NetSendCmdDelItem(TRUE, 4); + plr[pnum].InvBody[4]._itype = -1; + CalcPlrInv(pnum, TRUE); + } + } + if(plr[pnum].InvBody[5]._itype == ITYPE_SHIELD) { + if(plr[pnum].InvBody[5]._iDurability == 255) { + return; + } + plr[pnum].InvBody[5]._iDurability--; + if(plr[pnum].InvBody[5]._iDurability == 0) { + NetSendCmdDelItem(TRUE, 5); + plr[pnum].InvBody[5]._itype = -1; + CalcPlrInv(pnum, TRUE); + } + } +} + +int PM_DoBlock(int pnum) +{ + if((DWORD)pnum >= MAX_PLRS) { + app_fatal("PM_DoBlock: illegal player %d", pnum); + } + + if(plr[pnum]._pIFlags & ISPL_FASTBLOCK && plr[pnum]._pAnimFrame != 1) { + plr[pnum]._pAnimFrame = plr[pnum]._pBFrames; + } + + if(plr[pnum]._pAnimFrame >= plr[pnum]._pBFrames) { + StartStand(pnum, plr[pnum]._pdir); + ClearPlrPVars(pnum); + if(random(3, 10) == 0) { + ShieldDur(pnum); + } + return TRUE; + } else { + return FALSE; + } +} + +int PM_DoSpell(int pnum) +{ + if((DWORD)pnum >= MAX_PLRS) { + app_fatal("PM_DoSpell: illegal player %d", pnum); + } + + if(plr[pnum]._pVar8 == plr[pnum]._pSFNum) { + CastSpell( + pnum, + plr[pnum]._pSpell, + plr[pnum].WorldX, + plr[pnum].WorldY, + plr[pnum]._pVar1, + plr[pnum]._pVar2, + 0, + plr[pnum]._pVar4); + if(plr[pnum]._pSplFrom == 0) { + if(plr[pnum]._pRSplType == RSPLTYPE_SCROLL && !(plr[pnum]._pScrlSpells64 & (__int64)1 << (plr[pnum]._pRSpell - 1))) { + plr[pnum]._pRSpell = -1; + plr[pnum]._pRSplType = RSPLTYPE_INVALID; + force_redraw = 255; + } + if(plr[pnum]._pRSplType == RSPLTYPE_CHARGES && !(plr[pnum]._pISpells64 & (__int64)1 << (plr[pnum]._pRSpell - 1))) { + plr[pnum]._pRSpell = -1; + plr[pnum]._pRSplType = RSPLTYPE_INVALID; + force_redraw = 255; + } + } + } + + plr[pnum]._pVar8++; + + if(leveltype == DTYPE_TOWN) { + if(plr[pnum]._pVar8 > plr[pnum]._pSFrames) { + StartWalkStand(pnum); + ClearPlrPVars(pnum); + return TRUE; + } else { + return FALSE; + } + } else { + if(plr[pnum]._pAnimFrame == plr[pnum]._pSFrames) { + StartStand(pnum, plr[pnum]._pdir); + ClearPlrPVars(pnum); + return TRUE; + } else { + return FALSE; + } + } +} + +int PM_DoGotHit(int pnum) +{ + int frame; + BOOL rv; + + if((DWORD)pnum >= MAX_PLRS) { + app_fatal("PM_DoGotHit: illegal player %d", pnum); + } + + frame = plr[pnum]._pAnimFrame; + if(plr[pnum]._pIFlags & ISPL_FASTRECOVER && frame == 3) { + plr[pnum]._pAnimFrame++; + } + if(plr[pnum]._pIFlags & ISPL_FASTERRECOVER && (frame == 3 || frame == 5)) { + plr[pnum]._pAnimFrame++; + } + if(plr[pnum]._pIFlags & ISPL_FASTESTRECOVER && (frame == 1 || frame == 3 || frame == 5)) { + plr[pnum]._pAnimFrame++; + } + + if(plr[pnum]._pAnimFrame >= plr[pnum]._pHFrames) { + StartStand(pnum, plr[pnum]._pdir); + ClearPlrPVars(pnum); + if(random(3, 4) != 0) { + ArmorDur(pnum); + } + rv = TRUE; + } else { + rv = FALSE; + } + + return rv; +} + +void ArmorDur(int pnum) +{ + PlayerStruct *p; + int a; + ItemStruct *pi; + + if(pnum != myplr) { + return; + } + + if((DWORD)pnum >= MAX_PLRS) { + app_fatal("ArmorDur: illegal player %d", pnum); + } + + p = &plr[pnum]; + if(p->InvBody[6]._itype == -1 && p->InvBody[0]._itype == -1) { + return; + } + + a = random(8, 3); + if(p->InvBody[6]._itype != -1 && p->InvBody[0]._itype == -1) { + a = 1; + } + if(p->InvBody[6]._itype == -1 && p->InvBody[0]._itype != -1) { + a = 0; + } + + if(a != 0) { + pi = &p->InvBody[6]; + } else { + pi = &p->InvBody[0]; + } + + if(pi->_iDurability != 255) { + pi->_iDurability--; + if(pi->_iDurability == 0) { + if(a != 0) { + NetSendCmdDelItem(TRUE, 6); + } else { + NetSendCmdDelItem(TRUE, 0); + } + pi->_itype = -1; + CalcPlrInv(pnum, TRUE); + } + } +} + +int PM_DoDeath(int pnum) +{ + if((DWORD)pnum >= MAX_PLRS) { + app_fatal("PM_DoDeath: illegal player %d", pnum); + } + + if(plr[pnum]._pVar8 >= 2 * plr[pnum]._pDFrames) { + if(deathdelay > 1 && pnum == myplr) { + deathdelay--; + if(deathdelay == 1) { + deathflag = 1; + if(gbMaxPlayers == 1) { + gamemenu_on(); + } + } + } + plr[pnum]._pAnimDelay = 10000; + plr[pnum]._pAnimFrame = plr[pnum]._pAnimLen; + dFlags[plr[pnum].WorldX][plr[pnum].WorldY] |= 4; + } + if(plr[pnum]._pVar8 < 100) { + plr[pnum]._pVar8++; + } + + return FALSE; +} + +int PM_DoNewLvl(int pnum) +{ + return FALSE; +} + +void CheckNewPath(int pnum) +{ + int v1; // edi + int v2; // ebx + int v3; // eax + int v4; // ecx + _bool v5; // zf + int v6; // eax + int v7; // esi + int v8; // eax + int v9; // edx + int v10; // esi + int v11; // esi + int v12; // eax + int v13; // eax + int v14; // ecx + int v15; // edx + int v16; // eax + int v17; // eax + int v18; // eax + int v19; // ecx + int v20; // eax + int v21; // edi + int v22; // esi + int v23; // ST38_4 + int v24; // eax + int v25; // esi + int v26; // esi + int v27; // ST38_4 + int v28; // eax + int v29; // ecx + int v30; // edx + int v31; // ecx + int *v32; // esi + int *v33; // edi + int v34; // esi + int v35; // eax + int v36; // ecx + int v37; // eax + int v38; // eax + int v39; // eax + int v40; // eax + int v41; // eax + int *v42; // esi + int *v43; // edi + int v44; // eax + int v45; // eax + int v46; // esi + int v47; // esi + int v48; // eax + int v49; // ecx + int v50; // esi + int v51; // eax + int v52; // ecx + int v53; // edi + int v54; // esi + int v55; // ST38_4 + int v56; // eax + int v57; // edi + int v58; // esi + int v59; // ST38_4 + int v60; // eax + int v61; // eax + int v62; // ecx + int v63; // esi + int v64; // ST38_4 + int v65; // eax + int v66; // esi + int v67; // edi + int v68; // eax + int v69; // esi + int v70; // esi + int v71; // eax + int v72; // ecx + int v73; // eax + int v74; // eax + int *v75; // esi + int *v76; // edi + int v77; // eax + int v78; // eax + int v79; // eax + int v80; // eax + int *v81; // esi + int *v82; // edi + int v83; // eax + int v84; // eax + int v85; // eax + int v86; // [esp-18h] [ebp-34h] + int v87; // [esp-10h] [ebp-2Ch] + int v88; // [esp-10h] [ebp-2Ch] + int v89; // [esp-Ch] [ebp-28h] + int v90; // [esp-Ch] [ebp-28h] + int v91; // [esp-8h] [ebp-24h] + int v92; // [esp-8h] [ebp-24h] + int v93; // [esp-8h] [ebp-24h] + int v94; // [esp-4h] [ebp-20h] + int v95; // [esp-4h] [ebp-20h] + int v96; // [esp-4h] [ebp-20h] + signed int v97; // [esp+Ch] [ebp-10h] + int arglist; // [esp+10h] [ebp-Ch] + int arglista; // [esp+10h] [ebp-Ch] + int arglistb; // [esp+10h] [ebp-Ch] + int v101; // [esp+14h] [ebp-8h] + int v102; // [esp+14h] [ebp-8h] + int v103; // [esp+14h] [ebp-8h] + int v104; // [esp+14h] [ebp-8h] + int p; // [esp+18h] [ebp-4h] + + v1 = pnum; + p = pnum; + if ( (unsigned int)pnum >= MAX_PLRS ) + app_fatal("CheckNewPath: illegal player %d", pnum); + v2 = v1; + if ( plr[v1].destAction == 20 ) + MakePlrPath(v1, monster[plr[v2].destParam1]._mfutx, monster[plr[v2].destParam1]._mfuty, 0); + if ( plr[v2].destAction == 21 ) + MakePlrPath(v1, plr[plr[v2].destParam1]._px, plr[plr[v2].destParam1]._py, 0); + if ( plr[v2].walkpath[0] == -1 ) + { + v18 = plr[v2].destAction; + if ( v18 == -1 ) + return; + v19 = plr[v2]._pmode; + if ( v19 == PM_STAND ) + { + switch ( v18 ) + { + case 9: + v20 = GetDirection(plr[v2].WorldX, plr[v2].WorldY, plr[v2].destParam1, plr[v2].destParam2); + goto LABEL_52; + case 10: + v30 = plr[v2].WorldY; + v31 = plr[v2].WorldX; + v32 = &plr[v2].destParam2; + v33 = &plr[v2].destParam1; + goto LABEL_59; + case 12: + v39 = GetDirection(plr[v2].WorldX, plr[v2].WorldY, plr[v2].destParam1, plr[v2].destParam2); + StartSpell(p, v39, plr[v2].destParam1, plr[v2].destParam2); + v40 = plr[v2].destParam3; + goto LABEL_66; + case 13: + v46 = plr[v2].destParam1; + arglista = v46; + v47 = v46; + v102 = abs(plr[v2].WorldX - object[v47]._ox); + v48 = abs(plr[v2].WorldY - object[v47]._oy); + if ( v48 > 1 ) + { + v49 = object[v47]._oy; + if ( dObject[object[v47]._ox][v49-1] == -1 - arglista ) /* dungeon[39][112 * object[v47]._ox + 39 + v49] check */ + v48 = abs(plr[v2].WorldY - v49 + 1); + } + if ( v102 > 1 || v48 > 1 ) + break; + if ( object[v47]._oBreak != 1 ) + goto LABEL_73; + goto LABEL_80; + case 14: + v50 = plr[v2].destParam1; + arglista = v50; + v47 = v50; + v103 = abs(plr[v2].WorldX - object[v47]._ox); + v51 = abs(plr[v2].WorldY - object[v47]._oy); + if ( v51 > 1 ) + { + v52 = object[v47]._oy; + if ( dObject[object[v47]._ox][v52-1] == -1 - arglista ) /* dungeon[39][112 * object[v47]._ox + 39 + v52] check */ + v51 = abs(plr[v2].WorldY - v52 + 1); + } + if ( v103 > 1 || v51 > 1 ) + break; + if ( object[v47]._oBreak == 1 ) + { +LABEL_80: + v20 = GetDirection(plr[v2].WorldX, plr[v2].WorldY, object[v47]._ox, object[v47]._oy); +LABEL_81: + v29 = p; +LABEL_82: + StartAttack(v29, v20); + } + else + { + TryDisarm(p, arglista); +LABEL_73: + OperateObject(p, arglista, 0); + } + break; + case 15: + if ( v1 == myplr ) + { + v53 = plr[v2].destParam1; + v54 = plr[v2].destParam1; + v55 = abs(plr[v2].WorldX - item[v54]._ix); + v56 = abs(plr[v2].WorldY - item[v54]._iy); + if ( v55 <= 1 && v56 <= 1 && pcurs == 1 && !item[v54]._iRequest ) + { + NetSendCmdGItem(1u, CMD_REQUESTGITEM, myplr, myplr, v53); + item[v54]._iRequest = 1; + } + } + break; + case 16: + if ( v1 == myplr ) + { + v57 = plr[v2].destParam1; + v58 = plr[v2].destParam1; + v59 = abs(plr[v2].WorldX - item[v58]._ix); + v60 = abs(plr[v2].WorldY - item[v58]._iy); + if ( v59 <= 1 && v60 <= 1 && pcurs == 1 ) + NetSendCmdGItem(1u, CMD_REQUESTAGITEM, myplr, myplr, v57); + } + break; + case 17: + if ( v1 == myplr ) + TalkToTowner(v1, plr[v2].destParam1); + break; + case 18: + if ( object[plr[v2].destParam1]._oBreak != 1 ) + OperateObject(v1, plr[v2].destParam1, 1u); + break; + case 20: + v21 = plr[v2].destParam1; + v22 = plr[v2].destParam1; + v23 = abs(plr[v2].WorldX - monster[v22]._mfutx); + v24 = abs(plr[v2].WorldY - monster[v22]._mfuty); + if ( v23 > 1 || v24 > 1 ) + break; + v20 = GetDirection(plr[v2]._px, plr[v2]._py, monster[v22]._mfutx, monster[v22]._mfuty); + v25 = monster[v22].mtalkmsg; + if ( v25 && v25 != TEXT_VILE14 ) + goto LABEL_56; + goto LABEL_81; + case 21: + v26 = plr[v2].destParam1; + v27 = abs(plr[v2].WorldX - plr[v26]._px); + v28 = abs(plr[v2].WorldY - plr[v26]._py); + if ( v27 > 1 || v28 > 1 ) + break; + v20 = GetDirection(plr[v2]._px, plr[v2]._py, plr[v26]._px, plr[v26]._py); +LABEL_52: + v29 = v1; + goto LABEL_82; + case 22: + v21 = plr[v2].destParam1; + v34 = plr[v2].destParam1; + v35 = GetDirection(plr[v2]._px, plr[v2]._py, monster[v34]._mfutx, monster[v34]._mfuty); + v36 = monster[v34].mtalkmsg; + if ( v36 && v36 != TEXT_VILE14 ) +LABEL_56: + TalktoMonster(v21); + else + StartRangeAttack(p, v35, monster[v34]._mfutx, monster[v34]._mfuty); + break; + case 23: + v30 = plr[v2]._py; + v37 = plr[v2].destParam1; + v31 = plr[v2]._px; + v32 = &plr[v37]._py; + v33 = &plr[v37]._px; +LABEL_59: + v38 = GetDirection(v31, v30, *v33, *v32); + StartRangeAttack(p, v38, *v33, *v32); + break; + case 24: + v41 = plr[v2].destParam1; + v42 = &monster[v41]._mfuty; + v43 = &monster[v41]._mfutx; + goto LABEL_65; + case 25: + v44 = plr[v2].destParam1; + v42 = &plr[v44]._py; + v43 = &plr[v44]._px; +LABEL_65: + v45 = GetDirection(plr[v2].WorldX, plr[v2].WorldY, *v43, *v42); + StartSpell(p, v45, *v43, *v42); + v40 = plr[v2].destParam2; + goto LABEL_66; + case 26: + StartSpell(v1, plr[v2].destParam3, plr[v2].destParam1, plr[v2].destParam2); + plr[v2]._pVar3 = plr[v2].destParam3; + v40 = plr[v2].destParam4; +LABEL_66: + plr[v2]._pVar4 = v40; + break; + default: + break; + } + FixPlayerLocation(p, plr[v2]._pdir); + goto LABEL_143; + } + if ( v19 == 4 && plr[v2]._pAnimFrame > plr[myplr]._pAFNum ) + { + switch ( v18 ) + { + case 9: + v61 = GetDirection(plr[v2]._px, plr[v2]._py, plr[v2].destParam1, plr[v2].destParam2); +LABEL_105: + v62 = v1; +LABEL_106: + StartAttack(v62, v61); +LABEL_107: + plr[v2].destAction = -1; + break; + case 20: + v63 = plr[v2].destParam1; + v64 = abs(plr[v2].WorldX - monster[v63]._mfutx); + v65 = abs(plr[v2].WorldY - monster[v63]._mfuty); + if ( v64 > 1 || v65 > 1 ) + goto LABEL_107; + v61 = GetDirection(plr[v2]._px, plr[v2]._py, monster[v63]._mfutx, monster[v63]._mfuty); + goto LABEL_105; + case 21: + v66 = plr[v2].destParam1; + v67 = abs(plr[v2].WorldX - plr[v66]._px); + v68 = abs(plr[v2].WorldY - plr[v66]._py); + if ( v67 > 1 || v68 > 1 ) + goto LABEL_107; + v61 = GetDirection(plr[v2]._px, plr[v2]._py, plr[v66]._px, plr[v66]._py); + v62 = p; + goto LABEL_106; + case 13: + v69 = plr[v2].destParam1; + arglistb = v69; + v70 = v69; + v104 = abs(plr[v2].WorldX - object[v70]._ox); + v71 = abs(plr[v2].WorldY - object[v70]._oy); + if ( v71 > 1 ) + { + v72 = object[v70]._oy; + if ( dObject[object[v70]._ox][v72-1] == -1 - arglistb ) /* dungeon[39][112 * object[v70]._ox + 39 + v72] check */ + v71 = abs(plr[v2].WorldY - v72 + 1); + } + if ( v104 <= 1 && v71 <= 1 ) + { + if ( object[v70]._oBreak == 1 ) + { + v73 = GetDirection(plr[v2].WorldX, plr[v2].WorldY, object[v70]._ox, object[v70]._oy); + StartAttack(p, v73); + } + else + { + OperateObject(p, arglistb, 0); + } + } + break; + } + } + if ( plr[v2]._pmode == PM_RATTACK && plr[v2]._pAnimFrame > plr[myplr]._pAFNum ) + { + v74 = plr[v2].destAction; + switch ( v74 ) + { + case 10: + v75 = &plr[v2].destParam2; + v76 = &plr[v2].destParam1; +LABEL_133: + v79 = GetDirection(plr[v2].WorldX, plr[v2].WorldY, *v76, *v75); + StartRangeAttack(p, v79, *v76, *v75); + plr[v2].destAction = -1; + break; + case 22: + v77 = plr[v2].destParam1; + v75 = &monster[v77]._mfuty; + v76 = &monster[v77]._mfutx; + goto LABEL_133; + case 23: + v78 = plr[v2].destParam1; + v75 = &plr[v78]._py; + v76 = &plr[v78]._px; + goto LABEL_133; + } + } + if ( plr[v2]._pmode == PM_SPELL && plr[v2]._pAnimFrame > plr[v2]._pSFNum ) + { + v80 = plr[v2].destAction; + switch ( v80 ) + { + case 12: + v81 = &plr[v2].destParam2; + v82 = &plr[v2].destParam1; + break; + case 24: + v83 = plr[v2].destParam1; + v81 = &monster[v83]._mfuty; + v82 = &monster[v83]._mfutx; + break; + case 25: + v84 = plr[v2].destParam1; + v81 = &plr[v84]._py; + v82 = &plr[v84]._px; + break; + default: + return; + } + v85 = GetDirection(plr[v2].WorldX, plr[v2].WorldY, *v82, *v81); + StartSpell(p, v85, *v82, *v81); + goto LABEL_143; + } + return; + } + if ( plr[v2]._pmode == PM_STAND ) + { + if ( v1 == myplr ) + { + v3 = plr[v2].destAction; + if ( v3 == 20 || v3 == 21 ) + { + v4 = plr[v2].destParam1; + v5 = v3 == 20; + v6 = plr[v2]._px; + arglist = plr[v2].destParam1; + if ( v5 ) + { + v7 = v4; + v101 = abs(v6 - monster[v4]._mfutx); + v8 = abs(plr[v2]._py - monster[v7]._mfuty); + v9 = plr[v2]._py; + v94 = monster[v7]._mfuty; + v91 = monster[v7]._mfutx; + } + else + { + v10 = v4; + v101 = abs(v6 - plr[v4]._px); + v8 = abs(plr[v2]._py - plr[v10]._py); + v9 = plr[v2]._py; + v94 = plr[v10]._py; + v91 = plr[v10]._px; + } + v97 = v8; + v11 = GetDirection(plr[v2]._px, v9, v91, v94); + if ( v101 < 2 && v97 < 2 ) + { + ClrPlrPath(p); + v12 = monster[arglist].mtalkmsg; + if ( v12 && v12 != TEXT_VILE14 ) + TalktoMonster(arglist); + else + StartAttack(p, v11); + plr[v2].destAction = -1; + } + } + } + if ( currlevel ) + { + v13 = SLOBYTE(plr[v2]._pClass); + v14 = PWVel[v13][0]; + v15 = PWVel[v13][1]; + v16 = PWVel[v13][2]; + } + else + { + v14 = 2048; + v15 = 1024; + v16 = 512; + } + switch ( plr[v2].walkpath[0] ) + { + case WALK_NE: + v95 = 2; + v92 = DIR_NE; + v89 = -1; + v87 = 0; + v17 = -v16; + goto LABEL_37; + case WALK_NW: + v95 = 8; + v92 = DIR_NW; + v89 = 0; + v87 = -1; + v17 = -v16; + v15 = -v15; +LABEL_37: + StartWalk(p, v15, v17, v87, v89, v92, v95); + break; + case WALK_SE: + v96 = 4; + v93 = DIR_SE; + v90 = 0; + v88 = 1; + v86 = -32; + goto LABEL_32; + case WALK_SW: + v96 = 6; + v93 = DIR_SW; + v90 = 1; + v88 = 0; + v86 = 32; + v15 = -v15; +LABEL_32: + StartWalk2(p, v15, v16, v86, -16, v88, v90, v93, v96); + break; + case WALK_N: + StartWalk(p, 0, -v15, -1, -1, DIR_N, 1); + break; + case WALK_E: + StartWalk3(p, v14, 0, -32, -16, 1, -1, 1, 0, DIR_E, 3); + break; + case WALK_S: + StartWalk2(p, 0, v15, 0, -32, 1, 1, DIR_S, 5); + break; + case WALK_W: + StartWalk3(p, -v14, 0, 32, -16, -1, 1, 0, 1, DIR_W, 7); + break; + default: + break; + } + qmemcpy(plr[v2].walkpath, &plr[v2].walkpath[1], 0x18u); + plr[v2].walkpath[24] = -1; + if ( plr[v2]._pmode == PM_STAND ) + { + StartStand(p, plr[v2]._pdir); +LABEL_143: + plr[v2].destAction = -1; + return; + } + } +} + +BOOL PlrDeathModeOK(int p) +{ + if(p != myplr) { + return TRUE; + } + + if((DWORD)p >= MAX_PLRS) { + app_fatal("PlrDeathModeOK: illegal player %d", p); + } + + if(plr[p]._pmode == PM_DEATH) { + return TRUE; + } + if(plr[p]._pmode == PM_QUIT) { + return TRUE; + } + if(plr[p]._pmode == PM_NEWLVL) { + return TRUE; + } + + return FALSE; +} + +void ValidatePlayer() +{ + int v0; // edi + int v1; // esi + char *v2; // eax + int v3; // ecx + int v4; // ecx + int *v5; // eax + int v6; // eax + int v7; // edx + int v8; // edx + int v9; // edx + int v10; // eax + int *v11; // ebx + signed int v12; // edi + char *v13; // eax + __int64 v14; // [esp+Ch] [ebp-8h] + + v0 = 0; + v14 = (__int64)0; + if ( (unsigned int)myplr >= 4 ) + app_fatal("ValidatePlayer: illegal player %d", myplr); + v1 = myplr; + v2 = &plr[myplr]._pLevel; + if ( *v2 > 50 ) + *v2 = 50; + v3 = plr[v1]._pNextExper; + if ( plr[v1]._pExperience > v3 ) + plr[v1]._pExperience = v3; + v4 = 0; + if ( plr[v1]._pNumInv > 0 ) + { + v5 = &plr[v1].InvList[0]._ivalue; + do + { + if ( *(v5 - 47) == 11 ) + { + if ( *v5 > 5000 ) + *v5 = 5000; + v4 += *v5; + } + ++v0; + v5 += 92; + } + while ( v0 < plr[v1]._pNumInv ); + } + if ( v4 != plr[v1]._pGold ) + plr[v1]._pGold = v4; + v6 = SLOBYTE(plr[v1]._pClass); + v7 = MaxStats[v6][0]; + if ( plr[v1]._pBaseStr > v7 ) + plr[v1]._pBaseStr = v7; + v8 = MaxStats[v6][1]; + if ( plr[v1]._pBaseMag > v8 ) + plr[v1]._pBaseMag = v8; + v9 = MaxStats[v6][2]; + if ( plr[v1]._pBaseDex > v9 ) + plr[v1]._pBaseDex = v9; + v10 = MaxStats[v6][3]; + if ( plr[v1]._pBaseVit > v10 ) + plr[v1]._pBaseVit = v10; + v11 = &spelldata[1].sBookLvl; + v12 = 1; + do + { + if ( *v11 != -1 ) + { + v14 |= (__int64)1 << ((unsigned char)v12 - 1); + v13 = &plr[v1]._pSplLvl[v12]; + if ( *v13 > 15 ) + *v13 = 15; + } + v11 += 14; + ++v12; + } + while ( (signed int)v11 < (signed int)&spelldata[37].sBookLvl ); + *(_QWORD *)plr[v1]._pMemSpells &= v14; +} + +void ProcessPlayers() +{ + int v0; // eax + int v1; // eax + unsigned char *v2; // ecx + char v3; // al + int v4; // ebp + int *v5; // esi + int v6; // eax + //int v7; // eax + int v8; // eax + int v9; // eax + int v10; // eax + int v11; // edi + int v12; // eax + char *v13; // eax + char *v14; // eax + + v0 = myplr; + if ( (unsigned int)myplr >= 4 ) + { + app_fatal("ProcessPlayers: illegal player %d", myplr); + v0 = myplr; + } + v1 = v0; + v2 = &plr[v1].pLvlLoad; + v3 = plr[v1].pLvlLoad; + if ( v3 ) + *v2 = v3 - 1; + v4 = 0; + if ( sfxdelay > 0 && !--sfxdelay ) + PlaySFX(sfxdnum); + ValidatePlayer(); + v5 = &plr[0]._pHitPoints; + do + { + v6 = (int)(v5 - 89); + if ( *((_BYTE *)v5 - 379) && currlevel == *(_DWORD *)v6 && (v4 == myplr || !*(_BYTE *)(v6 + 267)) ) + { + CheckCheatStats(v4); + //_LOBYTE(v7) = PlrDeathModeOK(v4); + if ( !PlrDeathModeOK(v4) && (signed int)(*v5 & 0xFFFFFFC0) <= 0 ) + SyncPlrKill(v4, -1); + if ( v4 == myplr ) + { + if ( v5[5294] & 0x40 && currlevel ) + { + *v5 -= 4; + v8 = *v5; + *(v5 - 2) -= 4; + if ( (signed int)(v8 & 0xFFFFFFC0) <= 0 ) + SyncPlrKill(v4, 0); + drawhpflag = 1; + } + if ( *((_BYTE *)v5 + 21179) & 8 ) + { + v9 = v5[3]; + if ( v9 > 0 ) + { + v10 = v9 - v5[5]; + v5[5] = 0; + drawmanaflag = 1; + v5[3] = v10; + } + } + } + v11 = 0; + do + { + switch ( *(v5 - 102) ) + { + case PM_STAND: + v12 = PM_DoStand(v4); + goto LABEL_38; + case PM_WALK: + v12 = PM_DoWalk(v4); + goto LABEL_38; + case PM_WALK2: + v12 = PM_DoWalk2(v4); + goto LABEL_38; + case PM_WALK3: + v12 = PM_DoWalk3(v4); + goto LABEL_38; + case PM_ATTACK: + v12 = PM_DoAttack(v4); + goto LABEL_38; + case PM_RATTACK: + v12 = PM_DoRangeAttack(v4); + goto LABEL_38; + case PM_BLOCK: + v12 = PM_DoBlock(v4); + goto LABEL_38; + case PM_GOTHIT: + v12 = PM_DoGotHit(v4); + goto LABEL_38; + case PM_DEATH: + v12 = PM_DoDeath(v4); + goto LABEL_38; + case PM_SPELL: + v12 = PM_DoSpell(v4); + goto LABEL_38; + case PM_NEWLVL: + v12 = PM_DoNewLvl(v4); +LABEL_38: + v11 = v12; + break; + default: + break; + } + CheckNewPath(v4); + } + while ( v11 ); + v13 = (char *)(v5 - 69); + ++*(_DWORD *)v13; + if ( *(v5 - 69) > *(v5 - 70) ) + { + *(_DWORD *)v13 = 0; + v14 = (char *)(v5 - 67); + ++*(_DWORD *)v14; + if ( *(v5 - 67) > *(v5 - 68) ) + *(_DWORD *)v14 = 1; + } + } + v5 += 5430; + ++v4; + } + while ( (signed int)v5 < (signed int)&plr[MAX_PLRS]._pHitPoints ); +} + +void CheckCheatStats(int pnum) +{ + int v1; // ecx + int *v2; // ecx + + v1 = pnum; + if ( plr[v1]._pStrength > 750 ) + plr[v1]._pStrength = 750; + if ( plr[v1]._pDexterity > 750 ) + plr[v1]._pDexterity = 750; + if ( plr[v1]._pMagic > 750 ) + plr[v1]._pMagic = 750; + if ( plr[v1]._pVitality > 750 ) + plr[v1]._pVitality = 750; + if ( plr[v1]._pHitPoints > 128000 ) + plr[v1]._pHitPoints = 128000; + v2 = &plr[v1]._pMana; + if ( *v2 > 128000 ) + *v2 = 128000; +} + +void ClrPlrPath(int pnum) +{ + int v1; // esi + + v1 = pnum; + if ( (unsigned int)pnum >= MAX_PLRS ) + app_fatal("ClrPlrPath: illegal player %d", pnum); + memset(plr[v1].walkpath, -1, 0x19u); +} + +BOOL PosOkPlayer(int pnum, int px, int py) +{ + char v8; // cl + unsigned int v9; // ecx + int v10; // esi + char v11; // al + char v12; // cl + _bool result; // eax + + result = 0; + if ( px >= 0 && px < 112 && py >= 0 && py < 112 && !SolidLoc(px, py) ) + { + if ( dPiece[px][py] ) + { + v8 = dPlayer[px][py]; + if ( !v8 || (v8 <= 0 ? (v9 = -1 - v8) : (v9 = v8 - 1), v9 == pnum || v9 >= 4 || !plr[v9]._pHitPoints) ) + { + v10 = dMonster[px][py]; + if ( !v10 || currlevel && v10 > 0 && (signed int)(monster[v10-1]._mhitpoints & 0xFFFFFFC0) <= 0 ) /* fix */ + { + v11 = dObject[px][py]; + if ( !v11 || (v11 <= 0 ? (v12 = -1 - v11) : (v12 = v11 - 1), !object[v12]._oSolidFlag) ) + result = 1; + } + } + } + } + return result; +} + +void MakePlrPath(int pnum, int xx, int yy, BOOL endspace) +{ + int v4; // esi + int v5; // ebx + int v6; // esi + int v7; // edi + int v8; // eax + int v9; // eax + int v10; // ecx + int a2; // [esp+Ch] [ebp-4h] + + v4 = pnum; + v5 = xx; + a2 = pnum; + if ( (unsigned int)pnum >= MAX_PLRS ) + app_fatal("MakePlrPath: illegal player %d", pnum); + v6 = v4; + v7 = yy; + v8 = plr[v6]._px; + plr[v6]._ptargx = v5; + plr[v6]._ptargy = yy; + if ( v8 != v5 || plr[v6]._py != yy ) + { + v9 = FindPath(PosOkPlayer, a2, v8, plr[v6]._py, v5, yy, plr[v6].walkpath); + if ( v9 ) + { + if ( !endspace ) + { + v10 = plr[v6].walkpath[--v9]; /* *((char *)&plr[v6]._pmode + v9-- + 3) */ + switch ( v10 ) + { + case 1: // N + goto LABEL_12; + case 2: // W + ++v5; + break; + case 3: // E + --v5; + break; + case 4: // S + goto LABEL_15; + case 5: // NW + ++v5; + goto LABEL_12; + case 6: // NE + --v5; +LABEL_12: + v7 = yy + 1; + break; + case 7: // SE + --v5; + goto LABEL_15; + case 8: // SW + ++v5; +LABEL_15: + v7 = yy - 1; + break; + default: // 0/Neutral + break; + } + plr[v6]._ptargx = v5; + plr[v6]._ptargy = v7; + } + plr[v6].walkpath[v9] = -1; + } + } +} + +void CheckPlrSpell() +{ + int v0; // ecx + int v1; // eax + int v2; // edx + char v3; // al + int v4; // ecx + char v5; // al + int v6; // eax + int v7; // edx + int v8; // esi + int v9; // ST10_4 + int v10; // eax + int v11; // eax + int v12; // eax + int v13; // ST10_4 + int v14; // eax + char v15; // al + + v0 = myplr; + if ( (unsigned int)myplr >= 4 ) + { + app_fatal("CheckPlrSpell: illegal player %d", myplr); + v0 = myplr; + } + v1 = 21720 * v0; + v2 = plr[v0]._pRSpell; + if ( v2 != -1 ) + { + if ( leveltype == DTYPE_TOWN && !*(_DWORD *)&spelldata[v2].sTownSpell ) + { + v5 = *((_BYTE *)&plr[0]._pClass + v1); + switch ( v5 ) + { + case UI_WARRIOR: + v4 = PS_WARR27; + goto LABEL_53; + case UI_ROGUE: + v4 = PS_ROGUE27; + goto LABEL_53; + case UI_SORCERER: + v4 = PS_MAGE27; + goto LABEL_53; + } + return; + } + if ( pcurs != CURSOR_HAND + || MouseY >= 352 + || (chrflag && MouseX < 320 || invflag && MouseX > 320) + && v2 != 2 + && v2 != 5 + && v2 != 26 + && v2 != 9 + && v2 != 27 ) + { + return; + } + _LOBYTE(v1) = *((_BYTE *)&plr[0]._pRSplType + v1); + if ( (v1 & 0x80u) != 0 ) + goto LABEL_46; + if ( (char)v1 <= 1 ) + { + v6 = CheckSpell(v0, v2, v1, 0); + } + else + { + if ( (_BYTE)v1 != 2 ) + { + if ( (_BYTE)v1 == 3 ) + { + v6 = UseStaff(); + goto LABEL_36; + } +LABEL_46: + if ( plr[v0]._pRSplType == 1 ) + { + v15 = plr[v0]._pClass; + switch ( v15 ) + { + case UI_WARRIOR: + v4 = PS_WARR35; + goto LABEL_53; + case UI_ROGUE: + v4 = PS_ROGUE35; + goto LABEL_53; + case UI_SORCERER: + v4 = PS_MAGE35; + goto LABEL_53; + } + } + return; + } + v6 = UseScroll(); + } +LABEL_36: + v0 = myplr; + if ( v6 ) + { + v7 = plr[myplr]._pRSpell; + if ( v7 == 6 ) + { + v8 = GetDirection(plr[myplr].WorldX, plr[myplr].WorldY, cursmx, cursmy); + v9 = GetSpellLevel(myplr, plr[myplr]._pRSpell); + v10 = 21720 * myplr; + _LOWORD(v10) = plr[myplr]._pRSpell; + NetSendCmdLocParam3(1u, CMD_SPELLXYD, cursmx, cursmy, v10, v8, v9); + } + else if ( pcursmonst == -1 ) + { + if ( pcursplr == -1 ) + { + v13 = GetSpellLevel(myplr, v7); + v14 = 21720 * myplr; + _LOWORD(v14) = plr[myplr]._pRSpell; + NetSendCmdLocParam2(1u, CMD_SPELLXY, cursmx, cursmy, v14, v13); + } + else + { + v12 = GetSpellLevel(myplr, v7); + NetSendCmdParam3(1u, CMD_SPELLPID, pcursplr, plr[myplr]._pRSpell, v12); + } + } + else + { + v11 = GetSpellLevel(myplr, v7); + NetSendCmdParam3(1u, CMD_SPELLID, pcursmonst, plr[myplr]._pRSpell, v11); + } + return; + } + goto LABEL_46; + } + v3 = *((_BYTE *)&plr[0]._pClass + v1); + switch ( v3 ) + { + case UI_WARRIOR: + v4 = PS_WARR34; +LABEL_53: + PlaySFX(v4); + return; + case UI_ROGUE: + v4 = PS_ROGUE34; + goto LABEL_53; + case UI_SORCERER: + v4 = PS_MAGE34; + goto LABEL_53; + } +} + +void SyncPlrAnim(int pnum) +{ + int v1; // esi + int v2; // eax + int v3; // ecx + unsigned char *v4; // ecx + int v5; // edx + + v1 = pnum; + if ( (unsigned int)pnum >= MAX_PLRS ) + app_fatal("SyncPlrAnim: illegal player %d", pnum); + v2 = v1; + v3 = plr[v1]._pdir; + switch ( plr[v1]._pmode ) + { + case PM_STAND: + case PM_NEWLVL: + case PM_QUIT: + v4 = plr[0]._pNAnim[v3 + 5430 * v1]; + goto LABEL_19; + case PM_WALK: + case PM_WALK2: + case PM_WALK3: + v4 = plr[0]._pWAnim[v3 + 5430 * v1]; + goto LABEL_19; + case PM_ATTACK: + case PM_RATTACK: + v4 = plr[0]._pAAnim[v3 + 5430 * v1]; + goto LABEL_19; + case PM_BLOCK: + v4 = plr[0]._pBAnim[v3 + 5430 * v1]; + goto LABEL_19; + case PM_GOTHIT: + v4 = plr[0]._pHAnim[v3 + 5430 * v1]; + goto LABEL_19; + case PM_DEATH: + v4 = plr[0]._pDAnim[v3 + 5430 * v1]; + goto LABEL_19; + case PM_SPELL: + if ( v1 == myplr ) + v5 = (unsigned char)spelldata[plr[v2]._pSpell].sType; + else + v5 = 0; + if ( !v5 ) + plr[v2]._pAnimData = plr[0]._pFAnim[v3 + 5430 * v1]; + if ( v5 == STYPE_LIGHTNING ) + plr[v2]._pAnimData = plr[0]._pLAnim[v3 + 5430 * v1]; + if ( v5 == STYPE_MAGIC ) + { + v4 = plr[0]._pTAnim[v3 + 5430 * v1]; +LABEL_19: + plr[v2]._pAnimData = v4; + } + break; + default: + app_fatal("SyncPlrAnim"); + break; + } +} + +void SyncInitPlrPos(int pnum) +{ + int v1; // esi + _bool v2; // zf + unsigned int v3; // eax + int v4; // ebx + int v5; // edi + int v6; // eax + signed int v7; // [esp+Ch] [ebp-18h] + int p; // [esp+10h] [ebp-14h] + int v9; // [esp+14h] [ebp-10h] + signed int v10; // [esp+18h] [ebp-Ch] + signed int v11; // [esp+1Ch] [ebp-8h] + unsigned int i; // [esp+20h] [ebp-4h] + signed int v13; // [esp+20h] [ebp-4h] + + p = pnum; + v1 = pnum; + v2 = gbMaxPlayers == 1; + plr[v1]._ptargx = plr[pnum].WorldX; + plr[v1]._ptargy = plr[pnum].WorldY; + if ( !v2 && plr[v1].plrlevel == currlevel ) + { + v3 = 0; + for ( i = 0; ; v3 = i ) + { + v4 = plr[v1].WorldX + *(int *)((char *)plrxoff2 + v3); + v5 = plr[v1].WorldY + *(int *)((char *)plryoff2 + v3); + if ( PosOkPlayer(p, v4, v5) ) + break; + i += 4; + if ( i >= 0x20 ) + break; + } + if ( !PosOkPlayer(p, v4, v5) ) + { + v11 = 0; + v6 = -1; + v13 = 1; + v7 = -1; + do + { + if ( v11 ) + break; + v9 = v6; + while ( v6 <= v13 && !v11 ) + { + v5 = v9 + plr[v1].WorldY; + v10 = v7; + do + { + if ( v11 ) + break; + v4 = v10 + plr[v1].WorldX; + if ( PosOkPlayer(p, v10 + plr[v1].WorldX, v5) && !PosOkPortal(currlevel, v4, v5) ) + v11 = 1; + ++v10; + } + while ( v10 <= v13 ); + v6 = ++v9; + } + ++v13; + v6 = v7-- - 1; + } + while ( v7 > -50 ); + } + plr[v1].WorldX = v4; + v2 = p == myplr; + plr[v1].WorldY = v5; + dPlayer[v4][v5] = p + 1; + if ( v2 ) + { + plr[v1]._px = v4; + plr[v1]._py = v5; + plr[v1]._ptargx = v4; + plr[v1]._ptargy = v5; + ViewX = v4; + ViewY = v5; + } + } +} + +void SyncInitPlr(int pnum) +{ + int v1; // esi + + v1 = pnum; + if ( (unsigned int)pnum >= MAX_PLRS ) + app_fatal("SyncInitPlr: illegal player %d", pnum); + SetPlrAnims(v1); + SyncInitPlrPos(v1); +} + +void CheckStats(int pnum) +{ + int v1; // esi + int v2; // eax + char v3; // cl + signed int v4; // esi + signed int v5; // edi + int v6; // edx + int v7; // ecx + int v8; // edx + int v9; // ecx + int v10; // edx + int v11; // ecx + int v12; // edx + int v13; // ecx + //signed int v14; // [esp+Ch] [ebp-4h] + + v1 = pnum; + if ( (unsigned int)pnum >= MAX_PLRS ) + app_fatal("CheckStats: illegal player %d", pnum); + v2 = v1; + v3 = plr[v1]._pClass; + if ( v3 ) + { + if ( v3 == 1 ) + { + v4 = 1; + } + else if ( v3 == 2 ) + { + v4 = 2; + } + /*else + { + v4 = v14; + }*/ + } + else + { + v4 = 0; + } + v5 = 0; + do + { + if ( v5 ) + { + switch ( v5 ) + { + case ATTRIB_MAG: + v10 = plr[v2]._pBaseMag; + v11 = MaxStats[v4][1]; + if ( v10 <= v11 ) + { + if ( v10 < 0 ) + plr[v2]._pBaseMag = 0; + } + else + { + plr[v2]._pBaseMag = v11; + } + break; + case ATTRIB_DEX: + v8 = plr[v2]._pBaseDex; + v9 = MaxStats[v4][2]; + if ( v8 <= v9 ) + { + if ( v8 < 0 ) + plr[v2]._pBaseDex = 0; + } + else + { + plr[v2]._pBaseDex = v9; + } + break; + case ATTRIB_VIT: + v6 = plr[v2]._pBaseVit; + v7 = MaxStats[v4][3]; + if ( v6 <= v7 ) + { + if ( v6 < 0 ) + plr[v2]._pBaseVit = 0; + } + else + { + plr[v2]._pBaseVit = v7; + } + break; + } + } + else + { + v12 = plr[v2]._pBaseStr; + v13 = MaxStats[v4][0]; + if ( v12 <= v13 ) + { + if ( v12 < 0 ) + plr[v2]._pBaseStr = 0; + } + else + { + plr[v2]._pBaseStr = v13; + } + } + ++v5; + } + while ( v5 < 4 ); +} + +void ModifyPlrStr(int pnum, int l) +{ + int v2; // esi + int v3; // edi + int v4; // esi + char v5; // dl + int v6; // ecx + int v7; // eax + int v8; // ebx + int v9; // eax + signed int v10; // ecx + int p; // [esp+8h] [ebp-4h] + + v2 = pnum; + v3 = l; + p = pnum; + if ( (unsigned int)pnum >= MAX_PLRS ) + app_fatal("ModifyPlrStr: illegal player %d", pnum); + v4 = v2; + v5 = plr[v4]._pClass; + v6 = plr[v4]._pBaseStr; + v7 = MaxStats[v5][0]; + if ( v6 + v3 > v7 ) + v3 = v7 - v6; + plr[v4]._pBaseStr = v3 + v6; + plr[v4]._pStrength += v3; + v8 = plr[v4]._pStrength; + if ( v5 == 1 ) + { + v9 = plr[v4]._pLevel * (v8 + plr[v4]._pDexterity); + v10 = 200; + } + else + { + v9 = v8 * plr[v4]._pLevel; + v10 = 100; + } + plr[v4]._pDamageMod = v9 / v10; + CalcPlrInv(p, 1u); + if ( p == myplr ) + NetSendCmdParam1(0, CMD_SETSTR, plr[v4]._pBaseStr); +} + +void ModifyPlrMag(int pnum, int l) +{ + int v2; // esi + int v3; // edi + int v4; // esi + char v5; // dl + int v6; // ecx + int v7; // eax + int v8; // eax + int v9; // edi + int p; // [esp+8h] [ebp-4h] + + v2 = pnum; + v3 = l; + p = pnum; + if ( (unsigned int)pnum >= MAX_PLRS ) + app_fatal("ModifyPlrMag: illegal player %d", pnum); + v4 = v2; + v5 = plr[v4]._pClass; + v6 = MaxStats[v5][1]; + v7 = plr[v4]._pBaseMag; + if ( v7 + v3 > v6 ) + v3 = v6 - v7; + plr[v4]._pMagic += v3; + v8 = v3 + v7; + v9 = v3 << 6; + plr[v4]._pBaseMag = v8; + if ( v5 == 2 ) + v9 *= 2; + plr[v4]._pMaxManaBase += v9; + plr[v4]._pMaxMana += v9; + if ( !(plr[v4]._pIFlags & 0x8000000) ) + { + plr[v4]._pManaBase += v9; + plr[v4]._pMana += v9; + } + CalcPlrInv(p, 1u); + if ( p == myplr ) + NetSendCmdParam1(0, CMD_SETMAG, plr[v4]._pBaseMag); +} + +void ModifyPlrDex(int pnum, int l) +{ + int v2; // ebx + int v3; // edi + int v4; // esi + int v5; // ecx + int v6; // eax + + v2 = pnum; + v3 = l; + if ( (unsigned int)pnum >= MAX_PLRS ) + app_fatal("ModifyPlrDex: illegal player %d", pnum); + v4 = v2; + v5 = MaxStats[SLOBYTE(plr[v2]._pClass)][2]; + v6 = plr[v2]._pBaseDex; + if ( v6 + v3 > v5 ) + v3 = v5 - v6; + plr[v4]._pDexterity += v3; + plr[v4]._pBaseDex = v3 + v6; + CalcPlrInv(v2, 1u); + if ( _LOBYTE(plr[v4]._pClass) == 1 ) + plr[v4]._pDamageMod = plr[v4]._pLevel * (plr[v4]._pDexterity + plr[v4]._pStrength) / 200; + if ( v2 == myplr ) + NetSendCmdParam1(0, CMD_SETDEX, plr[v4]._pBaseDex); +} + +void ModifyPlrVit(int pnum, int l) +{ + int v2; // esi + int v3; // edi + int v4; // esi + char v5; // dl + int v6; // ecx + int v7; // eax + int v8; // eax + int v9; // edi + int p; // [esp+8h] [ebp-4h] + + v2 = pnum; + v3 = l; + p = pnum; + if ( (unsigned int)pnum >= MAX_PLRS ) + app_fatal("ModifyPlrVit: illegal player %d", pnum); + v4 = v2; + v5 = plr[v4]._pClass; + v6 = MaxStats[v5][3]; + v7 = plr[v4]._pBaseVit; + if ( v7 + v3 > v6 ) + v3 = v6 - v7; + plr[v4]._pVitality += v3; + v8 = v3 + v7; + v9 = v3 << 6; + plr[v4]._pBaseVit = v8; + if ( !v5 ) + v9 *= 2; + plr[v4]._pHPBase += v9; + plr[v4]._pMaxHPBase += v9; + plr[v4]._pHitPoints += v9; + plr[v4]._pMaxHP += v9; + CalcPlrInv(p, 1u); + if ( p == myplr ) + NetSendCmdParam1(0, CMD_SETVIT, plr[v4]._pBaseVit); +} + +void SetPlayerHitPoints(int pnum, int newhp) +{ + int v2; // esi + int v3; // edi + int v4; // eax + int v5; // ecx + _bool v6; // zf + + v2 = pnum; + v3 = newhp; + if ( (unsigned int)pnum >= MAX_PLRS ) + app_fatal("SetPlayerHitPoints: illegal player %d", pnum); + v4 = v2; + v5 = plr[v2]._pMaxHPBase; + plr[v4]._pHitPoints = v3; + v6 = v2 == myplr; + plr[v4]._pHPBase = v3 + v5 - plr[v2]._pMaxHP; + if ( v6 ) + drawhpflag = 1; +} + +void SetPlrStr(int pnum, int v) +{ + int v2; // edi + int v3; // ebx + int v4; // esi + int v5; // eax + signed int v6; // ecx + + v2 = pnum; + v3 = v; + if ( (unsigned int)pnum >= MAX_PLRS ) + app_fatal("SetPlrStr: illegal player %d", pnum); + v4 = v2; + plr[v2]._pBaseStr = v3; + CalcPlrInv(v2, 1u); + if ( _LOBYTE(plr[v2]._pClass) == 1 ) + { + v5 = plr[v4]._pLevel * (plr[v4]._pStrength + plr[v4]._pDexterity); + v6 = 200; + } + else + { + v5 = plr[v4]._pStrength * plr[v4]._pLevel; + v6 = 100; + } + plr[v4]._pDamageMod = v5 / v6; +} + +void SetPlrMag(int pnum, int v) +{ + int v2; // edi + int v3; // esi + int v4; // eax + int v5; // esi + + v2 = pnum; + v3 = v; + if ( (unsigned int)pnum >= MAX_PLRS ) + app_fatal("SetPlrMag: illegal player %d", pnum); + v4 = v2; + plr[v2]._pBaseMag = v3; + v5 = v3 << 6; + if ( _LOBYTE(plr[v2]._pClass) == 2 ) + v5 *= 2; + plr[v4]._pMaxManaBase = v5; + plr[v4]._pMaxMana = v5; + CalcPlrInv(v2, 1u); +} + +void SetPlrDex(int pnum, int v) +{ + int v2; // edi + int v3; // ebx + int v4; // esi + int v5; // eax + signed int v6; // ecx + + v2 = pnum; + v3 = v; + if ( (unsigned int)pnum >= MAX_PLRS ) + app_fatal("SetPlrDex: illegal player %d", pnum); + v4 = v2; + plr[v2]._pBaseDex = v3; + CalcPlrInv(v2, 1u); + if ( _LOBYTE(plr[v2]._pClass) == 1 ) + { + v5 = plr[v4]._pLevel * (plr[v4]._pStrength + plr[v4]._pDexterity); + v6 = 200; + } + else + { + v5 = plr[v4]._pStrength * plr[v4]._pLevel; + v6 = 100; + } + plr[v4]._pDamageMod = v5 / v6; +} + +void SetPlrVit(int pnum, int v) +{ + int v2; // edi + int v3; // esi + int v4; // eax + int v5; // esi + + v2 = pnum; + v3 = v; + if ( (unsigned int)pnum >= MAX_PLRS ) + app_fatal("SetPlrVit: illegal player %d", pnum); + v4 = v2; + plr[v2]._pBaseVit = v3; + v5 = v3 << 6; + if ( !_LOBYTE(plr[v2]._pClass) ) + v5 *= 2; + plr[v4]._pHPBase = v5; + plr[v4]._pMaxHPBase = v5; + CalcPlrInv(v2, 1u); +} + +void InitDungMsgs(int pnum) +{ + int v1; // esi + + v1 = pnum; + if ( (unsigned int)pnum >= MAX_PLRS ) + app_fatal("InitDungMsgs: illegal player %d", pnum); + plr[v1].pDungMsgs = 0; +} + +void PlayDungMsgs() +{ + int v0; // eax + int v1; // eax + char v2; // cl + char v3; // dl + char v4; // cl + char v5; // cl + char v6; // dl + char v7; // cl + char v8; // dl + char v9; // cl + char v10; // dl + char v11; // cl + char v12; // dl + + v0 = myplr; + if ( (unsigned int)myplr >= 4 ) + { + app_fatal("PlayDungMsgs: illegal player %d", myplr); + v0 = myplr; + } + switch ( currlevel ) + { + case 1u: + v1 = v0; + if ( !plr[v1]._pLvlVisited[1] && gbMaxPlayers == currlevel ) + { + v2 = plr[v1].pDungMsgs; + if ( !(v2 & 1) ) + { + v3 = plr[v1]._pClass; + sfxdelay = 40; + if ( v3 ) + { + if ( v3 == 1 ) + { + sfxdnum = PS_ROGUE97; + } + else if ( v3 == 2 ) + { + sfxdnum = PS_MAGE97; + } + } + else + { + sfxdnum = PS_WARR97; + } + v4 = v2 | 1; +LABEL_14: + plr[v1].pDungMsgs = v4; + return; + } + } + break; + case 5u: + v1 = v0; + if ( !plr[v1]._pLvlVisited[5] && gbMaxPlayers == 1 ) + { + v5 = plr[v1].pDungMsgs; + if ( !(v5 & 2) ) + { + v6 = plr[v1]._pClass; + sfxdelay = 40; + if ( v6 ) + { + if ( v6 == 1 ) + { + sfxdnum = PS_ROGUE96; + } + else if ( v6 == 2 ) + { + sfxdnum = PS_MAGE96; + } + } + else + { + sfxdnum = PS_WARR96B; + } + v4 = v5 | 2; + goto LABEL_14; + } + } + break; + case 9u: + v1 = v0; + if ( !plr[v1]._pLvlVisited[9] && gbMaxPlayers == 1 ) + { + v7 = plr[v1].pDungMsgs; + if ( !(v7 & 4) ) + { + v8 = plr[v1]._pClass; + sfxdelay = 40; + if ( v8 ) + { + if ( v8 == 1 ) + { + sfxdnum = PS_ROGUE98; + } + else if ( v8 == 2 ) + { + sfxdnum = PS_MAGE98; + } + } + else + { + sfxdnum = PS_WARR98; + } + v4 = v7 | 4; + goto LABEL_14; + } + } + break; + case 13u: + v1 = v0; + if ( !plr[v1]._pLvlVisited[13] && gbMaxPlayers == 1 ) + { + v9 = plr[v1].pDungMsgs; + if ( !(v9 & 8) ) + { + v10 = plr[v1]._pClass; + sfxdelay = 40; + if ( v10 ) + { + if ( v10 == 1 ) + { + sfxdnum = PS_ROGUE99; + } + else if ( v10 == 2 ) + { + sfxdnum = PS_MAGE99; + } + } + else + { + sfxdnum = PS_WARR99; + } + v4 = v9 | 8; + goto LABEL_14; + } + } + break; + case 16u: + v1 = v0; + if ( !plr[v1]._pLvlVisited[15] && gbMaxPlayers == 1 ) + { + v11 = plr[v1].pDungMsgs; + if ( !(v11 & 0x10) ) + { + v12 = plr[v1]._pClass; + sfxdelay = 40; + if ( !v12 || v12 == 1 || v12 == 2 ) + sfxdnum = PS_DIABLVLINT; + v4 = v11 | 0x10; + goto LABEL_14; + } + } + break; + } + sfxdelay = 0; +} diff --git a/2020_03_31/Source/player.h b/2020_03_31/Source/player.h new file mode 100644 index 00000000..da064d21 --- /dev/null +++ b/2020_03_31/Source/player.h @@ -0,0 +1,137 @@ +//HEADER_GOES_HERE +#ifndef __PLAYER_H__ +#define __PLAYER_H__ + +extern int plr_lframe_size; // idb +extern int plr_wframe_size; // idb +extern BYTE plr_gfx_flag; // weak +extern int plr_aframe_size; // idb +extern int myplr; +extern PlayerStruct plr[MAX_PLRS]; +extern int plr_fframe_size; // idb +extern int plr_qframe_size; // idb +extern int deathflag; // idb +extern int plr_hframe_size; // idb +extern int plr_bframe_size; // idb +extern char plr_gfx_bflag; // weak +extern int plr_sframe_size; // idb +extern int deathdelay; // weak +extern int plr_dframe_size; // idb + +void SetPlayerGPtrs(BYTE *pData, BYTE **pAnim); +void LoadPlrGFX(int pnum, DWORD dwMask); +void InitPlayerGFX(int pnum); +void InitPlrGFXMem(int pnum); +DWORD GetPlrGFXSize(char *szCel); +void FreePlayerGFX(int pnum); +void NewPlrAnim(int pnum, unsigned char *Peq, int numFrames, int Delay, int width); +void ClearPlrPVars(int pnum); +void SetPlrAnims(int pnum); +void ClearPlrRVars(PlayerStruct *p); +void CreatePlayer(int pnum, char c); +int CalcStatDiff(int pnum); +void NextPlrLevel(int pnum); +void AddPlrExperience(int pnum, int lvl, long exp); +void AddPlrMonstExper(int lvl, long exp, char pmask); +void InitPlayer(int pnum, BOOL FirstTime); +void InitMultiView(); +void CheckEFlag(int pnum, BOOL flag); +BOOL SolidLoc(int x, int y); +BOOL PlrDirOK(int pnum, int dir); +void PlrClrTrans(int x, int y); +void PlrDoTrans(int x, int y); +void SetPlayerOld(int pnum); +void FixPlayerLocation(int pnum, int bDir); +void StartStand(int pnum, int dir); +void StartWalkStand(int pnum); +void PM_ChangeLightOff(int pnum); +void PM_ChangeOffset(int pnum); +void StartWalk(int pnum, int xvel, int yvel, int xadd, int yadd, int EndDir, int sdir); +void StartWalk2(int pnum, int xvel, int yvel, int xoff, int yoff, int xadd, int yadd, int EndDir, int sdir); +void StartWalk3(int pnum, int xvel, int yvel, int xoff, int yoff, int xadd, int yadd, int mapx, int mapy, int EndDir, int sdir); +void StartAttack(int pnum, int d); +void StartRangeAttack(int pnum, int d, int cx, int cy); +void StartPlrBlock(int pnum, int dir); +void StartSpell(int pnum, int d, int cx, int cy); +void FixPlrWalkTags(int pnum); +void RemovePlrFromMap(int pnum); +void StartPlrHit(int pnum, int dam, unsigned char forcehit); +void RespawnDeadItem(ItemStruct *itm, int x, int y); +void StartPlayerKill(int pnum, int earflag); +void PlrDeadItem(int pnum, ItemStruct *itm, int xx, int yy); +void DropHalfPlayersGold(int pnum); +void SyncPlrKill(int pnum, int earflag); +void j_StartPlayerKill(int pnum, int earflag); +void RemovePlrMissiles(int pnum); +void InitLevelChange(int pnum); +void StartNewLvl(int pnum, int fom, int lvl); +void RestartTownLvl(int pnum); +void StartWarpLvl(int pnum, int pidx); +int PM_DoStand(int pnum); +int PM_DoWalk(int pnum); +int PM_DoWalk2(int pnum); +int PM_DoWalk3(int pnum); +BOOL WeaponDur(int pnum, int durrnd); +BOOL PlrHitMonst(int pnum, int m); +BOOL PlrHitPlr(int pnum, char p); +BOOL PlrHitObj(int pnum, int mx, int my); +int PM_DoAttack(int pnum); +int PM_DoRangeAttack(int pnum); +void ShieldDur(int pnum); +int PM_DoBlock(int pnum); +int PM_DoSpell(int pnum); +int PM_DoGotHit(int pnum); +void ArmorDur(int pnum); +int PM_DoDeath(int pnum); +int PM_DoNewLvl(int pnum); +void CheckNewPath(int pnum); +BOOL PlrDeathModeOK(int p); +void ValidatePlayer(); +void ProcessPlayers(); +void CheckCheatStats(int pnum); +void ClrPlrPath(int pnum); +BOOL PosOkPlayer(int pnum, int px, int py); +void MakePlrPath(int pnum, int xx, int yy, BOOL endspace); +void CheckPlrSpell(); +void SyncPlrAnim(int pnum); +void SyncInitPlrPos(int pnum); +void SyncInitPlr(int pnum); +void CheckStats(int pnum); +void ModifyPlrStr(int pnum, int l); +void ModifyPlrMag(int pnum, int l); +void ModifyPlrDex(int pnum, int l); +void ModifyPlrVit(int pnum, int l); +void SetPlayerHitPoints(int pnum, int newhp); +void SetPlrStr(int pnum, int v); +void SetPlrMag(int pnum, int v); +void SetPlrDex(int pnum, int v); +void SetPlrVit(int pnum, int v); +void InitDungMsgs(int pnum); +void PlayDungMsgs(); + +/* rdata */ + +extern const char ArmourChar[4]; +extern const char WepChar[10]; +extern const char CharChar[4]; + +/* data */ + +extern int plrxoff[9]; +extern int plryoff[9]; +extern int plrxoff2[9]; +extern int plryoff2[9]; +extern char PlrGFXAnimLens[3][11]; +extern int PWVel[3][3]; +extern int WalkAnimTbl[3]; +extern int StrengthTbl[3]; +extern int MagicTbl[3]; +extern int DexterityTbl[3]; +extern int VitalityTbl[3]; +extern int ToBlkTbl[3]; +extern char *ClassStrTblOld[3]; +extern int MaxStats[3][4]; +extern int ExpLvlsTbl[51]; +extern char *ClassStrTbl[3]; + +#endif /* __PLAYER_H__ */ diff --git a/2020_03_31/Source/plrmsg.cpp b/2020_03_31/Source/plrmsg.cpp new file mode 100644 index 00000000..c4d0094a --- /dev/null +++ b/2020_03_31/Source/plrmsg.cpp @@ -0,0 +1,209 @@ +#include "diablo.h" + +int plrmsg_ticks; // weak +char plr_msg_slot; // weak +_plrmsg plr_msgs[8]; + +const char text_color_from_player_num[5] = { COL_WHITE, COL_WHITE, COL_WHITE, COL_WHITE, COL_GOLD }; + +void plrmsg_delay(int a1) +{ + _plrmsg *pMsg; // eax + signed int v2; // ecx + + if ( a1 ) + { + plrmsg_ticks = -GetTickCount(); + } + else + { + plrmsg_ticks += GetTickCount(); + pMsg = plr_msgs; + v2 = 8; + do + { + pMsg->time += plrmsg_ticks; + ++pMsg; + --v2; + } + while ( v2 ); + } +} + +char *ErrorPlrMsg(char *pszMsg) +{ + _plrmsg *pMsg; // esi + char *v2; // edi + char *result; // eax + + pMsg = &plr_msgs[(unsigned char)plr_msg_slot]; + v2 = pszMsg; + plr_msg_slot = (plr_msg_slot + 1) & 7; + pMsg->player = 4; + pMsg->time = GetTickCount(); + result = strncpy(pMsg->str, v2, 0x90u); + pMsg->str[143] = 0; + return result; +} + +size_t __cdecl EventPlrMsg(char *pszFmt, ...) +{ + char *v1; // esi + va_list va; // [esp+Ch] [ebp+8h] + + va_start(va, pszFmt); + v1 = (char *)&plr_msgs[(unsigned char)plr_msg_slot]; + plr_msg_slot = (plr_msg_slot + 1) & 7; + v1[4] = 4; + *(_DWORD *)v1 = GetTickCount(); + v1 += 5; + vsprintf(v1, pszFmt, va); + return strlen(v1); +} + +void SendPlrMsg(int pnum, const char *pszStr) +{ + _plrmsg *pMsg; // esi + int v3; // ebx + const char *v4; // ebp + int v5; // edi + const char *v6; // ebx + + pMsg = &plr_msgs[(unsigned char)plr_msg_slot]; + v3 = pnum; + v4 = pszStr; + plr_msg_slot = (plr_msg_slot + 1) & 7; + pMsg->player = pnum; + pMsg->time = GetTickCount(); + v5 = v3; + v6 = plr[v3]._pName; + strlen(v6); /* these are used in debug */ + strlen(v4); + sprintf(pMsg->str, "%s (lvl %d): %s", v6, plr[v5]._pLevel, v4); +} + +void ClearPlrMsg() +{ + _plrmsg *pMsg; // esi + DWORD v1; // eax + signed int v2; // ecx + + pMsg = plr_msgs; + v1 = GetTickCount(); + v2 = 8; + do + { + if ( (signed int)(v1 - pMsg->time) > 10000 ) + pMsg->str[0] = 0; + ++pMsg; + --v2; + } + while ( v2 ); +} + +void InitPlrMsg() +{ + memset(plr_msgs, 0, 0x4C0u); + plr_msg_slot = 0; +} + +void DrawPlrMsg() +{ + int v0; // ebx + int v1; // ebp + int v2; // edi + char *v3; // esi + signed int v4; // [esp+Ch] [ebp-4h] + + v0 = 74; + v1 = 230; + v2 = 620; + if ( chrflag || questlog ) + { + if ( invflag || sbookflag ) + return; + v0 = 394; + goto LABEL_9; + } + if ( invflag || sbookflag ) +LABEL_9: + v2 = 300; + v3 = plr_msgs[0].str; + v4 = 8; + do + { + if ( *v3 ) + PrintPlrMsg(v0, v1, v2, v3, (unsigned char)text_color_from_player_num[(unsigned char)*(v3 - 1)]); + v3 += 152; + v1 += 35; + --v4; + } + while ( v4 ); +} + +void PrintPlrMsg(int no, int x, int y, char *str, int just) +{ + char *v5; // edi + int *v6; // edx + int v7; // esi + char *v8; // edx + int v9; // esi + unsigned int v10; // eax + unsigned char v11; // cl + unsigned char v12; // cl + int v13; // eax + unsigned char v14; // bl + int v15; // [esp+Ch] [ebp-Ch] + int *v16; // [esp+10h] [ebp-8h] + int v17; // [esp+14h] [ebp-4h] + char *stra; // [esp+24h] [ebp+Ch] + + v17 = 0; + v5 = str; + v15 = no; + if ( *str ) + { + v6 = &PitchTbl[x]; + v16 = v6; + do + { + v7 = *v6; + v8 = v5; + v9 = v15 + v7; + v10 = 0; + stra = v5; + while ( 1 ) + { + v11 = *v8; + if ( !*v8 ) + break; + ++v8; + v12 = fontframe[gbFontTransTbl[v11]]; + v10 += fontkern[v12] + 1; + if ( v12 ) + { + if ( v10 >= y ) + goto LABEL_13; + } + else + { + stra = v8; + } + } + stra = v8; +LABEL_13: + while ( v5 < stra ) + { + v13 = (unsigned char)*v5++; + v14 = fontframe[gbFontTransTbl[v13]]; + if ( v14 ) + PrintChar(v9, v14, just); + v9 += fontkern[v14] + 1; + } + v6 = v16 + 10; + ++v17; + v16 += 10; + } + while ( v17 != 3 && *v5 ); + } +} diff --git a/2020_03_31/Source/plrmsg.h b/2020_03_31/Source/plrmsg.h new file mode 100644 index 00000000..51b4390f --- /dev/null +++ b/2020_03_31/Source/plrmsg.h @@ -0,0 +1,22 @@ +//HEADER_GOES_HERE +#ifndef __PLRMSG_H__ +#define __PLRMSG_H__ + +extern int plrmsg_ticks; // weak +extern char plr_msg_slot; // weak +extern _plrmsg plr_msgs[8]; + +void plrmsg_delay(int a1); +char *ErrorPlrMsg(char *pszMsg); +size_t __cdecl EventPlrMsg(char *pszFmt, ...); +void SendPlrMsg(int pnum, const char *pszStr); +void ClearPlrMsg(); +void InitPlrMsg(); +void DrawPlrMsg(); +void PrintPlrMsg(int no, int x, int y, char *str, int just); + +/* rdata */ + +extern const char text_color_from_player_num[5]; + +#endif /* __PLRMSG_H__ */ diff --git a/2020_03_31/Source/portal.cpp b/2020_03_31/Source/portal.cpp new file mode 100644 index 00000000..6e4282ee --- /dev/null +++ b/2020_03_31/Source/portal.cpp @@ -0,0 +1,203 @@ +#include "diablo.h" + +PortalStruct portal[MAXPORTAL]; +int portalindex; + +int WarpDropX[MAXPORTAL] = { 57, 59, 61, 63 }; +int WarpDropY[MAXPORTAL] = { 40, 40, 40, 40 }; + +void InitPortals() +{ + int i; // edi + + for(i = 0; i < MAXPORTAL; i++) + { + if(delta_portal_inited(i)) + portal[i].open = 0; + } +} + +void SetPortalStats(int i, int o, int x, int y, int lvl, int lvltype) +{ + portal[i].x = x; + portal[i].setlvl = 0; + portal[i].y = y; + portal[i].open = o; + portal[i].level = lvl; + portal[i].ltype = lvltype; +} + +void AddWarpMissile(int i, int x, int y) +{ + int mi; // eax + + missiledata[MIS_TOWN].mlSFX = -1; + dMissile[x][y] = 0; + mi = AddMissile(0, 0, x, y, 0, MIS_TOWN, 0, i, 0, 0); + + if ( mi != -1 ) + { + SetMissDir(mi, 1); + + if ( currlevel ) + missile[mi]._mlid = AddLight(missile[mi]._mix, missile[mi]._miy, 15); + + missiledata[MIS_TOWN].mlSFX = LS_SENTINEL; + } +} + +void SyncPortals() +{ + int v0; // edi + int *v1; // esi + int v2; // eax + + v0 = 0; + v1 = &portal[0].level; + do + { + if ( *(v1 - 3) ) + { + if ( currlevel ) + { + v2 = currlevel; + if ( setlevel ) + v2 = (unsigned char)setlvlnum; + if ( *v1 == v2 ) + AddWarpMissile(v0, *(v1 - 2), *(v1 - 1)); + } + else + { + AddWarpMissile(v0, WarpDropX[v0], WarpDropY[v0]); + } + } + v1 += 6; + ++v0; + } + while ( (signed int)v1 < (signed int)&portal[MAXPORTAL].level ); +} + +void AddInTownPortal(int i) +{ + AddWarpMissile(i, WarpDropX[i], WarpDropY[i]); +} + +void ActivatePortal(int i, int x, int y, int lvl, int lvltype, int sp) +{ + portal[i].open = 1; + + if ( lvl ) + { + portal[i].level = lvl; + portal[i].x = x; + portal[i].ltype = lvltype; + portal[i].y = y; + portal[i].setlvl = sp; + } +} + +void DeactivatePortal(int i) +{ + portal[i].open = 0; +} + +_bool PortalOnLevel(int i) +{ + if ( portal[i].level == currlevel ) + return 1; + else + return currlevel == 0; +} + +void RemovePortalMissile(int id) +{ + int i; // esi + int mi; // eax + + for ( i = 0; i < nummissiles; ++i ) + { + mi = missileactive[i]; + if ( missile[mi]._mitype == MIS_TOWN && missile[mi]._misource == id ) + { + dFlags[missile[mi]._mix][missile[mi]._miy] &= 0xFE; + dMissile[missile[mi]._mix][missile[mi]._miy] = 0; + + if ( portal[id].level ) + AddUnLight(missile[mi]._mlid); + + DeleteMissile(mi, i); + } + } +} + +void SetCurrentPortal(int p) +{ + portalindex = p; +} + +void GetPortalLevel() +{ + if ( currlevel ) + { + setlevel = 0; + currlevel = 0; + leveltype = 0; + plr[myplr].plrlevel = 0; + } + else + { + if ( portal[portalindex].setlvl ) + { + setlevel = 1; + setlvlnum = portal[portalindex].level; + } + else + { + setlevel = 0; + } + + currlevel = portal[portalindex].level; + leveltype = portal[portalindex].ltype; + plr[myplr].plrlevel = portal[portalindex].level; + + if ( portalindex == myplr ) + { + NetSendCmd(1, CMD_DEACTIVATEPORTAL); + DeactivatePortal(portalindex); + } + } +} + +void GetPortalLvlPos() +{ + if ( currlevel ) + { + ViewX = portal[portalindex].x; + ViewY = portal[portalindex].y; + + if ( portalindex != myplr ) + { + ViewX++; + ViewY++; + } + } + else + { + ViewX = WarpDropX[portalindex] + 1; + ViewY = WarpDropY[portalindex] + 1; + } +} + +_bool PosOkPortal(int lvl, int x, int y) +{ + int *v3; // eax + + v3 = &portal[0].x; + while ( !*(v3 - 1) || v3[2] != lvl || (*v3 != x || v3[1] != y) && (*v3 != x - 1 || v3[1] != y - 1) ) + { + v3 += 6; + if ( (signed int)v3 >= (signed int)&portal[MAXPORTAL].x ) + return 0; + } + return 1; +} diff --git a/2020_03_31/Source/portal.h b/2020_03_31/Source/portal.h new file mode 100644 index 00000000..24f3388c --- /dev/null +++ b/2020_03_31/Source/portal.h @@ -0,0 +1,27 @@ +//HEADER_GOES_HERE +#ifndef __PORTAL_H__ +#define __PORTAL_H__ + +extern PortalStruct portal[MAXPORTAL]; +extern int portalindex; +// int END_portalstruct; // weak + +void InitPortals(); +void SetPortalStats(int i, int o, int x, int y, int lvl, int lvltype); +void AddWarpMissile(int i, int x, int y); +void SyncPortals(); +void AddInTownPortal(int i); +void ActivatePortal(int i, int x, int y, int lvl, int lvltype, int sp); +void DeactivatePortal(int i); +_bool PortalOnLevel(int i); +void RemovePortalMissile(int id); +void SetCurrentPortal(int p); +void GetPortalLevel(); +void GetPortalLvlPos(); +_bool PosOkPortal(int lvl, int x, int y); + +/* rdata */ +extern int WarpDropX[MAXPORTAL]; +extern int WarpDropY[MAXPORTAL]; + +#endif /* __PORTAL_H__ */ diff --git a/2020_03_31/Source/quests.cpp b/2020_03_31/Source/quests.cpp new file mode 100644 index 00000000..a82fba37 --- /dev/null +++ b/2020_03_31/Source/quests.cpp @@ -0,0 +1,865 @@ +#include "diablo.h" + +int qtopline; // idb +int questlog; // weak +void *pQLogCel; +QuestStruct quests[MAXQUESTS]; +int qline; // weak +int qlist[MAXQUESTS]; +int numqlines; // weak +int WaterDone; // idb +int ReturnLvlY; // idb +int ReturnLvlX; // idb +int ReturnLvlT; // idb +int ALLQUESTS; // idb +int ReturnLvl; // idb + +QuestData questlist[MAXQUESTS] = +{ +#include "Data/xl_quest.cpp" +}; +char questxoff[7] = { 0, -1, 0, -1, -2, -1, -2 }; +char questyoff[7] = { 0, 0, -1, -1, -1, -2, -2 }; +char *questtrigstr[5] = +{ + "King Leoric's Tomb", + "The Chamber of Bone", + "Maze", + "A Dark Passage", + "Unholy Altar" +}; +int QuestGroup1[3] = { Q_BUTCHER, Q_LTBANNER, Q_GARBUD }; +int QuestGroup2[3] = { Q_BLIND, Q_ROCK, Q_BLOOD }; +int QuestGroup3[3] = { Q_MUSHROOM, Q_ZHAR, Q_ANVIL }; +int QuestGroup4[2] = { Q_VEIL, Q_WARLORD }; + +void InitQuests() +{ + int i, gri, deltaq; + + if(gbMaxPlayers == 1) { + for(i = 0; i < MAXQUESTS; i++) { + quests[i]._qactive = 0; + } + } else { + for(i = 0; i < MAXQUESTS; i++) { + if(!(questlist[i]._qflags & 1)) { + quests[i]._qactive = 0; + } + } + } + + questlog = 0; + ALLQUESTS = 1; + WaterDone = 0; + + deltaq = 0; + for(i = 0; (DWORD)i < MAXQUESTS; i++) { + if(gbMaxPlayers > 1 && !(questlist[i]._qflags & 1)) { + continue; + } + quests[i]._qtype = questlist[i]._qdtype; + if(gbMaxPlayers > 1) { + quests[i]._qlevel = questlist[i]._qdmultlvl; + if(!delta_quest_inited(deltaq)) { + quests[i]._qactive = 1; + quests[i]._qvar1 = 0; + quests[i]._qlog = FALSE; + } + deltaq++; + } else { + quests[i]._qactive = 1; + quests[i]._qlevel = questlist[i]._qdlvl; + quests[i]._qvar1 = 0; + quests[i]._qlog = FALSE; + } + quests[i]._qslvl = questlist[i]._qslvl; + quests[i]._qtx = 0; + quests[i]._qty = 0; + quests[i]._qidx = i; + quests[i]._qlvltype = questlist[i]._qlvlt; + quests[i]._qvar2 = 0; + quests[i]._qmsg = questlist[i]._qdmsg; + } + + if(gbMaxPlayers == 1) { + SetRndSeed(glSeedTbl[15]); + if(random(0, 2) != 0) { + quests[Q_PWATER]._qactive = 0; + } else { + quests[Q_SKELKING]._qactive = 0; + } + gri = random(0, 3); + quests[QuestGroup1[gri]]._qactive = 0; + gri = random(0, 3); + quests[QuestGroup2[gri]]._qactive = 0; + gri = random(0, 3); + quests[QuestGroup3[gri]]._qactive = 0; + gri = random(0, 2); + quests[QuestGroup4[gri]]._qactive = 0; + } +#ifdef _DEBUG + if(questdebug != -1) { + quests[questdebug]._qactive = 2; + } +#endif + if(quests[Q_SKELKING]._qactive == 0) { + quests[Q_SKELKING]._qvar2 = 2; + } + if(quests[Q_ROCK]._qactive == 0) { + quests[Q_ROCK]._qvar2 = 2; + } + + quests[Q_LTBANNER]._qvar1 = 1; + + if(gbMaxPlayers != 1) { + quests[Q_BETRAYER]._qvar1 = 2; + } +} + +void CheckQuests() +{ + int i, rportx, rporty; + + if(QuestStatus(Q_BETRAYER) && gbMaxPlayers != 1 && quests[Q_BETRAYER]._qvar1 == 2) { + AddObject(OBJ_ALTBOY, 2 * setpc_x + 20, 2 * setpc_y + 22); + quests[Q_BETRAYER]._qvar1 = 3; + NetSendCmdQuest(TRUE, Q_BETRAYER); + } + + if(gbMaxPlayers != 1) { + return; + } + + if(currlevel == quests[Q_BETRAYER]._qlevel + && !setlevel + && quests[Q_BETRAYER]._qvar1 >= 2 + && (quests[Q_BETRAYER]._qactive == 2 || quests[Q_BETRAYER]._qactive == 3) + && (quests[Q_BETRAYER]._qvar2 == 0 || quests[Q_BETRAYER]._qvar2 == 2)) { + quests[Q_BETRAYER]._qtx = 2 * quests[Q_BETRAYER]._qtx + 16; + quests[Q_BETRAYER]._qty = 2 * quests[Q_BETRAYER]._qty + 16; + rportx = quests[Q_BETRAYER]._qtx; + rporty = quests[Q_BETRAYER]._qty; + AddMissile(rportx, rporty, rportx, rporty, 0, MIS_RPORTAL, 0, myplr, 0, 0); + quests[Q_BETRAYER]._qvar2 = 1; + if(quests[Q_BETRAYER]._qactive == 2) { + quests[Q_BETRAYER]._qvar1 = 3; + } + } + + if(quests[Q_BETRAYER]._qactive == 3 + && setlevel + && setlvlnum == SL_VILEBETRAYER + && quests[Q_BETRAYER]._qvar2 == 4) { + rportx = 35; + rporty = 32; + AddMissile(rportx, rporty, rportx, rporty, 0, MIS_RPORTAL, 0, myplr, 0, 0); + quests[Q_BETRAYER]._qvar2 = 3; + } + + if(setlevel) { + if(setlvlnum == quests[Q_PWATER]._qslvl + && quests[Q_PWATER]._qactive != 1 + && leveltype == quests[Q_PWATER]._qlvltype + && nummonsters == 4 + && quests[Q_PWATER]._qactive != 3) { + quests[Q_PWATER]._qactive = 3; + PlaySfxLoc(IS_QUESTDN, plr[myplr].WorldX, plr[myplr].WorldY); + LoadPalette("Levels\\L3Data\\L3pwater.pal"); + WaterDone = 32; + } + if(WaterDone > 0) { + Lava2Water(WaterDone); + WaterDone--; + } + } else if(plr[myplr]._pmode == PM_STAND) { + for(i = 0; i < MAXQUESTS; i++) { + if(currlevel == quests[i]._qlevel + && quests[i]._qslvl != 0 + && quests[i]._qactive != 0 + && plr[myplr].WorldX == quests[i]._qtx + && plr[myplr].WorldY == quests[i]._qty) { + if(quests[i]._qlvltype != 255) { + setlvltype = quests[i]._qlvltype; + } + StartNewLvl(myplr, WM_DIABSETLVL, quests[i]._qslvl); + } + } + } +} + +BOOL ForceQuests() +{ + int i, j, ql, qx, qy; + + if(gbMaxPlayers != 1) { + return FALSE; + } + + for(i = 0; i < MAXQUESTS; i++) { + if(i != Q_BETRAYER && currlevel == quests[i]._qlevel && quests[i]._qslvl != 0) { + ql = quests[quests[i]._qidx]._qslvl - 1; + qx = quests[i]._qtx; + qy = quests[i]._qty; + for(j = 0; j < 7; j++) { + if(qx + questxoff[j] == cursmx && qy + questyoff[j] == cursmy) { + sprintf(infostr, "To %s", questtrigstr[ql]); + cursmx = qx; + cursmy = qy; + return TRUE; + } + } + } + } + + return FALSE; +} + +BOOL QuestStatus(int i) +{ + if(setlevel) { + return FALSE; + } + /// ASSERT: assert((DWORD)i < MAXQUESTS); + if(currlevel != quests[i]._qlevel) { + return FALSE; + } + if(quests[i]._qactive == 0) { + return FALSE; + } + if(gbMaxPlayers != 1 && !(questlist[i]._qflags & 1)) { + return FALSE; + } + + return TRUE; +} + +void CheckQuestKill(int m, BOOL sendmsg) +{ + int i, j; + + /// ASSERT: assert((DWORD)m < MAXMONSTERS); + if(monster[m].MType->mtype == MT_SKING) { + quests[Q_SKELKING]._qactive = 3; + sfxdelay = 30; + if(plr[myplr]._pClass == PC_WARRIOR) { + sfxdnum = PS_WARR82; + } else if(plr[myplr]._pClass == PC_ROGUE) { + sfxdnum = PS_ROGUE82; + } else if(plr[myplr]._pClass == PC_SORCERER) { + sfxdnum = PS_MAGE82; + } + if(sendmsg) { + NetSendCmdQuest(TRUE, Q_SKELKING); + } + } else if(monster[m].MType->mtype == MT_CLEAVER) { + quests[Q_BUTCHER]._qactive = 3; + sfxdelay = 30; + if(plr[myplr]._pClass == PC_WARRIOR) { + sfxdnum = PS_WARR80; + } else if(plr[myplr]._pClass == PC_ROGUE) { + sfxdnum = PS_ROGUE80; + } else if(plr[myplr]._pClass == PC_SORCERER) { + sfxdnum = PS_MAGE80; + } + if(sendmsg) { + NetSendCmdQuest(TRUE, Q_BUTCHER); + } + } else if(monster[m].mName == UniqMonst[0].mName) { + quests[Q_GARBUD]._qactive = 3; + sfxdelay = 30; + if(plr[myplr]._pClass == PC_WARRIOR) { + sfxdnum = PS_WARR61; + } else if(plr[myplr]._pClass == PC_ROGUE) { + sfxdnum = PS_ROGUE61; + } else if(plr[myplr]._pClass == PC_SORCERER) { + sfxdnum = PS_MAGE61; + } + } else if(monster[m].mName == UniqMonst[2].mName) { + quests[Q_ZHAR]._qactive = 3; + sfxdelay = 30; + if(plr[myplr]._pClass == PC_WARRIOR) { + sfxdnum = PS_WARR62; + } else if(plr[myplr]._pClass == PC_ROGUE) { + sfxdnum = PS_ROGUE62; + } else if(plr[myplr]._pClass == PC_SORCERER) { + sfxdnum = PS_MAGE62; + } + } else if(monster[m].mName == UniqMonst[4].mName && gbMaxPlayers != 1) { + quests[Q_BETRAYER]._qactive = 3; + quests[Q_BETRAYER]._qvar1 = 7; + sfxdelay = 30; + quests[Q_DIABLO]._qactive = 2; + for(j = 0; j < MAXDUNY; j++) { + for(i = 0; i < MAXDUNX; i++) { + if(dPiece[i][j] == 370) { + trigs[numtrigs]._tx = i; + trigs[numtrigs]._ty = j; + trigs[numtrigs]._tmsg = WM_DIABNEXTLVL; + numtrigs++; + } + } + } + if(plr[myplr]._pClass == PC_WARRIOR) { + sfxdnum = PS_WARR83; + } else if(plr[myplr]._pClass == PC_ROGUE) { + sfxdnum = PS_ROGUE83; + } else if(plr[myplr]._pClass == PC_SORCERER) { + sfxdnum = PS_MAGE83; + } + if(sendmsg) { + NetSendCmdQuest(TRUE, Q_BETRAYER); + NetSendCmdQuest(TRUE, Q_DIABLO); + } + } else if(monster[m].mName == UniqMonst[4].mName && gbMaxPlayers == 1) { + quests[Q_BETRAYER]._qactive = 3; + sfxdelay = 30; + InitVPTriggers(); + quests[Q_BETRAYER]._qvar1 = 7; + quests[Q_BETRAYER]._qvar2 = 4; + quests[Q_DIABLO]._qactive = 2; + AddMissile(35, 32, 35, 32, 0, MIS_RPORTAL, 0, myplr, 0, 0); + if(plr[myplr]._pClass == PC_WARRIOR) { + sfxdnum = PS_WARR83; + } else if(plr[myplr]._pClass == PC_ROGUE) { + sfxdnum = PS_ROGUE83; + } else if(plr[myplr]._pClass == PC_SORCERER) { + sfxdnum = PS_MAGE83; + } + } else if(monster[m].mName == UniqMonst[8].mName) { + /// ASSERT: assert(gbMaxPlayers == 1); + quests[Q_WARLORD]._qactive = 3; + sfxdelay = 30; + if(plr[myplr]._pClass == PC_WARRIOR) { + sfxdnum = PS_WARR94; + } else if(plr[myplr]._pClass == PC_ROGUE) { + sfxdnum = PS_ROGUE94; + } else if(plr[myplr]._pClass == PC_SORCERER) { + sfxdnum = PS_MAGE94; + } + } +} + +void DrawButcher() +{ + int xx, yy; + + xx = 2 * setpc_x + 16; + yy = 2 * setpc_y + 16; + + DRLG_RectTrans(xx + 3, yy + 3, xx + 10, yy + 10); +} + +void DrawSkelKing(int q, int x, int y) +{ + /// ASSERT: assert((DWORD)q < MAXQUESTS); + quests[q]._qtx = 2 * x + 28; + quests[q]._qty = 2 * y + 23; +} + +void DrawWarLord(int x, int y) +{ + int rw, rh, i, j; + BYTE *sp, *setp; + + setp = DiabLoad("Levels\\L4Data\\Warlord2.DUN", NULL, 'QSTt'); + sp = setp; + rw = *sp; + sp += 2; + rh = *sp; + sp += 2; + + setpc_w = rw; + setpc_h = rh; + setpc_x = x; + setpc_y = y; + + /// ASSERT: assert((DWORD)(rw + x - 1) < MDMAXX); + /// ASSERT: assert((DWORD)(rh + y - 1) < MDMAXY); + for(j = y; j < y + rh; j++) { + for(i = x; i < x + rw; i++) { + dungeon[i][j] = *sp != 0 ? *sp : 6; + sp += 2; + } + } + + MemFreeDbg(setp); +} + +void DrawSChamber(int q, int x, int y) +{ + int i, j, rw, rh, xx, yy; + BYTE *sp, *setp; + + setp = DiabLoad("Levels\\L2Data\\Bonestr1.DUN", NULL, 'QSTt'); + sp = setp; + rw = *sp; + sp += 2; + rh = *sp; + sp += 2; + + setpc_w = rw; + setpc_h = rh; + setpc_x = x; + setpc_y = y; + + /// ASSERT: assert((DWORD)(rw + x - 1) < MDMAXX); + /// ASSERT: assert((DWORD)(rh + y - 1) < MDMAXY); + for(j = y; j < y + rh; j++) { + for(i = x; i < x + rw; i++) { + dungeon[i][j] = *sp != 0 ? *sp : 3; + sp += 2; + } + } + + xx = 2 * x + 22; + yy = 2 * y + 23; + /// ASSERT: assert((DWORD)q < MAXQUESTS); + quests[q]._qtx = xx; + quests[q]._qty = yy; + + MemFreeDbg(setp); +} + +void DrawLTBanner(int x, int y) +{ + int rw, rh, i, j; + BYTE *sp, *setp; + + setp = DiabLoad("Levels\\L1Data\\Banner1.DUN", NULL, 'QSTt'); + sp = setp; + rw = *sp; + sp += 2; + rh = *sp; + sp += 2; + + setpc_w = rw; + setpc_h = rh; + setpc_x = x; + setpc_y = y; + + /// ASSERT: assert((DWORD)(x+rw-1) < MDMAXX); + /// ASSERT: assert((DWORD)(y+rh-1) < MDMAXY); + for(j = 0; j < rh; j++) { + for(i = 0; i < rw; i++) { + if(*sp != 0) { + pdungeon[i + x][j + y] = *sp; + } + sp += 2; + } + } + + MemFreeDbg(setp); +} + +void DrawBlind(int x, int y) +{ + int rw, rh, i, j; + BYTE *sp, *setp; + + setp = DiabLoad("Levels\\L2Data\\Blind1.DUN", NULL, 'QSTt'); + sp = setp; + rw = *sp; + sp += 2; + rh = *sp; + sp += 2; + + setpc_x = x; + setpc_y = y; + setpc_w = rw; + setpc_h = rh; + + /// ASSERT: assert((DWORD)(x+rw-1) < MDMAXX); + /// ASSERT: assert((DWORD)(y+rh-1) < MDMAXY); + for(j = 0; j < rh; j++) { + for(i = 0; i < rw; i++) { + if(*sp != 0) { + pdungeon[i + x][j + y] = *sp; + } + sp += 2; + } + } + + MemFreeDbg(setp); +} + +void DrawBlood(int x, int y) +{ + int rw, rh, i, j; + BYTE *sp, *setp; + + setp = DiabLoad("Levels\\L2Data\\Blood2.DUN", NULL, 'QSTt'); + sp = setp; + rw = *sp; + sp += 2; + rh = *sp; + sp += 2; + + setpc_x = x; + setpc_y = y; + setpc_w = rw; + setpc_h = rh; + + /// ASSERT: assert((DWORD)(rw + x - 1) < MDMAXX); + /// ASSERT: assert((DWORD)(rh + y - 1) < MDMAXY); + for(j = 0; j < rh; j++) { + for(i = 0; i < rw; i++) { + if(*sp != 0) { + dungeon[i + x][j + y] = *sp; + } + sp += 2; + } + } + + MemFreeDbg(setp); +} + +void DRLG_CheckQuests(int x, int y) +{ + int i; + + for(i = 0; i < MAXQUESTS; i++) { + if(QuestStatus(i)) { + switch(quests[i]._qtype) { + case Q_BUTCHER: + DrawButcher(); + break; + case Q_SKELKING: + DrawSkelKing(i, x, y); + break; + case Q_SCHAMB: + DrawSChamber(i, x, y); + break; + case Q_BLIND: + DrawBlind(x, y); + break; + case Q_BLOOD: + DrawBlood(x, y); + break; + case Q_LTBANNER: + DrawLTBanner(x, y); + break; + case Q_WARLORD: + DrawWarLord(x, y); + break; + } + } + } +} + +void SetReturnLvlPos() +{ + switch(setlvlnum) { + case SL_SKELKING: + ReturnLvlX = quests[Q_SKELKING]._qtx + 1; + ReturnLvlY = quests[Q_SKELKING]._qty; + ReturnLvl = quests[Q_SKELKING]._qlevel; + ReturnLvlT = DTYPE_CATHEDRAL; + break; + case SL_BONECHAMB: + ReturnLvlX = quests[Q_SCHAMB]._qtx + 1; + ReturnLvlY = quests[Q_SCHAMB]._qty; + ReturnLvl = quests[Q_SCHAMB]._qlevel; + ReturnLvlT = DTYPE_CATACOMBS; + break; + case SL_POISONWATER: + ReturnLvlX = quests[Q_PWATER]._qtx; + ReturnLvlY = quests[Q_PWATER]._qty + 1; + ReturnLvl = quests[Q_PWATER]._qlevel; + ReturnLvlT = DTYPE_CATHEDRAL; + break; + case SL_VILEBETRAYER: + ReturnLvlX = quests[Q_BETRAYER]._qtx + 1; + ReturnLvlY = quests[Q_BETRAYER]._qty - 1; + ReturnLvl = quests[Q_BETRAYER]._qlevel; + ReturnLvlT = DTYPE_HELL; + break; + } +} + +void GetReturnLvlPos() +{ + if(quests[Q_BETRAYER]._qactive == 3) { + quests[Q_BETRAYER]._qvar2 = 2; + } + + ViewX = ReturnLvlX; + ViewY = ReturnLvlY; + currlevel = ReturnLvl; + leveltype = ReturnLvlT; +} + +void ResyncMPQuests() +{ + if(quests[Q_SKELKING]._qactive == 1 && currlevel >= quests[Q_SKELKING]._qlevel - 1 && currlevel <= quests[Q_SKELKING]._qlevel + 1) { + quests[Q_SKELKING]._qactive = 2; + NetSendCmdQuest(TRUE, Q_SKELKING); + } + if(quests[Q_BUTCHER]._qactive == 1 && currlevel >= quests[Q_BUTCHER]._qlevel - 1 && currlevel <= quests[Q_BUTCHER]._qlevel + 1) { + quests[Q_BUTCHER]._qactive = 2; + NetSendCmdQuest(TRUE, Q_BUTCHER); + } + if(quests[Q_BETRAYER]._qactive == 1 && currlevel == quests[Q_BETRAYER]._qlevel - 1) { + quests[Q_BETRAYER]._qactive = 2; + NetSendCmdQuest(TRUE, Q_BETRAYER); + } + if(QuestStatus(Q_BETRAYER)) { + AddObject(OBJ_ALTBOY, 2 * setpc_x + 20, 2 * setpc_y + 22); + } +} + +void ResyncQuests() +{ + int i, tren; + + if(setlevel && setlvlnum == quests[Q_PWATER]._qslvl && quests[Q_PWATER]._qactive != 1 && leveltype == quests[Q_PWATER]._qlvltype) { + if(quests[Q_PWATER]._qactive == 3) { + LoadPalette("Levels\\L3Data\\L3pwater.pal"); + } else { + LoadPalette("Levels\\L3Data\\L3pfoul.pal"); + } + for(i = 0; i <= 32; i++) { + Lava2Water(i); + } + } + if(QuestStatus(Q_LTBANNER)) { + if(quests[Q_LTBANNER]._qvar1 == 1) { + ObjChangeMapResync(setpc_x + setpc_w - 2, setpc_y + setpc_h - 2, setpc_x + setpc_w + 1, setpc_y + setpc_h + 1); + } + if(quests[Q_LTBANNER]._qvar1 == 2) { + ObjChangeMapResync(setpc_x + setpc_w - 2, setpc_y + setpc_h - 2, setpc_x + setpc_w + 1, setpc_y + setpc_h + 1); + ObjChangeMapResync(setpc_x, setpc_y, setpc_x + (setpc_w >> 1) + 2, setpc_y + (setpc_h >> 1) - 2); + for(i = 0; i < nobjects; i++) { + SyncObjectAnim(objectactive[i]); + } + tren = TransVal; + TransVal = 9; + DRLG_MRectTrans(setpc_x, setpc_y, setpc_x + (setpc_w >> 1) + 4, setpc_y + (setpc_h >> 1)); + TransVal = tren; + } + if(quests[Q_LTBANNER]._qvar1 == 3) { + ObjChangeMapResync(setpc_x, setpc_y, setpc_x + setpc_w + 1, setpc_y + setpc_h + 1); + for(i = 0; i < nobjects; i++) { + SyncObjectAnim(objectactive[i]); + } + tren = TransVal; + TransVal = 9; + DRLG_MRectTrans(setpc_x, setpc_y, setpc_x + (setpc_w >> 1) + 4, setpc_y + (setpc_h >> 1)); + TransVal = tren; + } + } + if(currlevel == quests[Q_MUSHROOM]._qlevel) { + if(quests[Q_MUSHROOM]._qactive == 1) { + if(quests[Q_MUSHROOM]._qvar1 == 0) { + SpawnQuestItem(IDI_FUNGALTM, 0, 0, 5, 1); + quests[Q_MUSHROOM]._qvar1 = 1; + } + } else if(quests[Q_MUSHROOM]._qactive == 2) { + if(quests[Q_MUSHROOM]._qvar1 >= 5) { + Qtalklist[TOWN_HEALER][Q_MUSHROOM] = TEXT_MUSH3; + Qtalklist[TOWN_WITCH][Q_MUSHROOM] = -1; + } else if(quests[Q_MUSHROOM]._qvar1 >= 7) { + Qtalklist[TOWN_HEALER][Q_MUSHROOM] = -1; + } + } + } + if(currlevel == quests[Q_VEIL]._qlevel + 1 && quests[Q_VEIL]._qactive == 2 && quests[Q_VEIL]._qvar1 == 0) { + quests[Q_VEIL]._qvar1 = 1; + SpawnQuestItem(IDI_GLDNELIX, 0, 0, 5, 1); + } + if(setlevel && setlvlnum == SL_VILEBETRAYER) { + if(quests[Q_BETRAYER]._qvar1 >= 4) { + ObjChangeMapResync(1, 11, 20, 18); + } + if(quests[Q_BETRAYER]._qvar1 >= 6) { + ObjChangeMapResync(1, 18, 20, 24); + } + if(quests[Q_BETRAYER]._qvar1 >= 7) { + InitVPTriggers(); + } + for(i = 0; i < nobjects; i++) { + SyncObjectAnim(objectactive[i]); + } + } + if(currlevel == quests[Q_BETRAYER]._qlevel + && !setlevel + && (quests[Q_BETRAYER]._qvar2 == 1 || quests[Q_BETRAYER]._qvar2 >= 3) + && (quests[Q_BETRAYER]._qactive == 2 || quests[Q_BETRAYER]._qactive == 3)) { + quests[Q_BETRAYER]._qvar2 = 2; + } +} + +void PrintQLString(int x, int y, BOOL cjustflag, char *str, int col) +{ + int sx, sy, len, l, i, w, No; + BYTE c; + + sy = SStringY[y]; + No = x + PitchTbl[sy + 204] + 96; + len = strlen(str); + + w = 0; + if(cjustflag) { + l = 0; + for(i = 0; i < len; i++) { + c = fontframe[gbFontTransTbl[(BYTE)str[i]]]; + l += fontkern[c] + 1; + } + if(l < 257) { + w = (257 - l) >> 1; + } + No += w; + } + if(qline == y) { + if(cjustflag) { + sx = x + w + 76; + } else { + sx = x + 76; + } + CelDecodeOnly(sx, sy + 205, (BYTE *)pSPentSpnCels, ALLQUESTS, 12); + } + + for(i = 0; i < len; i++) { + c = fontframe[gbFontTransTbl[(BYTE)str[i]]]; + w += fontkern[c] + 1; + if(c != 0 && w <= 257) { + PrintChar(No, c, col); + } + No += fontkern[c] + 1; + } + + if(qline == y) { + if(cjustflag) { + sx = x + w + 100; + } else { + sx = 340 - x; + } + CelDecodeOnly(sx, sy + 205, (BYTE *)pSPentSpnCels, ALLQUESTS, 12); + } +} + +void DrawQuestLog() +{ + int i, l, q; + + PrintQLString(0, 2, TRUE, "Quest Log", COL_GOLD); + CelDecodeOnly(64, 511, (BYTE *)pQLogCel, 1, 320); + + l = qtopline; + for(i = 0; i < numqlines; i++) { + q = qlist[i]; + PrintQLString(0, l, TRUE, questlist[q]._qlstr, COL_WHITE); + l += 2; + } + + PrintQLString(0, 22, TRUE, "Close Quest Log", COL_WHITE); + ALLQUESTS = (ALLQUESTS & 7) + 1; +} + +void StartQuestlog() +{ + int i; + + numqlines = 0; + for(i = 0; (DWORD)i < MAXQUESTS; i++) { + if(quests[i]._qactive == 2 && quests[i]._qlog) { + qlist[numqlines] = i; + numqlines++; + } + } + + if(numqlines > 5) { + qtopline = 5 - (numqlines >> 1); + } else { + qtopline = 8; + } + + if(numqlines == 0) { + qline = 22; + } else { + qline = qtopline; + } + + questlog = 1; + ALLQUESTS = 1; +} + +void QuestlogUp() +{ + if(numqlines != 0) { + if(qline == qtopline) { + qline = 22; + } else if(qline == 22) { + qline = qtopline + 2 * numqlines - 2; + } else { + qline -= 2; + } + PlaySFX(IS_TITLEMOV); + } +} + +void QuestlogDown() +{ + if(numqlines != 0) { + if(qline == 22) { + qline = qtopline; + } else if(qline == qtopline + 2 * numqlines - 2) { + qline = 22; + } else { + qline += 2; + } + PlaySFX(IS_TITLEMOV); + } +} + +void QuestlogEnter() +{ + int q; + + PlaySFX(IS_TITLSLCT); + + if(numqlines != 0 && qline != 22) { + q = qlist[(qline - qtopline) >> 1]; + InitQTextMsg(quests[q]._qmsg); + } + + questlog = 0; +} + +void QuestlogESC() +{ + int i, l; + + l = (MouseY - 32) / 12; + if(numqlines != 0) { + for(i = 0; i < numqlines; i++) { + if(l == qtopline + 2 * i) { + qline = l; + QuestlogEnter(); + } + } + } + if(l == 22) { + qline = 22; + QuestlogEnter(); + } +} + +void SetMultiQuest(int q, int s, BOOL l, int v1) +{ + /// ASSERT: assert((DWORD)q < MAXQUESTS); + /// ASSERT: assert(quests[q]._qactive != QUEST_NOTAVAIL); + if(quests[q]._qactive == 3) { + return; + } + + if(s > quests[q]._qactive) { + quests[q]._qactive = s; + } + + quests[q]._qlog |= l; + + if(v1 > quests[q]._qvar1) { + quests[q]._qvar1 = v1; + } +} diff --git a/2020_03_31/Source/quests.h b/2020_03_31/Source/quests.h new file mode 100644 index 00000000..5f588d88 --- /dev/null +++ b/2020_03_31/Source/quests.h @@ -0,0 +1,55 @@ +//HEADER_GOES_HERE +#ifndef __QUESTS_H__ +#define __QUESTS_H__ + +extern int qtopline; // idb +extern int questlog; // weak +extern void *pQLogCel; +extern QuestStruct quests[MAXQUESTS]; +extern int qline; // weak +extern int qlist[MAXQUESTS]; +extern int numqlines; // weak +extern int WaterDone; // idb +extern int ReturnLvlY; // idb +extern int ReturnLvlX; // idb +extern int ReturnLvlT; // idb +extern int ALLQUESTS; // idb +extern int ReturnLvl; // idb + +void InitQuests(); +void CheckQuests(); +BOOL ForceQuests(); +BOOL QuestStatus(int i); +void CheckQuestKill(int m, BOOL sendmsg); +void DrawButcher(); +void DrawSkelKing(int q, int x, int y); +void DrawWarLord(int x, int y); +void DrawSChamber(int q, int x, int y); +void DrawLTBanner(int x, int y); +void DrawBlind(int x, int y); +void DrawBlood(int x, int y); +void DRLG_CheckQuests(int x, int y); +void SetReturnLvlPos(); +void GetReturnLvlPos(); +void ResyncMPQuests(); +void ResyncQuests(); +void PrintQLString(int x, int y, BOOL cjustflag, char *str, int col); +void DrawQuestLog(); +void StartQuestlog(); +void QuestlogUp(); +void QuestlogDown(); +void QuestlogEnter(); +void QuestlogESC(); +void SetMultiQuest(int q, int s, BOOL l, int v1); + +/* rdata */ +extern QuestData questlist[MAXQUESTS]; +extern char questxoff[7]; +extern char questyoff[7]; +extern char *questtrigstr[5]; +extern int QuestGroup1[3]; +extern int QuestGroup2[3]; +extern int QuestGroup3[3]; +extern int QuestGroup4[2]; + +#endif /* __QUESTS_H__ */ diff --git a/2020_03_31/Source/render.cpp b/2020_03_31/Source/render.cpp new file mode 100644 index 00000000..dd75f0b2 --- /dev/null +++ b/2020_03_31/Source/render.cpp @@ -0,0 +1,6539 @@ +#include "diablo.h" +#include "_asm.cpp" + +int WorldBoolFlag = 0; +unsigned int gdwCurrentMask = 0; +// char world_4B3264 = 0; +unsigned char *gpCelFrame = NULL; +unsigned int *gpDrawMask = NULL; +// char world_4B326D[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + +unsigned int RightMask[32] = +{ + 0xEAAAAAAA, 0xF5555555, 0xFEAAAAAA, 0xFF555555, 0xFFEAAAAA, 0xFFF55555, 0xFFFEAAAA, 0xFFFF5555, + 0xFFFFEAAA, 0xFFFFF555, 0xFFFFFEAA, 0xFFFFFF55, 0xFFFFFFEA, 0xFFFFFFF5, 0xFFFFFFFE, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF +}; + +unsigned int LeftMask[32] = +{ + 0xAAAAAAAB, 0x5555555F, 0xAAAAAABF, 0x555555FF, 0xAAAAABFF, 0x55555FFF, 0xAAAABFFF, 0x5555FFFF, + 0xAAABFFFF, 0x555FFFFF, 0xAABFFFFF, 0x55FFFFFF, 0xABFFFFFF, 0x5FFFFFFF, 0xBFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF +}; + +unsigned int WallMask[32] = +{ + 0xAAAAAAAA, 0x55555555, 0xAAAAAAAA, 0x55555555, 0xAAAAAAAA, 0x55555555, 0xAAAAAAAA, 0x55555555, + 0xAAAAAAAA, 0x55555555, 0xAAAAAAAA, 0x55555555, 0xAAAAAAAA, 0x55555555, 0xAAAAAAAA, 0x55555555, + 0xAAAAAAAA, 0x55555555, 0xAAAAAAAA, 0x55555555, 0xAAAAAAAA, 0x55555555, 0xAAAAAAAA, 0x55555555, + 0xAAAAAAAA, 0x55555555, 0xAAAAAAAA, 0x55555555, 0xAAAAAAAA, 0x55555555, 0xAAAAAAAA, 0x55555555 +}; + +int WorldTbl3x16[48] = +{ + 0, 0, 0, + 4, 4, 4, + 8, 8, 8, + 12, 12, 12, + 16, 16, 16, + 20, 20, 20, + 24, 24, 24, + 28, 28, 28, + 32, 32, 32, + 36, 36, 36, + 40, 40, 40, + 44, 44, 44, + 48, 48, 48, + 52, 52, 52, + 56, 56, 56, + 60, 60, 60 +}; + +// slope/angle tables, left and right +int WorldTbl17_1[17] = { 0, 4, 8, 16, 24, 36, 48, 64, 80, 100, 120, 144, 168, 196, 224, 256, 288 }; +int WorldTbl17_2[17] = { 0, 32, 60, 88, 112, 136, 156, 176, 192, 208, 220, 232, 240, 248, 252, 256, 288 }; + +/* + 32x32 arch types + add 8 if light index is 0 + + |-| 0x8 (0) + |-| + + /\ 0x9 (1) + \/ + + /| 0xA (2) + \| + + |\ 0xB (3) + |/ + + |-| 0xC (4) + \| + + |-| 0xD (5) + |/ +*/ + +#ifdef USE_ASM +#include "_render.cpp" +#else +void drawTopArchesUpperScreen(BYTE *pBuff) +{ + unsigned char *dst; // edi MAPDST + unsigned char *tbl; // ebx + unsigned char *src; // esi MAPDST + short cel_type_16; // ax MAPDST + signed int xx_32; // ebp MAPDST + signed int yy_32; // edx MAPDST + unsigned int width; // eax MAPDST + unsigned int chk_sh_and; // ecx MAPDST + unsigned int n_draw_shift; // ecx MAPDST + unsigned int x_minus; // ecx MAPDST + unsigned int y_minus; // ecx MAPDST + signed int i; // edx MAPDST + signed int j; // ecx MAPDST + + gpCelFrame = (unsigned char *)SpeedFrameTbl; + dst = pBuff; + if ( !(_BYTE)light_table_index ) + { + if ( level_cel_block & 0x8000 ) + level_cel_block = *(_DWORD *)&gpCelFrame[64 * (level_cel_block & 0xFFF)] + + (unsigned short)(level_cel_block & 0xF000); + src = (unsigned char *)pDungeonCels + *((_DWORD *)pDungeonCels + (level_cel_block & 0xFFF)); + cel_type_16 = ((level_cel_block >> 12) & 7) + 8; + goto LABEL_11; + } + if ( (_BYTE)light_table_index != lightmax ) + { + if ( !(level_cel_block & 0x8000) ) + { + src = (unsigned char *)pDungeonCels + *((_DWORD *)pDungeonCels + (level_cel_block & 0xFFF)); + tbl = &pLightTbl[256 * light_table_index]; + cel_type_16 = (unsigned char)(level_cel_block >> 12); + switch ( cel_type_16 ) + { + case 0: // upper (top transparent), with lighting + i = 16; + do + { + if ( dst < gpBufEnd ) + break; + asm_trans_light_square_1_3(8, tbl, dst, src); + dst -= 800; + if ( dst < gpBufEnd ) + break; + asm_trans_light_square_0_2(8, tbl, dst, src); + dst -= 800; + --i; + } + while ( i ); + break; + case 1: // upper (top transparent), with lighting + WorldBoolFlag = (unsigned char)pBuff & 1; + xx_32 = 32; + do + { + yy_32 = 32; + do + { + while ( 1 ) + { + width = (unsigned char)*src++; + if ( (width & 0x80u) == 0 ) + break; + _LOBYTE(width) = -(char)width; + dst += width; + yy_32 -= width; + if ( !yy_32 ) + goto LABEL_67; + } + if ( dst < gpBufEnd ) + return; + if ( ((unsigned char)dst & 1) == WorldBoolFlag ) + { + asm_trans_light_cel_0_2(width, tbl, dst, src); + } + else + { + asm_trans_light_cel_1_3(width, tbl, dst, src); + } + yy_32 -= width; + } + while ( yy_32 ); +LABEL_67: + WorldBoolFlag = ((_BYTE)WorldBoolFlag + 1) & 1; + dst -= 800; + --xx_32; + } + while ( xx_32 ); + break; + case 2: // upper (top transparent), with lighting + WorldBoolFlag = 0; + xx_32 = 30; + while ( dst >= gpBufEnd ) + { + dst += xx_32; + src += (32 - (_BYTE)xx_32) & 2; + WorldBoolFlag = ((_BYTE)WorldBoolFlag + 1) & 1; + if ( WorldBoolFlag ) + { + asm_trans_light_cel_0_2(32 - xx_32, tbl, dst, src); + } + else + { + asm_trans_light_cel_1_3(32 - xx_32, tbl, dst, src); + } + dst -= 800; + xx_32 -= 2; + if ( xx_32 < 0 ) + { + yy_32 = 2; + do + { + if ( dst < gpBufEnd ) + break; + dst += yy_32; + src += (32 - (_BYTE)yy_32) & 2; + WorldBoolFlag = ((_BYTE)WorldBoolFlag + 1) & 1; + if ( WorldBoolFlag ) + { + asm_trans_light_cel_0_2(32 - yy_32, tbl, dst, src); + } + else + { + asm_trans_light_cel_1_3(32 - yy_32, tbl, dst, src); + } + dst -= 800; + yy_32 += 2; + } + while ( yy_32 != 32 ); + return; + } + } + break; + case 3: // upper (top transparent), with lighting + WorldBoolFlag = 0; + xx_32 = 30; + while ( dst >= gpBufEnd ) + { + WorldBoolFlag = ((_BYTE)WorldBoolFlag + 1) & 1; + if ( WorldBoolFlag ) + { + asm_trans_light_cel_0_2(32 - xx_32, tbl, dst, src); + } + else + { + asm_trans_light_cel_1_3(32 - xx_32, tbl, dst, src); + } + src += (unsigned char)src & 2; + dst = &dst[xx_32 - 800]; + xx_32 -= 2; + if ( xx_32 < 0 ) + { + yy_32 = 2; + do + { + if ( dst < gpBufEnd ) + break; + WorldBoolFlag = ((_BYTE)WorldBoolFlag + 1) & 1; + if ( WorldBoolFlag ) + { + asm_trans_light_cel_0_2(32 - yy_32, tbl, dst, src); + } + else + { + asm_trans_light_cel_1_3(32 - yy_32, tbl, dst, src); + } + src += (unsigned char)src & 2; + dst = &dst[yy_32 - 800]; + yy_32 += 2; + } + while ( yy_32 != 32 ); + return; + } + } + break; + case 4: // upper (top transparent), with lighting + WorldBoolFlag = 0; + xx_32 = 30; + while ( dst >= gpBufEnd ) + { + dst += xx_32; + src += (32 - (_BYTE)xx_32) & 2; + WorldBoolFlag = ((_BYTE)WorldBoolFlag + 1) & 1; + if ( WorldBoolFlag ) + { + asm_trans_light_cel_0_2(32 - xx_32, tbl, dst, src); + } + else + { + asm_trans_light_cel_1_3(32 - xx_32, tbl, dst, src); + } + dst -= 800; + xx_32 -= 2; + if ( xx_32 < 0 ) + { + i = 8; + do + { + if ( dst < gpBufEnd ) + break; + asm_trans_light_square_1_3(8, tbl, dst, src); + dst -= 800; + if ( dst < gpBufEnd ) + break; + asm_trans_light_square_0_2(8, tbl, dst, src); + dst -= 800; + --i; + } + while ( i ); + return; + } + } + break; + default: // upper (top transparent), with lighting + WorldBoolFlag = 0; + xx_32 = 30; + while ( dst >= gpBufEnd ) + { + WorldBoolFlag = ((_BYTE)WorldBoolFlag + 1) & 1; + if ( WorldBoolFlag ) + { + asm_trans_light_cel_0_2(32 - xx_32, tbl, dst, src); + } + else + { + asm_trans_light_cel_1_3(32 - xx_32, tbl, dst, src); + } + src += (unsigned char)src & 2; + dst = &dst[xx_32 - 800]; + xx_32 -= 2; + if ( xx_32 < 0 ) + { + i = 8; + do + { + if ( dst < gpBufEnd ) + break; + asm_trans_light_square_1_3(8, tbl, dst, src); + dst -= 800; + if ( dst < gpBufEnd ) + break; + asm_trans_light_square_0_2(8, tbl, dst, src); + dst -= 800; + --i; + } + while ( i ); + return; + } + } + break; + } + return; + } + src = (unsigned char *)pSpeedCels + + *(_DWORD *)&gpCelFrame[4 * (light_table_index + 16 * (level_cel_block & 0xFFF))]; + cel_type_16 = (unsigned char)(level_cel_block >> 12); +LABEL_11: + + switch ( cel_type_16 ) + { + case 8: // upper (top transparent), without lighting + i = 16; + do + { + if ( dst < gpBufEnd ) + break; + j = 8; + do + { + dst[1] = src[1]; + dst[3] = src[3]; + src += 4; + dst += 4; + --j; + } + while ( j ); + dst -= 800; + if ( dst < gpBufEnd ) + break; + j = 8; + do + { + dst[0] = src[0]; + dst[2] = src[2]; + src += 4; + dst += 4; + --j; + } + while ( j ); + dst -= 800; + --i; + } + while ( i ); + break; + case 9: // upper (top transparent), without lighting + WorldBoolFlag = (unsigned char)pBuff & 1; + yy_32 = 32; +LABEL_251: + xx_32 = 32; + while ( 1 ) + { + while ( 1 ) + { + width = (unsigned char)*src++; + if ( (width & 0x80u) == 0 ) + break; + _LOBYTE(width) = -(char)width; + dst += width; + xx_32 -= width; + if ( !xx_32 ) + { +LABEL_271: + WorldBoolFlag = ((_BYTE)WorldBoolFlag + 1) & 1; + dst -= 800; + if ( !--yy_32 ) + return; + goto LABEL_251; + } + } + xx_32 -= width; + if ( dst < gpBufEnd ) + return; + if ( ((unsigned char)dst & 1) == WorldBoolFlag ) + { + chk_sh_and = width >> 1; + if ( !(width & 1) ) + goto LABEL_258; + ++src; + ++dst; + if ( chk_sh_and ) + { +LABEL_265: + n_draw_shift = chk_sh_and >> 1; + if ( chk_sh_and & 1 ) + { + dst[0] = src[0]; + src += 2; + dst += 2; + } + if ( n_draw_shift ) + { + do + { + dst[0] = src[0]; + dst[2] = src[2]; + src += 4; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + goto LABEL_268; + } + } + else + { + chk_sh_and = width >> 1; + if ( !(width & 1) ) + goto LABEL_265; + *dst++ = *src++; + if ( chk_sh_and ) + { +LABEL_258: + n_draw_shift = chk_sh_and >> 1; + if ( chk_sh_and & 1 ) + { + dst[1] = src[1]; + src += 2; + dst += 2; + } + if ( n_draw_shift ) + { + do + { + dst[1] = src[1]; + dst[3] = src[3]; + src += 4; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + goto LABEL_268; + } + } +LABEL_268: + if ( !xx_32 ) + goto LABEL_271; + } + break; + case 10: // upper (top transparent), without lighting + WorldBoolFlag = 0; + xx_32 = 30; + while ( dst >= gpBufEnd ) + { + dst += xx_32; + x_minus = 32 - xx_32; + WorldBoolFlag = ((_BYTE)WorldBoolFlag + 1) & 1; + if ( WorldBoolFlag ) + { + n_draw_shift = x_minus >> 2; + if ( x_minus & 2 ) + { + dst[1] = src[3]; + src += 4; + dst += 2; + } + if ( n_draw_shift ) + { + do + { + dst[1] = src[1]; + dst[3] = src[3]; + src += 4; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + } + else + { + n_draw_shift = x_minus >> 2; + if ( x_minus & 2 ) + { + dst[0] = src[2]; + src += 4; + dst += 2; + } + if ( n_draw_shift ) + { + do + { + dst[0] = src[0]; + dst[2] = src[2]; + src += 4; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + } + dst -= 800; + xx_32 -= 2; + if ( xx_32 < 0 ) + { + yy_32 = 2; + do + { + if ( dst < gpBufEnd ) + break; + dst += yy_32; + y_minus = 32 - yy_32; + WorldBoolFlag = ((_BYTE)WorldBoolFlag + 1) & 1; + if ( WorldBoolFlag ) + { + n_draw_shift = y_minus >> 2; + if ( y_minus & 2 ) + { + dst[1] = src[3]; + src += 4; + dst += 2; + } + if ( n_draw_shift ) + { + do + { + dst[1] = src[1]; + dst[3] = src[3]; + src += 4; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + } + else + { + n_draw_shift = y_minus >> 2; + if ( y_minus & 2 ) + { + dst[0] = src[2]; + src += 4; + dst += 2; + } + if ( n_draw_shift ) + { + do + { + dst[0] = src[0]; + dst[2] = src[2]; + src += 4; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + } + dst -= 800; + yy_32 += 2; + } + while ( yy_32 != 32 ); + return; + } + } + break; + case 11: // upper (top transparent), without lighting + WorldBoolFlag = 0; + xx_32 = 30; + while ( dst >= gpBufEnd ) + { + x_minus = 32 - xx_32; + WorldBoolFlag = ((_BYTE)WorldBoolFlag + 1) & 1; + if ( WorldBoolFlag ) + { + for ( n_draw_shift = x_minus >> 2; n_draw_shift; --n_draw_shift ) + { + dst[1] = src[1]; + dst[3] = src[3]; + src += 4; + dst += 4; + } + if ( x_minus & 2 ) + { + dst[1] = src[1]; + src += 4; + dst += 2; + } + } + else + { + for ( n_draw_shift = x_minus >> 2; n_draw_shift; --n_draw_shift ) + { + dst[0] = src[0]; + dst[2] = src[2]; + src += 4; + dst += 4; + } + if ( x_minus & 2 ) + { + dst[0] = src[0]; + src += 4; + dst += 2; + } + } + dst = &dst[xx_32 - 800]; + xx_32 -= 2; + if ( xx_32 < 0 ) + { + yy_32 = 2; + do + { + if ( dst < gpBufEnd ) + break; + y_minus = 32 - yy_32; + WorldBoolFlag = ((_BYTE)WorldBoolFlag + 1) & 1; + if ( WorldBoolFlag ) + { + for ( n_draw_shift = y_minus >> 2; n_draw_shift; --n_draw_shift ) + { + dst[1] = src[1]; + dst[3] = src[3]; + src += 4; + dst += 4; + } + if ( x_minus & 2 ) /// BUGFIX: change to `y_minus & 2` + { + dst[1] = src[1]; + src += 4; + dst += 2; + } + } + else + { + for ( n_draw_shift = y_minus >> 2; n_draw_shift; --n_draw_shift ) + { + dst[0] = src[0]; + dst[2] = src[2]; + src += 4; + dst += 4; + } + if ( x_minus & 2 ) /// BUGFIX: change to `y_minus & 2` + { + dst[0] = src[0]; + src += 4; + dst += 2; + } + } + dst = &dst[yy_32 - 800]; + yy_32 += 2; + } + while ( yy_32 != 32 ); + return; + } + } + break; + case 12: // upper (top transparent), without lighting + WorldBoolFlag = 0; + xx_32 = 30; + while ( dst >= gpBufEnd ) + { + dst += xx_32; + x_minus = 32 - xx_32; + WorldBoolFlag = ((_BYTE)WorldBoolFlag + 1) & 1; + if ( WorldBoolFlag ) + { + n_draw_shift = x_minus >> 2; + if ( x_minus & 2 ) + { + dst[1] = src[3]; + src += 4; + dst += 2; + } + if ( n_draw_shift) + { + do + { + dst[1] = src[1]; + dst[3] = src[3]; + src += 4; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + } + else + { + n_draw_shift = x_minus >> 2; + if ( x_minus & 2 ) + { + dst[0] = src[2]; + src += 4; + dst += 2; + } + if ( n_draw_shift ) + { + do + { + dst[0] = src[0]; + dst[2] = src[2]; + src += 4; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + } + dst -= 800; + xx_32 -= 2; + if ( xx_32 < 0 ) + { + i = 8; + do + { + if ( dst < gpBufEnd ) + break; + j = 8; + do + { + dst[1] = src[1]; + dst[3] = src[3]; + src += 4; + dst += 4; + --j; + } + while ( j ); + dst -= 800; + if ( dst < gpBufEnd ) + break; + j = 8; + do + { + dst[0] = src[0]; + dst[2] = src[2]; + src += 4; + dst += 4; + --j; + } + while ( j ); + dst -= 800; + --i; + } + while ( i ); + return; + } + } + break; + default: // upper (top transparent), without lighting + WorldBoolFlag = 0; + xx_32 = 30; + while ( dst >= gpBufEnd ) + { + x_minus = 32 - xx_32; + WorldBoolFlag = ((_BYTE)WorldBoolFlag + 1) & 1; + if ( WorldBoolFlag ) + { + for ( n_draw_shift = x_minus >> 2; n_draw_shift; --n_draw_shift ) + { + dst[1] = src[1]; + dst[3] = src[3]; + src += 4; + dst += 4; + } + if ( (32 - (_BYTE)xx_32) & 2 ) + { + dst[1] = src[1]; + src += 4; + dst += 2; + } + } + else + { + for ( n_draw_shift = x_minus >> 2; n_draw_shift; --n_draw_shift ) + { + dst[0] = src[0]; + dst[2] = src[2]; + src += 4; + dst += 4; + } + if ( (32 - (_BYTE)xx_32) & 2 ) + { + dst[0] = src[0]; + src += 4; + dst += 2; + } + } + dst = &dst[xx_32 - 800]; + xx_32 -= 2; + if ( xx_32 < 0 ) + { + i = 8; + do + { + if ( dst < gpBufEnd ) + break; + j = 8; + do + { + dst[1] = src[1]; + dst[3] = src[3]; + src += 4; + dst += 4; + --j; + } + while ( j ); + dst -= 800; + if ( dst < gpBufEnd ) + break; + j = 8; + do + { + dst[0] = src[0]; + dst[2] = src[2]; + src += 4; + dst += 4; + --j; + } + while ( j ); + dst -= 800; + --i; + } + while ( i ); + return; + } + } + break; + } + return; + } + if ( level_cel_block & 0x8000 ) + level_cel_block = *(_DWORD *)&gpCelFrame[64 * (level_cel_block & 0xFFF)] + + (unsigned short)(level_cel_block & 0xF000); + src = (unsigned char *)pDungeonCels + *((_DWORD *)pDungeonCels + (level_cel_block & 0xFFF)); + cel_type_16 = (level_cel_block >> 12) & 7; + switch ( cel_type_16 ) + { + case 0: // upper (top transparent), black + i = 16; + do + { + if ( dst < gpBufEnd ) + break; + j = 8; + do + { + dst[1] = 0; + dst[3] = 0; + dst += 4; + --j; + } + while ( j ); + dst -= 800; + if ( dst < gpBufEnd ) + break; + j = 8; + do + { + dst[0] = 0; + dst[2] = 0; + dst += 4; + --j; + } + while ( j ); + dst -= 800; + --i; + } + while ( i ); + break; + case 1: // upper (top transparent), black + WorldBoolFlag = (unsigned char)pBuff & 1; + xx_32 = 32; + while ( 1 ) + { + yy_32 = 32; + do + { + while ( 1 ) + { + width = (unsigned char)*src++; + if ( (width & 0x80u) != 0 ) + break; + yy_32 -= width; + if ( dst < gpBufEnd ) + return; + src += width; + if ( ((unsigned char)dst & 1) == WorldBoolFlag ) + { + chk_sh_and = width >> 1; + if ( !(width & 1) ) + goto LABEL_378; + ++dst; + if ( chk_sh_and ) + { +LABEL_385: + n_draw_shift = chk_sh_and >> 1; + if ( chk_sh_and & 1 ) + { + dst[0] = 0; + dst += 2; + } + if ( n_draw_shift ) + { + do + { + dst[0] = 0; + dst[2] = 0; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + goto LABEL_388; + } + } + else + { + chk_sh_and = width >> 1; + if ( !(width & 1) ) + goto LABEL_385; + *dst++ = 0; + if ( chk_sh_and ) + { +LABEL_378: + n_draw_shift = chk_sh_and >> 1; + if ( chk_sh_and & 1 ) + { + dst[1] = 0; + dst += 2; + } + if ( n_draw_shift ) + { + do + { + dst[1] = 0; + dst[3] = 0; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + goto LABEL_388; + } + } +LABEL_388: + if ( !yy_32 ) + goto LABEL_391; + } + _LOBYTE(width) = -(char)width; + dst += width; + yy_32 -= width; + } + while ( yy_32 ); +LABEL_391: + WorldBoolFlag = ((_BYTE)WorldBoolFlag + 1) & 1; + dst -= 800; + if ( !--xx_32 ) + return; + } + case 2: // upper (top transparent), black + WorldBoolFlag = 0; + for ( xx_32 = 30; ; xx_32 -= 2 ) + { + if ( dst < gpBufEnd ) + return; + dst += xx_32; + x_minus = 32 - xx_32; + WorldBoolFlag = ((_BYTE)WorldBoolFlag + 1) & 1; + if ( WorldBoolFlag ) + { + n_draw_shift = x_minus >> 2; + if ( x_minus & 2 ) + { + dst[1] = 0; + dst += 2; + } + if ( n_draw_shift ) + { + do + { + dst[1] = 0; + dst[3] = 0; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + } + else + { + n_draw_shift = x_minus >> 2; + if ( x_minus & 2 ) + { + dst[0] = 0; + dst += 2; + } + if ( n_draw_shift) + { + do + { + dst[0] = 0; + dst[2] = 0; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + } + dst -= 800; + if ( !xx_32 ) + break; + } + yy_32 = 2; + do + { + if ( dst < gpBufEnd ) + break; + dst += yy_32; + y_minus = 32 - yy_32; + WorldBoolFlag = ((_BYTE)WorldBoolFlag + 1) & 1; + if ( WorldBoolFlag ) + { + n_draw_shift = y_minus >> 2; + if ( y_minus & 2 ) + { + dst[1] = 0; + dst += 2; + } + if ( n_draw_shift ) + { + do + { + dst[1] = 0; + dst[3] = 0; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + } + else + { + n_draw_shift = y_minus >> 2; + if ( y_minus & 2 ) + { + dst[0] = 0; + dst += 2; + } + if ( n_draw_shift) + { + do + { + dst[0] = 0; + dst[2] = 0; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + } + dst -= 800; + yy_32 += 2; + } + while ( yy_32 != 32 ); + break; + case 3: // upper (top transparent), black + WorldBoolFlag = 0; + for ( xx_32 = 30; ; xx_32 -= 2 ) + { + if ( dst < gpBufEnd ) + return; + x_minus = 32 - xx_32; + WorldBoolFlag = ((_BYTE)WorldBoolFlag + 1) & 1; + if ( WorldBoolFlag ) + { + n_draw_shift = x_minus >> 2; + if ( x_minus & 2 ) + { + dst[1] = 0; + dst += 2; + } + if ( n_draw_shift ) + { + do + { + dst[1] = 0; + dst[3] = 0; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + } + else + { + n_draw_shift = x_minus >> 2; + if ( x_minus & 2 ) + { + dst[0] = 0; + dst += 2; + } + if ( n_draw_shift ) + { + do + { + dst[0] = 0; + dst[2] = 0; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + } + dst -= 800; + if ( !xx_32 ) + break; + dst += xx_32; + } + yy_32 = 2; + do + { + if ( dst < gpBufEnd ) + break; + y_minus = 32 - yy_32; + WorldBoolFlag = ((_BYTE)WorldBoolFlag + 1) & 1; + if ( WorldBoolFlag ) + { + n_draw_shift = y_minus >> 2; + if ( y_minus & 2 ) + { + dst[1] = 0; + dst += 2; + } + if ( n_draw_shift ) + { + do + { + dst[1] = 0; + dst[3] = 0; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + } + else + { + n_draw_shift = y_minus >> 2; + if ( y_minus & 2 ) + { + dst[0] = 0; + dst += 2; + } + if ( n_draw_shift ) + { + do + { + dst[0] = 0; + dst[2] = 0; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + } + dst = &dst[yy_32 - 800]; + yy_32 += 2; + } + while ( yy_32 != 32 ); + break; + case 4: // upper (top transparent), black + WorldBoolFlag = 0; + for ( xx_32 = 30; ; xx_32 -= 2 ) + { + if ( dst < gpBufEnd ) + return; + dst += xx_32; + x_minus = 32 - xx_32; + WorldBoolFlag = ((_BYTE)WorldBoolFlag + 1) & 1; + if ( WorldBoolFlag ) + { + n_draw_shift = x_minus >> 2; + if ( x_minus & 2 ) + { + dst[1] = 0; + dst += 2; + } + if ( n_draw_shift ) + { + do + { + dst[1] = 0; + dst[3] = 0; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + } + else + { + n_draw_shift = x_minus >> 2; + if ( x_minus & 2 ) + { + dst[0] = 0; + dst += 2; + } + if ( n_draw_shift ) + { + do + { + dst[0] = 0; + dst[2] = 0; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + } + dst -= 800; + if ( !xx_32 ) + break; + } + i = 8; + do + { + if ( dst < gpBufEnd ) + break; + j = 8; + do + { + dst[1] = 0; + dst[3] = 0; + dst += 4; + --j; + } + while ( j ); + dst -= 800; + if ( dst < gpBufEnd ) + break; + j = 8; + do + { + dst[0] = 0; + dst[2] = 0; + dst += 4; + --j; + } + while ( j ); + dst -= 800; + --i; + } + while ( i ); + break; + default: // upper (top transparent), black + WorldBoolFlag = 0; + for ( xx_32 = 30; ; xx_32 -= 2 ) + { + if ( dst < gpBufEnd ) + return; + x_minus = 32 - xx_32; + WorldBoolFlag = ((_BYTE)WorldBoolFlag + 1) & 1; + if ( WorldBoolFlag ) + { + n_draw_shift = x_minus >> 2; + if ( x_minus & 2 ) + { + dst[1] = 0; + dst += 2; + } + if ( n_draw_shift ) + { + do + { + dst[1] = 0; + dst[3] = 0; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + } + else + { + n_draw_shift = x_minus >> 2; + if ( x_minus & 2 ) + { + dst[0] = 0; + dst += 2; + } + if ( n_draw_shift ) + { + do + { + dst[0] = 0; + dst[2] = 0; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + } + dst -= 800; + if ( !xx_32 ) + break; + dst += xx_32; + } + i = 8; + do + { + if ( dst < gpBufEnd ) + break; + j = 8; + do + { + dst[1] = 0; + dst[3] = 0; + dst += 4; + --j; + } + while ( j ); + dst -= 800; + if ( dst < gpBufEnd ) + break; + j = 8; + do + { + dst[0] = 0; + dst[2] = 0; + dst += 4; + --j; + } + while ( j ); + dst -= 800; + --i; + } + while ( i ); + break; + } +} + +void drawBottomArchesUpperScreen(BYTE *pBuff, unsigned int *pMask) +{ + unsigned char *dst; // edi MAPDST + unsigned char *src; // esi MAPDST + short cel_type_16; // ax MAPDST + int xx_32; // edx MAPDST + unsigned int left_shift; // edx MAPDST + int yy_32; // edx MAPDST + int width; // eax MAPDST + int and80_i; // ecx MAPDST + unsigned int n_draw_shift; // ecx MAPDST + signed int i; // ecx MAPDST + unsigned char *tbl; + + gpCelFrame = (unsigned char *)SpeedFrameTbl; + dst = pBuff; + gpDrawMask = pMask; + if ( !(_BYTE)light_table_index ) + { + if ( level_cel_block & 0x8000 ) + level_cel_block = *(_DWORD *)&gpCelFrame[64 * (level_cel_block & 0xFFF)] + + (unsigned short)(level_cel_block & 0xF000); + src = (unsigned char *)pDungeonCels + *((_DWORD *)pDungeonCels + (level_cel_block & 0xFFF)); + cel_type_16 = ((level_cel_block >> 12) & 7) + 8; +LABEL_12: + switch ( cel_type_16 ) + { + case 8: // upper (bottom transparent), without lighting + xx_32 = 32; + do + { + if ( dst < gpBufEnd ) + break; + left_shift = *gpDrawMask; + i = 32; + do + { + if ( left_shift & 0x80000000 ) + dst[0] = src[0]; + left_shift *= 2; + ++src; + ++dst; + --i; + } + while ( i ); + dst -= 800; + --gpDrawMask; + --xx_32; + } + while ( xx_32 ); + break; + case 9: // upper (bottom transparent), without lighting + xx_32 = 32; + do + { + gdwCurrentMask = *gpDrawMask; + yy_32 = 32; + do + { + while ( 1 ) + { + width = (unsigned char)*src++; + if ( (width & 0x80u) == 0 ) + break; + _LOBYTE(width) = -(char)width; + dst += width; + if ( width & 0x1F ) + gdwCurrentMask <<= width & 0x1F; + yy_32 -= width; + if ( !yy_32 ) + goto LABEL_129; + } + yy_32 -= width; + if ( dst < gpBufEnd ) + return; + left_shift = gdwCurrentMask; + and80_i = width; + do + { + if ( left_shift & 0x80000000 ) + dst[0] = src[0]; + left_shift *= 2; + ++src; + ++dst; + --and80_i; + } + while ( and80_i ); + gdwCurrentMask = left_shift; + } + while ( yy_32 ); +LABEL_129: + dst -= 800; + --gpDrawMask; + --xx_32; + } + while ( xx_32 ); + break; + case 10: // upper (bottom transparent), without lighting + xx_32 = 30; + while ( dst >= gpBufEnd ) + { + dst += xx_32; + n_draw_shift = (unsigned int)(32 - xx_32) >> 2; + if ( (32 - xx_32) & 2 ) + { + *(_WORD *)dst = *((_WORD *)src + 1); + src += 4; + dst += 2; + } + if ( n_draw_shift ) + { + do + { + *(_DWORD *)dst = *(_DWORD *)src; + src += 4; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + dst -= 800; + xx_32 -= 2; + if ( xx_32 < 0 ) + { + yy_32 = 2; + do + { + if ( dst < gpBufEnd ) + break; + dst += yy_32; + n_draw_shift = (unsigned int)(32 - yy_32) >> 2; + if ( (32 - yy_32) & 2 ) + { + *(_WORD *)dst = *((_WORD *)src + 1); + src += 4; + dst += 2; + } + if ( n_draw_shift ) + { + do + { + *(_DWORD *)dst = *(_DWORD *)src; + src += 4; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + dst -= 800; + yy_32 += 2; + } + while ( yy_32 != 32 ); + return; + } + } + break; + case 11: // upper (bottom transparent), without lighting + xx_32 = 30; + while ( dst >= gpBufEnd ) + { + for ( n_draw_shift = (unsigned int)(32 - xx_32) >> 2; n_draw_shift; --n_draw_shift ) + { + *(_DWORD *)dst = *(_DWORD *)src; + src += 4; + dst += 4; + } + if ( (32 - (_BYTE)xx_32) & 2 ) + { + *(_WORD *)dst = *(_WORD *)src; + src += 4; + dst += 2; + } + dst = &dst[xx_32 - 800]; + xx_32 -= 2; + if ( xx_32 < 0 ) + { + yy_32 = 2; + do + { + if ( dst < gpBufEnd ) + break; + for ( n_draw_shift = (unsigned int)(32 - yy_32) >> 2; n_draw_shift; --n_draw_shift ) + { + *(_DWORD *)dst = *(_DWORD *)src; + src += 4; + dst += 4; + } + if ( (32 - (_BYTE)yy_32) & 2 ) + { + *(_WORD *)dst = *(_WORD *)src; + src += 4; + dst += 2; + } + dst = &dst[yy_32 - 800]; + yy_32 += 2; + } + while ( yy_32 != 32 ); + return; + } + } + break; + case 12: // upper (bottom transparent), without lighting + xx_32 = 30; + while ( dst >= gpBufEnd ) + { + dst += xx_32; + n_draw_shift = (unsigned int)(32 - xx_32) >> 2; + if ( (32 - xx_32) & 2 ) + { + *(_WORD *)dst = *((_WORD *)src + 1); + src += 4; + dst += 2; + } + if ( n_draw_shift ) + { + do + { + *(_DWORD *)dst = *(_DWORD *)src; + src += 4; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + dst -= 800; + xx_32 -= 2; + if ( xx_32 < 0 ) + { + gpDrawMask -= 16; + yy_32 = 16; + do + { + if ( dst < gpBufEnd ) + break; + left_shift = *gpDrawMask; + i = 32; + do + { + if ( left_shift & 0x80000000 ) + dst[0] = src[0]; + left_shift *= 2; + ++src; + ++dst; + --i; + } + while ( i ); + dst -= 800; + --gpDrawMask; + --yy_32; + } + while ( yy_32 ); + return; + } + } + break; + default: // upper (bottom transparent), without lighting + xx_32 = 30; + while ( dst >= gpBufEnd ) + { + for ( n_draw_shift = (unsigned int)(32 - xx_32) >> 2; n_draw_shift; --n_draw_shift ) + { + *(_DWORD *)dst = *(_DWORD *)src; + src += 4; + dst += 4; + } + if ( (32 - (_BYTE)xx_32) & 2 ) + { + *(_WORD *)dst = *(_WORD *)src; + src += 4; + dst += 2; + } + dst = &dst[xx_32 - 800]; + xx_32 -= 2; + if ( xx_32 < 0 ) + { + gpDrawMask -= 16; + yy_32 = 16; + do + { + if ( dst < gpBufEnd ) + break; + left_shift = *gpDrawMask; + i = 32; + do + { + if ( left_shift & 0x80000000 ) + dst[0] = src[0]; + left_shift *= 2; + ++src; + ++dst; + --i; + } + while ( i ); + src += (unsigned char)src & 2; + dst -= 800; + --gpDrawMask; + --yy_32; + } + while ( yy_32 ); + return; + } + } + break; + } + return; + } + if ( (_BYTE)light_table_index != lightmax ) + { + if ( !(level_cel_block & 0x8000) ) + { + src = (unsigned char *)pDungeonCels + *((_DWORD *)pDungeonCels + (level_cel_block & 0xFFF)); + tbl = &pLightTbl[256 * light_table_index]; + cel_type_16 = (unsigned char)(level_cel_block >> 12); + switch ( cel_type_16 ) + { + case 0: // upper (bottom transparent), with lighting + xx_32 = 32; + do + { + if ( dst < gpBufEnd ) + break; + asm_trans_light_mask(32, tbl, dst, src, *gpDrawMask); + dst -= 800; + --gpDrawMask; + --xx_32; + } + while ( xx_32 ); + break; + case 1: // upper (bottom transparent), with lighting + xx_32 = 32; + do + { + gdwCurrentMask = *gpDrawMask; + yy_32 = 32; + do + { + while ( 1 ) + { + width = (unsigned char)*src++; + if ( (width & 0x80u) == 0 ) + break; + _LOBYTE(width) = -(char)width; + dst += width; + if ( width & 0x1F ) + gdwCurrentMask <<= width & 0x1F; + yy_32 -= width; + if ( !yy_32 ) + goto LABEL_50; + } + yy_32 -= width; + if ( dst < gpBufEnd ) + return; + gdwCurrentMask = asm_trans_light_mask(width, tbl, dst, src, gdwCurrentMask); + } + while ( yy_32 ); +LABEL_50: + dst -= 800; + --gpDrawMask; + --xx_32; + } + while ( xx_32 ); + break; + case 2: // upper (bottom transparent), with lighting + xx_32 = 30; + while ( dst >= gpBufEnd ) + { + dst += xx_32; + src += (32 - (_BYTE)xx_32) & 2; + asm_cel_light_edge(32 - xx_32, tbl, dst, src); + dst -= 800; + xx_32 -= 2; + if ( xx_32 < 0 ) + { + yy_32 = 2; + do + { + if ( dst < gpBufEnd ) + break; + dst += yy_32; + src += (32 - (_BYTE)yy_32) & 2; + asm_cel_light_edge(32 - yy_32, tbl, dst, src); + dst -= 800; + yy_32 += 2; + } + while ( yy_32 != 32 ); + return; + } + } + break; + case 3: // upper (bottom transparent), with lighting + xx_32 = 30; + while ( dst >= gpBufEnd ) + { + asm_cel_light_edge(32 - xx_32, tbl, dst, src); + src += (unsigned char)src & 2; + dst = &dst[xx_32 - 800]; + xx_32 -= 2; + if ( xx_32 < 0 ) + { + yy_32 = 2; + do + { + if ( dst < gpBufEnd ) + break; + asm_cel_light_edge(32 - yy_32, tbl, dst, src); + src += (unsigned char)src & 2; + dst = &dst[yy_32 - 800]; + yy_32 += 2; + } + while ( yy_32 != 32 ); + return; + } + } + break; + case 4: // upper (bottom transparent), with lighting + xx_32 = 30; + while ( dst >= gpBufEnd ) + { + dst += xx_32; + src += (32 - (_BYTE)xx_32) & 2; + asm_cel_light_edge(32 - xx_32, tbl, dst, src); + dst -= 800; + xx_32 -= 2; + if ( xx_32 < 0 ) + { + gpDrawMask -= 16; + yy_32 = 16; + do + { + if ( dst < gpBufEnd ) + break; + src += (unsigned char)src & 2; + asm_trans_light_mask(32, tbl, dst, src, *gpDrawMask); + dst -= 800; + --gpDrawMask; + --yy_32; + } + while ( yy_32 ); + return; + } + } + break; + default: // upper (bottom transparent), with lighting + xx_32 = 30; + while ( dst >= gpBufEnd ) + { + asm_cel_light_edge(32 - xx_32, tbl, dst, src); + src += (unsigned char)src & 2; + dst = &dst[xx_32 - 800]; + xx_32 -= 2; + if ( xx_32 < 0 ) + { + gpDrawMask -= 16; + yy_32 = 16; + do + { + if ( dst < gpBufEnd ) + break; + asm_trans_light_mask(32, tbl, dst, src, *gpDrawMask); + src += (unsigned char)src & 2; + dst -= 800; + --gpDrawMask; + --yy_32; + } + while ( yy_32 ); + return; + } + } + break; + } + return; + } + src = (unsigned char *)pSpeedCels + + *(_DWORD *)&gpCelFrame[4 * (light_table_index + 16 * (level_cel_block & 0xFFF))]; + cel_type_16 = (unsigned char)(level_cel_block >> 12); + goto LABEL_12; + } + if ( level_cel_block & 0x8000 ) + level_cel_block = *(_DWORD *)&gpCelFrame[64 * (level_cel_block & 0xFFF)] + + (unsigned short)(level_cel_block & 0xF000); + src = (unsigned char *)pDungeonCels + *((_DWORD *)pDungeonCels + (level_cel_block & 0xFFF)); + cel_type_16 = (level_cel_block >> 12) & 7; + switch ( cel_type_16 ) + { + case 0: // upper (bottom transparent), black + xx_32 = 32; + do + { + if ( dst < gpBufEnd ) + break; + left_shift = *gpDrawMask; + i = 32; + do + { + if ( left_shift & 0x80000000 ) + dst[0] = 0; + left_shift *= 2; + ++dst; + --i; + } + while ( i ); + dst -= 800; + --gpDrawMask; + --xx_32; + } + while ( xx_32 ); + break; + case 1: // upper (bottom transparent), black + xx_32 = 32; + do + { + gdwCurrentMask = *gpDrawMask; + yy_32 = 32; + do + { + while ( 1 ) + { + width = (unsigned char)*src++; + if ( (width & 0x80u) == 0 ) + break; + _LOBYTE(width) = -(char)width; + dst += width; + if ( width & 0x1F ) + gdwCurrentMask <<= width & 0x1F; + yy_32 -= width; + if ( !yy_32 ) + goto LABEL_208; + } + yy_32 -= width; + if ( dst < gpBufEnd ) + return; + left_shift = gdwCurrentMask; + and80_i = width; + src += width; + do + { + if ( left_shift & 0x80000000 ) + dst[0] = 0; + left_shift *= 2; + ++dst; + --and80_i; + } + while ( and80_i ); + gdwCurrentMask = left_shift; + } + while ( yy_32 ); +LABEL_208: + dst -= 800; + --gpDrawMask; + --xx_32; + } + while ( xx_32 ); + break; + case 2: // upper (bottom transparent), black + xx_32 = 30; + while ( dst >= gpBufEnd ) + { + dst += xx_32; + n_draw_shift = (unsigned int)(32 - xx_32) >> 2; + if ( (32 - xx_32) & 2 ) + { + *(_WORD *)dst = 0; + dst += 2; + } + if ( n_draw_shift ) + { + do + { + *(_DWORD *)dst = 0; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + dst -= 800; + if ( !xx_32 ) + { + yy_32 = 2; + do + { + if ( dst < gpBufEnd ) + break; + dst += yy_32; + n_draw_shift = (unsigned int)(32 - yy_32) >> 2; + if ( (32 - yy_32) & 2 ) + { + *(_WORD *)dst = 0; + dst += 2; + } + if ( n_draw_shift ) + { + do + { + *(_DWORD *)dst = 0; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + dst -= 800; + yy_32 += 2; + } + while ( yy_32 != 32 ); + return; + } + xx_32 -= 2; + } + break; + case 3: // upper (bottom transparent), black + xx_32 = 30; + while ( dst >= gpBufEnd ) + { + n_draw_shift = (unsigned int)(32 - xx_32) >> 2; + if ( (32 - xx_32) & 2 ) + { + *(_WORD *)dst = 0; + dst += 2; + } + if ( n_draw_shift ) + { + do + { + *(_DWORD *)dst = 0; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + dst -= 800; + if ( !xx_32 ) + { + yy_32 = 2; + do + { + if ( dst < gpBufEnd ) + break; + n_draw_shift = (unsigned int)(32 - yy_32) >> 2; + if ( (32 - yy_32) & 2 ) + { + *(_WORD *)dst = 0; + dst += 2; + } + if ( n_draw_shift ) + { + do + { + *(_DWORD *)dst = 0; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + dst = &dst[yy_32 - 800]; + yy_32 += 2; + } + while ( yy_32 != 32 ); + return; + } + dst += xx_32; + xx_32 -= 2; + } + break; + case 4: // upper (bottom transparent), black + xx_32 = 30; + while ( dst >= gpBufEnd ) + { + dst += xx_32; + n_draw_shift = (unsigned int)(32 - xx_32) >> 2; + if ( (32 - xx_32) & 2 ) + { + *(_WORD *)dst = 0; + dst += 2; + } + if ( n_draw_shift ) + { + do + { + *(_DWORD *)dst = 0; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + dst -= 800; + if ( !xx_32 ) + { + gpDrawMask -= 16; + yy_32 = 16; + do + { + if ( dst < gpBufEnd ) + break; + left_shift = *gpDrawMask; + i = 32; + do + { + if ( left_shift & 0x80000000 ) + dst[0] = 0; + left_shift *= 2; + ++dst; + --i; + } + while ( i ); + dst -= 800; + --gpDrawMask; + --yy_32; + } + while ( yy_32 ); + return; + } + xx_32 -= 2; + } + break; + default: // upper (bottom transparent), black + xx_32 = 30; + while ( dst >= gpBufEnd ) + { + n_draw_shift = (unsigned int)(32 - xx_32) >> 2; + if ( (32 - xx_32) & 2 ) + { + *(_WORD *)dst = 0; + dst += 2; + } + if ( n_draw_shift ) + { + do + { + *(_DWORD *)dst = 0; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + dst -= 800; + if ( !xx_32 ) + { + gpDrawMask -= 16; + yy_32 = 16; + do + { + if ( dst < gpBufEnd ) + break; + left_shift = *gpDrawMask; + i = 32; + do + { + if ( left_shift & 0x80000000 ) + dst[0] = 0; + left_shift *= 2; + ++dst; + --i; + } + while ( i ); + dst -= 800; + --gpDrawMask; + --yy_32; + } + while ( yy_32 ); + return; + } + dst += xx_32; + xx_32 -= 2; + } + break; + } +} + +void drawUpperScreen(BYTE *pBuff) +{ + unsigned char *dst; // edi MAPDST + unsigned char *tbl; // ebx + unsigned char *src; // esi MAPDST + short cel_type_16; // ax MAPDST + signed int xx_32; // ebp MAPDST + signed int yy_32; // edx MAPDST + unsigned int width; // eax MAPDST + unsigned int chk_sh_and; // ecx MAPDST + unsigned int n_draw_shift; // ecx MAPDST + signed int i; // edx MAPDST + signed int j; // ecx MAPDST + + if ( cel_transparency_active ) + { + if ( !arch_draw_type ) + { + drawTopArchesUpperScreen(pBuff); + return; + } + if ( arch_draw_type == 1 ) + { + if ( block_lvid[level_piece_id] == 1 || block_lvid[level_piece_id] == 3 ) + { + drawBottomArchesUpperScreen(pBuff, &LeftMask[31]); + return; + } + } + if ( arch_draw_type == 2 ) + { + if ( block_lvid[level_piece_id] == 2 || block_lvid[level_piece_id] == 3 ) + { + drawBottomArchesUpperScreen(pBuff, &RightMask[31]); + return; + } + } + } + gpCelFrame = (unsigned char *)SpeedFrameTbl; + dst = pBuff; + if ( !(_BYTE)light_table_index ) + { + if ( level_cel_block & 0x8000 ) + level_cel_block = *(_DWORD *)&gpCelFrame[64 * (level_cel_block & 0xFFF)] + + (unsigned short)(level_cel_block & 0xF000); + src = (unsigned char *)pDungeonCels + *((_DWORD *)pDungeonCels + (level_cel_block & 0xFFF)); + cel_type_16 = ((level_cel_block >> 12) & 7) + 8; +LABEL_22: + switch ( cel_type_16 ) + { + case 8: // upper (solid), without lighting + i = 32; + do + { + if ( dst < gpBufEnd ) + break; + j = 8; + do + { + *(_DWORD *)dst = *(_DWORD *)src; + src += 4; + dst += 4; + --j; + } + while ( j ); + dst -= 800; + --i; + } + while ( i ); + break; + case 9: // upper (solid), without lighting + xx_32 = 32; + do + { + yy_32 = 32; + do + { + while ( 1 ) + { + width = *src++; + if ( (width & 0x80u) == 0 ) + break; + _LOBYTE(width) = -(char)width; + dst += width; + yy_32 -= width; + if ( !yy_32 ) + goto LABEL_133; + } + yy_32 -= width; + if ( dst < gpBufEnd ) + return; + chk_sh_and = width >> 1; + if ( width & 1 ) + { + *dst++ = *src++; + if ( !chk_sh_and ) + continue; + } + n_draw_shift = chk_sh_and >> 1; + if ( chk_sh_and & 1 ) + { + *(_WORD *)dst = *(_WORD *)src; + src += 2; + dst += 2; + if ( !n_draw_shift ) + continue; + } + do + { + *(_DWORD *)dst = *(_DWORD *)src; + src += 4; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + while ( yy_32 ); +LABEL_133: + dst -= 800; + --xx_32; + } + while ( xx_32 ); + break; + case 10: // upper (solid), without lighting + xx_32 = 30; + while ( dst >= gpBufEnd ) + { + dst += xx_32; + n_draw_shift = (unsigned int)(32 - xx_32) >> 2; + if ( (32 - xx_32) & 2 ) + { + *(_WORD *)dst = *((_WORD *)src + 1); + src += 4; + dst += 2; + } + if ( n_draw_shift ) + { + do + { + *(_DWORD *)dst = *(_DWORD *)src; + src += 4; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + dst -= 800; + xx_32 -= 2; + if ( xx_32 < 0 ) + { + yy_32 = 2; + do + { + if ( dst < gpBufEnd ) + break; + dst += yy_32; + n_draw_shift = (unsigned int)(32 - yy_32) >> 2; + if ( (32 - yy_32) & 2 ) + { + *(_WORD *)dst = *((_WORD *)src + 1); + src += 4; + dst += 2; + } + if ( n_draw_shift ) + { + do + { + *(_DWORD *)dst = *(_DWORD *)src; + src += 4; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + dst -= 800; + yy_32 += 2; + } + while ( yy_32 != 32 ); + return; + } + } + break; + case 11: // upper (solid), without lighting + xx_32 = 30; + while ( dst >= gpBufEnd ) + { + for ( n_draw_shift = (unsigned int)(32 - xx_32) >> 2; n_draw_shift; --n_draw_shift ) + { + *(_DWORD *)dst = *(_DWORD *)src; + src += 4; + dst += 4; + } + if ( (32 - (_BYTE)xx_32) & 2 ) + { + *(_WORD *)dst = *(_WORD *)src; + src += 4; + dst += 2; + } + dst = &dst[xx_32 - 800]; + xx_32 -= 2; + if ( xx_32 < 0 ) + { + yy_32 = 2; + do + { + if ( dst < gpBufEnd ) + break; + for ( n_draw_shift = (unsigned int)(32 - yy_32) >> 2; n_draw_shift; --n_draw_shift ) + { + *(_DWORD *)dst = *(_DWORD *)src; + src += 4; + dst += 4; + } + if ( (32 - (_BYTE)yy_32) & 2 ) + { + *(_WORD *)dst = *(_WORD *)src; + src += 4; + dst += 2; + } + dst = &dst[yy_32 - 800]; + yy_32 += 2; + } + while ( yy_32 != 32 ); + return; + } + } + break; + case 12: // upper (solid), without lighting + xx_32 = 30; + while ( dst >= gpBufEnd ) + { + dst += xx_32; + n_draw_shift = (unsigned int)(32 - xx_32) >> 2; + if ( (32 - xx_32) & 2 ) + { + *(_WORD *)dst = *((_WORD *)src + 1); + src += 4; + dst += 2; + } + if ( n_draw_shift ) + { + do + { + *(_DWORD *)dst = *(_DWORD *)src; + src += 4; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + dst -= 800; + xx_32 -= 2; + if ( xx_32 < 0 ) + { + i = 16; + do + { + if ( dst < gpBufEnd ) + break; + j = 8; + do + { + *(_DWORD *)dst = *(_DWORD *)src; + src += 4; + dst += 4; + --j; + } + while ( j ); + dst -= 800; + --i; + } + while ( i ); + return; + } + } + break; + default: // upper (solid), without lighting + xx_32 = 30; + while ( dst >= gpBufEnd ) + { + for ( n_draw_shift = (unsigned int)(32 - xx_32) >> 2; n_draw_shift; --n_draw_shift ) + { + *(_DWORD *)dst = *(_DWORD *)src; + src += 4; + dst += 4; + } + if ( (32 - (_BYTE)xx_32) & 2 ) + { + *(_WORD *)dst = *(_WORD *)src; + src += 4; + dst += 2; + } + dst = &dst[xx_32 - 800]; + xx_32 -= 2; + if ( xx_32 < 0 ) + { + i = 16; + do + { + if ( dst < gpBufEnd ) + break; + j = 8; + do + { + *(_DWORD *)dst = *(_DWORD *)src; + src += 4; + dst += 4; + --j; + } + while ( j ); + dst -= 800; + --i; + } + while ( i ); + return; + } + } + break; + } + return; + } + if ( (_BYTE)light_table_index != lightmax ) + { + if ( !(level_cel_block & 0x8000) ) + { + src = (unsigned char *)pDungeonCels + *((_DWORD *)pDungeonCels + (level_cel_block & 0xFFF)); + tbl = &pLightTbl[256 * light_table_index]; + cel_type_16 = (unsigned short)level_cel_block >> 12; + switch ( cel_type_16 ) + { + case 0: // upper (solid), with lighting + xx_32 = 32; + do + { + if ( dst < gpBufEnd ) + break; + asm_cel_light_square(8, tbl, dst, src); + dst -= 800; + --xx_32; + } + while ( xx_32 ); + break; + case 1: // upper (solid), with lighting + xx_32 = 32; + do + { + yy_32 = 32; + do + { + while ( 1 ) + { + width = *src++; + if ( (width & 0x80u) == 0 ) + break; + _LOBYTE(width) = -(char)width; + dst += width; + yy_32 -= width; + if ( !yy_32 ) + goto LABEL_58; + } + yy_32 -= width; + if ( dst < gpBufEnd ) + return; + asm_cel_light_edge(width, tbl, dst, src); + } + while ( yy_32 ); +LABEL_58: + dst -= 800; + --xx_32; + } + while ( xx_32 ); + break; + case 2: // upper (solid), with lighting + xx_32 = 30; + while ( dst >= gpBufEnd ) + { + dst += xx_32; + src += (32 - (_BYTE)xx_32) & 2; + asm_cel_light_edge(32 - xx_32, tbl, dst, src); + dst -= 800; + xx_32 -= 2; + if ( xx_32 < 0 ) + { + yy_32 = 2; + do + { + if ( dst < gpBufEnd ) + break; + dst += yy_32; + src += (32 - (_BYTE)yy_32) & 2; + asm_cel_light_edge(32 - yy_32, tbl, dst, src); + dst -= 800; + yy_32 += 2; + } + while ( yy_32 != 32 ); + return; + } + } + break; + case 3: // upper (solid), with lighting + xx_32 = 30; + while ( dst >= gpBufEnd ) + { + asm_cel_light_edge(32 - xx_32, tbl, dst, src); + src += (unsigned char)src & 2; + dst = &dst[xx_32 - 800]; + xx_32 -= 2; + if ( xx_32 < 0 ) + { + yy_32 = 2; + do + { + if ( dst < gpBufEnd ) + break; + asm_cel_light_edge(32 - yy_32, tbl, dst, src); + src += (unsigned char)src & 2; + dst = &dst[yy_32 - 800]; + yy_32 += 2; + } + while ( yy_32 != 32 ); + return; + } + } + break; + case 4: // upper (solid), with lighting + xx_32 = 30; + while ( dst >= gpBufEnd ) + { + dst += xx_32; + src += (32 - (_BYTE)xx_32) & 2; + asm_cel_light_edge(32 - xx_32, tbl, dst, src); + dst -= 800; + xx_32 -= 2; + if ( xx_32 < 0 ) + { + yy_32 = 16; + do + { + if ( dst < gpBufEnd ) + break; + asm_cel_light_square(8, tbl, dst, src); + dst -= 800; + --yy_32; + } + while ( yy_32 ); + return; + } + } + break; + default: // upper (solid), with lighting + xx_32 = 30; + while ( dst >= gpBufEnd ) + { + asm_cel_light_edge(32 - xx_32, tbl, dst, src); + src += (unsigned char)src & 2; + dst = &dst[xx_32 - 800]; + xx_32 -= 2; + if ( xx_32 < 0 ) + { + yy_32 = 16; + do + { + if ( dst < gpBufEnd ) + break; + asm_cel_light_square(8, tbl, dst, src); + dst -= 800; + --yy_32; + } + while ( yy_32 ); + return; + } + } + break; + } + return; + } + src = (unsigned char *)pSpeedCels + + *(_DWORD *)&gpCelFrame[4 * (light_table_index + 16 * (level_cel_block & 0xFFF))]; + cel_type_16 = (unsigned short)level_cel_block >> 12; + goto LABEL_22; + } + if ( level_cel_block & 0x8000 ) + level_cel_block = *(_DWORD *)&gpCelFrame[64 * (level_cel_block & 0xFFF)] + + (unsigned short)(level_cel_block & 0xF000); + src = (unsigned char *)pDungeonCels + *((_DWORD *)pDungeonCels + (level_cel_block & 0xFFF)); + cel_type_16 = ((unsigned int)level_cel_block >> 12) & 7; + switch ( cel_type_16 ) + { + case 0: // upper (solid), black + i = 32; + do + { + if ( dst < gpBufEnd ) + break; + j = 8; + do + { + *(_DWORD *)dst = 0; + dst += 4; + --j; + } + while ( j ); + dst -= 800; + --i; + } + while ( i ); + break; + case 1: // upper (solid), black + xx_32 = 32; + do + { + yy_32 = 32; + do + { + while ( 1 ) + { + width = *src++; + if ( (width & 0x80u) == 0 ) + break; + _LOBYTE(width) = -(char)width; + dst += width; + yy_32 -= width; + if ( !yy_32 ) + goto LABEL_205; + } + yy_32 -= width; + if ( dst < gpBufEnd ) + return; + src += width; + chk_sh_and = width >> 1; + if ( width & 1 ) + { + *dst++ = 0; + if ( !chk_sh_and ) + continue; + } + n_draw_shift = width >> 2; + if ( chk_sh_and & 1 ) + { + *(_WORD *)dst = 0; + dst += 2; + if ( !n_draw_shift ) + continue; + } + do + { + *(_DWORD *)dst = 0; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + while ( yy_32 ); +LABEL_205: + dst -= 800; + --xx_32; + } + while ( xx_32 ); + break; + case 2: // upper (solid), black + xx_32 = 30; + while ( dst >= gpBufEnd ) + { + dst += xx_32; + n_draw_shift = (unsigned int)(32 - xx_32) >> 2; + if ( (32 - xx_32) & 2 ) + { + *(_WORD *)dst = 0; + dst += 2; + } + if ( n_draw_shift ) + { + do + { + *(_DWORD *)dst = 0; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + dst -= 800; + if ( !xx_32 ) + { + yy_32 = 2; + do + { + if ( dst < gpBufEnd ) + break; + dst += yy_32; + n_draw_shift = (unsigned int)(32 - yy_32) >> 2; + if ( (32 - yy_32) & 2 ) + { + *(_WORD *)dst = 0; + dst += 2; + } + if ( n_draw_shift ) + { + do + { + *(_DWORD *)dst = 0; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + dst -= 800; + yy_32 += 2; + } + while ( yy_32 != 32 ); + return; + } + xx_32 -= 2; + } + break; + case 3: // upper (solid), black + xx_32 = 30; + while ( dst >= gpBufEnd ) + { + n_draw_shift = (unsigned int)(32 - xx_32) >> 2; + if ( (32 - xx_32) & 2 ) + { + *(_WORD *)dst = 0; + dst += 2; + } + if ( n_draw_shift ) + { + do + { + *(_DWORD *)dst = 0; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + dst -= 800; + if ( !xx_32 ) + { + yy_32 = 2; + do + { + if ( dst < gpBufEnd ) + break; + n_draw_shift = (unsigned int)(32 - yy_32) >> 2; + if ( (32 - yy_32) & 2 ) + { + *(_WORD *)dst = 0; + dst += 2; + } + if ( n_draw_shift ) + { + do + { + *(_DWORD *)dst = 0; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + dst = &dst[yy_32 - 800]; + yy_32 += 2; + } + while ( yy_32 != 32 ); + return; + } + dst += xx_32; + xx_32 -= 2; + } + break; + case 4: // upper (solid), black + xx_32 = 30; + while ( dst >= gpBufEnd ) + { + dst += xx_32; + n_draw_shift = (unsigned int)(32 - xx_32) >> 2; + if ( (32 - xx_32) & 2 ) + { + *(_WORD *)dst = 0; + dst += 2; + } + if ( n_draw_shift ) + { + do + { + *(_DWORD *)dst = 0; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + dst -= 800; + if ( !xx_32 ) + { + i = 16; + do + { + if ( dst < gpBufEnd ) + break; + j = 8; + do + { + *(_DWORD *)dst = 0; + dst += 4; + --j; + } + while ( j ); + dst -= 800; + --i; + } + while ( i ); + return; + } + xx_32 -= 2; + } + break; + default: // upper (solid), black + xx_32 = 30; + while ( dst >= gpBufEnd ) + { + n_draw_shift = (unsigned int)(32 - xx_32) >> 2; + if ( (32 - xx_32) & 2 ) + { + *(_WORD *)dst = 0; + dst += 2; + } + if ( n_draw_shift ) + { + do + { + *(_DWORD *)dst = 0; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + dst -= 800; + if ( !xx_32 ) + { + i = 16; + do + { + if ( dst < gpBufEnd ) + break; + j = 8; + do + { + *(_DWORD *)dst = 0; + dst += 4; + --j; + } + while ( j ); + dst -= 800; + --i; + } + while ( i ); + return; + } + dst += xx_32; + xx_32 -= 2; + } + break; + } +} + +void drawTopArchesLowerScreen(BYTE *pBuff) +{ + unsigned char *dst; // edi MAPDST + unsigned char *tbl; // ebx + unsigned char *src; // esi MAPDST + short cel_type_16; // ax MAPDST + signed int tile_42_45; // eax MAPDST + unsigned int world_tbl; // ecx MAPDST + unsigned int width; // eax MAPDST + unsigned int chk_sh_and; // ecx MAPDST + int xx_32; // edx MAPDST + unsigned int x_minus; // ecx MAPDST + unsigned int n_draw_shift; // ecx MAPDST + int yy_32; // edx MAPDST + unsigned int y_minus; // ecx MAPDST + signed int i; // edx MAPDST + signed int j; // ecx MAPDST + + gpCelFrame = (unsigned char *)SpeedFrameTbl; + dst = pBuff; + if ( !(_BYTE)light_table_index ) + { + if ( level_cel_block & 0x8000 ) + level_cel_block = *(_DWORD *)&gpCelFrame[64 * (level_cel_block & 0xFFF)] + + (unsigned short)(level_cel_block & 0xF000); + src = (unsigned char *)pDungeonCels + *((_DWORD *)pDungeonCels + (level_cel_block & 0xFFF)); + cel_type_16 = ((level_cel_block >> 12) & 7) + 8; + goto LABEL_11; + } + if ( (_BYTE)light_table_index == lightmax ) + { + if ( level_cel_block & 0x8000 ) + level_cel_block = *(_DWORD *)&gpCelFrame[64 * (level_cel_block & 0xFFF)] + + (unsigned short)(level_cel_block & 0xF000); + src = (unsigned char *)pDungeonCels + *((_DWORD *)pDungeonCels + (level_cel_block & 0xFFF)); + cel_type_16 = (level_cel_block >> 12) & 7; + switch ( cel_type_16 ) + { + case 0: // lower (top transparent), black + i = 16; + do + { + if ( dst < gpBufEnd ) + { + j = 8; + do + { + dst[1] = 0; + dst[3] = 0; + dst += 4; + --j; + } + while ( j ); + } + else + { + src += 32; + dst += 32; + } + dst -= 800; + if ( dst < gpBufEnd ) + { + j = 8; + do + { + dst[0] = 0; + dst[2] = 0; + dst += 4; + --j; + } + while ( j ); + } + else + { + src += 32; + dst += 32; + } + dst -= 800; + --i; + } + while ( i ); + break; + case 1: // lower (top transparent), black + WorldBoolFlag = (unsigned char)pBuff & 1; + xx_32 = 32; +LABEL_412: + yy_32 = 32; + while ( 1 ) + { + while ( 1 ) + { + width = (unsigned char)*src++; + if ( (width & 0x80u) == 0 ) + break; + _LOBYTE(width) = -(char)width; + dst += width; + yy_32 -= width; + if ( !yy_32 ) + { +LABEL_433: + WorldBoolFlag = ((_BYTE)WorldBoolFlag + 1) & 1; + dst -= 800; + if ( !--xx_32 ) + return; + goto LABEL_412; + } + } + yy_32 -= width; + if ( dst < gpBufEnd ) + { + src += width; + if ( ((unsigned char)dst & 1) == WorldBoolFlag ) + { + chk_sh_and = width >> 1; + if ( !(width & 1) ) + goto LABEL_420; + ++dst; + if ( chk_sh_and ) + { +LABEL_427: + n_draw_shift = chk_sh_and >> 1; + if ( chk_sh_and & 1 ) + { + dst[0] = 0; + dst += 2; + } + if ( n_draw_shift ) + { + do + { + dst[0] = 0; + dst[2] = 0; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + goto LABEL_430; + } + } + else + { + chk_sh_and = width >> 1; + if ( !(width & 1) ) + goto LABEL_427; + *dst++ = 0; + if ( chk_sh_and ) + { +LABEL_420: + n_draw_shift = chk_sh_and >> 1; + if ( chk_sh_and & 1 ) + { + dst[1] = 0; + dst += 2; + } + if ( n_draw_shift ) + { + do + { + dst[1] = 0; + dst[3] = 0; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + goto LABEL_430; + } + } + } + else + { + src += width; + dst += width; + } +LABEL_430: + if ( !yy_32 ) + goto LABEL_433; + } + break; + case 2: // lower (top transparent), black + WorldBoolFlag = 0; + for ( xx_32 = 30; ; xx_32 -= 2 ) + { + if ( dst < gpBufEnd ) + { + dst += xx_32; + x_minus = 32 - xx_32; + WorldBoolFlag = ((_BYTE)WorldBoolFlag + 1) & 1; + if ( WorldBoolFlag ) + { + n_draw_shift = x_minus >> 2; + if ( x_minus & 2 ) + { + dst[1] = 0; + dst += 2; + } + if ( n_draw_shift ) + { + do + { + dst[1] = 0; + dst[3] = 0; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + } + else + { + n_draw_shift = x_minus >> 2; + if ( x_minus & 2 ) + { + dst[0] = 0; + dst += 2; + } + if ( n_draw_shift ) + { + do + { + dst[0] = 0; + dst[2] = 0; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + } + } + else + { + src = &src[-xx_32 + 32]; + dst += 32; + } + dst -= 800; + if ( !xx_32 ) + break; + } + yy_32 = 2; + do + { + if ( dst < gpBufEnd ) + { + dst += yy_32; + y_minus = 32 - yy_32; + WorldBoolFlag = ((_BYTE)WorldBoolFlag + 1) & 1; + if ( WorldBoolFlag ) + { + n_draw_shift = y_minus >> 2; + if ( y_minus & 2 ) + { + dst[1] = 0; + dst += 2; + } + if ( n_draw_shift ) + { + do + { + dst[1] = 0; + dst[3] = 0; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + } + else + { + n_draw_shift = y_minus >> 2; + if ( y_minus & 2 ) + { + dst[0] = 0; + dst += 2; + } + if ( n_draw_shift ) + { + do + { + dst[0] = 0; + dst[2] = 0; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + } + } + else + { + src = &src[-yy_32 + 32]; + dst += 32; + } + dst -= 800; + yy_32 += 2; + } + while ( yy_32 != 32 ); + break; + case 3: // lower (top transparent), black + WorldBoolFlag = 0; + for ( xx_32 = 30; ; xx_32 -= 2 ) + { + if ( dst < gpBufEnd ) + { + x_minus = 32 - xx_32; + WorldBoolFlag = ((_BYTE)WorldBoolFlag + 1) & 1; + if ( WorldBoolFlag ) + { + n_draw_shift = x_minus >> 2; + if ( x_minus & 2 ) + { + dst[1] = 0; + dst += 2; + } + if ( n_draw_shift ) + { + do + { + dst[1] = 0; + dst[3] = 0; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + } + else + { + n_draw_shift = x_minus >> 2; + if ( x_minus & 2 ) + { + dst[0] = 0; + dst += 2; + } + if ( n_draw_shift ) + { + do + { + dst[0] = 0; + dst[2] = 0; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + } + } + else + { + src = &src[-xx_32 + 32]; + dst = &dst[-xx_32 + 32]; + } + dst -= 800; + if ( !xx_32 ) + break; + dst += xx_32; + } + yy_32 = 2; + do + { + if ( dst < gpBufEnd ) + { + y_minus = 32 - yy_32; + WorldBoolFlag = ((_BYTE)WorldBoolFlag + 1) & 1; + if ( WorldBoolFlag ) + { + n_draw_shift = y_minus >> 2; + if ( y_minus & 2 ) + { + dst[1] = 0; + dst += 2; + } + if ( n_draw_shift ) + { + do + { + dst[1] = 0; + dst[3] = 0; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + } + else + { + n_draw_shift = y_minus >> 2; + if ( y_minus & 2 ) + { + dst[0] = 0; + dst += 2; + } + if ( n_draw_shift ) + { + do + { + dst[0] = 0; + dst[2] = 0; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + } + } + else + { + src = &src[-yy_32 + 32]; + dst = &dst[-yy_32 + 32]; + } + dst = &dst[yy_32 - 800]; + yy_32 += 2; + } + while ( yy_32 != 32 ); + break; + case 4: // lower (top transparent), black + WorldBoolFlag = 0; + for ( xx_32 = 30; ; xx_32 -= 2 ) + { + if ( dst < gpBufEnd ) + { + dst += xx_32; + x_minus = 32 - xx_32; + WorldBoolFlag = ((_BYTE)WorldBoolFlag + 1) & 1; + if ( WorldBoolFlag ) + { + n_draw_shift = x_minus >> 2; + if ( x_minus & 2 ) + { + dst[1] = 0; + dst += 2; + } + if ( n_draw_shift ) + { + do + { + dst[1] = 0; + dst[3] = 0; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + } + else + { + n_draw_shift = x_minus >> 2; + if ( x_minus & 2 ) + { + dst[0] = 0; + dst += 2; + } + if ( n_draw_shift ) + { + do + { + dst[0] = 0; + dst[2] = 0; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + } + } + else + { + src = &src[-xx_32 + 32]; + dst += 32; + } + dst -= 800; + if ( !xx_32 ) + break; + } + i = 8; + do + { + if ( dst < gpBufEnd ) + { + j = 8; + do + { + dst[1] = 0; + dst[3] = 0; + dst += 4; + --j; + } + while ( j ); + } + else + { + src += 32; + dst += 32; + } + dst -= 800; + if ( dst < gpBufEnd ) + { + j = 8; + do + { + dst[0] = 0; + dst[2] = 0; + dst += 4; + --j; + } + while ( j ); + } + else + { + src += 32; + dst += 32; + } + dst -= 800; + --i; + } + while ( i ); + break; + default: // lower (top transparent), black + WorldBoolFlag = 0; + for ( xx_32 = 30; ; xx_32 -= 2 ) + { + if ( dst < gpBufEnd ) + { + x_minus = 32 - xx_32; + WorldBoolFlag = ((_BYTE)WorldBoolFlag + 1) & 1; + if ( WorldBoolFlag ) + { + n_draw_shift = x_minus >> 2; + if ( x_minus & 2 ) + { + dst[1] = 0; + dst += 2; + } + if ( n_draw_shift ) + { + do + { + dst[1] = 0; + dst[3] = 0; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + } + else + { + n_draw_shift = x_minus >> 2; + if ( x_minus & 2 ) + { + dst[0] = 0; + dst += 2; + } + if ( n_draw_shift ) + { + do + { + dst[0] = 0; + dst[2] = 0; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + } + } + else + { + src = &src[-xx_32 + 32]; + dst = &dst[-xx_32 + 32]; + } + dst -= 800; + if ( !xx_32 ) + break; + dst += xx_32; + } + i = 8; + do + { + if ( dst < gpBufEnd ) + { + j = 8; + do + { + dst[1] = 0; + dst[3] = 0; + dst += 4; + --j; + } + while ( j ); + } + else + { + src += 32; + dst += 32; + } + dst -= 800; + if ( dst < gpBufEnd ) + { + j = 8; + do + { + dst[0] = 0; + dst[2] = 0; + dst += 4; + --j; + } + while ( j ); + } + else + { + src += 32; + dst += 32; + } + dst -= 800; + --i; + } + while ( i ); + break; + } + return; + } + if ( !(level_cel_block & 0x8000) ) + { + src = (unsigned char *)pDungeonCels + *((_DWORD *)pDungeonCels + (level_cel_block & 0xFFF)); + tbl = &pLightTbl[256 * light_table_index]; + cel_type_16 = (unsigned char)(level_cel_block >> 12); + switch ( cel_type_16 ) + { + case 0: // lower (top transparent), with lighting + i = 16; + do + { + if ( dst < gpBufEnd ) + { + asm_trans_light_square_1_3(8, tbl, dst, src); + } + else + { + src += 32; + dst += 32; + } + dst -= 800; + if ( dst < gpBufEnd ) + { + asm_trans_light_square_0_2(8, tbl, dst, src); + } + else + { + src += 32; + dst += 32; + } + dst -= 800; + --i; + } + while ( i ); + break; + case 1: // lower (top transparent), with lighting + WorldBoolFlag = (unsigned char)pBuff & 1; + xx_32 = 32; + do + { + yy_32 = 32; + do + { + while ( 1 ) + { + width = (unsigned char)*src++; + if ( (width & 0x80u) == 0 ) + break; + _LOBYTE(width) = -(char)width; + dst += width; + yy_32 -= width; + if ( !yy_32 ) + goto LABEL_69; + } + yy_32 -= width; + if ( dst < gpBufEnd ) + { + if ( ((unsigned char)dst & 1) == WorldBoolFlag ) + { + asm_trans_light_cel_0_2(width, tbl, dst, src); + } + else + { + asm_trans_light_cel_1_3(width, tbl, dst, src); + } + } + else + { + src += width; + dst += width; + } + } + while ( yy_32 ); +LABEL_69: + WorldBoolFlag = ((_BYTE)WorldBoolFlag + 1) & 1; + dst -= 800; + --xx_32; + } + while ( xx_32 ); + break; + case 2: // lower (top transparent), with lighting + WorldBoolFlag = 0; + xx_32 = 30; + if ( pBuff >= gpBufEnd ) + { + tile_42_45 = (unsigned int)(pBuff - gpBufEnd + 1023) >> 8; + if ( tile_42_45 > 45 ) + { + dst = pBuff - 12288; + src += 288; +LABEL_98: + yy_32 = 2; + if ( dst >= gpBufEnd ) + { + tile_42_45 = (unsigned int)(dst - gpBufEnd + 1023) >> 8; + if ( tile_42_45 > 42 ) + return; + world_tbl = WorldTbl3x16[tile_42_45]; + src += WorldTbl17_2[world_tbl >> 2]; + dst -= 192 * world_tbl; + world_tbl >>= 1; + yy_32 = world_tbl + 2; + WorldBoolFlag += world_tbl >> 1; + } + do + { + dst += yy_32; + src += (32 - (_BYTE)yy_32) & 2; + WorldBoolFlag = ((_BYTE)WorldBoolFlag + 1) & 1; + if ( WorldBoolFlag ) + { + asm_trans_light_cel_0_2(32 - yy_32, tbl, dst, src); + } + else + { + asm_trans_light_cel_1_3(32 - yy_32, tbl, dst, src); + } + dst -= 800; + yy_32 += 2; + } + while ( yy_32 != 32 ); + return; + } + world_tbl = WorldTbl3x16[tile_42_45]; + src += WorldTbl17_1[world_tbl >> 2]; + dst -= 192 * world_tbl; + world_tbl >>= 1; + xx_32 = 30 - world_tbl; + WorldBoolFlag += world_tbl >> 1; + } + do + { + dst += xx_32; + src += (32 - (_BYTE)xx_32) & 2; + WorldBoolFlag = ((_BYTE)WorldBoolFlag + 1) & 1; + if ( WorldBoolFlag ) + { + asm_trans_light_cel_0_2(32 - xx_32, tbl, dst, src); + } + else + { + asm_trans_light_cel_1_3(32 - xx_32, tbl, dst, src); + } + dst -= 800; + xx_32 -= 2; + } + while ( xx_32 >= 0 ); + goto LABEL_98; + case 3: // lower (top transparent), with lighting + WorldBoolFlag = 0; + xx_32 = 30; + if ( pBuff >= gpBufEnd ) + { + tile_42_45 = (unsigned int)(pBuff - gpBufEnd + 1023) >> 8; + if ( tile_42_45 > 45 ) + { + dst = pBuff - 12288; + src += 288; +LABEL_154: + yy_32 = 2; + if ( dst >= gpBufEnd ) + { + tile_42_45 = (unsigned int)(dst - gpBufEnd + 1023) >> 8; + if ( tile_42_45 > 42 ) + return; + world_tbl = WorldTbl3x16[tile_42_45]; + src += WorldTbl17_2[world_tbl >> 2]; + dst -= 192 * world_tbl; + world_tbl >>= 1; + yy_32 = world_tbl + 2; + WorldBoolFlag += world_tbl >> 1; + } + do + { + WorldBoolFlag = ((_BYTE)WorldBoolFlag + 1) & 1; + if ( WorldBoolFlag ) + { + asm_trans_light_cel_0_2(32 - yy_32, tbl, dst, src); + } + else + { + asm_trans_light_cel_1_3(32 - yy_32, tbl, dst, src); + } + src += (unsigned char)src & 2; + dst = &dst[yy_32 - 800]; + yy_32 += 2; + } + while ( yy_32 != 32 ); + return; + } + world_tbl = WorldTbl3x16[tile_42_45]; + src += WorldTbl17_1[world_tbl >> 2]; + dst -= 192 * world_tbl; + world_tbl >>= 1; + xx_32 = 30 - world_tbl; + WorldBoolFlag += world_tbl >> 1; + } + do + { + WorldBoolFlag = ((_BYTE)WorldBoolFlag + 1) & 1; + if ( WorldBoolFlag ) + { + asm_trans_light_cel_0_2(32 - xx_32, tbl, dst, src); + } + else + { + asm_trans_light_cel_1_3(32 - xx_32, tbl, dst, src); + } + src += (unsigned char)src & 2; + dst = &dst[xx_32 - 800]; + xx_32 -= 2; + } + while ( xx_32 >= 0 ); + goto LABEL_154; + case 4: // lower (top transparent), with lighting + WorldBoolFlag = 0; + xx_32 = 30; + if ( pBuff >= gpBufEnd ) + { + tile_42_45 = (unsigned int)(pBuff - gpBufEnd + 1023) >> 8; + if ( tile_42_45 > 45 ) + { + dst = pBuff - 12288; + src += 288; +LABEL_210: + i = 8; + do + { + if ( dst < gpBufEnd ) + { + asm_trans_light_square_1_3(8, tbl, dst, src); + } + else + { + src += 32; + dst += 32; + } + dst -= 800; + if ( dst < gpBufEnd ) + { + asm_trans_light_square_0_2(8, tbl, dst, src); + } + else + { + src += 32; + dst += 32; + } + dst -= 800; + --i; + } + while ( i ); + return; + } + world_tbl = WorldTbl3x16[tile_42_45]; + src += WorldTbl17_1[world_tbl >> 2]; + dst -= 192 * world_tbl; + world_tbl >>= 1; + xx_32 = 30 - world_tbl; + WorldBoolFlag += world_tbl >> 1; + } + do + { + dst += xx_32; + src += (32 - (_BYTE)xx_32) & 2; + WorldBoolFlag = ((_BYTE)WorldBoolFlag + 1) & 1; + if ( WorldBoolFlag ) + { + asm_trans_light_cel_0_2(32 - xx_32, tbl, dst, src); + } + else + { + asm_trans_light_cel_1_3(32 - xx_32, tbl, dst, src); + } + dst -= 800; + xx_32 -= 2; + } + while ( xx_32 >= 0 ); + goto LABEL_210; + default: // lower (top transparent), with lighting + WorldBoolFlag = 0; + xx_32 = 30; + if ( pBuff >= gpBufEnd ) + { + tile_42_45 = (unsigned int)(pBuff - gpBufEnd + 1023) >> 8; + if ( tile_42_45 > 45 ) + { + dst = pBuff - 12288; + src += 288; +LABEL_249: + i = 8; + do + { + if ( dst < gpBufEnd ) + { + asm_trans_light_square_1_3(8, tbl, dst, src); + } + else + { + src += 32; + dst += 32; + } + dst -= 800; + if ( dst < gpBufEnd ) + { + asm_trans_light_square_0_2(8, tbl, dst, src); + } + else + { + src += 32; + dst += 32; + } + dst -= 800; + --i; + } + while ( i ); + return; + } + world_tbl = WorldTbl3x16[tile_42_45]; + src += WorldTbl17_1[world_tbl >> 2]; + dst -= 192 * world_tbl; + world_tbl >>= 1; + xx_32 = 30 - world_tbl; + WorldBoolFlag += world_tbl >> 1; + } + do + { + WorldBoolFlag = ((_BYTE)WorldBoolFlag + 1) & 1; + if ( WorldBoolFlag ) + { + asm_trans_light_cel_0_2(32 - xx_32, tbl, dst, src); + } + else + { + asm_trans_light_cel_1_3(32 - xx_32, tbl, dst, src); + } + src += (unsigned char)src & 2; + dst = &dst[xx_32 - 800]; + xx_32 -= 2; + } + while ( xx_32 >= 0 ); + goto LABEL_249; + } + return; + } + src = (unsigned char *)pSpeedCels + *(_DWORD *)&gpCelFrame[4 * (light_table_index + 16 * (level_cel_block & 0xFFF))]; + cel_type_16 = (unsigned char)(level_cel_block >> 12); +LABEL_11: + switch ( cel_type_16 ) + { + case 8: // lower (top transparent), without lighting + i = 16; + do + { + if ( dst < gpBufEnd ) + { + j = 8; + do + { + dst[1] = src[1]; + dst[3] = src[3]; + src += 4; + dst += 4; + --j; + } + while ( j ); + } + else + { + src += 32; + dst += 32; + } + dst -= 800; + if ( dst < gpBufEnd ) + { + j = 8; + do + { + dst[0] = src[0]; + dst[2] = src[2]; + src += 4; + dst += 4; + --j; + } + while ( j ); + } + else + { + src += 32; + dst += 32; + } + dst -= 800; + --i; + } + while ( i ); + break; + case 9: // lower (top transparent), without lighting + WorldBoolFlag = (unsigned char)pBuff & 1; + xx_32 = 32; + while ( 1 ) + { + yy_32 = 32; + do + { + while ( 1 ) + { + width = (unsigned char)*src++; + if ( (width & 0x80u) != 0 ) + break; + yy_32 -= width; + if ( dst < gpBufEnd ) + { + if ( ((unsigned char)dst & 1) == WorldBoolFlag ) + { + chk_sh_and = width >> 1; + if ( !(width & 1) ) + goto LABEL_280; + ++src; + ++dst; + if ( chk_sh_and ) + { +LABEL_287: + n_draw_shift = chk_sh_and >> 1; + if ( chk_sh_and & 1 ) + { + dst[0] = src[0]; + src += 2; + dst += 2; + } + if ( n_draw_shift ) + { + do + { + dst[0] = src[0]; + dst[2] = src[2]; + src += 4; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + goto LABEL_290; + } + } + else + { + chk_sh_and = width >> 1; + if ( !(width & 1) ) + goto LABEL_287; + *dst++ = *src++; + if ( chk_sh_and ) + { +LABEL_280: + n_draw_shift = chk_sh_and >> 1; + if ( chk_sh_and & 1 ) + { + dst[1] = src[1]; + src += 2; + dst += 2; + } + if ( n_draw_shift ) + { + do + { + dst[1] = src[1]; + dst[3] = src[3]; + src += 4; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + goto LABEL_290; + } + } + } + else + { + src += width; + dst += width; + } +LABEL_290: + if ( !yy_32 ) + goto LABEL_293; + } + _LOBYTE(width) = -(char)width; + dst += width; + yy_32 -= width; + } + while ( yy_32 ); +LABEL_293: + WorldBoolFlag = ((_BYTE)WorldBoolFlag + 1) & 1; + dst -= 800; + if ( !--xx_32 ) + return; + } + case 10: // lower (top transparent), without lighting + WorldBoolFlag = 0; + xx_32 = 30; + if ( pBuff >= gpBufEnd ) + { + tile_42_45 = (unsigned int)(pBuff - gpBufEnd + 1023) >> 8; + if ( tile_42_45 > 45 ) + { + dst = pBuff - 12288; + src += 288; +LABEL_308: + yy_32 = 2; + if ( dst >= gpBufEnd ) + { + tile_42_45 = (unsigned int)(dst - gpBufEnd + 1023) >> 8; + if ( tile_42_45 > 42 ) + return; + world_tbl = WorldTbl3x16[tile_42_45]; + src += WorldTbl17_2[world_tbl >> 2]; + dst -= 192 * world_tbl; + world_tbl >>= 1; + yy_32 = world_tbl + 2; + WorldBoolFlag += world_tbl >> 1; + } + do + { + dst += yy_32; + y_minus = 32 - yy_32; + WorldBoolFlag = ((_BYTE)WorldBoolFlag + 1) & 1; + if ( WorldBoolFlag ) + { + n_draw_shift = y_minus >> 2; + if ( y_minus & 2 ) + { + dst[1] = src[3]; + src += 4; + dst += 2; + } + if ( n_draw_shift ) + { + do + { + dst[1] = src[1]; + dst[3] = src[3]; + src += 4; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + } + else + { + n_draw_shift = y_minus >> 2; + if ( y_minus & 2 ) + { + dst[0] = src[2]; + src += 4; + dst += 2; + --n_draw_shift; /// BUGFIX: delete this line + } + if ( n_draw_shift ) + { + do + { + dst[0] = src[0]; + dst[2] = src[2]; + src += 4; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + } + dst -= 800; + yy_32 += 2; + } + while ( yy_32 != 32 ); + return; + } + world_tbl = WorldTbl3x16[tile_42_45]; + src += WorldTbl17_1[world_tbl >> 2]; + dst -= 192 * world_tbl; + world_tbl >>= 1; + xx_32 = 30 - world_tbl; + WorldBoolFlag += world_tbl >> 1; + } + do + { + dst += xx_32; + x_minus = 32 - xx_32; + WorldBoolFlag = ((_BYTE)WorldBoolFlag + 1) & 1; + if ( WorldBoolFlag ) + { + n_draw_shift = x_minus >> 2; + if ( x_minus & 2 ) + { + dst[1] = src[3]; + src += 4; + dst += 2; + } + if ( n_draw_shift ) + { + do + { + dst[1] = src[1]; + dst[3] = src[3]; + src += 4; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + } + else + { + n_draw_shift = x_minus >> 2; + if ( x_minus & 2 ) + { + dst[0] = src[2]; + src += 4; + dst += 2; + } + if ( n_draw_shift ) + { + do + { + dst[0] = src[0]; + dst[2] = src[2]; + src += 4; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + } + dst -= 800; + xx_32 -= 2; + } + while ( xx_32 >= 0 ); + goto LABEL_308; + case 11: // lower (top transparent), without lighting + WorldBoolFlag = 0; + xx_32 = 30; + if ( pBuff < gpBufEnd ) + goto LABEL_326; + tile_42_45 = (unsigned int)(pBuff - gpBufEnd + 1023) >> 8; + if ( tile_42_45 <= 45 ) + { + world_tbl = WorldTbl3x16[tile_42_45]; + src += WorldTbl17_1[world_tbl >> 2]; + dst -= 192 * world_tbl; + world_tbl >>= 1; + xx_32 = 30 - world_tbl; + WorldBoolFlag += world_tbl >> 1; + do + { +LABEL_326: + x_minus = 32 - xx_32; + WorldBoolFlag = ((_BYTE)WorldBoolFlag + 1) & 1; + if ( WorldBoolFlag ) + { + for ( n_draw_shift = x_minus >> 2; n_draw_shift; --n_draw_shift ) + { + dst[1] = src[1]; + dst[3] = src[3]; + src += 4; + dst += 4; + } + if ( (32 - (_BYTE)xx_32) & 2 ) + { + dst[1] = src[1]; + src += 4; + dst += 2; + } + } + else + { + for ( n_draw_shift = x_minus >> 2; n_draw_shift; --n_draw_shift ) + { + dst[0] = src[0]; + dst[2] = src[2]; + src += 4; + dst += 4; + } + if ( (32 - (_BYTE)xx_32) & 2 ) + { + dst[0] = src[0]; + src += 4; + dst += 2; + } + } + dst = &dst[xx_32 - 800]; + xx_32 -= 2; + } + while ( xx_32 >= 0 ); + goto LABEL_336; + } + dst = pBuff - 12288; + src += 288; +LABEL_336: + yy_32 = 2; + if ( dst >= gpBufEnd ) + { + tile_42_45 = (unsigned int)(dst - gpBufEnd + 1023) >> 8; + if ( tile_42_45 > 42 ) + return; + world_tbl = WorldTbl3x16[tile_42_45]; + src += WorldTbl17_2[world_tbl >> 2]; + dst -= 192 * world_tbl; + world_tbl >>= 1; + yy_32 = world_tbl + 2; + WorldBoolFlag += world_tbl >> 1; + } + do + { + y_minus = 32 - yy_32; + WorldBoolFlag = ((_BYTE)WorldBoolFlag + 1) & 1; + if ( WorldBoolFlag ) + { + for ( n_draw_shift = y_minus >> 2; n_draw_shift; --n_draw_shift ) + { + dst[1] = src[1]; + dst[3] = src[3]; + src += 4; + dst += 4; + } + if ( (32 - (_BYTE)yy_32) & 2 ) + { + dst[1] = src[1]; + src += 4; + dst += 2; + } + } + else + { + for ( n_draw_shift = y_minus >> 2; n_draw_shift; --n_draw_shift ) + { + dst[0] = src[0]; + dst[2] = src[2]; + src += 4; + dst += 4; + } + if ( (32 - (_BYTE)yy_32) & 2 ) + { + dst[0] = src[0]; + src += 4; + dst += 2; + } + } + dst = &dst[yy_32 - 800]; + yy_32 += 2; + } + while ( yy_32 != 32 ); + break; + case 12: // lower (top transparent), without lighting + WorldBoolFlag = 0; + xx_32 = 30; + if ( pBuff >= gpBufEnd ) + { + tile_42_45 = (unsigned int)(pBuff - gpBufEnd + 1023) >> 8; + if ( tile_42_45 > 45 ) + { + dst = pBuff - 12288; + src += 288; +LABEL_364: + i = 8; + do + { + if ( dst < gpBufEnd ) + { + j = 8; + do + { + dst[1] = src[1]; + dst[3] = src[3]; + src += 4; + dst += 4; + --j; + } + while ( j ); + } + else + { + src += 32; + dst += 32; + } + dst -= 800; + if ( dst < gpBufEnd ) + { + j = 8; + do + { + dst[0] = src[0]; + dst[2] = src[2]; + src += 4; + dst += 4; + --j; + } + while ( j ); + } + else + { + src += 32; + dst += 32; + } + dst -= 800; + --i; + } + while ( i ); + return; + } + world_tbl = WorldTbl3x16[tile_42_45]; + src += WorldTbl17_1[world_tbl >> 2]; + dst -= 192 * world_tbl; + world_tbl >>= 1; + xx_32 = 30 - world_tbl; + WorldBoolFlag += world_tbl >> 1; + } + do + { + dst += xx_32; + x_minus = 32 - xx_32; + WorldBoolFlag = ((_BYTE)WorldBoolFlag + 1) & 1; + if ( WorldBoolFlag ) + { + n_draw_shift = x_minus >> 2; + if ( x_minus & 2 ) + { + dst[1] = src[3]; + src += 4; + dst += 2; + } + if ( n_draw_shift ) + { + do + { + dst[1] = src[1]; + dst[3] = src[3]; + src += 4; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + } + else + { + n_draw_shift = x_minus >> 2; + if ( x_minus & 2 ) + { + dst[0] = src[2]; + src += 4; + dst += 2; + } + if ( n_draw_shift ) + { + do + { + dst[0] = src[0]; + dst[2] = src[2]; + src += 4; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + } + dst -= 800; + xx_32 -= 2; + } + while ( xx_32 >= 0 ); + goto LABEL_364; + default: // lower (top transparent), without lighting + WorldBoolFlag = 0; + xx_32 = 30; + if ( pBuff >= gpBufEnd ) + { + tile_42_45 = (unsigned int)(pBuff - gpBufEnd + 1023) >> 8; + if ( tile_42_45 > 45 ) + { + dst = pBuff - 12288; + src += 288; +LABEL_389: + i = 8; + do + { + if ( dst < gpBufEnd ) + { + j = 8; + do + { + dst[1] = src[1]; + dst[3] = src[3]; + src += 4; + dst += 4; + --j; + } + while ( j ); + } + else + { + src += 32; + dst += 32; + } + dst -= 800; + if ( dst < gpBufEnd ) + { + j = 8; + do + { + dst[0] = src[0]; + dst[2] = src[2]; + src += 4; + dst += 4; + --j; + } + while ( j ); + } + else + { + src += 32; + dst += 32; + } + dst -= 800; + --i; + } + while ( i ); + return; + } + world_tbl = WorldTbl3x16[tile_42_45]; + src += WorldTbl17_1[world_tbl >> 2]; + dst -= 192 * world_tbl; + world_tbl >>= 1; + xx_32 = 30 - world_tbl; + WorldBoolFlag += world_tbl >> 1; + } + do + { + x_minus = 32 - xx_32; + WorldBoolFlag = ((_BYTE)WorldBoolFlag + 1) & 1; + if ( WorldBoolFlag ) + { + for ( n_draw_shift = x_minus >> 2; n_draw_shift; --n_draw_shift ) + { + dst[1] = src[1]; + dst[3] = src[3]; + src += 4; + dst += 4; + } + if ( (32 - (_BYTE)xx_32) & 2 ) + { + dst[1] = src[1]; + src += 4; + dst += 2; + } + } + else + { + for ( n_draw_shift = x_minus >> 2; n_draw_shift; --n_draw_shift ) + { + dst[0] = src[0]; + dst[2] = src[2]; + src += 4; + dst += 4; + } + if ( (32 - (_BYTE)xx_32) & 2 ) + { + dst[0] = src[0]; + src += 4; + dst += 2; + } + } + dst = &dst[xx_32 - 800]; + xx_32 -= 2; + } + while ( xx_32 >= 0 ); + goto LABEL_389; + } +} + +void drawBottomArchesLowerScreen(BYTE *pBuff, unsigned int *pMask) +{ + unsigned char *dst; // edi MAPDST + short cel_type_16; // ax MAPDST + unsigned char *src; // esi MAPDST + int and80_i; // ecx MAPDST + signed int tile_42_45; // eax MAPDST + unsigned int world_tbl; // ecx MAPDST + int xx_32; // ecx MAPDST + int yy_32; // edx MAPDST + int width; // eax MAPDST + unsigned int left_shift; // edx MAPDST + signed int i; // edx MAPDST + unsigned int n_draw_shift; // ecx MAPDST + unsigned char *tbl; + + gpCelFrame = (unsigned char *)SpeedFrameTbl; + dst = pBuff; + gpDrawMask = pMask; + if ( (_BYTE)light_table_index ) + { + if ( (_BYTE)light_table_index == lightmax ) + { + if ( level_cel_block & 0x8000 ) + level_cel_block = *(_DWORD *)&gpCelFrame[64 * (level_cel_block & 0xFFF)] + + (unsigned short)(level_cel_block & 0xF000); + src = (unsigned char *)pDungeonCels + *((_DWORD *)pDungeonCels + (level_cel_block & 0xFFF)); + cel_type_16 = (level_cel_block >> 12) & 7; + switch ( cel_type_16 ) + { + case 0: // lower (bottom transparent), black + yy_32 = 32; + do + { + if ( dst < gpBufEnd ) + { + left_shift = *gpDrawMask; + i = 32; + do + { + if ( left_shift & 0x80000000 ) + dst[0] = 0; + left_shift *= 2; + ++dst; + --i; + } + while ( i ); + } + else + { + src += 32; + dst += 32; + } + dst -= 800; + --gpDrawMask; + --yy_32; + } + while ( yy_32 ); + break; + case 1: // lower (bottom transparent), black + xx_32 = 32; + do + { + gdwCurrentMask = *gpDrawMask; + yy_32 = 32; + do + { + while ( 1 ) + { + width = (unsigned char)*src++; + if ( (width & 0x80u) != 0 ) + break; + yy_32 -= width; + if ( dst < gpBufEnd ) + { + and80_i = width; + src += width; + left_shift = gdwCurrentMask; + do + { + if ( left_shift & 0x80000000 ) + dst[0] = 0; + left_shift *= 2; + ++dst; + --and80_i; + } + while ( and80_i ); + gdwCurrentMask = left_shift; + } + else + { + src += width; + dst += width; + } + if ( !yy_32 ) + goto LABEL_252; + } + _LOBYTE(width) = -(char)width; + dst += width; + if ( width & 0x1F ) + gdwCurrentMask <<= width & 0x1F; + yy_32 -= width; + } + while ( yy_32 ); +LABEL_252: + dst -= 800; + --gpDrawMask; + --xx_32; + } + while ( xx_32 ); + break; + case 2: // lower (bottom transparent), black + for ( i = 30; ; i -= 2 ) + { + if ( dst < gpBufEnd ) + { + dst += i; + n_draw_shift = (unsigned int)(32 - i) >> 2; + if ( (32 - i) & 2 ) + { + *(_WORD *)dst = 0; + dst += 2; + } + if ( n_draw_shift ) + { + do + { + *(_DWORD *)dst = 0; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + } + else + { + src = &src[32 - i]; + dst += 32; + } + dst -= 800; + if ( !i ) + break; + } + i = 2; + do + { + if ( dst < gpBufEnd ) + { + dst += i; + n_draw_shift = (unsigned int)(32 - i) >> 2; + if ( (32 - i) & 2 ) + { + *(_WORD *)dst = 0; + dst += 2; + } + if ( n_draw_shift ) + { + do + { + *(_DWORD *)dst = 0; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + } + else + { + src = &src[32 - i]; + dst += 32; + } + dst -= 800; + i += 2; + } + while ( i != 32 ); + break; + case 3: // lower (bottom transparent), black + for ( i = 30; ; i -= 2 ) + { + if ( dst < gpBufEnd ) + { + n_draw_shift = (unsigned int)(32 - i) >> 2; + if ( (32 - i) & 2 ) + { + *(_WORD *)dst = 0; + dst += 2; + } + if ( n_draw_shift ) + { + do + { + *(_DWORD *)dst = 0; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + } + else + { + src = &src[32 - i]; + dst = &dst[32 - i]; + } + dst -= 800; + if ( !i ) + break; + dst += i; + } + i = 2; + do + { + if ( dst < gpBufEnd ) + { + n_draw_shift = (unsigned int)(32 - i) >> 2; + if ( (32 - i) & 2 ) + { + *(_WORD *)dst = 0; + dst += 2; + } + if ( n_draw_shift ) + { + do + { + *(_DWORD *)dst = 0; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + } + else + { + src = &src[32 - i]; + dst = &dst[32 - i]; + } + dst = &dst[i - 800]; + i += 2; + } + while ( i != 32 ); + break; + case 4: // lower (bottom transparent), black + for ( i = 30; ; i -= 2 ) + { + if ( dst < gpBufEnd ) + { + dst += i; + n_draw_shift = (unsigned int)(32 - i) >> 2; + if ( (32 - i) & 2 ) + { + *(_WORD *)dst = 0; + dst += 2; + } + if ( n_draw_shift ) + { + do + { + *(_DWORD *)dst = 0; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + } + else + { + src = &src[32 - i]; + dst += 32; + } + dst -= 800; + if ( !i ) + break; + } + gpDrawMask -= 16; + yy_32 = 16; + do + { + if ( dst < gpBufEnd ) + { + left_shift = *gpDrawMask; + i = 32; + do + { + if ( left_shift & 0x80000000 ) + dst[0] = 0; + left_shift *= 2; + ++dst; + --i; + } + while ( i ); + } + else + { + src += 32; + dst += 32; + } + dst -= 800; + --gpDrawMask; + --yy_32; + } + while ( yy_32 ); + break; + default: // lower (bottom transparent), black + for ( i = 30; ; i -= 2 ) + { + if ( dst < gpBufEnd ) + { + n_draw_shift = (unsigned int)(32 - i) >> 2; + if ( (32 - i) & 2 ) + { + *(_WORD *)dst = 0; + dst += 2; + } + if ( n_draw_shift ) + { + do + { + *(_DWORD *)dst = 0; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + } + else + { + src = &src[32 - i]; + dst = &dst[32 - i]; + } + dst -= 800; + if ( !i ) + break; + dst += i; + } + gpDrawMask -= 16; + yy_32 = 16; + do + { + if ( dst < gpBufEnd ) + { + left_shift = *gpDrawMask; + i = 32; + do + { + if ( left_shift & 0x80000000 ) + dst[0] = 0; + left_shift *= 2; + ++dst; + --i; + } + while ( i ); + } + else + { + src += 32; + dst += 32; + } + dst -= 800; + --gpDrawMask; + --yy_32; + } + while ( yy_32 ); + break; + } + return; + } + if ( !(level_cel_block & 0x8000) ) + { + src = (unsigned char *)pDungeonCels + *((_DWORD *)pDungeonCels + (level_cel_block & 0xFFF)); + tbl = &pLightTbl[256 * light_table_index]; + cel_type_16 = (unsigned char)(level_cel_block >> 12); + switch ( cel_type_16 ) + { + case 0: // lower (bottom transparent), with lighting + yy_32 = 32; + do + { + if ( dst < gpBufEnd ) + { + asm_trans_light_mask(32, tbl, dst, src, *gpDrawMask); + } + else + { + src += 32; + dst += 32; + } + dst -= 800; + --gpDrawMask; + --yy_32; + } + while ( yy_32 ); + break; + case 1: // lower (bottom transparent), with lighting + xx_32 = 32; + do + { + gdwCurrentMask = *gpDrawMask; + yy_32 = 32; + do + { + while ( 1 ) + { + width = (unsigned char)*src++; + if ( (width & 0x80u) != 0 ) + break; + yy_32 -= width; + if ( dst < gpBufEnd ) + { + gdwCurrentMask = asm_trans_light_mask(width, tbl, dst, src, gdwCurrentMask); + } + else + { + src += width; + dst += width; + } + if ( !yy_32 ) + goto LABEL_52; + } + _LOBYTE(width) = -(char)width; + dst += width; + if ( width & 0x1F ) + gdwCurrentMask <<= width & 0x1F; + yy_32 -= width; + } + while ( yy_32 ); +LABEL_52: + dst -= 800; + --gpDrawMask; + --xx_32; + } + while ( xx_32 ); + break; + case 2: // lower (bottom transparent), with lighting + xx_32 = 30; + if ( pBuff >= gpBufEnd ) + { + tile_42_45 = (unsigned int)(pBuff - gpBufEnd + 1023) >> 8; + if ( tile_42_45 > 45 ) + { + dst = pBuff - 12288; + src += 288; +LABEL_62: + yy_32 = 2; + if ( dst >= gpBufEnd ) + { + tile_42_45 = (unsigned int)(dst - gpBufEnd + 1023) >> 8; + if ( tile_42_45 > 42 ) + return; + world_tbl = WorldTbl3x16[tile_42_45]; + src += WorldTbl17_2[world_tbl >> 2]; + dst -= 192 * world_tbl; + yy_32 = (world_tbl >> 1) + 2; + } + do + { + dst += yy_32; + src += (32 - (_BYTE)yy_32) & 2; + asm_cel_light_edge(32 - yy_32, tbl, dst, src); + yy_32 += 2; + dst -= 800; + } + while ( yy_32 != 32 ); + return; + } + world_tbl = WorldTbl3x16[tile_42_45]; + src += WorldTbl17_1[world_tbl >> 2]; + dst -= 192 * world_tbl; + xx_32 = 30 - (world_tbl >> 1); + } + do + { + dst += xx_32; + src += (32 - (_BYTE)xx_32) & 2; + asm_cel_light_edge(32 - xx_32, tbl, dst, src); + dst -= 800; + xx_32 -= 2; + } + while ( xx_32 >= 0 ); + goto LABEL_62; + case 3: // lower (bottom transparent), with lighting + xx_32 = 30; + if ( pBuff >= gpBufEnd ) + { + tile_42_45 = (unsigned int)(pBuff - gpBufEnd + 1023) >> 8; + if ( tile_42_45 > 45 ) + { + dst = pBuff - 12288; + src += 288; +LABEL_80: + yy_32 = 2; + if ( dst >= gpBufEnd ) + { + tile_42_45 = (unsigned int)(dst - gpBufEnd + 1023) >> 8; + if ( tile_42_45 > 42 ) + return; + world_tbl = WorldTbl3x16[tile_42_45]; + src += WorldTbl17_2[world_tbl >> 2]; + dst -= 192 * world_tbl; + yy_32 = (world_tbl >> 1) + 2; + } + do + { + asm_cel_light_edge(32 - yy_32, tbl, dst, src); + /// BUGFIX: uncomment this line + // src += (unsigned char)src & 2; + dst = &dst[yy_32 - 800]; + yy_32 += 2; + } + while ( yy_32 != 32 ); + return; + } + world_tbl = WorldTbl3x16[tile_42_45]; + src += WorldTbl17_1[world_tbl >> 2]; + dst -= 192 * world_tbl; + xx_32 = 30 - (world_tbl >> 1); + } + do + { + asm_cel_light_edge(32 - xx_32, tbl, dst, src); + src += (unsigned char)src & 2; + dst = &dst[xx_32 - 800]; + xx_32 -= 2; + } + while ( xx_32 >= 0 ); + goto LABEL_80; + case 4: // lower (bottom transparent), with lighting + xx_32 = 30; + if ( pBuff >= gpBufEnd ) + { + tile_42_45 = (unsigned int)(pBuff - gpBufEnd + 1023) >> 8; + if ( tile_42_45 > 45 ) + { + dst = pBuff - 12288; + src += 288; +LABEL_98: + gpDrawMask -= 16; + yy_32 = 16; + do + { + if ( dst < gpBufEnd ) + { + asm_trans_light_mask(32, tbl, dst, src, *gpDrawMask); + } + else + { + src += 32; + dst += 32; + } + dst -= 800; + --gpDrawMask; + --yy_32; + } + while ( yy_32 ); + return; + } + world_tbl = WorldTbl3x16[tile_42_45]; + src += WorldTbl17_1[world_tbl >> 2]; + dst -= 192 * world_tbl; + xx_32 = 30 - (world_tbl >> 1); + } + do + { + dst += xx_32; + src += (32 - (_BYTE)xx_32) & 2; + asm_cel_light_edge(32 - xx_32, tbl, dst, src); + dst -= 800; + xx_32 -= 2; + } + while ( xx_32 >= 0 ); + goto LABEL_98; + default: // lower (bottom transparent), with lighting + xx_32 = 30; + if ( pBuff >= gpBufEnd ) + { + tile_42_45 = (unsigned int)(pBuff - gpBufEnd + 1023) >> 8; + if ( tile_42_45 > 45 ) + { + dst = pBuff - 12288; + src += 288; +LABEL_117: + gpDrawMask -= 16; + yy_32 = 16; + do + { + if ( dst < gpBufEnd ) + { + asm_trans_light_mask(32, tbl, dst, src, *gpDrawMask); + src += (unsigned char)src & 2; + } + else + { + src += 32; + dst += 32; + } + dst -= 800; + --gpDrawMask; + --yy_32; + } + while ( yy_32 ); + return; + } + world_tbl = WorldTbl3x16[tile_42_45]; + src += WorldTbl17_1[world_tbl >> 2]; + dst -= 192 * world_tbl; + xx_32 = 30 - (world_tbl >> 1); + } + do + { + asm_cel_light_edge(32 - xx_32, tbl, dst, src); + src += (unsigned char)src & 2; + dst = &dst[xx_32 - 800]; + xx_32 -= 2; + } + while ( xx_32 >= 0 ); + goto LABEL_117; + } + return; + } + src = (unsigned char *)pSpeedCels + + *(_DWORD *)&gpCelFrame[4 * (light_table_index + 16 * (level_cel_block & 0xFFF))]; + cel_type_16 = (unsigned char)(level_cel_block >> 12); + } + else + { + if ( level_cel_block & 0x8000 ) + level_cel_block = *(_DWORD *)&gpCelFrame[64 * (level_cel_block & 0xFFF)] + + (unsigned short)(level_cel_block & 0xF000); + src = (unsigned char *)pDungeonCels + *((_DWORD *)pDungeonCels + (level_cel_block & 0xFFF)); + cel_type_16 = ((level_cel_block >> 12) & 7) + 8; + } + switch ( cel_type_16 ) + { + case 8: // lower (bottom transparent), without lighting + yy_32 = 32; + do + { + if ( dst < gpBufEnd ) + { + left_shift = *gpDrawMask; + i = 32; + do + { + if ( left_shift & 0x80000000 ) + dst[0] = src[0]; + left_shift *= 2; + ++src; + ++dst; + --i; + } + while ( i ); + } + else + { + src += 32; + dst += 32; + } + dst -= 800; + --gpDrawMask; + --yy_32; + } + while ( yy_32 ); + break; + case 9: // lower (bottom transparent), without lighting + xx_32 = 32; + do + { + gdwCurrentMask = *gpDrawMask; + yy_32 = 32; + do + { + while ( 1 ) + { + width = (unsigned char)*src++; + if ( (width & 0x80u) != 0 ) + break; + yy_32 -= width; + if ( dst < gpBufEnd ) + { + and80_i = width; + left_shift = gdwCurrentMask; + do + { + if ( left_shift & 0x80000000 ) + dst[0] = src[0]; + left_shift *= 2; + ++src; + ++dst; + --and80_i; + } + while ( and80_i ); + gdwCurrentMask = left_shift; + } + else + { + src += width; + dst += width; + } + if ( !yy_32 ) + goto LABEL_152; + } + _LOBYTE(width) = -(char)width; + dst += width; + if ( width & 0x1F ) + gdwCurrentMask <<= width & 0x1F; + yy_32 -= width; + } + while ( yy_32 ); +LABEL_152: + dst -= 800; + --gpDrawMask; + --xx_32; + } + while ( xx_32 ); + break; + case 10: // lower (bottom transparent), without lighting + xx_32 = 30; + if ( pBuff >= gpBufEnd ) + { + tile_42_45 = (unsigned int)(pBuff - gpBufEnd + 1023) >> 8; + if ( tile_42_45 > 45 ) + { + dst = pBuff - 12288; + src += 288; +LABEL_162: + yy_32 = 2; + if ( dst >= gpBufEnd ) + { + tile_42_45 = (unsigned int)(dst - gpBufEnd + 1023) >> 8; + if ( tile_42_45 > 42 ) + return; + world_tbl = WorldTbl3x16[tile_42_45]; + src += WorldTbl17_2[world_tbl >> 2]; + dst -= 192 * world_tbl; + yy_32 = (world_tbl >> 1) + 2; + } + do + { + dst += yy_32; + n_draw_shift = (unsigned int)(32 - yy_32) >> 2; + if ( (32 - yy_32) & 2 ) + { + *(_WORD *)dst = *((_WORD *)src + 1); + src += 4; + dst += 2; + } + if ( n_draw_shift ) + { + do + { + *(_DWORD *)dst = *(_DWORD *)src; + src += 4; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + dst -= 800; + yy_32 += 2; + } + while ( yy_32 != 32 ); + return; + } + world_tbl = WorldTbl3x16[tile_42_45]; + src += WorldTbl17_1[world_tbl >> 2]; + dst -= 192 * world_tbl; + xx_32 = 30 - (world_tbl >> 1); + } + do + { + dst += xx_32; + n_draw_shift = (unsigned int)(32 - xx_32) >> 2; + if ( (32 - xx_32) & 2 ) + { + *(_WORD *)dst = *((_WORD *)src + 1); + src += 4; + dst += 2; + } + if ( n_draw_shift ) + { + do + { + *(_DWORD *)dst = *(_DWORD *)src; + src += 4; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + dst -= 800; + xx_32 -= 2; + } + while ( xx_32 >= 0 ); + goto LABEL_162; + case 11: // lower (bottom transparent), without lighting + xx_32 = 30; + if ( pBuff < gpBufEnd ) + goto LABEL_175; + tile_42_45 = (unsigned int)(pBuff - gpBufEnd + 1023) >> 8; + if ( tile_42_45 <= 45 ) + { + world_tbl = WorldTbl3x16[tile_42_45]; + src += WorldTbl17_1[world_tbl >> 2]; + dst -= 192 * world_tbl; + xx_32 = 30 - (world_tbl >> 1); + do + { +LABEL_175: + for ( n_draw_shift = (unsigned int)(32 - xx_32) >> 2; n_draw_shift; --n_draw_shift ) + { + *(_DWORD *)dst = *(_DWORD *)src; + src += 4; + dst += 4; + } + if ( (32 - (_BYTE)xx_32) & 2 ) + { + *(_WORD *)dst = *(_WORD *)src; + src += 4; + dst += 2; + } + dst = &dst[xx_32 - 800]; + xx_32 -= 2; + } + while ( xx_32 >= 0 ); + goto LABEL_180; + } + dst = pBuff - 12288; + src += 288; +LABEL_180: + yy_32 = 2; + if ( dst >= gpBufEnd ) + { + tile_42_45 = (unsigned int)(dst - gpBufEnd + 1023) >> 8; + if ( tile_42_45 > 42 ) + return; + world_tbl = WorldTbl3x16[tile_42_45]; + src += WorldTbl17_2[world_tbl >> 2]; + dst -= 192 * world_tbl; + yy_32 = (world_tbl >> 1) + 2; + } + do + { + for ( n_draw_shift = (unsigned int)(32 - yy_32) >> 2; n_draw_shift; --n_draw_shift ) + { + *(_DWORD *)dst = *(_DWORD *)src; + src += 4; + dst += 4; + } + if ( (32 - (_BYTE)yy_32) & 2 ) + { + *(_WORD *)dst = *(_WORD *)src; + src += 4; + dst += 2; + } + dst = &dst[yy_32 - 800]; + yy_32 += 2; + } + while ( yy_32 != 32 ); + break; + case 12: // lower (bottom transparent), without lighting + xx_32 = 30; + if ( pBuff >= gpBufEnd ) + { + tile_42_45 = (unsigned int)(pBuff - gpBufEnd + 1023) >> 8; + if ( tile_42_45 > 45 ) + { + dst = pBuff - 12288; + src += 288; +LABEL_198: + gpDrawMask -= 16; + yy_32 = 16; + do + { + if ( dst < gpBufEnd ) + { + left_shift = *gpDrawMask; + i = 32; + do + { + if ( left_shift & 0x80000000 ) + dst[0] = src[0]; + left_shift *= 2; + ++src; + ++dst; + --i; + } + while ( i ); + } + else + { + src += 32; + dst += 32; + } + dst -= 800; + --gpDrawMask; + --yy_32; + } + while ( yy_32 ); + return; + } + world_tbl = WorldTbl3x16[tile_42_45]; + src += WorldTbl17_1[world_tbl >> 2]; + dst -= 192 * world_tbl; + xx_32 = 30 - (world_tbl >> 1); + } + do + { + dst += xx_32; + n_draw_shift = (unsigned int)(32 - xx_32) >> 2; + if ( (32 - xx_32) & 2 ) + { + *(_WORD *)dst = *((_WORD *)src + 1); + src += 4; + dst += 2; + } + if ( n_draw_shift ) + { + do + { + *(_DWORD *)dst = *(_DWORD *)src; + src += 4; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + dst -= 800; + xx_32 -= 2; + } + while ( xx_32 >= 0 ); + goto LABEL_198; + default: // lower (bottom transparent), without lighting + xx_32 = 30; + if ( pBuff >= gpBufEnd ) + { + tile_42_45 = (unsigned int)(pBuff - gpBufEnd + 1023) >> 8; + if ( tile_42_45 > 45 ) + { + dst = pBuff - 12288; + src += 288; +LABEL_217: + gpDrawMask -= 16; + yy_32 = 16; + do + { + if ( dst < gpBufEnd ) + { + left_shift = *gpDrawMask; + i = 32; + do + { + if ( left_shift & 0x80000000 ) + dst[0] = src[0]; + left_shift *= 2; + ++src; + ++dst; + --i; + } + while ( i ); + src += (unsigned char)src & 2; + } + else + { + src += 32; + dst += 32; + } + dst -= 800; + --gpDrawMask; + --yy_32; + } + while ( yy_32 ); + return; + } + world_tbl = WorldTbl3x16[tile_42_45]; + src += WorldTbl17_1[world_tbl >> 2]; + dst -= 192 * world_tbl; + xx_32 = 30 - (world_tbl >> 1); + } + do + { + for ( n_draw_shift = (unsigned int)(32 - xx_32) >> 2; n_draw_shift; --n_draw_shift ) + { + *(_DWORD *)dst = *(_DWORD *)src; + src += 4; + dst += 4; + } + if ( (32 - (_BYTE)xx_32) & 2 ) + { + *(_WORD *)dst = *(_WORD *)src; + src += 4; + dst += 2; + } + dst = &dst[xx_32 - 800]; + xx_32 -= 2; + } + while ( xx_32 >= 0 ); + goto LABEL_217; + } +} + +void drawLowerScreen(BYTE *pBuff) +{ + unsigned char *dst; // edi MAPDST + unsigned char *src; // esi MAPDST + unsigned char *tbl; // ebx + short cel_type_16; // ax MAPDST + int xx_32; // edx MAPDST + int yy_32; // ebp MAPDST + unsigned int chk_sh_and; // ecx MAPDST + signed int tile_42_45; // eax MAPDST + unsigned int world_tbl; // ecx MAPDST + unsigned int n_draw_shift; // ecx MAPDST + unsigned int width; // eax MAPDST + signed int i; // edx MAPDST + signed int j; // ecx MAPDST + + if ( cel_transparency_active ) + { + if ( !arch_draw_type ) + { + drawTopArchesLowerScreen(pBuff); + return; + } + if ( arch_draw_type == 1 ) + { + if ( block_lvid[level_piece_id] == 1 || block_lvid[level_piece_id] == 3 ) + { + drawBottomArchesLowerScreen(pBuff, &LeftMask[31]); + return; + } + } + if ( arch_draw_type == 2 ) + { + if ( block_lvid[level_piece_id] == 2 || block_lvid[level_piece_id] == 3 ) + { + drawBottomArchesLowerScreen(pBuff, &RightMask[31]); + return; + } + } + } + gpCelFrame = (unsigned char *)SpeedFrameTbl; + dst = pBuff; + if ( (_BYTE)light_table_index ) + { + if ( (_BYTE)light_table_index == lightmax ) + { + if ( level_cel_block & 0x8000 ) + level_cel_block = *(_DWORD *)&gpCelFrame[64 * (level_cel_block & 0xFFF)] + + (unsigned short)(level_cel_block & 0xF000); + src = (unsigned char *)pDungeonCels + *((_DWORD *)pDungeonCels + (level_cel_block & 0xFFF)); + cel_type_16 = (level_cel_block >> 12) & 7; + switch ( cel_type_16 ) + { + case 0: // lower (solid), black + i = 32; + do + { + if ( dst < gpBufEnd ) + { + j = 8; + do + { + *(_DWORD *)dst = 0; + dst += 4; + --j; + } + while ( j ); + } + else + { + src += 32; + dst += 32; + } + dst -= 800; + --i; + } + while ( i ); + break; + case 1: // lower (solid), black + xx_32 = 32; + do + { + yy_32 = 32; + do + { + while ( 1 ) + { + width = (unsigned char)*src++; + if ( (width & 0x80u) == 0 ) + break; + _LOBYTE(width) = -(char)width; + dst += width; + yy_32 -= width; + if ( !yy_32 ) + goto LABEL_232; + } + yy_32 -= width; + if ( dst < gpBufEnd ) + { + src += width; + chk_sh_and = width >> 1; + if ( width & 1 ) + { + dst[0] = 0; + ++dst; + } + if ( chk_sh_and ) + { + n_draw_shift = width >> 2; + if ( chk_sh_and & 1 ) + { + *(_WORD *)dst = 0; + dst += 2; + } + if ( n_draw_shift ) + { + do + { + *(_DWORD *)dst = 0; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + } + } + else + { + src += width; + dst += width; + } + } + while ( yy_32 ); +LABEL_232: + dst -= 800; + --xx_32; + } + while ( xx_32 ); + break; + case 2: // lower (solid), black + for ( i = 30; ; i -= 2 ) + { + if ( dst < gpBufEnd ) + { + dst += i; + n_draw_shift = (unsigned int)(32 - i) >> 2; + if ( (32 - i) & 2 ) + { + *(_WORD *)dst = 0; + dst += 2; + } + if ( n_draw_shift ) + { + do + { + *(_DWORD *)dst = 0; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + } + else + { + src = &src[32 - i]; + dst += 32; + } + dst -= 800; + if ( !i ) + break; + } + i = 2; + do + { + if ( dst < gpBufEnd ) + { + dst += i; + n_draw_shift = (unsigned int)(32 - i) >> 2; + if ( (32 - i) & 2 ) + { + *(_WORD *)dst = 0; + dst += 2; + } + if ( n_draw_shift ) + { + do + { + *(_DWORD *)dst = 0; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + } + else + { + src = &src[32 - i]; + dst += 32; + } + dst -= 800; + i += 2; + } + while ( i != 32 ); + break; + case 3: // lower (solid), black + for ( i = 30; ; i -= 2 ) + { + if ( dst < gpBufEnd ) + { + n_draw_shift = (unsigned int)(32 - i) >> 2; + if ( (32 - i) & 2 ) + { + *(_WORD *)dst = 0; + dst += 2; + } + if ( n_draw_shift ) + { + do + { + *(_DWORD *)dst = 0; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + } + else + { + src = &src[32 - i]; + dst = &dst[32 - i]; + } + dst -= 800; + if ( !i ) + break; + dst += i; + } + i = 2; + do + { + if ( dst < gpBufEnd ) + { + n_draw_shift = (unsigned int)(32 - i) >> 2; + if ( (32 - i) & 2 ) + { + *(_WORD *)dst = 0; + dst += 2; + } + if ( n_draw_shift ) + { + do + { + *(_DWORD *)dst = 0; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + } + else + { + src = &src[32 - i]; + dst = &dst[32 - i]; + } + dst = &dst[i - 800]; + i += 2; + } + while ( i != 32 ); + break; + case 4: // lower (solid), black + for ( i = 30; ; i -= 2 ) + { + if ( dst < gpBufEnd ) + { + dst += i; + n_draw_shift = (unsigned int)(32 - i) >> 2; + if ( (32 - i) & 2 ) + { + *(_WORD *)dst = 0; + dst += 2; + } + if ( n_draw_shift ) + { + do + { + *(_DWORD *)dst = 0; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + } + else + { + src = &src[32 - i]; + dst += 32; + } + dst -= 800; + if ( !i ) + break; + } + i = 16; + do + { + if ( dst < gpBufEnd ) + { + j = 8; + do + { + *(_DWORD *)dst = 0; + dst += 4; + --j; + } + while ( j ); + } + else + { + src += 32; + dst += 32; + } + dst -= 800; + --i; + } + while ( i ); + break; + default: // lower (solid), black + for ( i = 30; ; i -= 2 ) + { + if ( dst < gpBufEnd ) + { + n_draw_shift = (unsigned int)(32 - i) >> 2; + if ( (32 - i) & 2 ) + { + *(_WORD *)dst = 0; + dst += 2; + } + if ( n_draw_shift ) + { + do + { + *(_DWORD *)dst = 0; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + } + else + { + src = &src[32 - i]; + dst = &dst[32 - i]; + } + dst -= 800; + if ( !i ) + break; + dst += i; + } + i = 16; + do + { + if ( dst < gpBufEnd ) + { + j = 8; + do + { + *(_DWORD *)dst = 0; + dst += 4; + --j; + } + while ( j ); + } + else + { + src += 32; + dst += 32; + } + dst -= 800; + --i; + } + while ( i ); + break; + } + return; + } + if ( !(level_cel_block & 0x8000) ) + { + src = (unsigned char *)pDungeonCels + *((_DWORD *)pDungeonCels + (level_cel_block & 0xFFF)); + tbl = &pLightTbl[256 * light_table_index]; + cel_type_16 = (unsigned short)level_cel_block >> 12; + switch ( cel_type_16 ) + { + case 0: // lower (solid), with lighting + xx_32 = 32; + do + { + if ( dst < gpBufEnd ) + { + asm_cel_light_square(8, tbl, dst, src); + } + else + { + src += 32; + dst += 32; + } + dst -= 800; + --xx_32; + } + while ( xx_32 ); + break; + case 1: // lower (solid), with lighting + xx_32 = 32; + do + { + yy_32 = 32; + do + { + width = (unsigned char)*src++; + if ( (width & 0x80u) == 0 ) + { + yy_32 -= width; + if ( dst < gpBufEnd ) + { + asm_cel_light_edge(width, tbl, dst, src); + } + else + { + src += width; + dst += width; + } + } + else + { + _LOBYTE(width) = -(char)width; + dst += width; + yy_32 -= width; + } + } + while ( yy_32 ); + dst -= 800; + --xx_32; + } + while ( xx_32 ); + break; + case 2: // lower (solid), with lighting + xx_32 = 30; + if ( pBuff >= gpBufEnd ) + { + tile_42_45 = (unsigned int)(pBuff - gpBufEnd + 1023) >> 8; + if ( tile_42_45 > 45 ) + { + dst = pBuff - 12288; + src += 288; +LABEL_68: + yy_32 = 2; + if ( dst >= gpBufEnd ) + { + tile_42_45 = (unsigned int)(dst - gpBufEnd + 1023) >> 8; + if ( tile_42_45 > 42 ) + return; + world_tbl = WorldTbl3x16[tile_42_45]; + src += WorldTbl17_2[world_tbl >> 2]; + dst -= 192 * world_tbl; + yy_32 = (world_tbl >> 1) + 2; + } + do + { + dst += yy_32; + src += (32 - (_BYTE)yy_32) & 2; + asm_cel_light_edge(32 - yy_32, tbl, dst, src); + yy_32 += 2; + dst -= 800; + } + while ( yy_32 != 32 ); + return; + } + world_tbl = WorldTbl3x16[tile_42_45]; + src += WorldTbl17_1[world_tbl >> 2]; + dst -= 192 * world_tbl; + xx_32 = 30 - (world_tbl >> 1); + } + do + { + dst += xx_32; + src += (32 - (_BYTE)xx_32) & 2; + asm_cel_light_edge(32 - xx_32, tbl, dst, src); + dst -= 800; + xx_32 -= 2; + } + while ( xx_32 >= 0 ); + goto LABEL_68; + case 3: // lower (solid), with lighting + xx_32 = 30; + if ( pBuff >= gpBufEnd ) + { + tile_42_45 = (unsigned int)(pBuff - gpBufEnd + 1023) >> 8; + if ( tile_42_45 > 45 ) + { + dst = pBuff - 12288; + src += 288; +LABEL_83: + yy_32 = 2; + if ( dst >= gpBufEnd ) + { + tile_42_45 = (unsigned int)(dst - gpBufEnd + 1023) >> 8; + if ( tile_42_45 > 42 ) + return; + world_tbl = WorldTbl3x16[tile_42_45]; + src += WorldTbl17_2[world_tbl >> 2]; + dst -= 192 * world_tbl; + yy_32 = (world_tbl >> 1) + 2; + } + do + { + asm_cel_light_edge(32 - yy_32, tbl, dst, src); + src += (unsigned char)src & 2; + dst = &dst[yy_32 - 800]; + yy_32 += 2; + } + while ( yy_32 != 32 ); + return; + } + world_tbl = WorldTbl3x16[tile_42_45]; + src += WorldTbl17_1[world_tbl >> 2]; + dst -= 192 * world_tbl; + xx_32 = 30 - (world_tbl >> 1); + } + do + { + asm_cel_light_edge(32 - xx_32, tbl, dst, src); + src += (unsigned char)src & 2; + dst = &dst[xx_32 - 800]; + xx_32 -= 2; + } + while ( xx_32 >= 0 ); + goto LABEL_83; + case 4: // lower (solid), with lighting + xx_32 = 30; + if ( pBuff >= gpBufEnd ) + { + tile_42_45 = (unsigned int)(pBuff - gpBufEnd + 1023) >> 8; + if ( tile_42_45 > 45 ) + { + dst = pBuff - 12288; + src += 288; +LABEL_100: + i = 16; + do + { + if ( dst < gpBufEnd ) + { + asm_cel_light_square(8, tbl, dst, src); + } + else + { + src += 32; + dst += 32; + } + dst -= 800; + --i; + } + while ( i ); + return; + } + world_tbl = WorldTbl3x16[tile_42_45]; + src += WorldTbl17_1[world_tbl >> 2]; + dst -= 192 * world_tbl; + xx_32 = 30 - (world_tbl >> 1); + } + do + { + dst += xx_32; + src += (32 - (_BYTE)xx_32) & 2; + asm_cel_light_edge(32 - xx_32, tbl, dst, src); + dst -= 800; + xx_32 -= 2; + } + while ( xx_32 >= 0 ); + goto LABEL_100; + default: // lower (solid), with lighting + xx_32 = 30; + if ( pBuff >= gpBufEnd ) + { + tile_42_45 = (unsigned int)(pBuff - gpBufEnd + 1023) >> 8; + if ( tile_42_45 > 45 ) + { + dst = pBuff - 12288; + src += 288; +LABEL_116: + j = 16; + do + { + if ( dst < gpBufEnd ) + { + asm_cel_light_square(8, tbl, dst, src); + } + else + { + src += 32; + dst += 32; + } + dst -= 800; + --j; + } + while ( j ); + return; + } + world_tbl = WorldTbl3x16[tile_42_45]; + src += WorldTbl17_1[world_tbl >> 2]; + dst -= 192 * world_tbl; + xx_32 = 30 - (world_tbl >> 1); + } + do + { + asm_cel_light_edge(32 - xx_32, tbl, dst, src); + src += (unsigned char)src & 2; + dst = &dst[xx_32 - 800]; + xx_32 -= 2; + } + while ( xx_32 >= 0 ); + goto LABEL_116; + } + return; + } + src = (unsigned char *)pSpeedCels + + *(_DWORD *)&gpCelFrame[4 * (light_table_index + 16 * (level_cel_block & 0xFFF))]; + cel_type_16 = (unsigned short)level_cel_block >> 12; + } + else + { + if ( level_cel_block & 0x8000 ) + level_cel_block = *(_DWORD *)&gpCelFrame[64 * (level_cel_block & 0xFFF)] + + (unsigned short)(level_cel_block & 0xF000); + src = (unsigned char *)pDungeonCels + *((_DWORD *)pDungeonCels + (level_cel_block & 0xFFF)); + cel_type_16 = (((unsigned int)level_cel_block >> 12) & 7) + 8; + } + switch ( cel_type_16 ) + { + case 8: // lower (solid), without lighting + i = 32; + do + { + if ( dst < gpBufEnd ) + { + j = 8; + do + { + *(_DWORD *)dst = *(_DWORD *)src; + src += 4; + dst += 4; + --j; + } + while ( j ); + } + else + { + src += 32; + dst += 32; + } + dst -= 800; + --i; + } + while ( i ); + break; + case 9: // lower (solid), without lighting + xx_32 = 32; + do + { + yy_32 = 32; + do + { + while ( 1 ) + { + width = (unsigned char)*src++; + if ( (width & 0x80u) == 0 ) + break; + _LOBYTE(width) = -(char)width; + dst += width; + yy_32 -= width; + if ( !yy_32 ) + goto LABEL_143; + } + yy_32 -= width; + if ( dst < gpBufEnd ) + { + chk_sh_and = width >> 1; + if ( width & 1 ) + { + dst[0] = src[0]; + ++src; + ++dst; + } + if ( chk_sh_and ) + { + n_draw_shift = chk_sh_and >> 1; + if ( chk_sh_and & 1 ) + { + *(_WORD *)dst = *(_WORD *)src; + src += 2; + dst += 2; + } + if ( n_draw_shift ) + { + do + { + *(_DWORD *)dst = *(_DWORD *)src; + src += 4; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + } + } + else + { + src += width; + dst += width; + } + } + while ( yy_32 ); +LABEL_143: + dst -= 800; + --xx_32; + } + while ( xx_32 ); + break; + case 10: // lower (solid), without lighting + xx_32 = 30; + if ( pBuff >= gpBufEnd ) + { + tile_42_45 = (unsigned int)(pBuff - gpBufEnd + 1023) >> 8; + if ( tile_42_45 > 45 ) + { + dst = pBuff - 12288; + src += 288; +LABEL_153: + yy_32 = 2; + if ( dst >= gpBufEnd ) + { + tile_42_45 = (unsigned int)(dst - gpBufEnd + 1023) >> 8; + if ( tile_42_45 > 42 ) + return; + world_tbl = WorldTbl3x16[tile_42_45]; + src += WorldTbl17_2[world_tbl >> 2]; + dst -= 192 * world_tbl; + yy_32 = (world_tbl >> 1) + 2; + } + do + { + dst += yy_32; + n_draw_shift = (unsigned int)(32 - yy_32) >> 2; + if ( (32 - yy_32) & 2 ) + { + *(_WORD *)dst = *((_WORD *)src + 1); + src += 4; + dst += 2; + } + if ( n_draw_shift ) + { + do + { + *(_DWORD *)dst = *(_DWORD *)src; + src += 4; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + yy_32 += 2; + dst -= 800; + } + while ( yy_32 < 32 ); + return; + } + world_tbl = WorldTbl3x16[tile_42_45]; + src += WorldTbl17_1[world_tbl >> 2]; + dst -= 192 * world_tbl; + xx_32 = 30 - (world_tbl >> 1); + } + do + { + dst += xx_32; + n_draw_shift = (unsigned int)(32 - xx_32) >> 2; + if ( (32 - xx_32) & 2 ) + { + *(_WORD *)dst = *((_WORD *)src + 1); + src += 4; + dst += 2; + } + if ( n_draw_shift ) + { + do + { + *(_DWORD *)dst = *(_DWORD *)src; + src += 4; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + dst -= 800; + xx_32 -= 2; + } + while ( xx_32 >= 0 ); + goto LABEL_153; + case 11: // lower (solid), without lighting + xx_32 = 30; + if ( pBuff < gpBufEnd ) + goto LABEL_166; + tile_42_45 = (unsigned int)(pBuff - gpBufEnd + 1023) >> 8; + if ( tile_42_45 <= 45 ) + { + world_tbl = WorldTbl3x16[tile_42_45]; + src += WorldTbl17_1[world_tbl >> 2]; + dst -= 192 * world_tbl; + xx_32 = 30 - (world_tbl >> 1); + do + { +LABEL_166: + for ( n_draw_shift = (unsigned int)(32 - xx_32) >> 2; n_draw_shift; --n_draw_shift ) + { + *(_DWORD *)dst = *(_DWORD *)src; + src += 4; + dst += 4; + } + if ( (32 - (_BYTE)xx_32) & 2 ) + { + *(_WORD *)dst = *(_WORD *)src; + src += 4; + dst += 2; + } + dst = &dst[xx_32 - 800]; + xx_32 -= 2; + } + while ( xx_32 >= 0 ); + goto LABEL_171; + } + dst = pBuff - 12288; + src += 288; +LABEL_171: + yy_32 = 2; + if ( dst >= gpBufEnd ) + { + tile_42_45 = (unsigned int)(dst - gpBufEnd + 1023) >> 8; + if ( tile_42_45 > 42 ) + return; + world_tbl = WorldTbl3x16[tile_42_45]; + src += WorldTbl17_2[world_tbl >> 2]; + dst -= 192 * world_tbl; + yy_32 = (world_tbl >> 1) + 2; + } + do + { + for ( n_draw_shift = (unsigned int)(32 - yy_32) >> 2; n_draw_shift; --n_draw_shift ) + { + *(_DWORD *)dst = *(_DWORD *)src; + src += 4; + dst += 4; + } + if ( (32 - (_BYTE)yy_32) & 2 ) + { + *(_WORD *)dst = *(_WORD *)src; + src += 4; + dst += 2; + } + dst += yy_32; + yy_32 += 2; + dst -= 800; + } + while ( yy_32 < 32 ); + break; + case 12: // lower (solid), without lighting + xx_32 = 30; + if ( pBuff >= gpBufEnd ) + { + tile_42_45 = (unsigned int)(pBuff - gpBufEnd + 1023) >> 8; + if ( tile_42_45 > 45 ) + { + dst = pBuff - 12288; + src += 288; +LABEL_189: + i = 16; + do + { + if ( dst < gpBufEnd ) + { + j = 8; + do + { + *(_DWORD *)dst = *(_DWORD *)src; + src += 4; + dst += 4; + --j; + } + while ( j ); + } + else + { + src += 32; + dst += 32; + } + dst -= 800; + --i; + } + while ( i ); + return; + } + world_tbl = WorldTbl3x16[tile_42_45]; + src += WorldTbl17_1[world_tbl >> 2]; + dst -= 192 * world_tbl; + xx_32 = 30 - (world_tbl >> 1); + } + do + { + dst += xx_32; + n_draw_shift = (unsigned int)(32 - xx_32) >> 2; + if ( (32 - xx_32) & 2 ) + { + *(_WORD *)dst = *((_WORD *)src + 1); + src += 4; + dst += 2; + } + if ( n_draw_shift ) + { + do + { + *(_DWORD *)dst = *(_DWORD *)src; + src += 4; + dst += 4; + --n_draw_shift; + } + while ( n_draw_shift ); + } + dst -= 800; + xx_32 -= 2; + } + while ( xx_32 >= 0 ); + goto LABEL_189; + default: // lower (solid), without lighting + xx_32 = 30; + if ( pBuff >= gpBufEnd ) + { + tile_42_45 = (unsigned int)(pBuff - gpBufEnd + 1023) >> 8; + if ( tile_42_45 > 45 ) + { + dst = pBuff - 12288; + src += 288; +LABEL_205: + i = 16; + do + { + if ( dst < gpBufEnd ) + { + j = 8; + do + { + *(_DWORD *)dst = *(_DWORD *)src; + src += 4; + dst += 4; + --j; + } + while ( j ); + } + else + { + src += 32; + dst += 32; + } + dst -= 800; + --i; + } + while ( i ); + return; + } + world_tbl = WorldTbl3x16[tile_42_45]; + src += WorldTbl17_1[world_tbl >> 2]; + dst -= 192 * world_tbl; + xx_32 = 30 - (world_tbl >> 1); + } + do + { + for ( n_draw_shift = (unsigned int)(32 - xx_32) >> 2; n_draw_shift; --n_draw_shift ) + { + *(_DWORD *)dst = *(_DWORD *)src; + src += 4; + dst += 4; + } + if ( (32 - (_BYTE)xx_32) & 2 ) + { + *(_WORD *)dst = *(_WORD *)src; + src += 4; + dst += 2; + } + dst = &dst[xx_32 - 800]; + xx_32 -= 2; + } + while ( xx_32 >= 0 ); + goto LABEL_205; + } +} + +void world_draw_black_tile(BYTE *pBuff) +{ + unsigned char *dst; // edi MAPDST + signed int xx_32; // edx + signed int i; // ebx MAPDST + signed int j; // ecx MAPDST + signed int yy_32; // edx + + dst = pBuff; + xx_32 = 30; + for ( i = 1; ; ++i ) + { + dst += xx_32; + j = i; + do + { + *(_DWORD *)dst = 0; + dst += 4; + --j; + } + while ( j ); + dst = &dst[xx_32 - 832]; + if ( !xx_32 ) + break; + xx_32 -= 2; + } + yy_32 = 2; + i = 15; + do + { + dst += yy_32; + j = i; + do + { + *(_DWORD *)dst = 0; + dst += 4; + --j; + } + while ( j ); + dst = &dst[yy_32 - 832]; + --i; + yy_32 += 2; + } + while ( yy_32 != 32 ); +} +#endif diff --git a/2020_03_31/Source/render.h b/2020_03_31/Source/render.h new file mode 100644 index 00000000..8310e9b4 --- /dev/null +++ b/2020_03_31/Source/render.h @@ -0,0 +1,28 @@ +//HEADER_GOES_HERE +#ifndef __RENDER_H__ +#define __RENDER_H__ + +void drawTopArchesUpperScreen(BYTE *pBuff); +void drawBottomArchesUpperScreen(BYTE *pBuff, unsigned int *pMask); +void drawUpperScreen(BYTE *pBuff); +void drawTopArchesLowerScreen(BYTE *pBuff); +void drawBottomArchesLowerScreen(BYTE *pBuff, unsigned int *pMask); +void drawLowerScreen(BYTE *pBuff); +void world_draw_black_tile(BYTE *pBuff); + +/* rdata */ + +extern int WorldBoolFlag; +extern unsigned int gdwCurrentMask; +// extern char world_4B3264; +extern unsigned char *gpCelFrame; +extern unsigned int *gpDrawMask; +// extern char world_4B326D[16]; +extern unsigned int RightMask[32]; +extern unsigned int LeftMask[32]; +extern unsigned int WallMask[32]; +extern int WorldTbl3x16[48]; +extern int WorldTbl17_1[17]; +extern int WorldTbl17_2[17]; + +#endif /* __RENDER_H__ */ diff --git a/2020_03_31/Source/restrict.cpp b/2020_03_31/Source/restrict.cpp new file mode 100644 index 00000000..5fce22cb --- /dev/null +++ b/2020_03_31/Source/restrict.cpp @@ -0,0 +1,71 @@ +#include "diablo.h" + +BOOL SystemSupported() +{ + BOOL v0; // di + struct _OSVERSIONINFOA VersionInformation; // [esp+4h] [ebp-94h] + + v0 = 0; + memset(&VersionInformation, 0, 0x94u); + VersionInformation.dwOSVersionInfoSize = 148; + if ( GetVersionEx(&VersionInformation) + && VersionInformation.dwPlatformId == 2 + && VersionInformation.dwMajorVersion >= 5 ) + { + v0 = 1; + } + return v0; +} + +BOOL RestrictedTest() +{ + BOOL v0; // si + FILE *v2; // eax + char Buffer[260]; // [esp+4h] [ebp-104h] + + v0 = 0; + if ( SystemSupported() && GetWindowsDirectory(Buffer, 0x104u) ) + { + strcat(Buffer, "\\Diablo1RestrictedTest.foo"); + v2 = fopen(Buffer, "wt"); + if ( v2 ) + { + fclose(v2); + remove(Buffer); + } + else + { + v0 = 1; + } + } + return v0; +} + +BOOL ReadOnlyTest() +{ + BOOL v0; // si + char *v1; // eax + FILE *v2; // eax + char Filename[260]; // [esp+4h] [ebp-104h] + + v0 = 0; + if ( GetModuleFileName(ghInst, Filename, 0x104u) ) + { + v1 = strrchr(Filename, '\\'); + if ( v1 ) + { + strcpy(v1 + 1, "Diablo1ReadOnlyTest.foo"); + v2 = fopen(Filename, "wt"); + if ( v2 ) + { + fclose(v2); + remove(Filename); + } + else + { + v0 = 1; + } + } + } + return v0; +} diff --git a/2020_03_31/Source/restrict.h b/2020_03_31/Source/restrict.h new file mode 100644 index 00000000..f56a523c --- /dev/null +++ b/2020_03_31/Source/restrict.h @@ -0,0 +1,9 @@ +//HEADER_GOES_HERE +#ifndef __RESTRICT_H__ +#define __RESTRICT_H__ + +BOOL SystemSupported(); +BOOL RestrictedTest(); +BOOL ReadOnlyTest(); + +#endif /* __RESTRICT_H__ */ diff --git a/2020_03_31/Source/scrollrt.cpp b/2020_03_31/Source/scrollrt.cpp new file mode 100644 index 00000000..91a49948 --- /dev/null +++ b/2020_03_31/Source/scrollrt.cpp @@ -0,0 +1,2627 @@ +#include "diablo.h" +#include "../3rdParty/Storm/Source/storm.h" + +int light_table_index; // weak +int PitchTbl[1024]; +DWORD sgdwCursWdtOld; // idb +DWORD sgdwCursX; // idb +DWORD sgdwCursY; // idb +unsigned char *gpBufEnd; // weak +DWORD sgdwCursHgt; +int level_cel_block; // weak +DWORD sgdwCursXOld; // idb +DWORD sgdwCursYOld; // idb +char arch_draw_type; // weak +DDSURFACEDESC DDS_desc; +int cel_transparency_active; // weak +int level_piece_id; // weak +DWORD sgdwCursWdt; +void (*DrawPlrProc)(int, int, int, int, int, BYTE *, int, int, int, int); +BYTE sgSaveBack[8192]; +int draw_monster_num; // weak +DWORD sgdwCursHgtOld; // idb + +/* data */ + +/* used in 1.00 debug */ +char *szMonModeAssert[18] = +{ + "standing", + "walking (1)", + "walking (2)", + "walking (3)", + "attacking", + "getting hit", + "dying", + "attacking (special)", + "fading in", + "fading out", + "attacking (ranged)", + "standing (special)", + "attacking (special ranged)", + "delaying", + "charging", + "stoned", + "healing", + "talking" +}; + +char *szPlrModeAssert[12] = +{ + "standing", + "walking (1)", + "walking (2)", + "walking (3)", + "attacking (melee)", + "attacking (ranged)", + "blocking", + "getting hit", + "dying", + "casting a spell", + "changing levels", + "quitting" +}; + +void ClearCursor() // CODE_FIX: this was supposed to be in cursor.cpp +{ + sgdwCursWdt = 0; + sgdwCursWdtOld = 0; +} + +static void scrollrt_draw_cursor_back_buffer() +{ + int i; + BYTE *src, *dst; + + if(sgdwCursWdt == 0) { + return; + } + + /// ASSERT: assert(gpBuffer); + src = sgSaveBack; + dst = &gpBuffer[SCREENXY(sgdwCursX, sgdwCursY)]; + + for(i = sgdwCursHgt; i != 0; i--, src += sgdwCursWdt, dst += 768) { + memcpy(dst, src, sgdwCursWdt); + } + + sgdwCursXOld = sgdwCursX; + sgdwCursYOld = sgdwCursY; + sgdwCursWdtOld = sgdwCursWdt; + sgdwCursHgtOld = sgdwCursHgt; + sgdwCursWdt = 0; +} + +static void scrollrt_draw_cursor_item() +{ + int i, mx, my, col; + BYTE *src, *dst; + + /// ASSERT: assert(! sgdwCursWdt); + + if(pcurs <= 0 || cursW == 0 || cursH == 0) { + return; + } + + mx = MouseX - 1; + if(mx < 0) { + mx = 0; + } else if(mx > 640 - 1) { + return; + } + my = MouseY - 1; + if(my < 0) { + my = 0; + } else if(my > 480 - 1) { + return; + } + + sgdwCursX = mx; + sgdwCursWdt = sgdwCursX + cursW + 1; + if(sgdwCursWdt > 640 - 1) { + sgdwCursWdt = 640 - 1; + } + sgdwCursX &= ~3; + sgdwCursWdt |= 3; + sgdwCursWdt -= sgdwCursX; + sgdwCursWdt++; + + sgdwCursY = my; + sgdwCursHgt = sgdwCursY + cursH + 1; + if(sgdwCursHgt > 480 - 1) { + sgdwCursHgt = 480 - 1; + } + sgdwCursHgt -= sgdwCursY; + sgdwCursHgt++; + + /// ASSERT: assert(sgdwCursWdt * sgdwCursHgt < sizeof sgSaveBack); + /// ASSERT: assert(gpBuffer); + dst = sgSaveBack; + src = &gpBuffer[SCREENXY(sgdwCursX, sgdwCursY)]; + + for(i = sgdwCursHgt; i != 0; i--, dst += sgdwCursWdt, src += 768) { + memcpy(dst, src, sgdwCursWdt); + } + + mx++; + my++; + gpBufEnd = &gpBuffer[PitchTbl[640] - cursW - 2]; + + if(pcurs >= CURSOR_FIRSTITEM) { + col = PAL16_YELLOW + 5; + if(plr[myplr].HoldItem._iMagical != 0) { + col = PAL16_BLUE + 5; + } + if(!plr[myplr].HoldItem._iStatFlag) { + col = PAL16_RED + 5; + } + CelDrawHdrClrHL(col, mx + 64, my + cursH + 160 - 1, (BYTE *)pCursCels, pcurs, cursW, 0, 8); + if(col != PAL16_RED + 5) { + Cel2DrawHdrOnly(mx + 64, my + cursH + 160 - 1, (BYTE *)pCursCels, pcurs, cursW, 0, 8); + } else { + Cel2DrawHdrLightRed(mx + 64, my + cursH + 160 - 1, (BYTE *)pCursCels, pcurs, cursW, 0, 8, 1); + } + } else { + Cel2DrawHdrOnly(mx + 64, my + cursH + 160 - 1, (BYTE *)pCursCels, pcurs, cursW, 0, 8); + } +} + +void DrawMissile(int x, int y, int sx, int sy, int a5, int a6, BOOL pre) +{ + int i, mx, my, nCel; + MissileStruct *m; + BYTE *pCelBuff; + DWORD *pFrameTable; + + if(dMissile[x][y] == -1) { + for(i = 0; i < nummissiles; i++) { + /// ASSERT: assert(missileactive[i] < MAXMISSILES); + if(missileactive[i] >= MAXMISSILES) + break; + m = &missile[missileactive[i]]; + if(m->_mix == x && m->_miy == y && m->_miPreFlag == pre && m->_miDrawFlag) { + pCelBuff = m->_miAnimData; + if(!pCelBuff) { + // app_fatal("Draw Missile type %d: NULL Cel Buffer", m->_mitype); + return; + } + nCel = m->_miAnimFrame; + pFrameTable = (DWORD *)pCelBuff; + if(nCel < 1 || pFrameTable[0] > 50 || nCel > (int)pFrameTable[0]) { + // app_fatal("Draw Missile: frame %d of %d, missile type==%d", nCel, pFrameTable[0], m->_mitype); + return; + } + mx = sx + m->_mixoff - m->_miAnimWidth2; + my = sy + m->_miyoff; + if(m->_miUniqTrans) + Cl2DecodeFrm3(mx, my, m->_miAnimData, m->_miAnimFrame, m->_miAnimWidth, a5, a6, m->_miUniqTrans + 3); + else if(m->_miLightFlag) + Cl2DecodeLightTbl(mx, my, m->_miAnimData, m->_miAnimFrame, m->_miAnimWidth, a5, a6); + else + Cl2DecodeFrm1(mx, my, m->_miAnimData, m->_miAnimFrame, m->_miAnimWidth, a5, a6); + } + } + } else { + m = &missile[dMissile[x][y] - 1]; + if(m->_miPreFlag == pre && m->_miDrawFlag) { + pCelBuff = m->_miAnimData; + if(!pCelBuff) { + // app_fatal("Draw Missile 2 type %d: NULL Cel Buffer", m->_mitype); + return; + } + nCel = m->_miAnimFrame; + pFrameTable = (DWORD *)pCelBuff; + if(nCel < 1 || pFrameTable[0] > 50 || nCel > (int)pFrameTable[0]) { + // app_fatal("Draw Missile 2: frame %d of %d, missile type==%d", nCel, pFrameTable[0], m->_mitype); + return; + } + mx = sx + m->_mixoff - m->_miAnimWidth2; + my = sy + m->_miyoff; + if(m->_miUniqTrans) + Cl2DecodeFrm3(mx, my, m->_miAnimData, m->_miAnimFrame, m->_miAnimWidth, a5, a6, m->_miUniqTrans + 3); + else if(m->_miLightFlag) + Cl2DecodeLightTbl(mx, my, m->_miAnimData, m->_miAnimFrame, m->_miAnimWidth, a5, a6); + else + Cl2DecodeFrm1(mx, my, m->_miAnimData, m->_miAnimFrame, m->_miAnimWidth, a5, a6); + } + } +} + +void DrawClippedMissile(int x, int y, int sx, int sy, int a5, int a6, BOOL pre) +{ + int i, mx, my, nCel; + MissileStruct *m; + BYTE *pCelBuff; + DWORD *pFrameTable; + + if(dMissile[x][y] == -1) { + for(i = 0; i < nummissiles; i++) { + /// ASSERT: assert(missileactive[i] < MAXMISSILES); + if(missileactive[i] >= MAXMISSILES) + break; + m = &missile[missileactive[i]]; + if(m->_mix == x && m->_miy == y && m->_miPreFlag == pre && m->_miDrawFlag) { + pCelBuff = m->_miAnimData; + if(!pCelBuff) { + // app_fatal("Draw Missile type %d Clipped: NULL Cel Buffer", m->_mitype); + return; + } + nCel = m->_miAnimFrame; + pFrameTable = (DWORD *)pCelBuff; + if(nCel < 1 || pFrameTable[0] > 50 || nCel > (int)pFrameTable[0]) { + // app_fatal("Draw Clipped Missile: frame %d of %d, missile type==%d", nCel, pFrameTable[0], m->_mitype); + return; + } + mx = sx + m->_mixoff - m->_miAnimWidth2; + my = sy + m->_miyoff; + if(m->_miUniqTrans) + Cl2DecodeFrm5(mx, my, m->_miAnimData, m->_miAnimFrame, m->_miAnimWidth, a5, a6, m->_miUniqTrans + 3); + else if(m->_miLightFlag) + Cl2DecodeFrm6(mx, my, m->_miAnimData, m->_miAnimFrame, m->_miAnimWidth, a5, a6); + else + Cl2DecodeFrm4(mx, my, m->_miAnimData, m->_miAnimFrame, m->_miAnimWidth, a5, a6); + } + } + } else { + m = &missile[dMissile[x][y] - 1]; + if(m->_miPreFlag == pre && m->_miDrawFlag) { + pCelBuff = m->_miAnimData; + if(!pCelBuff) { + // app_fatal("Draw Missile 2 type %d Clipped: NULL Cel Buffer", m->_mitype); + return; + } + nCel = m->_miAnimFrame; + pFrameTable = (DWORD *)pCelBuff; + if(nCel < 1 || pFrameTable[0] > 50 || nCel > (int)pFrameTable[0]) { + // app_fatal("Draw Clipped Missile 2: frame %d of %d, missile type==%d", nCel, pFrameTable[0], m->_mitype); + return; + } + mx = sx + m->_mixoff - m->_miAnimWidth2; + my = sy + m->_miyoff; + if(m->_miUniqTrans) + Cl2DecodeFrm5(mx, my, m->_miAnimData, m->_miAnimFrame, m->_miAnimWidth, a5, a6, m->_miUniqTrans + 3); + else if(m->_miLightFlag) + Cl2DecodeFrm6(mx, my, m->_miAnimData, m->_miAnimFrame, m->_miAnimWidth, a5, a6); + else + Cl2DecodeFrm4(mx, my, m->_miAnimData, m->_miAnimFrame, m->_miAnimWidth, a5, a6); + } + } +} + +static void DrawMonster(int x, int y, int mx, int my, int m, int a6, int a7) +{ + int nCel; + char trans; + BYTE *pCelBuff; + DWORD *pFrameTable; + + if((DWORD)m >= MAXMONSTERS) { + // app_fatal("Draw Monster: tried to draw illegal monster %d", m); + return; + } + + pCelBuff = monster[m]._mAnimData; + if(!pCelBuff) { + // app_fatal("Draw Monster \"%s\": NULL Cel Buffer", monster[m].mName); + return; + } + + nCel = monster[m]._mAnimFrame; + pFrameTable = (DWORD *)pCelBuff; + if(nCel < 1 || pFrameTable[0] > 50 || nCel > (int)pFrameTable[0]) { + /* + const char *szMode = "unknown action"; + if(monster[m]._mmode <= 17) + szMode = szMonModeAssert[monster[m]._mmode]; + app_fatal( + "Draw Monster \"%s\" %s: facing %d, frame %d of %d", + monster[m].mName, + szMode, + monster[m]._mdir, + nCel, + pFrameTable[0]); + */ + return; + } + + if(!(dFlags[x][y] & 0x40)) { + Cl2DecodeFrm3(mx, my, monster[m]._mAnimData, monster[m]._mAnimFrame, monster[m].MType->flags_1, a6, a7, 1); + } else { + trans = 0; + if(monster[m]._uniqtype) + trans = monster[m]._uniqtrans + 4; + if(monster[m]._mmode == MM_STONE) + trans = 2; + if(plr[myplr]._pInfraFlag && light_table_index > 8) + trans = 1; + if(trans) + Cl2DecodeFrm3(mx, my, monster[m]._mAnimData, monster[m]._mAnimFrame, monster[m].MType->flags_1, a6, a7, trans); + else + Cl2DecodeLightTbl(mx, my, monster[m]._mAnimData, monster[m]._mAnimFrame, monster[m].MType->flags_1, a6, a7); + } +} + +static void DrawClippedMonster(int x, int y, int mx, int my, int m, int a6, int a7) +{ + int nCel; + char trans; + BYTE *pCelBuff; + DWORD *pFrameTable; + + if((DWORD)m >= MAXMONSTERS) { + // app_fatal("Draw Monster Clipped: tried to draw illegal monster %d", m); + return; + } + + pCelBuff = monster[m]._mAnimData; + if(!pCelBuff) { + // app_fatal("Draw Monster \"%s\" Clipped: NULL Cel Buffer", monster[m].mName); + return; + } + + nCel = monster[m]._mAnimFrame; + pFrameTable = (DWORD *)pCelBuff; + if(nCel < 1 || pFrameTable[0] > 50 || nCel > (int)pFrameTable[0]) { + /* + const char *szMode = "unknown action"; + if(monster[m]._mmode <= 17) + szMode = szMonModeAssert[monster[m]._mmode]; + app_fatal( + "Draw Monster \"%s\" %s Clipped: facing %d, frame %d of %d", + monster[m].mName, + szMode, + monster[m]._mdir, + nCel, + pFrameTable[0]); + */ + return; + } + + if(!(dFlags[x][y] & 0x40)) { + Cl2DecodeFrm5(mx, my, monster[m]._mAnimData, monster[m]._mAnimFrame, monster[m].MType->flags_1, a6, a7, 1); + } else { + trans = 0; + if(monster[m]._uniqtype) + trans = monster[m]._uniqtrans + 4; + if(monster[m]._mmode == MM_STONE) + trans = 2; + if(plr[myplr]._pInfraFlag && light_table_index > 8) + trans = 1; + if(trans) + Cl2DecodeFrm5(mx, my, monster[m]._mAnimData, monster[m]._mAnimFrame, monster[m].MType->flags_1, a6, a7, trans); + else + Cl2DecodeFrm6(mx, my, monster[m]._mAnimData, monster[m]._mAnimFrame, monster[m].MType->flags_1, a6, a7); + } +} + +static void DrawPlayer(int pnum, int x, int y, int px, int py, BYTE *pCelBuff, int nCel, int nWidth, int a9, int a10) +{ + int l; + DWORD *pFrameTable; + + if(dFlags[x][y] & 0x40 || plr[myplr]._pInfraFlag || !setlevel && !currlevel) { + if(!pCelBuff) { + // app_fatal("Drawing player %d \"%s\": NULL Cel Buffer", pnum, plr[pnum]._pName); + return; + } + pFrameTable = (DWORD *)pCelBuff; + if(nCel < 1 || pFrameTable[0] > 50 || nCel > (int)pFrameTable[0]) { + /* + const char *szMode = "unknown action"; + if(plr[pnum]._pmode <= 11) + szMode = szPlrModeAssert[plr[pnum]._pmode]; + app_fatal( + "Drawing player %d \"%s\" %s: facing %d, frame %d of %d", + pnum, + plr[pnum]._pName, + szMode, + plr[pnum]._pdir, + nCel, + pFrameTable[0]); + */ + return; + } + if(pnum == pcursplr) + Cl2DecodeFrm2(165, px, py, pCelBuff, nCel, nWidth, a9, a10); + if(pnum == myplr) { + Cl2DecodeFrm1(px, py, pCelBuff, nCel, nWidth, a9, a10); + if(plr[pnum].pManaShield) + Cl2DecodeFrm1( + px + plr[pnum]._pAnimWidth2 - misfiledata[MFILE_MANASHLD].mAnimWidth2[0], + py, + misfiledata[MFILE_MANASHLD].mAnimData[0], + 1, + misfiledata[MFILE_MANASHLD].mAnimWidth[0], + a9, + a10); + } else if(!(dFlags[x][y] & 0x40) || plr[myplr]._pInfraFlag && light_table_index > 8) { + Cl2DecodeFrm3(px, py, pCelBuff, nCel, nWidth, a9, a10, 1); + if(plr[pnum].pManaShield) + Cl2DecodeFrm3( + px + plr[pnum]._pAnimWidth2 - misfiledata[MFILE_MANASHLD].mAnimWidth2[0], + py, + misfiledata[MFILE_MANASHLD].mAnimData[0], + 1, + misfiledata[MFILE_MANASHLD].mAnimWidth[0], + a9, + a10, + 1); + } else { + l = light_table_index; + if(light_table_index < 5) + light_table_index = 0; + else + light_table_index -= 5; + Cl2DecodeLightTbl(px, py, pCelBuff, nCel, nWidth, a9, a10); + if(plr[pnum].pManaShield) + Cl2DecodeLightTbl( + px + plr[pnum]._pAnimWidth2 - misfiledata[MFILE_MANASHLD].mAnimWidth2[0], + py, + misfiledata[MFILE_MANASHLD].mAnimData[0], + 1, + misfiledata[MFILE_MANASHLD].mAnimWidth[0], + a9, + a10); + light_table_index = l; + } + } +} + +static void DrawClippedPlayer(int pnum, int x, int y, int px, int py, BYTE *pCelBuff, int nCel, int nWidth, int a9, int a10) +{ + int l; + DWORD *pFrameTable; + + if(dFlags[x][y] & 0x40 || plr[myplr]._pInfraFlag) { + if(!pCelBuff) { + // app_fatal("Drawing player %d \"%s\" clipped: NULL Cel Buffer", pnum, plr[pnum]._pName); + return; + } + pFrameTable = (DWORD *)pCelBuff; + if(nCel < 1 || pFrameTable[0] > 50 || nCel > (int)pFrameTable[0]) { + /* + const char *szMode = "unknown action"; + if(plr[pnum]._pmode <= 11) + szMode = szPlrModeAssert[plr[pnum]._pmode]; + app_fatal( + "Drawing player %d \"%s\" %s clipped: facing %d, frame %d of %d", + pnum, + plr[pnum]._pName, + szMode, + plr[pnum]._pdir, + nCel, + pFrameTable[0]); + */ + return; + } + if(pnum == pcursplr) + Cl2DecodeClrHL(165, px, py, pCelBuff, nCel, nWidth, a9, a10); + if(pnum == myplr) { + Cl2DecodeFrm4(px, py, pCelBuff, nCel, nWidth, a9, a10); + if(plr[pnum].pManaShield) + Cl2DecodeFrm4( + px + plr[pnum]._pAnimWidth2 - misfiledata[MFILE_MANASHLD].mAnimWidth2[0], + py, + misfiledata[MFILE_MANASHLD].mAnimData[0], + 1, + misfiledata[MFILE_MANASHLD].mAnimWidth[0], + a9, + a10); + } else if(!(dFlags[x][y] & 0x40) || plr[myplr]._pInfraFlag && light_table_index > 8) { + Cl2DecodeFrm5(px, py, pCelBuff, nCel, nWidth, a9, a10, 1); + if(plr[pnum].pManaShield) + Cl2DecodeFrm5( + px + plr[pnum]._pAnimWidth2 - misfiledata[MFILE_MANASHLD].mAnimWidth2[0], + py, + misfiledata[MFILE_MANASHLD].mAnimData[0], + 1, + misfiledata[MFILE_MANASHLD].mAnimWidth[0], + a9, + a10, + 1); + } else { + l = light_table_index; + if(light_table_index < 5) + light_table_index = 0; + else + light_table_index -= 5; + Cl2DecodeFrm6(px, py, pCelBuff, nCel, nWidth, a9, a10); + if(plr[pnum].pManaShield) + Cl2DecodeFrm6( + px + plr[pnum]._pAnimWidth2 - misfiledata[MFILE_MANASHLD].mAnimWidth2[0], + py, + misfiledata[MFILE_MANASHLD].mAnimData[0], + 1, + misfiledata[MFILE_MANASHLD].mAnimWidth[0], + a9, + a10); + light_table_index = l; + } + } +} + +void DrawDeadPlayer(int x, int y, int sx, int sy, int a5, int a6, BOOL clipped) +{ + int i, px, py, nCel; + PlayerStruct *p; + BYTE *pCelBuff; + DWORD *pFrameTable; + + if(clipped) + DrawPlrProc = DrawClippedPlayer; + else + DrawPlrProc = DrawPlayer; + + dFlags[x][y] &= ~4; + + for(i = 0; i < MAX_PLRS; i++) { + p = &plr[i]; + if(p->plractive && !p->_pHitPoints && p->plrlevel == (unsigned char)currlevel && p->WorldX == x && p->WorldY == y) { + pCelBuff = p->_pAnimData; + if(!pCelBuff) { + // app_fatal("Drawing dead player %d \"%s\": NULL Cel Buffer", i, p->_pName); + break; + } + nCel = p->_pAnimFrame; + pFrameTable = (DWORD *)pCelBuff; + if(nCel < 1 || pFrameTable[0] > 50 || nCel > (int)pFrameTable[0]) { + // app_fatal("Drawing dead player %d \"%s\": facing %d, frame %d of %d", i, p->_pName, p->_pdir, nCel, pFrameTable[0]); + break; + } + dFlags[x][y] |= 4; + px = sx + p->_pxoff - p->_pAnimWidth2; + py = sy + p->_pyoff; + DrawPlrProc(i, x, y, px, py, p->_pAnimData, p->_pAnimFrame, p->_pAnimWidth, a5, a6); + } + } +} + +static void DrawObject(int x, int y, int ox, int oy, BOOL pre, int a6, int dir) +{ + int sx, sy, xx, yy, nCel; + char bv; + BYTE *pCelBuff; + DWORD *pFrameTable; + + if(dObject[x][y] > 0) { + bv = dObject[x][y] - 1; + if(object[bv]._oPreFlag != pre) + return; + sx = ox - object[bv]._oAnimWidth2; + sy = oy; + } else { + bv = -(dObject[x][y] + 1); + if(object[bv]._oPreFlag != pre) + return; + xx = object[bv]._ox - x; + yy = object[bv]._oy - y; + sx = (xx << 5) + ox - object[bv]._oAnimWidth2 - (yy << 5); + sy = oy + (yy << 4) + (xx << 4); + a6 = 0; + dir = 8; + } + + /// ASSERT: assert((unsigned char)bv < MAXOBJECTS); + if((unsigned char)bv >= MAXOBJECTS) + return; + + pCelBuff = object[bv]._oAnimData; + if(!pCelBuff) { + // app_fatal("Draw Object type %d: NULL Cel Buffer", object[bv]._otype); + return; + } + + nCel = object[bv]._oAnimFrame; + pFrameTable = (DWORD *)pCelBuff; + if(nCel < 1 || pFrameTable[0] > 50 || nCel > (int)pFrameTable[0]) { + // app_fatal("Draw Object: frame %d of %d, object type==%d", nCel, pFrameTable[0], object[bv]._otype); + return; + } + + if(bv == pcursobj) + CelDecodeClr(194, sx, sy, object[bv]._oAnimData, object[bv]._oAnimFrame, object[bv]._oAnimWidth, a6, dir); + if(object[bv]._oLight) { + CelDecodeHdrLightOnly(sx, sy, object[bv]._oAnimData, object[bv]._oAnimFrame, object[bv]._oAnimWidth, a6, dir); + } else { + /// ASSERT: assert(object[bv]._oAnimData); + if(object[bv]._oAnimData) /// BUGFIX: _oAnimData was already checked, this is redundant + CelDrawHdrOnly(sx, sy, object[bv]._oAnimData, object[bv]._oAnimFrame, object[bv]._oAnimWidth, a6, dir); + } +} + +static void DrawClippedObject(int x, int y, int ox, int oy, BOOL pre, int a6, int dir) +{ + int sx, sy, xx, yy, nCel; + char bv; + BYTE *pCelBuff; + DWORD *pFrameTable; + + if(dObject[x][y] > 0) { + bv = dObject[x][y] - 1; + if(object[bv]._oPreFlag != pre) + return; + sx = ox - object[bv]._oAnimWidth2; + sy = oy; + } else { + bv = -(dObject[x][y] + 1); + if(object[bv]._oPreFlag != pre) + return; + xx = object[bv]._ox - x; + yy = object[bv]._oy - y; + sx = (xx << 5) + ox - object[bv]._oAnimWidth2 - (yy << 5); + sy = oy + (yy << 4) + (xx << 4); + a6 = 0; + dir = 8; + } + + /// ASSERT: assert((unsigned char)bv < MAXOBJECTS); + if((unsigned char)bv >= MAXOBJECTS) + return; + + pCelBuff = object[bv]._oAnimData; + if(!pCelBuff) { + // app_fatal("Draw Object type %d Clipped: NULL Cel Buffer", object[bv]._otype); + return; + } + + nCel = object[bv]._oAnimFrame; + pFrameTable = (DWORD *)pCelBuff; + if(nCel < 1 || pFrameTable[0] > 50 || nCel > (int)pFrameTable[0]) { + // app_fatal("Draw Clipped Object: frame %d of %d, object type==%d", nCel, pFrameTable[0], object[bv]._otype); + return; + } + + if(bv == pcursobj) + CelDrawHdrClrHL(194, sx, sy, object[bv]._oAnimData, object[bv]._oAnimFrame, object[bv]._oAnimWidth, a6, dir); + if(object[bv]._oLight) + Cel2DecodeHdrLight(sx, sy, object[bv]._oAnimData, object[bv]._oAnimFrame, object[bv]._oAnimWidth, a6, dir); + else + Cel2DrawHdrOnly(sx, sy, object[bv]._oAnimData, object[bv]._oAnimFrame, object[bv]._oAnimWidth, a6, dir); +} + +static void scrollrt_draw_clipped_dungeon(BYTE *pBuff, int sx, int sy, int dx, int dy, int me_flag); + +static void scrollrt_draw_clipped_e_flag(BYTE *pBuff, int x, int y, int a4, int a5) +{ + int i, lti_old, cta_old, lpi_old; + BYTE *dst; + MICROS *pMap; + + lti_old = light_table_index; + cta_old = cel_transparency_active; + lpi_old = level_piece_id; + + level_piece_id = dPiece[x][y]; + light_table_index = dLight[x][y]; + cel_transparency_active = (unsigned char)(nTransTable[level_piece_id] & TransList[dTransVal[x][y]]); + pMap = &dpiece_defs_map_1[IsometricCoord(x, y)]; + + dst = pBuff; + arch_draw_type = 1; + level_cel_block = pMap->mt[0]; + if(level_cel_block != 0) { + drawLowerScreen(dst); + } + arch_draw_type = 2; + level_cel_block = pMap->mt[1]; + if(level_cel_block != 0) { + drawLowerScreen(dst + 32); + } + + dst = pBuff; + arch_draw_type = 0; + for(i = 2; i < MicroTileLen; i += 2) { + dst -= 768 * 32; + level_cel_block = pMap->mt[i]; + if(level_cel_block != 0) { + drawLowerScreen(dst); + } + level_cel_block = pMap->mt[i + 1]; + if(level_cel_block != 0) { + drawLowerScreen(dst + 32); + } + } + + scrollrt_draw_clipped_dungeon(pBuff, x, y, a4, a5, 0); + + light_table_index = lti_old; + cel_transparency_active = cta_old; + level_piece_id = lpi_old; +} + +static void scrollrt_draw_clipped_dungeon(BYTE *pBuff, int sx, int sy, int dx, int dy, int me_flag) +{ + int px, py, nCel, nMon, negMon, p; + char bFlag, bDead, bObj, bItem, bPlr, bArch, bMap, negPlr, dd; + DeadStruct *pDeadGuy; + ItemStruct *pItem; + PlayerStruct *pPlayer; + MonsterStruct *pMonster; + BYTE *pCelBuff; + DWORD *pFrameTable; + + /// ASSERT: assert((DWORD)sx < MAXDUNX); + /// ASSERT: assert((DWORD)sy < MAXDUNY); + bFlag = dFlags[sx][sy]; + bDead = dDead[sx][sy]; + bObj = dObject[sx][sy]; + bItem = dItem[sx][sy]; + bPlr = dPlayer[sx][sy]; + bArch = dSpecial[sx][sy]; + bMap = dTransVal[sx][sy]; + nMon = dMonster[sx][sy]; + + /// ASSERT: assert((DWORD)(sy-1) < MAXDUNY); + negPlr = dPlayer[sx][sy - 1]; + negMon = dMonster[sx][sy - 1]; + + if(visiondebug && bFlag & 0x40) { + Cel2DecodeHdrOnly(pBuff, (BYTE *)pSquareCel, 1, 64, 0, 8); + } + if(MissilePreFlag && bFlag & 1) { + DrawClippedMissile(sx, sy, dx, dy, 0, 8, 1); + } + if(light_table_index < lightmax) { + if(bDead != 0) { + pDeadGuy = &dead[(bDead & 0x1F) - 1]; + dd = (bDead >> 5) & 7; + px = dx - pDeadGuy->_deadWidth2; + pCelBuff = pDeadGuy->_deadData[dd]; + /// ASSERT: assert(pDeadGuy->_deadData[dd] != NULL); + if(pCelBuff != NULL) { + pFrameTable = (DWORD *)pDeadGuy->_deadData[dd]; + nCel = pDeadGuy->_deadFrame; + if(nCel >= 1 && pFrameTable[0] <= 50 && nCel <= (int)pFrameTable[0]) { + if(pDeadGuy->_deadtrans != 0) { + Cl2DecodeFrm5(px, dy, pCelBuff, nCel, pDeadGuy->_deadWidth, 0, 8, pDeadGuy->_deadtrans); + } else { + Cl2DecodeFrm6(px, dy, pCelBuff, nCel, pDeadGuy->_deadWidth, 0, 8); + } + } else { + // app_fatal("Clipped dead sub: frame %d of %d, deadnum==%d", nCel, pFrameTable[0], (bDead & 0x1F) - 1); + } + } + } + if(bObj != 0) { + DrawClippedObject(sx, sy, dx, dy, 1, 0, 8); + } + } + if(bItem != 0) { + pItem = &item[bItem - 1]; + if(!pItem->_iPostDraw) { + /// ASSERT: assert((unsigned char)bItem <= MAXITEMS); + if((unsigned char)bItem <= MAXITEMS) { + pCelBuff = pItem->_iAnimData; + if(pCelBuff != NULL) { + pFrameTable = (DWORD *)pCelBuff; + nCel = pItem->_iAnimFrame; + if(nCel >= 1 && pFrameTable[0] <= 50 && nCel <= (int)pFrameTable[0]) { + px = dx - pItem->_iAnimWidth2; + if(bItem - 1 == pcursitem) { + CelDrawHdrClrHL(181, px, dy, pCelBuff, pItem->_iAnimFrame, pItem->_iAnimWidth, 0, 8); + } + Cel2DecodeHdrLight(px, dy, pItem->_iAnimData, pItem->_iAnimFrame, pItem->_iAnimWidth, 0, 8); + } else { + /* + app_fatal( + "Draw Clipped \"%s\" Item: frame %d of %d, item type==%d", + pItem->_iIName, + nCel, + pFrameTable[0], + pItem->_itype); + */ + } + } else { + // app_fatal("Draw Item \"%s\" Clipped 1: NULL Cel Buffer", pItem->_iIName); + } + } + } + } + if(bFlag & 0x20) { + p = -(negPlr + 1); + if((DWORD)p < MAX_PLRS) { + pPlayer = &plr[p]; + px = dx + pPlayer->_pxoff - pPlayer->_pAnimWidth2; + py = dy + pPlayer->_pyoff; + DrawClippedPlayer(p, sx, sy - 1, px, py, pPlayer->_pAnimData, pPlayer->_pAnimFrame, pPlayer->_pAnimWidth, 0, 8); + if(me_flag && pPlayer->_peflag != 0) { + if(pPlayer->_peflag == 2) { + scrollrt_draw_clipped_e_flag(pBuff - (768 * 16 + 96), sx - 2, sy + 1, dx - 96, dy - 16); + } + scrollrt_draw_clipped_e_flag(pBuff - 64, sx - 1, sy + 1, dx - 64, dy); + } + } else { + // app_fatal("draw player clipped: tried to draw illegal player %d", p); + } + } + if(bFlag & 0x10 && (bFlag & 0x40 || plr[myplr]._pInfraFlag) && negMon < 0) { + draw_monster_num = -(negMon + 1); + if((DWORD)draw_monster_num < MAXMONSTERS) { + pMonster = &monster[draw_monster_num]; + if(!(pMonster->_mFlags & 1)) { + if(pMonster->MType != NULL) { + px = dx + pMonster->_mxoff - pMonster->MType->flags_2; + py = dy + pMonster->_myoff; + if(draw_monster_num == pcursmonst) { + Cl2DecodeClrHL(233, px, py, pMonster->_mAnimData, pMonster->_mAnimFrame, pMonster->MType->flags_1, 0, 8); + } + DrawClippedMonster(sx, sy, px, py, draw_monster_num, 0, 8); + if(me_flag && pMonster->_meflag) { + scrollrt_draw_clipped_e_flag(pBuff - 64, sx - 1, sy + 1, dx - 64, dy); + } + } else { + // app_fatal("Draw Monster \"%s\" Clipped: uninitialized monster", pMonster->mName); + } + } + } else { + // app_fatal("Draw Monster Clipped: tried to draw illegal monster %d", draw_monster_num); + } + } + if(bFlag & 4) { + DrawDeadPlayer(sx, sy, dx, dy, 0, 8, 1); + } + if(bPlr > 0) { + p = bPlr - 1; + if((DWORD)p < MAX_PLRS) { + pPlayer = &plr[p]; + px = dx + pPlayer->_pxoff - pPlayer->_pAnimWidth2; + py = dy + pPlayer->_pyoff; + DrawClippedPlayer(p, sx, sy, px, py, pPlayer->_pAnimData, pPlayer->_pAnimFrame, pPlayer->_pAnimWidth, 0, 8); + if(me_flag && pPlayer->_peflag != 0) { + if(pPlayer->_peflag == 2) { + scrollrt_draw_clipped_e_flag(pBuff - (768 * 16 + 96), sx - 2, sy + 1, dx - 96, dy - 16); + } + scrollrt_draw_clipped_e_flag(pBuff - 64, sx - 1, sy + 1, dx - 64, dy); + } + } else { + // app_fatal("draw player clipped: tried to draw illegal player %d", p); + } + } + if(nMon > 0 && (bFlag & 0x40 || plr[myplr]._pInfraFlag)) { + draw_monster_num = nMon - 1; + if((DWORD)draw_monster_num < MAXMONSTERS) { + pMonster = &monster[draw_monster_num]; + if(!(pMonster->_mFlags & 1)) { + if(pMonster->MType != NULL) { + px = dx + pMonster->_mxoff - pMonster->MType->flags_2; + py = dy + pMonster->_myoff; + if(draw_monster_num == pcursmonst) { + Cl2DecodeClrHL(233, px, py, pMonster->_mAnimData, pMonster->_mAnimFrame, pMonster->MType->flags_1, 0, 8); + } + DrawClippedMonster(sx, sy, px, py, draw_monster_num, 0, 8); + if(me_flag && pMonster->_meflag) { + scrollrt_draw_clipped_e_flag(pBuff - 64, sx - 1, sy + 1, dx - 64, dy); + } + } else { + // app_fatal("Draw Monster \"%s\" Clipped: uninitialized monster", pMonster->mName); + } + } + } else { + // app_fatal("Draw Monster Clipped: tried to draw illegal monster %d", draw_monster_num); + } + } + if(bFlag & 1) { + DrawClippedMissile(sx, sy, dx, dy, 0, 8, 0); + } + if(bObj != 0 && light_table_index < lightmax) { + DrawClippedObject(sx, sy, dx, dy, 0, 0, 8); + } + if(bItem != 0) { + pItem = &item[bItem - 1]; + if(pItem->_iPostDraw) { + /// ASSERT: assert((unsigned char)bItem <= MAXITEMS); + if((unsigned char)bItem <= MAXITEMS) { + pCelBuff = pItem->_iAnimData; + if(pCelBuff != NULL) { + pFrameTable = (DWORD *)pCelBuff; + nCel = pItem->_iAnimFrame; + if(nCel >= 1 && pFrameTable[0] <= 50 && nCel <= (int)pFrameTable[0]) { + px = dx - pItem->_iAnimWidth2; + if(bItem - 1 == pcursitem) { + CelDrawHdrClrHL(181, px, dy, pCelBuff, pItem->_iAnimFrame, pItem->_iAnimWidth, 0, 8); + } + Cel2DecodeHdrLight(px, dy, pItem->_iAnimData, pItem->_iAnimFrame, pItem->_iAnimWidth, 0, 8); + } else { + /* + app_fatal( + "Draw Clipped \"%s\" Item 2: frame %d of %d, item type==%d", + pItem->_iIName, + nCel, + pFrameTable[0], + pItem->_itype); + */ + } + } else { + // app_fatal("Draw Item \"%s\" Clipped 2: NULL Cel Buffer", pItem->_iIName); + } + } + } + } + if(bArch != 0) { + cel_transparency_active = (unsigned char)TransList[bMap]; + Cel2DecodeLightTrans(pBuff, pSpecialCels, bArch, 64, 0, 8); + } +} + +static void scrollrt_draw_lower(int x, int y, int sx, int sy, int a5, int some_flag) +{ + int i, j; + BYTE *dst; + MICROS *pMap; + + /// ASSERT: assert(gpBuffer); + + pMap = &dpiece_defs_map_1[IsometricCoord(x, y)]; + + if(some_flag) { + if((DWORD)y < MAXDUNY && (DWORD)x < MAXDUNX) { + level_piece_id = dPiece[x][y]; + light_table_index = dLight[x][y]; + if(level_piece_id != 0) { + dst = &gpBuffer[sx + 32 + PitchTbl[sy]]; + cel_transparency_active = (unsigned char)(nTransTable[level_piece_id] & TransList[dTransVal[x][y]]); + arch_draw_type = 2; + level_cel_block = pMap->mt[1]; + if(level_cel_block != 0) { + drawLowerScreen(dst); + } + arch_draw_type = 0; + dst -= 768 * 32; + level_cel_block = pMap->mt[3]; + if(level_cel_block != 0) { + drawLowerScreen(dst); + } + dst -= 768 * 32; + level_cel_block = pMap->mt[5]; + if(level_cel_block != 0) { + drawLowerScreen(dst); + } + dst -= 768 * 32; + level_cel_block = pMap->mt[7]; + if(level_cel_block != 0) { + drawLowerScreen(dst); + } + dst -= 768 * 32; + level_cel_block = pMap->mt[9]; + if(level_cel_block != 0) { + drawLowerScreen(dst); + } + dst -= 768 * 32; + level_cel_block = pMap->mt[11]; + if(level_cel_block != 0 && leveltype == DTYPE_HELL) { + drawLowerScreen(dst); + } + scrollrt_draw_clipped_dungeon(&gpBuffer[sx + PitchTbl[sy]], x, y, sx, sy, 0); + } else { + world_draw_black_tile(&gpBuffer[sx + PitchTbl[sy]]); + } + } + x++; + y--; + sx += 64; + pMap++; + a5--; + } + + j = a5; + while(j != 0) { + j--; + if(y < 0 || x >= MAXDUNX) { + break; + } + if(y < MAXDUNY && x >= 0) { + level_piece_id = dPiece[x][y]; + light_table_index = dLight[x][y]; + if(level_piece_id == 0) { + world_draw_black_tile(&gpBuffer[sx + PitchTbl[sy]]); + } else { + dst = &gpBuffer[sx + PitchTbl[sy]]; + cel_transparency_active = (unsigned char)(nTransTable[level_piece_id] & TransList[dTransVal[x][y]]); + arch_draw_type = 1; + level_cel_block = pMap->mt[0]; + if(level_cel_block != 0) { + drawLowerScreen(dst); + } + arch_draw_type = 2; + level_cel_block = pMap->mt[1]; + if(level_cel_block != 0) { + drawLowerScreen(dst + 32); + } + arch_draw_type = 0; + for(i = 2; i < MicroTileLen; i += 2) { + dst -= 768 * 32; + level_cel_block = pMap->mt[i]; + if(level_cel_block != 0) { + drawLowerScreen(dst); + } + level_cel_block = pMap->mt[i + 1]; + if(level_cel_block != 0) { + drawLowerScreen(dst + 32); + } + } + scrollrt_draw_clipped_dungeon(&gpBuffer[sx + PitchTbl[sy]], x, y, sx, sy, 1); + } + } + x++; + y--; + sx += 64; + pMap++; + } + + if(some_flag && (DWORD)y < MAXDUNY && (DWORD)x < MAXDUNX) { + level_piece_id = dPiece[x][y]; + light_table_index = dLight[x][y]; + if(level_piece_id == 0) { + world_draw_black_tile(&gpBuffer[sx + PitchTbl[sy]]); + } else { + dst = &gpBuffer[sx + PitchTbl[sy]]; + cel_transparency_active = (unsigned char)(nTransTable[level_piece_id] & TransList[dTransVal[x][y]]); + arch_draw_type = 1; + level_cel_block = pMap->mt[0]; + if(level_cel_block != 0) { + drawLowerScreen(dst); + } + arch_draw_type = 0; + dst -= 768 * 32; + level_cel_block = pMap->mt[2]; + if(level_cel_block != 0) { + drawLowerScreen(dst); + } + dst -= 768 * 32; + level_cel_block = pMap->mt[4]; + if(level_cel_block != 0) { + drawLowerScreen(dst); + } + dst -= 768 * 32; + level_cel_block = pMap->mt[6]; + if(level_cel_block != 0) { + drawLowerScreen(dst); + } + dst -= 768 * 32; + level_cel_block = pMap->mt[8]; + if(level_cel_block != 0) { + drawLowerScreen(dst); + } + dst -= 768 * 32; + level_cel_block = pMap->mt[10]; + if(level_cel_block != 0 && leveltype == DTYPE_HELL) { + drawLowerScreen(dst); + } + scrollrt_draw_clipped_dungeon(&gpBuffer[sx + PitchTbl[sy]], x, y, sx, sy, 0); + } + } +} + +static void scrollrt_draw_clipped_dungeon_2(BYTE *pBuff, int sx, int sy, int a4, int a5, int dx, int dy, int me_flag); + +static void scrollrt_draw_clipped_e_flag_2(BYTE *pBuff, int x, int y, int a4, signed int a5, int sx, int sy) +{ + int lti_old, cta_old, lpi_old; + BYTE *dst; + MICROS *pMap; + + lti_old = light_table_index; + cta_old = cel_transparency_active; + lpi_old = level_piece_id; + + level_piece_id = dPiece[x][y]; + light_table_index = dLight[x][y]; + dst = &pBuff[768 * 32 * a4]; + cel_transparency_active = (unsigned char)(nTransTable[level_piece_id] & TransList[dTransVal[x][y]]); + pMap = &dpiece_defs_map_1[IsometricCoord(x, y)]; + + switch(a4) { + case 0: + level_cel_block = pMap->mt[2]; + if(level_cel_block != 0) { + drawLowerScreen(dst); + } + level_cel_block = pMap->mt[3]; + if(level_cel_block != 0) { + drawLowerScreen(dst + 32); + } + case 1: + dst -= 768 * 32; + level_cel_block = pMap->mt[4]; + if(level_cel_block != 0) { + drawLowerScreen(dst); + } + level_cel_block = pMap->mt[5]; + if(level_cel_block != 0) { + drawLowerScreen(dst + 32); + } + case 2: + dst -= 768 * 32; + level_cel_block = pMap->mt[6]; + if(level_cel_block != 0) { + drawLowerScreen(dst); + } + level_cel_block = pMap->mt[7]; + if(level_cel_block != 0) { + drawLowerScreen(dst + 32); + } + case 3: + dst -= 768 * 32; + level_cel_block = pMap->mt[8]; + if(level_cel_block != 0) { + drawLowerScreen(dst); + } + level_cel_block = pMap->mt[9]; + if(level_cel_block != 0) { + drawLowerScreen(dst + 32); + } + break; + } + + if(a5 < 8) { + scrollrt_draw_clipped_dungeon_2(pBuff, x, y, a4, a5, sx, sy, 0); + } + + light_table_index = lti_old; + cel_transparency_active = cta_old; + level_piece_id = lpi_old; +} + +static void scrollrt_draw_clipped_dungeon_2(BYTE *pBuff, int sx, int sy, int a4, int a5, int dx, int dy, int me_flag) +{ + int px, py, nCel, nMon, negMon, p; + char bFlag, bDead, bObj, bItem, bPlr, bArch, bMap, negPlr, dd; + DeadStruct *pDeadGuy; + ItemStruct *pItem; + PlayerStruct *pPlayer; + MonsterStruct *pMonster; + BYTE *pCelBuff; + DWORD *pFrameTable; + + /// ASSERT: assert((DWORD)sx < MAXDUNX); + /// ASSERT: assert((DWORD)sy < MAXDUNY); + bFlag = dFlags[sx][sy]; + bDead = dDead[sx][sy]; + bObj = dObject[sx][sy]; + bItem = dItem[sx][sy]; + bPlr = dPlayer[sx][sy]; + bArch = dSpecial[sx][sy]; + bMap = dTransVal[sx][sy]; + nMon = dMonster[sx][sy]; + + /// ASSERT: assert((DWORD)(sy-1) < MAXDUNY); + negPlr = dPlayer[sx][sy - 1]; + negMon = dMonster[sx][sy - 1]; + + if(visiondebug && bFlag & 0x40) { + Cel2DecodeHdrOnly(pBuff, (BYTE *)pSquareCel, 1, 64, a5, 8); + } + if(MissilePreFlag && bFlag & 1) { + DrawClippedMissile(sx, sy, dx, dy, a5, 8, 1); + } + if(light_table_index < lightmax) { + if(bDead != 0) { + pDeadGuy = &dead[(bDead & 0x1F) - 1]; + dd = (bDead >> 5) & 7; + px = dx - pDeadGuy->_deadWidth2; + pCelBuff = pDeadGuy->_deadData[dd]; + /// ASSERT: assert(pDeadGuy->_deadData[dd] != NULL); + if(pCelBuff != NULL) { + pFrameTable = (DWORD *)pDeadGuy->_deadData[dd]; + nCel = pDeadGuy->_deadFrame; + if(nCel >= 1 && pFrameTable[0] <= 50 && nCel <= (int)pFrameTable[0]) { + if(pDeadGuy->_deadtrans != 0) { + Cl2DecodeFrm5(px, dy, pCelBuff, pDeadGuy->_deadFrame, pDeadGuy->_deadWidth, a5, 8, pDeadGuy->_deadtrans); + } else { + Cl2DecodeFrm6(px, dy, pCelBuff, pDeadGuy->_deadFrame, pDeadGuy->_deadWidth, a5, 8); + } + } else { + // app_fatal("Clipped dead sub2: frame %d of %d, deadnum==%d", nCel, pFrameTable[0], (bDead & 0x1F) - 1); + } + } + } + if(bObj != 0) { + DrawClippedObject(sx, sy, dx, dy, 1, a5, 8); + } + } + if(bItem != 0) { + pItem = &item[bItem - 1]; + if(!pItem->_iPostDraw) { + /// ASSERT: assert((unsigned char)bItem <= MAXITEMS); + if((unsigned char)bItem <= MAXITEMS) { + pCelBuff = pItem->_iAnimData; + if(pCelBuff != NULL) { + pFrameTable = (DWORD *)pCelBuff; + nCel = pItem->_iAnimFrame; + if(nCel >= 1 && pFrameTable[0] <= 50 && nCel <= (int)pFrameTable[0]) { + px = dx - pItem->_iAnimWidth2; + if(bItem - 1 == pcursitem) { + CelDrawHdrClrHL(181, px, dy, pCelBuff, pItem->_iAnimFrame, pItem->_iAnimWidth, a5, 8); + } + Cel2DecodeHdrLight(px, dy, pItem->_iAnimData, pItem->_iAnimFrame, pItem->_iAnimWidth, a5, 8); + } else { + /* + app_fatal( + "Draw Clipped \"%s\" Item 3: frame %d of %d, item type==%d", + pItem->_iIName, + nCel, + pFrameTable[0], + pItem->_itype); + */ + } + } else { + // app_fatal("Draw Item \"%s\" Clipped 3: NULL Cel Buffer", pItem->_iIName); + } + } + } + } + if(bFlag & 0x20) { + p = -(negPlr + 1); + if((DWORD)p < MAX_PLRS) { + pPlayer = &plr[p]; + px = dx + pPlayer->_pxoff - pPlayer->_pAnimWidth2; + py = dy + pPlayer->_pyoff; + DrawClippedPlayer(p, sx, sy - 1, px, py, pPlayer->_pAnimData, pPlayer->_pAnimFrame, pPlayer->_pAnimWidth, a5, 8); + if(me_flag && pPlayer->_peflag != 0) { + if(pPlayer->_peflag == 2) { + scrollrt_draw_clipped_e_flag_2(pBuff - (768 * 16 + 96), sx - 2, sy + 1, a4, a5, dx - 96, dy - 16); + } + scrollrt_draw_clipped_e_flag_2(pBuff - 64, sx - 1, sy + 1, a4, a5, dx - 64, dy); + } + } else { + // app_fatal("draw player clipped: tried to draw illegal player %d", p); + } + } + if(bFlag & 0x10 && (bFlag & 0x40 || plr[myplr]._pInfraFlag) && negMon < 0) { + draw_monster_num = -(negMon + 1); + if((DWORD)draw_monster_num < MAXMONSTERS) { + pMonster = &monster[draw_monster_num]; + if(!(pMonster->_mFlags & 1)) { + if(pMonster->MType != NULL) { + px = dx + pMonster->_mxoff - pMonster->MType->flags_2; + py = dy + pMonster->_myoff; + if(draw_monster_num == pcursmonst) { + Cl2DecodeClrHL(233, px, py, pMonster->_mAnimData, pMonster->_mAnimFrame, pMonster->MType->flags_1, a5, 8); + } + DrawClippedMonster(sx, sy, px, py, draw_monster_num, a5, 8); + if(me_flag && !pMonster->_meflag) { + scrollrt_draw_clipped_e_flag_2(pBuff - 64, sx - 1, sy + 1, a4, a5, dx - 64, dy); + } + } else { + // app_fatal("Draw Monster \"%s\" Clipped: uninitialized monster", pMonster->mName); + } + } + } else { + // app_fatal("Draw Monster Clipped: tried to draw illegal monster %d", draw_monster_num); + } + } + if(bFlag & 4) { + DrawDeadPlayer(sx, sy, dx, dy, a5, 8, 1); + } + if(bPlr > 0) { + p = bPlr - 1; + if((DWORD)p < MAX_PLRS) { + pPlayer = &plr[p]; + px = dx + pPlayer->_pxoff - pPlayer->_pAnimWidth2; + py = dy + pPlayer->_pyoff; + DrawClippedPlayer(p, sx, sy, px, py, pPlayer->_pAnimData, pPlayer->_pAnimFrame, pPlayer->_pAnimWidth, a5, 8); + if(me_flag && pPlayer->_peflag != 0) { + if(pPlayer->_peflag == 2) { + scrollrt_draw_clipped_e_flag_2(pBuff - (768 * 16 + 96), sx - 2, sy + 1, a4, a5, dx - 96, dy - 16); + } + scrollrt_draw_clipped_e_flag_2(pBuff - 64, sx - 1, sy + 1, a4, a5, dx - 64, dy); + } + } else { + // app_fatal("draw player clipped: tried to draw illegal player %d", p); + } + } + if(nMon > 0 && (bFlag & 0x40 || plr[myplr]._pInfraFlag)) { + draw_monster_num = nMon - 1; + if((DWORD)draw_monster_num < MAXMONSTERS) { + pMonster = &monster[draw_monster_num]; + if(!(pMonster->_mFlags & 1)) { + if(pMonster->MType != NULL) { + px = dx + pMonster->_mxoff - pMonster->MType->flags_2; + py = dy + pMonster->_myoff; + if(draw_monster_num == pcursmonst) { + Cl2DecodeClrHL(233, px, py, pMonster->_mAnimData, pMonster->_mAnimFrame, pMonster->MType->flags_1, a5, 8); + } + DrawClippedMonster(sx, sy, px, py, draw_monster_num, a5, 8); + if(me_flag && !pMonster->_meflag) { + scrollrt_draw_clipped_e_flag_2(pBuff - 64, sx - 1, sy + 1, a4, a5, dx - 64, dy); + } + } else { + // app_fatal("Draw Monster \"%s\" Clipped: uninitialized monster", pMonster->mName); + } + } + } else { + // app_fatal("Draw Monster Clipped: tried to draw illegal monster %d", draw_monster_num); + } + } + if(bFlag & 1) { + DrawClippedMissile(sx, sy, dx, dy, a5, 8, 0); + } + if(bObj != 0 && light_table_index < lightmax) { + DrawClippedObject(sx, sy, dx, dy, 0, a5, 8); + } + if(bItem != 0) { + pItem = &item[bItem - 1]; + if(pItem->_iPostDraw) { + /// ASSERT: assert((unsigned char)bItem <= MAXITEMS); + if((unsigned char)bItem <= MAXITEMS) { + pCelBuff = pItem->_iAnimData; + if(pCelBuff != NULL) { + pFrameTable = (DWORD *)pCelBuff; + nCel = pItem->_iAnimFrame; + if(nCel >= 1 && pFrameTable[0] <= 50 && nCel <= (int)pFrameTable[0]) { + px = dx - pItem->_iAnimWidth2; + if(bItem - 1 == pcursitem) { + CelDrawHdrClrHL(181, px, dy, pCelBuff, nCel, pItem->_iAnimWidth, a5, 8); + } + Cel2DecodeHdrLight(px, dy, pItem->_iAnimData, pItem->_iAnimFrame, pItem->_iAnimWidth, a5, 8); + } else { + /* + app_fatal( + "Draw Clipped \"%s\" Item 4: frame %d of %d, item type==%d", + pItem->_iIName, + nCel, + pFrameTable[0], + pItem->_itype); + */ + } + } else { + // app_fatal("Draw Item \"%s\" Clipped 4: NULL Cel Buffer", pItem->_iIName); + } + } + } + } + if(bArch != 0) { + cel_transparency_active = (unsigned char)TransList[bMap]; + Cel2DecodeLightTrans(pBuff, pSpecialCels, bArch, 64, a5, 8); + } +} + +static void scrollrt_draw_lower_2(int x, int y, int sx, int sy, int a5, int a6, int some_flag) +{ + int i, j, dir; + BYTE *dst; + MICROS *pMap; + + /// ASSERT: assert(gpBuffer); + + pMap = &dpiece_defs_map_1[IsometricCoord(x, y)]; + dir = 2 * a6 + 2; + + if(some_flag) { + if(y >= 0 && y < MAXDUNY && x >= 0 && x < MAXDUNX) { + level_piece_id = dPiece[x][y]; + light_table_index = dLight[x][y]; + if(level_piece_id != 0) { + dst = &gpBuffer[sx - (768 * 32 - 32) + PitchTbl[sy]]; + cel_transparency_active = (unsigned char)(nTransTable[level_piece_id] & TransList[dTransVal[x][y]]); + for(i = 0; i < (MicroTileLen >> 1) - 1; i++) { + if(a6 <= i) { + level_cel_block = pMap->mt[2 * i + 3]; + if(level_cel_block != 0) { + drawLowerScreen(dst); + } + } + dst -= 768 * 32; + } + if(dir < 8) { + scrollrt_draw_clipped_dungeon_2(&gpBuffer[sx + PitchTbl[sy] - 768 * 16 * dir], x, y, a6, dir, sx, sy, 0); + } + } + } + x++; + y--; + sx += 64; + a5--; + pMap++; + } + + j = a5; + while(j != 0) { + j--; + if(x >= MAXDUNX || y < 0) { + break; + } + if(y < MAXDUNY && x >= 0) { + level_piece_id = dPiece[x][y]; + light_table_index = dLight[x][y]; + if(level_piece_id != 0) { + dst = &gpBuffer[sx - 768 * 32 + PitchTbl[sy]]; + cel_transparency_active = (unsigned char)(nTransTable[level_piece_id] & TransList[dTransVal[x][y]]); + i = 0; + while(i < (MicroTileLen >> 1) - 1) { + if(a6 <= i) { + level_cel_block = pMap->mt[2 * i + 2]; + if(level_cel_block != 0) { + drawLowerScreen(dst); + } + level_cel_block = pMap->mt[2 * i + 3]; + if(level_cel_block != 0) { + drawLowerScreen(dst + 32); + } + } + i++; + dst -= 768 * 32; + } + if(dir < 8) { + scrollrt_draw_clipped_dungeon_2(&gpBuffer[sx + PitchTbl[sy] - 768 * 32 * (a6 + 1)], x, y, a6, dir, sx, sy, 1); + } + } + } + x++; + y--; + sx += 64; + pMap++; + } + + if(some_flag && (DWORD)y < MAXDUNY && (DWORD)x < MAXDUNX) { + level_piece_id = dPiece[x][y]; + light_table_index = dLight[x][y]; + if(level_piece_id != 0) { + dst = &gpBuffer[sx - 768 * 32 + PitchTbl[sy]]; + cel_transparency_active = (unsigned char)(nTransTable[level_piece_id] & TransList[dTransVal[x][y]]); + for(i = 0; i < (MicroTileLen >> 1) - 1; i++) { + if(a6 <= i) { + level_cel_block = pMap->mt[2 * i + 2]; + if(level_cel_block != 0) { + drawLowerScreen(dst); + } + } + dst -= 768 * 32; + } + if(dir < 8) { + scrollrt_draw_clipped_dungeon_2(&gpBuffer[sx + PitchTbl[sy] - 768 * 16 * dir], x, y, a6, dir, sx, sy, 0); + } + } + } +} + +static void scrollrt_draw_dungeon(BYTE *pBuff, int sx, int sy, int a4, int a5, int dx, int dy, int me_flag); + +static void scrollrt_draw_e_flag(BYTE *pBuff, int x, int y, int a4, int a5, int sx, int sy) +{ + int i, lti_old, cta_old, lpi_old; + BYTE *dst; + MICROS *pMap; + + lti_old = light_table_index; + cta_old = cel_transparency_active; + lpi_old = level_piece_id; + + level_piece_id = dPiece[x][y]; + light_table_index = dLight[x][y]; + dst = pBuff; + cel_transparency_active = (unsigned char)(nTransTable[level_piece_id] & TransList[dTransVal[x][y]]); + pMap = &dpiece_defs_map_1[IsometricCoord(x, y)]; + + arch_draw_type = 1; + level_cel_block = pMap->mt[0]; + if(level_cel_block != 0) { + drawUpperScreen(dst); + } + arch_draw_type = 2; + level_cel_block = pMap->mt[1]; + if(level_cel_block != 0) { + drawUpperScreen(dst + 32); + } + + arch_draw_type = 0; + for(i = 1; i < (MicroTileLen >> 1) - 1; i++) { + dst -= 768 * 32; + if(a4 >= i) { + level_cel_block = pMap->mt[2 * i]; + if(level_cel_block != 0) { + drawUpperScreen(dst); + } + level_cel_block = pMap->mt[2 * i + 1]; + if(level_cel_block != 0) { + drawUpperScreen(dst + 32); + } + } + } + + scrollrt_draw_dungeon(pBuff, x, y, a4, a5, sx, sy, 0); + + light_table_index = lti_old; + cel_transparency_active = cta_old; + level_piece_id = lpi_old; +} + +static void scrollrt_draw_dungeon(BYTE *pBuff, int sx, int sy, int a4, int a5, int dx, int dy, int me_flag) +{ + int px, py, nCel, nMon, negMon, p; + char bFlag, bDead, bObj, bItem, bPlr, bArch, bMap, negPlr, dd; + DeadStruct *pDeadGuy; + ItemStruct *pItem; + PlayerStruct *pPlayer; + MonsterStruct *pMonster; + BYTE *pCelBuff; + DWORD *pFrameTable; + + /// ASSERT: assert((DWORD)sx < MAXDUNX); + /// ASSERT: assert((DWORD)sy < MAXDUNY); + bFlag = dFlags[sx][sy]; + bDead = dDead[sx][sy]; + bObj = dObject[sx][sy]; + bItem = dItem[sx][sy]; + bPlr = dPlayer[sx][sy]; + bArch = dSpecial[sx][sy]; + bMap = dTransVal[sx][sy]; + nMon = dMonster[sx][sy]; + + /// ASSERT: assert((DWORD)(sy-1) < MAXDUNY); + negPlr = dPlayer[sx][sy - 1]; + negMon = dMonster[sx][sy - 1]; + + if(visiondebug && (bFlag & 0x40)) { + CelDecodeHdrOnly(pBuff, (BYTE *)pSquareCel, 1, 64, 0, a5); + } + if(MissilePreFlag && (bFlag & 1)) { + DrawMissile(sx, sy, dx, dy, 0, a5, 1); + } + if(light_table_index < lightmax) { + if(bDead != 0) { + pDeadGuy = &dead[(bDead & 0x1F) - 1]; + dd = (unsigned char)(bDead >> 5) & 7; + px = dx - pDeadGuy->_deadWidth2; + pCelBuff = pDeadGuy->_deadData[dd]; + /// ASSERT: assert(pDeadGuy->_deadData[dd] != NULL); + if(pCelBuff != NULL) { + nCel = pDeadGuy->_deadFrame; + pFrameTable = (DWORD *)pCelBuff; + if(nCel >= 1 && pFrameTable[0] <= 50 && nCel <= (int)pFrameTable[0]) { + if(pDeadGuy->_deadtrans != 0) { + Cl2DecodeFrm3(px, dy, pDeadGuy->_deadData[dd], pDeadGuy->_deadFrame, pDeadGuy->_deadWidth, 0, a5, pDeadGuy->_deadtrans); + } else { + Cl2DecodeLightTbl(px, dy, pDeadGuy->_deadData[dd], pDeadGuy->_deadFrame, pDeadGuy->_deadWidth, 0, a5); + } + } else { + // app_fatal("Unclipped dead: frame %d of %d, deadnum==%d", nCel, pFrameTable[0], (bDead & 0x1F) - 1); + } + } + } + if(bObj != 0) { + DrawObject(sx, sy, dx, dy, 1, 0, a5); + } + } + if(bItem != 0) { + pItem = &item[bItem - 1]; + if(!pItem->_iPostDraw) { + /// ASSERT: assert((unsigned char)bItem <= MAXITEMS); + if((unsigned char)bItem <= MAXITEMS) { + pCelBuff = pItem->_iAnimData; + if(pCelBuff != NULL) { + nCel = pItem->_iAnimFrame; + pFrameTable = (DWORD *)pCelBuff; + if(nCel >= 1 && pFrameTable[0] <= 50 && nCel <= (int)pFrameTable[0]) { + px = dx - pItem->_iAnimWidth2; + if(bItem - 1 == pcursitem) { + CelDecodeClr(181, px, dy, pItem->_iAnimData, pItem->_iAnimFrame, pItem->_iAnimWidth, 0, a5); + } + CelDecodeHdrLightOnly(px, dy, pItem->_iAnimData, pItem->_iAnimFrame, pItem->_iAnimWidth, 0, a5); + } else { + // app_fatal("Draw \"%s\" Item 1: frame %d of %d, item type==%d", pItem->_iIName, nCel, pFrameTable[0], pItem->_itype); + } + } else { + // app_fatal("Draw Item \"%s\" 1: NULL Cel Buffer", pItem->_iIName); + } + } + } + } + if(bFlag & 0x20) { + p = -(negPlr + 1); + if((DWORD)p < MAX_PLRS) { + pPlayer = &plr[p]; + px = dx + pPlayer->_pxoff - pPlayer->_pAnimWidth2; + py = dy + pPlayer->_pyoff; + DrawPlayer(p, sx, sy - 1, px, py, pPlayer->_pAnimData, pPlayer->_pAnimFrame, pPlayer->_pAnimWidth, 0, a5); + if(me_flag && pPlayer->_peflag != 0) { + if(pPlayer->_peflag == 2) { + scrollrt_draw_e_flag(pBuff - (768 * 16 + 96), sx - 2, sy + 1, a4, a5, dx - 96, dy - 16); + } + scrollrt_draw_e_flag(pBuff - 64, sx - 1, sy + 1, a4, a5, dx - 64, dy); + } + } else { + // app_fatal("draw player: tried to draw illegal player %d", p); + } + } + if((bFlag & 0x10) && ((bFlag & 0x40) || plr[myplr]._pInfraFlag) && negMon < 0) { + draw_monster_num = -(negMon + 1); + if((DWORD)draw_monster_num < MAXMONSTERS) { + pMonster = &monster[draw_monster_num]; + if(!(pMonster->_mFlags & 1)) { + if(pMonster->MType != NULL) { + py = dy + pMonster->_myoff; + px = dx + pMonster->_mxoff - pMonster->MType->flags_2; + if(draw_monster_num == pcursmonst) { + Cl2DecodeFrm2(233, px, py, pMonster->_mAnimData, pMonster->_mAnimFrame, pMonster->MType->flags_1, 0, a5); + } + DrawMonster(sx, sy, px, py, draw_monster_num, 0, a5); + if(me_flag && !pMonster->_meflag) { + scrollrt_draw_e_flag(pBuff - 64, sx - 1, sy + 1, a4, a5, dx - 64, dy); + } + } else { + // app_fatal("Draw Monster \"%s\": uninitialized monster", pMonster->mName); + } + } + } else { + // app_fatal("Draw Monster: tried to draw illegal monster %d", draw_monster_num); + } + } + if(bFlag & 4) { + DrawDeadPlayer(sx, sy, dx, dy, 0, a5, 0); + } + if(bPlr > 0) { + p = bPlr - 1; + if((DWORD)p < MAX_PLRS) { + pPlayer = &plr[p]; + px = dx + pPlayer->_pxoff - pPlayer->_pAnimWidth2; + py = dy + pPlayer->_pyoff; + DrawPlayer(p, sx, sy, px, py, pPlayer->_pAnimData, pPlayer->_pAnimFrame, pPlayer->_pAnimWidth, 0, a5); + if(me_flag && pPlayer->_peflag != 0) { + if(pPlayer->_peflag == 2) { + scrollrt_draw_e_flag(pBuff - (768 * 16 + 96), sx - 2, sy + 1, a4, a5, dx - 96, dy - 16); + } + scrollrt_draw_e_flag(pBuff - 64, sx - 1, sy + 1, a4, a5, dx - 64, dy); + } + } else { + // app_fatal("draw player: tried to draw illegal player %d", p); + } + } + if(nMon > 0 && ((bFlag & 0x40) || plr[myplr]._pInfraFlag)) { + draw_monster_num = nMon - 1; + if((DWORD)draw_monster_num < MAXMONSTERS) { + pMonster = &monster[draw_monster_num]; + if(!(pMonster->_mFlags & 1)) { + if(pMonster->MType != NULL) { + py = dy + pMonster->_myoff; + px = dx + pMonster->_mxoff - pMonster->MType->flags_2; + if(draw_monster_num == pcursmonst) { + Cl2DecodeFrm2(233, px, py, pMonster->_mAnimData, pMonster->_mAnimFrame, pMonster->MType->flags_1, 0, a5); + } + DrawMonster(sx, sy, px, py, draw_monster_num, 0, a5); + if(me_flag && !pMonster->_meflag) { + scrollrt_draw_e_flag(pBuff - 64, sx - 1, sy + 1, a4, a5, dx - 64, dy); + } + } else { + // app_fatal("Draw Monster \"%s\": uninitialized monster", pMonster->mName); + } + } + } else { + // app_fatal("Draw Monster: tried to draw illegal monster %d", draw_monster_num); + } + } + if(bFlag & 1) { + DrawMissile(sx, sy, dx, dy, 0, a5, 0); + } + if(bObj != 0 && light_table_index < lightmax) { + DrawObject(sx, sy, dx, dy, 0, 0, a5); + } + if(bItem != 0) { + pItem = &item[bItem - 1]; + if(pItem->_iPostDraw) { + /// ASSERT: assert((unsigned char)bItem <= MAXITEMS); + if((unsigned char)bItem <= MAXITEMS) { + pCelBuff = pItem->_iAnimData; + if(pCelBuff != NULL) { + nCel = pItem->_iAnimFrame; + pFrameTable = (DWORD *)pCelBuff; + if(nCel >= 1 && pFrameTable[0] <= 50 && nCel <= (int)pFrameTable[0]) { + px = dx - pItem->_iAnimWidth2; + if(bItem - 1 == pcursitem) { + CelDecodeClr(181, px, dy, pItem->_iAnimData, pItem->_iAnimFrame, pItem->_iAnimWidth, 0, a5); + } + CelDecodeHdrLightOnly(px, dy, pItem->_iAnimData, pItem->_iAnimFrame, pItem->_iAnimWidth, 0, a5); + } else { + // app_fatal("Draw \"%s\" Item 2: frame %d of %d, item type==%d", pItem->_iIName, nCel, pFrameTable[0], pItem->_itype); + } + } else { + // app_fatal("Draw Item \"%s\" 2: NULL Cel Buffer", pItem->_iIName); + } + } + } + } + if(bArch != 0) { + cel_transparency_active = (unsigned char)TransList[bMap]; + CelDecodeHdrLightTrans(pBuff, pSpecialCels, bArch, 64, 0, a5); + } +} + +static void scrollrt_draw_upper(int x, int y, int sx, int sy, int a5, int a6, int some_flag) +{ + int i, j, dir; + BYTE *dst; + MICROS *pMap; + + /// ASSERT: assert(gpBuffer); + + pMap = &dpiece_defs_map_1[IsometricCoord(x, y)]; + dir = 2 * a6 + 2; + if(dir > 8) { + dir = 8; + } + + if(some_flag) { + if(y >= 0 && y < MAXDUNY && x >= 0 && x < MAXDUNX) { + level_piece_id = dPiece[x][y]; + light_table_index = dLight[x][y]; + if(level_piece_id != 0) { + dst = &gpBuffer[sx + 32 + PitchTbl[sy]]; + cel_transparency_active = (unsigned char)(nTransTable[level_piece_id] & TransList[dTransVal[x][y]]); + if(a6 >= 0) { + level_cel_block = pMap->mt[1]; + if(level_cel_block != 0) { + arch_draw_type = 2; + drawUpperScreen(dst); + arch_draw_type = 0; + } + } + dst -= 768 * 32; + if(a6 >= 1) { + level_cel_block = pMap->mt[3]; + if(level_cel_block != 0) { + drawUpperScreen(dst); + } + } + dst -= 768 * 32; + if(a6 >= 2) { + level_cel_block = pMap->mt[5]; + if(level_cel_block != 0) { + drawUpperScreen(dst); + } + } + dst -= 768 * 32; + if(a6 >= 3) { + level_cel_block = pMap->mt[7]; + if(level_cel_block != 0) { + drawUpperScreen(dst); + } + } + scrollrt_draw_dungeon(&gpBuffer[sx + PitchTbl[sy]], x, y, a6, dir, sx, sy, 0); + } else { + world_draw_black_tile(&gpBuffer[sx + PitchTbl[sy]]); + } + } + x++; + y--; + sx += 64; + a5--; + pMap++; + } + + for(j = 0; j < a5; j++) { + if(y >= 0 && y < MAXDUNY && x >= 0 && x < MAXDUNX) { + level_piece_id = dPiece[x][y]; + light_table_index = dLight[x][y]; + if(level_piece_id != 0) { + dst = &gpBuffer[sx + PitchTbl[sy]]; + cel_transparency_active = (unsigned char)(nTransTable[level_piece_id] & TransList[dTransVal[x][y]]); + arch_draw_type = 1; + level_cel_block = pMap->mt[0]; + if(level_cel_block != 0) { + drawUpperScreen(dst); + } + arch_draw_type = 2; + level_cel_block = pMap->mt[1]; + if(level_cel_block != 0) { + drawUpperScreen(dst + 32); + } + arch_draw_type = 0; + for(i = 1; i < (MicroTileLen >> 1) - 1; i++) { + dst -= 768 * 32; + if(a6 >= i) { + level_cel_block = pMap->mt[2 * i]; + if(level_cel_block != 0) { + drawUpperScreen(dst); + } + level_cel_block = pMap->mt[2 * i + 1]; + if(level_cel_block != 0) { + drawUpperScreen(dst + 32); + } + } + } + scrollrt_draw_dungeon(&gpBuffer[sx + PitchTbl[sy]], x, y, a6, dir, sx, sy, 1); + } else { + world_draw_black_tile(&gpBuffer[sx + PitchTbl[sy]]); + } + } + x++; + y--; + sx += 64; + pMap++; + } + + if(some_flag && y >= 0 && y < MAXDUNY && x >= 0 && x < MAXDUNX) { + level_piece_id = dPiece[x][y]; + light_table_index = dLight[x][y]; + if(level_piece_id != 0) { + dst = &gpBuffer[sx + PitchTbl[sy]]; + cel_transparency_active = (unsigned char)(nTransTable[level_piece_id] & TransList[dTransVal[x][y]]); + arch_draw_type = 1; + if(a6 >= 0) { + level_cel_block = pMap->mt[0]; + if(level_cel_block != 0) { + drawUpperScreen(dst); + } + } + arch_draw_type = 0; + dst -= 768 * 32; + if(a6 >= 1) { + level_cel_block = pMap->mt[2]; + if(level_cel_block != 0) { + drawUpperScreen(dst); + } + } + dst -= 768 * 32; + if(a6 >= 2) { + level_cel_block = pMap->mt[4]; + if(level_cel_block != 0) { + drawUpperScreen(dst); + } + } + dst -= 768 * 32; + if(a6 >= 3) { + level_cel_block = pMap->mt[6]; + if(level_cel_block != 0) { + drawUpperScreen(dst); + } + } + scrollrt_draw_dungeon(&gpBuffer[sx + PitchTbl[sy]], x, y, a6, dir, sx, sy, 0); + } else { + world_draw_black_tile(&gpBuffer[sx + PitchTbl[sy]]); + } + } +} + +static void DrawGame(int x, int y) +{ + int i, sx, sy, chunks, blocks; + + ViewDX = 640; + ViewDY = 352; + ViewBX = 10; + ViewBY = 11; + + sx = ScrollInfo._sxoff + 64; + sy = ScrollInfo._syoff + 175; + x -= 10; + y--; + chunks = 10; + blocks = 8; + + if(chrflag || questlog) { + x += 2; + y -= 2; + sx += 288; + chunks = 6; + } + if(invflag || sbookflag) { + x += 2; + y -= 2; + sx -= 32; + chunks = 6; + } + + switch(ScrollInfo._sdir) { + case 0: + break; + case 2: + chunks++; + case 1: + sy -= 32; + x--; + y--; + blocks++; + break; + case 4: + blocks++; + case 3: + chunks++; + break; + case 5: + blocks++; + break; + case 6: + blocks++; + case 7: + sx -= 64; + x--; + y++; + chunks++; + break; + case 8: + sx -= 64; + sy -= 32; + x -= 2; + chunks++; + blocks++; + break; + } + + /// ASSERT: assert(gpBuffer); + gpBufEnd = &gpBuffer[PitchTbl[160]]; + for(i = 0; i < 4; i++) { + scrollrt_draw_upper(x, y, sx, sy, chunks, i, 0); + y++; + sx -= 32; + sy += 16; + scrollrt_draw_upper(x, y, sx, sy, chunks, i, 1); + x++; + sx += 32; + sy += 16; + } + /// ASSERT: assert(gpBuffer); + gpBufEnd = &gpBuffer[PitchTbl[512]]; + for(i = 0; i < blocks; i++) { + scrollrt_draw_lower(x, y, sx, sy, chunks, 0); + y++; + sx -= 32; + sy += 16; + scrollrt_draw_lower(x, y, sx, sy, chunks, 1); + x++; + sx += 32; + sy += 16; + } + arch_draw_type = 0; + for(i = 0; i < 4; i++) { + scrollrt_draw_lower_2(x, y, sx, sy, chunks, i, 0); + y++; + sx -= 32; + sy += 16; + scrollrt_draw_lower_2(x, y, sx, sy, chunks, i, 1); + x++; + sx += 32; + sy += 16; + } +} + +static void DrawZoom(int x, int y) +{ + int i, sx, sy, chunks, blocks; + int wdt, nSrcOff, nDstOff; + + ViewDX = 384; + ViewDY = 192; + ViewBX = 6; + ViewBY = 6; + + sx = ScrollInfo._sxoff + 64; + sy = ScrollInfo._syoff + 143; + x -= 6; + y--; + chunks = 6; + blocks = 3; + + switch(ScrollInfo._sdir) { + case 0: + break; + case 2: + chunks++; + case 1: + sy -= 32; + x--; + y--; + blocks++; + break; + case 4: + blocks++; + case 3: + chunks++; + break; + case 5: + blocks++; + break; + case 6: + blocks++; + case 7: + sx -= 64; + x--; + y++; + chunks++; + break; + case 8: + sx -= 64; + sy -= 32; + x -= 2; + chunks++; + blocks++; + break; + } + + /// ASSERT: assert(gpBuffer); + gpBufEnd = &gpBuffer[PitchTbl[143]]; + for(i = 0; i < 4; i++) { + scrollrt_draw_upper(x, y, sx, sy, chunks, i, 0); + y++; + sx -= 32; + sy += 16; + scrollrt_draw_upper(x, y, sx, sy, chunks, i, 1); + x++; + sx += 32; + sy += 16; + } + /// ASSERT: assert(gpBuffer); + gpBufEnd = &gpBuffer[PitchTbl[320]]; + for(i = 0; i < blocks; i++) { + scrollrt_draw_lower(x, y, sx, sy, chunks, 0); + y++; + sx -= 32; + sy += 16; + scrollrt_draw_lower(x, y, sx, sy, chunks, 1); + x++; + sx += 32; + sy += 16; + } + arch_draw_type = 0; + for(i = 0; i < 4; i++) { + scrollrt_draw_lower_2(x, y, sx, sy, chunks, i, 0); + y++; + sx -= 32; + sy += 16; + scrollrt_draw_lower_2(x, y, sx, sy, chunks, i, 1); + x++; + sx += 32; + sy += 16; + } + + if(chrflag || questlog) { + nSrcOff = SCREENXY(112, 159); + nDstOff = SCREENXY(320, 350); + wdt = 160; + } else if(invflag || sbookflag) { + nSrcOff = SCREENXY(112, 159); + nDstOff = SCREENXY(0, 350); + wdt = 160; + } else { + nSrcOff = SCREENXY(32, 159); + nDstOff = SCREENXY(0, 350); + wdt = 320; + } + + /// ASSERT: assert(gpBuffer); + +#ifdef USE_ASM + __asm { + mov esi, gpBuffer + mov edx, nDstOff + mov edi, esi + mov ecx, nSrcOff + add edi, edx + add esi, ecx + mov ebx, edi + add ebx, 768 + mov edx, 176 + label1: + mov ecx, wdt + label2: + mov al, [esi] + inc esi + mov ah, al + mov [edi], ax + mov [ebx], ax + add edi, 2 + add ebx, 2 + dec ecx + jnz label2 + mov eax, 768 + add eax, wdt + sub esi, eax + add eax, eax + sub ebx, eax + sub edi, eax + dec edx + jnz label1 + } +#else + int hgt; + BYTE *src, *dst1, *dst2; + + src = &gpBuffer[nSrcOff]; + dst1 = &gpBuffer[nDstOff]; + dst2 = &gpBuffer[nDstOff + 768]; + + for(hgt = 176; hgt != 0; hgt--, src -= 768 + wdt, dst1 -= 2 * (768 + wdt), dst2 -= 2 * (768 + wdt)) { + for(i = wdt; i != 0; i--) { + *dst1++ = *src; + *dst1++ = *src; + *dst2++ = *src; + *dst2++ = *src; + src++; + } + } +#endif +} + +void DrawView(int StartX, int StartY) +{ + if(zoomflag) { + DrawGame(StartX, StartY); + } else { + DrawZoom(StartX, StartY); + } + if(automapflag) { + DrawAutomap(); + } + if(invflag) { + DrawInv(); + } else if(sbookflag) { + DrawSpellBook(); + } + + DrawDurIcon(); + + if(chrflag) { + DrawChr(); + } else if(questlog) { + DrawQuestLog(); + } else if(plr[myplr]._pStatPts != 0 && !spselflag) { + DrawLevelUpIcon(); + } + if(uitemflag) { + DrawUniqueInfo(); + } + if(qtextflag) { + DrawQText(); + } + if(spselflag) { + DrawSpellList(); + } + if(dropGoldFlag) { + DrawGoldSplit(dropGoldValue); + } + if(helpflag) { + DrawHelp(); + } + if(msgflag) { + DrawDiabloMsg(); + } + if(deathflag) { + RedBack(); + } else if(PauseMode != 0) { + gmenu_draw_pause(); + } + + DrawPlrMsg(); + gmenu_draw(); + doom_draw(); + DrawInfoBox(); + DrawLifeFlask(); + DrawManaFlask(); +} + +void ClearScreenBuffer() +{ + lock_buf(3); + + /// ASSERT: assert(gpBuffer); + +#ifdef USE_ASM + __asm { + mov edi, gpBuffer + add edi, SCREENXY(0, 0) + mov edx, 480 + xor eax, eax + zeroline: + mov ecx, 640 / 4 + rep stosd + add edi, 768 - 640 + dec edx + jnz zeroline + } +#else + int i; + BYTE *dst; + + dst = &gpBuffer[SCREENXY(0, 0)]; + + for(i = 0; i < 480; i++, dst += 768) { + memset(dst, 0, 640); + } +#endif + + unlock_buf(3); +} + +#ifdef _DEBUG +void ScrollView() +{ + BOOL scroll; + + if(pcurs >= CURSOR_FIRSTITEM) + return; + + scroll = FALSE; + + if(MouseX < 20) { + if(dmaxy - 1 <= ViewY || dminx >= ViewX) { + if(dmaxy - 1 > ViewY) { + ViewY++; + scroll = TRUE; + } + if(dminx < ViewX) { + ViewX--; + scroll = TRUE; + } + } else { + ViewY++; + ViewX--; + scroll = TRUE; + } + } + if(MouseX > 640-20) { + if(dmaxx - 1 <= ViewX || dminy >= ViewY) { + if(dmaxx - 1 > ViewX) { + ViewX++; + scroll = TRUE; + } + if(dminy < ViewY) { + ViewY--; + scroll = TRUE; + } + } else { + ViewY--; + ViewX++; + scroll = TRUE; + } + } + if(MouseY < 20) { + if(dminy >= ViewY || dminx >= ViewX) { + if(dminy < ViewY) { + ViewY--; + scroll = TRUE; + } + if(dminx < ViewX) { + ViewX--; + scroll = TRUE; + } + } else { + ViewX--; + ViewY--; + scroll = TRUE; + } + } + if(MouseY > 480-20) { + if(dmaxy - 1 <= ViewY || dmaxx - 1 <= ViewX) { + if(dmaxy - 1 > ViewY) { + ViewY++; + scroll = TRUE; + } + if(dmaxx - 1 > ViewX) { + ViewX++; + scroll = TRUE; + } + } else { + ViewX++; + ViewY++; + scroll = TRUE; + } + } + + if(scroll) + ScrollInfo._sdir = 0; +} + +void EnableFrameCount() +{ + frameflag = frameflag == 0; + framestart = GetTickCount(); +} + +static void DrawFPS() +{ + DWORD v0; // eax + int v1; // esi + char String[12]; // [esp+8h] [ebp-10h] + HDC hdc; // [esp+14h] [ebp-4h] + + if ( frameflag && gbActive ) + { + ++frameend; + v0 = GetTickCount(); + v1 = v0 - framestart; + if ( v0 - framestart >= 1000 ) + { + framestart = v0; + framerate = 1000 * frameend / v1; + frameend = 0; + } + if ( framerate > 99 ) + framerate = 99; + wsprintf(String, "%2d", framerate); + if ( !lpDDSPrimary->GetDC(&hdc) ) + { + TextOut(hdc, 0, 400, String, strlen(String)); + lpDDSPrimary->ReleaseDC(hdc); + } + } +} +#endif + +static void DoBlitScreen(DWORD dwX, DWORD dwY, DWORD dwWdt, DWORD dwHgt) +{ + int nSrcOff, nDstOff, nSrcWdt, nDstWdt; + DWORD dwTicks; + HRESULT hDDVal; + RECT SrcRect; + + /// ASSERT: assert(! (dwX & 3)); + /// ASSERT: assert(! (dwWdt & 3)); + + if(lpDDSBackBuf != NULL) { + SrcRect.left = dwX + 64; + SrcRect.top = dwY + 160; + SrcRect.right = SrcRect.left + dwWdt - 1; + SrcRect.bottom = SrcRect.top + dwHgt - 1; + /// ASSERT: assert(! gpBuffer); + dwTicks = GetTickCount(); + while(1) { + hDDVal = lpDDSPrimary->BltFast(dwX, dwY, lpDDSBackBuf, &SrcRect, DDBLTFAST_WAIT); + if(hDDVal == DD_OK) { + break; + } + if(dwTicks - GetTickCount() > 5000) { + break; + } + Sleep(1); + if(hDDVal == DDERR_SURFACELOST) { + return; + } + if(hDDVal != DDERR_WASSTILLDRAWING && hDDVal != DDERR_SURFACEBUSY) { + break; + } + } + if(hDDVal != DDERR_SURFACELOST + && hDDVal != DDERR_WASSTILLDRAWING + && hDDVal != DDERR_SURFACEBUSY + && hDDVal != DD_OK) { + DDErrMsg(hDDVal, 3596, "C:\\Src\\Diablo\\Source\\SCROLLRT.CPP"); + } + } else { + nSrcOff = SCREENXY(dwX, dwY); + nDstOff = dwX * (SCREEN_BPP / 8) + dwY * DDS_desc.lPitch; + nSrcWdt = 768 - dwWdt; + nDstWdt = DDS_desc.lPitch - dwWdt * (SCREEN_BPP / 8); + dwWdt >>= 2; + + lock_buf(6); + + /// ASSERT: assert(gpBuffer); + +#if defined(USE_ASM) && !defined(RGBMODE) + __asm { + mov esi, gpBuffer + mov edi, DDS_desc.lpSurface + add esi, nSrcOff + add edi, nDstOff + mov eax, nSrcWdt + mov ebx, nDstWdt + mov edx, dwHgt + blitline: + mov ecx, dwWdt + rep movsd + add esi, eax + add edi, ebx + dec edx + jnz blitline + } +#else + int wdt, hgt; + BYTE *src, *dst; + + src = &gpBuffer[nSrcOff]; + dst = (BYTE *)DDS_desc.lpSurface + nDstOff; + + for(hgt = 0; hgt < dwHgt; hgt++, src += nSrcWdt, dst += nDstWdt) { + for(wdt = 0; wdt < 4 * dwWdt; wdt++) { +#ifndef RGBMODE + *dst++ = *src++; +#else + PALETTEENTRY pal = system_palette[*src++]; + dst[0] = pal.peBlue; + dst[1] = pal.peGreen; + dst[2] = pal.peRed; + dst += 4; +#endif + } + } +#endif + + unlock_buf(6); + } +} + +static void DrawMain(int dwHgt, int draw_desc, int draw_hp, int draw_mana, int draw_sbar, int draw_btn) +{ + int ysize; + DWORD dwTicks; + BOOL retry; + HRESULT hDDVal; + + ysize = dwHgt; + + if(!gbActive || lpDDSPrimary == NULL) { + return; + } + + if(lpDDSPrimary->IsLost() == DDERR_SURFACELOST) { + if(lpDDSPrimary->Restore() != DD_OK) { + return; + } + ResetPal(); + ysize = 480; + } + + if(lpDDSBackBuf == NULL) { + retry = TRUE; + dwTicks = GetTickCount(); + while(1) { + DDS_desc.dwSize = sizeof(DDS_desc); + hDDVal = lpDDSPrimary->Lock(NULL, &DDS_desc, DDLOCK_WRITEONLY|DDLOCK_WAIT, NULL); + if(hDDVal == DD_OK) { + break; + } + if(dwTicks - GetTickCount() > 5000) { + break; + } + Sleep(1); + if(hDDVal == DDERR_SURFACELOST) { + return; + } + if(hDDVal != DDERR_WASSTILLDRAWING && hDDVal != DDERR_SURFACEBUSY) { + if(!retry || hDDVal != DDERR_GENERIC) { + break; + } + retry = FALSE; + dx_reinit(); + ysize = 480; + dwTicks = GetTickCount(); + } + } + if(hDDVal == DDERR_SURFACELOST + || hDDVal == DDERR_WASSTILLDRAWING + || hDDVal == DDERR_SURFACEBUSY) { + return; + } + if(hDDVal != DD_OK) { + DDErrMsg(hDDVal, 3707, "C:\\Src\\Diablo\\Source\\SCROLLRT.CPP"); + } + } + + /// ASSERT: assert(ysize >= 0 && ysize <= 480); + + if(ysize > 0) { + DoBlitScreen(0, 0, 640, ysize); + } + if(ysize < 480) { + if(draw_sbar) { + DoBlitScreen(204, 357, 232, 28); + } + if(draw_desc) { + DoBlitScreen(176, 398, 288, 60); + } + if(draw_mana) { + DoBlitScreen(460, 352, 88, 72); + DoBlitScreen(564, 416, 56, 56); + } + if(draw_hp) { + DoBlitScreen(96, 352, 88, 72); + } + if(draw_btn) { + DoBlitScreen(8, 357, 72, 119); + DoBlitScreen(556, 357, 72, 48); + if(gbMaxPlayers > 1) { + DoBlitScreen(84, 443, 36, 32); + DoBlitScreen(524, 443, 36, 32); + } + } + if(sgdwCursWdtOld != 0) { + DoBlitScreen(sgdwCursXOld, sgdwCursYOld, sgdwCursWdtOld, sgdwCursHgtOld); + } + if(sgdwCursWdt != 0) { + DoBlitScreen(sgdwCursX, sgdwCursY, sgdwCursWdt, sgdwCursHgt); + } + } + + if(lpDDSBackBuf == NULL) { + hDDVal = lpDDSPrimary->Unlock(NULL); + if(hDDVal != DDERR_SURFACELOST && hDDVal != DD_OK) { + DDErrMsg(hDDVal, 3779, "C:\\Src\\Diablo\\Source\\SCROLLRT.CPP"); + } + } + +#ifdef _DEBUG + DrawFPS(); +#endif +} + +void scrollrt_draw_game_screen(BOOL draw_cursor) +{ + int hgt; + + if(force_redraw == 255) { + force_redraw = 0; + hgt = 480; + } else { + hgt = 0; + } + + if(draw_cursor) { + lock_buf(0); + scrollrt_draw_cursor_item(); + unlock_buf(0); + } + + DrawMain(hgt, 0, 0, 0, 0, 0); + + if(draw_cursor) { + lock_buf(0); + scrollrt_draw_cursor_back_buffer(); + unlock_buf(0); + } +} + +void DrawAndBlit() +{ + int hgt; + BOOL ddsdesc, ctrlPan; + + if(!gbRunGame) { + return; + } + + if(force_redraw == 255) { + drawhpflag = TRUE; + drawmanaflag = TRUE; + drawbtnflag = TRUE; + drawsbarflag = TRUE; + ddsdesc = FALSE; + ctrlPan = TRUE; + hgt = 480; + } else if(force_redraw == 1) { + ddsdesc = TRUE; + ctrlPan = FALSE; + hgt = 352; + } else { + return; + } + + force_redraw = 0; + + lock_buf(0); + if(leveltype != DTYPE_TOWN) { + DrawView(ViewX, ViewY); + } else { + T_DrawView(ViewX, ViewY); + } + if(ctrlPan) { + DrawCtrlPan(); + } + if(drawhpflag) { + UpdateLifeFlask(); + } + if(drawmanaflag) { + UpdateManaFlask(); + } + if(drawbtnflag) { + DrawCtrlBtns(); + } + if(drawsbarflag) { + DrawInvBelt(); + } + if(talkflag) { + DrawTalkPan(); + hgt = 480; + } + scrollrt_draw_cursor_item(); + unlock_buf(0); + + DrawMain(hgt, ddsdesc, drawhpflag, drawmanaflag, drawsbarflag, drawbtnflag); + + lock_buf(0); + scrollrt_draw_cursor_back_buffer(); + unlock_buf(0); + + drawhpflag = FALSE; + drawmanaflag = FALSE; + drawbtnflag = FALSE; + drawsbarflag = FALSE; +} diff --git a/2020_03_31/Source/scrollrt.h b/2020_03_31/Source/scrollrt.h new file mode 100644 index 00000000..c6fa5ab8 --- /dev/null +++ b/2020_03_31/Source/scrollrt.h @@ -0,0 +1,44 @@ +//HEADER_GOES_HERE +#ifndef __SCROLLRT_H__ +#define __SCROLLRT_H__ + +extern int light_table_index; // weak +extern int PitchTbl[1024]; +extern DWORD sgdwCursWdtOld; // idb +extern DWORD sgdwCursX; // idb +extern DWORD sgdwCursY; // idb +extern unsigned char *gpBufEnd; // weak +extern DWORD sgdwCursHgt; +extern int level_cel_block; // weak +extern DWORD sgdwCursXOld; // idb +extern DWORD sgdwCursYOld; // idb +extern char arch_draw_type; // weak +extern DDSURFACEDESC DDS_desc; +extern int cel_transparency_active; // weak +extern int level_piece_id; // weak +extern DWORD sgdwCursWdt; +extern void (*DrawPlrProc)(int, int, int, int, int, BYTE *, int, int, int, int); +extern BYTE sgSaveBack[8192]; +extern int draw_monster_num; // weak +extern DWORD sgdwCursHgtOld; // idb + +void ClearCursor(); +void DrawMissile(int x, int y, int sx, int sy, int a5, int a6, BOOL pre); +void DrawClippedMissile(int x, int y, int sx, int sy, int a5, int a6, BOOL pre); +void DrawDeadPlayer(int x, int y, int sx, int sy, int a5, int a6, BOOL clipped); +void DrawView(int StartX, int StartY); +void ClearScreenBuffer(); +#ifdef _DEBUG +void ScrollView(); +void EnableFrameCount(); +#endif +void scrollrt_draw_game_screen(BOOL draw_cursor); +void DrawAndBlit(); + +/* data */ + +/* used in 1.00 debug */ +extern char *szMonModeAssert[18]; +extern char *szPlrModeAssert[12]; + +#endif /* __SCROLLRT_H__ */ diff --git a/2020_03_31/Source/setmaps.cpp b/2020_03_31/Source/setmaps.cpp new file mode 100644 index 00000000..68997a5f --- /dev/null +++ b/2020_03_31/Source/setmaps.cpp @@ -0,0 +1,199 @@ +#include "diablo.h" + +unsigned char SkelKingTrans1[8] = +{ + 19, 47, 26, 55, + 26, 49, 30, 53 +}; + +unsigned char SkelKingTrans2[8] = +{ + 33, 19, 47, 29, + 37, 29, 43, 39 +}; + +unsigned char SkelKingTrans3[20] = +{ + 27, 53, 35, 61, + 27, 35, 34, 42, + 45, 35, 53, 43, + 45, 53, 53, 61, + 31, 39, 49, 57 +}; + +unsigned char SkelKingTrans4[28] = +{ + 49, 45, 58, 51, + 57, 31, 62, 37, + 63, 31, 69, 40, + 59, 41, 73, 55, + 63, 55, 69, 65, + 73, 45, 78, 51, + 79, 43, 89, 53 +}; + +unsigned char SkelChamTrans1[20] = +{ + 43, 19, 50, 26, + 51, 19, 59, 26, + 35, 27, 42, 34, + 43, 27, 49, 34, + 50, 27, 59, 34 +}; + +unsigned char SkelChamTrans2[8] = +{ + 19, 31, 34, 47, + 34, 35, 42, 42 +}; + +unsigned char SkelChamTrans3[36] = +{ + 43, 35, 50, 42, + 51, 35, 62, 42, + 63, 31, 66, 46, + 67, 31, 78, 34, + 67, 35, 78, 42, + 67, 43, 78, 46, + 35, 43, 42, 51, + 43, 43, 49, 51, + 50, 43, 59, 51 +}; + +char *quest_level_names[] = +{ + "", + "Skeleton King's Lair", + "Bone Chamber", + "Maze", + "Poisoned Water Supply", + "Archbishop Lazarus' Lair" +}; + +int ObjIndex(int x, int y) +{ + int i, oi; + + for(i = 0; i < nobjects; i++) { + oi = objectactive[i]; + if(object[oi]._ox == x && object[oi]._oy == y) { + return oi; + } + } + + app_fatal("ObjIndex: Active object not found at (%d,%d)", x, y); + return -1; +} + +void AddSKingObjs() +{ + SetObjMapRange(ObjIndex(64, 34), 20, 7, 23, 10, 1); + SetObjMapRange(ObjIndex(64, 59), 20, 14, 21, 16, 2); + SetObjMapRange(ObjIndex(27, 37), 8, 1, 15, 11, 3); + SetObjMapRange(ObjIndex(46, 35), 8, 1, 15, 11, 3); + SetObjMapRange(ObjIndex(49, 53), 8, 1, 15, 11, 3); + SetObjMapRange(ObjIndex(27, 53), 8, 1, 15, 11, 3); +} + +void AddSChamObjs() +{ + SetObjMapRange(ObjIndex(37, 30), 17, 0, 21, 5, 1); + SetObjMapRange(ObjIndex(37, 46), 13, 0, 16, 5, 2); +} + +void AddVileObjs() +{ + SetObjMapRange(ObjIndex(26, 45), 1, 1, 9, 10, 1); + SetObjMapRange(ObjIndex(45, 46), 11, 1, 20, 10, 2); + SetObjMapRange(ObjIndex(35, 36), 7, 11, 13, 18, 3); +} + +void DRLG_SetMapTrans(char *sFileName) +{ + int i, j, rw, rh; + long mapoff; + BYTE *pLevelMap, *lm; + + pLevelMap = DiabLoad(sFileName, NULL, 'LMPt'); + lm = pLevelMap; + rw = *lm; + lm += 2; + rh = *lm; + mapoff = 2 * rw * rh + 2; + rw <<= 1; + rh <<= 1; + mapoff += 6 * rw * rh; + lm += mapoff; + + for(j = 0; j < rh; j++) { + for(i = 0; i < rw; i++) { + dTransVal[i + 16][j + 16] = *lm; + lm += 2; + } + } + + MemFreeDbg(pLevelMap); +} + +void LoadSetMap() +{ + switch(setlvlnum) { + case SL_SKELKING: + if(quests[Q_SKELKING]._qactive == 1) { + quests[Q_SKELKING]._qactive = 2; + quests[Q_SKELKING]._qvar1 = 1; + } + LoadPreL1Dungeon("Levels\\L1Data\\SklKng1.DUN", 83, 45); + LoadL1Dungeon("Levels\\L1Data\\SklKng2.DUN", 83, 45); + LoadPalette("Levels\\L1Data\\L1_2.pal"); + DRLG_AreaTrans(2, SkelKingTrans1); + DRLG_ListTrans(2, SkelKingTrans2); + DRLG_AreaTrans(5, SkelKingTrans3); + DRLG_ListTrans(7, SkelKingTrans4); + AddL1Objs(0, 0, 112, 112); + AddSKingObjs(); + InitSKingTriggers(); + break; + case SL_BONECHAMB: + LoadPreL2Dungeon("Levels\\L2Data\\Bonecha2.DUN", 69, 39); + LoadL2Dungeon("Levels\\L2Data\\Bonecha1.DUN", 69, 39); + LoadPalette("Levels\\L2Data\\L2_2.pal"); + DRLG_ListTrans(5, SkelChamTrans1); + DRLG_AreaTrans(2, SkelChamTrans2); + DRLG_ListTrans(9, SkelChamTrans3); + AddL2Objs(0, 0, 112, 112); + AddSChamObjs(); + InitSChambTriggers(); + break; + case SL_MAZE: + LoadPreL1Dungeon("Levels\\L1Data\\Lv1MazeA.DUN", 20, 50); + LoadL1Dungeon("Levels\\L1Data\\Lv1MazeB.DUN", 20, 50); + LoadPalette("Levels\\L1Data\\L1_5.pal"); + AddL1Objs(0, 0, 112, 112); + DRLG_SetMapTrans("Levels\\L1Data\\Lv1MazeA.DUN"); + break; + case SL_POISONWATER: + if(quests[Q_PWATER]._qactive == 1) { + quests[Q_PWATER]._qactive = 2; + } + LoadPreL3Dungeon("Levels\\L3Data\\Foulwatr.DUN", 19, 50); + LoadL3Dungeon("Levels\\L3Data\\Foulwatr.DUN", 20, 50); + LoadPalette("Levels\\L3Data\\L3pfoul.pal"); + InitPWaterTriggers(); + break; + case SL_VILEBETRAYER: + if(quests[Q_BETRAYER]._qactive == 3) { + quests[Q_BETRAYER]._qvar2 = 4; + } else if(quests[Q_BETRAYER]._qactive == 2) { + quests[Q_BETRAYER]._qvar2 = 3; + } + LoadPreL1Dungeon("Levels\\L1Data\\Vile1.DUN", 35, 36); + LoadL1Dungeon("Levels\\L1Data\\Vile2.DUN", 35, 36); + LoadPalette("Levels\\L1Data\\L1_2.pal"); + AddL1Objs(0, 0, 112, 112); + AddVileObjs(); + DRLG_SetMapTrans("Levels\\L1Data\\Vile1.DUN"); + InitNoTriggers(); + break; + } +} diff --git a/2020_03_31/Source/setmaps.h b/2020_03_31/Source/setmaps.h new file mode 100644 index 00000000..450d75f9 --- /dev/null +++ b/2020_03_31/Source/setmaps.h @@ -0,0 +1,22 @@ +//HEADER_GOES_HERE +#ifndef __SETMAPS_H__ +#define __SETMAPS_H__ + +int ObjIndex(int x, int y); +void AddSKingObjs(); +void AddSChamObjs(); +void AddVileObjs(); +void DRLG_SetMapTrans(char *sFileName); +void LoadSetMap(); + +/* rdata */ +extern unsigned char SkelKingTrans1[8]; +extern unsigned char SkelKingTrans2[8]; +extern unsigned char SkelKingTrans3[20]; +extern unsigned char SkelKingTrans4[28]; +extern unsigned char SkelChamTrans1[20]; +extern unsigned char SkelChamTrans2[8]; +extern unsigned char SkelChamTrans3[36]; +extern char *quest_level_names[]; + +#endif /* __SETMAPS_H__ */ diff --git a/2020_03_31/Source/sha.cpp b/2020_03_31/Source/sha.cpp new file mode 100644 index 00000000..a1197848 --- /dev/null +++ b/2020_03_31/Source/sha.cpp @@ -0,0 +1,150 @@ +#include "diablo.h" + +SHA1Context sgSHA1[3]; + +void SHA1Clear() +{ + memset(sgSHA1, 0, 0x114u); +} + +void SHA1Result(int n, char Message_Digest[SHA1HashSize]) +{ + char *v2; // eax + SHA1Context *v3; // ecx + signed int i; // edx + int v5; // esi + + v2 = Message_Digest; + if ( Message_Digest ) + { + v3 = &sgSHA1[n]; + i = 5; + do + { + v5 = v3->state[0]; + v3 = (SHA1Context *)((char *)v3 + 4); + *(_DWORD *)v2 = v5; + v2 += 4; + --i; + } + while ( i ); + } +} + +void SHA1Calculate(int n, const char *data, char Message_Digest[SHA1HashSize]) +{ + int v3; // esi + + v3 = n; + SHA1Input(&sgSHA1[n], data, 64); + if ( Message_Digest ) + SHA1Result(v3, (char *)Message_Digest); +} + +void SHA1Input(SHA1Context *context, const char *message_array, int len) +{ + SHA1Context *v3; // esi + const char *v4; // ebx + int v5; // ecx + int v6; // edx + unsigned int v7; // ebp + + v3 = context; + v4 = message_array; + v5 = context->count[0]; + v6 = v5 + 8 * len; + if ( v6 < v5 ) + ++v3->count[1]; + v3->count[0] = v6; + v3->count[1] += len >> 29; + if ( len >= 64 ) + { + v7 = (unsigned int)len >> 6; + do + { + memcpy(v3->buffer, v4, 0x40u); + SHA1ProcessMessageBlock(v3); + v4 += 64; + --v7; + } + while ( v7 ); + } +} + +void SHA1ProcessMessageBlock(SHA1Context *context) +{ + int i; // [esp+158h] [ebp-4h] + int temp; // esi + int W[80]; // [esp+Ch] [ebp-150h] + int A, B, C, D, E; // [esp+150h] [ebp-Ch] + + qmemcpy(W, context->buffer, 0x40u); + + for(i = 16; i < 80; i++) + { + W[i] = W[i-16] ^ W[i-14] ^ W[i-8] ^ W[i-3]; + } + + A = context->state[0]; + B = context->state[1]; + C = context->state[2]; + D = context->state[3]; + E = context->state[4]; + + for(i = 0; i < 20; i++) + { + temp = SHA1CircularShift(5,A) + ((B & C) | ((~B) & D)) + E + W[i] + 0x5A827999; + E = D; + D = C; + C = SHA1CircularShift(30,B); + B = A; + A = temp; + } + + for(i = 20; i < 40; i++) + { + temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[i] + 0x6ED9EBA1; + E = D; + D = C; + C = SHA1CircularShift(30,B); + B = A; + A = temp; + } + + for(i = 40; i < 60; i++) + { + temp = SHA1CircularShift(5,A) + ((B & C) | (B & D) | (C & D)) + E + W[i] + 0x8F1BBCDC; + E = D; + D = C; + C = SHA1CircularShift(30,B); + B = A; + A = temp; + } + + for(i = 60; i < 80; i++) + { + temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[i] + 0xCA62C1D6; + E = D; + D = C; + C = SHA1CircularShift(30,B); + B = A; + A = temp; + } + + context->state[0] += A; + context->state[1] += B; + context->state[2] += C; + context->state[3] += D; + context->state[4] += E; +} + +void SHA1Reset(int n) +{ + sgSHA1[n].count[0] = 0; + sgSHA1[n].count[1] = 0; + sgSHA1[n].state[0] = 0x67452301; + sgSHA1[n].state[1] = 0xEFCDAB89; + sgSHA1[n].state[2] = 0x98BADCFE; + sgSHA1[n].state[3] = 0x10325476; + sgSHA1[n].state[4] = 0xC3D2E1F0; +} diff --git a/2020_03_31/Source/sha.h b/2020_03_31/Source/sha.h new file mode 100644 index 00000000..1d635f48 --- /dev/null +++ b/2020_03_31/Source/sha.h @@ -0,0 +1,22 @@ +//HEADER_GOES_HERE +#ifndef __SHA_H__ +#define __SHA_H__ + +/* + * Define the SHA1 circular left shift macro + */ +#define SHA1CircularShift(bits,word) \ + (((word) << (bits)) | ((word) >> (32-(bits)))) +#define SHA1HashSize 20 + +//sha +extern SHA1Context sgSHA1[3]; + +void SHA1Clear(); +void SHA1Result(int n, char Message_Digest[SHA1HashSize]); +void SHA1Calculate(int n, const char *data, char Message_Digest[SHA1HashSize]); +void SHA1Input(SHA1Context *context, const char *message_array, int len); +void SHA1ProcessMessageBlock(SHA1Context *context); +void SHA1Reset(int n); + +#endif /* __SHA_H__ */ diff --git a/2020_03_31/Source/sound.cpp b/2020_03_31/Source/sound.cpp new file mode 100644 index 00000000..22c2a29e --- /dev/null +++ b/2020_03_31/Source/sound.cpp @@ -0,0 +1,509 @@ +#include "diablo.h" +#include "../3rdParty/Storm/Source/storm.h" + +IDirectSoundBuffer *DSBs[8]; +IDirectSound *sglpDS; +char gbSndInited; +long sglMusicVolume; +long sglSoundVolume; +HMODULE hDsound_dll; // idb +HANDLE sghMusic; +IDirectSoundBuffer *sglpDSB; + +/* data */ + +char gbMusicOn = 1; // weak +char gbSoundOn = 1; // weak +char gbDupSounds = 1; // weak +int sgnMusicTrack = 6; +char *sgszMusicTracks[6] = +{ + "Music\\DTowne.wav", + "Music\\DLvlA.wav", + "Music\\DLvlB.wav", + "Music\\DLvlC.wav", + "Music\\DLvlD.wav", + "Music\\Dintro.wav" +}; +char unk_volume[4][2] = +{ + { 15, -16 }, + { 15, -16 }, + { 30, -31 }, + { 30, -31 } +}; + +void snd_update(BOOL bStopAll) +{ + int i; + HRESULT hDSVal; + DWORD dwStatus; + + for(i = 0; (DWORD)i < 8; i++) { + if(DSBs[i] == NULL) { + continue; + } + if(!bStopAll) { + hDSVal = DSBs[i]->GetStatus(&dwStatus); + if(hDSVal == DS_OK && dwStatus == DSBSTATUS_PLAYING) { + continue; + } + } + DSBs[i]->Stop(); + DSBs[i]->Release(); + DSBs[i] = NULL; + } +} + +static IDirectSoundBuffer *sound_dup_channel(IDirectSoundBuffer *pDSB) +{ + int i; + HRESULT hDSVal; + + if(!gbDupSounds) { + return NULL; + } + + for(i = 0; (DWORD)i < 8; i++) { + if(DSBs[i] == NULL) { + hDSVal = sglpDS->DuplicateSoundBuffer(pDSB, &DSBs[i]); + if(hDSVal == DS_OK) { + return DSBs[i]; + } + break; + } + } + + return NULL; +} + +static void snd_get_volume(const char *pszKey, long *plVolume) +{ + DWORD dwTemp; + + dwTemp = *plVolume; + if(!SRegLoadValue("Diablo", pszKey, 0, &dwTemp)) { + dwTemp = VOLUME_MAX; + } + *plVolume = dwTemp; + + if(*plVolume < VOLUME_MIN) { + *plVolume = VOLUME_MIN; + } else if(*plVolume > VOLUME_MAX) { + *plVolume = VOLUME_MAX; + } + + *plVolume -= *plVolume % 100; +} + +static void snd_set_volume(const char *pszKey, long lVolume) +{ + SRegSaveValue("Diablo", pszKey, 0, lVolume); +} + +static BOOL sound_file_reload(TSnd *pSnd, IDirectSoundBuffer *pDSB) +{ + BOOL rv; + HRESULT hDSVal; + HANDLE hsFile; + DWORD dwAudioBytes1, dwAudioBytes2; + void *vAudioPtr1, *vAudioPtr2; + + /// ASSERT: assert(pSnd); + /// ASSERT: assert(pDSB); + + if(pDSB->Restore()) { + return FALSE; + } + + rv = FALSE; + WOpenFile(pSnd->sound_path, &hsFile, 0); + WSetFilePointer(hsFile, pSnd->chunk.dwOffset, NULL, 0); + + hDSVal = pDSB->Lock(0, pSnd->chunk.dwSize, &vAudioPtr1, &dwAudioBytes1, &vAudioPtr2, &dwAudioBytes2, 0); + if(hDSVal != DS_OK) { +#ifdef _DEBUG + DSErrMsg(hDSVal, 163, "C:\\Diablo\\Direct\\SOUND.CPP"); +#endif + } else { + WReadFile(hsFile, (char *)vAudioPtr1, dwAudioBytes1); + hDSVal = pDSB->Unlock(vAudioPtr1, dwAudioBytes1, vAudioPtr2, dwAudioBytes2); + if(hDSVal != DS_OK) { +#ifdef _DEBUG + DSErrMsg(hDSVal, 169, "C:\\Diablo\\Direct\\SOUND.CPP"); +#endif + } else { + rv = TRUE; + } + } + + WCloseFile(hsFile); + return rv; +} + +void snd_stop_snd(TSnd *pSnd) +{ + if(pSnd == NULL) { + return; + } + if(pSnd->DSB == NULL) { + return; + } + + pSnd->DSB->Stop(); +} + +BOOL snd_playing(TSnd *pSnd) +{ + HRESULT hDSVal; + DWORD dwStatus; + + if(pSnd == NULL) { + return FALSE; + } + if(pSnd->DSB == NULL) { + return FALSE; + } + + hDSVal = pSnd->DSB->GetStatus(&dwStatus); + if(hDSVal != DS_OK) { +#ifdef _DEBUG + DSErrMsg(hDSVal, 195, "C:\\Diablo\\Direct\\SOUND.CPP"); +#endif + return FALSE; + } + + return dwStatus == DSBSTATUS_PLAYING; +} + +void snd_play_snd(TSnd *pSnd, long lVolume, long lPan) +{ + DWORD dwTicks; + HRESULT hDSVal; + IDirectSoundBuffer *pDSB; + + if(pSnd == NULL) { + return; + } + if(!gbSoundOn) { + return; + } + pDSB = pSnd->DSB; + if(pDSB == NULL) { + return; + } + + dwTicks = GetTickCount(); + if(dwTicks - pSnd->start_tc < 80) { + GetTickCount(); /// BUGFIX: call has no purpose + return; + } + if(snd_playing(pSnd)) { + pDSB = sound_dup_channel(pSnd->DSB); + if(pDSB == NULL) { + return; + } + } + + lVolume += sglSoundVolume; + if(lVolume < VOLUME_MIN) { + lVolume = VOLUME_MIN; + } else if(lVolume > VOLUME_MAX) { + lVolume = VOLUME_MAX; + } + + hDSVal = pDSB->SetVolume(lVolume); +#ifdef _DEBUG + if(hDSVal != DS_OK) { + DSErrMsg(hDSVal, 235, "C:\\Diablo\\Direct\\SOUND.CPP"); + } +#endif + hDSVal = pDSB->SetPan(lPan); +#ifdef _DEBUG + if(hDSVal != DS_OK) { + DSErrMsg(hDSVal, 238, "C:\\Diablo\\Direct\\SOUND.CPP"); + } +#endif + + hDSVal = pDSB->Play(0, 0, 0); + if(hDSVal != DSERR_BUFFERLOST) { + if(hDSVal != DS_OK) { + DSErrMsg(hDSVal, 261, "C:\\Src\\Diablo\\Source\\SOUND.CPP"); + } + } else if(sound_file_reload(pSnd, pDSB)) { + hDSVal = pDSB->Play(0, 0, 0); + } + + pSnd->start_tc = dwTicks; +} + +static void sound_CreateSoundBuffer(TSnd *pSnd) +{ + HRESULT hDSVal; + DSBUFFERDESC dsbd; + + /// ASSERT: assert(sglpDS); + + memset(&dsbd, 0, sizeof(dsbd)); + dsbd.dwSize = sizeof(dsbd); + dsbd.dwFlags = DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLPAN | DSBCAPS_STATIC; + dsbd.dwBufferBytes = pSnd->chunk.dwSize; + dsbd.lpwfxFormat = &pSnd->fmt; + + hDSVal = sglpDS->CreateSoundBuffer(&dsbd, &pSnd->DSB, NULL); + if(hDSVal != DS_OK) { + DSErrMsg(hDSVal, 282, "C:\\Src\\Diablo\\Source\\SOUND.CPP"); + } +} + +TSnd *sound_file_load(const char *pszFile) +{ + HRESULT hDSVal; + HANDLE hsFile; + DWORD dwAudioBytes1, dwAudioBytes2; + void *vAudioPtr1, *vAudioPtr2; + TSnd *pSnd; + BYTE *p; + + if(sglpDS == NULL) { + return NULL; + } + + WOpenFile((char *)pszFile, &hsFile, 0); + + pSnd = (TSnd *)DiabloAllocPtr(sizeof(*pSnd)); + memset(pSnd, 0, sizeof(*pSnd)); + pSnd->sound_path = (char *)pszFile; + pSnd->start_tc = GetTickCount() - 81; + + p = (BYTE *)LoadWaveFile(hsFile, &pSnd->fmt, &pSnd->chunk); + if(p == NULL) { + app_fatal("Invalid sound format on file %s", pSnd->sound_path); + } + + sound_CreateSoundBuffer(pSnd); + + hDSVal = pSnd->DSB->Lock(0, pSnd->chunk.dwSize, &vAudioPtr1, &dwAudioBytes1, &vAudioPtr2, &dwAudioBytes2, 0); + if(hDSVal != DS_OK) { + DSErrMsg(hDSVal, 318, "C:\\Src\\Diablo\\Source\\SOUND.CPP"); + } + + memcpy(vAudioPtr1, &p[pSnd->chunk.dwOffset], dwAudioBytes1); + + hDSVal = pSnd->DSB->Unlock(vAudioPtr1, dwAudioBytes1, vAudioPtr2, dwAudioBytes2); + if(hDSVal != DS_OK) { + DSErrMsg(hDSVal, 325, "C:\\Src\\Diablo\\Source\\SOUND.CPP"); + } + + MemFreeDbg(p); + WCloseFile(hsFile); + return pSnd; +} + +void sound_file_cleanup(TSnd *pSnd) +{ + if(pSnd != NULL) { + if(pSnd->DSB != NULL) { + pSnd->DSB->Stop(); + pSnd->DSB->Release(); + pSnd->DSB = NULL; + } + MemFreeDbg(pSnd); + } +} + +static void sound_create_primary_buffer(HANDLE hMusic) +{ + HRESULT hDSVal; + DSCAPS caps; + DSBUFFERDESC dsbd; + WAVEFORMATEX fmt; + + /// ASSERT: assert(sglpDS); + + if(hMusic == NULL) { + memset(&dsbd, 0, sizeof(dsbd)); + dsbd.dwSize = sizeof(dsbd); + dsbd.dwFlags = DSBCAPS_PRIMARYBUFFER; + hDSVal = sglpDS->CreateSoundBuffer(&dsbd, &sglpDSB, NULL); + if(hDSVal != DS_OK) { + DSErrMsg(hDSVal, 375, "C:\\Src\\Diablo\\Source\\SOUND.CPP"); + } + } + + if(sglpDSB == NULL) { + return; + } + + caps.dwSize = sizeof(caps); + hDSVal = sglpDS->GetCaps(&caps); + if(hDSVal != DS_OK) { + DSErrMsg(hDSVal, 383, "C:\\Src\\Diablo\\Source\\SOUND.CPP"); + } + + if(hMusic == NULL || !LoadWaveFormat(hMusic, &fmt)) { + memset(&fmt, 0, sizeof(fmt)); + fmt.wFormatTag = WAVE_FORMAT_PCM; + fmt.nSamplesPerSec = 22050; + fmt.wBitsPerSample = 16; + fmt.nChannels = 2; + fmt.cbSize = 0; + } + fmt.nChannels = 2; + fmt.nBlockAlign = fmt.nChannels * fmt.wBitsPerSample / 8; + fmt.nAvgBytesPerSec = fmt.nSamplesPerSec * fmt.nBlockAlign; + hDSVal = sglpDSB->SetFormat(&fmt); +#ifdef _DEBUG + if(hDSVal != DS_OK && hDSVal != DSERR_BADFORMAT) { + if(hDSVal != DS_OK) { + DSErrMsg(hDSVal, 383, "C:\\Diablo\\Direct\\SOUND.CPP"); + } + } +#endif +} + +static HRESULT sound_DirectSoundCreate(GUID FAR *lpGUID, LPDIRECTSOUND FAR *lplpDS, IUnknown FAR *pUnkOuter) +{ + DSCREATEPROC dscp; + + if(hDsound_dll == NULL) { + hDsound_dll = LoadLibrary("dsound.dll"); + if(hDsound_dll == NULL) { + ErrDlg(IDD_DIALOG5, GetLastError(), "C:\\Src\\Diablo\\Source\\SOUND.CPP", 422); + } + } + dscp = (DSCREATEPROC)GetProcAddress(hDsound_dll, "DirectSoundCreate"); + if(dscp == NULL) { + ErrDlg(IDD_DIALOG5, GetLastError(), "C:\\Src\\Diablo\\Source\\SOUND.CPP", 427); + } + + return dscp(lpGUID, lplpDS, pUnkOuter); +} + +void snd_init(HWND hWnd) +{ + HRESULT hDSVal; + BOOL bSuccess; + + snd_get_volume("Sound Volume", &sglSoundVolume); + gbSoundOn = sglSoundVolume > VOLUME_MIN; + snd_get_volume("Music Volume", &sglMusicVolume); + gbMusicOn = sglMusicVolume > VOLUME_MIN; + + /// ASSERT: assert(! sglpDS); + hDSVal = sound_DirectSoundCreate(NULL, &sglpDS, NULL); + if(hDSVal != DS_OK) { + sglpDS = NULL; + } + if(sglpDS != NULL && sglpDS->SetCooperativeLevel(hWnd, DSSCL_EXCLUSIVE) == DS_OK) { + sound_create_primary_buffer(NULL); + } + + bSuccess = SVidInitialize(sglpDS); + /// ASSERT: assert(! sglpDS || bSuccess); + + bSuccess = SFileDdaInitialize(sglpDS); + /// ASSERT: assert(! sglpDS || bSuccess); + + gbSndInited = sglpDS != NULL; +} + +void sound_cleanup() +{ + snd_update(TRUE); + SVidDestroy(); + SFileDdaDestroy(); + + if(sglpDS != NULL) { + sglpDS->Release(); + sglpDS = NULL; + } + if(gbSndInited) { + gbSndInited = 0; + snd_set_volume("Sound Volume", sglSoundVolume); + snd_set_volume("Music Volume", sglMusicVolume); + } +} + +void music_stop() +{ + if(sghMusic != NULL) { + SFileDdaEnd(sghMusic); + SFileCloseFile(sghMusic); + sghMusic = NULL; + sgnMusicTrack = NUM_MUSIC; + } +} + +void music_start(int nTrack) +{ + BOOL bSuccess; + + /// ASSERT: assert((DWORD) nTrack < NUM_MUSIC); + + music_stop(); + + if(sglpDS == NULL) { + return; + } + if(!gbMusicOn) { + return; + } + +#ifdef _DEBUG + SFileEnableDirectAccess(FALSE); +#endif + bSuccess = SFileOpenFile(sgszMusicTracks[nTrack], &sghMusic); +#ifdef _DEBUG + SFileEnableDirectAccess(TRUE); +#endif + + sound_create_primary_buffer(sghMusic); + + if(!bSuccess) { + sghMusic = NULL; + return; + } + + SFileDdaBeginEx(sghMusic, 0x40000, 0x40000, 0, sglMusicVolume, 0, 0); + sgnMusicTrack = nTrack; +} + +void sound_disable_music(BOOL disable) +{ + if(disable) { + music_stop(); + } else if(sgnMusicTrack != NUM_MUSIC) { + music_start(sgnMusicTrack); + } +} + +long sound_get_or_set_music_volume(long lVolume) +{ + if(lVolume == 1) { + return sglMusicVolume; + } + + /// ASSERT: assert(lVolume >= VOLUME_MIN); + /// ASSERT: assert(lVolume <= VOLUME_MAX); + sglMusicVolume = lVolume; + + if(sghMusic != NULL) { + SFileDdaSetVolume(sghMusic, sglMusicVolume, 0); + } + + return sglMusicVolume; +} + +long sound_get_or_set_sound_volume(long lVolume) +{ + if(lVolume == 1) { + return sglSoundVolume; + } + + /// ASSERT: assert(lVolume >= VOLUME_MIN); + /// ASSERT: assert(lVolume <= VOLUME_MAX); + sglSoundVolume = lVolume; + + return sglSoundVolume; +} diff --git a/2020_03_31/Source/sound.h b/2020_03_31/Source/sound.h new file mode 100644 index 00000000..53b59115 --- /dev/null +++ b/2020_03_31/Source/sound.h @@ -0,0 +1,37 @@ +//HEADER_GOES_HERE +#ifndef __SOUND_H__ +#define __SOUND_H__ + +extern IDirectSoundBuffer *DSBs[8]; +extern IDirectSound *sglpDS; +extern char gbSndInited; +extern long sglMusicVolume; +extern long sglSoundVolume; +extern HMODULE hDsound_dll; // idb +extern HANDLE sghMusic; +extern IDirectSoundBuffer *sglpDSB; + +void snd_update(BOOL bStopAll); +void snd_stop_snd(TSnd *pSnd); +BOOL snd_playing(TSnd *pSnd); +void snd_play_snd(TSnd *pSnd, long lVolume, long lPan); +TSnd *sound_file_load(const char *pszFile); +void sound_file_cleanup(TSnd *pSnd); +void snd_init(HWND hWnd); +void sound_cleanup(); +void music_stop(); +void music_start(int nTrack); +void sound_disable_music(BOOL disable); +long sound_get_or_set_music_volume(long lVolume); +long sound_get_or_set_sound_volume(long lVolume); + +/* data */ + +extern char gbMusicOn; // weak +extern char gbSoundOn; // weak +extern char gbDupSounds; // weak +extern int sgnMusicTrack; +extern char *sgszMusicTracks[6]; +extern char unk_volume[4][2]; + +#endif /* __SOUND_H__ */ diff --git a/2020_03_31/Source/spelldat.cpp b/2020_03_31/Source/spelldat.cpp new file mode 100644 index 00000000..11706607 --- /dev/null +++ b/2020_03_31/Source/spelldat.cpp @@ -0,0 +1,6 @@ +#include "diablo.h" + +SpellData spelldata[37] = +{ +#include "Data/xl_spell.cpp" +}; diff --git a/2020_03_31/Source/spelldat.h b/2020_03_31/Source/spelldat.h new file mode 100644 index 00000000..c7ab7f6d --- /dev/null +++ b/2020_03_31/Source/spelldat.h @@ -0,0 +1,7 @@ +//HEADER_GOES_HERE +#ifndef __SPELLDAT_H__ +#define __SPELLDAT_H__ + +extern SpellData spelldata[37]; + +#endif /* __SPELLDAT_H__ */ diff --git a/2020_03_31/Source/spells.cpp b/2020_03_31/Source/spells.cpp new file mode 100644 index 00000000..cbaaa08f --- /dev/null +++ b/2020_03_31/Source/spells.cpp @@ -0,0 +1,265 @@ +#include "diablo.h" + +int GetManaAmount(int id, int sn) +{ + int i, sl, ma, adj; + + adj = 0; + sl = plr[id]._pSplLvl[sn] + plr[id]._pISplLvlAdd - 1; + if(sl < 0) { + sl = 0; + } + + for(i = sl; i > 0; i--) { + adj += spelldata[sn].sManaAdj; + } + + if(sn == SPL_FIREBOLT) { + adj >>= 1; + } + if(sn == SPL_RESURRECT && sl > 0) { + adj = 0; + for(i = sl; i > 0; i--) { + adj += spelldata[SPL_RESURRECT].sManaCost >> 3; + } + } + + if(spelldata[sn].sManaCost == 255) { + ma = ((BYTE)plr[id]._pMaxManaBase - adj) << 6; + } else { + ma = (spelldata[sn].sManaCost - adj) << 6; + } + + if(sn == SPL_HEAL) { + ma = (spelldata[SPL_HEAL].sManaCost + 2 * plr[id]._pLevel - adj) << 6; + } + if(sn == SPL_HEALOTHER) { + ma = (spelldata[SPL_HEAL].sManaCost + 2 * plr[id]._pLevel - adj) << 6; + } + if(sn == SPL_RESURRECT) { /// BUGFIX: optimized away, 'adj' has no purpose now + adj = 0; + for(i = sl; i > 0; i--) { + adj += spelldata[SPL_RESURRECT].sManaCost; + } + } + + if(plr[id]._pClass == PC_ROGUE) { + ma -= ma >> 2; + } + if(spelldata[sn].sMinMana > ma >> 6) { + ma = spelldata[sn].sMinMana << 6; + } + + ma = ma * (100 - plr[id]._pISplCost) / 100; + return ma; +} + +void UseMana(int id, int sn) +{ + int ma; + + if(id != myplr) { + return; + } + + switch(plr[id]._pSplType) { + case RSPLTYPE_SKILL: + case RSPLTYPE_INVALID: + break; + case RSPLTYPE_SCROLL: + RemoveScroll(id); + break; + case RSPLTYPE_CHARGES: + UseStaffCharge(id); + break; + case RSPLTYPE_SPELL: +#ifdef _DEBUG + if(debug_mode_key_inverted_v) { + break; + } +#endif + ma = GetManaAmount(id, sn); + plr[id]._pMana -= ma; + plr[id]._pManaBase -= ma; + drawmanaflag = 1; + break; + } +} + +BOOL CheckSpell(int id, int sn, char st, BOOL manaonly) +{ + int ma; + +#ifdef _DEBUG + if(debug_mode_key_inverted_v) { + return TRUE; + } +#endif + if(!manaonly && pcurs != CURSOR_HAND) { + return FALSE; + } + if(st == RSPLTYPE_SKILL) { + return TRUE; + } + if(GetSpellLevel(id, sn) <= 0) { + return FALSE; + } + ma = GetManaAmount(id, sn); + if(plr[id]._pMana < ma) { + return FALSE; + } + + return TRUE; +} + +void CastSpell(int id, int spl, int sx, int sy, int dx, int dy, int caster, int spllvl) +{ + int i, dir; + + switch(caster) { + case 0: + dir = plr[id]._pdir; + caster = 0; + if(spl == SPL_FIREWALL) { + dir = plr[id]._pVar3; + } + break; + case 1: + dir = monster[id]._mdir; + break; + } + + for(i = 0; spelldata[spl].sMissiles[i] != 0 && i < 3; i++) { + AddMissile(sx, sy, dx, dy, dir, spelldata[spl].sMissiles[i], caster, id, 0, spllvl); + } + + if(spelldata[spl].sMissiles[0] == MIS_TOWN) { + UseMana(id, SPL_TOWN); + } + if(spelldata[spl].sMissiles[0] == MIS_CBOLT) { + UseMana(id, SPL_CBOLT); + for(i = (spllvl >> 1) + 3; i > 0; i--) { + AddMissile(sx, sy, dx, dy, dir, MIS_CBOLT, caster, id, 0, spllvl); + } + } +} + +static void PlacePlayer(int pnum) +{ + int i, j, l, xx, yy; + BOOL done; + + if(plr[pnum].plrlevel != currlevel) { + return; + } + + for(i = 0; (DWORD)i < 8; i++) { + xx = plr[pnum].WorldX + plrxoff2[i]; + yy = plr[pnum].WorldY + plryoff2[i]; + if(PosOkPlayer(pnum, xx, yy)) { + break; + } + } + + if(!PosOkPlayer(pnum, xx, yy)) { + done = FALSE; + for(l = 1; l < 50 && !done; l++) { + for(j = -l; j <= l && !done; j++) { + yy = j + plr[pnum].WorldY; + for(i = -l; i <= l && !done; i++) { + xx = i + plr[pnum].WorldX; + if(PosOkPlayer(pnum, xx, yy)) { + done = TRUE; + } + } + } + } + } + + plr[pnum].WorldX = xx; + plr[pnum].WorldY = yy; + dPlayer[xx][yy] = pnum + 1; + + if(pnum == myplr) { + ViewX = xx; + ViewY = yy; + } +} + +void DoResurrect(int pnum, int rid) +{ + int hp; + + if((BYTE)rid != 255) { + AddMissile(plr[rid].WorldX, plr[rid].WorldY, plr[rid].WorldX, plr[rid].WorldY, 0, MIS_RESURRECTBEAM, 0, pnum, 0, 0); + } + if(pnum == myplr) { + SetCursor_(CURSOR_HAND); + } + if((BYTE)rid != 255) { + if(plr[rid]._pHitPoints != 0) { + return; + } + if(rid == myplr) { + deathflag = 0; + gamemenu_off(); + drawhpflag = 1; + drawmanaflag = 1; + } + ClrPlrPath(rid); + plr[rid].destAction = -1; + plr[rid]._pInvincible = 0; + PlacePlayer(rid); + hp = 640; + if(plr[rid]._pMaxHPBase < hp) { + hp = plr[rid]._pMaxHPBase; + } + SetPlayerHitPoints(rid, hp); + plr[rid]._pHPBase = plr[rid]._pHitPoints - (plr[rid]._pMaxHP - plr[rid]._pMaxHPBase); + plr[rid]._pMana = 0; + plr[rid]._pManaBase = plr[rid]._pMana - (plr[rid]._pMaxMana - plr[rid]._pMaxManaBase); + CalcPlrInv(rid, TRUE); + if(plr[rid].plrlevel == currlevel) { + StartStand(rid, plr[rid]._pdir); + } else { + plr[rid]._pmode = PM_STAND; + } + } +} + +void DoHealOther(int pnum, int rid) +{ + int i; + long l; + + if(pnum == myplr) { + SetCursor_(CURSOR_HAND); + } + if((BYTE)rid != 255) { + if(plr[rid]._pHitPoints >> 6 <= 0) { + return; + } + l = (random(57, 10) + 1) << 6; + for(i = 0; i < plr[pnum]._pLevel; i++) { + l += (random(57, 4) + 1) << 6; + } + for(i = 0; i < GetSpellLevel(pnum, SPL_HEALOTHER); i++) { + l += (random(57, 6) + 1) << 6; + } + if(plr[pnum]._pClass == PC_WARRIOR) { + l <<= 1; + } + if(plr[pnum]._pClass == PC_ROGUE) { + l += l >> 1; + } + plr[rid]._pHitPoints += l; + if(plr[rid]._pHitPoints > plr[rid]._pMaxHP) { + plr[rid]._pHitPoints = plr[rid]._pMaxHP; + } + plr[rid]._pHPBase += l; + if(plr[rid]._pHPBase > plr[rid]._pMaxHPBase) { + plr[rid]._pHPBase = plr[rid]._pMaxHPBase; + } + drawhpflag = 1; + } +} diff --git a/2020_03_31/Source/spells.h b/2020_03_31/Source/spells.h new file mode 100644 index 00000000..37d50ba1 --- /dev/null +++ b/2020_03_31/Source/spells.h @@ -0,0 +1,12 @@ +//HEADER_GOES_HERE +#ifndef __SPELLS_H__ +#define __SPELLS_H__ + +int GetManaAmount(int id, int sn); +void UseMana(int id, int sn); +BOOL CheckSpell(int id, int sn, char st, BOOL manaonly); +void CastSpell(int id, int spl, int sx, int sy, int dx, int dy, int caster, int spllvl); +void DoResurrect(int pnum, int rid); +void DoHealOther(int pnum, int rid); + +#endif /* __SPELLS_H__ */ diff --git a/2020_03_31/Source/stores.cpp b/2020_03_31/Source/stores.cpp new file mode 100644 index 00000000..cedf4e88 --- /dev/null +++ b/2020_03_31/Source/stores.cpp @@ -0,0 +1,3111 @@ +#include "diablo.h" + +int stextup; // weak +int storenumh; // weak +int stextlhold; // weak +ItemStruct boyitem; +int stextshold; // idb +ItemStruct premiumitem[6]; +void *pSTextBoxCels; +int premiumlevel; // idb +int talker; // weak +STextStruct stext[24]; +char stextsize; // weak +int stextsmax; // weak +int sspinframe; // idb +ItemStruct storehold[48]; +int gossipstart; // weak +ItemStruct witchitem[20]; +BOOL stextscrl; // weak +int numpremium; // idb +ItemStruct healitem[20]; +ItemStruct golditem; +char storehidx[48]; +void *pSTextSlidCels; +int stextvhold; // weak +int stextsel; // weak +char stextscrldbtn; // weak +int gossipend; // weak +void *pSPentSpnCels; +int stextsval; // idb +int boylevel; // weak +ItemStruct smithitem[20]; +int stextdown; // weak +char stextscrlubtn; // weak +char stextflag; // weak + +int SStringY[24] = +{ + 0, + 12, + 24, + 36, + 48, + 60, + 72, + 84, + 96, + 108, + 120, + 132, + 144, + 156, + 168, + 180, + 192, + 204, + 216, + 228, + 240, + 252, + 264, + 276 +}; +char *talkname[9] = +{ + "Griswold", + "Pepin", + "", + "Ogden", + "Cain", + "Farnham", + "Adria", + "Gillian", + "Wirt" +}; + +void InitStores() +{ + int i; + + /// ASSERT: assert(! pSTextBoxCels); + pSTextBoxCels = DiabLoad("Data\\TextBox2.CEL", NULL, 'STOR'); + pSPentSpnCels = DiabLoad("Data\\PentSpn2.CEL", NULL, 'STOR'); + pSTextSlidCels = DiabLoad("Data\\TextSlid.CEL", NULL, 'STOR'); + + ClearSText(0, 24); + + stextflag = 0; + sspinframe = 1; + stextsize = 0; + stextscrl = FALSE; + numpremium = 0; + premiumlevel = 1; + + for(i = 0; i < 6; i++) { + premiumitem[i]._itype = -1; + } + + boyitem._itype = -1; + boylevel = 0; +} + +void SetupTownStores() +{ + int i, l; + + SetRndSeed(glSeedTbl[currlevel] * GetTickCount()); + + if(gbMaxPlayers == 1) { + l = 0; + for(i = 0; i < NUMLEVELS; i++) { + if(plr[myplr]._pLvlVisited[i]) { + l = i; + } + } + } else { + l = plr[myplr]._pLevel >> 1; + } + + l += 2; + if(l < 6) { + l = 6; + } + if(l > 16) { + l = 16; + } + + SpawnStoreGold(); + SpawnSmith(l); + SpawnWitch(l); + SpawnHealer(l); + SpawnBoy(plr[myplr]._pLevel); + SpawnPremium(plr[myplr]._pLevel); +} + +void FreeStoreMem() +{ + MemFreeDbg(pSTextBoxCels); + MemFreeDbg(pSPentSpnCels); + MemFreeDbg(pSTextSlidCels); +} + +void DrawSTextBack() +{ + CelDecodeOnly(408, 487, (BYTE *)pSTextBoxCels, 1, 271); + + /// ASSERT: assert(gpBuffer); + +#ifdef USE_ASM + __asm { + mov edi, gpBuffer + add edi, SCREENXY(347, 324) + xor eax, eax + mov edx, 297 / 2 + label1: + mov ecx, 265 / 2 + label2: + stosb + inc edi + loop label2 + stosb + sub edi, 768 + 265 + mov ecx, 265 / 2 + label3: + inc edi + stosb + loop label3 + sub edi, 768 + (265 - 1) + dec edx + jnz label1 + mov ecx, 265 / 2 + label4: + stosb + inc edi + loop label4 + stosb + } +#else + int wdt, hgt; + BYTE *dst; + + dst = &gpBuffer[SCREENXY(347, 324)]; + + for(hgt = 297 / 2; hgt != 0; hgt--) { + for(wdt = 265 / 2; wdt != 0; wdt--) { + dst[0] = 0; + dst += 2; + } + *dst = 0; + dst -= 768 + (265 - 1); + for(wdt = 265 / 2; wdt != 0; wdt--) { + dst[1] = 0; + dst += 2; + } + dst -= 768 + (265 - 1); + } + for(wdt = 265 / 2; wdt != 0; wdt--) { + dst[0] = 0; + dst += 2; + } + *dst = 0; +#endif +} + +void PrintSString(int x, int y, BOOL cjustflag, char *str, char col, int val) +{ + int i, l, xx, yy, w, width, No, justw, sx; + BYTE c; + char valstr[32]; + + yy = SStringY[y] + stext[y]._syoff; + + if(stextsize == 0) { + xx = 416; + } else { + xx = 96; + } + + No = x + xx + PitchTbl[yy + 204]; + l = strlen(str); + + if(stextsize == 0) { + width = 257; + } else { + width = 577; + } + + w = 0; + if(cjustflag) { + justw = 0; + for(i = 0; i < l; i++) { + c = gbFontTransTbl[(BYTE)str[i]]; + c = fontframe[c]; + justw += fontkern[c] + 1; + } + if(justw < width) { + w = (width - justw) >> 1; + } + No += w; + } + if(stextsel == y) { + if(cjustflag) { + sx = xx + w + x - 20; + } else { + sx = xx + x - 20; + } + CelDecodeOnly(sx, yy + 205, (BYTE *)pSPentSpnCels, sspinframe, 12); + } + + for(i = 0; i < l; i++) { + c = gbFontTransTbl[(BYTE)str[i]]; + c = fontframe[c]; + w += fontkern[c] + 1; + if(c != 0 && w <= width) { + PrintChar(No, c, col); + } + No += fontkern[c] + 1; + } + + if(!cjustflag && val >= 0) { + sprintf(valstr, "%i", val); + No = 656 - x + PitchTbl[yy + 204]; + l = strlen(valstr); + for(i = l - 1; i >= 0; i--) { + c = gbFontTransTbl[(BYTE)valstr[i]]; + c = fontframe[c]; + No -= fontkern[c] + 1; + if(c != 0) { + PrintChar(No, c, col); + } + } + } + if(stextsel == y) { + if(cjustflag) { + sx = xx + w + x + 4; + } else { + sx = 660 - x; + } + CelDecodeOnly(sx, yy + 205, (BYTE *)pSPentSpnCels, sspinframe, 12); + } +} + +void DrawSLine(int y) +{ + int yy, nSrcOff, nDstOff, width, line; + + yy = SStringY[y]; + + if(stextsize == 1) { + nSrcOff = SCREENXY(26, 25); + nDstOff = 26 + 64 + PitchTbl[yy + 198]; + width = 586 / 4; + line = 768 - 586; + } else { + nSrcOff = SCREENXY(346, 25); + nDstOff = 346 + 64 + PitchTbl[yy + 198]; + width = 266 / 4; + line = 768 - 266; + } + + /// ASSERT: assert(gpBuffer); + +#ifdef USE_ASM + __asm { + mov esi, gpBuffer + mov edi, esi + add esi, nSrcOff + add edi, nDstOff + mov ebx, line + mov edx, 3 + copyline: + mov ecx, width + rep movsd + movsw + add esi, ebx + add edi, ebx + dec edx + jnz copyline + } +#else + int i; + BYTE *src, *dst; + + src = &gpBuffer[nSrcOff]; + dst = &gpBuffer[nDstOff]; + + for(i = 0; i < 3; i++, src += 768, dst += 768) { + memcpy(dst, src, 768 - line); + } +#endif +} + +void DrawSSlider(int y1, int y2) +{ + int uy, dy, i, base_y, bar_y; + + uy = SStringY[y1] + 204; + dy = SStringY[y2] + 204; + + if(stextscrlubtn != -1) { + CelDecodeOnly(665, uy, (BYTE *)pSTextSlidCels, 12, 12); + } else { + CelDecodeOnly(665, uy, (BYTE *)pSTextSlidCels, 10, 12); + } + if(stextscrldbtn != -1) { + CelDecodeOnly(665, dy, (BYTE *)pSTextSlidCels, 11, 12); + } else { + CelDecodeOnly(665, dy, (BYTE *)pSTextSlidCels, 9, 12); + } + + for(i = uy + 12; i < dy; i += 12) { + CelDecodeOnly(665, i, (BYTE *)pSTextSlidCels, 14, 12); + } + + if(stextsel != 22) { + base_y = stextsel; + } else { + base_y = stextlhold; + } + if(storenumh > 1) { + bar_y = stextsval + ((base_y - stextup) >> 2); + bar_y *= 1000; + bar_y /= storenumh - 1; + bar_y *= SStringY[y2] - SStringY[y1] - 24; + bar_y /= 1000; + } else { + bar_y = 0; + } + bar_y += SStringY[y1 + 1] + 204; + CelDecodeOnly(665, bar_y, (BYTE *)pSTextSlidCels, 13, 12); +} + +void DrawSTextHelp() +{ + stextsize = 1; + stextsel = -1; +} + +void ClearSText(int s, int e) +{ + int i; + + for(i = s; i < e; i++) { + stext[i]._sx = 0; + stext[i]._syoff = 0; + stext[i]._sstr[0] = '\0'; + stext[i]._sjust = 0; + stext[i]._sclr = 0; + stext[i]._sline = 0; + stext[i]._ssel = FALSE; + stext[i]._sval = -1; + } +} + +void AddSLine(int y) +{ + stext[y]._sx = 0; + stext[y]._syoff = 0; + stext[y]._sstr[0] = '\0'; + stext[y]._sline = 1; +} + +void AddSTextVal(int y, int val) +{ + stext[y]._sval = val; +} + +void OffsetSTextY(int y, int yo) +{ + stext[y]._syoff = yo; +} + +void AddSText(int x, int y, BOOL j, char *str, char clr, BOOL sel) +{ + stext[y]._sx = x; + stext[y]._syoff = 0; + strcpy(stext[y]._sstr, str); + stext[y]._sjust = j; + stext[y]._sclr = clr; + stext[y]._sline = 0; + stext[y]._ssel = sel; +} + +void StoreAutoPlace() +{ + int i, w, h, idx; + BOOL done; + + SetICursor(plr[myplr].HoldItem._iCurs + 12); + + done = FALSE; + w = icursW28; + h = icursH28; + if(w == 1 && h == 1) { + idx = plr[myplr].HoldItem.IDidx; + if(plr[myplr].HoldItem._iStatFlag && AllItemsList[idx].iUsable) { + for(i = 0; i < 8 && !done; i++) { + if(plr[myplr].SpdList[i]._itype == -1) { + plr[myplr].SpdList[i] = plr[myplr].HoldItem; + done = TRUE; + } + } + } + for(i = 30; i <= 39 && !done; i++) { + done = AutoPlace(myplr, i, w, h, TRUE); + } + for(i = 20; i <= 29 && !done; i++) { + done = AutoPlace(myplr, i, w, h, TRUE); + } + for(i = 10; i <= 19 && !done; i++) { + done = AutoPlace(myplr, i, w, h, TRUE); + } + for(i = 0; i <= 9 && !done; i++) { + done = AutoPlace(myplr, i, w, h, TRUE); + } + } + if(w == 1 && h == 2) { + for(i = 29; i >= 20 && !done; i--) { + done = AutoPlace(myplr, i, w, h, TRUE); + } + for(i = 9; i >= 0 && !done; i--) { + done = AutoPlace(myplr, i, w, h, TRUE); + } + for(i = 19; i >= 10 && !done; i--) { + done = AutoPlace(myplr, i, w, h, TRUE); + } + } + if(w == 1 && h == 3) { + for(i = 0; i < 20 && !done; i++) { + done = AutoPlace(myplr, i, w, h, TRUE); + } + } + if(w == 2 && h == 2) { + for(i = 0; i < 10 && !done; i++) { + done = AutoPlace(myplr, AP2x2Tbl[i], w, h, TRUE); + } + for(i = 21; i < 29 && !done; i += 2) { + done = AutoPlace(myplr, i, w, h, TRUE); + } + for(i = 1; i < 9 && !done; i += 2) { + done = AutoPlace(myplr, i, w, h, TRUE); + } + for(i = 10; i < 19 && !done; i++) { + done = AutoPlace(myplr, i, w, h, TRUE); + } + } + if(w == 2 && h == 3) { + for(i = 0; i < 9 && !done; i++) { + done = AutoPlace(myplr, i, w, h, TRUE); + } + for(i = 10; i < 19 && !done; i++) { + done = AutoPlace(myplr, i, w, h, TRUE); + } + } +} + +void S_StartSmith() +{ + stextsize = 0; + stextscrl = FALSE; + + AddSText(0, 1, TRUE, "Welcome to the", COL_GOLD, FALSE); + AddSText(0, 3, TRUE, "Blacksmith's shop", COL_GOLD, FALSE); + AddSText(0, 7, TRUE, "Would you like to:", COL_GOLD, FALSE); + AddSText(0, 10, TRUE, "Talk to Griswold", COL_BLUE, TRUE); + AddSText(0, 12, TRUE, "Buy basic items", COL_WHITE, TRUE); + AddSText(0, 14, TRUE, "Buy premium items", COL_WHITE, TRUE); + AddSText(0, 16, TRUE, "Sell items", COL_WHITE, TRUE); + AddSText(0, 18, TRUE, "Repair items", COL_WHITE, TRUE); + AddSText(0, 20, TRUE, "Leave the shop", COL_WHITE, TRUE); + AddSLine(5); + + storenumh = 20; +} + +void S_ScrollSBuy(int idx) +{ + int l, ls; + char iclr; + + ClearSText(5, 21); + + stextup = 5; + + for(l = 5; l < 20; l += 4) { + if(smithitem[idx]._itype != -1) { + ls = l; + iclr = COL_WHITE; + if(smithitem[idx]._iMagical != 0) { + iclr = COL_BLUE; + } + if(!smithitem[idx]._iStatFlag) { + iclr = COL_RED; + } + if(smithitem[idx]._iMagical != 0) { + AddSText(20, l, FALSE, smithitem[idx]._iIName, iclr, TRUE); + } else { + AddSText(20, l, FALSE, smithitem[idx]._iName, iclr, TRUE); + } + AddSTextVal(l, smithitem[idx]._iIvalue); + PrintStoreItem(&smithitem[idx], l + 1, iclr); + stextdown = ls; + idx++; + } + } + + if(!stext[stextsel]._ssel && stextsel != 22) { + stextsel = stextdown; + } +} + +void PrintStoreItem(const ItemStruct *x, int l, char iclr) +{ + char sstr[128]; + + sstr[0] = '\0'; + if(x->_iIdentified) { + if(x->_iMagical != 2 && x->_iPrePower != -1) { + PrintItemPower(x->_iPrePower, x); + strcat(sstr, tempstr); + } + if(x->_iSufPower != -1) { + PrintItemPower(x->_iSufPower, x); + if(sstr[0] != '\0') { + strcat(sstr, ", "); + } + strcat(sstr, tempstr); + } + } + if(x->_iMiscId == IMISC_STAFF && x->_iMaxCharges != 0) { + sprintf(tempstr, "Charges: %i/%i", x->_iCharges, x->_iMaxCharges); + if(sstr[0] != '\0') { + strcat(sstr, ", "); + } + strcat(sstr, tempstr); + } + if(sstr[0] != '\0') { + AddSText(40, l, FALSE, sstr, iclr, FALSE); + l++; + } + + sstr[0] = '\0'; + if(x->_iClass == ICLASS_WEAPON) { + sprintf(sstr, "Damage: %i-%i ", x->_iMinDam, x->_iMaxDam); + } + if(x->_iClass == ICLASS_ARMOR) { + sprintf(sstr, "Armor: %i ", x->_iAC); + } + if(x->_iMaxDur == 255 || x->_iMaxDur == 0) { + strcat(sstr, "Indestructible, "); + } else { + sprintf(tempstr, "Dur: %i/%i, ", x->_iDurability, x->_iMaxDur); + strcat(sstr, tempstr); + } + if(x->_itype == ITYPE_MISC) { + sstr[0] = '\0'; + } + if(!(x->_iMinStr + x->_iMinMag + x->_iMinDex)) { + strcat(sstr, "No required attributes"); + } else { + strcpy(tempstr, "Required:"); + if(x->_iMinStr != 0) { + sprintf(tempstr, "%s %i Str", tempstr, x->_iMinStr); + } + if(x->_iMinMag != 0) { + sprintf(tempstr, "%s %i Mag", tempstr, x->_iMinMag); + } + if(x->_iMinDex != 0) { + sprintf(tempstr, "%s %i Dex", tempstr, x->_iMinDex); + } + strcat(sstr, tempstr); + } + AddSText(40, l, FALSE, sstr, iclr, FALSE); + l++; + + if(x->_iMagical == 2 && x->_iIdentified) { + AddSText(40, l, FALSE, "Unique Item", iclr, FALSE); + } +} + +void S_StartSBuy() +{ + int i; + + stextsize = 1; + stextscrl = TRUE; + stextsval = 0; + + sprintf(tempstr, "I have these items for sale : Your gold : %i", plr[myplr]._pGold); + AddSText(0, 1, TRUE, tempstr, COL_GOLD, FALSE); + AddSLine(3); + AddSLine(21); + S_ScrollSBuy(stextsval); + AddSText(0, 22, TRUE, "Back", COL_WHITE, FALSE); + OffsetSTextY(22, 6); + + storenumh = 0; + for(i = 0; smithitem[i]._itype != -1; i++) { + storenumh++; + } + + stextsmax = storenumh - 4; + if(stextsmax < 0) { + stextsmax = 0; + } +} + +void S_ScrollSPBuy(int idx) +{ + int l, ls, boughtitems; + char iclr; + + ClearSText(5, 21); + + stextup = 5; + + boughtitems = idx; + idx = 0; + while(boughtitems != 0) { + if(premiumitem[idx]._itype != -1) { + boughtitems--; + } + idx++; + } + + for(l = 5; l < 20 && idx < 6; l += 4) { + if(premiumitem[idx]._itype != -1) { + ls = l; + iclr = COL_WHITE; + if(premiumitem[idx]._iMagical != 0) { + iclr = COL_BLUE; + } + if(!premiumitem[idx]._iStatFlag) { + iclr = COL_RED; + } + AddSText(20, l, FALSE, premiumitem[idx]._iIName, iclr, TRUE); + AddSTextVal(l, premiumitem[idx]._iIvalue); + PrintStoreItem(&premiumitem[idx], l + 1, iclr); + stextdown = ls; + } else if(idx < 6) { + l -= 4; + } + idx++; + } + + if(!stext[stextsel]._ssel && stextsel != 22) { + stextsel = stextdown; + } +} + +BOOL S_StartSPBuy() +{ + int i; + + storenumh = 0; + for(i = 0; i < 6; i++) { + if(premiumitem[i]._itype != -1) { + storenumh++; + } + } + + if(storenumh == 0) { + StartStore(STORE_SMITH); + stextsel = 14; + return FALSE; + } + + stextsize = 1; + stextscrl = TRUE; + stextsval = 0; + + sprintf(tempstr, "I have these premium items for sale : Your gold : %i", plr[myplr]._pGold); + AddSText(0, 1, TRUE, tempstr, COL_GOLD, FALSE); + AddSLine(3); + AddSLine(21); + AddSText(0, 22, TRUE, "Back", COL_WHITE, FALSE); + OffsetSTextY(22, 6); + + stextsmax = storenumh - 4; + if(stextsmax < 0) { + stextsmax = 0; + } + + S_ScrollSPBuy(stextsval); + return TRUE; +} + +BOOL SmithSellOk(int i) +{ + if(plr[myplr].InvList[i]._itype == -1) { + return FALSE; + } + if(plr[myplr].InvList[i]._itype == ITYPE_MISC) { + return FALSE; + } + if(plr[myplr].InvList[i]._itype == ITYPE_GOLD) { + return FALSE; + } + if(plr[myplr].InvList[i]._itype == ITYPE_MEAT) { + return FALSE; + } + if(plr[myplr].InvList[i]._itype == ITYPE_STAFF) { + return FALSE; + } + if(plr[myplr].InvList[i].IDidx == IDI_LAZSTAFF) { + return FALSE; + } + + return TRUE; +} + +void S_ScrollSSell(int idx) +{ + int l, ls, v; + char iclr; + + ClearSText(5, 21); + + stextup = 5; + + for(l = 5; l < 20 && idx < storenumh; l += 4) { + if(storehold[idx]._itype != -1) { + ls = l; + iclr = COL_WHITE; + if(storehold[idx]._iMagical != 0) { + iclr = COL_BLUE; + } + if(!storehold[idx]._iStatFlag) { + iclr = COL_RED; + } + if(storehold[idx]._iMagical != 0 && storehold[idx]._iIdentified) { + AddSText(20, l, FALSE, storehold[idx]._iIName, iclr, TRUE); + v = storehold[idx]._iIvalue; + } else { + AddSText(20, l, FALSE, storehold[idx]._iName, iclr, TRUE); + v = storehold[idx]._ivalue; + } + AddSTextVal(l, v); + PrintStoreItem(&storehold[idx], l + 1, iclr); + stextdown = ls; + } + idx++; + } + + stextsmax = storenumh - 4; + if(stextsmax < 0) { + stextsmax = 0; + } +} + +void S_StartSSell() +{ + int i; + BOOL sellok; + + stextsize = 1; + sellok = FALSE; + storenumh = 0; + + for(i = 0; i < 48; i++) { + storehold[i]._itype = -1; + } + + for(i = 0; i < plr[myplr]._pNumInv; i++) { + if(SmithSellOk(i)) { + sellok = TRUE; + storehold[storenumh] = plr[myplr].InvList[i]; + if(storehold[storenumh]._iMagical != 0 && storehold[storenumh]._iIdentified) { + storehold[storenumh]._ivalue = storehold[storenumh]._iIvalue; + } + storehold[storenumh]._ivalue >>= 2; + if(storehold[storenumh]._ivalue == 0) { + storehold[storenumh]._ivalue = 1; + } + storehold[storenumh]._iIvalue = storehold[storenumh]._ivalue; + storehidx[storenumh] = i; + storenumh++; + } + } + + if(!sellok) { + stextscrl = FALSE; + sprintf(tempstr, "You have nothing I want. Your gold : %i", plr[myplr]._pGold); + AddSText(0, 1, TRUE, tempstr, COL_GOLD, FALSE); + AddSLine(3); + AddSLine(21); + AddSText(0, 22, TRUE, "Back", COL_WHITE, TRUE); + OffsetSTextY(22, 6); + } else { + stextscrl = TRUE; + stextsval = 0; + stextsmax = plr[myplr]._pNumInv; + sprintf(tempstr, "Which item is for sale? Your gold : %i", plr[myplr]._pGold); + AddSText(0, 1, TRUE, tempstr, COL_GOLD, FALSE); + AddSLine(3); + AddSLine(21); + S_ScrollSSell(stextsval); + AddSText(0, 22, TRUE, "Back", COL_WHITE, TRUE); + OffsetSTextY(22, 6); + } +} + +BOOL SmithRepairOk(int i) +{ + if(plr[myplr].InvList[i]._itype == -1) { + return FALSE; + } + if(plr[myplr].InvList[i]._itype == ITYPE_MISC) { + return FALSE; + } + if(plr[myplr].InvList[i]._itype == ITYPE_GOLD) { + return FALSE; + } + if(plr[myplr].InvList[i]._itype == ITYPE_MEAT) { + return FALSE; + } + if(plr[myplr].InvList[i]._iDurability == plr[myplr].InvList[i]._iMaxDur) { + return FALSE; + } + + return TRUE; +} + +void S_StartSRepair() +{ + int i; + BOOL repairok; + + stextsize = 1; + repairok = FALSE; + storenumh = 0; + + for(i = 0; i < 48; i++) { + storehold[i]._itype = -1; + } + + if(plr[myplr].InvBody[0]._itype != -1 && plr[myplr].InvBody[0]._iDurability != plr[myplr].InvBody[0]._iMaxDur) { + repairok = TRUE; + AddStoreHoldRepair(&plr[myplr].InvBody[0], -1); + } + if(plr[myplr].InvBody[6]._itype != -1 && plr[myplr].InvBody[6]._iDurability != plr[myplr].InvBody[6]._iMaxDur) { + repairok = TRUE; + AddStoreHoldRepair(&plr[myplr].InvBody[6], -2); + } + if(plr[myplr].InvBody[4]._itype != -1 && plr[myplr].InvBody[4]._iDurability != plr[myplr].InvBody[4]._iMaxDur) { + repairok = TRUE; + AddStoreHoldRepair(&plr[myplr].InvBody[4], -3); + } + if(plr[myplr].InvBody[5]._itype != -1 && plr[myplr].InvBody[5]._iDurability != plr[myplr].InvBody[5]._iMaxDur) { + repairok = TRUE; + AddStoreHoldRepair(&plr[myplr].InvBody[5], -4); + } + + for(i = 0; i < plr[myplr]._pNumInv; i++) { + if(SmithRepairOk(i)) { + repairok = TRUE; + AddStoreHoldRepair(&plr[myplr].InvList[i], i); + } + } + + if(!repairok) { + stextscrl = FALSE; + sprintf(tempstr, "You have nothing to repair. Your gold : %i", plr[myplr]._pGold); + AddSText(0, 1, TRUE, tempstr, COL_GOLD, FALSE); + AddSLine(3); + AddSLine(21); + AddSText(0, 22, TRUE, "Back", COL_WHITE, TRUE); + OffsetSTextY(22, 6); + } else { + stextscrl = TRUE; + stextsval = 0; + stextsmax = plr[myplr]._pNumInv; + sprintf(tempstr, "Repair which item? Your gold : %i", plr[myplr]._pGold); + AddSText(0, 1, TRUE, tempstr, COL_GOLD, FALSE); + AddSLine(3); + AddSLine(21); + S_ScrollSSell(stextsval); + AddSText(0, 22, TRUE, "Back", COL_WHITE, TRUE); + OffsetSTextY(22, 6); + } +} + +void AddStoreHoldRepair(ItemStruct *itm, int i) +{ + int v; + + /// ASSERT: assert(itm->_iMaxDur > 0); + + storehold[storenumh] = *itm; + itm = &storehold[storenumh]; + + if(itm->_iMagical != 0 && itm->_iIdentified) { + itm->_ivalue = 30 * itm->_iIvalue / 100; + } + + v = 100 * (itm->_iMaxDur - itm->_iDurability) / itm->_iMaxDur; + v = v * itm->_ivalue / 100; + + if(v == 0) { + if(itm->_iMagical != 0 && itm->_iIdentified) { + return; + } + v = 1; + } + if(v > 1) { + v >>= 1; + } + + itm->_iIvalue = v; + itm->_ivalue = v; + storehidx[storenumh] = i; + storenumh++; +} + +void S_StartWitch() +{ + stextsize = 0; + stextscrl = FALSE; + + AddSText(0, 2, TRUE, "Witch's shack", COL_GOLD, FALSE); + AddSText(0, 9, TRUE, "Would you like to:", COL_GOLD, FALSE); + AddSText(0, 12, TRUE, "Talk to Adria", COL_BLUE, TRUE); + AddSText(0, 14, TRUE, "Buy items", COL_WHITE, TRUE); + AddSText(0, 16, TRUE, "Sell items", COL_WHITE, TRUE); + AddSText(0, 18, TRUE, "Recharge staves", COL_WHITE, TRUE); + AddSText(0, 20, TRUE, "Leave the shack", COL_WHITE, TRUE); + AddSLine(5); + + storenumh = 20; +} + +void S_ScrollWBuy(int idx) +{ + int l, ls; + char iclr; + + ClearSText(5, 21); + + stextup = 5; + + for(l = 5; l < 20; l += 4) { + if(witchitem[idx]._itype != -1) { + ls = l; + iclr = COL_WHITE; + if(witchitem[idx]._iMagical != 0) { + iclr = COL_BLUE; + } + if(!witchitem[idx]._iStatFlag) { + iclr = COL_RED; + } + if(witchitem[idx]._iMagical != 0) { + AddSText(20, l, FALSE, witchitem[idx]._iIName, iclr, TRUE); + } else { + AddSText(20, l, FALSE, witchitem[idx]._iName, iclr, TRUE); + } + AddSTextVal(l, witchitem[idx]._iIvalue); + PrintStoreItem(&witchitem[idx], l + 1, iclr); + stextdown = ls; + idx++; + } + } + + if(!stext[stextsel]._ssel && stextsel != 22) { + stextsel = stextdown; + } +} + +void S_StartWBuy() +{ + int i; + + stextsize = 1; + stextscrl = TRUE; + stextsval = 0; + stextsmax = 20; + + sprintf(tempstr, "I have these items for sale : Your gold : %i", plr[myplr]._pGold); + AddSText(0, 1, TRUE, tempstr, COL_GOLD, FALSE); + AddSLine(3); + AddSLine(21); + S_ScrollWBuy(stextsval); + AddSText(0, 22, TRUE, "Back", COL_WHITE, FALSE); + OffsetSTextY(22, 6); + + storenumh = 0; + for(i = 0; witchitem[i]._itype != -1; i++) { + storenumh++; + } + + stextsmax = storenumh - 4; + if(stextsmax < 0) { + stextsmax = 0; + } +} + +BOOL WitchSellOk(int i) +{ + BOOL rv; + ItemStruct *pI; + + rv = FALSE; + + if(i >= 0) { + pI = &plr[myplr].InvList[i]; + } else { + pI = &plr[myplr].SpdList[-(i + 1)]; + } + + if(pI->_itype == ITYPE_MISC) { + rv = TRUE; + } + if(pI->_itype == ITYPE_STAFF) { + rv = TRUE; + } + if(pI->IDidx >= IDI_FIRSTQUEST && pI->IDidx <= IDI_LASTQUEST) { + rv = FALSE; + } + if(pI->IDidx == IDI_LAZSTAFF) { + rv = FALSE; + } + + return rv; +} + +void S_StartWSell() +{ + int i; + BOOL sellok; + + stextsize = 1; + sellok = FALSE; + storenumh = 0; + + for(i = 0; i < 48; i++) { + storehold[i]._itype = -1; + } + + for(i = 0; i < plr[myplr]._pNumInv; i++) { + if(WitchSellOk(i)) { + sellok = TRUE; + storehold[storenumh] = plr[myplr].InvList[i]; + if(storehold[storenumh]._iMagical != 0 && storehold[storenumh]._iIdentified) { + storehold[storenumh]._ivalue = storehold[storenumh]._iIvalue; + } + storehold[storenumh]._ivalue >>= 2; + if(storehold[storenumh]._ivalue == 0) { + storehold[storenumh]._ivalue = 1; + } + storehold[storenumh]._iIvalue = storehold[storenumh]._ivalue; + storehidx[storenumh] = i; + storenumh++; + } + } + for(i = 0; i < 8; i++) { + if(plr[myplr].SpdList[i]._itype != -1 && WitchSellOk(-(i + 1))) { + sellok = TRUE; + storehold[storenumh] = plr[myplr].SpdList[i]; + if(storehold[storenumh]._iMagical != 0 && storehold[storenumh]._iIdentified) { + storehold[storenumh]._ivalue = storehold[storenumh]._iIvalue; + } + storehold[storenumh]._ivalue >>= 2; + if(storehold[storenumh]._ivalue == 0) { + storehold[storenumh]._ivalue = 1; + } + storehold[storenumh]._iIvalue = storehold[storenumh]._ivalue; + storehidx[storenumh] = -(i + 1); + storenumh++; + } + } + + if(!sellok) { + stextscrl = FALSE; + sprintf(tempstr, "You have nothing I want. Your gold : %i", plr[myplr]._pGold); + AddSText(0, 1, TRUE, tempstr, COL_GOLD, FALSE); + AddSLine(3); + AddSLine(21); + AddSText(0, 22, TRUE, "Back", COL_WHITE, TRUE); + OffsetSTextY(22, 6); + } else { + stextscrl = TRUE; + stextsval = 0; + stextsmax = plr[myplr]._pNumInv; + sprintf(tempstr, "Which item is for sale? Your gold : %i", plr[myplr]._pGold); + AddSText(0, 1, TRUE, tempstr, COL_GOLD, FALSE); + AddSLine(3); + AddSLine(21); + S_ScrollSSell(stextsval); + AddSText(0, 22, TRUE, "Back", COL_WHITE, TRUE); + OffsetSTextY(22, 6); + } +} + +BOOL WitchRechargeOk(int i) +{ + BOOL rv; + + rv = FALSE; + + if(plr[myplr].InvList[i]._itype == ITYPE_STAFF && plr[myplr].InvList[i]._iCharges != plr[myplr].InvList[i]._iMaxCharges) { + rv = TRUE; + } + + return rv; +} + +void AddStoreHoldRecharge(ItemStruct itm, int i) +{ + int v; + + storehold[storenumh] = itm; + storehold[storenumh]._ivalue += spelldata[itm._iSpell].sStaffCost; + v = 100 * (storehold[storenumh]._iMaxCharges - storehold[storenumh]._iCharges) / storehold[storenumh]._iMaxCharges; + storehold[storenumh]._ivalue = v * storehold[storenumh]._ivalue / 100 >> 1; + storehold[storenumh]._iIvalue = storehold[storenumh]._ivalue; + storehidx[storenumh] = i; + storenumh++; +} + +void S_StartWRecharge() +{ + int i; + BOOL rechargeok; + + stextsize = 1; + rechargeok = FALSE; + storenumh = 0; + + for(i = 0; i < 48; i++) { + storehold[i]._itype = -1; + } + + if(plr[myplr].InvBody[4]._itype == ITYPE_STAFF && plr[myplr].InvBody[4]._iCharges != plr[myplr].InvBody[4]._iMaxCharges) { + rechargeok = TRUE; + AddStoreHoldRecharge(plr[myplr].InvBody[4], -1); + } + + for(i = 0; i < plr[myplr]._pNumInv; i++) { + if(WitchRechargeOk(i)) { + rechargeok = TRUE; + AddStoreHoldRecharge(plr[myplr].InvList[i], i); + } + } + + if(!rechargeok) { + stextscrl = FALSE; + sprintf(tempstr, "You have nothing to recharge. Your gold : %i", plr[myplr]._pGold); + AddSText(0, 1, TRUE, tempstr, COL_GOLD, FALSE); + AddSLine(3); + AddSLine(21); + AddSText(0, 22, TRUE, "Back", COL_WHITE, TRUE); + OffsetSTextY(22, 6); + } else { + stextscrl = TRUE; + stextsval = 0; + stextsmax = plr[myplr]._pNumInv; + sprintf(tempstr, "Recharge which item? Your gold : %i", plr[myplr]._pGold); + AddSText(0, 1, TRUE, tempstr, COL_GOLD, FALSE); + AddSLine(3); + AddSLine(21); + S_ScrollSSell(stextsval); + AddSText(0, 22, TRUE, "Back", COL_WHITE, TRUE); + OffsetSTextY(22, 6); + } +} + +void S_StartNoMoney() +{ + StartStore(stextshold); + + stextsize = 1; + stextscrl = FALSE; + + ClearSText(5, 23); + AddSText(0, 14, TRUE, "You do not have enough gold", COL_WHITE, TRUE); +} + +void S_StartNoRoom() +{ + StartStore(stextshold); + + stextscrl = FALSE; + + ClearSText(5, 23); + AddSText(0, 14, TRUE, "You do not have enough room in inventory", COL_WHITE, TRUE); +} + +void S_StartConfirm() +{ + char iclr; + BOOL idprint; + + StartStore(stextshold); + + stextscrl = FALSE; + + ClearSText(5, 23); + + iclr = COL_WHITE; + if(plr[myplr].HoldItem._iMagical != 0) { + iclr = COL_BLUE; + } + if(!plr[myplr].HoldItem._iStatFlag) { + iclr = COL_RED; + } + + idprint = plr[myplr].HoldItem._iMagical != 0; + if(stextshold == STORE_SIDENTIFY) { + idprint = FALSE; + } + if(plr[myplr].HoldItem._iMagical != 0 && !plr[myplr].HoldItem._iIdentified) { + if(stextshold == STORE_SSELL) { + idprint = FALSE; + } + if(stextshold == STORE_WSELL) { + idprint = FALSE; + } + if(stextshold == STORE_SREPAIR) { + idprint = FALSE; + } + if(stextshold == STORE_WRECHARGE) { + idprint = FALSE; + } + } + + if(idprint) { + AddSText(20, 8, FALSE, plr[myplr].HoldItem._iIName, iclr, FALSE); + } else { + AddSText(20, 8, FALSE, plr[myplr].HoldItem._iName, iclr, FALSE); + } + + AddSTextVal(8, plr[myplr].HoldItem._iIvalue); + PrintStoreItem(&plr[myplr].HoldItem, 9, iclr); + + switch(stextshold) { + case STORE_SBUY: + case STORE_WBUY: + case STORE_HBUY: + case STORE_SPBUY: + strcpy(tempstr, "Are you sure you want to buy this item?"); + break; + case STORE_SSELL: + case STORE_WSELL: + strcpy(tempstr, "Are you sure you want to sell this item?"); + break; + case STORE_SREPAIR: + strcpy(tempstr, "Are you sure you want to repair this item?"); + break; + case STORE_WRECHARGE: + strcpy(tempstr, "Are you sure you want to recharge this item?"); + break; + case STORE_BBOY: + strcpy(tempstr, "Do we have a deal?"); + break; + case STORE_SIDENTIFY: + strcpy(tempstr, "Are you sure you want to identify this item?"); + break; + } + + AddSText(0, 15, TRUE, tempstr, COL_WHITE, FALSE); + AddSText(0, 18, TRUE, "Yes", COL_WHITE, TRUE); + AddSText(0, 20, TRUE, "No", COL_WHITE, TRUE); +} + +void S_StartBoy() +{ + stextsize = 0; + stextscrl = FALSE; + + AddSText(0, 2, TRUE, "Wirt the Peg-legged boy", COL_GOLD, FALSE); + AddSLine(5); + + if(boyitem._itype != -1) { + AddSText(0, 8, TRUE, "Talk to Wirt", COL_BLUE, TRUE); + AddSText(0, 12, TRUE, "I have something for sale,", COL_GOLD, FALSE); + AddSText(0, 14, TRUE, "but it will cost 50 gold", COL_GOLD, FALSE); + AddSText(0, 16, TRUE, "just to take a look. ", COL_GOLD, FALSE); + AddSText(0, 18, TRUE, "What have you got?", COL_WHITE, TRUE); + AddSText(0, 20, TRUE, "Say goodbye", COL_WHITE, TRUE); + } else { + AddSText(0, 12, TRUE, "Talk to Wirt", COL_BLUE, TRUE); + AddSText(0, 18, TRUE, "Say goodbye", COL_WHITE, TRUE); + } +} + +void S_StartBBoy() +{ + int iclr; + + stextsize = 1; + stextscrl = FALSE; + + sprintf(tempstr, "I have this item for sale : Your gold : %i", plr[myplr]._pGold); + AddSText(0, 1, TRUE, tempstr, COL_GOLD, FALSE); + AddSLine(3); + AddSLine(21); + + iclr = COL_WHITE; + if(boyitem._iMagical != 0) { + iclr = COL_BLUE; + } + if(!boyitem._iStatFlag) { + iclr = COL_RED; + } + + if(boyitem._iMagical != 0) { + AddSText(20, 10, FALSE, boyitem._iIName, iclr, TRUE); + } else { + AddSText(20, 10, FALSE, boyitem._iName, iclr, TRUE); + } + + AddSTextVal(10, boyitem._iIvalue + (boyitem._iIvalue >> 1)); + PrintStoreItem(&boyitem, 11, iclr); + AddSText(0, 22, TRUE, "Leave", COL_WHITE, TRUE); + OffsetSTextY(22, 6); +} + +void S_StartHealer() +{ + stextsize = 0; + stextscrl = FALSE; + + AddSText(0, 1, TRUE, "Welcome to the", COL_GOLD, FALSE); + AddSText(0, 3, TRUE, "Healer's home", COL_GOLD, FALSE); + AddSText(0, 9, TRUE, "Would you like to:", COL_GOLD, FALSE); + AddSText(0, 12, TRUE, "Talk to Pepin", COL_BLUE, TRUE); + AddSText(0, 14, TRUE, "Receive healing", COL_WHITE, TRUE); + AddSText(0, 16, TRUE, "Buy items", COL_WHITE, TRUE); + AddSText(0, 18, TRUE, "Leave Healer's home", COL_WHITE, TRUE); + AddSLine(5); + + storenumh = 20; +} + +void S_ScrollHBuy(int idx) +{ + int l, ls; + char iclr; + + ClearSText(5, 21); + + stextup = 5; + + for(l = 5; l < 20; l += 4) { + if(healitem[idx]._itype != -1) { + ls = l; + iclr = COL_WHITE; + if(!healitem[idx]._iStatFlag) { + iclr = COL_RED; + } + AddSText(20, l, FALSE, healitem[idx]._iName, iclr, TRUE); + AddSTextVal(l, healitem[idx]._iIvalue); + PrintStoreItem(&healitem[idx], l + 1, iclr); + stextdown = ls; + idx++; + } + } + + if(!stext[stextsel]._ssel && stextsel != 22) { + stextsel = stextdown; + } +} + +void S_StartHBuy() +{ + int i; + + stextsize = 1; + stextscrl = TRUE; + stextsval = 0; + + sprintf(tempstr, "I have these items for sale : Your gold : %i", plr[myplr]._pGold); + AddSText(0, 1, TRUE, tempstr, COL_GOLD, FALSE); + AddSLine(3); + AddSLine(21); + S_ScrollHBuy(stextsval); + AddSText(0, 22, TRUE, "Back", COL_WHITE, FALSE); + OffsetSTextY(22, 6); + + storenumh = 0; + for(i = 0; healitem[i]._itype != -1; i++) { + storenumh++; + } + + stextsmax = storenumh - 4; + if(stextsmax < 0) { + stextsmax = 0; + } +} + +void S_StartStory() +{ + stextsize = 0; + stextscrl = FALSE; + + AddSText(0, 2, TRUE, "The Town Elder", COL_GOLD, FALSE); + AddSText(0, 9, TRUE, "Would you like to:", COL_GOLD, FALSE); + AddSText(0, 12, TRUE, "Talk to Cain", COL_BLUE, TRUE); + AddSText(0, 14, TRUE, "Identify an item", COL_WHITE, TRUE); + AddSText(0, 18, TRUE, "Say goodbye", COL_WHITE, TRUE); + AddSLine(5); +} + +BOOL IdItemOk(ItemStruct *i) +{ + if(i->_itype == -1) { + return FALSE; + } + if(i->_iMagical == 0) { + return FALSE; + } + if(i->_iIdentified) { + return FALSE; + } + + return TRUE; +} + +void AddStoreHoldId(ItemStruct itm, int i) +{ + storehold[storenumh] = itm; + storehold[storenumh]._ivalue = 100; + storehold[storenumh]._iIvalue = 100; + storehidx[storenumh] = i; + storenumh++; +} + +void S_StartSIdentify() +{ + int i; + BOOL idok; + + stextsize = 1; + idok = FALSE; + storenumh = 0; + + for(i = 0; i < 48; i++) { + storehold[i]._itype = -1; + } + + if(IdItemOk(&plr[myplr].InvBody[0])) { + idok = TRUE; + AddStoreHoldId(plr[myplr].InvBody[0], -1); + } + if(IdItemOk(&plr[myplr].InvBody[6])) { + idok = TRUE; + AddStoreHoldId(plr[myplr].InvBody[6], -2); + } + if(IdItemOk(&plr[myplr].InvBody[4])) { + idok = TRUE; + AddStoreHoldId(plr[myplr].InvBody[4], -3); + } + if(IdItemOk(&plr[myplr].InvBody[5])) { + idok = TRUE; + AddStoreHoldId(plr[myplr].InvBody[5], -4); + } + if(IdItemOk(&plr[myplr].InvBody[1])) { + idok = TRUE; + AddStoreHoldId(plr[myplr].InvBody[1], -5); + } + if(IdItemOk(&plr[myplr].InvBody[2])) { + idok = TRUE; + AddStoreHoldId(plr[myplr].InvBody[2], -6); + } + if(IdItemOk(&plr[myplr].InvBody[3])) { + idok = TRUE; + AddStoreHoldId(plr[myplr].InvBody[3], -7); + } + + for(i = 0; i < plr[myplr]._pNumInv; i++) { + if(IdItemOk(&plr[myplr].InvList[i])) { + idok = TRUE; + AddStoreHoldId(plr[myplr].InvList[i], i); + } + } + + if(!idok) { + stextscrl = FALSE; + sprintf(tempstr, "You have nothing to identify. Your gold : %i", plr[myplr]._pGold); + AddSText(0, 1, TRUE, tempstr, COL_GOLD, FALSE); + AddSLine(3); + AddSLine(21); + AddSText(0, 22, TRUE, "Back", COL_WHITE, TRUE); + OffsetSTextY(22, 6); + } else { + stextscrl = TRUE; + stextsval = 0; + stextsmax = plr[myplr]._pNumInv; + sprintf(tempstr, "Identify which item? Your gold : %i", plr[myplr]._pGold); + AddSText(0, 1, TRUE, tempstr, COL_GOLD, FALSE); + AddSLine(3); + AddSLine(21); + S_ScrollSSell(stextsval); + AddSText(0, 22, TRUE, "Back", COL_WHITE, TRUE); + OffsetSTextY(22, 6); + } +} + +void S_StartIdShow() +{ + char iclr; + + StartStore(stextshold); + + stextscrl = FALSE; + + ClearSText(5, 23); + + iclr = COL_WHITE; + if(plr[myplr].HoldItem._iMagical != 0) { + iclr = COL_BLUE; + } + if(!plr[myplr].HoldItem._iStatFlag) { + iclr = COL_RED; + } + + AddSText(0, 7, TRUE, "This item is:", COL_WHITE, FALSE); + AddSText(20, 11, FALSE, plr[myplr].HoldItem._iIName, iclr, FALSE); + PrintStoreItem(&plr[myplr].HoldItem, 12, iclr); + AddSText(0, 18, TRUE, "Done", COL_WHITE, TRUE); +} + +void S_StartTalk() +{ + int i, tq, sn, la, gl; + + stextsize = 0; + stextscrl = FALSE; + + sprintf(tempstr, "Talk to %s", talkname[talker]); + AddSText(0, 2, TRUE, tempstr, COL_GOLD, FALSE); + AddSLine(5); + + tq = 0; + for(i = 0; i < MAXQUESTS; i++) { + if(quests[i]._qactive == 2 && Qtalklist[talker][i] != -1 && quests[i]._qlog) { + tq++; + } + } + + if(tq > 6) { + sn = 14 - (tq >> 1); + la = 1; + } else { + sn = 15 - tq; + la = 2; + } + + gl = sn - 2; + + for(i = 0; i < MAXQUESTS; i++) { + if(quests[i]._qactive == 2 && Qtalklist[talker][i] != -1 && quests[i]._qlog) { + AddSText(0, sn, TRUE, questlist[i]._qlstr, COL_WHITE, TRUE); + sn += la; + } + } + + AddSText(0, gl, TRUE, "Gossip", COL_BLUE, TRUE); + AddSText(0, 22, TRUE, "Back", COL_WHITE, TRUE); +} + +void S_StartTavern() +{ + stextsize = 0; + stextscrl = FALSE; + + AddSText(0, 1, TRUE, "Welcome to the", COL_GOLD, FALSE); + AddSText(0, 3, TRUE, "Rising Sun", COL_GOLD, FALSE); + AddSText(0, 9, TRUE, "Would you like to:", COL_GOLD, FALSE); + AddSText(0, 12, TRUE, "Talk to Ogden", COL_BLUE, TRUE); + AddSText(0, 18, TRUE, "Leave the tavern", COL_WHITE, TRUE); + AddSLine(5); + + storenumh = 20; +} + +void S_StartBarMaid() +{ + stextsize = 0; + stextscrl = FALSE; + + AddSText(0, 2, TRUE, "Gillian", COL_GOLD, FALSE); + AddSText(0, 9, TRUE, "Would you like to:", COL_GOLD, FALSE); + AddSText(0, 12, TRUE, "Talk to Gillian", COL_BLUE, TRUE); + AddSText(0, 18, TRUE, "Say goodbye", COL_WHITE, TRUE); + AddSLine(5); + + storenumh = 20; +} + +void S_StartDrunk() +{ + stextsize = 0; + stextscrl = FALSE; + + AddSText(0, 2, TRUE, "Farnham the Drunk", COL_GOLD, FALSE); + AddSText(0, 9, TRUE, "Would you like to:", COL_GOLD, FALSE); + AddSText(0, 12, TRUE, "Talk to Farnham", COL_BLUE, TRUE); + AddSText(0, 18, TRUE, "Say Goodbye", COL_WHITE, TRUE); + AddSLine(5); + + storenumh = 20; +} + +void StartStore(char s) +{ + int i; + + sbookflag = 0; + invflag = 0; + chrflag = 0; + questlog = 0; + dropGoldFlag = 0; + + ClearSText(0, 24); + ReleaseStoreBtn(); + + switch(s) { + case STORE_SMITH: + S_StartSmith(); + break; + case STORE_SBUY: + if(storenumh > 0) { + S_StartSBuy(); + } + break; + case STORE_SSELL: + S_StartSSell(); + break; + case STORE_SREPAIR: + S_StartSRepair(); + break; + case STORE_WITCH: + S_StartWitch(); + break; + case STORE_WBUY: + if(storenumh > 0) { + S_StartWBuy(); + } + break; + case STORE_WSELL: + S_StartWSell(); + break; + case STORE_WRECHARGE: + S_StartWRecharge(); + break; + case STORE_NOMONEY: + S_StartNoMoney(); + break; + case STORE_NOROOM: + S_StartNoRoom(); + break; + case STORE_CONFIRM: + S_StartConfirm(); + break; + case STORE_BOY: + S_StartBoy(); + break; + case STORE_BBOY: + S_StartBBoy(); + break; + case STORE_HEALER: + S_StartHealer(); + break; + case STORE_STORY: + S_StartStory(); + break; + case STORE_HBUY: + if(storenumh > 0) { + S_StartHBuy(); + } + break; + case STORE_SIDENTIFY: + S_StartSIdentify(); + break; + case STORE_SPBUY: + if(!S_StartSPBuy()) { + return; + } + break; + case STORE_GOSSIP: + S_StartTalk(); + break; + case STORE_IDSHOW: + S_StartIdShow(); + break; + case STORE_TAVERN: + S_StartTavern(); + break; + case STORE_DRUNK: + S_StartDrunk(); + break; + case STORE_BARMAID: + S_StartBarMaid(); + break; + } + + for(i = 0; i < 24; i++) { + if(stext[i]._ssel) { + break; + } + } + + if(i == 24) { + stextsel = -1; + } else { + stextsel = i; + } + + stextflag = s; + + if(s == STORE_SBUY && storenumh == 0) { + StartStore(STORE_SMITH); + } +} + +void DrawSText() +{ + int i; + + if(stextsize == 0) { + DrawSTextBack(); + } else { + DrawQTextBack(); + } + + if(stextscrl) { + switch(stextflag) { + case STORE_SBUY: + S_ScrollSBuy(stextsval); + break; + case STORE_SPBUY: + S_ScrollSPBuy(stextsval); + break; + case STORE_SSELL: + case STORE_SREPAIR: + case STORE_WSELL: + case STORE_WRECHARGE: + case STORE_SIDENTIFY: + S_ScrollSSell(stextsval); + break; + case STORE_WBUY: + S_ScrollWBuy(stextsval); + break; + case STORE_HBUY: + S_ScrollHBuy(stextsval); + break; + } + } + + for(i = 0; i < 24; i++) { + if(stext[i]._sline) { + DrawSLine(i); + } + if(stext[i]._sstr[0] != '\0') { + PrintSString(stext[i]._sx, i, stext[i]._sjust, stext[i]._sstr, stext[i]._sclr, stext[i]._sval); + } + } + + if(stextscrl) { + DrawSSlider(4, 20); + } + + sspinframe = (sspinframe & 7) + 1; +} + +void STextESC() +{ + if(qtextflag) { + qtextflag = 0; + if(leveltype == DTYPE_TOWN) { + stream_stop(); + } + return; + } + + switch(stextflag) { + case STORE_SMITH: + case STORE_WITCH: + case STORE_BOY: + case STORE_BBOY: + case STORE_HEALER: + case STORE_STORY: + case STORE_TAVERN: + case STORE_DRUNK: + case STORE_BARMAID: + stextflag = 0; + break; + case STORE_GOSSIP: + StartStore(stextshold); + stextsel = stextlhold; + break; + case STORE_SBUY: + StartStore(STORE_SMITH); + stextsel = 12; + break; + case STORE_SPBUY: + StartStore(STORE_SMITH); + stextsel = 14; + break; + case STORE_SSELL: + StartStore(STORE_SMITH); + stextsel = 16; + break; + case STORE_SREPAIR: + StartStore(STORE_SMITH); + stextsel = 18; + break; + case STORE_WBUY: + StartStore(STORE_WITCH); + stextsel = 14; + break; + case STORE_WSELL: + StartStore(STORE_WITCH); + stextsel = 16; + break; + case STORE_WRECHARGE: + StartStore(STORE_WITCH); + stextsel = 18; + break; + case STORE_HBUY: + StartStore(STORE_HEALER); + stextsel = 16; + break; + case STORE_SIDENTIFY: + StartStore(STORE_STORY); + stextsel = 14; + break; + case STORE_IDSHOW: + StartStore(STORE_SIDENTIFY); + break; + case STORE_NOMONEY: + case STORE_NOROOM: + case STORE_CONFIRM: + StartStore(stextshold); + stextsel = stextlhold; + stextsval = stextvhold; + break; + } +} + +void STextUp() +{ + PlaySFX(IS_TITLEMOV); + + if(stextsel != -1) { + if(stextscrl) { + if(stextsel == stextup) { + if(stextsval != 0) { + stextsval--; + } + } else { + stextsel--; + while(!stext[stextsel]._ssel) { + if(stextsel == 0) { + stextsel = 23; + } else { + stextsel--; + } + } + } + } else { + if(stextsel == 0) { + stextsel = 23; + } else { + stextsel--; + } + while(!stext[stextsel]._ssel) { + if(stextsel == 0) { + stextsel = 23; + } else { + stextsel--; + } + } + } + } +} + +void STextDown() +{ + PlaySFX(IS_TITLEMOV); + + if(stextsel != -1) { + if(stextscrl) { + if(stextsel == stextdown) { + if(stextsval < stextsmax) { + stextsval++; + } + } else { + stextsel++; + while(!stext[stextsel]._ssel) { + if(stextsel == 23) { + stextsel = 0; + } else { + stextsel++; + } + } + } + } else { + if(stextsel == 23) { + stextsel = 0; + } else { + stextsel++; + } + while(!stext[stextsel]._ssel) { + if(stextsel == 23) { + stextsel = 0; + } else { + stextsel++; + } + } + } + } +} + +void STextPrior() +{ + PlaySFX(IS_TITLEMOV); + + if(stextsel != -1 && stextscrl) { + if(stextsel == stextup) { + if(stextsval != 0) { + stextsval -= 4; + } + if(stextsval < 0) { + stextsval = 0; + } + } else { + stextsel = stextup; + } + } +} + +void STextNext() +{ + PlaySFX(IS_TITLEMOV); + + if(stextsel != -1 && stextscrl) { + if(stextsel == stextdown) { + if(stextsval < stextsmax) { + stextsval += 4; + } + if(stextsval > stextsmax) { + stextsval = stextsmax; + } + } else { + stextsel = stextdown; + } + } +} + +void S_SmithEnter() +{ + switch(stextsel) { + case 10: + talker = TOWN_SMITH; + stextshold = STORE_SMITH; + stextlhold = stextsel; + gossipstart = TEXT_GRISWOLD2; + gossipend = TEXT_GRISWOLD13; + StartStore(STORE_GOSSIP); + break; + case 12: + StartStore(STORE_SBUY); + break; + case 14: + StartStore(STORE_SPBUY); + break; + case 16: + StartStore(STORE_SSELL); + break; + case 18: + StartStore(STORE_SREPAIR); + break; + case 20: + stextflag = 0; + break; + } +} + +void SetGoldCurs(int pnum, int i) +{ + if(plr[pnum].InvList[i]._ivalue >= 2500) { + plr[pnum].InvList[i]._iCurs = 6; + } else if(plr[pnum].InvList[i]._ivalue <= 1000) { + plr[pnum].InvList[i]._iCurs = 4; + } else { + plr[pnum].InvList[i]._iCurs = 5; + } +} + +void SetSpdbarGoldCurs(int pnum, int i) +{ + if(plr[pnum].SpdList[i]._ivalue >= 2500) { + plr[pnum].SpdList[i]._iCurs = 6; + } else if(plr[pnum].SpdList[i]._ivalue <= 1000) { + plr[pnum].SpdList[i]._iCurs = 4; + } else { + plr[pnum].SpdList[i]._iCurs = 5; + } +} + +void TakePlrsMoney(long cost) +{ + int i; + + plr[myplr]._pGold = CalculateGold(myplr) - cost; + + for(i = 0; i < 8 && cost > 0; i++) { + if(plr[myplr].SpdList[i]._itype == ITYPE_GOLD && plr[myplr].SpdList[i]._ivalue != 5000) { + if(cost < plr[myplr].SpdList[i]._ivalue) { + plr[myplr].SpdList[i]._ivalue -= cost; + SetSpdbarGoldCurs(myplr, i); + cost = 0; + } else { + cost -= plr[myplr].SpdList[i]._ivalue; + RemoveSpdBarItem(myplr, i); + i = -1; + } + } + } + if(cost > 0) { + for(i = 0; i < 8 && cost > 0; i++) { + if(plr[myplr].SpdList[i]._itype == ITYPE_GOLD) { + if(cost < plr[myplr].SpdList[i]._ivalue) { + plr[myplr].SpdList[i]._ivalue -= cost; + SetSpdbarGoldCurs(myplr, i); + cost = 0; + } else { + cost -= plr[myplr].SpdList[i]._ivalue; + RemoveSpdBarItem(myplr, i); + i = -1; + } + } + } + } + + force_redraw = 255; + + if(cost > 0) { + for(i = 0; i < plr[myplr]._pNumInv && cost > 0; i++) { + if(plr[myplr].InvList[i]._itype == ITYPE_GOLD && plr[myplr].InvList[i]._ivalue != 5000) { + if(cost < plr[myplr].InvList[i]._ivalue) { + plr[myplr].InvList[i]._ivalue -= cost; + SetGoldCurs(myplr, i); + cost = 0; + } else { + cost -= plr[myplr].InvList[i]._ivalue; + RemoveInvItem(myplr, i); + i = -1; + } + } + } + if(cost > 0) { + for(i = 0; i < plr[myplr]._pNumInv && cost > 0; i++) { + if(plr[myplr].InvList[i]._itype == ITYPE_GOLD) { + if(cost < plr[myplr].InvList[i]._ivalue) { + plr[myplr].InvList[i]._ivalue -= cost; + SetGoldCurs(myplr, i); + cost = 0; + } else { + cost -= plr[myplr].InvList[i]._ivalue; + RemoveInvItem(myplr, i); + i = -1; + } + } + } + } + } +} + +void SmithBuyItem() +{ + int idx; + + TakePlrsMoney(plr[myplr].HoldItem._iIvalue); + + if(plr[myplr].HoldItem._iMagical == 0) { + plr[myplr].HoldItem._iIdentified = FALSE; + } + + StoreAutoPlace(); + + idx = stextvhold + ((stextlhold - stextup) >> 2); + if(idx == 19) { + smithitem[idx]._itype = -1; + } else { + while(smithitem[idx + 1]._itype != -1) { + smithitem[idx] = smithitem[idx + 1]; + idx++; + } + smithitem[idx]._itype = -1; + } + + CalcPlrInv(myplr, TRUE); +} + +void S_SBuyEnter() +{ + int idx, i; + BOOL done; + + if(stextsel == 22) { + StartStore(STORE_SMITH); + stextsel = 12; + } else { + stextshold = STORE_SBUY; + stextlhold = stextsel; + stextvhold = stextsval; + idx = stextsval + ((stextsel - stextup) >> 2); + if(plr[myplr]._pGold < smithitem[idx]._iIvalue) { + StartStore(STORE_NOMONEY); + } else { + plr[myplr].HoldItem = smithitem[idx]; + SetCursor_(plr[myplr].HoldItem._iCurs + 12); + done = FALSE; + for(i = 0; i < 40 && !done; i++) { + done = AutoPlace(myplr, i, cursW / 28, cursH / 28, FALSE); + } + if(done) { + StartStore(STORE_CONFIRM); + } else { + StartStore(STORE_NOROOM); + } + SetCursor_(CURSOR_HAND); + } + } +} + +void SmithBuyPItem() +{ + int idx, i, xx; + + TakePlrsMoney(plr[myplr].HoldItem._iIvalue); + + if(plr[myplr].HoldItem._iMagical == 0) { + plr[myplr].HoldItem._iIdentified = FALSE; + } + + StoreAutoPlace(); + + idx = stextvhold + ((stextlhold - stextup) >> 2); + xx = 0; + for(i = 0; idx >= 0; i++) { + if(premiumitem[i]._itype != -1) { + idx--; + xx = i; + } + } + + premiumitem[xx]._itype = -1; + numpremium--; + + SpawnPremium(plr[myplr]._pLevel); +} + +void S_SPBuyEnter() +{ + int idx, i, xx; + BOOL done; + + if(stextsel == 22) { + StartStore(STORE_SMITH); + stextsel = 14; + } else { + stextshold = STORE_SPBUY; + stextlhold = stextsel; + stextvhold = stextsval; + idx = stextsval + ((stextsel - stextup) >> 2); + xx = 0; + for(i = 0; idx >= 0; i++) { + if(premiumitem[i]._itype != -1) { + idx--; + xx = i; + } + } + if(plr[myplr]._pGold < premiumitem[xx]._iIvalue) { + StartStore(STORE_NOMONEY); + } else { + plr[myplr].HoldItem = premiumitem[xx]; + SetCursor_(plr[myplr].HoldItem._iCurs + 12); + done = FALSE; + for(i = 0; i < 40 && !done; i++) { + done = AutoPlace(myplr, i, cursW / 28, cursH / 28, FALSE); + } + if(done) { + StartStore(STORE_CONFIRM); + } else { + StartStore(STORE_NOROOM); + } + SetCursor_(CURSOR_HAND); + } + } +} + +BOOL StoreGoldFit(int idx) +{ + int sz, numsqrs, i; + long cost; + + cost = storehold[idx]._iIvalue; + + sz = cost / 5000; + if(cost % 5000) { + sz++; + } + + SetCursor_(storehold[idx]._iCurs + 12); + numsqrs = (cursW / 28) * (cursH / 28); + SetCursor_(CURSOR_HAND); + + if(numsqrs >= sz) { + return TRUE; + } + + for(i = 0; i < 40; i++) { + if(plr[myplr].InvGrid[i] == 0) { + numsqrs++; + } + } + + for(i = 0; i < plr[myplr]._pNumInv; i++) { + if(plr[myplr].InvList[i]._itype == ITYPE_GOLD && plr[myplr].InvList[i]._ivalue != 5000) { + if(cost + plr[myplr].InvList[i]._ivalue <= 5000) { + cost = 0; + } else { + cost -= 5000 - plr[myplr].InvList[i]._ivalue; + } + } + } + + sz = cost / 5000; + if(cost % 5000) { + sz++; + } + + if(numsqrs >= sz) { + return TRUE; + } + + return FALSE; +} + +void PlaceStoreGold(long v) +{ + int i, ii, xx, yy; + BOOL done; + + done = FALSE; + for(ii = 0; ii < 40 && !done; ii++) { + yy = 10 * (ii / 10); + xx = ii % 10; + if(plr[myplr].InvGrid[xx + yy] == 0) { + i = plr[myplr]._pNumInv; + GetGoldSeed(myplr, &golditem); + plr[myplr].InvList[i] = golditem; + plr[myplr]._pNumInv++; + plr[myplr].InvGrid[xx + yy] = plr[myplr]._pNumInv; + plr[myplr].InvList[i]._ivalue = v; + SetGoldCurs(myplr, i); + done = TRUE; + } + } +} + +void StoreSellItem() +{ + int idx, i; + long cost; + + idx = stextvhold + ((stextlhold - stextup) >> 2); + + if(storehidx[idx] >= 0) { + RemoveInvItem(myplr, storehidx[idx]); + } else { + RemoveSpdBarItem(myplr, -(storehidx[idx] + 1)); + } + + cost = storehold[idx]._iIvalue; + + storenumh--; + if(idx != storenumh) { + while(idx < storenumh) { + storehold[idx] = storehold[idx + 1]; + storehidx[idx] = storehidx[idx + 1]; + idx++; + } + } + + plr[myplr]._pGold += cost; + + for(i = 0; i < plr[myplr]._pNumInv && cost > 0; i++) { + if(plr[myplr].InvList[i]._itype == ITYPE_GOLD && plr[myplr].InvList[i]._ivalue != 5000) { + if(cost + plr[myplr].InvList[i]._ivalue <= 5000) { + plr[myplr].InvList[i]._ivalue += cost; + SetGoldCurs(myplr, i); + cost = 0; + } else { + cost -= 5000 - plr[myplr].InvList[i]._ivalue; + plr[myplr].InvList[i]._ivalue = 5000; + SetGoldCurs(myplr, i); + } + } + } + + if(cost > 0) { + while(cost > 5000) { + PlaceStoreGold(5000); + cost -= 5000; + } + PlaceStoreGold(cost); + } +} + +void S_SSellEnter() +{ + int idx; + + if(stextsel == 22) { + StartStore(STORE_SMITH); + stextsel = 16; + } else { + stextshold = STORE_SSELL; + stextlhold = stextsel; + stextvhold = stextsval; + idx = stextsval + ((stextsel - stextup) >> 2); + plr[myplr].HoldItem = storehold[idx]; + if(StoreGoldFit(idx)) { + StartStore(STORE_CONFIRM); + } else { + StartStore(STORE_NOROOM); + } + } +} + +void SmithRepairItem() +{ + int i, idx; + + TakePlrsMoney(plr[myplr].HoldItem._iIvalue); + + idx = stextvhold + ((stextlhold - stextup) >> 2); + storehold[idx]._iDurability = storehold[idx]._iMaxDur; + + i = storehidx[idx]; + if(i < 0) { + if(i == -1) { + plr[myplr].InvBody[0]._iDurability = plr[myplr].InvBody[0]._iMaxDur; + } + if(i == -2) { + plr[myplr].InvBody[6]._iDurability = plr[myplr].InvBody[6]._iMaxDur; + } + if(i == -3) { + plr[myplr].InvBody[4]._iDurability = plr[myplr].InvBody[4]._iMaxDur; + } + if(i == -4) { + plr[myplr].InvBody[5]._iDurability = plr[myplr].InvBody[5]._iMaxDur; + } + } else { + plr[myplr].InvList[i]._iDurability = plr[myplr].InvList[i]._iMaxDur; + } +} + +void S_SRepairEnter() +{ + int idx; + + if(stextsel == 22) { + StartStore(STORE_SMITH); + stextsel = 18; + } else { + stextshold = STORE_SREPAIR; + stextlhold = stextsel; + stextvhold = stextsval; + idx = stextsval + ((stextsel - stextup) >> 2); + plr[myplr].HoldItem = storehold[idx]; + if(plr[myplr]._pGold < storehold[idx]._iIvalue) { + StartStore(STORE_NOMONEY); + } else { + StartStore(STORE_CONFIRM); + } + } +} + +void S_WitchEnter() +{ + switch(stextsel) { + case 12: + talker = TOWN_WITCH; + stextshold = STORE_WITCH; + stextlhold = stextsel; + gossipstart = TEXT_ADRIA2; + gossipend = TEXT_ADRIA13; + StartStore(STORE_GOSSIP); + break; + case 14: + StartStore(STORE_WBUY); + break; + case 16: + StartStore(STORE_WSELL); + break; + case 18: + StartStore(STORE_WRECHARGE); + break; + case 20: + stextflag = 0; + break; + } +} + +void WitchBuyItem() +{ + int idx; + + idx = stextvhold + ((stextlhold - stextup) >> 2); + if(idx < 3) { + plr[myplr].HoldItem._iSeed = GetRndSeed(); + } + + TakePlrsMoney(plr[myplr].HoldItem._iIvalue); + StoreAutoPlace(); + + if(idx < 3) { + CalcPlrInv(myplr, TRUE); + return; + } + + if(idx == 19) { + witchitem[idx]._itype = -1; + } else { + while(witchitem[idx + 1]._itype != -1) { + witchitem[idx] = witchitem[idx + 1]; + idx++; + } + witchitem[idx]._itype = -1; + } + + CalcPlrInv(myplr, TRUE); +} + +void S_WBuyEnter() +{ + int idx, i; + BOOL done; + + if(stextsel == 22) { + StartStore(STORE_WITCH); + stextsel = 14; + } else { + stextshold = STORE_WBUY; + stextlhold = stextsel; + stextvhold = stextsval; + idx = stextsval + ((stextsel - stextup) >> 2); + if(plr[myplr]._pGold < witchitem[idx]._iIvalue) { + StartStore(STORE_NOMONEY); + } else { + plr[myplr].HoldItem = witchitem[idx]; + SetCursor_(plr[myplr].HoldItem._iCurs + 12); + done = FALSE; + for(i = 0; i < 40 && !done; i++) { + done = SpecialAutoPlace(myplr, i, cursW / 28, cursH / 28, FALSE); + } + if(done) { + StartStore(STORE_CONFIRM); + } else { + StartStore(STORE_NOROOM); + } + SetCursor_(CURSOR_HAND); + } + } +} + +void S_WSellEnter() +{ + int idx; + + if(stextsel == 22) { + StartStore(STORE_WITCH); + stextsel = 16; + } else { + stextshold = STORE_WSELL; + stextlhold = stextsel; + stextvhold = stextsval; + idx = stextsval + ((stextsel - stextup) >> 2); + plr[myplr].HoldItem = storehold[idx]; + if(StoreGoldFit(idx)) { + StartStore(STORE_CONFIRM); + } else { + StartStore(STORE_NOROOM); + } + } +} + +void WitchRechargeItem() +{ + int i, idx; + + TakePlrsMoney(plr[myplr].HoldItem._iIvalue); + + idx = stextvhold + ((stextlhold - stextup) >> 2); + storehold[idx]._iCharges = storehold[idx]._iMaxCharges; + + i = storehidx[idx]; + if(i < 0) { + plr[myplr].InvBody[4]._iCharges = plr[myplr].InvBody[4]._iMaxCharges; + } else { + plr[myplr].InvList[i]._iCharges = plr[myplr].InvList[i]._iMaxCharges; + } + + CalcPlrInv(myplr, TRUE); +} + +void S_WRechargeEnter() +{ + int idx; + + if(stextsel == 22) { + StartStore(STORE_WITCH); + stextsel = 18; + } else { + stextshold = STORE_WRECHARGE; + stextlhold = stextsel; + stextvhold = stextsval; + idx = stextsval + ((stextsel - stextup) >> 2); + plr[myplr].HoldItem = storehold[idx]; + if(plr[myplr]._pGold < storehold[idx]._iIvalue) { + StartStore(STORE_NOMONEY); + } else { + StartStore(STORE_CONFIRM); + } + } +} + +void S_BoyEnter() +{ + if(boyitem._itype != -1 && stextsel == 18) { + if(plr[myplr]._pGold < 50) { + stextshold = STORE_BOY; + stextlhold = stextsel; + stextvhold = stextsval; + StartStore(STORE_NOMONEY); + } else { + TakePlrsMoney(50); + StartStore(STORE_BBOY); + } + } else if(stextsel == 8 && boyitem._itype != -1 || stextsel == 12 && boyitem._itype == -1) { + talker = TOWN_PEGBOY; + stextshold = STORE_BOY; + stextlhold = stextsel; + gossipstart = TEXT_WIRT2; + gossipend = TEXT_WIRT12; + StartStore(STORE_GOSSIP); + } else { + stextflag = 0; + } +} + +void BoyBuyItem() +{ + TakePlrsMoney(plr[myplr].HoldItem._iIvalue); + StoreAutoPlace(); + + boyitem._itype = -1; + stextshold = STORE_BOY; + + CalcPlrInv(myplr, TRUE); +} + +void HealerBuyItem() +{ + int idx; + + idx = stextvhold + ((stextlhold - stextup) >> 2); + if(gbMaxPlayers == 1) { + if(idx < 2) { + plr[myplr].HoldItem._iSeed = GetRndSeed(); + } + } else { + if(idx < 3) { + plr[myplr].HoldItem._iSeed = GetRndSeed(); + } + } + + TakePlrsMoney(plr[myplr].HoldItem._iIvalue); + + if(plr[myplr].HoldItem._iMagical == 0) { + plr[myplr].HoldItem._iIdentified = FALSE; + } + + StoreAutoPlace(); + + if(gbMaxPlayers == 1) { + if(idx < 2) { + return; + } + } else { + if(idx < 3) { + return; + } + } + + idx = stextvhold + ((stextlhold - stextup) >> 2); + if(idx == 19) { + healitem[idx]._itype = -1; + } else { + while(healitem[idx + 1]._itype != -1) { + healitem[idx] = healitem[idx + 1]; + idx++; + } + healitem[idx]._itype = -1; + } + + CalcPlrInv(myplr, TRUE); +} + +void S_BBuyEnter() +{ + int i; + BOOL done; + + if(stextsel == 10) { + stextshold = STORE_BBOY; + stextlhold = stextsel; + stextvhold = stextsval; + if(plr[myplr]._pGold < boyitem._iIvalue + (boyitem._iIvalue >> 1)) { + StartStore(STORE_NOMONEY); + } else { + plr[myplr].HoldItem = boyitem; + plr[myplr].HoldItem._iIvalue += plr[myplr].HoldItem._iIvalue >> 1; + SetCursor_(plr[myplr].HoldItem._iCurs + 12); + done = FALSE; + for(i = 0; i < 40 && !done; i++) { + done = AutoPlace(myplr, i, cursW / 28, cursH / 28, FALSE); + } + if(done) { + StartStore(STORE_CONFIRM); + } else { + StartStore(STORE_NOROOM); + } + SetCursor_(CURSOR_HAND); + } + } else { + stextflag = 0; + } +} + +void StoryIdItem() +{ + int i, idx; + + idx = stextvhold + ((stextlhold - stextup) >> 2); + + i = storehidx[idx]; + if(i < 0) { + if(i == -1) { + plr[myplr].InvBody[0]._iIdentified = TRUE; + } + if(i == -2) { + plr[myplr].InvBody[6]._iIdentified = TRUE; + } + if(i == -3) { + plr[myplr].InvBody[4]._iIdentified = TRUE; + } + if(i == -4) { + plr[myplr].InvBody[5]._iIdentified = TRUE; + } + if(i == -5) { + plr[myplr].InvBody[1]._iIdentified = TRUE; + } + if(i == -6) { + plr[myplr].InvBody[2]._iIdentified = TRUE; + } + if(i == -7) { + plr[myplr].InvBody[3]._iIdentified = TRUE; + } + } else { + plr[myplr].InvList[i]._iIdentified = TRUE; + } + + plr[myplr].HoldItem._iIdentified = TRUE; + + TakePlrsMoney(plr[myplr].HoldItem._iIvalue); + CalcPlrInv(myplr, TRUE); +} + +void S_ConfirmEnter() +{ + if(stextsel == 18) { + switch(stextshold) { + case STORE_SBUY: + SmithBuyItem(); + break; + case STORE_SPBUY: + SmithBuyPItem(); + break; + case STORE_SSELL: + case STORE_WSELL: + StoreSellItem(); + break; + case STORE_SREPAIR: + SmithRepairItem(); + break; + case STORE_WBUY: + WitchBuyItem(); + break; + case STORE_WRECHARGE: + WitchRechargeItem(); + break; + case STORE_BBOY: + BoyBuyItem(); + break; + case STORE_HBUY: + HealerBuyItem(); + break; + case STORE_SIDENTIFY: + StoryIdItem(); + StartStore(STORE_IDSHOW); + return; + } + StartStore(stextshold); + } else { + StartStore(stextshold); + stextsel = stextlhold; + stextsval = stextvhold; + } +} + +void S_HealerEnter() +{ + switch(stextsel) { + case 12: + talker = TOWN_HEALER; + stextshold = STORE_HEALER; + stextlhold = stextsel; + gossipstart = TEXT_PEPIN2; + gossipend = TEXT_PEPIN11; + StartStore(STORE_GOSSIP); + break; + case 14: + if(plr[myplr]._pHitPoints != plr[myplr]._pMaxHP) { + PlaySFX(IS_CAST8); + } + plr[myplr]._pHitPoints = plr[myplr]._pMaxHP; + plr[myplr]._pHPBase = plr[myplr]._pMaxHPBase; + drawhpflag = 1; + break; + case 16: + StartStore(STORE_HBUY); + break; + case 18: + stextflag = 0; + break; + } +} + +void S_HBuyEnter() +{ + int idx, i; + BOOL done; + + if(stextsel == 22) { + StartStore(STORE_HEALER); + stextsel = 16; + } else { + stextshold = STORE_HBUY; + stextlhold = stextsel; + stextvhold = stextsval; + idx = stextsval + ((stextsel - stextup) >> 2); + if(plr[myplr]._pGold < healitem[idx]._iIvalue) { + StartStore(STORE_NOMONEY); + } else { + plr[myplr].HoldItem = healitem[idx]; + SetCursor_(plr[myplr].HoldItem._iCurs + 12); + done = FALSE; + for(i = 0; i < 40 && !done; i++) { + done = SpecialAutoPlace(myplr, i, cursW / 28, cursH / 28, FALSE); + } + if(done) { + StartStore(STORE_CONFIRM); + } else { + StartStore(STORE_NOROOM); + } + SetCursor_(CURSOR_HAND); + } + } +} + +void S_StoryEnter() +{ + switch(stextsel) { + case 12: + talker = TOWN_STORY; + stextshold = STORE_STORY; + stextlhold = stextsel; + gossipstart = TEXT_STORY2; + gossipend = TEXT_STORY11; + StartStore(STORE_GOSSIP); + break; + case 14: + StartStore(STORE_SIDENTIFY); + break; + case 18: + stextflag = 0; + break; + } +} + +void S_SIDEnter() +{ + int idx; + + if(stextsel == 22) { + StartStore(STORE_STORY); + stextsel = 14; + } else { + stextshold = STORE_SIDENTIFY; + stextlhold = stextsel; + stextvhold = stextsval; + idx = stextsval + ((stextsel - stextup) >> 2); + plr[myplr].HoldItem = storehold[idx]; + if(plr[myplr]._pGold < storehold[idx]._iIvalue) { + StartStore(STORE_NOMONEY); + } else { + StartStore(STORE_CONFIRM); + } + } +} + +void S_TalkEnter() +{ + int i, tq, sn, la, gl, m; + + if(stextsel == 22) { + StartStore(stextshold); + stextsel = stextlhold; + } else { + tq = 0; + for(i = 0; i < MAXQUESTS; i++) { + if(quests[i]._qactive == 2 && Qtalklist[talker][i] != -1 && quests[i]._qlog) { + tq++; + } + } + if(tq > 6) { + sn = 14 - (tq >> 1); + la = 1; + } else { + sn = 15 - tq; + la = 2; + } + gl = sn - 2; + if(stextsel == gl) { + SetRndSeed(towner[talker]._tSeed); + m = random(0, gossipend - gossipstart + 1) + gossipstart; + InitQTextMsg(m); + } else { + for(i = 0; i < MAXQUESTS; i++) { + if(quests[i]._qactive == 2 && Qtalklist[talker][i] != -1 && quests[i]._qlog) { + if(sn == stextsel) { + InitQTextMsg(Qtalklist[talker][i]); + } + sn += la; + } + } + } + } +} + +void S_TavernEnter() +{ + switch(stextsel) { + case 12: + talker = TOWN_TAVERN; + stextshold = STORE_TAVERN; + stextlhold = 12; + gossipstart = TEXT_OGDEN2; + gossipend = TEXT_OGDEN10; + StartStore(STORE_GOSSIP); + break; + case 18: + stextflag = 0; + break; + } +} + +void S_BarmaidEnter() +{ + switch(stextsel) { + case 12: + talker = TOWN_BMAID; + stextshold = STORE_BARMAID; + stextlhold = 12; + gossipstart = TEXT_GILLIAN2; + gossipend = TEXT_GILLIAN10; + StartStore(STORE_GOSSIP); + break; + case 18: + stextflag = 0; + break; + } +} + +void S_DrunkEnter() +{ + switch(stextsel) { + case 12: + talker = TOWN_DRUNK; + stextshold = STORE_DRUNK; + stextlhold = 12; + gossipstart = TEXT_FARNHAM2; + gossipend = TEXT_FARNHAM13; + StartStore(STORE_GOSSIP); + break; + case 18: + stextflag = 0; + break; + } +} + +void STextEnter() +{ + if(qtextflag) { + qtextflag = 0; + if(leveltype == DTYPE_TOWN) { + stream_stop(); + } + return; + } + + PlaySFX(IS_TITLSLCT); + + switch(stextflag) { + case STORE_SMITH: + S_SmithEnter(); + break; + case STORE_SBUY: + S_SBuyEnter(); + break; + case STORE_SPBUY: + S_SPBuyEnter(); + break; + case STORE_SSELL: + S_SSellEnter(); + break; + case STORE_SREPAIR: + S_SRepairEnter(); + break; + case STORE_WITCH: + S_WitchEnter(); + break; + case STORE_WBUY: + S_WBuyEnter(); + break; + case STORE_WSELL: + S_WSellEnter(); + break; + case STORE_WRECHARGE: + S_WRechargeEnter(); + break; + case STORE_NOMONEY: + case STORE_NOROOM: + StartStore(stextshold); + stextsel = stextlhold; + stextsval = stextvhold; + break; + case STORE_CONFIRM: + S_ConfirmEnter(); + break; + case STORE_BOY: + S_BoyEnter(); + break; + case STORE_BBOY: + S_BBuyEnter(); + break; + case STORE_HEALER: + S_HealerEnter(); + break; + case STORE_STORY: + S_StoryEnter(); + break; + case STORE_HBUY: + S_HBuyEnter(); + break; + case STORE_SIDENTIFY: + S_SIDEnter(); + break; + case STORE_GOSSIP: + S_TalkEnter(); + break; + case STORE_IDSHOW: + StartStore(STORE_SIDENTIFY); + break; + case STORE_TAVERN: + S_TavernEnter(); + break; + case STORE_BARMAID: + S_BarmaidEnter(); + break; + case STORE_DRUNK: + S_DrunkEnter(); + break; + } +} + +void CheckStoreBtn() +{ + int y; + + if(qtextflag) { + qtextflag = 0; + if(leveltype == DTYPE_TOWN) { + stream_stop(); + } + return; + } + + if(stextsel == -1) { + return; + } + if(MouseY < 32 || MouseY > 320) { + return; + } + if(stextsize == 0) { + if(MouseX < 344 || MouseX > 616) { + return; + } + } else { + if(MouseX < 24 || MouseX > 616) { + return; + } + } + + y = (MouseY - 32) / 12; + if(stextscrl && MouseX > 600) { + if(y == 4) { + if(stextscrlubtn <= 0) { + STextUp(); + stextscrlubtn = 10; + } else { + stextscrlubtn--; + } + } + if(y == 20) { + if(stextscrldbtn <= 0) { + STextDown(); + stextscrldbtn = 10; + } else { + stextscrldbtn--; + } + } + } else if(y >= 5) { + if(y >= 23) { + y = 22; + } + if(stextscrl && y < 21 && !stext[y]._ssel) { + if(stext[y - 2]._ssel) { + y -= 2; + } else if(stext[y - 1]._ssel) { + y--; + } + } + if(stext[y]._ssel || stextscrl && y == 22) { + stextsel = y; + STextEnter(); + } + } +} + +void ReleaseStoreBtn() +{ + stextscrlubtn = -1; + stextscrldbtn = -1; +} diff --git a/2020_03_31/Source/stores.h b/2020_03_31/Source/stores.h new file mode 100644 index 00000000..6b55781e --- /dev/null +++ b/2020_03_31/Source/stores.h @@ -0,0 +1,140 @@ +//HEADER_GOES_HERE +#ifndef __STORES_H__ +#define __STORES_H__ + +extern int stextup; // weak +extern int storenumh; // weak +extern int stextlhold; // weak +extern ItemStruct boyitem; +extern int stextshold; // idb +extern ItemStruct premiumitem[6]; +extern void *pSTextBoxCels; +extern int premiumlevel; // idb +extern int talker; // weak +extern STextStruct stext[24]; +extern char stextsize; // weak +extern int stextsmax; // weak +extern int sspinframe; // idb +extern ItemStruct storehold[48]; +extern int gossipstart; // weak +extern ItemStruct witchitem[20]; +extern BOOL stextscrl; // weak +extern int numpremium; // idb +extern ItemStruct healitem[20]; +extern ItemStruct golditem; +extern char storehidx[48]; +extern void *pSTextSlidCels; +extern int stextvhold; // weak +extern int stextsel; // weak +extern char stextscrldbtn; // weak +extern int gossipend; // weak +extern void *pSPentSpnCels; +extern int stextsval; // idb +extern int boylevel; // weak +extern ItemStruct smithitem[20]; +extern int stextdown; // weak +extern char stextscrlubtn; // weak +extern char stextflag; // weak + +void InitStores(); +void SetupTownStores(); +void FreeStoreMem(); +void DrawSTextBack(); +void PrintSString(int x, int y, BOOL cjustflag, char *str, char col, int val); +void DrawSLine(int y); +void DrawSSlider(int y1, int y2); +void DrawSTextHelp(); +void ClearSText(int s, int e); +void AddSLine(int y); +void AddSTextVal(int y, int val); +void OffsetSTextY(int y, int yo); +void AddSText(int x, int y, BOOL j, char *str, char clr, BOOL sel); +void StoreAutoPlace(); +void S_StartSmith(); +void S_ScrollSBuy(int idx); +void PrintStoreItem(const ItemStruct *x, int l, char iclr); +void S_StartSBuy(); +void S_ScrollSPBuy(int idx); +BOOL S_StartSPBuy(); +BOOL SmithSellOk(int i); +void S_ScrollSSell(int idx); +void S_StartSSell(); +BOOL SmithRepairOk(int i); +void S_StartSRepair(); +void AddStoreHoldRepair(ItemStruct *itm, int i); +void S_StartWitch(); +void S_ScrollWBuy(int idx); +void S_StartWBuy(); +BOOL WitchSellOk(int i); +void S_StartWSell(); +BOOL WitchRechargeOk(int i); +void AddStoreHoldRecharge(ItemStruct itm, int i); +void S_StartWRecharge(); +void S_StartNoMoney(); +void S_StartNoRoom(); +void S_StartConfirm(); +void S_StartBoy(); +void S_StartBBoy(); +void S_StartHealer(); +void S_ScrollHBuy(int idx); +void S_StartHBuy(); +void S_StartStory(); +BOOL IdItemOk(ItemStruct *i); +void AddStoreHoldId(ItemStruct itm, int i); +void S_StartSIdentify(); +void S_StartIdShow(); +void S_StartTalk(); +void S_StartTavern(); +void S_StartBarMaid(); +void S_StartDrunk(); +void StartStore(char s); +void DrawSText(); +void STextESC(); +void STextUp(); +void STextDown(); +void STextPrior(); +void STextNext(); +void S_SmithEnter(); +void SetGoldCurs(int pnum, int i); +void SetSpdbarGoldCurs(int pnum, int i); +void TakePlrsMoney(long cost); +void SmithBuyItem(); +void S_SBuyEnter(); +void SmithBuyPItem(); +void S_SPBuyEnter(); +BOOL StoreGoldFit(int idx); +void PlaceStoreGold(long v); +void StoreSellItem(); +void S_SSellEnter(); +void SmithRepairItem(); +void S_SRepairEnter(); +void S_WitchEnter(); +void WitchBuyItem(); +void S_WBuyEnter(); +void S_WSellEnter(); +void WitchRechargeItem(); +void S_WRechargeEnter(); +void S_BoyEnter(); +void BoyBuyItem(); +void HealerBuyItem(); +void S_BBuyEnter(); +void StoryIdItem(); +void S_ConfirmEnter(); +void S_HealerEnter(); +void S_HBuyEnter(); +void S_StoryEnter(); +void S_SIDEnter(); +void S_TalkEnter(); +void S_TavernEnter(); +void S_BarmaidEnter(); +void S_DrunkEnter(); +void STextEnter(); +void CheckStoreBtn(); +void ReleaseStoreBtn(); + +/* rdata */ + +extern int SStringY[24]; +extern char *talkname[9]; + +#endif /* __STORES_H__ */ diff --git a/2020_03_31/Source/sync.cpp b/2020_03_31/Source/sync.cpp new file mode 100644 index 00000000..072d2545 --- /dev/null +++ b/2020_03_31/Source/sync.cpp @@ -0,0 +1,285 @@ +#include "diablo.h" + +WORD sync_word_6AA708[MAXMONSTERS]; +int sgnMonsters; +WORD sgwLRU[MAXMONSTERS]; +int sgnSyncItem; +int sgnSyncPInv; + +DWORD sync_all_monsters(const BYTE *pbBuf, DWORD dwMaxLen) +{ + TSyncHeader *pHdr; + int i; + BOOL sync; + + if(nummonsters < 1) { + return dwMaxLen; + } + if(dwMaxLen < sizeof(*pHdr) + sizeof(TSyncMonster)) { + return dwMaxLen; + } + + pHdr = (TSyncHeader *)pbBuf; + pbBuf += sizeof(*pHdr); + dwMaxLen -= sizeof(*pHdr); + + pHdr->bCmd = CMD_SYNCDATA; + pHdr->bLevel = currlevel; + pHdr->wLen = 0; + SyncPlrInv(pHdr); + /// ASSERT: assert(dwMaxLen <= 0xffff); + sync_one_monster(); + + for(i = 0; i < nummonsters && dwMaxLen >= sizeof(TSyncMonster); i++) { + sync = FALSE; + if(i < 2) { + sync = sync_monster_active2((TSyncMonster *)pbBuf); + } + if(!sync) { + sync = sync_monster_active((TSyncMonster *)pbBuf); + } + if(!sync) { + break; + } + pbBuf += sizeof(TSyncMonster); + pHdr->wLen += sizeof(TSyncMonster); + dwMaxLen -= sizeof(TSyncMonster); + } + + return dwMaxLen; +} + +void sync_one_monster() +{ + int i, m; + + for(i = 0; i < nummonsters; i++) { + m = monstactive[i]; + sync_word_6AA708[m] = abs(plr[myplr].WorldX - monster[m]._mx) + abs(plr[myplr].WorldY - monster[m]._my); + if(monster[m]._msquelch == 0) { + sync_word_6AA708[m] += 0x1000; + } else if(sgwLRU[m] != 0) { + sgwLRU[m]--; + } + } +} + +BOOL sync_monster_active(TSyncMonster *p) +{ + int i, m, ndx; + DWORD lru; + + ndx = -1; + lru = 0xFFFFFFFF; + + for(i = 0; i < nummonsters; i++) { + m = monstactive[i]; + if(sync_word_6AA708[m] < lru && sgwLRU[m] < 0xFFFE) { + lru = sync_word_6AA708[m]; + ndx = monstactive[i]; + } + } + + if(ndx == -1) { + return FALSE; + } + + sync_monster_pos(p, ndx); + return TRUE; +} + +void sync_monster_pos(TSyncMonster *p, int ndx) +{ + p->_mndx = ndx; + p->_mx = monster[ndx]._mx; + p->_my = monster[ndx]._my; + p->_menemy = encode_enemy(ndx); + p->_mdelta = sync_word_6AA708[ndx] > 255 ? 255 : sync_word_6AA708[ndx]; + + sync_word_6AA708[ndx] = 0xFFFF; + sgwLRU[ndx] = monster[ndx]._msquelch == 0 ? 0xFFFF : 0xFFFE; +} + +BOOL sync_monster_active2(TSyncMonster *p) +{ + int i, m, ndx; + DWORD lru; + + ndx = -1; + lru = 0xFFFE; + + for(i = 0; i < nummonsters; i++) { + if(sgnMonsters >= nummonsters) { + sgnMonsters = 0; + } + m = monstactive[sgnMonsters]; + if(sgwLRU[m] < lru) { + lru = sgwLRU[m]; + ndx = monstactive[sgnMonsters]; + } + sgnMonsters++; + } + + if(ndx == -1) { + return FALSE; + } + + sync_monster_pos(p, ndx); + return TRUE; +} + +void SyncPlrInv(TSyncHeader *pHdr) +{ + int ii; + ItemStruct *pItem; + + if(numitems > 0) { + if(sgnSyncItem >= numitems) { + sgnSyncItem = 0; + } + ii = itemactive[sgnSyncItem++]; + pHdr->bItemI = ii; + pHdr->bItemX = item[ii]._ix; + pHdr->bItemY = item[ii]._iy; + pHdr->wItemIndx = item[ii].IDidx; + if(item[ii].IDidx == IDI_EAR) { + pHdr->wItemCI = (item[ii]._iName[7] << 8) | item[ii]._iName[8]; + pHdr->dwItemSeed = (item[ii]._iName[9] << 24) | (item[ii]._iName[10] << 16) | (item[ii]._iName[11] << 8) | item[ii]._iName[12]; + pHdr->bItemId = item[ii]._iName[13]; + pHdr->bItemDur = item[ii]._iName[14]; + pHdr->bItemMDur = item[ii]._iName[15]; + pHdr->bItemCh = item[ii]._iName[16]; + pHdr->bItemMCh = item[ii]._iName[17]; + pHdr->wItemVal = (item[ii]._iName[18] << 8) | ((item[ii]._iCurs - 19) << 6) | item[ii]._ivalue; + pHdr->dwItemBuff = (item[ii]._iName[19] << 24) | (item[ii]._iName[20] << 16) | (item[ii]._iName[21] << 8) | item[ii]._iName[22]; + } else { + pHdr->wItemCI = item[ii]._iCreateInfo; + pHdr->dwItemSeed = item[ii]._iSeed; + pHdr->bItemId = item[ii]._iIdentified; + pHdr->bItemDur = item[ii]._iDurability; + pHdr->bItemMDur = item[ii]._iMaxDur; + pHdr->bItemCh = item[ii]._iCharges; + pHdr->bItemMCh = item[ii]._iMaxCharges; + if(item[ii].IDidx == IDI_GOLD) { + pHdr->wItemVal = item[ii]._ivalue; + } + } + } else { + pHdr->bItemI = -1; + } + + /// ASSERT: assert((DWORD) sgnSyncPInv < NUM_INVLOC); + pItem = &plr[myplr].InvBody[sgnSyncPInv]; + if(pItem->_itype != -1) { + pHdr->bPInvLoc = sgnSyncPInv; + pHdr->wPInvIndx = pItem->IDidx; + pHdr->wPInvCI = pItem->_iCreateInfo; + pHdr->dwPInvSeed = pItem->_iSeed; + pHdr->bPInvId = pItem->_iIdentified; + } else { + pHdr->bPInvLoc = -1; + } + + sgnSyncPInv++; + if(sgnSyncPInv >= NUM_INVLOC) { + sgnSyncPInv = 0; + } +} + +DWORD sync_update(int pnum, const BYTE *pbBuf) +{ + TSyncHeader *pHdr; + WORD wLen; + + pHdr = (TSyncHeader *)pbBuf; + pbBuf += sizeof(*pHdr); + + if(pHdr->bCmd != CMD_SYNCDATA) { + app_fatal("bad sync command"); + } + + /// ASSERT: assert(gbBufferMsgs != BUFFER_PROCESS); + + if(gbBufferMsgs == 1) { + return pHdr->wLen + sizeof(*pHdr); + } + if(pnum == myplr) { + return pHdr->wLen + sizeof(*pHdr); + } + + for(wLen = pHdr->wLen; wLen >= sizeof(TSyncMonster); wLen -= sizeof(TSyncMonster)) { + if(currlevel == pHdr->bLevel) { + sync_monster(pnum, (TSyncMonster *)pbBuf); + } + delta_sync_monster((TSyncMonster *)pbBuf, pHdr->bLevel); + pbBuf += sizeof(TSyncMonster); + } + + /// ASSERT: assert(wLen == 0); + + return pHdr->wLen + sizeof(*pHdr); +} + +void sync_monster(int pnum, const TSyncMonster *p) +{ + int i, ndx, md, mdx, mdy; + DWORD delta; + + ndx = p->_mndx; + + if(monster[ndx]._mhitpoints == 0) { + return; + } + + for(i = 0; i < nummonsters; i++) { + if(monstactive[i] == ndx) { + break; + } + } + + delta = abs(plr[myplr].WorldX - monster[ndx]._mx) + abs(plr[myplr].WorldY - monster[ndx]._my); + if(delta > 255) { + delta = 255; + } + + if(delta < p->_mdelta || (delta == p->_mdelta && pnum > myplr)) { + return; + } + if(monster[ndx]._mfutx == p->_mx && monster[ndx]._mfuty == p->_my) { + return; + } + if(monster[ndx]._mmode == MM_CHARGE || monster[ndx]._mmode == MM_STONE) { + return; + } + + mdx = abs(monster[ndx]._mx - p->_mx); + mdy = abs(monster[ndx]._my - p->_my); + if(mdx <= 2 && mdy <= 2) { + if(monster[ndx]._mmode < MM_WALK || monster[ndx]._mmode > MM_WALK3) { + md = GetDirection(monster[ndx]._mx, monster[ndx]._my, p->_mx, p->_my); + if(DirOK(ndx, md)) { + M_ClearSquares(ndx); + dMonster[monster[ndx]._mx][monster[ndx]._my] = ndx + 1; + M_WalkDir(ndx, md); + monster[ndx]._msquelch = -1; + } + } + } else if(dMonster[p->_mx][p->_my] == 0) { + M_ClearSquares(ndx); + dMonster[p->_mx][p->_my] = ndx + 1; + monster[ndx]._mx = p->_mx; + monster[ndx]._my = p->_my; + decode_enemy(ndx, p->_menemy); + md = GetDirection(p->_mx, p->_my, monster[ndx]._menemyx, monster[ndx]._menemyy); + M_StartStand(ndx, md); + monster[ndx]._msquelch = -1; + } + + decode_enemy(ndx, p->_menemy); +} + +void sync_init() +{ + sgnMonsters = 16 * myplr; + memset(sgwLRU, 255, sizeof(sgwLRU)); +} diff --git a/2020_03_31/Source/sync.h b/2020_03_31/Source/sync.h new file mode 100644 index 00000000..de67bf55 --- /dev/null +++ b/2020_03_31/Source/sync.h @@ -0,0 +1,21 @@ +//HEADER_GOES_HERE +#ifndef __SYNC_H__ +#define __SYNC_H__ + +extern WORD sync_word_6AA708[MAXMONSTERS]; +extern int sgnMonsters; +extern WORD sgwLRU[MAXMONSTERS]; +extern int sgnSyncItem; +extern int sgnSyncPInv; + +DWORD sync_all_monsters(const BYTE *pbBuf, DWORD dwMaxLen); +void sync_one_monster(); +BOOL sync_monster_active(TSyncMonster *p); +void sync_monster_pos(TSyncMonster *p, int ndx); +BOOL sync_monster_active2(TSyncMonster *p); +void SyncPlrInv(TSyncHeader *pHdr); +DWORD sync_update(int pnum, const BYTE *pbBuf); +void sync_monster(int pnum, const TSyncMonster *p); +void sync_init(); + +#endif /* __SYNC_H__ */ diff --git a/2020_03_31/Source/textdat.cpp b/2020_03_31/Source/textdat.cpp new file mode 100644 index 00000000..7eddd06a --- /dev/null +++ b/2020_03_31/Source/textdat.cpp @@ -0,0 +1,9 @@ +#include "diablo.h" + +/* todo: move text out of struct */ + +const TextDataStruct alltext[259] = +{ +#include "Data/speech.cpp" +}; +const int gdwAllTextEntries = 259; /* unused */ diff --git a/2020_03_31/Source/textdat.h b/2020_03_31/Source/textdat.h new file mode 100644 index 00000000..d3b5aac1 --- /dev/null +++ b/2020_03_31/Source/textdat.h @@ -0,0 +1,8 @@ +//HEADER_GOES_HERE +#ifndef __TEXTDAT_H__ +#define __TEXTDAT_H__ + +extern const TextDataStruct alltext[259]; +extern const int gdwAllTextEntries; + +#endif /* __TEXTDAT_H__ */ diff --git a/2020_03_31/Source/themes.cpp b/2020_03_31/Source/themes.cpp new file mode 100644 index 00000000..830d88e4 --- /dev/null +++ b/2020_03_31/Source/themes.cpp @@ -0,0 +1,1414 @@ +#include "diablo.h" + +int numthemes; // idb +BOOL armorFlag; // weak +int ThemeGoodIn[4]; +BOOL weaponFlag; // weak +BOOL treasureFlag; // weak +BOOL mFountainFlag; // weak +BOOL cauldronFlag; // weak +BOOL tFountainFlag; // weak +int zharlib; // weak +int themex; // idb +int themey; // idb +int themeVar1; // idb +ThemeStruct themes[MAXTHEMES]; +BOOL pFountainFlag; // weak +BOOL bFountainFlag; // weak +BOOL bCrossFlag; // weak + +int ThemeGood[4] = { THEME_GOATSHRINE, THEME_SHRINE, THEME_SKELROOM, THEME_LIBRARY }; + +int trm5x[25] = +{ + -2, -1, 0, 1, 2, + -2, -1, 0, 1, 2, + -2, -1, 0, 1, 2, + -2, -1, 0, 1, 2, + -2, -1, 0, 1, 2 +}; + +int trm5y[25] = +{ + -2, -2, -2, -2, -2, + -1, -1, -1, -1, -1, + 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, + 2, 2, 2, 2, 2 +}; + +int trm3x[9] = +{ + -1, 0, 1, + -1, 0, 1, + -1, 0, 1 +}; + +int trm3y[9] = +{ + -1, -1, -1, + 0, 0, 0, + 1, 1, 1 +}; + +_bool TFit_Shrine(int i) +{ + int v1; // ecx + int v2; // esi + int v3; // eax + int v4; // edx + signed int v6; // [esp+Ch] [ebp-8h] + int v7; // [esp+10h] [ebp-4h] + + v1 = themes[i].ttval; + v7 = 0; + v2 = 0; + v6 = 0; + while ( 1 ) + { + v3 = v2 + 112 * v7; + if ( dTransVal[0][v3] != v1 ) /* check */ + goto LABEL_20; + v4 = dPiece[0][v3 - 1]; // *(_DWORD *)&dflags[39][4 * v3 + 36]; + if ( nTrapTable[v4] + && !nSolidTable[dPiece[-1][v3]] // !nSolidTable[*(_DWORD *)&dflags[28][4 * v3 + 32]] + && !nSolidTable[dPiece[1][v3]] + && dTransVal[-1][v3] == v1 // block_lvid[v3 + 1940] == v1 + && dTransVal[1][v3] == v1 + && !dObject[-1][v3 - 1] + && !dObject[0][v3 + 111] ) + { + v6 = 1; + } + if ( v6 ) + break; + if ( !nTrapTable[dPiece[-1][v3]] // !nTrapTable[*(_DWORD *)&dflags[28][4 * v3 + 32]] + || nSolidTable[v4] + || nSolidTable[dPiece[0][v3 + 1]] + || dTransVal[0][v3 - 1] != v1 // *(&byte_5B78EB + v3) != v1 + || dTransVal[0][v3 + 1] != v1 + || dObject[-1][v3 - 1] + || dObject[-1][v3 + 1] ) /* check */ + { + goto LABEL_21; + } + v6 = 2; +LABEL_20: + if ( v6 ) + break; +LABEL_21: + if ( ++v7 == 112 ) + { + ++v2; + v7 = 0; + if ( v2 == 112 ) + return 0; + } + } + themey = v2; + themex = v7; + themeVar1 = v6; + return 1; +} + +_bool TFit_Obj5(int t) +{ + int v2; // ebx + int v3; // esi + int v4; // eax + int v5; // edi + int v6; // ecx + signed int v7; // edx + int v8; // ecx + int v10; // [esp+Ch] [ebp-Ch] + int v11; // [esp+10h] [ebp-8h] + signed int v12; // [esp+14h] [ebp-4h] + + v2 = 0; + v3 = 0; + v4 = random(0, 5) + 1; + v10 = v4; + if ( v4 <= 0 ) + { +LABEL_19: + themex = v2; + themey = v3; + return 1; + } + v5 = themes[t].ttval; + v11 = v5; + while ( 1 ) + { + v6 = v3 + 112 * v2; + if ( dTransVal[0][v6] == v5 && !nSolidTable[dPiece[0][v6]] ) + { + v12 = 1; + v7 = 0; + do + { + if ( v7 >= 25 ) + break; + v8 = v3 + trm5y[v7] + 112 * (v2 + trm5x[v7]); + if ( nSolidTable[dPiece[0][v8]] ) + v12 = 0; + v5 = v11; + if ( dTransVal[0][v8] != v11 ) + v12 = 0; + ++v7; + } + while ( v12 ); + if ( v12 ) + { + --v4; + goto LABEL_18; + } + } + if ( ++v2 != 112 ) + goto LABEL_18; + v2 = 0; + if ( ++v3 != 112 ) + goto LABEL_18; + if ( v4 == v10 ) + return 0; + v3 = 0; +LABEL_18: + if ( v4 <= 0 ) + goto LABEL_19; + } +} + +_bool TFit_SkelRoom(int t) +{ + int i; // esi + + if ( leveltype != 1 && leveltype != 2 ) + return 0; + i = 0; + if ( nummtypes <= 0 ) + return 0; + + while ( !IsSkel(Monsters[i].mtype) ) + { + ++i; + if ( i >= nummtypes ) + return 0; + } + themeVar1 = i; + return TFit_Obj5(t); +} + +_bool TFit_GoatShrine(int t) +{ + int i; // esi + + i = 0; + if ( nummtypes <= 0 ) + return 0; + + while ( !IsGoat(Monsters[i].mtype) ) + { + ++i; + if ( i >= nummtypes ) + return 0; + } + themeVar1 = i; + return TFit_Obj5(t); +} + +_bool CheckThemeObj3(int xp, int yp, int t, int f) +{ + int i; // edi + + i = 0; + while ( 1 ) + { + if ( xp + trm3x[i] < 0 ) + break; + if ( yp + trm3y[i] < 0 ) + break; + if ( nSolidTable[dPiece[xp + trm3x[i]][yp + trm3y[i]]] ) + break; + if ( dTransVal[xp + trm3x[i]][yp + trm3y[i]] != themes[t].ttval ) + break; + if ( dObject[xp + trm3x[i]][yp + trm3y[i]] ) + break; + if ( f != -1 ) + { + if ( !random(0, f) ) + break; + } + ++i; + if ( i >= 9 ) + return 1; + } + return 0; +} + +_bool TFit_Obj3(int t) +{ + int yp; // edi + int xp; // esi + char objrnd[4]; // [esp+Bh] [ebp-5h] + + objrnd[0] = 4; + objrnd[1] = 4; + objrnd[2] = 3; + objrnd[3] = 5; + yp = 1; + while ( 2 ) + { + xp = 1; + do + { + if ( CheckThemeObj3(xp, yp, t, objrnd[leveltype-1]) ) + { + themex = xp; + themey = yp; + return 1; + } + ++xp; + } + while ( xp < 111 ); + if ( ++yp < 111 ) + continue; + break; + } + return 0; +} + +_bool CheckThemeReqs(int t) +{ + _bool rv; // al + int v2; // ecx + int v3; // ecx + int v4; // ecx + int v5; // ecx + _bool v6; // zf + int v7; // ecx + int v8; // ecx + int v9; // ecx + + rv = 1; + if ( t <= 10 ) + { + if ( t != 10 ) + { + v2 = t - 1; + if ( v2 ) + { + v3 = v2 - 2; + if ( v3 ) + { + v4 = v3 - 2; + if ( v4 ) + { + v5 = v4 - 2; + if ( v5 ) + { + if ( v5 != 2 ) + return rv; + v6 = pFountainFlag == 0; + } + else + { + v6 = bFountainFlag == 0; + } +LABEL_21: + if ( !v6 ) + return rv; + return 0; + } + } + } + if ( leveltype != 3 ) + { + v6 = leveltype == DTYPE_HELL; + goto LABEL_21; + } + return 0; + } +LABEL_16: + v6 = leveltype == DTYPE_CATHEDRAL; + goto LABEL_21; + } + v7 = t - 12; + if ( v7 ) + { + v8 = v7 - 1; + if ( !v8 ) + { + v6 = mFountainFlag == 0; + goto LABEL_21; + } + v9 = v8 - 1; + if ( !v9 ) + { + v6 = tFountainFlag == 0; + goto LABEL_21; + } + if ( v9 != 2 ) + return rv; + goto LABEL_16; + } + if ( leveltype == DTYPE_HELL ) + { + v6 = cauldronFlag == 0; + goto LABEL_21; + } + return 0; +} + +_bool SpecialThemeFit(int i, int t) +{ + _bool rv; // eax + + rv = CheckThemeReqs(t); + switch ( t ) + { + case THEME_SHRINE: + case THEME_LIBRARY: + if ( rv ) + rv = TFit_Shrine(i); + break; + case THEME_SKELROOM: + if ( rv ) + rv = TFit_SkelRoom(i); + break; + case THEME_TREASURE: + rv = treasureFlag; + if ( treasureFlag ) + treasureFlag = 0; + break; + case THEME_TORTURE: + case THEME_DECAPITATED: + case THEME_ARMORSTAND: + case THEME_BRNCROSS: + case THEME_WEAPONRACK: + if ( rv ) + rv = TFit_Obj3(i); + break; + case THEME_BLOODFOUNTAIN: + if ( rv ) + { + rv = TFit_Obj5(i); + if ( rv ) + bFountainFlag = 0; + } + break; + case THEME_PURIFYINGFOUNTAIN: + if ( rv ) + { + rv = TFit_Obj5(i); + if ( rv ) + pFountainFlag = 0; + } + break; + case THEME_GOATSHRINE: + if ( rv ) + rv = TFit_GoatShrine(i); + break; + case THEME_CAULDRON: + if ( rv ) + { + rv = TFit_Obj5(i); + if ( rv ) + cauldronFlag = 0; + } + break; + case THEME_MURKYFOUNTAIN: + if ( rv ) + { + rv = TFit_Obj5(i); + if ( rv ) + mFountainFlag = 0; + } + break; + case THEME_TEARFOUNTAIN: + if ( rv ) + { + rv = TFit_Obj5(i); + if ( rv ) + tFountainFlag = 0; + } + break; + default: + return rv; + } + return rv; +} + +_bool CheckThemeRoom(int tv) +{ + int v1; // esi + int *v2; // edx + signed int v3; // edi + signed int v4; // esi + signed int v5; // edx + signed int v6; // eax + int v7; // edi + int *v8; // esi + char *v9; // eax + int *v10; // edx + signed int v12; // [esp+Ch] [ebp-8h] + + v1 = 0; + if ( numtrigs <= 0 ) + { +LABEL_5: + v3 = 0; + v4 = 0; + do + { + v5 = 0; + v6 = v4; + do + { + if ( dTransVal[0][v6] == tv ) + { + if ( dFlags[0][v6] & 8 ) + return 0; + ++v3; + } + ++v5; + v6 += 112; + } + while ( v5 < 112 ); + ++v4; + } + while ( v4 < 112 ); + if ( leveltype != 1 || v3 >= 9 && v3 <= 100 ) + { + v7 = 0; + v8 = &dPiece[-1][111]; +LABEL_16: + v12 = 0; + v9 = &dTransVal[-1][v7 + 111]; + v10 = v8; + while ( v9[1] != tv + || nSolidTable[v10[1]] + || (*(v9 - 111) == tv || nSolidTable[*(v10 - 111)]) /* check */ + && (v9[113] == tv || nSolidTable[v10[113]]) + && (*v9 == tv || nSolidTable[*v10]) + && (v9[2] == tv || nSolidTable[v10[2]]) ) + { + ++v12; + v10 += 112; + v9 += 112; + if ( v12 >= 112 ) + { + ++v8; + ++v7; + if ( (signed int)v8 < (signed int)&dPiece[0][111] ) + goto LABEL_16; + return 1; + } + } + } + } + else + { + v2 = &trigs[0]._ty; + while ( dTransVal[*(v2 - 1)][*v2] != tv ) + { + ++v1; + v2 += 4; + if ( v1 >= numtrigs ) + goto LABEL_5; + } + } + return 0; +} + +void InitThemes() +{ + int v0; // esi + char v1; // bl + int v2; // edi + //int v3; // eax + int i; // ebx + //int v6; // eax + int v8; // esi + int v9; // ecx + int j; // eax + //int v11; // eax + int *v13; // edi + int v14; // esi + int *v15; // ebx + //int v16; // eax + int v17; // eax + int k; // esi + int l; // ebx + //int v20; // eax + + zharlib = -1; + v0 = 0; + bCrossFlag = 0; + numthemes = 0; + armorFlag = 1; + bFountainFlag = 1; + cauldronFlag = 1; + mFountainFlag = 1; + pFountainFlag = 1; + tFountainFlag = 1; + treasureFlag = 1; + weaponFlag = 1; + if ( currlevel != 16 ) + { + v1 = leveltype; + if ( leveltype == DTYPE_CATHEDRAL ) + { + ThemeGoodIn[0] = 0; + ThemeGoodIn[1] = 0; + ThemeGoodIn[2] = 0; + ThemeGoodIn[3] = 0; + v2 = 0; + do + { + if ( v0 >= MAXTHEMES ) + break; + //_LOBYTE(v3) = CheckThemeRoom(v2); + if ( CheckThemeRoom(v2) ) + { + themes[v0].ttval = v2; + for ( i = ThemeGood[random(0, 4)]; ; i = random(0, 17) ) + { + //_LOBYTE(v6) = SpecialThemeFit(numthemes, i); + if ( SpecialThemeFit(numthemes, i) ) + break; + } + v8 = numthemes; + themes[numthemes].ttype = i; + v1 = leveltype; + v0 = v8 + 1; + numthemes = v0; + } + ++v2; + } + while ( v2 < 256 ); + } + if ( v1 == 2 || v1 == 3 || v1 == 4 ) + { + v9 = themeCount; + for ( j = 0; j < v9; ++j ) + themes[j].ttype = -1; + //_LOBYTE(v11) = QuestStatus(3); + v13 = &themeLoc[0].ttval; + if ( QuestStatus(3) ) + { + v14 = 0; + if ( themeCount > 0 ) + { + v15 = &themeLoc[0].ttval; + while ( 1 ) + { + themes[v14].ttval = *v15; + //_LOBYTE(v16) = SpecialThemeFit(v14, 5); + if ( SpecialThemeFit(v14, 5) ) + break; + ++v14; + v15 += 5; + if ( v14 >= themeCount ) + goto LABEL_23; + } + themes[v14].ttype = 5; + zharlib = v14; + } + } +LABEL_23: + v17 = themeCount; + for ( k = 0; k < themeCount; v13 += 5 ) + { + if ( themes[k].ttype == -1 ) + { + themes[k].ttval = *v13; + for ( l = ThemeGood[random(0, 4)]; ; l = random(0, 17) ) + { + //_LOBYTE(v20) = SpecialThemeFit(k, l); + if ( SpecialThemeFit(k, l) ) + break; + } + themes[k].ttype = l; + } + v17 = themeCount; + ++k; + } + numthemes += v17; + } + } +} + +void HoldThemeRooms() +{ + int v0; // ebx + int i; // esi + char v2; // dl + signed int v3; // ecx + signed int v4; // eax + signed int v5; // edi + + if ( currlevel != 16 ) + { + if ( leveltype == DTYPE_CATHEDRAL ) + { + v0 = numthemes; + for ( i = 0; i < v0; ++i ) + { + v2 = themes[i].ttval; + v3 = 0; + do + { + v4 = v3; + v5 = 112; + do + { + if ( dTransVal[0][v4] == v2 ) + dFlags[0][v4] |= 8u; + v4 += 112; + --v5; + } + while ( v5 ); + ++v3; + } + while ( v3 < 112 ); + } + } + else + { + DRLG_HoldThemeRooms(); + } + } +} + +void PlaceThemeMonsts(int t, int f) +{ + int numscattypes; // edx + int i; // ecx + int yp; // ebx + int xp; // edi + int scattertypes[111]; // [esp+Ch] [ebp-1D0h] + int mtype; // [esp+1CCh] [ebp-10h] + + numscattypes = 0; + + if ( nummtypes > 0 ) + { + for(i = 0; i < nummtypes; i++) + { + if ( Monsters[i].mPlaceFlags & 1 ) + scattertypes[numscattypes++] = i; + } + } + + mtype = scattertypes[random(0, numscattypes)]; + + for(yp = 0; yp < 112; yp++) + { + for(xp = 0; xp < 112; xp++) + { + if ( dTransVal[xp][yp] == themes[t].ttval && !nSolidTable[dPiece[xp][yp]] && !dItem[xp][yp] && !dObject[xp][yp] ) + { + if ( !random(0, f) ) + AddMonster(xp, yp, random(0, 8), mtype, 1); + } + } + } +} + +void Theme_Barrel(int t) +{ + int yp; // edi + int xp; // ebx + int r; + char monstrnd[4]; + char barrnd[4]; + + barrnd[0] = 2; + barrnd[1] = 6; + barrnd[2] = 4; + barrnd[3] = 8; + monstrnd[0] = 5; + monstrnd[1] = 7; + monstrnd[2] = 3; + monstrnd[3] = 9; + + for(yp = 0; yp < 112; yp++) + { + for(xp = 0; xp < 112; xp++) + { + if ( dTransVal[xp][yp] == themes[t].ttval && !nSolidTable[dPiece[xp][yp]] ) + { + if ( !random(0, barrnd[leveltype-1]) ) + { + r = random(0, barrnd[leveltype-1]); + AddObject((r != 0) + OBJ_BARREL, xp, yp); + } + } + } + } + + PlaceThemeMonsts(t, monstrnd[leveltype-1]); +} + +void Theme_Shrine(int t) +{ + char monstrnd[4]; // [esp+3h] [ebp-5h] + + monstrnd[0] = 6; + monstrnd[1] = 6; + monstrnd[2] = 3; + monstrnd[3] = 9; + TFit_Shrine(t); + if ( themeVar1 == 1 ) + { + AddObject(OBJ_CANDLE2, themex - 1, themey); + AddObject(OBJ_SHRINER, themex, themey); + AddObject(OBJ_CANDLE2, themex + 1, themey); + } + else + { + AddObject(OBJ_CANDLE2, themex, themey - 1); + AddObject(OBJ_SHRINEL, themex, themey); + AddObject(OBJ_CANDLE2, themex, themey + 1); + } + PlaceThemeMonsts(t, monstrnd[leveltype-1]); +} + +void Theme_MonstPit(int t) +{ + int r; // eax + int ixp; // ecx + int iyp; // edx + char monstrnd[4]; // [esp+4h] [ebp-8h] + + monstrnd[0] = 6; + monstrnd[1] = 7; + monstrnd[2] = 3; + monstrnd[3] = 9; + r = random(0, 100) + 1; + ixp = 0; + iyp = 0; + if ( r > 0 ) + { + while ( 1 ) + { + if ( dTransVal[ixp][iyp] == themes[t].ttval && !nSolidTable[dPiece[ixp][iyp]] ) + --r; + if ( r <= 0 ) + break; + if ( ++ixp == 112 ) + { + ixp = 0; + if ( ++iyp == 112 ) + iyp = 0; + } + } + } + CreateRndItem(ixp, iyp, 1u, 0, 1); + ItemNoFlippy(); + PlaceThemeMonsts(t, monstrnd[leveltype-1]); +} + +void Theme_SkelRoom(int t) +{ + int xp, yp, i; + char monstrnd[4] = { 6, 7, 3, 9 }; + + TFit_SkelRoom(t); + + xp = themex; + yp = themey; + + AddObject(OBJ_SKFIRE, xp, yp); + + if(random(0, monstrnd[leveltype - 1]) != 0) { + i = PreSpawnSkeleton(); + SpawnSkeleton(i, xp - 1, yp - 1); + } else { + AddObject(OBJ_BANNERL, xp - 1, yp - 1); + } + + i = PreSpawnSkeleton(); + SpawnSkeleton(i, xp, yp - 1); + + if(random(0, monstrnd[leveltype - 1]) != 0) { + i = PreSpawnSkeleton(); + SpawnSkeleton(i, xp + 1, yp - 1); + } else { + AddObject(OBJ_BANNERR, xp + 1, yp - 1); + } + if(random(0, monstrnd[leveltype - 1]) != 0) { + i = PreSpawnSkeleton(); + SpawnSkeleton(i, xp - 1, yp); + } else { + AddObject(OBJ_BANNERM, xp - 1, yp); + } + if(random(0, monstrnd[leveltype - 1]) != 0) { + i = PreSpawnSkeleton(); + SpawnSkeleton(i, xp + 1, yp); + } else { + AddObject(OBJ_BANNERM, xp + 1, yp); + } + if(random(0, monstrnd[leveltype - 1]) != 0) { + i = PreSpawnSkeleton(); + SpawnSkeleton(i, xp - 1, yp + 1); + } else { + AddObject(OBJ_BANNERR, xp - 1, yp + 1); + } + + i = PreSpawnSkeleton(); + SpawnSkeleton(i, xp, yp + 1); + + if(random(0, monstrnd[leveltype - 1]) != 0) { + i = PreSpawnSkeleton(); + SpawnSkeleton(i, xp + 1, yp + 1); + } else { + AddObject(OBJ_BANNERL, xp + 1, yp + 1); + } + + if(dObject[xp][yp - 3] == 0) { + AddObject(OBJ_SKELBOOK, xp, yp - 2); + } + if(dObject[xp][yp + 3] == 0) { + AddObject(OBJ_SKELBOOK, xp, yp + 2); + } +} + +void Theme_Treasure(int t) +{ + int i, rv; + int xp, yp; + char treasrnd[4] = { 4, 9, 7, 10 }; + char monstrnd[4] = { 6, 8, 3, 7 }; + + /// ASSERT: assert((DWORD)t < MAXTHEMES); + + GetRndSeed(); + + for(yp = 0; yp < MAXDUNY; yp++) { + for(xp = 0; xp < MAXDUNX; xp++) { + if(dTransVal[xp][yp] == themes[t].ttval && !nSolidTable[dPiece[xp][yp]]) { + rv = random(0, treasrnd[(unsigned char)leveltype-1]); + if(!(2 * random(0, treasrnd[(unsigned char)leveltype-1]))) { + CreateTypeItem(xp, yp, 0, ITYPE_GOLD, 0, 0, 1); + ItemNoFlippy(); + } + if(!rv) { + CreateRndItem(xp, yp, 0, 0, 1); + ItemNoFlippy(); + } + if(!rv || rv >= treasrnd[(unsigned char)leveltype-1] - 2) { + i = ItemNoFlippy(); + if(rv >= treasrnd[(unsigned char)leveltype-1] - 2 && (unsigned char)leveltype != 1) + item[i]._ivalue >>= 1; + } + } + } + } + + PlaceThemeMonsts(t, monstrnd[(unsigned char)leveltype-1]); +} + +void Theme_Library(int t) +{ + int xp, yp, oi; + char librnd[4] = { 1, 2, 2, 5 }; + char monstrnd[4] = { 5, 7, 3, 9 }; + + TFit_Shrine(t); + + if(themeVar1 == 1) { + AddObject(OBJ_BOOKCANDLE, themex - 1, themey); + AddObject(OBJ_BOOKCASER, themex, themey); + AddObject(OBJ_BOOKCANDLE, themex + 1, themey); + } else { + AddObject(OBJ_BOOKCANDLE, themex, themey - 1); + AddObject(OBJ_BOOKCASEL, themex, themey); + AddObject(OBJ_BOOKCANDLE, themex, themey + 1); + } + + for(yp = 1; yp < MAXDUNY - 1; yp++) { + for(xp = 1; xp < MAXDUNX - 1; xp++) { + if(CheckThemeObj3(xp, yp, t, -1) && dMonster[xp][yp] == 0 && random(0, librnd[leveltype - 1]) == 0) { + AddObject(OBJ_BOOKSTAND, xp, yp); + if(random(0, 2 * librnd[leveltype - 1]) != 0) { + oi = dObject[xp][yp] - 1; + object[oi]._oSelFlag = 0; + object[oi]._oAnimFrame += 2; + } + } + } + } + + if(!QuestStatus(Q_ZHAR)) { + PlaceThemeMonsts(t, monstrnd[leveltype]); /// BUGFIX: `leveltype - 1` + } else if(t != zharlib) { + PlaceThemeMonsts(t, monstrnd[leveltype]); /// BUGFIX: `leveltype - 1` + } +} + +void Theme_Torture(int t) +{ + int v1; // ebx + int v2; // esi + char *v3; // edi + //int v4; // eax + int *x; // [esp+Ch] [ebp-14h] + char monstrnd[4]; // [esp+10h] [ebp-10h] + int *v8; // [esp+14h] [ebp-Ch] + char tortrnd[4]; // [esp+18h] [ebp-8h] + int v10; // [esp+1Ch] [ebp-4h] + + v1 = t; + tortrnd[0] = 6; + tortrnd[1] = 8; + tortrnd[2] = 3; + tortrnd[3] = 8; + monstrnd[0] = 6; + monstrnd[1] = 8; + monstrnd[2] = 3; + monstrnd[3] = 9; + v2 = 1; + v8 = &dPiece[1][1]; + do + { + v10 = 1; + v3 = &dTransVal[1][v2]; + x = v8; + do + { + if ( *v3 == themes[v1].ttval && !nSolidTable[*x] ) + { + //LOBYTE(v4) = CheckThemeObj3(v10, v2, v1, -1); + if ( CheckThemeObj3(v10, v2, v1, -1) ) + { + if ( !random(0, tortrnd[leveltype-1]) ) + AddObject(OBJ_TNUDEM2, v10, v2); + } + } + ++v10; + x += 112; + v3 += 112; + } + while ( v10 < 111 ); + ++v8; + ++v2; + } + while ( (signed int)v8 < (signed int)&dPiece[1][111] ); + PlaceThemeMonsts(v1, monstrnd[leveltype-1]); +} + +void Theme_BloodFountain(int t) +{ + char monstrnd[4]; // [esp+3h] [ebp-5h] + + monstrnd[0] = 6; + monstrnd[1] = 8; + monstrnd[2] = 3; + monstrnd[3] = 9; + TFit_Obj5(t); + AddObject(OBJ_BLOODFTN, themex, themey); + PlaceThemeMonsts(t, monstrnd[leveltype-1]); +} + +void Theme_Decap(int t) +{ + int v1; // ebx + int v2; // esi + char *v3; // edi + //int v4; // eax + int *x; // [esp+Ch] [ebp-14h] + char monstrnd[4]; // [esp+10h] [ebp-10h] + int *v8; // [esp+14h] [ebp-Ch] + char decaprnd[4]; // [esp+18h] [ebp-8h] + int v10; // [esp+1Ch] [ebp-4h] + + v1 = t; + decaprnd[0] = 6; + decaprnd[1] = 8; + decaprnd[2] = 3; + decaprnd[3] = 8; + monstrnd[0] = 6; + monstrnd[1] = 8; + monstrnd[2] = 3; + monstrnd[3] = 9; + v2 = 1; + v8 = &dPiece[1][1]; + do + { + v10 = 1; + v3 = &dTransVal[1][v2]; + x = v8; + do + { + if ( *v3 == themes[v1].ttval && !nSolidTable[*x] ) + { + //LOBYTE(v4) = CheckThemeObj3(v10, v2, v1, -1); + if ( CheckThemeObj3(v10, v2, v1, -1) ) + { + if ( !random(0, decaprnd[leveltype-1]) ) + AddObject(OBJ_DECAP, v10, v2); + } + } + ++v10; + x += 112; + v3 += 112; + } + while ( v10 < 111 ); + ++v8; + ++v2; + } + while ( (signed int)v8 < (signed int)&dPiece[1][111] ); + PlaceThemeMonsts(v1, monstrnd[leveltype-1]); +} + +void Theme_PurifyingFountain(int t) +{ + char monstrnd[4]; // [esp+3h] [ebp-5h] + + monstrnd[0] = 6; + monstrnd[1] = 7; + monstrnd[2] = 3; + monstrnd[3] = 9; + TFit_Obj5(t); + AddObject(OBJ_PURIFYINGFTN, themex, themey); + PlaceThemeMonsts(t, monstrnd[leveltype-1]); +} + +void Theme_ArmorStand(int t) +{ + int v1; // esi + int v2; // ebx + char *v3; // edi + //int v4; // eax + int ta; // [esp+Ch] [ebp-14h] + int *v7; // [esp+10h] [ebp-10h] + char monstrnd[4]; // [esp+14h] [ebp-Ch] + int *v9; // [esp+18h] [ebp-8h] + char armorrnd[4]; // [esp+1Ch] [ebp-4h] + + v1 = 0; + ta = t; + armorrnd[0] = 6; + armorrnd[1] = 8; + armorrnd[2] = 3; + armorrnd[3] = 8; + monstrnd[0] = 6; + monstrnd[1] = 7; + monstrnd[2] = 3; + monstrnd[3] = 9; + if ( armorFlag ) + { + TFit_Obj3(t); + AddObject(OBJ_ARMORSTAND, themex, themey); + } + v9 = (int *)dPiece; + do + { + v2 = 0; + v3 = (char *)dTransVal + v1; + v7 = v9; + do + { + if ( *v3 == themes[ta].ttval && !nSolidTable[*v7] ) + { + //LOBYTE(v4) = CheckThemeObj3(v2, v1, ta, -1); + if ( CheckThemeObj3(v2, v1, ta, -1) ) + { + if ( !random(0, armorrnd[leveltype-1]) ) + AddObject(OBJ_ARMORSTANDN, v2, v1); + } + } + v7 += 112; + ++v2; + v3 += 112; + } + while ( v2 < 112 ); + ++v9; + ++v1; + } + while ( (signed int)v9 < (signed int)dPiece[1] ); + PlaceThemeMonsts(ta, monstrnd[leveltype-1]); + armorFlag = 0; +} + +void Theme_GoatShrine(int t) +{ + int v1; // edx + int v2; // esi + int v3; // ecx + int v4; // edi + int v5; // eax + char *v6; // ebx + _DWORD *v7; // [esp+4h] [ebp-8h] + + TFit_GoatShrine(t); + AddObject(OBJ_GOATSHRINE, themex, themey); + v1 = themey; + v2 = themey - 1; + if ( themey - 1 <= themey + 1 ) + { + v3 = themex; + do + { + v4 = v3 - 1; + if ( (unsigned char)(__OFSUB__(v3 - 1, v3 + 1) ^ 1) | (v3 - 1 == v3 + 1) ) + { + v5 = v2 + 112 * v4; + v6 = (char *)dTransVal + v5; + v7 = (_DWORD *)((char *)dPiece + 4 * v5); + do + { + if ( *v6 == themes[t].ttval && !nSolidTable[*v7] && (v4 != v3 || v2 != v1) ) + { + AddMonster(v4, v2, 1, themeVar1, 1); + v1 = themey; + v3 = themex; + } + v7 += 112; + ++v4; + v6 += 112; + } + while ( v4 <= v3 + 1 ); + } + ++v2; + } + while ( v2 <= v1 + 1 ); + } +} + +void Theme_Cauldron(int t) +{ + char monstrnd[4]; // [esp+3h] [ebp-5h] + + monstrnd[0] = 6; + monstrnd[1] = 7; + monstrnd[2] = 3; + monstrnd[3] = 9; + TFit_Obj5(t); + AddObject(OBJ_CAULDRON, themex, themey); + PlaceThemeMonsts(t, monstrnd[leveltype-1]); +} + +void Theme_MurkyFountain(int t) +{ + char monstrnd[4]; // [esp+3h] [ebp-5h] + + monstrnd[0] = 6; + monstrnd[1] = 7; + monstrnd[2] = 3; + monstrnd[3] = 9; + TFit_Obj5(t); + AddObject(OBJ_MURKYFTN, themex, themey); + PlaceThemeMonsts(t, monstrnd[leveltype-1]); +} + +void Theme_TearFountain(int t) +{ + char monstrnd[4]; // [esp+3h] [ebp-5h] + + monstrnd[0] = 6; + monstrnd[1] = 7; + monstrnd[2] = 3; + monstrnd[3] = 9; + TFit_Obj5(t); + AddObject(OBJ_TEARFTN, themex, themey); + PlaceThemeMonsts(t, monstrnd[leveltype-1]); +} + +void Theme_BrnCross(int t) +{ + int v1; // esi + int v2; // ebx + char *v3; // edi + //int v4; // eax + int ta; // [esp+Ch] [ebp-14h] + int *v7; // [esp+10h] [ebp-10h] + char monstrnd[4]; // [esp+14h] [ebp-Ch] + int *v9; // [esp+18h] [ebp-8h] + char bcrossrnd[4]; // [esp+1Ch] [ebp-4h] + + ta = t; + monstrnd[0] = 6; + monstrnd[1] = 8; + monstrnd[2] = 3; + monstrnd[3] = 9; + bcrossrnd[0] = 5; + bcrossrnd[1] = 7; + bcrossrnd[2] = 3; + bcrossrnd[3] = 8; + v1 = 0; + v9 = (int *)dPiece; + do + { + v2 = 0; + v3 = (char *)dTransVal + v1; + v7 = v9; + do + { + if ( *v3 == themes[ta].ttval && !nSolidTable[*v7] ) + { + //LOBYTE(v4) = CheckThemeObj3(v2, v1, ta, -1); + if ( CheckThemeObj3(v2, v1, ta, -1) ) + { + if ( !random(0, bcrossrnd[leveltype-1]) ) + AddObject(OBJ_TBCROSS, v2, v1); + } + } + v7 += 112; + ++v2; + v3 += 112; + } + while ( v2 < 112 ); + ++v9; + ++v1; + } + while ( (signed int)v9 < (signed int)dPiece[1] ); + PlaceThemeMonsts(ta, monstrnd[leveltype-1]); + bCrossFlag = 1; +} + +void Theme_WeaponRack(int t) +{ + int v1; // esi + int v2; // ebx + char *v3; // edi + //int v4; // eax + int ta; // [esp+Ch] [ebp-14h] + int *v7; // [esp+10h] [ebp-10h] + char monstrnd[4]; // [esp+14h] [ebp-Ch] + int *v9; // [esp+18h] [ebp-8h] + char weaponrnd[4]; // [esp+1Ch] [ebp-4h] + + v1 = 0; + ta = t; + weaponrnd[0] = 6; + weaponrnd[1] = 8; + weaponrnd[2] = 5; + weaponrnd[3] = 8; + monstrnd[0] = 6; + monstrnd[1] = 7; + monstrnd[2] = 3; + monstrnd[3] = 9; + if ( weaponFlag ) + { + TFit_Obj3(t); + AddObject(OBJ_WEAPONRACK, themex, themey); + } + v9 = (int *)dPiece; + do + { + v2 = 0; + v3 = (char *)dTransVal + v1; + v7 = v9; + do + { + if ( *v3 == themes[ta].ttval && !nSolidTable[*v7] ) + { + //LOBYTE(v4) = CheckThemeObj3(v2, v1, ta, -1); + if ( CheckThemeObj3(v2, v1, ta, -1) ) + { + if ( !random(0, weaponrnd[leveltype-1]) ) + AddObject(OBJ_WEAPONRACKN, v2, v1); + } + } + v7 += 112; + ++v2; + v3 += 112; + } + while ( v2 < 112 ); + ++v9; + ++v1; + } + while ( (signed int)v9 < (signed int)dPiece[1] ); + PlaceThemeMonsts(ta, monstrnd[leveltype-1]); + weaponFlag = 0; +} + +void UpdateL4Trans() +{ + int i; // ecx + int j; // edx + + for(i = 0; i < 112; i++) + { + for(j = 0; j < 112; j++) + { + if ( dTransVal[i][j] ) + dTransVal[i][j] = 1; + } + } +} + +void CreateThemeRooms() +{ + int i; // esi + + if ( currlevel != 16 ) + { + InitObjFlag = 1; + for ( i = 0; i < numthemes; i++ ) + { + themex = 0; + themey = 0; + switch ( themes[i].ttype ) + { + case THEME_BARREL: + Theme_Barrel(i); + break; + case THEME_SHRINE: + Theme_Shrine(i); + break; + case THEME_MONSTPIT: + Theme_MonstPit(i); + break; + case THEME_SKELROOM: + Theme_SkelRoom(i); + break; + case THEME_TREASURE: + Theme_Treasure(i); + break; + case THEME_LIBRARY: + Theme_Library(i); + break; + case THEME_TORTURE: + Theme_Torture(i); + break; + case THEME_BLOODFOUNTAIN: + Theme_BloodFountain(i); + break; + case THEME_DECAPITATED: + Theme_Decap(i); + break; + case THEME_PURIFYINGFOUNTAIN: + Theme_PurifyingFountain(i); + break; + case THEME_ARMORSTAND: + Theme_ArmorStand(i); + break; + case THEME_GOATSHRINE: + Theme_GoatShrine(i); + break; + case THEME_CAULDRON: + Theme_Cauldron(i); + break; + case THEME_MURKYFOUNTAIN: + Theme_MurkyFountain(i); + break; + case THEME_TEARFOUNTAIN: + Theme_TearFountain(i); + break; + case THEME_BRNCROSS: + Theme_BrnCross(i); + break; + case THEME_WEAPONRACK: + Theme_WeaponRack(i); + break; + default: + continue; + } + } + InitObjFlag = 0; + if ( leveltype == DTYPE_HELL && themeCount > 0 ) + UpdateL4Trans(); + } +} diff --git a/2020_03_31/Source/themes.h b/2020_03_31/Source/themes.h new file mode 100644 index 00000000..e53fbfa8 --- /dev/null +++ b/2020_03_31/Source/themes.h @@ -0,0 +1,62 @@ +//HEADER_GOES_HERE +#ifndef __THEMES_H__ +#define __THEMES_H__ + +extern int numthemes; // idb +extern BOOL armorFlag; // weak +extern int ThemeGoodIn[4]; +extern BOOL weaponFlag; // weak +extern BOOL treasureFlag; // weak +extern BOOL mFountainFlag; // weak +extern BOOL cauldronFlag; // weak +extern BOOL tFountainFlag; // weak +extern int zharlib; // weak +extern int themex; // idb +extern int themey; // idb +extern int themeVar1; // idb +extern ThemeStruct themes[MAXTHEMES]; +extern BOOL pFountainFlag; // weak +extern BOOL bFountainFlag; // weak +extern BOOL bCrossFlag; // weak + +_bool TFit_Shrine(int i); +_bool TFit_Obj5(int t); +_bool TFit_SkelRoom(int t); +_bool TFit_GoatShrine(int t); +_bool CheckThemeObj3(int xp, int yp, int t, int f); +_bool TFit_Obj3(int t); +_bool CheckThemeReqs(int t); +_bool SpecialThemeFit(int i, int t); +_bool CheckThemeRoom(int tv); +void InitThemes(); +void HoldThemeRooms(); +void PlaceThemeMonsts(int t, int f); +void Theme_Barrel(int t); +void Theme_Shrine(int t); +void Theme_MonstPit(int t); +void Theme_SkelRoom(int t); +void Theme_Treasure(int t); +void Theme_Library(int t); +void Theme_Torture(int t); +void Theme_BloodFountain(int t); +void Theme_Decap(int t); +void Theme_PurifyingFountain(int t); +void Theme_ArmorStand(int t); +void Theme_GoatShrine(int t); +void Theme_Cauldron(int t); +void Theme_MurkyFountain(int t); +void Theme_TearFountain(int t); +void Theme_BrnCross(int t); +void Theme_WeaponRack(int t); +void UpdateL4Trans(); +void CreateThemeRooms(); + +/* rdata */ + +extern int ThemeGood[4]; +extern int trm5x[25]; +extern int trm5y[25]; +extern int trm3x[9]; +extern int trm3y[9]; + +#endif /* __THEMES_H__ */ diff --git a/2020_03_31/Source/tmsg.cpp b/2020_03_31/Source/tmsg.cpp new file mode 100644 index 00000000..4c97b4b5 --- /dev/null +++ b/2020_03_31/Source/tmsg.cpp @@ -0,0 +1,80 @@ +#include "diablo.h" + +TMsg *sgpTimedMsgHead; + +int tmsg_get(unsigned char *pbMsg, unsigned int dwMaxLen) +{ + unsigned char *v2; // ebx + DWORD v3; // eax + TMsg *v4; // esi + size_t v6; // edi + + v2 = pbMsg; + if ( !sgpTimedMsgHead ) + return 0; + v3 = GetTickCount(); + v4 = sgpTimedMsgHead; + if ( (signed int)(sgpTimedMsgHead->hdr.dwTime - v3) >= 0 ) + return 0; + sgpTimedMsgHead = sgpTimedMsgHead->hdr.pNext; + v6 = v4->hdr.bLen; + memcpy(v2, v4->body, v6); + mem_free_dbg(v4); + return v6; +} + +void tmsg_add(const BYTE *pbMsg, unsigned char bLen) +{ + unsigned char v2; // bl + //unsigned char *v3; // ebp + size_t v4; // edi + TMsg *v5; // eax + TMsg *v6; // esi + DWORD v7; // eax + TMsg *v8; // ecx + TMsg **v9; // eax + + v2 = bLen; + //v3 = pbMsg; + v4 = bLen; + v5 = (TMsg *)DiabloAllocPtr(bLen + 12); + v6 = v5; + v5->hdr.pNext = 0; + v7 = GetTickCount(); + v6->hdr.bLen = v2; + v6->hdr.dwTime = v7 + 500; + memcpy(v6->body, pbMsg, v4); + v8 = sgpTimedMsgHead; + v9 = &sgpTimedMsgHead; + while ( v8 ) + { + v9 = &v8->hdr.pNext; + v8 = v8->hdr.pNext; + } + *v9 = v6; +} + +void tmsg_start() +{ + /// ASSERT: assert(! sgpTimedMsgHead); +} + +void tmsg_cleanup() +{ + TMsg *v0; // eax + TMsg *v1; // esi + + v0 = sgpTimedMsgHead; + if ( sgpTimedMsgHead ) + { + do + { + v1 = v0->hdr.pNext; + sgpTimedMsgHead = 0; + mem_free_dbg(v0); + v0 = v1; + sgpTimedMsgHead = v1; + } + while ( v1 ); + } +} diff --git a/2020_03_31/Source/tmsg.h b/2020_03_31/Source/tmsg.h new file mode 100644 index 00000000..527cd981 --- /dev/null +++ b/2020_03_31/Source/tmsg.h @@ -0,0 +1,12 @@ +//HEADER_GOES_HERE +#ifndef __TMSG_H__ +#define __TMSG_H__ + +extern TMsg *sgpTimedMsgHead; + +int tmsg_get(unsigned char *pbMsg, unsigned int dwMaxLen); +void tmsg_add(const BYTE *pbMsg, unsigned char bLen); +void tmsg_start(); +void tmsg_cleanup(); + +#endif /* __TMSG_H__ */ diff --git a/2020_03_31/Source/town.cpp b/2020_03_31/Source/town.cpp new file mode 100644 index 00000000..0768b3d6 --- /dev/null +++ b/2020_03_31/Source/town.cpp @@ -0,0 +1,1547 @@ +#include "diablo.h" + +void town_clear_upper_buf(BYTE *pBuff) +{ + /// ASSERT: assert(gpBuffer); + +#ifdef USE_ASM + __asm { + mov edi, pBuff + mov edx, 30 + mov ebx, 1 + xor eax, eax + label1: + cmp edi, gpBufEnd + jb label4 + add edi, edx + mov ecx, ebx + rep stosd + add edi, edx + sub edi, 768 + 64 + or edx, edx + jz label2 + sub edx, 2 + inc ebx + jmp label1 + label2: + mov edx, 2 + mov ebx, 15 + label3: + cmp edi, gpBufEnd + jb label4 + add edi, edx + mov ecx, ebx + rep stosd + add edi, edx + sub edi, 768 + 64 + dec ebx + add edx, 2 + cmp edx, 32 + jnz label3 + label4: + nop + } +#else + int i, j, k; + BYTE *dst; + + dst = pBuff; + + for(i = 30, j = 1; i >= 0 && dst >= gpBufEnd; i -= 2, j++, dst -= 768 + 64) { + dst += i; + for(k = 0; k < 4 * j; k++) + *dst++ = 0; + dst += i; + } + for(i = 2, j = 15; i != 32 && dst >= gpBufEnd; i += 2, j--, dst -= 768 + 64) { + dst += i; + for(k = 0; k < 4 * j; k++) + *dst++ = 0; + dst += i; + } +#endif +} + +void town_clear_low_buf(BYTE *pBuff) +{ + /// ASSERT: assert(gpBuffer); + +#ifdef USE_ASM + __asm { + mov edi, pBuff + mov edx, 30 + mov ebx, 1 + xor eax, eax + label1: + cmp edi, gpBufEnd + jb label2 + add edi, 64 + jmp label3 + label2: + add edi, edx + mov ecx, ebx + rep stosd + add edi, edx + label3: + sub edi, 768 + 64 + or edx, edx + jz label4 + sub edx, 2 + inc ebx + jmp label1 + label4: + mov edx, 2 + mov ebx, 15 + label5: + cmp edi, gpBufEnd + jb label6 + add edi, 64 + jmp label7 + label6: + add edi, edx + mov ecx, ebx + rep stosd + add edi, edx + label7: + sub edi, 768 + 64 + dec ebx + add edx, 2 + cmp edx, 32 + jnz label5 + } +#else + int i, j, k; + BYTE *dst; + + dst = pBuff; + + for(i = 30, j = 1; i >= 0; i -= 2, j++, dst -= 768 + 64) { + if(dst < gpBufEnd) { + dst += i; + for(k = 0; k < 4 * j; k++) + *dst++ = 0; + dst += i; + } else { + dst += 64; + } + } + for(i = 2, j = 15; i != 32; i += 2, j--, dst -= 768 + 64) { + if(dst < gpBufEnd) { + dst += i; + for(k = 0; k < 4 * j; k++) + *dst++ = 0; + dst += i; + } else { + dst += 64; + } + } +#endif +} + +void town_special_lower(BYTE *pBuff, int nCel) +{ +#if 0 + int w; + BYTE *end; + +#ifdef USE_ASM + __asm { + mov ebx, pSpecialCels + mov eax, nCel + shl eax, 2 + add ebx, eax + mov eax, [ebx+4] + sub eax, [ebx] + mov end, eax + mov esi, pSpecialCels + add esi, [ebx] + mov edi, pBuff + mov eax, 768 + 64 + mov w, eax + mov ebx, end + add ebx, esi + label1: + mov edx, 64 + label2: + xor eax, eax + lodsb + or al, al + js label7 + sub edx, eax + cmp edi, gpBufEnd + jb label3 + add esi, eax + add edi, eax + jmp label6 + label3: + mov ecx, eax + shr ecx, 1 + jnb label4 + movsb + jecxz label6 + label4: + shr ecx, 1 + jnb label5 + movsw + jecxz label6 + label5: + rep movsd + label6: + or edx, edx + jz label8 + jmp label2 + label7: + neg al + add edi, eax + sub edx, eax + jnz label2 + label8: + sub edi, w + cmp ebx, esi + jnz label1 + } +#else + BYTE width; + BYTE *src, *dst; + DWORD *pFrameTable; + + pFrameTable = (DWORD *)pSpecialCels; + src = &pSpecialCels[pFrameTable[nCel]]; + dst = pBuff; + end = &src[pFrameTable[nCel + 1] - pFrameTable[nCel]]; + + for(; src != end; dst -= 768 + 64) { + for(w = 64; w;) { + width = *src++; + if(!(width & 0x80)) { + w -= width; + if(dst < gpBufEnd) { + if(width & 1) { + dst[0] = src[0]; + src++; + dst++; + } + width >>= 1; + if(width & 1) { + dst[0] = src[0]; + dst[1] = src[1]; + src += 2; + dst += 2; + } + width >>= 1; + for(; width; width--) { + dst[0] = src[0]; + dst[1] = src[1]; + dst[2] = src[2]; + dst[3] = src[3]; + src += 4; + dst += 4; + } + } else { + src += width; + dst += width; + } + } else { + width = -(char)width; + dst += width; + w -= width; + } + } + } +#endif +#endif +} + +void town_special_upper(BYTE *pBuff, int nCel) +{ +#if 0 + int w; + BYTE *end; + +#ifdef USE_ASM + __asm { + mov ebx, pSpecialCels + mov eax, nCel + shl eax, 2 + add ebx, eax + mov eax, [ebx+4] + sub eax, [ebx] + mov end, eax + mov esi, pSpecialCels + add esi, [ebx] + mov edi, pBuff + mov eax, 768 + 64 + mov w, eax + mov ebx, end + add ebx, esi + label1: + mov edx, 64 + label2: + xor eax, eax + lodsb + or al, al + js label6 + sub edx, eax + cmp edi, gpBufEnd + jb label8 + mov ecx, eax + shr ecx, 1 + jnb label3 + movsb + jecxz label5 + label3: + shr ecx, 1 + jnb label4 + movsw + jecxz label5 + label4: + rep movsd + label5: + or edx, edx + jz label7 + jmp label2 + label6: + neg al + add edi, eax + sub edx, eax + jnz label2 + label7: + sub edi, w + cmp ebx, esi + jnz label1 + label8: + nop + } +#else + BYTE width; + BYTE *src, *dst; + DWORD *pFrameTable; + + pFrameTable = (DWORD *)pSpecialCels; + src = &pSpecialCels[pFrameTable[nCel]]; + dst = pBuff; + end = &src[pFrameTable[nCel + 1] - pFrameTable[nCel]]; + + for(; src != end; dst -= 768 + 64) { + for(w = 64; w;) { + width = *src++; + if(!(width & 0x80)) { + w -= width; + if(dst < gpBufEnd) { + return; + } + if(width & 1) { + dst[0] = src[0]; + src++; + dst++; + } + width >>= 1; + if(width & 1) { + dst[0] = src[0]; + dst[1] = src[1]; + src += 2; + dst += 2; + } + width >>= 1; + for(; width; width--) { + dst[0] = src[0]; + dst[1] = src[1]; + dst[2] = src[2]; + dst[3] = src[3]; + src += 4; + dst += 4; + } + } else { + width = -(char)width; + dst += width; + w -= width; + } + } + } +#endif +#endif +} + +void town_draw_clipped_e_flag(BYTE *pBuff, int x, int y, int sx, int sy) +{ + int i; + BYTE *dst; + MICROS *pMap; + + dst = pBuff; + pMap = &dpiece_defs_map_1[IsometricCoord(x, y)]; + + for(i = 0; i < 12; i += 2) { + level_cel_block = pMap->mt[i]; + if(level_cel_block != 0) { + drawLowerScreen(dst); + } + level_cel_block = pMap->mt[i + 1]; + if(level_cel_block != 0) { + drawLowerScreen(dst + 32); + } + dst -= 768 * 32; + } + + town_draw_clipped_town(pBuff, x, y, sx, sy, 0); +} + +void town_draw_clipped_town(BYTE *pBuff, int x, int y, int sx, int sy, int some_flag) +{ + int mi, px, py; + char bv; + + /// ASSERT: assert(gpBuffer); + + pBuff = &gpBuffer[sx + PitchTbl[sy]]; + + if(dItem[x][y] != 0) { + bv = dItem[x][y] - 1; + px = sx - item[bv]._iAnimWidth2; + if(bv == pcursitem) { + CelDrawHdrClrHL(181, px, sy, item[bv]._iAnimData, item[bv]._iAnimFrame, item[bv]._iAnimWidth, 0, 8); + } + Cel2DrawHdrOnly(px, sy, item[bv]._iAnimData, item[bv]._iAnimFrame, item[bv]._iAnimWidth, 0, 8); + } + if(dFlags[x][y] & 0x10) { + mi = -(dMonster[x][y - 1] + 1); + px = sx - towner[mi]._tAnimWidth2; + if(mi == pcursmonst) { + CelDrawHdrClrHL(166, px, sy, towner[mi]._tAnimData, towner[mi]._tAnimFrame, towner[mi]._tAnimWidth, 0, 8); + } + Cel2DrawHdrOnly(px, sy, towner[mi]._tAnimData, towner[mi]._tAnimFrame, towner[mi]._tAnimWidth, 0, 8); + } + if(dMonster[x][y] > 0) { + mi = dMonster[x][y] - 1; + px = sx - towner[mi]._tAnimWidth2; + if(mi == pcursmonst) { + CelDrawHdrClrHL(166, px, sy, towner[mi]._tAnimData, towner[mi]._tAnimFrame, towner[mi]._tAnimWidth, 0, 8); + } + Cel2DrawHdrOnly(px, sy, towner[mi]._tAnimData, towner[mi]._tAnimFrame, towner[mi]._tAnimWidth, 0, 8); + } + if(dFlags[x][y] & 0x20) { + bv = -(dPlayer[x][y - 1] + 1); + px = sx + plr[bv]._pxoff - plr[bv]._pAnimWidth2; + py = sy + plr[bv]._pyoff; + if(bv == pcursplr) { + Cl2DecodeClrHL(165, px, py, plr[bv]._pAnimData, plr[bv]._pAnimFrame, plr[bv]._pAnimWidth, 0, 8); + } + Cl2DecodeFrm4(px, py, plr[bv]._pAnimData, plr[bv]._pAnimFrame, plr[bv]._pAnimWidth, 0, 8); + if(some_flag && plr[bv]._peflag) { + town_draw_clipped_e_flag(pBuff - 64, x - 1, y + 1, sx - 64, sy); + } + } + if(dFlags[x][y] & 4) { + DrawDeadPlayer(x, y, sx, sy, 0, 8, 1); + } + if(dPlayer[x][y] > 0) { + bv = dPlayer[x][y] - 1; + px = sx + plr[bv]._pxoff - plr[bv]._pAnimWidth2; + py = sy + plr[bv]._pyoff; + if(bv == pcursplr) { + Cl2DecodeClrHL(165, px, py, plr[bv]._pAnimData, plr[bv]._pAnimFrame, plr[bv]._pAnimWidth, 0, 8); + } + Cl2DecodeFrm4(px, py, plr[bv]._pAnimData, plr[bv]._pAnimFrame, plr[bv]._pAnimWidth, 0, 8); + if(some_flag && plr[bv]._peflag) { + town_draw_clipped_e_flag(pBuff - 64, x - 1, y + 1, sx - 64, sy); + } + } + if(dFlags[x][y] & 1) { + DrawClippedMissile(x, y, sx, sy, 0, 8, 0); + } + if(dSpecial[x][y] != 0) { + town_special_lower(pBuff, dSpecial[x][y]); + } +} + +void town_draw_lower(int x, int y, int sx, int sy, int a5, int some_flag) +{ + int i, j; + BYTE *dst; + MICROS *pMap; + + /// ASSERT: assert(gpBuffer); + + if(some_flag) { + if(y >= 0 && y < MAXDUNY && x >= 0 && x < MAXDUNX) { + level_cel_block = dPiece[x][y]; + if(level_cel_block != 0) { + dst = &gpBuffer[sx + 32 + PitchTbl[sy]]; + pMap = &dpiece_defs_map_1[IsometricCoord(x, y)]; + for(i = 1; i < 17; i += 2) { + level_cel_block = pMap->mt[i]; + if(level_cel_block != 0) { + drawLowerScreen(dst); + } + dst -= 768 * 32; + } + town_draw_clipped_town(&gpBuffer[sx + PitchTbl[sy]], x, y, sx, sy, 0); + } else { + town_clear_low_buf(&gpBuffer[sx + PitchTbl[sy]]); + } + } else { + town_clear_low_buf(&gpBuffer[sx + PitchTbl[sy]]); + } + x++; + y--; + sx += 64; + } + + for(j = 0; j < a5 - some_flag; j++) { + if(y >= 0 && y < MAXDUNY && x >= 0 && x < MAXDUNX) { + level_cel_block = dPiece[x][y]; + if(level_cel_block != 0) { + dst = &gpBuffer[sx + PitchTbl[sy]]; + pMap = &dpiece_defs_map_1[IsometricCoord(x, y)]; + for(i = 0; i < 16; i += 2) { + level_cel_block = pMap->mt[i]; + if(level_cel_block != 0) { + drawLowerScreen(dst); + } + level_cel_block = pMap->mt[i + 1]; + if(level_cel_block != 0) { + drawLowerScreen(dst + 32); + } + dst -= 768 * 32; + } + town_draw_clipped_town(&gpBuffer[sx + PitchTbl[sy]], x, y, sx, sy, 1); + } else { + town_clear_low_buf(&gpBuffer[sx + PitchTbl[sy]]); + } + } else { + town_clear_low_buf(&gpBuffer[sx + PitchTbl[sy]]); + } + x++; + y--; + sx += 64; + } + + if(some_flag) { + if(y >= 0 && y < MAXDUNY && x >= 0 && x < MAXDUNX) { + level_cel_block = dPiece[x][y]; + if(level_cel_block != 0) { + dst = &gpBuffer[sx + PitchTbl[sy]]; + pMap = &dpiece_defs_map_1[IsometricCoord(x, y)]; + for(i = 0; i < 16; i += 2) { + level_cel_block = pMap->mt[i]; + if(level_cel_block != 0) { + drawLowerScreen(dst); + } + dst -= 768 * 32; + } + town_draw_clipped_town(&gpBuffer[sx + PitchTbl[sy]], x, y, sx, sy, 0); + } else { + town_clear_low_buf(&gpBuffer[sx + PitchTbl[sy]]); + } + } else { + town_clear_low_buf(&gpBuffer[sx + PitchTbl[sy]]); + } + } +} + +void town_draw_clipped_e_flag_2(BYTE *pBuff, int x, int y, int a4, int a5, int sx, int sy) +{ + int i; + BYTE *dst; + MICROS *pMap; + + if(a4 == 0) { + dst = pBuff; + } else { + dst = &pBuff[768 * 32 * a4]; + } + + pMap = &dpiece_defs_map_1[IsometricCoord(x, y)]; + + for(i = 0; i < 6; i++) { + if(a4 <= i) { + level_cel_block = pMap->mt[2 * i + 2]; + if(level_cel_block != 0) { + drawLowerScreen(dst); + } + level_cel_block = pMap->mt[2 * i + 3]; + if(level_cel_block != 0) { + drawLowerScreen(dst + 32); + } + } + dst -= 768 * 32; + } + + if(a5 < 8) { + town_draw_clipped_town_2(pBuff, x, y, a4, a5, sx, sy, 0); + } +} + +void town_draw_clipped_town_2(BYTE *pBuff, int x, int y, int a4, int a5, int sx, int sy, int some_flag) +{ + int mi, px, py; + char bv; + + if(dItem[x][y] != 0) { + bv = dItem[x][y] - 1; + px = sx - item[bv]._iAnimWidth2; + if(bv == pcursitem) { + CelDrawHdrClrHL(181, px, sy, item[bv]._iAnimData, item[bv]._iAnimFrame, item[bv]._iAnimWidth, a5, 8); + } + Cel2DrawHdrOnly(px, sy, item[bv]._iAnimData, item[bv]._iAnimFrame, item[bv]._iAnimWidth, a5, 8); + } + if(dFlags[x][y] & 0x10) { + mi = -(dMonster[x][y - 1] + 1); + px = sx - towner[mi]._tAnimWidth2; + if(mi == pcursmonst) { + CelDrawHdrClrHL(166, px, sy, towner[mi]._tAnimData, towner[mi]._tAnimFrame, towner[mi]._tAnimWidth, a5, 8); + } + Cel2DrawHdrOnly(px, sy, towner[mi]._tAnimData, towner[mi]._tAnimFrame, towner[mi]._tAnimWidth, a5, 8); + } + if(dMonster[x][y] > 0) { + mi = dMonster[x][y] - 1; + px = sx - towner[mi]._tAnimWidth2; + if(mi == pcursmonst) { + CelDrawHdrClrHL(166, px, sy, towner[mi]._tAnimData, towner[mi]._tAnimFrame, towner[mi]._tAnimWidth, a5, 8); + } + Cel2DrawHdrOnly(px, sy, towner[mi]._tAnimData, towner[mi]._tAnimFrame, towner[mi]._tAnimWidth, a5, 8); + } + if(dFlags[x][y] & 0x20) { + bv = -(dPlayer[x][y - 1] + 1); + px = sx + plr[bv]._pxoff - plr[bv]._pAnimWidth2; + py = sy + plr[bv]._pyoff; + if(bv == pcursplr) { + Cl2DecodeClrHL(165, px, py, plr[bv]._pAnimData, plr[bv]._pAnimFrame, plr[bv]._pAnimWidth, a5, 8); + } + Cl2DecodeFrm4(px, py, plr[bv]._pAnimData, plr[bv]._pAnimFrame, plr[bv]._pAnimWidth, a5, 8); + if(some_flag && plr[bv]._peflag) { + town_draw_clipped_e_flag_2(pBuff - 64, x - 1, y + 1, a4, a5, sx - 64, sy); + } + } + if(dFlags[x][y] & 4) { + DrawDeadPlayer(x, y, sx, sy, a5, 8, 1); + } + if(dPlayer[x][y] > 0) { + bv = dPlayer[x][y] - 1; + px = sx + plr[bv]._pxoff - plr[bv]._pAnimWidth2; + py = sy + plr[bv]._pyoff; + if(bv == pcursplr) { + Cl2DecodeClrHL(165, px, py, plr[bv]._pAnimData, plr[bv]._pAnimFrame, plr[bv]._pAnimWidth, a5, 8); + } + Cl2DecodeFrm4(px, py, plr[bv]._pAnimData, plr[bv]._pAnimFrame, plr[bv]._pAnimWidth, a5, 8); + if(some_flag && plr[bv]._peflag) { + town_draw_clipped_e_flag_2(pBuff - 64, x - 1, y + 1, a4, a5, sx - 64, sy); + } + } + if(dFlags[x][y] & 1) { + DrawClippedMissile(x, y, sx, sy, a5, 8, 0); + } + if(dSpecial[x][y] != 0) { + town_special_lower(&pBuff[PitchTbl[16 * a5]], dSpecial[x][y]); + } +} + +void town_draw_lower_2(int x, int y, int sx, int sy, int a5, int a6, int some_flag) +{ + int i, j, dir; + BYTE *dst; + MICROS *pMap; + + /// ASSERT: assert(gpBuffer); + + dir = 2 * a6 + 2; + + if(some_flag) { + if(y >= 0 && y < MAXDUNY && x >= 0 && x < MAXDUNX) { + level_cel_block = dPiece[x][y]; + if(level_cel_block != 0) { + dst = &gpBuffer[sx - (768 * 32 - 32) + PitchTbl[sy]]; + pMap = &dpiece_defs_map_1[IsometricCoord(x, y)]; + for(i = 0; i < 7; i++) { + if(a6 <= i) { + level_cel_block = pMap->mt[2 * i + 3]; + if(level_cel_block != 0) { + drawLowerScreen(dst); + } + } + dst -= 768 * 32; + } + if(dir < 8) { + town_draw_clipped_town_2(&gpBuffer[sx + PitchTbl[sy]], x, y, a6, dir, sx, sy, 0); + } + } else { + town_clear_low_buf(&gpBuffer[sx + PitchTbl[sy]]); + } + } else { + town_clear_low_buf(&gpBuffer[sx + PitchTbl[sy]]); + } + x++; + y--; + sx += 64; + } + + for(j = 0; j < a5 - some_flag; j++) { + if(y >= 0 && y < MAXDUNY && x >= 0 && x < MAXDUNX) { + level_cel_block = dPiece[x][y]; + if(level_cel_block != 0) { + dst = &gpBuffer[sx - 768 * 32 + PitchTbl[sy]]; + pMap = &dpiece_defs_map_1[IsometricCoord(x, y)]; + for(i = 0; i < 7; i++) { + if(a6 <= i) { + level_cel_block = pMap->mt[2 * i + 2]; + if(level_cel_block != 0) { + drawLowerScreen(dst); + } + level_cel_block = pMap->mt[2 * i + 3]; + if(level_cel_block != 0) { + drawLowerScreen(dst + 32); + } + } + dst -= 768 * 32; + } + if(dir < 8) { + town_draw_clipped_town_2(&gpBuffer[sx + PitchTbl[sy] - 768 * 16 * dir], x, y, a6, dir, sx, sy, 1); + } + } else { + town_clear_low_buf(&gpBuffer[sx + PitchTbl[sy]]); + } + } else { + town_clear_low_buf(&gpBuffer[sx + PitchTbl[sy]]); + } + x++; + y--; + sx += 64; + } + + if(some_flag) { + if(y >= 0 && y < MAXDUNY && x >= 0 && x < MAXDUNX) { + level_cel_block = dPiece[x][y]; + if(level_cel_block != 0) { + dst = &gpBuffer[sx - 768 * 32 + PitchTbl[sy]]; + pMap = &dpiece_defs_map_1[IsometricCoord(x, y)]; + for(i = 0; i < 7; i++) { + if(a6 <= i) { + level_cel_block = pMap->mt[2 * i + 2]; + if(level_cel_block != 0) { + drawLowerScreen(dst); + } + } + dst -= 768 * 32; + } + if(dir < 8) { + town_draw_clipped_town_2(&gpBuffer[sx + PitchTbl[sy]], x, y, a6, dir, sx, sy, 0); + } + } else { + town_clear_low_buf(&gpBuffer[sx + PitchTbl[sy]]); + } + } else { + town_clear_low_buf(&gpBuffer[sx + PitchTbl[sy]]); + } + } +} + +void town_draw_e_flag(BYTE *pBuff, int x, int y, int a4, int dir, int sx, int sy) +{ + int i; + BYTE *dst; + MICROS *pMap; + + dst = pBuff; + pMap = &dpiece_defs_map_1[IsometricCoord(x, y)]; + + for(i = 0; i < 7; i++) { + if(a4 >= i) { + level_cel_block = pMap->mt[2 * i]; + if(level_cel_block != 0) { + drawUpperScreen(dst); + } + level_cel_block = pMap->mt[2 * i + 1]; + if(level_cel_block != 0) { + drawUpperScreen(dst + 32); + } + } + dst -= 768 * 32; + } + + town_draw_town_all(pBuff, x, y, a4, dir, sx, sy, 0); +} + +void town_draw_town_all(BYTE *pBuff, int x, int y, int a4, int dir, int sx, int sy, int some_flag) +{ + int mi, px, py; + char bv; + + if(dItem[x][y] != 0) { + bv = dItem[x][y] - 1; + px = sx - item[bv]._iAnimWidth2; + if(bv == pcursitem) { + CelDecodeClr(181, px, sy, item[bv]._iAnimData, item[bv]._iAnimFrame, item[bv]._iAnimWidth, 0, dir); + } + /// ASSERT: assert(item[bv]._iAnimData); + CelDrawHdrOnly(px, sy, item[bv]._iAnimData, item[bv]._iAnimFrame, item[bv]._iAnimWidth, 0, dir); + } + if(dFlags[x][y] & 0x10) { + mi = -(dMonster[x][y - 1] + 1); + px = sx - towner[mi]._tAnimWidth2; + if(mi == pcursmonst) { + CelDecodeClr(166, px, sy, towner[mi]._tAnimData, towner[mi]._tAnimFrame, towner[mi]._tAnimWidth, 0, dir); + } + /// ASSERT: assert(towner[mi]._tAnimData); + CelDrawHdrOnly(px, sy, towner[mi]._tAnimData, towner[mi]._tAnimFrame, towner[mi]._tAnimWidth, 0, dir); + } + if(dMonster[x][y] > 0) { + mi = dMonster[x][y] - 1; + px = sx - towner[mi]._tAnimWidth2; + if(mi == pcursmonst) { + CelDecodeClr(166, px, sy, towner[mi]._tAnimData, towner[mi]._tAnimFrame, towner[mi]._tAnimWidth, 0, dir); + } + /// ASSERT: assert(towner[mi]._tAnimData); + CelDrawHdrOnly(px, sy, towner[mi]._tAnimData, towner[mi]._tAnimFrame, towner[mi]._tAnimWidth, 0, dir); + } + if(dFlags[x][y] & 0x20) { + bv = -(dPlayer[x][y - 1] + 1); + px = sx + plr[bv]._pxoff - plr[bv]._pAnimWidth2; + py = sy + plr[bv]._pyoff; + if(bv == pcursplr) { + Cl2DecodeFrm2(165, px, py, plr[bv]._pAnimData, plr[bv]._pAnimFrame, plr[bv]._pAnimWidth, 0, dir); + } + /// ASSERT: assert(plr[bv]._pAnimData); + Cl2DecodeFrm1(px, py, plr[bv]._pAnimData, plr[bv]._pAnimFrame, plr[bv]._pAnimWidth, 0, dir); + if(some_flag && plr[bv]._peflag) { + town_draw_e_flag(pBuff - 64, x - 1, y + 1, a4, dir, sx - 64, sy); + } + } + if(dFlags[x][y] & 4) { + DrawDeadPlayer(x, y, sx, sy, 0, dir, 0); + } + if(dPlayer[x][y] > 0) { + bv = dPlayer[x][y] - 1; + px = sx + plr[bv]._pxoff - plr[bv]._pAnimWidth2; + py = sy + plr[bv]._pyoff; + if(bv == pcursplr) { + Cl2DecodeFrm2(165, px, py, plr[bv]._pAnimData, plr[bv]._pAnimFrame, plr[bv]._pAnimWidth, 0, dir); + } + /// ASSERT: assert(plr[bv]._pAnimData); + Cl2DecodeFrm1(px, py, plr[bv]._pAnimData, plr[bv]._pAnimFrame, plr[bv]._pAnimWidth, 0, dir); + if(some_flag && plr[bv]._peflag) { + town_draw_e_flag(pBuff - 64, x - 1, y + 1, a4, dir, sx - 64, sy); + } + } + if(dFlags[x][y] & 1) { + DrawMissile(x, y, sx, sy, 0, dir, 0); + } + if(dSpecial[x][y] != 0) { + town_special_upper(pBuff, dSpecial[x][y]); + } +} + +void town_draw_upper(int x, int y, int sx, int sy, int a5, int a6, int some_flag) +{ + int i, j, dir; + BYTE *dst; + MICROS *pMap; + + /// ASSERT: assert(gpBuffer); + + dir = 2 * a6 + 2; + if(dir > 8) { + dir = 8; + } + + if(some_flag) { + if(y >= 0 && y < MAXDUNY && x >= 0 && x < MAXDUNX) { + level_cel_block = dPiece[x][y]; + if(level_cel_block != 0) { + dst = &gpBuffer[sx + 32 + PitchTbl[sy]]; + pMap = &dpiece_defs_map_1[IsometricCoord(x, y)]; + for(i = 0; i < 7; i++) { + if(a6 >= i) { + level_cel_block = pMap->mt[2 * i + 1]; + if(level_cel_block != 0) { + drawUpperScreen(dst); + } + } + dst -= 768 * 32; + } + town_draw_town_all(&gpBuffer[sx + PitchTbl[sy]], x, y, a6, dir, sx, sy, 0); + } else { + town_clear_upper_buf(&gpBuffer[sx + PitchTbl[sy]]); + } + } else { + town_clear_upper_buf(&gpBuffer[sx + PitchTbl[sy]]); + } + x++; + y--; + sx += 64; + } + + for(j = 0; j < a5 - some_flag; j++) { + if(y >= 0 && y < MAXDUNY && x >= 0 && x < MAXDUNX) { + level_cel_block = dPiece[x][y]; + if(level_cel_block != 0) { + dst = &gpBuffer[sx + PitchTbl[sy]]; + pMap = &dpiece_defs_map_1[IsometricCoord(x, y)]; + for(i = 0; i < 7; i++) { + if(a6 >= i) { + level_cel_block = pMap->mt[2 * i]; + if(level_cel_block != 0) { + drawUpperScreen(dst); + } + level_cel_block = pMap->mt[2 * i + 1]; + if(level_cel_block != 0) { + drawUpperScreen(dst + 32); + } + } + dst -= 768 * 32; + } + town_draw_town_all(&gpBuffer[sx + PitchTbl[sy]], x, y, a6, dir, sx, sy, 1); + } else { + town_clear_upper_buf(&gpBuffer[sx + PitchTbl[sy]]); + } + } else { + town_clear_upper_buf(&gpBuffer[sx + PitchTbl[sy]]); + } + x++; + y--; + sx += 64; + } + + if(some_flag) { + if(y >= 0 && y < MAXDUNY && x >= 0 && x < MAXDUNX) { + level_cel_block = dPiece[x][y]; + if(level_cel_block != 0) { + dst = &gpBuffer[sx + PitchTbl[sy]]; + pMap = &dpiece_defs_map_1[IsometricCoord(x, y)]; + for(i = 0; i < 7; i++) { + if(a6 >= i) { + level_cel_block = pMap->mt[2 * i]; + if(level_cel_block != 0) { + drawUpperScreen(dst); + } + } + dst -= 768 * 32; + } + town_draw_town_all(&gpBuffer[sx + PitchTbl[sy]], x, y, a6, dir, sx, sy, 0); + } else { + town_clear_upper_buf(&gpBuffer[sx + PitchTbl[sy]]); + } + } else { + town_clear_upper_buf(&gpBuffer[sx + PitchTbl[sy]]); + } + } +} + +void T_DrawGame(int x, int y) +{ + int i, sx, sy, chunks, blocks; + + ViewDX = 640; + ViewDY = 352; + ViewBX = 10; + ViewBY = 11; + + sx = ScrollInfo._sxoff + 64; + sy = ScrollInfo._syoff + 175; + x -= 10; + y--; + chunks = 10; + blocks = 5; + + if(chrflag || questlog) { + x += 2; + y -= 2; + sx += 288; + chunks = 6; + } + if(invflag || sbookflag) { + x += 2; + y -= 2; + sx -= 32; + chunks = 6; + } + + switch(ScrollInfo._sdir) { + case 0: + break; + case 1: + sy -= 32; + x--; + y--; + blocks++; + break; + case 2: + sy -= 32; + x--; + y--; + chunks++; + blocks++; + break; + case 3: + chunks++; + break; + case 4: + chunks++; + blocks++; + break; + case 5: + blocks++; + break; + case 6: + sx -= 64; + x--; + y++; + chunks++; + blocks++; + break; + case 7: + sx -= 64; + x--; + y++; + chunks++; + break; + case 8: + sx -= 64; + sy -= 32; + x -= 2; + chunks++; + blocks++; + break; + } + + /// ASSERT: assert(gpBuffer); + gpBufEnd = &gpBuffer[PitchTbl[160]]; + for(i = 0; i < 7; i++) { + town_draw_upper(x, y, sx, sy, chunks, i, 0); + y++; + sx -= 32; + sy += 16; + town_draw_upper(x, y, sx, sy, chunks, i, 1); + x++; + sx += 32; + sy += 16; + } + /// ASSERT: assert(gpBuffer); + gpBufEnd = &gpBuffer[PitchTbl[512]]; + for(i = 0; i < blocks; i++) { + town_draw_lower(x, y, sx, sy, chunks, 0); + y++; + sx -= 32; + sy += 16; + town_draw_lower(x, y, sx, sy, chunks, 1); + x++; + sx += 32; + sy += 16; + } + for(i = 0; i < 7; i++) { + town_draw_lower_2(x, y, sx, sy, chunks, i, 0); + y++; + sx -= 32; + sy += 16; + town_draw_lower_2(x, y, sx, sy, chunks, i, 1); + x++; + sx += 32; + sy += 16; + } +} + +void T_DrawZoom(int x, int y) +{ + int i, sx, sy, chunks, blocks; + int wdt, nSrcOff, nDstOff; + + ViewDX = 384; + ViewDY = 192; + ViewBX = 6; + ViewBY = 6; + + sx = ScrollInfo._sxoff + 64; + sy = ScrollInfo._syoff + 143; + x -= 6; + y--; + chunks = 6; + blocks = 0; + + switch(ScrollInfo._sdir) { + case 0: + break; + case 1: + sy -= 32; + x--; + y--; + blocks++; + break; + case 2: + sy -= 32; + x--; + y--; + chunks++; + blocks++; + break; + case 3: + chunks++; + break; + case 4: + chunks++; + blocks++; + break; + case 5: + blocks++; + break; + case 6: + sx -= 64; + x--; + y++; + chunks++; + blocks++; + break; + case 7: + sx -= 64; + x--; + y++; + chunks++; + break; + case 8: + sx -= 64; + sy -= 32; + x -= 2; + chunks++; + blocks++; + break; + } + + /// ASSERT: assert(gpBuffer); + gpBufEnd = &gpBuffer[PitchTbl[143]]; + for(i = 0; i < 7; i++) { + town_draw_upper(x, y, sx, sy, chunks, i, 0); + y++; + sx -= 32; + sy += 16; + town_draw_upper(x, y, sx, sy, chunks, i, 1); + x++; + sx += 32; + sy += 16; + } + /// ASSERT: assert(gpBuffer); + gpBufEnd = &gpBuffer[PitchTbl[320]]; + for(i = 0; i < blocks; i++) { + town_draw_lower(x, y, sx, sy, chunks, 0); + y++; + sx -= 32; + sy += 16; + town_draw_lower(x, y, sx, sy, chunks, 1); + x++; + sx += 32; + sy += 16; + } + for(i = 0; i < 7; i++) { + town_draw_lower_2(x, y, sx, sy, chunks, i, 0); + y++; + sx -= 32; + sy += 16; + town_draw_lower_2(x, y, sx, sy, chunks, i, 1); + x++; + sx += 32; + sy += 16; + } + + if(chrflag || questlog) { + nSrcOff = SCREENXY(112, 159); + nDstOff = SCREENXY(320, 350); + wdt = 160; + } else if(invflag || sbookflag) { + nSrcOff = SCREENXY(112, 159); + nDstOff = SCREENXY(0, 350); + wdt = 160; + } else { + nSrcOff = SCREENXY(32, 159); + nDstOff = SCREENXY(0, 350); + wdt = 320; + } + + /// ASSERT: assert(gpBuffer); + +#ifdef USE_ASM + __asm { + mov esi, gpBuffer + mov edx, nDstOff + mov edi, esi + mov ecx, nSrcOff + add edi, edx + add esi, ecx + mov ebx, edi + add ebx, 768 + mov edx, 176 + label1: + mov ecx, wdt + label2: + mov al, [esi] + inc esi + mov ah, al + mov [edi], ax + mov [ebx], ax + add edi, 2 + add ebx, 2 + dec ecx + jnz label2 + mov eax, 768 + add eax, wdt + sub esi, eax + add eax, eax + sub ebx, eax + sub edi, eax + dec edx + jnz label1 + } +#else + int hgt; + BYTE *src, *dst1, *dst2; + + src = &gpBuffer[nSrcOff]; + dst1 = &gpBuffer[nDstOff]; + dst2 = &gpBuffer[nDstOff + 768]; + + for(hgt = 176; hgt != 0; hgt--, src -= 768 + wdt, dst1 -= 2 * (768 + wdt), dst2 -= 2 * (768 + wdt)) { + for(i = wdt; i != 0; i--) { + *dst1++ = *src; + *dst1++ = *src; + *dst2++ = *src; + *dst2++ = *src; + src++; + } + } +#endif +} + +void T_DrawView(int StartX, int StartY) +{ + light_table_index = 0; + cel_transparency_active = 0; + if ( zoomflag ) + T_DrawGame(StartX, StartY); + else + T_DrawZoom(StartX, StartY); + if ( automapflag ) + DrawAutomap(); + if ( stextflag && !qtextflag ) + DrawSText(); + if ( invflag ) + { + DrawInv(); + } + else if ( sbookflag ) + { + DrawSpellBook(); + } + DrawDurIcon(); + if ( chrflag ) + { + DrawChr(); + } + else if ( questlog ) + { + DrawQuestLog(); + } + else if ( plr[myplr]._pStatPts && !spselflag ) + { + DrawLevelUpIcon(); + } + if ( uitemflag ) + DrawUniqueInfo(); + if ( qtextflag ) + DrawQText(); + if ( spselflag ) + DrawSpellList(); + if ( dropGoldFlag ) + DrawGoldSplit(dropGoldValue); + if ( helpflag ) + DrawHelp(); + if ( msgflag ) + DrawDiabloMsg(); + if ( PauseMode && !deathflag ) + gmenu_draw_pause(); + DrawPlrMsg(); + gmenu_draw(); + doom_draw(); + DrawInfoBox(); + DrawLifeFlask(); + DrawManaFlask(); +} + +void SetTownMicros() +{ + int i, x, y, lv; + WORD *pPiece; + MICROS *pMap; + + for(y = 0; y < MAXDUNY; y++) { + for(x = 0; x < MAXDUNX; x++) { + lv = dPiece[x][y]; + pMap = &dpiece_defs_map_1[IsometricCoord(x, y)]; + if(lv != 0) { + lv--; + pPiece = (WORD *)&pLevelPieces[32 * lv]; + for(i = 0; i < 16; i++) { + pMap->mt[i] = pPiece[(i & 1) + 16 - 2 - (i & 0xE)]; + } + } else { + for(i = 0; i < 16; i++) { + pMap->mt[i] = 0; + } + } + } + } + + if(zoomflag) { + ViewDX = 640; + ViewDY = 352; + ViewBX = 10; + ViewBY = 11; + } else { + ViewDX = 384; + ViewDY = 224; + ViewBX = 6; + ViewBY = 7; + } +} + +void T_FillSector(unsigned char *P3Tiles, unsigned char *pSector, int xi, int yi, int w, int h) +{ + int i, j, xx, yy; + long v1, v2, v3, v4, ii; + + ii = 4; + yy = yi; + for(j = 0; j < h; j++) { + xx = xi; + for(i = 0; i < w; i++) { +#ifdef USE_ASM + __asm { + mov esi, pSector + mov eax, ii + add esi, eax + xor eax, eax + lodsw + or eax, eax + jz label1 + dec eax + mov esi, P3Tiles + shl eax, 3 + add esi, eax + xor eax, eax + lodsw + inc eax + mov v1, eax + lodsw + inc eax + mov v2, eax + lodsw + inc eax + mov v3, eax + lodsw + inc eax + mov v4, eax + jmp label2 + label1: + mov v1, eax + mov v2, eax + mov v3, eax + mov v4, eax + label2: + nop + } +#else + WORD *Map; + + Map = (WORD *)&pSector[ii]; + if(*Map != 0) { + v1 = ((WORD *)&P3Tiles[(*Map - 1) << 3])[0] + 1; + v2 = ((WORD *)&P3Tiles[(*Map - 1) << 3])[1] + 1; + v3 = ((WORD *)&P3Tiles[(*Map - 1) << 3])[2] + 1; + v4 = ((WORD *)&P3Tiles[(*Map - 1) << 3])[3] + 1; + } else { + v1 = 0; + v2 = 0; + v3 = 0; + v4 = 0; + } +#endif + dPiece[xx][yy] = v1; + dPiece[xx + 1][yy] = v2; + dPiece[xx][yy + 1] = v3; + dPiece[xx + 1][yy + 1] = v4; + xx += 2; + ii += 2; + } + yy += 2; + } +} + +void T_FillTile(unsigned char *P3Tiles, int xx, int yy, int t) +{ + long v1, v2, v3, v4; + +#ifdef USE_ASM + __asm { + mov eax, t + dec eax + mov esi, P3Tiles + shl eax, 3 + add esi, eax + xor eax, eax + lodsw + inc eax + mov v1, eax + lodsw + inc eax + mov v2, eax + lodsw + inc eax + mov v3, eax + lodsw + inc eax + mov v4, eax + jmp label1 + mov v1, eax + mov v2, eax + mov v3, eax + mov v4, eax + label1: + nop + } +#else + v1 = ((WORD *)&P3Tiles[(t - 1) << 3])[0] + 1; + v2 = ((WORD *)&P3Tiles[(t - 1) << 3])[1] + 1; + v3 = ((WORD *)&P3Tiles[(t - 1) << 3])[2] + 1; + v4 = ((WORD *)&P3Tiles[(t - 1) << 3])[3] + 1; +#endif + + dPiece[xx][yy] = v1; + dPiece[xx + 1][yy] = v2; + dPiece[xx][yy + 1] = v3; + dPiece[xx + 1][yy + 1] = v4; +} + +void T_Pass3() +{ + int xx, yy, x; + unsigned char *P3Tiles, *pSector; + + for(yy = 0; yy < MAXDUNY; yy += 2) { + for(xx = 0; xx < MAXDUNX; xx += 2) { + dPiece[xx][yy] = 0; + dPiece[xx + 1][yy] = 0; + dPiece[xx][yy + 1] = 0; + dPiece[xx + 1][yy + 1] = 0; + } + } + + P3Tiles = DiabLoad("Levels\\TownData\\Town.TIL", NULL, 'TOWN'); + pSector = DiabLoad("Levels\\TownData\\Sector1s.DUN", NULL, 'TOWN'); + T_FillSector(P3Tiles, pSector, 46, 46, 25, 25); + mem_free_dbg(pSector); + pSector = DiabLoad("Levels\\TownData\\Sector2s.DUN", NULL, 'TOWN'); + T_FillSector(P3Tiles, pSector, 46, 0, 25, 23); + mem_free_dbg(pSector); + pSector = DiabLoad("Levels\\TownData\\Sector3s.DUN", NULL, 'TOWN'); + T_FillSector(P3Tiles, pSector, 0, 46, 23, 25); + mem_free_dbg(pSector); + pSector = DiabLoad("Levels\\TownData\\Sector4s.DUN", NULL, 'TOWN'); + T_FillSector(P3Tiles, pSector, 0, 0, 23, 23); + mem_free_dbg(pSector); + + if(gbMaxPlayers == 1) { + if(!(plr[myplr].pTownWarps & 1)) { + T_FillTile(P3Tiles, 48, 20, 320); + } + if(!(plr[myplr].pTownWarps & 2)) { + T_FillTile(P3Tiles, 16, 68, 332); + T_FillTile(P3Tiles, 16, 70, 331); + } + if(!(plr[myplr].pTownWarps & 4)) { + for(x = 36; x < 46; x++) { + T_FillTile(P3Tiles, x, 78, random(0, 4) + 1); + } + } + } + + if(quests[13]._qactive != 3 && quests[13]._qactive) { + T_FillTile(P3Tiles, 60, 70, 342); + } else { + T_FillTile(P3Tiles, 60, 70, 71); + } + + mem_free_dbg(P3Tiles); +} + +void CreateTown(int entry) +{ + int x, y; + + dminx = 10; + dminy = 10; + dmaxx = 84; + dmaxy = 84; + + if(entry == 0) { + ViewX = 75; + ViewY = 68; + } else if(entry == 1) { + ViewX = 25; + ViewY = 31; + } else if(entry == 7) { + if(TWarpFrom == 5) { + ViewX = 49; + ViewY = 22; + } + if(TWarpFrom == 9) { + ViewX = 18; + ViewY = 69; + } + if(TWarpFrom == 13) { + ViewX = 41; + ViewY = 81; + } + } + + T_Pass3(); + memset(dLight, 0, sizeof(dLight)); + memset(dFlags, 0, sizeof(dFlags)); + memset(dPlayer, 0, sizeof(dPlayer)); + memset(dMonster, 0, sizeof(dMonster)); + memset(dObject, 0, sizeof(dObject)); + memset(dItem, 0, sizeof(dItem)); + memset(dSpecial, 0, sizeof(dSpecial)); + + for(y = 0; y < MAXDUNY; y++) { + for(x = 0; x < MAXDUNX; x++) { + if(dPiece[x][y] == 360) { + dSpecial[x][y] = 1; + } else if(dPiece[x][y] == 358) { + dSpecial[x][y] = 2; + } else if(dPiece[x][y] == 129) { + dSpecial[x][y] = 6; + } else if(dPiece[x][y] == 130) { + dSpecial[x][y] = 7; + } else if(dPiece[x][y] == 128) { + dSpecial[x][y] = 8; + } else if(dPiece[x][y] == 117) { + dSpecial[x][y] = 9; + } else if(dPiece[x][y] == 157) { + dSpecial[x][y] = 10; + } else if(dPiece[x][y] == 158) { + dSpecial[x][y] = 11; + } else if(dPiece[x][y] == 156) { + dSpecial[x][y] = 12; + } else if(dPiece[x][y] == 162) { + dSpecial[x][y] = 13; + } else if(dPiece[x][y] == 160) { + dSpecial[x][y] = 14; + } else if(dPiece[x][y] == 214) { + dSpecial[x][y] = 15; + } else if(dPiece[x][y] == 212) { + dSpecial[x][y] = 16; + } else if(dPiece[x][y] == 217) { + dSpecial[x][y] = 17; + } else if(dPiece[x][y] == 216) { + dSpecial[x][y] = 18; + } + } + } + + SetTownMicros(); +} diff --git a/2020_03_31/Source/town.h b/2020_03_31/Source/town.h new file mode 100644 index 00000000..d1c4435c --- /dev/null +++ b/2020_03_31/Source/town.h @@ -0,0 +1,27 @@ +//HEADER_GOES_HERE +#ifndef __TOWN_H__ +#define __TOWN_H__ + +void town_clear_upper_buf(BYTE *pBuff); +void town_clear_low_buf(BYTE *pBuff); +void town_special_lower(BYTE *pBuff, int nCel); +void town_special_upper(BYTE *pBuff, int nCel); +void town_draw_clipped_e_flag(BYTE *pBuff, int x, int y, int sx, int sy); +void town_draw_clipped_town(BYTE *pBuff, int x, int y, int sx, int sy, int some_flag); +void town_draw_lower(int x, int y, int sx, int sy, int a5, int some_flag); +void town_draw_clipped_e_flag_2(BYTE *pBuff, int x, int y, int a4, int a5, int sx, int sy); +void town_draw_clipped_town_2(BYTE *pBuff, int x, int y, int a4, int a5, int sx, int sy, int some_flag); +void town_draw_lower_2(int x, int y, int sx, int sy, int a5, int a6, int some_flag); +void town_draw_e_flag(BYTE *pBuff, int x, int y, int a4, int dir, int sx, int sy); +void town_draw_town_all(BYTE *pBuff, int x, int y, int a4, int dir, int sx, int sy, int some_flag); +void town_draw_upper(int x, int y, int sx, int sy, int a5, int a6, int some_flag); +void T_DrawGame(int x, int y); +void T_DrawZoom(int x, int y); +void T_DrawView(int StartX, int StartY); +void SetTownMicros(); +void T_FillSector(unsigned char *P3Tiles, unsigned char *pSector, int xi, int yi, int w, int h); +void T_FillTile(unsigned char *P3Tiles, int xx, int yy, int t); +void T_Pass3(); +void CreateTown(int entry); + +#endif /* __TOWN_H__ */ diff --git a/2020_03_31/Source/towners.cpp b/2020_03_31/Source/towners.cpp new file mode 100644 index 00000000..28ae88e3 --- /dev/null +++ b/2020_03_31/Source/towners.cpp @@ -0,0 +1,1005 @@ +#include "diablo.h" + +int storeflag; // weak +int sgnCowMsg; // weak +int numtowners; // idb +DWORD sgdwCowClicks; // weak +BOOL bannerflag; // weak // unused 0x6AAC28 +BOOL boyloadflag; // weak +BYTE *pCowCels; // idb +TownerStruct towner[16]; + + +/* data */ + +char AnimOrder[6][148] = +{ + { + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 5, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 2, 3, 4, + -1 + }, + { + 1, 2, 3, 3, 2, 1, 20, 19, 19, 20, + 1, 2, 3, 3, 2, 1, 20, 19, 19, 20, + 1, 2, 3, 3, 2, 1, 20, 19, 19, 20, + 1, 2, 3, 3, 2, 1, 20, 19, 19, 20, + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 15, 14, 13, 12, + 11, 10, 9, 8, 7, 6, 5, 4, 5, 6, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, + 5, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 16, 17, 18, 19, 20, -1 + }, + { + 1, 1, 25, 25, 24, 23, 22, 21, 20, 19, + 18, 17, 16, 15, 16, 17, 18, 19, 20, 21, + 22, 23, 24, 25, 25, 25, 1, 1, 1, 25, + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 14, 13, 12, 11, 10, + 9, 8, 7, 6, 5, 4, 3, 2, 1, -1 + }, + { + 1, 2, 3, 3, 2, 1, 16, 15, 14, 14, + 16, 1, 2, 3, 3, 2, 1, 16, 15, 14, + 14, 15, 16, 1, 2, 3, 3, 2, 1, 16, + 15, 14, 14, 15, 16, 1, 2, 3, 3, 2, + 1, 16, 15, 14, 14, 15, 16, 1, 2, 3, + 3, 2, 1, 16, 15, 14, 14, 15, 16, 1, + 2, 3, 3, 2, 1, 16, 15, 14, 14, 15, + 16, 1, 2, 3, 3, 2, 1, 16, 15, 14, + 14, 15, 16, 1, 2, 3, 2, 1, 16, 15, + 14, 14, 15, 16, 1, 2, 3, 4, 5, 6, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + -1 + }, + { + 1, 1, 1, 2, 3, 4, 5, 6, 7, 8, + 9, 10, 11, 11, 11, 11, 12, 13, 14, 15, + 16, 17, 18, 18, 1, 1, 1, 18, 17, 16, + 15, 14, 13, 12, 11, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 1, 2, 3, 4, 5, 5, + 5, 4, 3, 2, -1 + }, + { + 4, 4, 4, 5, 6, 6, 6, 5, 4, 15, + 14, 13, 13, 13, 14, 15, 4, 5, 6, 6, + 6, 5, 4, 4, 4, 5, 6, 6, 6, 5, + 4, 15, 14, 13, 13, 13, 14, 15, 4, 5, + 6, 6, 6, 5, 4, 4, 4, 5, 6, 6, + 6, 5, 4, 15, 14, 13, 13, 13, 14, 15, + 4, 5, 6, 6, 6, 5, 4, 3, 2, 1, + 19, 18, 19, 1, 2, 1, 19, 18, 19, 1, + 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 15, 15, 14, 13, + 13, 13, 13, 14, 15, 15, 15, 14, 13, 12, + 12, 12, 11, 10, 10, 10, 9, 8, 9, 10, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 1, 2, 1, 19, 18, 19, 1, 2, 1, 2, + 3, -1 + } +}; +int TownCowX[3] = { 58, 56, 59 }; +int TownCowY[3] = { 16, 14, 20 }; +int TownCowDir[3] = { 1, 3, 4 }; +int cowoffx[8] = { -1, 0, -1, -1, -1, 0, -1, -1 }; +int cowoffy[8] = { -1, -1, -1, 0, -1, -1, -1, 0 }; +int Qtalklist[11][16] = +{ + { TEXT_INFRA6, TEXT_MUSH6, -1, -1, TEXT_VEIL5, -1, TEXT_BUTCH5, TEXT_BANNER6, TEXT_BLIND5, TEXT_BLOOD5, TEXT_ANVIL6, TEXT_WARLRD5, TEXT_KING7, TEXT_POISON7, TEXT_BONE5, TEXT_VILE9 }, + { TEXT_INFRA3, -1, -1, -1, TEXT_VEIL3, -1, TEXT_BUTCH3, TEXT_BANNER4, TEXT_BLIND3, TEXT_BLOOD3, TEXT_ANVIL3, TEXT_WARLRD3, TEXT_KING5, TEXT_POISON4, TEXT_BONE3, TEXT_VILE7 }, + { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, + { TEXT_INFRA2, TEXT_MUSH2, -1, -1, TEXT_VEIL2, -1, TEXT_BUTCH2, -1, TEXT_BLIND2, TEXT_BLOOD2, TEXT_ANVIL2, TEXT_WARLRD2, TEXT_KING3, TEXT_POISON2, TEXT_BONE2, TEXT_VILE4 }, + { TEXT_INFRA1, TEXT_MUSH1, -1, -1, TEXT_VEIL1, TEXT_VILE3, TEXT_BUTCH1, TEXT_BANNER1, TEXT_BLIND1, TEXT_BLOOD1, TEXT_ANVIL1, TEXT_WARLRD1, TEXT_KING1, TEXT_POISON1, TEXT_BONE1, TEXT_VILE2 }, + { TEXT_INFRA8, TEXT_MUSH7, -1, -1, TEXT_VEIL6, -1, TEXT_BUTCH6, TEXT_BANNER7, TEXT_BLIND6, TEXT_BLOOD6, TEXT_ANVIL8, TEXT_WARLRD6, TEXT_KING8, TEXT_POISON8, TEXT_BONE6, TEXT_VILE10 }, + { TEXT_INFRA9, TEXT_MUSH9, -1, -1, TEXT_VEIL7, -1, TEXT_BUTCH7, TEXT_BANNER8, TEXT_BLIND7, TEXT_BLOOD7, TEXT_ANVIL9, TEXT_WARLRD7, TEXT_KING9, TEXT_POISON9, TEXT_BONE7, TEXT_VILE11 }, + { TEXT_INFRA4, TEXT_MUSH5, -1, -1, TEXT_VEIL4, -1, TEXT_BUTCH4, TEXT_BANNER5, TEXT_BLIND4, TEXT_BLOOD4, TEXT_ANVIL4, TEXT_WARLRD4, TEXT_KING6, TEXT_POISON6, TEXT_BONE4, TEXT_VILE8 }, + { TEXT_INFRA10, TEXT_MUSH13, -1, -1, TEXT_VEIL8, -1, TEXT_BUTCH8, TEXT_BANNER9, TEXT_BLIND8, TEXT_BLOOD8, TEXT_ANVIL10, TEXT_WARLRD8, TEXT_KING10, TEXT_POISON10, TEXT_BONE8, TEXT_VILE12 }, + { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, + { TEXT_KING1, TEXT_KING1, TEXT_KING1, TEXT_KING1, TEXT_KING1, TEXT_KING1, TEXT_KING1, TEXT_KING1, TEXT_KING1, TEXT_KING1, TEXT_KING1, TEXT_KING1, TEXT_KING1, TEXT_KING1, TEXT_KING1, TEXT_KING1 } +}; +int CowPlaying = -1; + +int GetActiveTowner(int t) +{ + int i; + + for(i = 0; i < numtowners; i++) { + if(towner[i]._ttype == t) { + return i; + } + } + + return -1; +} + +void SetTownerGPtrs(BYTE *pData, BYTE **pAnim) +{ + int i; +#ifdef USE_ASM + BYTE *src; + + for(i = 0; i < 8; i++) { + src = pData; + __asm { + mov eax, src + mov ebx, eax + mov edx, i + shl edx, 2 + add ebx, edx + mov edx, [ebx] + add eax, edx + mov src, eax + } + pAnim[i] = src; + } +#else + DWORD *pFrameTable; + + pFrameTable = (DWORD *)pData; + + for(i = 0; i < 8; i++) { + pAnim[i] = &pData[pFrameTable[i]]; + } +#endif +} + +void NewTownerAnim(int tnum, unsigned char *pAnim, int numFrames, int Delay) +{ + /// ASSERT: assert(pAnim); + + towner[tnum]._tAnimData = pAnim; + towner[tnum]._tAnimLen = numFrames; + towner[tnum]._tAnimFrame = 1; + towner[tnum]._tAnimCnt = 0; + towner[tnum]._tAnimDelay = Delay; +} + +void InitTownerInfo(int i, long w, BOOL sel, int t, int x, int y, char ao, int tp) /* int ao */ +{ + memset(&towner[i], 0, sizeof(*towner)); + + towner[i]._tSelFlag = sel; + towner[i]._tAnimWidth = w; + towner[i]._tAnimWidth2 = (w - 64) >> 1; + towner[i]._tMsgSaid = FALSE; + towner[i]._ttype = t; + towner[i]._tx = x; + towner[i]._ty = y; + dMonster[x][y] = i + 1; + towner[i]._tAnimOrder = ao; + towner[i]._tTenPer = tp; + towner[i]._tSeed = GetRndSeed(); +} + +void InitQstSnds(int i) +{ + int j, quest; + + j = i; + if(boyloadflag) { + j++; + } + + for(quest = 0; quest < MAXQUESTS; quest++) { + towner[i].qsts[quest]._qsttype = quests[quest]._qtype; + towner[i].qsts[quest]._qstmsg = Qtalklist[j][quest]; + if(Qtalklist[j][quest] != -1) { + towner[i].qsts[quest]._qstmsgact = TRUE; + } else { + towner[i].qsts[quest]._qstmsgact = FALSE; + } + } +} + +void InitSmith() +{ + int i; + + InitTownerInfo(numtowners, 96, 1, 0, 62, 63, 0, 10); + /// ASSERT: assert(! towner[numtowners]._tNData); + InitQstSnds(numtowners); + towner[numtowners]._tNData = DiabLoad("Towners\\Smith\\SmithN.CEL", NULL, 'TOWN'); + + for(i = 0; i < 8; i++) { + towner[numtowners]._tNAnim[i] = towner[numtowners]._tNData; + } + + towner[numtowners]._tNFrames = 16; + NewTownerAnim(numtowners, towner[numtowners]._tNAnim[1], towner[numtowners]._tNFrames, 3); + strcpy(towner[numtowners]._tName, "Griswold the Blacksmith"); + numtowners++; +} + +void InitBarOwner() +{ + int i; + + bannerflag = FALSE; + InitTownerInfo(numtowners, 96, 1, 3, 55, 62, 3, 10); + /// ASSERT: assert(! towner[numtowners]._tNData); + InitQstSnds(numtowners); + towner[numtowners]._tNData = DiabLoad("Towners\\TwnF\\TwnFN.CEL", NULL, 'TOWN'); + + for(i = 0; i < 8; i++) { + towner[numtowners]._tNAnim[i] = towner[numtowners]._tNData; + } + + towner[numtowners]._tNFrames = 16; + NewTownerAnim(numtowners, towner[numtowners]._tNAnim[1], towner[numtowners]._tNFrames, 3); + strcpy(towner[numtowners]._tName, "Ogden the Tavern owner"); + numtowners++; +} + +void InitTownDead() +{ + int i; + + InitTownerInfo(numtowners, 96, 1, 2, 24, 32, -1, 10); + /// ASSERT: assert(! towner[numtowners]._tNData); + InitQstSnds(numtowners); + towner[numtowners]._tNData = DiabLoad("Towners\\Butch\\Deadguy.CEL", NULL, 'TOWN'); + + for(i = 0; i < 8; i++) { + towner[numtowners]._tNAnim[i] = towner[numtowners]._tNData; + } + + towner[numtowners]._tNFrames = 8; + NewTownerAnim(numtowners, towner[numtowners]._tNAnim[4], towner[numtowners]._tNFrames, 6); + strcpy(towner[numtowners]._tName, "Wounded Townsman"); + numtowners++; +} + +void InitWitch() +{ + int i; + + InitTownerInfo(numtowners, 96, 1, 6, 80, 20, 5, 10); + /// ASSERT: assert(! towner[numtowners]._tNData); + InitQstSnds(numtowners); + towner[numtowners]._tNData = DiabLoad("Towners\\TownWmn1\\Witch.CEL", NULL, 'TOWN'); + + for(i = 0; i < 8; i++) { + towner[numtowners]._tNAnim[i] = towner[numtowners]._tNData; + } + + towner[numtowners]._tNFrames = 19; + NewTownerAnim(numtowners, towner[numtowners]._tNAnim[0], towner[numtowners]._tNFrames, 6); + strcpy(towner[numtowners]._tName, "Adria the Witch"); + numtowners++; +} + +void InitBarmaid() +{ + int i; + + InitTownerInfo(numtowners, 96, 1, 7, 43, 66, -1, 10); + /// ASSERT: assert(! towner[numtowners]._tNData); + InitQstSnds(numtowners); + towner[numtowners]._tNData = DiabLoad("Towners\\TownWmn1\\WmnN.CEL", NULL, 'TOWN'); + + for(i = 0; i < 8; i++) { + towner[numtowners]._tNAnim[i] = towner[numtowners]._tNData; + } + + towner[numtowners]._tNFrames = 18; + NewTownerAnim(numtowners, towner[numtowners]._tNAnim[0], towner[numtowners]._tNFrames, 6); + strcpy(towner[numtowners]._tName, "Gillian the Barmaid"); + numtowners++; +} + +void InitBoy() +{ + int i; + + boyloadflag = TRUE; + InitTownerInfo(numtowners, 96, 1, 8, 11, 53, -1, 10); + /// ASSERT: assert(! towner[numtowners]._tNData); + InitQstSnds(numtowners); + towner[numtowners]._tNData = DiabLoad("Towners\\TownBoy\\PegKid1.CEL", NULL, 'TOWN'); + + for(i = 0; i < 8; i++) { + towner[numtowners]._tNAnim[i] = towner[numtowners]._tNData; + } + + towner[numtowners]._tNFrames = 20; + NewTownerAnim(numtowners, towner[numtowners]._tNAnim[0], towner[numtowners]._tNFrames, 6); + strcpy(towner[numtowners]._tName, "Wirt the Peg-legged boy"); + numtowners++; +} + +void InitHealer() +{ + int i; + + InitTownerInfo(numtowners, 96, 1, 1, 55, 79, 1, 10); + /// ASSERT: assert(! towner[numtowners]._tNData); + InitQstSnds(numtowners); + towner[numtowners]._tNData = DiabLoad("Towners\\Healer\\Healer.CEL", NULL, 'TOWN'); + + for(i = 0; i < 8; i++) { + towner[numtowners]._tNAnim[i] = towner[numtowners]._tNData; + } + + towner[numtowners]._tNFrames = 20; + NewTownerAnim(numtowners, towner[numtowners]._tNAnim[7], towner[numtowners]._tNFrames, 6); + strcpy(towner[numtowners]._tName, "Pepin the Healer"); + numtowners++; +} + +void InitTeller() +{ + int i; + + InitTownerInfo(numtowners, 96, 1, 4, 62, 71, 2, 10); + /// ASSERT: assert(! towner[numtowners]._tNData); + InitQstSnds(numtowners); + towner[numtowners]._tNData = DiabLoad("Towners\\Strytell\\Strytell.CEL", NULL, 'TOWN'); + + for(i = 0; i < 8; i++) { + towner[numtowners]._tNAnim[i] = towner[numtowners]._tNData; + } + + towner[numtowners]._tNFrames = 25; + NewTownerAnim(numtowners, towner[numtowners]._tNAnim[0], towner[numtowners]._tNFrames, 3); + strcpy(towner[numtowners]._tName, "Cain the Elder"); + numtowners++; +} + +void InitDrunk() +{ + int i; + + InitTownerInfo(numtowners, 96, 1, 5, 71, 84, 4, 10); + /// ASSERT: assert(! towner[numtowners]._tNData); + InitQstSnds(numtowners); + towner[numtowners]._tNData = DiabLoad("Towners\\Drunk\\TwnDrunk.CEL", NULL, 'TOWN'); + + for(i = 0; i < 8; i++) { + towner[numtowners]._tNAnim[i] = towner[numtowners]._tNData; + } + + towner[numtowners]._tNFrames = 18; + NewTownerAnim(numtowners, towner[numtowners]._tNAnim[0], towner[numtowners]._tNFrames, 3); + strcpy(towner[numtowners]._tName, "Farnham the Drunk"); + numtowners++; +} + +void InitCows() +{ + int i, x, y, d, x2, y2; + + /// ASSERT: assert(! pCowCels); + pCowCels = DiabLoad("Towners\\Animals\\Cow.CEL", NULL, 'TOWN'); + + for(i = 0; i < 3; i++) { + x = TownCowX[i]; + y = TownCowY[i]; + d = TownCowDir[i]; + InitTownerInfo(numtowners, 128, 0, 9, x, y, -1, 10); + towner[numtowners]._tNData = pCowCels; + SetTownerGPtrs(towner[numtowners]._tNData, towner[numtowners]._tNAnim); + towner[numtowners]._tNFrames = 12; + NewTownerAnim(numtowners, towner[numtowners]._tNAnim[d], towner[numtowners]._tNFrames, 3); + towner[numtowners]._tAnimFrame = random(0, 11) + 1; + towner[numtowners]._tSelFlag = 1; + strcpy(towner[numtowners]._tName, "Cow"); + x2 = x + cowoffx[d]; + y2 = y + cowoffy[d]; + if(dMonster[x][y2] == 0) { + dMonster[x][y2] = -(numtowners + 1); + } + if(dMonster[x2][y] == 0) { + dMonster[x2][y] = -(numtowners + 1); + } + if(dMonster[x2][y2] == 0) { + dMonster[x2][y2] = -(numtowners + 1); + } + numtowners++; + } +} + +void InitTowners() +{ + numtowners = 0; + boyloadflag = FALSE; + InitSmith(); + InitHealer(); + + if(quests[6]._qactive != 0 && quests[6]._qactive != 3) { + InitTownDead(); + } + + InitBarOwner(); + InitTeller(); + InitDrunk(); + InitWitch(); + InitBarmaid(); + InitBoy(); + InitCows(); +} + +void FreeTownerGFX() +{ + int i; + + for(i = 0; i < 16; i++) { + if(towner[i]._tNData == pCowCels) { + towner[i]._tNData = NULL; + } else if(towner[i]._tNData != NULL) { + MemFreeDbg(towner[i]._tNData); + } + } + + MemFreeDbg(pCowCels); +} + +void TownCtrlMsg(int i) +{ + int p, dx, dy; + + if(towner[i]._tbtcnt == 0) { + return; + } + + p = towner[i]._tVar1; + dx = abs(towner[i]._tx - plr[p].WorldX); + dy = abs(towner[i]._ty - plr[p].WorldY); + + if(dx >= 2 || dy >= 2) { + towner[i]._tbtcnt = 0; + } + if(towner[i]._tbtcnt == 0) { + qtextflag = 0; + stream_stop(); + } +} + +void TownBlackSmith() +{ + int /* x, y, */ tidx; + + tidx = GetActiveTowner(TOWN_SMITH); + TownCtrlMsg(tidx); +} + +void TownBarOwner() +{ + int /* x, y, */ tidx; + + tidx = GetActiveTowner(TOWN_TAVERN); + TownCtrlMsg(tidx); +} + +void TownDead() +{ + int tidx; + + tidx = GetActiveTowner(TOWN_DEADGUY); + TownCtrlMsg(tidx); + + if(!qtextflag) { + if((quests[6]._qactive != 2 || quests[6]._qlog) && quests[6]._qactive != 1) { + towner[tidx]._tAnimDelay = 1000; + towner[tidx]._tAnimFrame = 1; + strcpy(towner[tidx]._tName, "Slain Townsman"); + } else { + return; + } + } + if(quests[6]._qactive != 1) { + towner[tidx]._tAnimCnt = 0; + } +} + +void TownHealer() +{ + TownCtrlMsg(GetActiveTowner(TOWN_HEALER)); +} + +void TownStory() +{ + TownCtrlMsg(GetActiveTowner(TOWN_STORY)); +} + +void TownDrunk() +{ + TownCtrlMsg(GetActiveTowner(TOWN_DRUNK)); +} + +void TownBoy() +{ + TownCtrlMsg(GetActiveTowner(TOWN_PEGBOY)); +} + +void TownWitch() +{ + TownCtrlMsg(GetActiveTowner(TOWN_WITCH)); +} + +void TownBarMaid() +{ + TownCtrlMsg(GetActiveTowner(TOWN_BMAID)); +} + +void TownCow() +{ + TownCtrlMsg(GetActiveTowner(TOWN_COW)); +} + +void ProcessTowners() +{ + int i, ao; + + for(i = 0; i < 16; i++) { + switch(towner[i]._ttype) { + case TOWN_SMITH: + TownBlackSmith(); + break; + case TOWN_HEALER: + TownHealer(); + break; + case TOWN_DEADGUY: + TownDead(); + break; + case TOWN_TAVERN: + TownBarOwner(); + break; + case TOWN_STORY: + TownStory(); + break; + case TOWN_DRUNK: + TownDrunk(); + break; + case TOWN_WITCH: + TownWitch(); + break; + case TOWN_BMAID: + TownBarMaid(); + break; + case TOWN_PEGBOY: + TownBoy(); + break; + case TOWN_COW: + TownCow(); + break; + } + towner[i]._tAnimCnt++; + if(towner[i]._tAnimCnt >= towner[i]._tAnimDelay) { + towner[i]._tAnimCnt = 0; + if(towner[i]._tAnimOrder >= 0) { + ao = towner[i]._tAnimOrder; + towner[i]._tAnimFrameCnt++; + if(AnimOrder[ao][towner[i]._tAnimFrameCnt] == -1) { + towner[i]._tAnimFrameCnt = 0; + } + towner[i]._tAnimFrame = AnimOrder[ao][towner[i]._tAnimFrameCnt]; + } else { + towner[i]._tAnimFrame++; + if(towner[i]._tAnimFrame > towner[i]._tAnimLen) { + towner[i]._tAnimFrame = 1; + } + } + } + } +} + +ItemStruct *PlrHasItem(int pnum, int item, int &i) +{ + for(i = 0; i < plr[pnum]._pNumInv; i++) { + if(plr[pnum].InvList[i].IDidx == item) { + return &plr[pnum].InvList[i]; + } + } + + return NULL; +} + +void TownerTalk(int first, int t) +{ + sgdwCowClicks = 0; + sgnCowMsg = 0; + storeflag = 1; + InitQTextMsg(first); +} + +void TalkToTowner(int p, int t) +{ + int i, dx, dy, rv1, rv2, rv3; + ItemStruct *Item; + + rv1 = random(6, 3); /* unused */ + rv2 = random(6, 4); /* unused */ + rv3 = random(6, 5); /* unused */ + + dx = abs(plr[p].WorldX - towner[t]._tx); + dy = abs(plr[p].WorldY - towner[t]._ty); +#ifdef _DEBUG + if(!debug_mode_key_d && (dx >= 2 || dy >= 2)) { + return; + } +#else + if(dx >= 2 || dy >= 2) { + return; + } +#endif + + if(qtextflag) { + return; + } + + towner[t]._tMsgSaid = FALSE; + + if(pcurs >= CURSOR_FIRSTITEM && !DropItemBeforeTrig()) { + return; + } + + if(t == GetActiveTowner(TOWN_TAVERN)) { + if(!plr[p]._pLvlVisited[0] && !towner[t]._tMsgSaid) { + towner[t]._tbtcnt = 150; + towner[t]._tVar1 = p; + InitQTextMsg(TEXT_INTRO); + towner[t]._tMsgSaid = TRUE; + } + if((plr[p]._pLvlVisited[2] || plr[p]._pLvlVisited[4]) && quests[Q_SKELKING]._qactive != 0) { + if(quests[Q_SKELKING]._qvar2 == 0) { + if(!towner[t]._tMsgSaid) { + quests[Q_SKELKING]._qvar2 = 1; + quests[Q_SKELKING]._qlog = TRUE; + if(quests[Q_SKELKING]._qactive == 1) { + quests[Q_SKELKING]._qactive = 2; + quests[Q_SKELKING]._qvar1 = 1; + } + towner[t]._tbtcnt = 150; + towner[t]._tVar1 = p; + InitQTextMsg(TEXT_KING2); + towner[t]._tMsgSaid = TRUE; + NetSendCmdQuest(TRUE, Q_SKELKING); + } + } + if(quests[Q_SKELKING]._qactive == 3 && quests[Q_SKELKING]._qvar2 == 1) { + if(!towner[t]._tMsgSaid) { + quests[Q_SKELKING]._qvar2 = 2; + quests[Q_SKELKING]._qvar1 = 2; + towner[t]._tbtcnt = 150; + towner[t]._tVar1 = p; + InitQTextMsg(TEXT_KING4); + towner[t]._tMsgSaid = TRUE; + NetSendCmdQuest(TRUE, Q_SKELKING); + } + } + } + if(gbMaxPlayers == 1 && plr[p]._pLvlVisited[3] && quests[Q_LTBANNER]._qactive != 0) { + if((quests[Q_LTBANNER]._qactive == 1 || quests[Q_LTBANNER]._qactive == 2) && quests[Q_LTBANNER]._qvar2 == 0) { + if(!towner[t]._tMsgSaid) { + quests[Q_LTBANNER]._qvar2 = 1; + if(quests[Q_LTBANNER]._qactive == 1) { + quests[Q_LTBANNER]._qvar1 = 1; + quests[Q_LTBANNER]._qactive = 2; + } + quests[Q_LTBANNER]._qlog = TRUE; + towner[t]._tbtcnt = 150; + towner[t]._tVar1 = p; + InitQTextMsg(TEXT_BANNER2); + towner[t]._tMsgSaid = TRUE; + } + } + if(quests[Q_LTBANNER]._qvar2 == 1 && PlrHasItem(p, IDI_BANNER, i) != NULL) { + if(!towner[t]._tMsgSaid) { + quests[Q_LTBANNER]._qactive = 3; + quests[Q_LTBANNER]._qvar1 = 3; + RemoveInvItem(p, i); + CreateItem(UITEM_HARCREST, towner[t]._tx, towner[t]._ty + 1); + towner[t]._tbtcnt = 150; + towner[t]._tVar1 = p; + InitQTextMsg(TEXT_BANNER3); + towner[t]._tMsgSaid = TRUE; + } + } + } + if(!qtextflag) { + TownerTalk(TEXT_OGDEN1, t); + if(storeflag) { + StartStore(STORE_TAVERN); + } + } + } else if(t == GetActiveTowner(TOWN_DEADGUY)) { + if(quests[Q_BUTCHER]._qactive == 2 && quests[Q_BUTCHER]._qvar1 == 1) { + towner[t]._tbtcnt = 150; + towner[t]._tVar1 = p; + quests[Q_BUTCHER]._qvar1 = 1; + if(plr[p]._pClass == 0 && !effect_is_playing(PS_WARR8)) { + PlaySFX(PS_WARR8); + } else if(plr[p]._pClass == 1 && !effect_is_playing(PS_ROGUE8)) { + PlaySFX(PS_ROGUE8); + } else if(plr[p]._pClass == 2 && !effect_is_playing(PS_MAGE8)) { + PlaySFX(PS_MAGE8); + } + towner[t]._tMsgSaid = TRUE; + } else if(quests[Q_BUTCHER]._qactive == 3 && quests[Q_BUTCHER]._qvar1 == 1) { + quests[Q_BUTCHER]._qvar1 = 1; + towner[t]._tbtcnt = 150; + towner[t]._tVar1 = p; + towner[t]._tMsgSaid = TRUE; + } else if(quests[Q_BUTCHER]._qactive == 1 || quests[Q_BUTCHER]._qactive == 2 && quests[Q_BUTCHER]._qvar1 == 0) { + quests[Q_BUTCHER]._qactive = 2; + quests[Q_BUTCHER]._qlog = TRUE; + quests[Q_BUTCHER]._qmsg = TEXT_BUTCH9; + quests[Q_BUTCHER]._qvar1 = 1; + towner[t]._tbtcnt = 50; + towner[t]._tVar1 = p; + towner[t]._tVar2 = 3; + InitQTextMsg(TEXT_BUTCH9); + towner[t]._tMsgSaid = TRUE; + NetSendCmdQuest(TRUE, Q_BUTCHER); + } + } else if(t == GetActiveTowner(TOWN_SMITH)) { + if(gbMaxPlayers == 1) { + if(plr[p]._pLvlVisited[4] && quests[Q_ROCK]._qactive != 0) { + if(quests[Q_ROCK]._qvar2 == 0) { + quests[Q_ROCK]._qvar2 = 1; + quests[Q_ROCK]._qlog = TRUE; + if(quests[Q_ROCK]._qactive == 1) { + quests[Q_ROCK]._qactive = 2; + quests[Q_ROCK]._qvar1 = 1; + } + towner[t]._tbtcnt = 150; + towner[t]._tVar1 = p; + InitQTextMsg(TEXT_INFRA5); + towner[t]._tMsgSaid = TRUE; + } + if(quests[Q_ROCK]._qvar2 == 1 && PlrHasItem(p, IDI_ROCK, i) != NULL) { + if(!towner[t]._tMsgSaid) { + quests[Q_ROCK]._qactive = 3; + quests[Q_ROCK]._qvar2 = 2; + quests[Q_ROCK]._qvar1 = 2; + RemoveInvItem(p, i); + CreateItem(UITEM_INFRARING, towner[t]._tx, towner[t]._ty + 1); + towner[t]._tbtcnt = 150; + towner[t]._tVar1 = p; + InitQTextMsg(TEXT_INFRA7); + towner[t]._tMsgSaid = TRUE; + } + } + } + if(plr[p]._pLvlVisited[9] && quests[Q_ANVIL]._qactive != 0) { + if((quests[Q_ANVIL]._qactive == 1 || quests[Q_ANVIL]._qactive == 2) && quests[Q_ANVIL]._qvar2 == 0) { + if(!towner[t]._tMsgSaid) { + if(quests[Q_ROCK]._qvar2 == 2 || quests[Q_ROCK]._qactive == 2 && quests[Q_ROCK]._qvar2 == 1) { + quests[Q_ANVIL]._qvar2 = 1; + quests[Q_ANVIL]._qlog = TRUE; + if(quests[Q_ANVIL]._qactive == 1) { + quests[Q_ANVIL]._qactive = 2; + quests[Q_ANVIL]._qvar1 = 1; + } + towner[t]._tbtcnt = 150; + towner[t]._tVar1 = p; + InitQTextMsg(TEXT_ANVIL5); + towner[t]._tMsgSaid = TRUE; + } + } + } + if(quests[Q_ANVIL]._qvar2 == 1 && PlrHasItem(p, IDI_ANVIL, i) != NULL) { + if(!towner[t]._tMsgSaid) { + quests[Q_ANVIL]._qactive = 3; + quests[Q_ANVIL]._qvar2 = 2; + quests[Q_ANVIL]._qvar1 = 2; + RemoveInvItem(p, i); + CreateItem(UITEM_GRISWOLD, towner[t]._tx, towner[t]._ty + 1); + towner[t]._tbtcnt = 150; + towner[t]._tVar1 = p; + InitQTextMsg(TEXT_ANVIL7); + towner[t]._tMsgSaid = TRUE; + } + } + } + } + if(!qtextflag) { + TownerTalk(TEXT_GRISWOLD1, t); + if(storeflag) { + StartStore(STORE_SMITH); + } + } + } else if(t == GetActiveTowner(TOWN_WITCH)) { + if(quests[Q_MUSHROOM]._qactive == 1 && PlrHasItem(p, IDI_FUNGALTM, i) != NULL) { + RemoveInvItem(p, i); + quests[Q_MUSHROOM]._qactive = 2; + quests[Q_MUSHROOM]._qlog = TRUE; + quests[Q_MUSHROOM]._qvar1 = 2; + towner[t]._tbtcnt = 150; + towner[t]._tVar1 = p; + InitQTextMsg(TEXT_MUSH8); + towner[t]._tMsgSaid = TRUE; + } else if(quests[Q_MUSHROOM]._qactive == 2) { + if(quests[Q_MUSHROOM]._qvar1 >= 2 && quests[Q_MUSHROOM]._qvar1 <= 4) { + if(PlrHasItem(p, IDI_MUSHROOM, i) != NULL) { + RemoveInvItem(p, i); + quests[Q_MUSHROOM]._qvar1 = 5; + Qtalklist[TOWN_HEALER][Q_MUSHROOM] = TEXT_MUSH3; + Qtalklist[TOWN_WITCH][Q_MUSHROOM] = -1; + towner[t]._tbtcnt = 150; + towner[t]._tVar1 = p; + quests[Q_MUSHROOM]._qmsg = TEXT_MUSH10; + InitQTextMsg(TEXT_MUSH10); + towner[t]._tMsgSaid = TRUE; + } else if(quests[Q_MUSHROOM]._qmsg != TEXT_MUSH9) { + towner[t]._tbtcnt = 150; + towner[t]._tVar1 = p; + quests[Q_MUSHROOM]._qmsg = TEXT_MUSH9; + InitQTextMsg(TEXT_MUSH9); + towner[t]._tMsgSaid = TRUE; + } + } else { + Item = PlrHasItem(p, IDI_SPECELIX, i); + if(Item != NULL) { + towner[t]._tbtcnt = 150; + towner[t]._tVar1 = p; + InitQTextMsg(TEXT_MUSH12); + quests[Q_MUSHROOM]._qactive = 3; + towner[t]._tMsgSaid = TRUE; + AllItemsList[Item->IDidx].iUsable = TRUE; + } else if(PlrHasItem(p, IDI_BRAIN, i) != NULL && quests[Q_MUSHROOM]._qvar2 != TEXT_MUSH11) { + towner[t]._tbtcnt = 150; + towner[t]._tVar1 = p; + quests[Q_MUSHROOM]._qvar2 = TEXT_MUSH11; + InitQTextMsg(TEXT_MUSH11); + towner[t]._tMsgSaid = TRUE; + } + } + } + if(!qtextflag) { + TownerTalk(TEXT_ADRIA1, t); + if(storeflag) { + StartStore(STORE_WITCH); + } + } + } else if(t == GetActiveTowner(TOWN_BMAID)) { + if(!qtextflag) { + TownerTalk(TEXT_GILLIAN1, t); + if(storeflag) { + StartStore(STORE_BARMAID); + } + } + } else if(t == GetActiveTowner(TOWN_DRUNK)) { + if(!qtextflag) { + TownerTalk(TEXT_FARNHAM1, t); + if(storeflag) { + StartStore(STORE_DRUNK); + } + } + } else if(t == GetActiveTowner(TOWN_HEALER)) { + if(gbMaxPlayers == 1) { + if(plr[p]._pLvlVisited[1] && !towner[t]._tMsgSaid) { + if(quests[Q_PWATER]._qactive == 1) { + quests[Q_PWATER]._qactive = 2; + quests[Q_PWATER]._qlog = TRUE; + quests[Q_PWATER]._qmsg = TEXT_POISON3; + quests[Q_PWATER]._qvar1 = 1; + towner[t]._tbtcnt = 150; + towner[t]._tVar1 = p; + InitQTextMsg(TEXT_POISON3); + towner[t]._tMsgSaid = TRUE; + } else if(quests[Q_PWATER]._qactive == 3 && quests[Q_PWATER]._qvar1 != 2) { + quests[Q_PWATER]._qvar1 = 2; + towner[t]._tbtcnt = 150; + towner[t]._tVar1 = p; + InitQTextMsg(TEXT_POISON5); + CreateItem(UITEM_TRING, towner[t]._tx, towner[t]._ty + 1); + towner[t]._tMsgSaid = TRUE; + } + } + if(quests[Q_MUSHROOM]._qactive == 2 && quests[Q_MUSHROOM]._qmsg == TEXT_MUSH10 && PlrHasItem(p, IDI_BRAIN, i) != NULL) { + RemoveInvItem(p, i); + SpawnQuestItem(IDI_SPECELIX, towner[t]._tx, towner[t]._ty + 1, 0, 0); + InitQTextMsg(TEXT_MUSH4); + quests[Q_MUSHROOM]._qvar1 = 7; + Qtalklist[TOWN_HEALER][Q_MUSHROOM] = -1; + } + } + if(!qtextflag) { + TownerTalk(TEXT_PEPIN1, t); + if(storeflag) { + StartStore(STORE_HEALER); + } + } + } else if(t == GetActiveTowner(TOWN_PEGBOY)) { + if(!qtextflag) { + TownerTalk(TEXT_WIRT1, t); + if(storeflag) { + StartStore(STORE_BOY); + } + } + } else if(t == GetActiveTowner(TOWN_STORY)) { + if(gbMaxPlayers == 1) { + if(quests[Q_BETRAYER]._qactive == 1 && PlrHasItem(p, IDI_LAZSTAFF, i) != NULL) { + RemoveInvItem(p, i); + quests[Q_BETRAYER]._qvar1 = 2; + towner[t]._tbtcnt = 150; + towner[t]._tVar1 = p; + InitQTextMsg(TEXT_VILE1); + quests[Q_BETRAYER]._qactive = 2; + quests[Q_BETRAYER]._qlog = TRUE; + towner[t]._tMsgSaid = TRUE; + } else if(quests[Q_BETRAYER]._qactive == 3 && quests[Q_BETRAYER]._qvar1 == 7) { + quests[Q_BETRAYER]._qvar1 = 8; + towner[t]._tbtcnt = 150; + towner[t]._tVar1 = p; + InitQTextMsg(TEXT_VILE3); + quests[Q_DIABLO]._qlog = TRUE; + towner[t]._tMsgSaid = TRUE; + } + } + if(gbMaxPlayers != 1) { + if(quests[Q_BETRAYER]._qactive == 2 && !quests[Q_BETRAYER]._qlog) { + towner[t]._tbtcnt = 150; + towner[t]._tVar1 = p; + InitQTextMsg(TEXT_VILE1); + towner[t]._tMsgSaid = TRUE; + quests[Q_BETRAYER]._qlog = TRUE; + NetSendCmdQuest(TRUE, Q_BETRAYER); + } else if(quests[Q_BETRAYER]._qactive == 3 && quests[Q_BETRAYER]._qvar1 == 7) { + quests[Q_BETRAYER]._qvar1 = 8; + towner[t]._tbtcnt = 150; + towner[t]._tVar1 = p; + InitQTextMsg(TEXT_VILE3); + towner[t]._tMsgSaid = TRUE; + NetSendCmdQuest(TRUE, Q_BETRAYER); + quests[Q_DIABLO]._qlog = TRUE; + NetSendCmdQuest(TRUE, Q_DIABLO); + } + } + if(!qtextflag) { + TownerTalk(TEXT_STORY1, t); + if(storeflag) { + StartStore(STORE_STORY); + } + } + } else if(towner[t]._ttype == TOWN_COW && !qtextflag) { + CowSFX(p); + } +} + +void CowSFX(int pnum) +{ + static const int snSFX[3][3] = { + { PS_WARR52, PS_ROGUE52, PS_MAGE52 }, + { PS_WARR49, PS_ROGUE49, PS_MAGE49 }, + { PS_WARR50, PS_ROGUE50, PS_MAGE50 } + }; + static const int snLastCowSFX = sizeof(snSFX) / sizeof(snSFX[0]); + + if(CowPlaying != -1 && effect_is_playing(CowPlaying)) { + return; + } + + sgdwCowClicks++; + if(sgdwCowClicks >= 8) { + PlaySfxLoc(TSFX_COW1, plr[pnum].WorldX, plr[pnum].WorldY + 5); + sgdwCowClicks = 4; + CowPlaying = snSFX[sgnCowMsg][plr[pnum]._pClass]; + sgnCowMsg++; + if(sgnCowMsg >= snLastCowSFX) { + sgnCowMsg = 0; + } + } else { + if(sgdwCowClicks != 4) { + CowPlaying = TSFX_COW1; + } else { + CowPlaying = TSFX_COW2; + } + } + + PlaySfxLoc(CowPlaying, plr[pnum].WorldX, plr[pnum].WorldY); +} diff --git a/2020_03_31/Source/towners.h b/2020_03_31/Source/towners.h new file mode 100644 index 00000000..e6b76cfd --- /dev/null +++ b/2020_03_31/Source/towners.h @@ -0,0 +1,59 @@ +//HEADER_GOES_HERE +#ifndef __TOWNERS_H__ +#define __TOWNERS_H__ + +extern int storeflag; // weak +extern int sgnCowMsg; // weak +extern int numtowners; // idb +extern DWORD sgdwCowClicks; // weak +extern BOOL bannerflag; // weak // unused 0x6AAC28 +extern BOOL boyloadflag; // weak +extern BYTE *pCowCels; // idb +extern TownerStruct towner[16]; + +int GetActiveTowner(int t); +void SetTownerGPtrs(BYTE *pData, BYTE **pAnim); +void NewTownerAnim(int tnum, unsigned char *pAnim, int numFrames, int Delay); +void InitTownerInfo(int i, long w, BOOL sel, int t, int x, int y, char ao, int tp); +void InitQstSnds(int i); +void InitSmith(); +void InitBarOwner(); +void InitTownDead(); +void InitWitch(); +void InitBarmaid(); +void InitBoy(); +void InitHealer(); +void InitTeller(); +void InitDrunk(); +void InitCows(); +void InitTowners(); +void FreeTownerGFX(); +void TownCtrlMsg(int i); +void TownBlackSmith(); +void TownBarOwner(); +void TownDead(); +void TownHealer(); +void TownStory(); +void TownDrunk(); +void TownBoy(); +void TownWitch(); +void TownBarMaid(); +void TownCow(); +void ProcessTowners(); +ItemStruct *PlrHasItem(int pnum, int item, int &i); +void TownerTalk(int first, int t); +void TalkToTowner(int p, int t); +void CowSFX(int pnum); + +/* data */ + +extern char AnimOrder[6][148]; +extern int TownCowX[3]; +extern int TownCowY[3]; +extern int TownCowDir[3]; +extern int cowoffx[8]; +extern int cowoffy[8]; +extern int Qtalklist[11][16]; +extern int CowPlaying; + +#endif /* __TOWNERS_H__ */ diff --git a/2020_03_31/Source/track.cpp b/2020_03_31/Source/track.cpp new file mode 100644 index 00000000..24d740c7 --- /dev/null +++ b/2020_03_31/Source/track.cpp @@ -0,0 +1,55 @@ +#include "diablo.h" +#include "../3rdParty/Storm/Source/storm.h" + +BOOL sgbIsScrolling; // weak +int sgdwLastWalk; // weak +_bool sgbIsWalking; // weak + +void track_process() +{ + int v0; // eax + DWORD v1; // eax + + if ( sgbIsWalking ) + { + if ( cursmx >= 0 && cursmx < 111 && cursmy >= 0 && cursmy < 111 ) + { + v0 = myplr; + if ( (plr[myplr]._pVar8 > 6 || plr[v0]._pmode == PM_STAND) + && (cursmx != plr[v0]._ptargx || cursmy != plr[v0]._ptargy) ) + { + v1 = GetTickCount(); + if ( v1 - sgdwLastWalk >= 300 ) + { + sgdwLastWalk = v1; + NetSendCmdLoc(1u, CMD_WALKXY, cursmx, cursmy); + if ( !sgbIsScrolling ) + sgbIsScrolling = 1; + } + } + } + } +} + +void track_repeat_walk(BOOL rep) +{ + if ( sgbIsWalking != rep ) + { + sgbIsWalking = rep; + if ( rep ) + { + sgbIsScrolling = 0; + sgdwLastWalk = GetTickCount() - 50; + NetSendCmdLoc(1u, CMD_WALKXY, cursmx, cursmy); + } + else if ( sgbIsScrolling ) + { + sgbIsScrolling = 0; + } + } +} + +BOOL track_isscrolling() +{ + return sgbIsScrolling; +} diff --git a/2020_03_31/Source/track.h b/2020_03_31/Source/track.h new file mode 100644 index 00000000..96901d05 --- /dev/null +++ b/2020_03_31/Source/track.h @@ -0,0 +1,13 @@ +//HEADER_GOES_HERE +#ifndef __TRACK_H__ +#define __TRACK_H__ + +extern BOOL sgbIsScrolling; // weak +extern int sgdwLastWalk; // weak +extern _bool sgbIsWalking; // weak + +void track_process(); +void track_repeat_walk(BOOL rep); +BOOL track_isscrolling(); + +#endif /* __TRACK_H__ */ diff --git a/2020_03_31/Source/trigs.cpp b/2020_03_31/Source/trigs.cpp new file mode 100644 index 00000000..f4782ce2 --- /dev/null +++ b/2020_03_31/Source/trigs.cpp @@ -0,0 +1,699 @@ +#include "diablo.h" + +BOOL townwarps[3]; +BOOL trigflag; +int numtrigs; +TriggerStruct trigs[MAXTRIGGERS]; +int TWarpFrom; // weak + +int TownDownList[11] = { 716, 715, 719, 720, 721, 723, 724, 725, 726, 727, -1 }; +int TownWarp1List[13] = { 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1181, 1183, 1185, -1 }; +int L1UpList[12] = { 127, 129, 130, 131, 132, 133, 135, 137, 138, 139, 140, -1 }; +int L1DownList[10] = { 106, 107, 108, 109, 110, 112, 114, 115, 118, -1 }; +int L2UpList[3] = { 266, 267, -1 }; +int L2DownList[5] = { 269, 270, 271, 272, -1 }; +int L2TWarpUpList[3] = { 558, 559, -1 }; +int L3UpList[15] = { 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, -1 }; +int L3DownList[9] = { 162, 163, 164, 165, 166, 167, 168, 169, -1 }; +int L3TWarpUpList[14] = { 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, -1 }; +int L4UpList[4] = { 82, 83, 90, -1 }; +int L4DownList[6] = { 120, 130, 131, 132, 133, -1 }; +int L4TWarpUpList[4] = { 421, 422, 429, -1 }; +int L4PentaList[33] = { 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, -1 }; + +void InitNoTriggers() +{ + numtrigs = 0; + trigflag = FALSE; +} + +void InitTownTriggers() +{ + int i; + + trigs[0]._tx = 25; + trigs[0]._ty = 29; + trigs[0]._tmsg = WM_DIABNEXTLVL; + + numtrigs = 1; + + if(gbMaxPlayers == 4) { + for(i = 0; i < 3; i++) { + townwarps[i] = TRUE; + } + trigs[1]._tx = 49; + trigs[1]._ty = 21; + trigs[1]._tmsg = WM_DIABTOWNWARP; + trigs[1]._tlvl = 5; + trigs[2]._tx = 17; + trigs[2]._ty = 69; + trigs[2]._tmsg = WM_DIABTOWNWARP; + trigs[2]._tlvl = 9; + trigs[3]._tx = 41; + trigs[3]._ty = 80; + trigs[3]._tmsg = WM_DIABTOWNWARP; + trigs[3]._tlvl = 13; + numtrigs = 4; + } else { + for(i = 0; i < 3; i++) { + townwarps[i] = FALSE; + } + if(plr[myplr].pTownWarps & 1) { + trigs[1]._tx = 49; + trigs[1]._ty = 21; + trigs[1]._tmsg = WM_DIABTOWNWARP; + trigs[1]._tlvl = 5; + numtrigs = 2; + townwarps[0] = TRUE; + } + if(plr[myplr].pTownWarps & 2) { + townwarps[1] = TRUE; + trigs[numtrigs]._tx = 17; + trigs[numtrigs]._ty = 69; + trigs[numtrigs]._tmsg = WM_DIABTOWNWARP; + trigs[numtrigs]._tlvl = 9; + numtrigs++; + } + if(plr[myplr].pTownWarps & 4) { + townwarps[2] = TRUE; + trigs[numtrigs]._tx = 41; + trigs[numtrigs]._ty = 80; + trigs[numtrigs]._tmsg = WM_DIABTOWNWARP; + trigs[numtrigs]._tlvl = 13; + numtrigs++; + } + } + + trigflag = FALSE; +} + +void InitL1Triggers() +{ + int i, j; + + numtrigs = 0; + + for(j = 0; j < MAXDUNY; j++) { + for(i = 0; i < MAXDUNX; i++) { + if(dPiece[i][j] == 129) { + trigs[numtrigs]._tx = i; + trigs[numtrigs]._ty = j; + trigs[numtrigs]._tmsg = WM_DIABPREVLVL; + numtrigs++; + } + if(dPiece[i][j] == 115) { + trigs[numtrigs]._tx = i; + trigs[numtrigs]._ty = j; + trigs[numtrigs]._tmsg = WM_DIABNEXTLVL; + numtrigs++; + } + } + } + + trigflag = FALSE; +} + +void InitL2Triggers() +{ + int i, j; + + numtrigs = 0; + + for(j = 0; j < MAXDUNY; j++) { + for(i = 0; i < MAXDUNX; i++) { + if(dPiece[i][j] == 267 && (i != quests[Q_SCHAMB]._qtx || j != quests[Q_SCHAMB]._qty)) { + trigs[numtrigs]._tx = i; + trigs[numtrigs]._ty = j; + trigs[numtrigs]._tmsg = WM_DIABPREVLVL; + numtrigs++; + } + if(dPiece[i][j] == 559) { + trigs[numtrigs]._tx = i; + trigs[numtrigs]._ty = j; + trigs[numtrigs]._tmsg = WM_DIABTWARPUP; + trigs[numtrigs]._tlvl = 0; + numtrigs++; + } + if(dPiece[i][j] == 271) { + trigs[numtrigs]._tx = i; + trigs[numtrigs]._ty = j; + trigs[numtrigs]._tmsg = WM_DIABNEXTLVL; + numtrigs++; + } + } + } + + trigflag = FALSE; +} + +void InitL3Triggers() +{ + int i, j; + + numtrigs = 0; + + for(j = 0; j < MAXDUNY; j++) { + for(i = 0; i < MAXDUNX; i++) { + if(dPiece[i][j] == 171) { + trigs[numtrigs]._tx = i; + trigs[numtrigs]._ty = j; + trigs[numtrigs]._tmsg = WM_DIABPREVLVL; + numtrigs++; + } + if(dPiece[i][j] == 168) { + trigs[numtrigs]._tx = i; + trigs[numtrigs]._ty = j; + trigs[numtrigs]._tmsg = WM_DIABNEXTLVL; + numtrigs++; + } + if(dPiece[i][j] == 549) { + trigs[numtrigs]._tx = i; + trigs[numtrigs]._ty = j; + trigs[numtrigs]._tmsg = WM_DIABTWARPUP; + numtrigs++; + } + } + } + + trigflag = FALSE; +} + +void InitL4Triggers() +{ + int i, j; + + numtrigs = 0; + + for(j = 0; j < MAXDUNY; j++) { + for(i = 0; i < MAXDUNX; i++) { + if(dPiece[i][j] == 83) { + trigs[numtrigs]._tx = i; + trigs[numtrigs]._ty = j; + trigs[numtrigs]._tmsg = WM_DIABPREVLVL; + numtrigs++; + } + if(dPiece[i][j] == 422) { + trigs[numtrigs]._tx = i; + trigs[numtrigs]._ty = j; + trigs[numtrigs]._tmsg = WM_DIABTWARPUP; + trigs[numtrigs]._tlvl = 0; + numtrigs++; + } + if(dPiece[i][j] == 120) { + trigs[numtrigs]._tx = i; + trigs[numtrigs]._ty = j; + trigs[numtrigs]._tmsg = WM_DIABNEXTLVL; + numtrigs++; + } + } + } + for(j = 0; j < MAXDUNY; j++) { + for(i = 0; i < MAXDUNX; i++) { + if(dPiece[i][j] == 370 && quests[Q_BETRAYER]._qactive == 3) { + trigs[numtrigs]._tx = i; + trigs[numtrigs]._ty = j; + trigs[numtrigs]._tmsg = WM_DIABNEXTLVL; + numtrigs++; + } + } + } + + trigflag = FALSE; +} + +void InitSKingTriggers() +{ + numtrigs = 1; + trigs[0]._tx = 82; + trigs[0]._ty = 42; + trigs[0]._tmsg = WM_DIABRTNLVL; + trigflag = FALSE; +} + +void InitSChambTriggers() +{ + numtrigs = 1; + trigs[0]._tx = 70; + trigs[0]._ty = 39; + trigs[0]._tmsg = WM_DIABRTNLVL; + trigflag = FALSE; +} + +void InitPWaterTriggers() +{ + numtrigs = 1; + trigs[0]._tx = 30; + trigs[0]._ty = 83; + trigs[0]._tmsg = WM_DIABRTNLVL; + trigflag = FALSE; +} + +void InitVPTriggers() +{ + numtrigs = 1; + trigs[0]._tx = 35; + trigs[0]._ty = 32; + trigs[0]._tmsg = WM_DIABRTNLVL; + trigflag = FALSE; +} + +BOOL ForceTownTrig() +{ + int i; + + for(i = 0; TownDownList[i] != -1; i++) { + if(dPiece[cursmx][cursmy] == TownDownList[i]) { + strcpy(infostr, "Down to dungeon"); + cursmx = 25; + cursmy = 29; + return TRUE; + } + } + if(townwarps[0]) { + for(i = 0; TownWarp1List[i] != -1; i++) { + if(dPiece[cursmx][cursmy] == TownWarp1List[i]) { + strcpy(infostr, "Down to catacombs"); + cursmx = 49; + cursmy = 21; + return TRUE; + } + } + } + if(townwarps[1]) { + for(i = 1199; i <= 1220; i++) { + if(dPiece[cursmx][cursmy] == i) { + strcpy(infostr, "Down to caves"); + cursmx = 17; + cursmy = 69; + return TRUE; + } + } + } + if(townwarps[2]) { + for(i = 1240; i <= 1255; i++) { + if(dPiece[cursmx][cursmy] == i) { + strcpy(infostr, "Down to hell"); + cursmx = 41; + cursmy = 80; + return TRUE; + } + } + } + + return FALSE; +} + +BOOL ForceL1Trig() +{ + int i, j; + + for(i = 0; L1UpList[i] != -1; i++) { + if(dPiece[cursmx][cursmy] == L1UpList[i]) { + if(currlevel > 1) { + sprintf(infostr, "Up to level %i", currlevel - 1); + } else { + strcpy(infostr, "Up to town"); + } + for(j = 0; j < numtrigs; j++) { + if(trigs[j]._tmsg == WM_DIABPREVLVL) { + cursmx = trigs[j]._tx; + cursmy = trigs[j]._ty; + return TRUE; + } + } + } + } + for(i = 0; L1DownList[i] != -1; i++) { + if(dPiece[cursmx][cursmy] == L1DownList[i]) { + sprintf(infostr, "Down to level %i", currlevel + 1); + for(j = 0; j < numtrigs; j++) { + if(trigs[j]._tmsg == WM_DIABNEXTLVL) { + cursmx = trigs[j]._tx; + cursmy = trigs[j]._ty; + return TRUE; + } + } + } + } + + return FALSE; +} + +BOOL ForceL2Trig() +{ + int i, j, dx, dy; + + for(i = 0; L2UpList[i] != -1; i++) { + if(dPiece[cursmx][cursmy] == L2UpList[i]) { + for(j = 0; j < numtrigs; j++) { + if(trigs[j]._tmsg == WM_DIABPREVLVL) { + dx = abs(trigs[j]._tx - cursmx); + dy = abs(trigs[j]._ty - cursmy); + if(dx < 4 && dy < 4) { + sprintf(infostr, "Up to level %i", currlevel - 1); + cursmx = trigs[j]._tx; + cursmy = trigs[j]._ty; + return TRUE; + } + } + } + } + } + for(i = 0; L2DownList[i] != -1; i++) { + if(dPiece[cursmx][cursmy] == L2DownList[i]) { + sprintf(infostr, "Down to level %i", currlevel + 1); + for(j = 0; j < numtrigs; j++) { + if(trigs[j]._tmsg == WM_DIABNEXTLVL) { + cursmx = trigs[j]._tx; + cursmy = trigs[j]._ty; + return TRUE; + } + } + } + } + if(currlevel == 5) { + for(i = 0; L2TWarpUpList[i] != -1; i++) { + if(dPiece[cursmx][cursmy] == L2TWarpUpList[i]) { + for(j = 0; j < numtrigs; j++) { + if(trigs[j]._tmsg == WM_DIABTWARPUP) { + dx = abs(trigs[j]._tx - cursmx); + dy = abs(trigs[j]._ty - cursmy); + if(dx < 4 && dy < 4) { + strcpy(infostr, "Up to town"); + cursmx = trigs[j]._tx; + cursmy = trigs[j]._ty; + return TRUE; + } + } + } + } + } + } + + return FALSE; +} + +BOOL ForceL3Trig() +{ + int i, j, dx, dy; + + for(i = 0; L3UpList[i] != -1; i++) { + if(dPiece[cursmx][cursmy] == L3UpList[i]) { + sprintf(infostr, "Up to level %i", currlevel - 1); + for(j = 0; j < numtrigs; j++) { + if(trigs[j]._tmsg == WM_DIABPREVLVL) { + cursmx = trigs[j]._tx; + cursmy = trigs[j]._ty; + return TRUE; + } + } + } + } + for(i = 0; L3DownList[i] != -1; i++) { + if(dPiece[cursmx][cursmy] == L3DownList[i] + || dPiece[cursmx + 1][cursmy] == L3DownList[i] + || dPiece[cursmx + 2][cursmy] == L3DownList[i]) { + sprintf(infostr, "Down to level %i", currlevel + 1); + for(j = 0; j < numtrigs; j++) { + if(trigs[j]._tmsg == WM_DIABNEXTLVL) { + cursmx = trigs[j]._tx; + cursmy = trigs[j]._ty; + return TRUE; + } + } + } + } + if(currlevel == 9) { + for(i = 0; L3TWarpUpList[i] != -1; i++) { + if(dPiece[cursmx][cursmy] == L3TWarpUpList[i]) { + for(j = 0; j < numtrigs; j++) { + if(trigs[j]._tmsg == WM_DIABTWARPUP) { + dx = abs(trigs[j]._tx - cursmx); + dy = abs(trigs[j]._ty - cursmy); + if(dx < 4 && dy < 4) { + strcpy(infostr, "Up to town"); + cursmx = trigs[j]._tx; + cursmy = trigs[j]._ty; + return TRUE; + } + } + } + } + } + } + + return FALSE; +} + +BOOL ForceL4Trig() +{ + int i, j, dx, dy; + + for(i = 0; L4UpList[i] != -1; i++) { + if(dPiece[cursmx][cursmy] == L4UpList[i]) { + sprintf(infostr, "Up to level %i", currlevel - 1); + for(j = 0; j < numtrigs; j++) { + if(trigs[j]._tmsg == WM_DIABPREVLVL) { + cursmx = trigs[j]._tx; + cursmy = trigs[j]._ty; + return TRUE; + } + } + } + } + for(i = 0; L4DownList[i] != -1; i++) { + if(dPiece[cursmx][cursmy] == L4DownList[i]) { + sprintf(infostr, "Down to level %i", currlevel + 1); + for(j = 0; j < numtrigs; j++) { + if(trigs[j]._tmsg == WM_DIABNEXTLVL) { + cursmx = trigs[j]._tx; + cursmy = trigs[j]._ty; + return TRUE; + } + } + } + } + if(currlevel == 13) { + for(i = 0; L4TWarpUpList[i] != -1; i++) { + if(dPiece[cursmx][cursmy] == L4TWarpUpList[i]) { + for(j = 0; j < numtrigs; j++) { + if(trigs[j]._tmsg == WM_DIABTWARPUP) { + dx = abs(trigs[j]._tx - cursmx); + dy = abs(trigs[j]._ty - cursmy); + if(dx < 4 && dy < 4) { + strcpy(infostr, "Up to town"); + cursmx = trigs[j]._tx; + cursmy = trigs[j]._ty; + return TRUE; + } + } + } + } + } + } + if(currlevel == 15) { + for(i = 0; L4PentaList[i] != -1; i++) { + if(dPiece[cursmx][cursmy] == L4PentaList[i]) { + strcpy(infostr, "Down to Diablo"); + for(j = 0; j < numtrigs; j++) { + if(trigs[j]._tmsg == WM_DIABNEXTLVL) { + cursmx = trigs[j]._tx; + cursmy = trigs[j]._ty; + return TRUE; + } + } + } + } + } + + return FALSE; +} + +void Freeupstairs() +{ + int j, tx, ty, xx, yy; + + for(j = 0; j < numtrigs; j++) { + tx = trigs[j]._tx; + ty = trigs[j]._ty; + for(yy = -2; yy < 3; yy++) { + for(xx = -2; xx < 3; xx++) { + dFlags[xx + tx][yy + ty] |= 8; + } + } + } +} + +BOOL ForceSKingTrig() +{ + int i; + + for(i = 0; L1UpList[i] != -1; i++) { + if(dPiece[cursmx][cursmy] == L1UpList[i]) { + sprintf(infostr, "Back to Level %i", quests[Q_SKELKING]._qlevel); + cursmx = trigs[0]._tx; + cursmy = trigs[0]._ty; + return TRUE; + } + } + + return FALSE; +} + +BOOL ForceSChambTrig() +{ + int i; + + for(i = 0; L2DownList[i] != -1; i++) { + if(dPiece[cursmx][cursmy] == L2DownList[i]) { + sprintf(infostr, "Back to Level %i", quests[Q_SCHAMB]._qlevel); + cursmx = trigs[0]._tx; + cursmy = trigs[0]._ty; + return TRUE; + } + } + + return FALSE; +} + +BOOL ForcePWaterTrig() +{ + int i; + + for(i = 0; L3DownList[i] != -1; i++) { + if(dPiece[cursmx][cursmy] == L3DownList[i]) { + sprintf(infostr, "Back to Level %i", quests[Q_PWATER]._qlevel); + cursmx = trigs[0]._tx; + cursmy = trigs[0]._ty; + return TRUE; + } + } + + return FALSE; +} + +void CheckTrigForce() +{ + trigflag = FALSE; + + if(MouseY > 352 - 1) { + return; + } + + if(!setlevel) { + switch(leveltype) { + case DTYPE_TOWN: + trigflag = ForceTownTrig(); + break; + case DTYPE_CATHEDRAL: + trigflag = ForceL1Trig(); + break; + case DTYPE_CATACOMBS: + trigflag = ForceL2Trig(); + break; + case DTYPE_CAVES: + trigflag = ForceL3Trig(); + break; + case DTYPE_HELL: + trigflag = ForceL4Trig(); + break; + } + if(leveltype != DTYPE_TOWN && !trigflag) { + trigflag = ForceQuests(); + } + } else { + switch(setlvlnum) { + case SL_SKELKING: + trigflag = ForceSKingTrig(); + break; + case SL_BONECHAMB: + trigflag = ForceSChambTrig(); + break; + case SL_POISONWATER: + trigflag = ForcePWaterTrig(); + break; + } + } + + if(trigflag) { + ClearPanel(); + } +} + +void CheckTriggers() +{ + int i, dx, dy; + char m; + BOOL abortflag; + + if(plr[myplr]._pmode != PM_STAND) { + return; + } + + for(i = 0; i < numtrigs; i++) { + if(plr[myplr].WorldX != trigs[i]._tx || plr[myplr].WorldY != trigs[i]._ty) { + continue; + } + switch(trigs[i]._tmsg) { + case WM_DIABNEXTLVL: + if(pcurs >= CURSOR_FIRSTITEM && DropItemBeforeTrig()) { + return; + } + StartNewLvl(myplr, trigs[i]._tmsg, currlevel + 1); + break; + case WM_DIABPREVLVL: + if(pcurs >= CURSOR_FIRSTITEM && DropItemBeforeTrig()) { + return; + } + StartNewLvl(myplr, trigs[i]._tmsg, currlevel - 1); + break; + case WM_DIABTOWNWARP: + if(gbMaxPlayers != 1) { + abortflag = FALSE; + if(trigs[i]._tlvl == 5 && plr[myplr]._pLevel < 8) { + abortflag = TRUE; + dx = plr[myplr].WorldX; + dy = plr[myplr].WorldY + 1; + m = 40; + } + if(trigs[i]._tlvl == 9 && plr[myplr]._pLevel < 13) { + abortflag = TRUE; + dx = plr[myplr].WorldX + 1; + dy = plr[myplr].WorldY; + m = 41; + } + if(trigs[i]._tlvl == 13 && plr[myplr]._pLevel < 17) { + abortflag = TRUE; + dx = plr[myplr].WorldX; + dy = plr[myplr].WorldY + 1; + m = 42; + } + if(abortflag) { + if(plr[myplr]._pClass == PC_WARRIOR) { + PlaySFX(PS_WARR43); + } else if(plr[myplr]._pClass == PC_ROGUE) { + PlaySFX(PS_ROGUE43); + } else if(plr[myplr]._pClass == PC_SORCERER) { + PlaySFX(PS_MAGE43); + } + InitDiabloMsg(m); + NetSendCmdLoc(TRUE, CMD_WALKXY, dx, dy); + return; + } + } + StartNewLvl(myplr, trigs[i]._tmsg, trigs[i]._tlvl); + break; + case WM_DIABTWARPUP: + TWarpFrom = currlevel; + StartNewLvl(myplr, trigs[i]._tmsg, 0); + break; + case WM_DIABRTNLVL: + /// ASSERT: assert(gbMaxPlayers == 1); + StartNewLvl(myplr, trigs[i]._tmsg, ReturnLvl); + break; + default: + app_fatal("Unknown trigger msg"); + break; + } + } +} diff --git a/2020_03_31/Source/trigs.h b/2020_03_31/Source/trigs.h new file mode 100644 index 00000000..80d7ddd8 --- /dev/null +++ b/2020_03_31/Source/trigs.h @@ -0,0 +1,50 @@ +//HEADER_GOES_HERE +#ifndef __TRIGS_H__ +#define __TRIGS_H__ + +extern BOOL townwarps[3]; +extern BOOL trigflag; +extern int numtrigs; +extern TriggerStruct trigs[MAXTRIGGERS]; +extern int TWarpFrom; // weak + +void InitNoTriggers(); +void InitTownTriggers(); +void InitL1Triggers(); +void InitL2Triggers(); +void InitL3Triggers(); +void InitL4Triggers(); +void InitSKingTriggers(); +void InitSChambTriggers(); +void InitPWaterTriggers(); +void InitVPTriggers(); +BOOL ForceTownTrig(); +BOOL ForceL1Trig(); +BOOL ForceL2Trig(); +BOOL ForceL3Trig(); +BOOL ForceL4Trig(); +void Freeupstairs(); +BOOL ForceSKingTrig(); +BOOL ForceSChambTrig(); +BOOL ForcePWaterTrig(); +void CheckTrigForce(); +void CheckTriggers(); + +/* rdata */ + +extern int TownDownList[11]; +extern int TownWarp1List[13]; +extern int L1UpList[12]; +extern int L1DownList[10]; +extern int L2UpList[3]; +extern int L2DownList[5]; +extern int L2TWarpUpList[3]; +extern int L3UpList[15]; +extern int L3DownList[9]; +extern int L3TWarpUpList[14]; +extern int L4UpList[4]; +extern int L4DownList[6]; +extern int L4TWarpUpList[4]; +extern int L4PentaList[33]; + +#endif /* __TRIGS_H__ */ diff --git a/2020_03_31/Source/wave.cpp b/2020_03_31/Source/wave.cpp new file mode 100644 index 00000000..a90e0c8f --- /dev/null +++ b/2020_03_31/Source/wave.cpp @@ -0,0 +1,299 @@ +#include "diablo.h" +#include "../3rdParty/Storm/Source/storm.h" + +_bool WCloseFile(void *file) +{ + return SFileCloseFile(file); +} + +int WGetFileSize(HANDLE hsFile, unsigned long *a2) +{ + unsigned long *v2; // edi + HANDLE i; // esi + int result; // eax + int a2a; // [esp+8h] [ebp-4h] + + a2a = 0; + v2 = a2; + for ( i = hsFile; ; WGetFileArchive(i, &a2a, 0) ) + { + result = SFileGetFileSize(i, v2); + if ( result ) + break; + } + return result; +} + +void WGetFileArchive(HANDLE hsFile, int *a2, char *dwInitParam) +{ + int *v3; // esi + HANDLE v4; // edi + //int v5; // eax + //int v6; // eax + HANDLE archive; // [esp+8h] [ebp-4h] + + v3 = a2; + v4 = hsFile; + if ( (unsigned int)*a2 >= 5 ) + FileErrDlg(dwInitParam); + if ( v4 && SFileGetFileArchive(v4, &archive) && archive != diabdat_mpq ) + { + Sleep(0x14u); + ++*v3; + } + else + { + //_LOBYTE(v6) = InsertCDDlg(); + if ( !InsertCDDlg() ) + FileErrDlg(dwInitParam); + } +} + +int WOpenFile(char *dwInitParam, HANDLE *phsFile, int a3) +{ + HANDLE *v3; // edi + char *i; // esi +// int v5; // eax + int a2a; // [esp+8h] [ebp-4h] + + a2a = 0; + v3 = phsFile; + for ( i = dwInitParam; ; WGetFileArchive(0, &a2a, i) ) + { + //_LOBYTE(v5) = SFileOpenFile(i, v3); + if ( SFileOpenFile(i, v3) ) + return 1; + if ( a3 && SErrGetLastError() == 2 ) + break; + } + return 0; +} + +void WReadFile(HANDLE hsFile, char *buf, int a3) +{ + char *v3; // ebx + HANDLE v4; // edi + int v5; // eax + int nread; // [esp+Ch] [ebp-Ch] + int offset; // [esp+10h] [ebp-8h] + int a2a; // [esp+14h] [ebp-4h] + + v3 = buf; + v4 = hsFile; + a2a = 0; + for ( offset = WSetFilePointer(hsFile, 0, 0, 1); ; WSetFilePointer(v4, offset, 0, 0) ) + { + v5 = SFileReadFile(v4, v3, a3, (unsigned long *)&nread, 0); + if ( v5 ) + break; + WGetFileArchive(v4, &a2a, 0); + } +} + +int WSetFilePointer(HANDLE file1, int offset, HANDLE file2, int whence) +{ + int v4; // edi + HANDLE i; // esi + int result; // eax + int a2; // [esp+8h] [ebp-4h] + + a2 = 0; + v4 = offset; + for ( i = file1; ; WGetFileArchive(i, &a2, 0) ) + { + result = SFileSetFilePointer(i, v4, file2, whence); + if ( result != -1 ) + break; + } + return result; +} + +int LoadWaveFormat(HANDLE hsFile, WAVEFORMATEX *pwfx) +{ + WAVEFORMATEX *v2; // esi + int v3; // esi + MEMFILE wave_file; // [esp+4h] [ebp-1Ch] + + v2 = pwfx; + AllocateMemFile(hsFile, &wave_file, 0); + v3 = ReadWaveFile(&wave_file, v2, 0); + FreeMemFile(&wave_file); + return v3; +} + +void *AllocateMemFile(HANDLE hsFile, MEMFILE *pMemFile, unsigned int dwPos) +{ + MEMFILE *v3; // esi + HANDLE v4; // edi + unsigned int v5; // eax + unsigned int v6; // ecx + void *result; // eax + + v3 = pMemFile; + v4 = hsFile; + memset(pMemFile, 0, 0x1Cu); + v5 = WGetFileSize(v4, 0); + v6 = 4096; + v3->end = v5; + if ( dwPos > 0x1000 ) + v6 = dwPos; + v3->buf_len = v6; + if ( v6 >= v5 ) + v6 = v5; + v3->buf_len = v6; + result = DiabloAllocPtr(v6); + v3->file = (int)v4; + v3->buf = (char *)result; + return result; +} + +void FreeMemFile(MEMFILE *pMemFile) +{ + MEMFILE *v1; // eax + char *v2; // ecx + + v1 = pMemFile; + v2 = pMemFile->buf; + v1->buf = 0; + mem_free_dbg(v2); +} + +int ReadWaveFile(MEMFILE *pMemFile, WAVEFORMATEX *pwfx, CKINFO *a3) +{ + WAVEFORMATEX *v3; // esi + MEMFILE *v4; // edi + WORD v5; // ax + int result; // eax + int a2a[5]; // [esp+8h] [ebp-2Ch] + PCMWAVEFORMAT v8; // [esp+1Ch] [ebp-18h] + CKINFO v9; // [esp+2Ch] [ebp-8h] + + v3 = pwfx; + v4 = pMemFile; + if ( !ReadMemFile(pMemFile, a2a, 0xCu) + || a2a[0] != 'FFIR' + || a2a[2] != 'EVAW' + || !ReadWaveSection(v4, ' tmf', &v9) + || v9.dwSize < 0x10u + || !ReadMemFile(v4, &v8, 0x10u) + || SeekMemFile(v4, v9.dwSize - 16, FILE_CURRENT) == -1 ) + { + return 0; + } + v5 = v8.wf.wFormatTag; + v3->cbSize = 0; + v3->wFormatTag = v5; + v3->nChannels = v8.wf.nChannels; + v3->nSamplesPerSec = v8.wf.nSamplesPerSec; + v3->nAvgBytesPerSec = v8.wf.nAvgBytesPerSec; + v3->nBlockAlign = v8.wf.nBlockAlign; + v3->wBitsPerSample = v8.wBitsPerSample; + if ( a3 ) + result = ReadWaveSection(v4, 'atad', a3); + else + result = 1; + return result; +} + +int ReadMemFile(MEMFILE *pMemFile, void *lpBuf, size_t a3) +{ + size_t v3; // ebx + void *v4; // ebp + MEMFILE *v5; // esi + size_t v6; // edi + + v3 = a3; + v4 = lpBuf; + v5 = pMemFile; + if ( !a3 ) + return 1; + while ( 1 ) + { + if ( !v5->bytes_to_read ) + FillMemFile(v5); + v6 = v5->bytes_to_read; + if ( v3 < v6 ) + v6 = v3; + if ( !v6 ) + break; + memcpy(v4, &v5->buf[v5->dist], v6); + v5->offset += v6; + v5->dist += v6; + v5->bytes_to_read -= v6; + v3 -= v6; + if ( !v3 ) + return 1; + } + return 0; +} + +void FillMemFile(MEMFILE *pMemFile) +{ + MEMFILE *v1; // esi + unsigned int v2; // edi + + v1 = pMemFile; + WSetFilePointer((HANDLE)pMemFile->file, pMemFile->offset, 0, 0); + v2 = v1->end - v1->offset; + if ( v1->buf_len < v2 ) + v2 = v1->buf_len; + if ( v2 ) + WReadFile((HANDLE)v1->file, v1->buf, v2); + v1->dist = 0; + v1->bytes_to_read = v2; +} + +int SeekMemFile(MEMFILE *pMemFile, unsigned int lDist, int dwMethod) +{ + unsigned int v3; // eax + + v3 = pMemFile->bytes_to_read; + if ( lDist >= v3 ) + { + pMemFile->bytes_to_read = 0; + } + else + { + pMemFile->dist += lDist; + pMemFile->bytes_to_read = v3 - lDist; + } + pMemFile->offset += lDist; + return pMemFile->offset; +} + +int ReadWaveSection(MEMFILE *pMemFile, int a2, CKINFO *a3) +{ + int v3; // esi + MEMFILE *v4; // edi + int v6; // eax + int a2a[2]; // [esp+8h] [ebp-8h] + + v3 = a2; + v4 = pMemFile; + while ( 1 ) + { + if ( !ReadMemFile(v4, a2a, 8u) ) + return 0; + if ( a2a[0] == v3 ) + break; + if ( SeekMemFile(v4, a2a[1], FILE_CURRENT) == -1 ) + return 0; + } + a3->dwSize = a2a[1]; + v6 = SeekMemFile(v4, 0, FILE_CURRENT); + a3->dwOffset = v6; + return v6 != -1; +} + +void *LoadWaveFile(HANDLE hsFile, WAVEFORMATEX *pwfx, CKINFO *a3) +{ + WAVEFORMATEX *v3; // esi + MEMFILE wave_file; // [esp+4h] [ebp-1Ch] + + v3 = pwfx; + AllocateMemFile(hsFile, &wave_file, 0xFFFFFFFF); + if ( ReadWaveFile(&wave_file, v3, a3) ) + return wave_file.buf; + FreeMemFile(&wave_file); + return 0; +} diff --git a/2020_03_31/Source/wave.h b/2020_03_31/Source/wave.h new file mode 100644 index 00000000..dca0915f --- /dev/null +++ b/2020_03_31/Source/wave.h @@ -0,0 +1,24 @@ +//HEADER_GOES_HERE +#ifndef __WAVE_H__ +#define __WAVE_H__ + +//int dword_6ABB9C; // weak + +_bool WCloseFile(void *file); +int WGetFileSize(HANDLE hsFile, unsigned long *a2); +void WGetFileArchive(HANDLE hsFile, int *a2, char *dwInitParam); +int WOpenFile(char *dwInitParam, HANDLE *phsFile, int a3); +void WReadFile(HANDLE hsFile, char *buf, int a3); +int WSetFilePointer(HANDLE file1, int offset, HANDLE file2, int whence); +int LoadWaveFormat(HANDLE hsFile, WAVEFORMATEX *pwfx); +void *AllocateMemFile(HANDLE hsFile, MEMFILE *pMemFile, unsigned int dwPos); +void FreeMemFile(MEMFILE *pMemFile); +int ReadWaveFile(MEMFILE *pMemFile, WAVEFORMATEX *pwfx, CKINFO *a3); +int ReadMemFile(MEMFILE *pMemFile, void *lpBuf, size_t a3); +void FillMemFile(MEMFILE *pMemFile); +int SeekMemFile(MEMFILE *pMemFile, unsigned int lDist, int dwMethod); +int ReadWaveSection(MEMFILE *pMemFile, int a2, CKINFO *a3); +void *LoadWaveFile(HANDLE hsFile, WAVEFORMATEX *pwfx, CKINFO *a3); +void j_engine_mem_free(void *ptr); + +#endif /* __WAVE_H__ */ diff --git a/2020_03_31/Support/CONTRIBUTING.md b/2020_03_31/Support/CONTRIBUTING.md new file mode 100644 index 00000000..9715d0d9 --- /dev/null +++ b/2020_03_31/Support/CONTRIBUTING.md @@ -0,0 +1,140 @@ +# Contribution Guide + +This guide outlines useful resources, tools and processes for contribution to +Devilution. + +## Useful Repos + +* [diasurgical/scalpel](https://github.com/diasurgical/scalpel) - uploaded .SYM + files from each release of Diablo 1 on Playstation +* [sanctuary/notes](https://github.com/sanctuary/notes) - documented + Windows-specific Diablo code + +## Software and Utils + +* A clean installation of Diablo patched to version 1.09b (Diablo.exe) +* Download IDA (Interactive Disassembler) [Hex-Rays](https://www.hex-rays.com/products/ida/support/download_freeware.shtml) +* Download IDC script from sanctuary/notes repository: [notes.idc](http://sanctuary.github.io/notes/notes.idc) + +## How To... + +Described below are steps for using the IDA and SYM files to reverse the Diablo +source. + +### Understanding Devilution and Sanctuary Notes + +Both Devilution and the Sanctuary Notes repo have the intended aim to get as +close as possible to document the original game. Devilution is closer in the +sense that the same names have been used for functions as based on the SYM +debug info. The notes repo has tried to use consistent naming for functions, +e.g. prefix with source file name. + +See for instance [drlg_l1_load_dun](http://sanctuary.github.io/notes/#function/drlg_l1_load_dun), +which is defined in `drlg_l1.cpp`. This function has the PSX signature +`void LoadL1Dungeon__FPcii(char *sFileName, int vx, int vy)`, but is documented +in the Sanctuary Notes repo as follows for consistency: + +```cpp +/// address: 0x40AE79 +/// +/// drlg_l1_load_dun loads tile IDs, monsters and objects from the given +/// dungeon file. +/// +/// PSX ref: 0x8013CF64 +/// PSX def: void LoadL1Dungeon__FPcii(char *sFileName, int vx, int vy) +void __fastcall drlg_l1_load_dun(char *dun_path, int view_x, int view_y); +``` + +### Interactive Disassembler Usage + +* Open the `Diablo.exe` (verison 1.09b in IDA) and wait for it to finish + analysis + * Open as "Portable Executable" + * Processor type i386 (80386) +* Run the IDC script in IDA on the fresh IDB database to import names for + variables and functions, type definitions, etc. (Note: run the IDC script + **only** on new IDB databases as it removes all variable names before adding new + ones.); for more info, see [#79 (comment)](https://github.com/diasurgical/devilution/pull/79#issuecomment-400536087) +* Example: search for `drlg_l1_load_dun` + * Starting memory address `0x40AE79` + * Function name `drlg_l1_load_dun` + * Function arguments `(char *dun_path, int view_x, int view_y)` + * #TODO what else can be inferred from below? + +```asm +; drlg_l1_load_dun loads tile IDs, monsters and objects from the given +; dungeon file. +; Attributes: bp-based frame + +; void __fastcall drlg_l1_load_dun(char *dun_path, int view_x, int view_y) +drlg_l1_load_dun proc near + +var_C= dword ptr -0Ch +var_8= dword ptr -8 +var_4= dword ptr -4 +view_y= dword ptr 8 + +push ebp +mov ebp, esp +sub esp, 0Ch +push ebx +push esi +push edi +push 10h +pop eax +mov [ebp+var_C], edx +push 60h +mov dword_5D2458, eax +mov dword_5D245C, eax +pop eax +mov esi, ecx +mov dword_5CF328, eax +mov dword_5CF32C, eax +call gendung_init_transparency +xor edx, edx ; size +mov ecx, esi ; file_path +call engine_mem_load_file +mov esi, eax +xor ecx, ecx +``` + +### About the SYM + +The [diasurgical/scalpel](https://github.com/diasurgical/scalpel) repository includes a copy of a symbolic file that was +accidentally left on the Japanese release of Diablo on Playstation 1. The CD +contained debug information in a .SYM file, the format of which has been +reversed, so we can recover type information, variable names, etc, for the PSX +release. + +* Download and open [jap_05291998.out](https://raw.githubusercontent.com/diasurgical/scalpel/master/psx/symbols/jap_05291998.out) +* Example: search for `LoadL1Dungeon__FPcii` + * Starting memory address `0x8013CF64` + * Function name `LoadL1Dungeon` + * Function arguments `(*char sFilename, int vx, int, vy)` + * #TODO what else can be inferred from below? + +``` +135ea8: $8013cf64 8c Function_start + fp = 29 + fsize = 48 + retreg = 31 + mask = $80070000 + maskoffs = -4 + line = 905 + file = C:\diabpsx\SOURCE\DRLG_L1.CPP + name = LoadL1Dungeon__FPcii +135ef4: $00000010 94 Def class REGPARM type PTR CHAR size 0 name sFileName +135f0b: $00000011 94 Def class REGPARM type INT size 0 name vx +135f1b: $00000012 94 Def class REGPARM type INT size 0 name vy +135f2b: $8013cf64 90 Block_start line = 1 +135f34: $00000005 94 Def class REG type INT size 0 name i +135f43: $00000007 94 Def class REG type INT size 0 name j +135f52: $0000000b 94 Def class REG type INT size 0 name rw +135f62: $0000000c 94 Def class REG type INT size 0 name rh +135f72: $00000010 94 Def class REG type PTR UCHAR size 0 name pLevelMap +135f89: $00000008 94 Def class REG type PTR UCHAR size 0 name lm +135f99: $8013d0c4 90 Block_start line = 44 +135fa2: $8013d11c 92 Block_end line = 60 +135fab: $8013d11c 92 Block_end line = 60 +135fb4: $8013d138 8e Function_end +``` diff --git a/2020_03_31/Support/INSTALL_linux.md b/2020_03_31/Support/INSTALL_linux.md new file mode 100644 index 00000000..efbdcd68 --- /dev/null +++ b/2020_03_31/Support/INSTALL_linux.md @@ -0,0 +1,49 @@ +# Installation + +## Dependencies + +Ubuntu +```bash +sudo apt install g++-mingw-w64-i686 +``` + +Arch Linux +```bash +pacman -S mingw-w64-gcc mingw-w64-binutils +``` + +Fedora 28: +```bash +sudo dnf install mingw32-gcc-c++ wine +``` + +elementary OS: +```bash +sudo apt install mingw-w64 wine +``` + + +## Building + +```bash +git clone https://github.com/galaxyhaxz/devilution +cd devilution +cp /path/to/diablo_game_dir/diabloui.dll . +cp /path/to/diablo_game_dir/storm.dll . +make +``` + +On a 32-bit host, `$ make MINGW32=mingw32` should be used, to specify the 32-bit +toolchain. + +## Install + +```bash +cp devilution.exe /path/to/diablo_game_dir/ +``` + +## Run + +```bash +wine devilution.exe +``` diff --git a/2020_03_31/Support/INSTALL_mac.md b/2020_03_31/Support/INSTALL_mac.md new file mode 100644 index 00000000..ef2d34d2 --- /dev/null +++ b/2020_03_31/Support/INSTALL_mac.md @@ -0,0 +1,32 @@ +# Installation + +## Dependencies + +[Homebrew](https://brew.sh/) + +```bash +brew install wine +brew install mingw-w64 +``` + +## Building + +```bash +git clone https://github.com/galaxyhaxz/devilution +cd devilution +cp /path/to/diablo_game_dir/diabloui.dll . +cp /path/to/diablo_game_dir/Storm.dll . +make +``` + +## Install + +```bash +cp devilution.exe /path/to/diablo_game_dir/ +``` + +## Run + +```bash +wine devilution.exe +``` diff --git a/2020_03_31/Support/INSTALL_windows.md b/2020_03_31/Support/INSTALL_windows.md new file mode 100644 index 00000000..8b4fea96 --- /dev/null +++ b/2020_03_31/Support/INSTALL_windows.md @@ -0,0 +1,46 @@ +# Installation + +## Dependencies and Initial Environment Configuration + +* Install [MSYS2](https://www.msys2.org/) + +```bash +# Start the *MSYS2 MinGW 32-bit* terminal. + +# If this is the first time, go ahead and update all of your components, and +# follow and instructions about restarting the terminal and running the update again: +pacman -Syu + +# After everything is updated, let's download all of the components needed +# to build it and set up any dependency symlinks: +pacman -Sy git make mingw-w64-i686-gcc mingw-w64-i686-binutils + +ln -s /mingw32/i686-w64-mingw32/bin/dlltool.exe /usr/bin/i686-w64-mingw32-dlltool.exe +ln -s /mingw32/i686-w64-mingw32/bin/as.exe /usr/bin/i686-w64-mingw32-as.exe +ln -s /mingw32/bin/windres.exe /usr/bin/i686-w64-mingw32-windres.exe +``` + +## Building + +```bash +git clone https://github.com/galaxyhaxz/devilution +cd devilution +cp /path/to/diablo_game_dir/diabloui.dll . +cp /path/to/diablo_game_dir/storm.dll . + +# If you only have a single core machine or if building in parallel +# causes issues, simply run the following command: +make + +# If you want to compile faster, then use the following command (Substitute # for +# your number of processors + 1. So if you have an 8 core processor, use 9: +make -j# +``` + +## Install + +```bash +# The Devilution executable will be placed in the root of your Devilution repository. +# Simply copy this over to your Diablo installation folder: +cp devilution.exe /path/to/diablo_game_dir/ +``` \ No newline at end of file diff --git a/2020_03_31/Support/TODO.md b/2020_03_31/Support/TODO.md new file mode 100644 index 00000000..7c5fdcc8 --- /dev/null +++ b/2020_03_31/Support/TODO.md @@ -0,0 +1,21 @@ +### Comments +- `BUG_FIX` known bugs in original (vanilla) code +- `/* */` block comments are things to be fixed/checked +- `FIX_ME` bad data + +### Known Bugs +Serious bugs (crash/fault) +- TBA + +Minor bugs (noticeable but can be avoided) +- Server commands are broken and have been disabled `msgcmd.cpp` + +Code issues (incorrect code that still works) +- Critical sections should be constructors using `CCritSect` +- Some code uses macros such as `__PAIR__` or `__ROL4__`, or `__int64` +- Some functions/structures have incorrect signing (signed/unsigned BYTE) +- Function `GetLevelMTypes`, decompile and check `monster.cpp` +- Function `SetAutomapView`, decompile and check `automap.cpp` +- Function `engine_draw_automap_pixels`, decompile and check `engine.cpp` +- Double check `UseMana` references +- Double check `LOBYTE` of function `random(int, int)` diff --git a/2020_03_31/Support/compatibility_matrix.md b/2020_03_31/Support/compatibility_matrix.md new file mode 100644 index 00000000..de415c06 --- /dev/null +++ b/2020_03_31/Support/compatibility_matrix.md @@ -0,0 +1,39 @@ +# Compatibility Matrix, Compilations, Platform Statuses, Etc + +Please use UTC times for all entries. The Z ending represents UTC time. + +## Status Cheat Sheet + +[Modeled after Wine HQ's Rating System](https://wiki.winehq.org/AppDB_Rating_Definitions) + +| Rank | Description | +| --- | --- | +| Platinum | Works perfectly right after compilation either better or equal to Native Diablo Executable. | +| Gold | Works right after compilation with no crashes during gameplay but workarounds needed. | +| Silver | Works right after compilation with no crashes during gameplay but issues exist where no workarounds exist. | +| Bronze | Mostly works but there are still some problems remaining that prevent a full playthrough.| +| Trash | Game has severe problems and cannot be played. | + +## Windows + +| Date | Status | OS | Bitness | Version (OS) | Build (OS) | Compiler | Build Platform | User | Workaround | +| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | +| 2018-06-24 @ 17:05 Z| Gold | 10 | x64 | 1803 | 17134.112 | i686-w64-mingw32-gcc-7.3.0 | MSYS 2 i686 | fearedbliss | Needed to use ddraw patch. | +| 2018-06-24 @ 12:52 Z| Platinum | 7 | x64 | 6.1 | 7601 | Visual C++ 6.0 | VC++ | Sergi4UA | None | +| 2018-06-24 @ 01:00 Z| Platinum | 7 | x64 | 6.1 | 7601 | Visual C++ 5.10 | VC++ | galaxyhaxz | None | +| 2018-06-24 @ 18:00 Z| Gold | 10 | x64 | 1803 | 17134.112 | Visual Studio 2017 (Community) | VC++ | MadHed | Disable DEP in linker options | +| 2018-06-24 @ 16:00 Z| Gold | 7 | x64 | 6.1 | 7601 | Visual Studio 2017 (Community) | VC++ | StephenCWills | Disable DEP in linker options | +| 2018-06-26 @ 19:30 Z| Platinum | 7 | x64 | 6.1 | 7601 | i686-w64-mingw32-g++ (GCC) 6.4.0 | Cygwin | StephenCWills | None | +| 2018-07-05 @ 23:54 Z| Gold | 10 | x64 | 1803 | 17134.112 | Visual Studio 2017 (Community) | VC++ | fearedbliss | Disable DEP in linker options | + +## Linux + +| Date | Status | OS | Bitness | Version (OS) | Build (OS) | Compiler | Build Platform | User | Workaround | +| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | +| 2018-08-20 @ 12:05 Z| Gold | Ubuntu (WSL) | x64 | xenial | 16.04.4 LTS | i686-w64-mingw32-g++ (GCC) 5.3.1 20160211 | Mingw64-x86 | ChaosMarc | Needed to use ddraw patch. | +| 2018-08-20 @ 12:05 Z| Trash | Ubuntu (WSL) | x64 | bionic | 18.04 LTS | i686-w64-mingw32-g++ (GCC) 7.3-win32 20180312 | Mingw64-x86 | ChaosMarc | Crashes on startup (#107) | + +## Mac OS X + +| Date | Status | OS | Bitness | Version (OS) | Build (OS) | Compiler | Build Platform | User | Workaround | +| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | diff --git a/2020_03_31/Support/debug.md b/2020_03_31/Support/debug.md new file mode 100644 index 00000000..7adb0765 --- /dev/null +++ b/2020_03_31/Support/debug.md @@ -0,0 +1,54 @@ +There are debug features available through both in-game and through the command-line. These have been ported from the 12-21-96 debug build. Note that not all of them are available yet. + +Command-line parameters +- `-^` : enable god mode and debug tools +- `-$` : enable god mode with less stuff (further documenting needed) [NOT YET IMPLEMENTED] +- `-b` : enables item drop log [NOT YET IMPLEMENTED] +- `-d` : disable startup video + increased item drops [PARTIALLY IMPLEMENTED] +- `-f` : display frames per second +- `-i` : disable network timeout +- `-n` : disable startup video +- `-s` : unused +- `-v` : draw yellow debug tiles +- `-w` : enable cheats +- `-x` : disable exclusive DirectDraw access [NOT YET IMPLEMENTED] +- `-j <##>` : init trigger at level [NOT YET IMPLEMENTED] +- `-l <#> <##>` : start in level as type +- `-m <###>` : add debug monster, up to 10 allowed +- `-q <#>` : force a certain quest +- `-r <##########>` : set map seed to +- `-t <##>` : sets current quest level + +In-game hotkeys +- `?` -> enter quest text mode [NOT YET IMPLEMENTED] + - `-`/`_` -> decrease message number/speed + - `+`/`=` -> increase message number/speed + - `Enter` -> play selected message + - `Esc` -> stop quest text mode +- `Shift` -> while holding, use the mouse to scroll screen +- `F2` -> display dungeon information [NOT YET IMPLEMENTED] +- `F3` -> display number of items on the ground/cursor item +- `F4` -> display quest status information +- `0`/`)` -> cycle between regular/magic arrows +- `8`/`*` -> level up character +- `~` -> refresh vendor items (Griswold premium and Adria) +- `]` -> all spells level 10 +- `:` -> all spells preset level +- `[` -> delete all gold in inventory +- `|` -> fill inventory with gold (5000 piece piles) +- `.` -> display dungeon Y/sum [NOT YET IMPLEMENTED] +- `a` -> increase level of the last spell casted and enable `Teleport` in town +- `A` -> display "Mid" monster related +- `d` -> print debug player info +- `D` -> switch current debug player +- `e` -> display "EFlag" +- `l`/`L` -> toggle lighting in dungeon +- `m` -> print debug monster info +- `M` -> switch current debug monster +- `r`/`R` -> display game seeds +- `t`/`T` -> display player and cursor coordinates + +Multiplayer hotkeys [NOT YET IMPLEMENTED] +- `Ctrl`+`C` -> trigger breakpoint +- `Ctrl`+`P` -> print mouse clicks and frame counter for each player +- `Ctrl`+`S` -> sleep the network thread diff --git a/2020_03_31/Support/troubleshooting.md b/2020_03_31/Support/troubleshooting.md new file mode 100644 index 00000000..3231ec52 --- /dev/null +++ b/2020_03_31/Support/troubleshooting.md @@ -0,0 +1,23 @@ +# Troubleshooting + +While Devilution should produce a binary close to the original (compatible with Windows 95/NT), it may cause issues on newer systems. It has been reported to frequently crash on some setups, although for many it appears to be running flawless otherwise. Windows 7, Linux-WINE, and Windows 10 have all reported success. + +Note that newer compilers may need to be tweaked to properly produce an executable. Currently this is being worked on to provide multiple Makefiles for a variety of systems. To ensure the best results, either MinGW or Visual Studio 2003/older should be used for the time being. + +## Compilations with Different Toolchains +Compiling with different compilers (Visual C++, MinGW, Etc) will lead lead to different +results with how the executable interacts with the operating system, and may lead to either +weird crashes or different types of problems either during startup or runtime. + +For example, for fearedbliss, on his Windows 10 x64 machine where he compiled Devilution +with MSYS2/MinGW32, he was getting the following messages: + +![Screenshot 1: Windows 2000 Advisory](https://i.imgur.com/ScFLGu5.png) + +![Screenshot 2: DirectDraw Error ](https://i.imgur.com/kiWkBuk.png) + +For the first issue, it is annoying but doesn't seem to stop you from playing the game. + +The second issue simply requires you to use the DirectDraw patch (ddraw.dll). Once the +dll is placed in your Diablo directory, and all of it's dependencies are installed +(DirectX 9 Runtime, and VC++ 2010 x86 Redistributable), it will work. \ No newline at end of file diff --git a/2020_03_31/Utils/MakeText/MakeText.dsp b/2020_03_31/Utils/MakeText/MakeText.dsp new file mode 100644 index 00000000..8771634d --- /dev/null +++ b/2020_03_31/Utils/MakeText/MakeText.dsp @@ -0,0 +1,102 @@ +# Microsoft Developer Studio Project File - Name="MakeText" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=MakeText - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "MakeText.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "MakeText.mak" CFG="MakeText - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "MakeText - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "MakeText - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "MakeText - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "../Bin" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "MakeText - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "../Bin" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "MakeText - Win32 Release" +# Name "MakeText - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\maketext.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/2020_03_31/Utils/MakeText/maketext.c b/2020_03_31/Utils/MakeText/maketext.c new file mode 100644 index 00000000..c0f0f438 --- /dev/null +++ b/2020_03_31/Utils/MakeText/maketext.c @@ -0,0 +1,319 @@ +#include +#include +#include + +// 1 megabyte +#define BUFFER_SIZE_LIMIT (1 * 1024 * 1024) + +// prevent including duplicate files +#define MAX_INCLUDE_FILES 256 +char IncludedNames[MAX_INCLUDE_FILES][256]; + +unsigned char *ConvertEOL(unsigned char *p, int bufsize, int *newsize) +{ + int i; + unsigned char *p2; + + p2 = (unsigned char *)malloc(sizeof(unsigned char) * (bufsize + 1)); + *newsize = 0; + + for(i = 0; i < bufsize; i++) { + if(p[i] == '\r') { + p2[(*newsize)++] = '\n'; + if(p[i + 1] == '\n') { + i++; + } + } else { + p2[(*newsize)++] = p[i]; + } + } + p2[(*newsize)++] = '\0'; + + return p2; +} + +unsigned char *RemoveWhitespace(unsigned char *p2, int fsize) +{ + unsigned char *p, *p3, *p4; + + p = (unsigned char *)malloc(sizeof(unsigned char) * (fsize + 1)); + p3 = p; + p4 = p2; + + while(*p4 != '\0') { + while(*p4 == ' ' || *p4 == '\t' || *p4 == '\n') { + p4++; + } + while(*p4 != '\n') { + *p3++ = *p4++; + } + *p3++ = *p4++; + } + *p3++ = '\0'; + + return p; +} + +unsigned char *LoadBinaryFile(char *file, int *pdwSize) +{ + unsigned char *p; + FILE *fp; + int bufsize; + + fp = fopen(file, "rb"); + + if(fp == NULL) { + fprintf(stderr, "Can't open file %s\n", file); + exit(-1); + } + + fseek(fp, 0L, SEEK_END); + bufsize = ftell(fp); + p = (unsigned char *)malloc(sizeof(unsigned char) * (bufsize + 1)); + fseek(fp, 0L, SEEK_SET); + fread(p, sizeof(char), bufsize, fp); + fclose(fp); + + if(pdwSize != NULL) { + *pdwSize = bufsize; + } + + return p; +} + +unsigned char *LoadTextFile(char *file, int *pdwSize) +{ + unsigned char *p, *p2; + int bufsize, fsize; + + p = LoadBinaryFile(file, &bufsize); + + p2 = ConvertEOL(p, bufsize, &fsize); + free(p); + p = RemoveWhitespace(p2, fsize); + free(p2); + + if(pdwSize != NULL) { + *pdwSize = fsize; + } + + return p; +} + +/* + * TODO: make recursive so all files with includes will expand into data buffer + * - currently only the main file may call the include function + */ +unsigned char *ExpandTextFile(unsigned char *p, int *fsize) +{ + char FileName[256]; + char Include[] = "#include"; + int i, size, index; + unsigned char *p2, *p3, *p4, *pInclude; + + p2 = (unsigned char *)malloc(sizeof(unsigned char) * (BUFFER_SIZE_LIMIT + 1)); + p3 = p2; + + *fsize = 0; + index = 0; + while(*p != '\0') { + if(strncmp(p, Include, sizeof(Include) - 1) == 0) { + p += sizeof(Include) - 1; + while(*p == ' ' || *p == '\t') { + p++; + } + if(*p != '"') { + fprintf(stderr, "Invalid file name\n"); + exit(-1); + } + p++; + i = 0; + while(*p != '\n') { + FileName[i++] = *p++; + if(i >= sizeof(FileName)) { + fprintf(stderr, "File name exceeds max path\n"); + exit(-1); + } + } + p++; + if(FileName[i - 1] != '"') { + fprintf(stderr, "Invalid file name: %s\n", FileName); + exit(-1); + } + FileName[i - 1] = '\0'; + for(i = 0; IncludedNames[i][0] != '\0'; i++) { + if(strcmp(IncludedNames[i], FileName) == 0) { + fprintf(stderr, "File %s already included\n", FileName); + exit(-1); + } + } + strcpy(IncludedNames[index++], FileName); + if(index >= MAX_INCLUDE_FILES) { + fprintf(stderr, "Including too many files\n"); + exit(-1); + } + pInclude = LoadTextFile(FileName, &size); + p4 = pInclude; + while(*p4 != '\0') { + if(p4[0] == '/' && p4[1] == '/') { + p4 += 2; + while(*p4 != '\n') { + p4++; + } + p4++; + } else { + (*fsize)++; + *p3++ = *p4++; + } + } + free(pInclude); + } else if(p[0] == '/' && p[1] == '/') { + p += 2; + while(*p != '\n') { + p++; + } + p++; + } else { + while(*p != '\n') { + (*fsize)++; + *p3++ = *p++; + } + (*fsize)++; + *p3++ = *p++; + } + if(*fsize >= BUFFER_SIZE_LIMIT) { + fprintf(stderr, "Exceeded buffer size limit\n"); + exit(-1); + } + } + + (*fsize)++; + *p3++ = *p++; + + return p2; +} + +void WriteDataFile(char *file, unsigned char *p, int fsize) +{ + FILE *fp; + int i; + char Pre[] = "\t{ "; + char Suf[] = " },\r\n"; + char Sep[] = ", "; + + fp = fopen(file, "wb"); + + if(fp == NULL) { + fprintf(stderr, "Can't create file %s\n", file); + exit(-1); + } + + while(*p != '\0') { + if(*p == '[') { + p++; + while(*p != ']' && *p != '\n') { + p++; + } + if(*p != ']') { + fprintf(stderr, "Error: invalid text entry\n"); + exit(-1); + } + p++; + while(*p != '\n') { + p++; + } + p++; + fwrite(Pre, sizeof(char), sizeof(Pre) - 1, fp); + for(i = 0; i < 4; i++) { + if(*p == '[') { + fprintf(stderr, "Error: unexpected text entry\n"); + exit(-1); + } + while(*p != '\n') { + fwrite(p, sizeof(char), 1, fp); + p++; + } + p++; + if(i < 4 - 1) { + fwrite(Sep, sizeof(char), sizeof(Sep) - 1, fp); + } + } + fwrite(Suf, sizeof(char), sizeof(Suf) - 1, fp); + } else { + fprintf(stderr, "Error: invalid text entry\n"); + exit(-1); + } + } + + fclose(fp); +} + +void WriteEnumFile(char *file, unsigned char *p, int fsize) +{ + int counter; + FILE *fp; + char EnumPre[] = "enum {\r\n"; + char EnumSuf[] = "};\r\n"; + char Tab[] = "\t"; + char EFmt[] = " = %d,\r\n"; + char Format[32]; + + fp = fopen(file, "wb"); + + if(fp == NULL) { + fprintf(stderr, "Can't create file %s\n", file); + exit(-1); + } + + fwrite(EnumPre, sizeof(char), sizeof(EnumPre) - 1, fp); + + counter = 0; + while(*p != '\0') { + if(*p == '[') { + p++; + fwrite(Tab, sizeof(char), sizeof(Tab) - 1, fp); + while(*p != ']') { + fwrite(p, sizeof(char), 1, fp); + p++; + } + p++; + sprintf(Format, EFmt, counter); + counter++; + fwrite(Format, sizeof(char), strlen(Format), fp); + while(*p != '\n') { + p++; + } + p++; + } else { + while(*p != '\n') { + p++; + } + p++; + } + } + + fwrite(EnumSuf, sizeof(char), sizeof(EnumSuf) - 1, fp); + fclose(fp); +} + +int main(int argc, char *argv[]) +{ + int size, fsize; + unsigned char *p, *p2; + + if(argc != 4) { + fprintf(stderr, "Usage: maketext [txt] [cpp] [h]\n"); + return 0; + } + + p = LoadTextFile(argv[1], &size); + + p2 = ExpandTextFile(p, &fsize); + WriteDataFile(argv[2], p2, fsize); + WriteEnumFile(argv[3], p2, fsize); + + free(p); + free(p2); + + return 0; +} diff --git a/2020_03_31/Utils/MakeXL/MakeXL.dsp b/2020_03_31/Utils/MakeXL/MakeXL.dsp new file mode 100644 index 00000000..d956f644 --- /dev/null +++ b/2020_03_31/Utils/MakeXL/MakeXL.dsp @@ -0,0 +1,100 @@ +# Microsoft Developer Studio Project File - Name="MakeXL" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=MakeXL - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "MakeXL.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "MakeXL.mak" CFG="MakeXL - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "MakeXL - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "MakeXL - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "MakeXL - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "../Bin" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "MakeXL - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "../Bin" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "MakeXL - Win32 Release" +# Name "MakeXL - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\makexl.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/2020_03_31/Utils/MakeXL/makexl.c b/2020_03_31/Utils/MakeXL/makexl.c new file mode 100644 index 00000000..28d652fe --- /dev/null +++ b/2020_03_31/Utils/MakeXL/makexl.c @@ -0,0 +1,426 @@ +#include +#include +#include + +#define MAX_COLUMNS 256 + +int NumCols, NumRows; +int Columns[MAX_COLUMNS]; +int HasEnum; + +enum { + FIELD_INTEGER, + FIELD_STRING, + FIELD_ARRAY, + FIELD_POINTER, + FIELD_COMMENT +}; + +unsigned char *LoadBinaryFile(char *file, int *pdwSize) +{ + unsigned char *p, *p2; + FILE *fp; + int bufsize, i, fsize; + + fp = fopen(file, "rb"); + + if(fp == NULL) { + fprintf(stderr, "Can't open file %s\n", file); + exit(-1); + } + + fseek(fp, 0L, SEEK_END); + bufsize = ftell(fp); + p = (unsigned char *)malloc(sizeof(unsigned char) * (bufsize + 1)); + fseek(fp, 0L, SEEK_SET); + fread(p, sizeof(char), bufsize, fp); + fclose(fp); + + p2 = (unsigned char *)malloc(sizeof(unsigned char) * (bufsize + 1)); + fsize = 0; + + for(i = 0; i < bufsize; i++) { + if(p[i] == '\r') { + p2[fsize++] = '\n'; + if(p[i + 1] == '\n') { + i++; + } + } else { + p2[fsize++] = p[i]; + } + } + p2[fsize++] = '\0'; + + free(p); + + if(pdwSize != NULL) { + *pdwSize = fsize; + } + + return p2; +} + +void WriteField(unsigned char *p, FILE *pFile, int c, int len) +{ + char BraceL[] = "{ "; + char BraceR[] = " }"; + char Ptr[] = "&"; + char Str[] = "\""; + char NoData[] = "0"; + char NoStr[] = "NULL"; + char Sep[] = ", "; + + switch(Columns[c]) { + case FIELD_INTEGER: + if(len != 0) { + fwrite(p, sizeof(char), len, pFile); + } else { + fwrite(NoData, sizeof(char), sizeof(NoData) - 1, pFile); + } + break; + case FIELD_STRING: + if(len != 0 && strncmp(NoStr, p, sizeof(NoStr) - 1) != 0) { + if(*p != '"') { + fwrite(Str, sizeof(char), sizeof(Str) - 1, pFile); + } + if(len != 1 || *p != '~') { + fwrite(p, sizeof(char), len, pFile); + } + if(p[len - 1] != '"') { + fwrite(Str, sizeof(char), sizeof(Str) - 1, pFile); + } + } else { + fwrite(NoStr, sizeof(char), sizeof(NoStr) - 1, pFile); + } + break; + case FIELD_ARRAY: + fwrite(BraceL, sizeof(char), sizeof(BraceL) - 1, pFile); + if(len != 0) { + if(p[0] == '\"' && p[len - 1] == '\"') { + fwrite(&p[1], sizeof(char), len - 2, pFile); + } else { + fwrite(p, sizeof(char), len, pFile); + } + } else { + fwrite(NoData, sizeof(char), sizeof(NoData) - 1, pFile); + } + fwrite(BraceR, sizeof(char), sizeof(BraceR) - 1, pFile); + break; + case FIELD_POINTER: + if(len != 0 && strncmp(NoStr, p, sizeof(NoStr) - 1) != 0) { + fwrite(Ptr, sizeof(char), sizeof(Ptr) - 1, pFile); + fwrite(p, sizeof(char), len, pFile); + } else { + fwrite(NoStr, sizeof(char), sizeof(NoStr) - 1, pFile); + } + break; + } + + if(c != NumCols - 1) { + fwrite(Sep, sizeof(char), sizeof(Sep) - 1, pFile); + } +} + +void WriteColumn(unsigned char *p, FILE *pFile, int c) +{ + unsigned char *p2; + int cur, len; + + cur = 0; + while(cur != c) { + while(*p != '\t' && *p != '\n') { + p++; + } + p++; + cur++; + } + + p2 = p; + len = 0; + while(*p2 != '\t' && *p2 != '\n') { + p2++; + len++; + } + + WriteField(p, pFile, c, len); +} + +void ConvertTextFile(char *name, unsigned char *p, int size) +{ + unsigned char *p2; + int c, len; + FILE *pOutput; + char Pre[] = "\t{ "; + char Suf[] = " },\r\n"; + + pOutput = fopen(name, "wb"); + + if(pOutput == NULL) { + fprintf(stderr, "Can't create file %s\n", name); + exit(-1); + } + + while(*p != '\n') { + p++; + } + p++; + + while(*p != '\0') { + p2 = p; + len = 0; + while(*p2 != '\n') { + p2++; + len++; + } + len++; + fwrite(Pre, sizeof(char), sizeof(Pre) - 1, pOutput); + for(c = 0; c < NumCols; c++) { + if(Columns[c] != FIELD_COMMENT) { + WriteColumn(p, pOutput, c); + } + } + fwrite(Suf, sizeof(char), sizeof(Suf) - 1, pOutput); + p += len; + } + + fclose(pOutput); +} + +void SetColumnType(char t, int c) +{ + switch(t) { + case 'i': + Columns[c] = FIELD_INTEGER; + return; + case 's': + Columns[c] = FIELD_STRING; + return; + case 'a': + Columns[c] = FIELD_ARRAY; + return; + case 'p': + Columns[c] = FIELD_POINTER; + return; + } + + fprintf(stderr, "Invalid type '%c' column %d\n", t, c + 1); + exit(-1); +} + +void CheckMaxColumns(unsigned char *p) +{ + int num_cols; + + num_cols = 0; + while(*p != '\n') { + if(*p == '\t') { + num_cols++; + } + p++; + } + num_cols++; + + if(num_cols >= MAX_COLUMNS) { + fprintf(stderr, "%d columns exceeds limit of %d\n", num_cols, MAX_COLUMNS - 1); + exit(-1); + } +} + +void SetupColumns(unsigned char *p) +{ + NumCols = 0; + + while(*p != '\n') { + if(*p == '\t') { + fprintf(stderr, "Invalid column %d\n", NumCols + 1); + exit(-1); + } + if(*p == '#') { + HasEnum = 1; + } + if(*p == '*' || p[0] == '#' && (p[1] == '\t' || p[1] == '\n')) { + Columns[NumCols++] = FIELD_COMMENT; + p++; + while(*p != '\t' && *p != '\n') { + p++; + } + if(*p != '\n') { + p++; + } + } else { + while(*p != '\t' && *p != '\n') { + p++; + } + p -= 3; + if(p[0] != '(' || p[2] != ')') { + fprintf(stderr, "No type for column %d\n", NumCols + 1); + exit(-1); + } + SetColumnType(p[1], NumCols++); + p += 3; + if(*p != '\n') { + p++; + } + } + } +} + +void GetNumRows(unsigned char *p) +{ + NumRows = 0; + while(*p != '\0') { + if(*p == '\n') { + NumRows++; + } + p++; + } +} + +void InitColumns(unsigned char *p) +{ + int i; + + for(i = 0; i < MAX_COLUMNS; i++) { + Columns[i] = -1; + } + + CheckMaxColumns(p); + SetupColumns(p); +} + +int IsValidEnum(unsigned char *p, int size) +{ + int i, valid; + + valid = 1; + for(i = 0; i < size && valid; i++) { + if(i != 0 && p[i] >= '0' && p[i] <= '9') { + continue; + } + if(p[i] >= 'A' && p[i] <= 'Z') { + continue; + } + if(p[i] >= 'a' && p[i] <= 'z') { + continue; + } + if(p[i] == '_') { + continue; + } + valid = 0; + } + + return valid; +} + +void WriteEnum(unsigned char *p, int c, FILE *pOutput) +{ + unsigned char *p2; + int i, cur, size; + char Pre[] = "enum {\r\n"; + char Tab[] = "\t"; + char Suf[] = ",\r\n"; + char End[] = "};\r\n"; + char tmp[16]; + + while(*p != '\n') { + p++; + } + p++; + + fwrite(Pre, sizeof(char), sizeof(Pre) - 1, pOutput); + + for(i = 0; i < NumRows - 1; i++) { + cur = 0; + while(cur != c) { + while(*p != '\t' && *p != '\n') { + p++; + } + p++; + cur++; + } + p2 = p; + size = 0; + while(*p2 != '\t' && *p2 != '\n') { + size++; + p2++; + } + if(IsValidEnum(p, size)) { + fwrite(Tab, sizeof(char), sizeof(Tab) - 1, pOutput); + fwrite(p, sizeof(char), size, pOutput); + sprintf(tmp, " = %d", i); + fwrite(tmp, sizeof(char), strlen(tmp), pOutput); + fwrite(Suf, sizeof(char), sizeof(Suf) - 1, pOutput); + } + p += size; + while(*p != '\n') { + p++; + } + p++; + } + + fwrite(End, sizeof(char), sizeof(End) - 1, pOutput); +} + +void WriteEnumFile(char *name, unsigned char *p, int size) +{ + int i, cur; + unsigned char *p2; + FILE *pOutput; + + pOutput = fopen(name, "wb"); + + if(pOutput == NULL) { + fprintf(stderr, "Can't create file %s\n", name); + exit(-1); + } + + for(i = 0; Columns[i] != -1; i++) { + p2 = p; + cur = 0; + while(cur != i) { + while(*p2 != '\t' && *p2 != '\n') { + p2++; + } + p2++; + cur++; + } + if(*p2 == '#') { + WriteEnum(p, i, pOutput); + } + } + + fclose(pOutput); +} + +int main(int argc, char *argv[]) +{ + int size; + unsigned char *p; + + if(argc != 3 && argc != 4) { + fprintf(stderr, "Usage: makexl [txt] [cpp] [h]\n"); + return 0; + } + + p = LoadBinaryFile(argv[1], &size); + + GetNumRows(p); + if(NumRows < 2) { + fprintf(stderr, "Not enough rows\n"); + free(p); + return 0; + } + + HasEnum = 0; + InitColumns(p); + + ConvertTextFile(argv[2], p, size); + + if(argc == 4 && HasEnum) { + WriteEnumFile(argv[3], p, size); + } + + free(p); + + return 0; +} diff --git a/2020_03_31/Utils/Utils.dsw b/2020_03_31/Utils/Utils.dsw new file mode 100644 index 00000000..a1956e1b --- /dev/null +++ b/2020_03_31/Utils/Utils.dsw @@ -0,0 +1,41 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "MakeText"=.\MakeText\MakeText.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "MakeXL"=.\MakeXL\MakeXL.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/2020_03_31/appveyor.yml b/2020_03_31/appveyor.yml new file mode 100644 index 00000000..2ba66073 --- /dev/null +++ b/2020_03_31/appveyor.yml @@ -0,0 +1,9 @@ +version: 1.0.{build} +pull_requests: + do_not_increment_build_number: true +image: Visual Studio 2017 +configuration: Release +platform: x86 +build: + project: Diablo.sln + verbosity: minimal diff --git a/2020_03_31/defs.h b/2020_03_31/defs.h new file mode 100644 index 00000000..0ce8f36a --- /dev/null +++ b/2020_03_31/defs.h @@ -0,0 +1,265 @@ +// some global definitions, found in debug release + +#define DMAXX 40 +#define DMAXY 40 + +#define LIGHTSIZE 6912 // 27 * 256 + +#define MAX_PLRS 4 +#define MAX_CHARACTERS 10 +#define MAX_LVLMTYPES 16 +// #define MAX_PATH 260 +#define MAX_SEND_STR_LEN 80 + +#define MAXDEAD 31 +#define MAXDUNX 112 +#define MAXDUNY 112 +#define MAXITEMS 127 +#define MAXLIGHTS 32 +#define MAXMISSILES 125 +#define MAXMONSTERS 200 +#define MAXMULTIQUESTS 4 +#define MAXOBJECTS 127 +#define MAXPORTAL 4 +#define MAXQUESTS 16 +#define MAXTHEMES 50 +#define MAXTILES 2048 +#define MAXTRIGGERS 5 +#define MAXVISION 32 +#define MDMAXX 40 +#define MDMAXY 40 + +// gmenu +#define MIN_SLIDER_TICKS 2 +#define MAX_SLIDER_TICKS 0xFFF + +// nthread +#define MIN_MSG_SIZE 128 +//#define MAX_MSG_SIZE 512 + +// sound +#define VOLUME_MIN -1600 +#define VOLUME_MAX 0 + +// todo: enums +#define NUM_INVLOC 7 +#define NUM_SFX 858 +#define NUMLEVELS 17 + +// from diablo 2 beta +#define MAXEXP 2000000000 + +#define PLR_NAME_LEN 32 + +// 256 kilobytes + 3 bytes (demo leftover) for file magic (262147) +// final game uses 4-byte magic instead of 3 +#define FILEBUFF ((256*1024)+3) + +// Diablo uses a 256 color palette +// Entry 0-127 (0x00-0x7F) are level specific +// Entry 128-255 (0x80-0xFF) are global + +// standard palette for all levels +// 8 or 16 shades per color +// example (dark blue): PAL16_BLUE+14, PAL8_BLUE+7 +// example (light red): PAL16_RED+2, PAL8_RED +// example (orange): PAL16_ORANGE+8, PAL8_ORANGE+4 +#define PAL8_BLUE 128 +#define PAL8_RED 136 +#define PAL8_YELLOW 144 +#define PAL8_ORANGE 152 +#define PAL16_BEIGE 160 +#define PAL16_BLUE 176 +#define PAL16_YELLOW 192 +#define PAL16_ORANGE 208 +#define PAL16_RED 224 +#define PAL16_GRAY 240 + + +#define SCREEN_WIDTH 640 +#define SCREEN_HEIGHT 480 + +// If defined, use 32-bit colors instead of 8-bit [Default -> Undefined] +//#define RGBMODE + +#ifndef RGBMODE +#define SCREEN_BPP 8 +#else +#define SCREEN_BPP 32 +#endif + +#define BORDER_LEFT 64 +#define BORDER_TOP 160 +#define BORDER_RIGHT 64 +#define BORDER_BOTTOM 16 + +#define SCREEN_X BORDER_LEFT +#define SCREEN_Y BORDER_TOP + +#define BUFFER_WIDTH (BORDER_LEFT + SCREEN_WIDTH + BORDER_RIGHT) +#define BUFFER_HEIGHT (BORDER_TOP + SCREEN_HEIGHT + BORDER_BOTTOM) +#define TILE_SIZE 32 + +#define SCREENXY(x, y) ((x) + SCREEN_X + ((y) + SCREEN_Y) * BUFFER_WIDTH) + +// debug +// #define DiabLoad(f, s, h) LoadFileInMem(f, s, h, __LINE__, __FILE__) +#define DiabLoad(f, s, h) LoadFileInMem(f, s) + +#define MemFreeDbg(p) \ +{ \ + void *p__p; \ + p__p = p; \ + p = NULL; \ + mem_free_dbg(p__p); \ +} + +#undef assert + +#ifndef _DEBUG +#define assert(exp) ((void)0) +#else +#define assert(exp) (void)( (exp) || (assert_fail(__LINE__, __FILE__, #exp), 0) ) +#endif + +///////////////////////////////////////////////////////////////////////// +/* temporary stuff from the decompiler */ +/* remove all the garbage below in the future */ +///////////////////////////////////////////////////////////////////////// +#ifndef IDA_GARBAGE +#define IDA_GARBAGE + +__inline void memset32(void *s, unsigned int c, size_t n) +{ + int i; + unsigned int *p = (unsigned int *)s; + for (i = 0; i < n; i++) { + p[i] = c; + } +} + +typedef __int64 ll; +typedef unsigned __int64 ull; + +typedef unsigned int uint; +typedef unsigned char uchar; +typedef unsigned short ushort; +typedef unsigned long ulong; + +typedef char int8; +typedef signed char sint8; +typedef unsigned char uint8; +typedef short int16; +typedef signed short sint16; +typedef unsigned short uint16; +typedef int int32; +typedef signed int sint32; +typedef unsigned int uint32; +typedef ll int64; +typedef ll sint64; +typedef ull uint64; + +// Partially defined types. They are used when the decompiler does not know +// anything about the type except its size. +#define _BYTE uint8 +#define _WORD uint16 +#define _DWORD uint32 +#define _QWORD uint64 + +// Some convenience macros to make partial accesses nicer +#define LAST_IND(x,part_type) (sizeof(x)/sizeof(part_type) - 1) +#if defined(__BYTE_ORDER) && __BYTE_ORDER == __BIG_ENDIAN +# define LOW_IND(x,part_type) LAST_IND(x,part_type) +# define HIGH_IND(x,part_type) 0 +#else +# define HIGH_IND(x,part_type) LAST_IND(x,part_type) +# define LOW_IND(x,part_type) 0 +#endif +// first unsigned macros: +#define BYTEn(x, n) (*((_BYTE*)&(x)+n)) +#define WORDn(x, n) (*((_WORD*)&(x)+n)) +#define DWORDn(x, n) (*((_DWORD*)&(x)+n)) + +#define _LOBYTE(x) BYTEn(x,LOW_IND(x,_BYTE)) +#define _LOWORD(x) WORDn(x,LOW_IND(x,_WORD)) +#define LODWORD(x) DWORDn(x,LOW_IND(x,_DWORD)) +#define _HIBYTE(x) BYTEn(x,HIGH_IND(x,_BYTE)) +#define _HIWORD(x) WORDn(x,HIGH_IND(x,_WORD)) +#define HIDWORD(x) DWORDn(x,HIGH_IND(x,_DWORD)) +#define BYTE1(x) BYTEn(x, 1) // byte 1 (counting from 0) +#define BYTE2(x) BYTEn(x, 2) + + +// now signed macros (the same but with sign extension) +#define SBYTEn(x, n) (*((int8*)&(x)+n)) +#define SWORDn(x, n) (*((int16*)&(x)+n)) + +#define SLOBYTE(x) SBYTEn(x,LOW_IND(x,int8)) +#define SHIWORD(x) SWORDn(x,HIGH_IND(x,int16)) + + + +// Helper functions to represent some assembly instructions. + +#ifdef __cplusplus + +__inline void *qmemcpy(void *dst, const void *src, size_t cnt) +{ + char *out = (char *)dst; + const char *in = (const char *)src; + while ( cnt > 0 ) + { + *out++ = *in++; + --cnt; + } + return dst; +} + +// sign flag +template int8 __SETS__(T x) +{ + if ( sizeof(T) == 1 ) + return int8(x) < 0; + if ( sizeof(T) == 2 ) + return int16(x) < 0; + if ( sizeof(T) == 4 ) + return int32(x) < 0; + return int64(x) < 0; +} + +// overflow flag of subtraction (x-y) +template int8 __OFSUB__(T x, U y) +{ + if ( sizeof(T) < sizeof(U) ) + { + U x2 = x; + int8 sx = __SETS__(x2); + return (sx ^ __SETS__(y)) & (sx ^ __SETS__(x2-y)); + } + else + { + T y2 = y; + int8 sx = __SETS__(x); + return (sx ^ __SETS__(y2)) & (sx ^ __SETS__(x-y2)); + } +} + +#endif + +#endif /* IDA_GARBAGE */ + +// Typedef for the function pointer +typedef void (*_PVFV)(void); + +#if defined(_MSC_VER) && !defined(__APPLE__) +// Define our segment names +#define SEGMENT_C_INIT ".CRT$XCU" + +// Build our various function tables and insert them into the correct segments. +#pragma data_seg(SEGMENT_C_INIT) +#pragma data_seg() // Switch back to the default segment +// Call function pointer arrays and place them in the segments created above +#define SEG_ALLOCATE(SEGMENT) __declspec(allocate(SEGMENT)) +#else +#define SEG_ALLOCATE(SEGMENT) +#endif diff --git a/2020_03_31/enums.h b/2020_03_31/enums.h new file mode 100644 index 00000000..a9a1ba38 --- /dev/null +++ b/2020_03_31/enums.h @@ -0,0 +1,990 @@ +enum unique_base_item +{ + UITYPE_NONE = 0x0, + UITYPE_SHORTBOW = 0x1, + UITYPE_LONGBOW = 0x2, + UITYPE_HUNTBOW = 0x3, + UITYPE_COMPBOW = 0x4, + UITYPE_WARBOW = 0x5, + UITYPE_BATTLEBOW = 0x6, + UITYPE_DAGGER = 0x7, + UITYPE_FALCHION = 0x8, + UITYPE_CLAYMORE = 0x9, + UITYPE_BROADSWR = 0xA, + UITYPE_SABRE = 0xB, + UITYPE_SCIMITAR = 0xC, + UITYPE_LONGSWR = 0xD, + UITYPE_BASTARDSWR = 0xE, + UITYPE_TWOHANDSWR = 0xF, + UITYPE_GREATSWR = 0x10, + UITYPE_CLEAVER = 0x11, + UITYPE_LARGEAXE = 0x12, + UITYPE_BROADAXE = 0x13, + UITYPE_SMALLAXE = 0x14, + UITYPE_BATTLEAXE = 0x15, + UITYPE_GREATAXE = 0x16, + UITYPE_MACE = 0x17, + UITYPE_MORNSTAR = 0x18, + UITYPE_SPIKCLUB = 0x19, + UITYPE_MAUL = 0x1A, + UITYPE_WARHAMMER = 0x1B, + UITYPE_FLAIL = 0x1C, + UITYPE_LONGSTAFF = 0x1D, + UITYPE_SHORTSTAFF = 0x1E, + UITYPE_COMPSTAFF = 0x1F, + UITYPE_QUARSTAFF = 0x20, + UITYPE_WARSTAFF = 0x21, + UITYPE_SKULLCAP = 0x22, + UITYPE_HELM = 0x23, + UITYPE_GREATHELM = 0x24, + UITYPE_CROWN = 0x25, + UITYPE_38 = 0x26, + UITYPE_RAGS = 0x27, + UITYPE_STUDARMOR = 0x28, + UITYPE_CLOAK = 0x29, + UITYPE_ROBE = 0x2A, + UITYPE_CHAINMAIL = 0x2B, + UITYPE_LEATHARMOR = 0x2C, + UITYPE_BREASTPLATE = 0x2D, + UITYPE_CAPE = 0x2E, + UITYPE_PLATEMAIL = 0x2F, + UITYPE_FULLPLATE = 0x30, + UITYPE_BUCKLER = 0x31, + UITYPE_SMALLSHIELD = 0x32, + UITYPE_LARGESHIELD = 0x33, + UITYPE_KITESHIELD = 0x34, + UITYPE_GOTHSHIELD = 0x35, + UITYPE_RING = 0x36, + UITYPE_55 = 0x37, + UITYPE_AMULET = 0x38, + UITYPE_SKCROWN = 0x39, + UITYPE_INFRARING = 0x3A, + UITYPE_OPTAMULET = 0x3B, + UITYPE_TRING = 0x3C, + UITYPE_HARCREST = 0x3D, + UITYPE_MAPOFDOOM = 0x3E, + UITYPE_ELIXIR = 0x3F, + UITYPE_ARMOFVAL = 0x40, + UITYPE_STEELVEIL = 0x41, + UITYPE_GRISWOLD = 0x42, + UITYPE_LGTFORGE = 0x43, + UITYPE_LAZSTAFF = 0x44, + UITYPE_INVALID = -1, +}; + +enum item_effect_type +{ + IPL_TOHIT = 0x0, + IPL_TOHIT_CURSE = 0x1, + IPL_DAMP = 0x2, + IPL_DAMP_CURSE = 0x3, + IPL_TOHIT_DAMP = 0x4, + IPL_TOHIT_DAMP_CURSE = 0x5, + IPL_ACP = 0x6, + IPL_ACP_CURSE = 0x7, + IPL_FIRERES = 0x8, + IPL_LIGHTRES = 0x9, + IPL_MAGICRES = 0xA, + IPL_ALLRES = 0xB, + IPL_SPLCOST = 0xC, + IPL_SPLDUR = 0xD, + IPL_SPLLVLADD = 0xE, + IPL_CHARGES = 0xF, + IPL_FIREDAM = 0x10, + IPL_LIGHTDAM = 0x11, + IPL_RNDSPL_5MIN = 0x12, + IPL_STR = 0x13, + IPL_STR_CURSE = 0x14, + IPL_MAG = 0x15, + IPL_MAG_CURSE = 0x16, + IPL_DEX = 0x17, + IPL_DEX_CURSE = 0x18, + IPL_VIT = 0x19, + IPL_VIT_CURSE = 0x1A, + IPL_ATTRIBS = 0x1B, + IPL_ATTRIBS_CURSE = 0x1C, + IPL_GETHIT_CURSE = 0x1D, + IPL_GETHIT = 0x1E, + IPL_LIFE = 0x1F, + IPL_LIFE_CURSE = 0x20, + IPL_MANA = 0x21, + IPL_MANA_CURSE = 0x22, + IPL_DUR = 0x23, + IPL_DUR_CURSE = 0x24, + IPL_INDESTRUCTIBLE = 0x25, + IPL_LIGHT = 0x26, + IPL_LIGHT_CURSE = 0x27, + IPL_INVISIBILITY = 0x28, + IPL_MULT_ARROWS = 0x29, /* only used in hellfire */ + IPL_FIRE_ARROWS = 0x2A, + IPL_LIGHT_ARROWS = 0x2B, + IPL_INVCURS = 0x2C, + IPL_THORNS = 0x2D, + IPL_NOMANA = 0x2E, + IPL_NOHEALPLR = 0x2F, + IPL_SCAREMONST = 0x30, + IPL_ATTACKTWICE = 0x31, + IPL_EXPONENTIALDMG = 0x32, + IPL_SEEINVISIBLE = 0x33, + IPL_ABSHALFTRAP = 0x34, + IPL_KNOCKBACK = 0x35, + IPL_NOHEALMON = 0x36, + IPL_STEALMANA = 0x37, + IPL_STEALLIFE = 0x38, + IPL_TARGAC = 0x39, + IPL_FASTATTACK = 0x3A, + IPL_FASTRECOVER = 0x3B, + IPL_FASTBLOCK = 0x3C, + IPL_DAMMOD = 0x3D, + IPL_RNDARROWVEL = 0x3E, + IPL_SETDAM = 0x3F, + IPL_SETDUR = 0x40, + IPL_NOMINSTR = 0x41, + IPL_SPELL = 0x42, + IPL_FASTSWING = 0x43, + IPL_ONEHAND = 0x44, + IPL_3XDAMVDEM = 0x45, + IPL_ALLRESZERO = 0x46, + IPL_DRAINLIFE = 0x48, + IPL_RNDSTEALLIFE = 0x49, + IPL_INFRAVISION = 0x4A, + IPL_SETAC = 0x4B, + IPL_ADDACLIFE = 0x4C, + IPL_ADDMANAAC = 0x4D, + IPL_FIRERESCLVL = 0x4E, + IPL_AC_CURSE = 0x4F, + IPL_INVALID = -1, +}; + +enum affix_item_type +{ + PLT_MISC = 0x1, + PLT_BOW = 0x10, + PLT_STAFF = 0x100, + PLT_WEAP = 0x1000, + PLT_SHLD = 0x10000, + PLT_ARMO = 0x100000, +}; + +#include "Source/Data/xl_sfx.h" + +enum item_equip_type +{ + ILOC_NONE = 0x0, + ILOC_ONEHAND = 0x1, + ILOC_TWOHAND = 0x2, + ILOC_ARMOR = 0x3, + ILOC_HELM = 0x4, + ILOC_RING = 0x5, + ILOC_AMULET = 0x6, + ILOC_UNEQUIPABLE = 0x7, + ILOC_BELT = 0x8, + ILOC_INVALID = -1, +}; + +#include "Source/Data/xl_mis.h" + +#include "Source/Data/xl_mfile.h" + +enum _mai_id +{ + AI_ZOMBIE = 0, + AI_FAT = 1, + AI_SKELSD = 2, + AI_SKELBOW = 3, + AI_SCAV = 4, + AI_RHINO = 5, + AI_GOATMC = 6, + AI_GOATBOW = 7, + AI_FALLEN = 8, + AI_MAGMA = 9, + AI_SKELKING = 10, + AI_BAT = 11, + AI_GARG = 12, + AI_CLEAVER = 13, + AI_SUCC = 14, + AI_SNEAK = 15, + AI_STORM = 16, + AI_FIREMAN = 17, + AI_GARBUD = 18, + AI_ACID = 19, + AI_ACIDUNIQ = 20, + AI_GOLUM = 21, + AI_ZHAR = 22, + AI_SNOTSPIL = 23, + AI_SNAKE = 24, + AI_COUNSLR = 25, + AI_MEGA = 26, + AI_DIABLO = 27, + AI_LAZURUS = 28, + AI_LAZHELP = 29, + AI_LACHDAN = 30, + AI_WARLORD = 31, +}; + +enum _mc_id +{ + MC_UNDEAD = 0, + MC_DEMON = 1, + MC_ANIMAL = 2, +}; + +#include "Source/Data/xl_monst.h" + +#include "Source/Data/speech.h" + +enum object_graphic_id +{ + OFILE_L1BRAZ = 0x0, + OFILE_L1DOORS = 0x1, + OFILE_LEVER = 0x2, + OFILE_CHEST1 = 0x3, + OFILE_CHEST2 = 0x4, + OFILE_BANNER = 0x5, + OFILE_SKULPILE = 0x6, + OFILE_SKULFIRE = 0x7, + OFILE_SKULSTIK = 0x8, + OFILE_CRUXSK1 = 0x9, + OFILE_CRUXSK2 = 0xA, + OFILE_CRUXSK3 = 0xB, + OFILE_BOOK1 = 0xC, + OFILE_BOOK2 = 0xD, + OFILE_ROCKSTAN = 0xE, + OFILE_ANGEL = 0xF, + OFILE_CHEST3 = 0x10, + OFILE_BURNCROS = 0x11, + OFILE_CANDLE2 = 0x12, + OFILE_NUDE2 = 0x13, + OFILE_SWITCH4 = 0x14, + OFILE_TNUDEM = 0x15, + OFILE_TNUDEW = 0x16, + OFILE_TSOUL = 0x17, + OFILE_L2DOORS = 0x18, + OFILE_WTORCH4 = 0x19, + OFILE_WTORCH3 = 0x1A, + OFILE_SARC = 0x1B, + OFILE_FLAME1 = 0x1C, + OFILE_PRSRPLT1 = 0x1D, + OFILE_TRAPHOLE = 0x1E, + OFILE_MINIWATR = 0x1F, + OFILE_WTORCH2 = 0x20, + OFILE_WTORCH1 = 0x21, + OFILE_BCASE = 0x22, + OFILE_BSHELF = 0x23, + OFILE_WEAPSTND = 0x24, + OFILE_BARREL = 0x25, + OFILE_BARRELEX = 0x26, + OFILE_LSHRINEG = 0x27, + OFILE_RSHRINEG = 0x28, + OFILE_BLOODFNT = 0x29, + OFILE_DECAP = 0x2A, + OFILE_PEDISTL = 0x2B, + OFILE_L3DOORS = 0x2C, + OFILE_PFOUNTN = 0x2D, + OFILE_ARMSTAND = 0x2E, + OFILE_GOATSHRN = 0x2F, + OFILE_CAULDREN = 0x30, + OFILE_MFOUNTN = 0x31, + OFILE_TFOUNTN = 0x32, + OFILE_ALTBOY = 0x33, + OFILE_MCIRL = 0x34, + OFILE_BKSLBRNT = 0x35, + OFILE_MUSHPTCH = 0x36, + OFILE_LZSTAND = 0x37, +}; + +enum dungeon_type +{ + DTYPE_TOWN = 0x0, + DTYPE_CATHEDRAL = 0x1, + DTYPE_CATACOMBS = 0x2, + DTYPE_CAVES = 0x3, + DTYPE_HELL = 0x4, + DTYPE_NONE = 0xFF, +}; + +enum magic_type +{ + STYPE_FIRE = 0x0, + STYPE_LIGHTNING = 0x1, + STYPE_MAGIC = 0x2, +}; + +enum theme_id +{ + THEME_BARREL = 0x0, + THEME_SHRINE = 0x1, + THEME_MONSTPIT = 0x2, + THEME_SKELROOM = 0x3, + THEME_TREASURE = 0x4, + THEME_LIBRARY = 0x5, + THEME_TORTURE = 0x6, + THEME_BLOODFOUNTAIN = 0x7, + THEME_DECAPITATED = 0x8, + THEME_PURIFYINGFOUNTAIN = 0x9, + THEME_ARMORSTAND = 0xA, + THEME_GOATSHRINE = 0xB, + THEME_CAULDRON = 0xC, + THEME_MURKYFOUNTAIN = 0xD, + THEME_TEARFOUNTAIN = 0xE, + THEME_BRNCROSS = 0xF, + THEME_WEAPONRACK = 0x10, + THEME_NONE = 0xFF, +}; + +enum event_type +{ + EVENT_TYPE_PLAYER_CREATE_GAME = 1, + EVENT_TYPE_2 = 2, + EVENT_TYPE_PLAYER_LEAVE_GAME = 3, + EVENT_TYPE_PLAYER_MESSAGE = 4, + EVENT_TYPE_5 = 5, + EVENT_TYPE_6 = 6, + EVENT_TYPE_7 = 7, + EVENT_TYPE_8 = 8, + EVENT_TYPE_9 = 9, + EVENT_TYPE_10 = 10, + EVENT_TYPE_11 = 11, + EVENT_TYPE_12 = 12, + EVENT_TYPE_13 = 13, + EVENT_TYPE_14 = 14, + EVENT_TYPE_15 = 15, +}; + +enum _copyprot_results +{ + COPYPROT_OK = 1, + COPYPROT_CANCEL = 2, +}; + +enum text_color +{ + COL_WHITE = 0x0, + COL_BLUE = 0x1, + COL_RED = 0x2, + COL_GOLD = 0x3, +}; + +enum _difficulty +{ + DIFF_NORMAL = 0x0, + DIFF_NIGHTMARE = 0x1, + DIFF_HELL = 0x2, + NUM_DIFFICULTIES = 0x3, +}; + +enum MON_MODE +{ + MM_STAND = 0, + MM_WALK = 1, + MM_WALK2 = 2, + MM_WALK3 = 3, + MM_ATTACK = 4, + MM_GOTHIT = 5, + MM_DEATH = 6, + MM_SATTACK = 7, + MM_FADEIN = 8, + MM_FADEOUT = 9, + MM_RATTACK = 10, + MM_SPSTAND = 11, + MM_RSPATTACK = 12, + MM_DELAY = 13, + MM_CHARGE = 14, + MM_STONE = 15, + MM_HEAL = 16, + MM_TALK = 17, +}; + +enum PLR_MODE +{ + PM_STAND = 0, + PM_WALK = 1, + PM_WALK2 = 2, + PM_WALK3 = 3, + PM_ATTACK = 4, + PM_RATTACK = 5, + PM_BLOCK = 6, + PM_GOTHIT = 7, + PM_DEATH = 8, + PM_SPELL = 9, + PM_NEWLVL = 10, + PM_QUIT = 11, +}; + +enum spell_type +{ + RSPLTYPE_SKILL = 0x0, + RSPLTYPE_SPELL = 0x1, + RSPLTYPE_SCROLL = 0x2, + RSPLTYPE_CHARGES = 0x3, + RSPLTYPE_INVALID = 0x4, +}; + +enum cursor_id +{ + CURSOR_NONE = 0x0, + CURSOR_HAND = 0x1, + CURSOR_IDENTIFY = 0x2, + CURSOR_REPAIR = 0x3, + CURSOR_RECHARGE = 0x4, + CURSOR_DISARM = 0x5, + CURSOR_OIL = 0x6, + CURSOR_TELEKINESIS = 0x7, + CURSOR_RESURRECT = 0x8, + CURSOR_TELEPORT = 0x9, + CURSOR_HEALOTHER = 0xA, + CURSOR_HOURGLASS = 0xB, + CURSOR_FIRSTITEM = 0xC, +}; + +enum direction +{ + DIR_S = 0x0, + DIR_SW = 0x1, + DIR_W = 0x2, + DIR_NW = 0x3, + DIR_N = 0x4, + DIR_NE = 0x5, + DIR_E = 0x6, + DIR_SE = 0x7, + DIR_OMNI = 0x8, +}; + +enum interface_mode +{ + WM_DIABNEXTLVL = 0x402, // WM_USER+2 + WM_DIABPREVLVL = 0x403, + WM_DIABRTNLVL = 0x404, + WM_DIABSETLVL = 0x405, + WM_DIABWARPLVL = 0x406, + WM_DIABTOWNWARP = 0x407, + WM_DIABTWARPUP = 0x408, + WM_DIABRETOWN = 0x409, + WM_DIABNEWGAME = 0x40A, + WM_DIABLOADGAME = 0x40B + // WM_LEIGHSKIP = 0x40C, // psx only + // WM_DIAVNEWLVL = 0x40D, // psx only +}; + +enum game_info +{ + GAMEINFO_NAME = 1, + GAMEINFO_PASSWORD = 2, + GAMEINFO_STATS = 3, + GAMEINFO_MODEFLAG = 4, + GAMEINFO_GAMETEMPLATE = 5, + GAMEINFO_PLAYERS = 6, +}; + +#include "Source/Data/xl_spell.h" + +enum _cmd_id +{ + CMD_STAND = 0, + CMD_WALKXY = 1, + CMD_ACK_PLRINFO = 2, + CMD_ADDSTR = 3, + CMD_ADDMAG = 4, + CMD_ADDDEX = 5, + CMD_ADDVIT = 6, + CMD_SBSPELL = 7, + CMD_GETITEM = 8, + CMD_AGETITEM = 9, + CMD_PUTITEM = 10, + CMD_RESPAWNITEM = 11, + CMD_ATTACKXY = 12, + CMD_RATTACKXY = 13, + CMD_SPELLXY = 14, + CMD_TSPELLXY = 15, + CMD_OPOBJXY = 16, + CMD_DISARMXY = 17, + CMD_ATTACKID = 18, + CMD_ATTACKPID = 19, + CMD_RATTACKID = 20, + CMD_RATTACKPID = 21, + CMD_SPELLID = 22, + CMD_SPELLPID = 23, + CMD_TSPELLID = 24, + CMD_TSPELLPID = 25, + CMD_RESURRECT = 26, + CMD_OPOBJT = 27, + CMD_KNOCKBACK = 28, + CMD_TALKXY = 29, + CMD_NEWLVL = 30, + CMD_WARP = 31, + CMD_CHEAT_EXPERIENCE = 32, + CMD_CHEAT_SPELL_LEVEL = 33, + CMD_DEBUG = 34, + CMD_SYNCDATA = 35, + CMD_MONSTDEATH = 36, + CMD_MONSTDAMAGE = 37, + CMD_PLRDEAD = 38, + CMD_REQUESTGITEM = 39, + CMD_REQUESTAGITEM = 40, + CMD_GOTOGETITEM = 41, + CMD_GOTOAGETITEM = 42, + CMD_OPENDOOR = 43, + CMD_CLOSEDOOR = 44, + CMD_OPERATEOBJ = 45, + CMD_PLROPOBJ = 46, + CMD_BREAKOBJ = 47, + CMD_CHANGEPLRITEMS = 48, + CMD_DELPLRITEMS = 49, + CMD_PLRDAMAGE = 50, + CMD_PLRLEVEL = 51, + CMD_DROPITEM = 52, + CMD_PLAYER_JOINLEVEL = 53, + CMD_SEND_PLRINFO = 54, + CMD_SATTACKXY = 55, + CMD_ACTIVATEPORTAL = 56, + CMD_DEACTIVATEPORTAL = 57, + CMD_DLEVEL_0 = 58, + CMD_DLEVEL_1 = 59, + CMD_DLEVEL_2 = 60, + CMD_DLEVEL_3 = 61, + CMD_DLEVEL_4 = 62, + CMD_DLEVEL_5 = 63, + CMD_DLEVEL_6 = 64, + CMD_DLEVEL_7 = 65, + CMD_DLEVEL_8 = 66, + CMD_DLEVEL_9 = 67, + CMD_DLEVEL_10 = 68, + CMD_DLEVEL_11 = 69, + CMD_DLEVEL_12 = 70, + CMD_DLEVEL_13 = 71, + CMD_DLEVEL_14 = 72, + CMD_DLEVEL_15 = 73, + CMD_DLEVEL_16 = 74, + CMD_DLEVEL_JUNK = 75, + CMD_DLEVEL_END = 76, + CMD_HEALOTHER = 77, + CMD_STRING = 78, + CMD_SETSTR = 79, + CMD_SETMAG = 80, + CMD_SETDEX = 81, + CMD_SETVIT = 82, + CMD_RETOWN = 83, + CMD_SPELLXYD = 84, + CMD_ITEMEXTRA = 85, + CMD_SYNCPUTITEM = 86, + CMD_KILLGOLEM = 87, + CMD_SYNCQUEST = 88, + CMD_ENDSHIELD = 89, + CMD_AWAKEGOLEM = 90, + CMD_NOVA = 91, + CMD_SETSHIELD = 92, + CMD_REMSHIELD = 93, + FAKE_CMD_SETID = 94, + FAKE_CMD_DROPID = 95, + NUM_CMDS = 96, +}; + +enum _talker_id +{ + TOWN_SMITH = 0x0, + TOWN_HEALER = 0x1, + TOWN_DEADGUY = 0x2, + TOWN_TAVERN = 0x3, + TOWN_STORY = 0x4, + TOWN_DRUNK = 0x5, + TOWN_WITCH = 0x6, + TOWN_BMAID = 0x7, + TOWN_PEGBOY = 0x8, + TOWN_COW = 0x9, + TOWN_PRIEST = 0xA, +}; + +enum _music_id +{ + TMUSIC_TOWN = 0, + TMUSIC_L1 = 1, + TMUSIC_L2 = 2, + TMUSIC_L3 = 3, + TMUSIC_L4 = 4, + TMUSIC_INTRO = 5, + NUM_MUSIC = 6, +}; + +enum _mainmenu_selections +{ + MAINMENU_SINGLE_PLAYER = 1, + MAINMENU_MULTIPLAYER = 2, + MAINMENU_REPLAY_INTRO = 3, + MAINMENU_SHOW_CREDITS = 4, + MAINMENU_EXIT_DIABLO = 5, + MAINMENU_ATTRACT_MODE = 6, +}; + +enum panel_button_id +{ + PANBTN_CHARINFO = 0, + PANBTN_QLOG = 1, + PANBTN_AUTOMAP = 2, + PANBTN_MAINMENU = 3, + PANBTN_INVENTORY = 4, + PANBTN_SPELLBOOK = 5, + PANBTN_SENDMSG = 6, + PANBTN_FRIENDLY = 7, +}; + +enum attribute_id +{ + ATTRIB_STR = 0, + ATTRIB_MAG = 1, + ATTRIB_DEX = 2, + ATTRIB_VIT = 3, +}; + +#include "Source/Data/xl_obj.h" + +enum item_misc_id +{ + IMISC_NONE = 0x0, + IMISC_USEFIRST = 0x1, + IMISC_FULLHEAL = 0x2, + IMISC_HEAL = 0x3, + IMISC_OLDHEAL = 0x4, + IMISC_DEADHEAL = 0x5, + IMISC_MANA = 0x6, + IMISC_FULLMANA = 0x7, + IMISC_POTEXP = 0x8, /* add experience */ + IMISC_POTFORG = 0x9, /* remove experience */ + IMISC_ELIXSTR = 0xA, + IMISC_ELIXMAG = 0xB, + IMISC_ELIXDEX = 0xC, + IMISC_ELIXVIT = 0xD, + IMISC_ELIXWEAK = 0xE, /* double check with alpha */ + IMISC_ELIXDIS = 0xF, + IMISC_ELIXCLUM = 0x10, + IMISC_ELIXSICK = 0x11, + IMISC_REJUV = 0x12, + IMISC_FULLREJUV = 0x13, + IMISC_USELAST = 0x14, + IMISC_SCROLL = 0x15, + IMISC_SCROLLT = 0x16, + IMISC_STAFF = 0x17, + IMISC_BOOK = 0x18, + IMISC_RING = 0x19, + IMISC_AMULET = 0x1A, + IMISC_UNIQUE = 0x1B, + IMISC_MEAT = 0x1C, + IMISC_OILFIRST = 0x1D, + IMISC_OILOF = 0x1E, /* oils are beta or hellfire only */ + IMISC_OILACC = 0x1F, + IMISC_OILMAST = 0x20, + IMISC_OILSHARP = 0x21, + IMISC_OILDEATH = 0x22, + IMISC_OILSKILL = 0x23, + IMISC_OILBSMTH = 0x24, + IMISC_OILFORT = 0x25, + IMISC_OILPERM = 0x26, + IMISC_OILHARD = 0x27, + IMISC_OILIMP = 0x28, + IMISC_OILLAST = 0x29, + IMISC_MAPOFDOOM = 0x2A, + IMISC_EAR = 0x2B, + IMISC_SPECELIX = 0x2C, + IMISC_INVALID = 0xFFFFFFFF, +}; + +enum item_type +{ + ITYPE_MISC = 0x0, + ITYPE_SWORD = 0x1, + ITYPE_AXE = 0x2, + ITYPE_BOW = 0x3, + ITYPE_MACE = 0x4, + ITYPE_SHIELD = 0x5, + ITYPE_LARMOR = 0x6, + ITYPE_HELM = 0x7, + ITYPE_MARMOR = 0x8, + ITYPE_HARMOR = 0x9, + ITYPE_STAFF = 0xA, + ITYPE_GOLD = 0xB, + ITYPE_RING = 0xC, + ITYPE_AMULET = 0xD, + ITYPE_MEAT = 0xE, /* used in demo */ + ITYPE_NONE = 0xFFFFFFFF, +}; + +enum _item_indexes +{ + IDI_GOLD = 0x0, + IDI_WARRIOR = 0x1, + IDI_WARRSHLD = 0x2, + IDI_WARRCLUB = 0x3, + IDI_ROGUE = 0x4, + IDI_SORCEROR = 0x5, + IDI_CLEAVER = 0x6, + IDI_FIRSTQUEST = 0x6, + IDI_SKCROWN = 0x7, + IDI_INFRARING = 0x8, + IDI_ROCK = 0x9, + IDI_OPTAMULET = 0xA, + IDI_TRING = 0xB, + IDI_BANNER = 0xC, + IDI_HARCREST = 0xD, + IDI_STEELVEIL = 0xE, + IDI_GLDNELIX = 0xF, + IDI_ANVIL = 0x10, + IDI_MUSHROOM = 0x11, + IDI_BRAIN = 0x12, + IDI_FUNGALTM = 0x13, + IDI_SPECELIX = 0x14, + IDI_BLDSTONE = 0x15, + IDI_LASTQUEST = 0x16, + IDI_MAPOFDOOM = 0x16, + IDI_EAR = 0x17, + IDI_HEAL = 0x18, + IDI_MANA = 0x19, + IDI_IDENTIFY = 0x1A, + IDI_PORTAL = 0x1B, + IDI_ARMOFVAL = 0x1C, + IDI_FULLHEAL = 0x1D, + IDI_FULLMANA = 0x1E, + IDI_GRISWOLD = 0x1F, + IDI_LGTFORGE = 0x20, + IDI_LAZSTAFF = 0x21, + IDI_RESURRECT = 0x22, +}; + +enum _setlevels +{ + //SL_BUTCHCHAMB = 0x0, + SL_SKELKING = 0x1, + SL_BONECHAMB = 0x2, + SL_MAZE = 0x3, + SL_POISONWATER = 0x4, + SL_VILEBETRAYER = 0x5, +}; + +#include "Source/Data/xl_quest.h" + +enum quest_state +{ + QUEST_NOTAVAIL = 0, + QUEST_INIT = 1, + QUEST_ACTIVE = 2, + QUEST_DONE = 3 +}; + +enum talk_id +{ + STORE_NONE = 0x0, + STORE_SMITH = 0x1, + STORE_SBUY = 0x2, + STORE_SSELL = 0x3, + STORE_SREPAIR = 0x4, + STORE_WITCH = 0x5, + STORE_WBUY = 0x6, + STORE_WSELL = 0x7, + STORE_WRECHARGE = 0x8, + STORE_NOMONEY = 0x9, + STORE_NOROOM = 0xA, + STORE_CONFIRM = 0xB, + STORE_BOY = 0xC, + STORE_BBOY = 0xD, + STORE_HEALER = 0xE, + STORE_STORY = 0xF, + STORE_HBUY = 0x10, + STORE_SIDENTIFY = 0x11, + STORE_SPBUY = 0x12, + STORE_GOSSIP = 0x13, + STORE_IDSHOW = 0x14, + STORE_TAVERN = 0x15, + STORE_DRUNK = 0x16, + STORE_BARMAID = 0x17, +}; + +enum _unique_items +{ + UITEM_CLEAVER = 0x0, + UITEM_SKCROWN = 0x1, + UITEM_INFRARING = 0x2, + UITEM_OPTAMULET = 0x3, + UITEM_TRING = 0x4, + UITEM_HARCREST = 0x5, + UITEM_STEELVEIL = 0x6, + UITEM_ARMOFVAL = 0x7, + UITEM_GRISWOLD = 0x8, + UITEM_LGTFORGE = 0x9, + UITEM_RIFTBOW = 0xA, + UITEM_NEEDLER = 0xB, + UITEM_CELESTBOW = 0xC, + UITEM_DEADLYHUNT = 0xD, + UITEM_BOWOFDEAD = 0xE, + UITEM_BLKOAKBOW = 0xF, + UITEM_FLAMEDART = 0x10, + UITEM_FLESHSTING = 0x11, + UITEM_WINDFORCE = 0x12, + UITEM_EAGLEHORN = 0x13, + UITEM_GONNAGALDIRK = 0x14, + UITEM_DEFENDER = 0x15, + UITEM_GRYPHONCLAW = 0x16, + UITEM_BLACKRAZOR = 0x17, + UITEM_GIBBOUSMOON = 0x18, + UITEM_ICESHANK = 0x19, + UITEM_EXECUTIONER = 0x1A, + UITEM_BONESAW = 0x1B, + UITEM_SHADHAWK = 0x1C, + UITEM_WIZSPIKE = 0x1D, + UITEM_LGTSABRE = 0x1E, + UITEM_FALCONTALON = 0x1F, + UITEM_INFERNO = 0x20, + UITEM_DOOMBRINGER = 0x21, + UITEM_GRIZZLY = 0x22, + UITEM_GRANDFATHER = 0x23, + UITEM_MANGLER = 0x24, + UITEM_SHARPBEAK = 0x25, + UITEM_BLOODLSLAYER = 0x26, + UITEM_CELESTAXE = 0x27, + UITEM_WICKEDAXE = 0x28, + UITEM_STONECLEAV = 0x29, + UITEM_AGUHATCHET = 0x2A, + UITEM_HELLSLAYER = 0x2B, + UITEM_MESSERREAVER = 0x2C, + UITEM_CRACKRUST = 0x2D, + UITEM_JHOLMHAMM = 0x2E, + UITEM_CIVERBS = 0x2F, + UITEM_CELESTSTAR = 0x30, + UITEM_BARANSTAR = 0x31, + UITEM_GNARLROOT = 0x32, + UITEM_CRANBASH = 0x33, + UITEM_SCHAEFHAMM = 0x34, + UITEM_DREAMFLANGE = 0x35, + UITEM_STAFFOFSHAD = 0x36, + UITEM_IMMOLATOR = 0x37, + UITEM_STORMSPIRE = 0x38, + UITEM_GLEAMSONG = 0x39, + UITEM_THUNDERCALL = 0x3A, + UITEM_PROTECTOR = 0x3B, + UITEM_NAJPUZZLE = 0x3C, + UITEM_MINDCRY = 0x3D, + UITEM_RODOFONAN = 0x3E, + UITEM_SPIRITSHELM = 0x3F, + UITEM_THINKINGCAP = 0x40, + UITEM_OVERLORDHELM = 0x41, + UITEM_FOOLSCREST = 0x42, + UITEM_GOTTERDAM = 0x43, + UITEM_ROYCIRCLET = 0x44, + UITEM_TORNFLESH = 0x45, + UITEM_GLADBANE = 0x46, + UITEM_RAINCLOAK = 0x47, + UITEM_LEATHAUT = 0x48, + UITEM_WISDWRAP = 0x49, + UITEM_SPARKMAIL = 0x4A, + UITEM_SCAVCARAP = 0x4B, + UITEM_NIGHTSCAPE = 0x4C, + UITEM_NAJPLATE = 0x4D, + UITEM_DEMONSPIKE = 0x4E, + UITEM_DEFLECTOR = 0x4F, + UITEM_SKULLSHLD = 0x50, + UITEM_DRAGONBRCH = 0x51, + UITEM_BLKOAKSHLD = 0x52, + UITEM_HOLYDEF = 0x53, + UITEM_STORMSHLD = 0x54, + UITEM_BRAMBLE = 0x55, + UITEM_REGHA = 0x56, + UITEM_BLEEDER = 0x57, + UITEM_CONSTRICT = 0x58, + UITEM_ENGAGE = 0x59, + UITEM_INVALID = 0x5A, +}; + +enum _plr_classes +{ + PC_WARRIOR = 0x0, + PC_ROGUE = 0x1, + PC_SORCERER = 0x2, + NUM_CLASSES = 0x3, +}; + +enum _ui_classes +{ + UI_WARRIOR = 0x0, + UI_ROGUE = 0x1, + UI_SORCERER = 0x2, + UI_NUM_CLASSES = 0x3, +}; + +enum _walk_path +{ + WALK_NONE = 0x0, + WALK_NE = 0x1, + WALK_NW = 0x2, + WALK_SE = 0x3, + WALK_SW = 0x4, + WALK_N = 0x5, + WALK_E = 0x6, + WALK_S = 0x7, + WALK_W = 0x8, +}; + +typedef enum { + ICLASS_NONE = 0, + ICLASS_WEAPON = 1, + ICLASS_ARMOR = 2, + ICLASS_MISC = 3, + ICLASS_GOLD = 4, + ICLASS_QUEST = 5, +} item_class; + +typedef enum { + IDROP_NEVER = 0, + IDROP_REGULAR = 1, + IDROP_DOUBLE = 2, +} item_drop_rate; + +typedef enum { + ISPL_NONE = 0x00000000, + ISPL_INFRAVISION = 0x00000001, + ISPL_RNDSTEALLIFE = 0x00000002, + ISPL_RNDARROWVEL = 0x00000004, + ISPL_FIRE_ARROWS = 0x00000008, + ISPL_FIREDAM = 0x00000010, + ISPL_LIGHTDAM = 0x00000020, + ISPL_DRAINLIFE = 0x00000040, + ISPL_UNKNOWN_1 = 0x00000080, + ISPL_NOHEALPLR = 0x00000100, + ISPL_MULT_ARROWS = 0x00000200, + ISPL_UNKNOWN_3 = 0x00000400, + ISPL_KNOCKBACK = 0x00000800, + ISPL_NOHEALMON = 0x00001000, + ISPL_STEALMANA_3 = 0x00002000, + ISPL_STEALMANA_5 = 0x00004000, + ISPL_STEALLIFE_3 = 0x00008000, + ISPL_STEALLIFE_5 = 0x00010000, + ISPL_QUICKATTACK = 0x00020000, + ISPL_FASTATTACK = 0x00040000, + ISPL_FASTERATTACK = 0x00080000, + ISPL_FASTESTATTACK = 0x00100000, + ISPL_FASTRECOVER = 0x00200000, + ISPL_FASTERRECOVER = 0x00400000, + ISPL_FASTESTRECOVER = 0x00800000, + ISPL_FASTBLOCK = 0x01000000, + ISPL_LIGHT_ARROWS = 0x02000000, + ISPL_THORNS = 0x04000000, + ISPL_NOMANA = 0x08000000, + ISPL_ABSHALFTRAP = 0x10000000, + ISPL_UNKNOWN_4 = 0x20000000, + ISPL_3XDAMVDEM = 0x40000000, + ISPL_ALLRESZERO = 0x80000000, +} item_special_effect; + +typedef enum _selhero_selections { + SELHERO_NEW_DUNGEON = 1, + SELHERO_CONTINUE = 2, + SELHERO_CONNECT = 3, + SELHERO_PREVIOUS = 4 +} _selhero_selections; + +enum automap_flags { + AFLAG_VERTDOOR = 1, + AFLAG_HORZDOOR = 2, + AFLAG_VERTARCH = 4, + AFLAG_HORZARCH = 8, + AFLAG_VERTGRATE = 0x10, + AFLAG_HORZGRATE = 0x20, + AFLAG_DIRT = 0x40, + AFLAG_STAIRS = 0x80 +}; diff --git a/2020_03_31/resource.h b/2020_03_31/resource.h new file mode 100644 index 00000000..511c43bc --- /dev/null +++ b/2020_03_31/resource.h @@ -0,0 +1,27 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by Diablo.rc +// +#define IDI_ICON1 101 +#define IDD_DIALOG1 104 // DX +#define IDD_DIALOG2 105 // NOMEMORY +#define IDD_DIALOG3 106 // NOFILE +#define IDD_DIALOG4 107 // DDRAW +#define IDD_DIALOG5 108 // DSOUND +#define IDD_DIALOG6 109 // PENTIUM (deprecated in 1.00) +#define IDD_DIALOG7 110 // DISKSPACE +#define IDD_DIALOG8 111 // VIDEOMODE +#define IDD_DIALOG9 112 // INSERTCD +#define IDD_DIALOG10 113 // RESTRICTED +#define IDD_DIALOG11 114 // READONLY + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 103 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1000 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/2020_03_31/structs.h b/2020_03_31/structs.h new file mode 100644 index 00000000..a55c7ecf --- /dev/null +++ b/2020_03_31/structs.h @@ -0,0 +1,1685 @@ +////////////////////////////////////////////////// +// direct x +////////////////////////////////////////////////// +typedef HRESULT (WINAPI *DDCREATEPROC)(GUID FAR *lpGUID, LPDIRECTDRAW FAR *lplpDD, IUnknown FAR *pUnkOuter); +typedef HRESULT (WINAPI *DSCREATEPROC)(GUID FAR *lpGUID, LPDIRECTSOUND FAR *lplpDS, IUnknown FAR *pUnkOuter); + +////////////////////////////////////////////////// +// items +////////////////////////////////////////////////// + +typedef struct PLStruct +{ + const char *PLName; + int PLPower; + int PLParam1; + int PLParam2; + char PLMinLvl; + int PLIType; + BYTE PLGOE; + int PLDouble; + int PLOk; + int PLMinVal; + int PLMaxVal; + int PLMultVal; +} PLStruct; + +typedef struct UItemStruct +{ + char *UIName; + char UIItemId; + char UIMinLvl; + char UINumPL; + int UIValue; + char UIPower1; + int UIParam1; + int UIParam2; + char UIPower2; + int UIParam3; + int UIParam4; + char UIPower3; + int UIParam5; + int UIParam6; + char UIPower4; + int UIParam7; + int UIParam8; + char UIPower5; + int UIParam9; + int UIParam10; + char UIPower6; + int UIParam11; + int UIParam12; +} UItemStruct; + +typedef struct ItemDataStruct +{ + int iRnd; + char iClass; + char iLoc; + int iCurs; + char itype; + char iItemId; + char *iName; + char *iSName; + char iMinMLvl; + int iDurability; + int iMinDam; + int iMaxDam; + int iMinAC; + int iMaxAC; + char iMinStr; + char iMinMag; + char iMinDex; + int iFlags; + int iMiscId; + int iSpell; + int iUsable; + int iValue; + int iMaxValue; +} ItemDataStruct; + +typedef struct ItemGetRecordStruct +{ + int nSeed; + unsigned short wCI; + int nIndex; + unsigned int dwTimestamp; +} ItemGetRecordStruct; + +typedef struct ItemStruct +{ + int _iSeed; + unsigned short _iCreateInfo; + int _itype; + int _ix; + int _iy; + int _iAnimFlag; + unsigned char *_iAnimData; // PSX name -> ItemFrame + int _iAnimLen; + int _iAnimFrame; + int _iAnimWidth; + int _iAnimWidth2; // width 2? + int _iDelFlag; // set when item is flagged for deletion, deprecated in 1.02 + char _iSelFlag; + int _iPostDraw; + int _iIdentified; + char _iMagical; + char _iName[64]; + char _iIName[64]; + char _iLoc; + char _iClass; + int _iCurs; + int _ivalue; + int _iIvalue; + int _iMinDam; + int _iMaxDam; + int _iAC; + int _iFlags; + int _iMiscId; + int _iSpell; + int _iCharges; + int _iMaxCharges; + int _iDurability; + int _iMaxDur; + int _iPLDam; + int _iPLToHit; + int _iPLAC; + int _iPLStr; + int _iPLMag; + int _iPLDex; + int _iPLVit; + int _iPLFR; + int _iPLLR; + int _iPLMR; + int _iPLMana; + int _iPLHP; + int _iPLDamMod; + int _iPLGetHit; + int _iPLLight; + char _iSplLvlAdd; + char _iRequest; + int _iUid; + int _iFMinDam; + int _iFMaxDam; + int _iLMinDam; + int _iLMaxDam; + int _iPLEnAc; + char _iPrePower; + char _iSufPower; + int _iVAdd1; + int _iVMult1; + int _iVAdd2; + int _iVMult2; + char _iMinStr; + unsigned char _iMinMag; + char _iMinDex; + int _iStatFlag; + int IDidx; + int offs016C; // _oldlight or _iInvalid +} ItemStruct; + +////////////////////////////////////////////////// +// player +////////////////////////////////////////////////// + +typedef struct PlayerStruct +{ + int _pmode; + char walkpath[25]; + unsigned char plractive; + int destAction; + int destParam1; + int destParam2; + int destParam3; + int destParam4; + int plrlevel; + int WorldX; + int WorldY; + int _px; + int _py; + int _ptargx; + int _ptargy; + int _pownerx; + int _pownery; + int _poldx; + int _poldy; + int _pxoff; + int _pyoff; + int _pxvel; + int _pyvel; + int _pdir; + int _nextdir; + int _pgfxnum; + unsigned char *_pAnimData; + int _pAnimDelay; + int _pAnimCnt; + int _pAnimLen; + int _pAnimFrame; + int _pAnimWidth; + int _pAnimWidth2; + int _peflag; + int _plid; + int _pvid; + int _pSpell; + char _pSplType; + char _pSplFrom; + int _pTSpell; + char _pTSplType; + int _pRSpell; + char _pRSplType; + int _pSBkSpell; + char _pSBkSplType; + char _pSplLvl[64]; + union { + __int64 _pMemSpells64; + int _pMemSpells[2]; + }; + union { + __int64 _pAblSpells64; + int _pAblSpells[2]; + }; + union { + __int64 _pScrlSpells64; + int _pScrlSpells[2]; + }; + char _pSpellFlags; + int _pSplHotKey[4]; + char _pSplTHotKey[4]; + int _pwtype; + unsigned char _pBlockFlag; + unsigned char _pInvincible; + char _pLightRad; + unsigned char _pLvlChanging; + char _pName[32]; + char _pClass; + int _pStrength; + int _pBaseStr; + int _pMagic; + int _pBaseMag; + int _pDexterity; + int _pBaseDex; + int _pVitality; + int _pBaseVit; + int _pStatPts; + int _pDamageMod; + int _pBaseToBlk; + int _pHPBase; + int _pMaxHPBase; + int _pHitPoints; + int _pMaxHP; + int _pHPPer; + int _pManaBase; + int _pMaxManaBase; + int _pMana; + int _pMaxMana; + int _pManaPer; + char _pLevel; + char _pMaxLvl; + int _pExperience; + int _pMaxExp; + int _pNextExper; + char _pArmorClass; + char _pMagResist; + char _pFireResist; + char _pLghtResist; + int _pGold; + int _pInfraFlag; + int _pVar1; + int _pVar2; + int _pVar3; + int _pVar4; + int _pVar5; + int _pVar6; + int _pVar7; + int _pVar8; + unsigned char _pLvlVisited[NUMLEVELS]; + unsigned char _pSLvlVisited[NUMLEVELS]; // only 10 used + int _pGFXLoad; + unsigned char *_pNAnim[8]; + int _pNFrames; + int _pNWidth; + unsigned char *_pWAnim[8]; + int _pWFrames; + int _pWWidth; + unsigned char *_pAAnim[8]; + int _pAFrames; + int _pAWidth; + int _pAFNum; + unsigned char *_pLAnim[8]; + unsigned char *_pFAnim[8]; + unsigned char *_pTAnim[8]; + int _pSFrames; + int _pSWidth; + int _pSFNum; + unsigned char *_pHAnim[8]; + int _pHFrames; + int _pHWidth; + unsigned char *_pDAnim[8]; + int _pDFrames; + int _pDWidth; + unsigned char *_pBAnim[8]; + int _pBFrames; + int _pBWidth; + ItemStruct InvBody[7]; + ItemStruct InvList[40]; + int _pNumInv; + char InvGrid[40]; + ItemStruct SpdList[8]; + ItemStruct HoldItem; + int _pIMinDam; + int _pIMaxDam; + int _pIAC; + int _pIBonusDam; + int _pIBonusToHit; + int _pIBonusAC; + int _pIBonusDamMod; + union { + __int64 _pISpells64; + int _pISpells[2]; + }; + int _pIFlags; + int _pIGetHit; + char _pISplLvlAdd; + char _pISplCost; /* unused (beta): reduce mana cost of spells */ + int _pISplDur; /* unused (beta): increase duration of spells */ + int _pIEnAc; + int _pIFMinDam; + int _pIFMaxDam; + int _pILMinDam; + int _pILMaxDam; + int _pOilType; /* unused (beta): current oil applied to item */ + unsigned char pTownWarps; + unsigned char pDungMsgs; + unsigned char pLvlLoad; + unsigned char pBattleNet; + unsigned char pManaShield; + char bReserved[3]; + short wReserved[8]; + DWORD pDiabloKillLevel; + int dwReserved[7]; + unsigned char *_pNData; + unsigned char *_pWData; + unsigned char *_pAData; + unsigned char *_pLData; + unsigned char *_pFData; + unsigned char *_pTData; + unsigned char *_pHData; + unsigned char *_pDData; + unsigned char *_pBData; + void *pReserved; +} PlayerStruct; + +////////////////////////////////////////////////// +// textdat +////////////////////////////////////////////////// + +typedef struct TextDataStruct +{ + char *txtstr; + int scrlltxt; + int txtspd; + int sfxnr; +} TextDataStruct; + +////////////////////////////////////////////////// +// missiles +////////////////////////////////////////////////// + +// TPDEF PTR FCN VOID MIADDPRC +// TPDEF PTR FCN VOID MIPROC + +typedef struct MissileData +{ + unsigned char mName; + void (* mAddProc)(int, int, int, int, int, int, char, int, int); + void (* mProc)(int); + int mDraw; + unsigned char mType; + unsigned char mResist; + unsigned char mFileNum; + int mlSFX; + int miSFX; +} MissileData; + +typedef struct MisFileData +{ + unsigned char mAnimName; + unsigned char mAnimFAmt; + char *mName; + int mFlags; + unsigned char *mAnimData[16]; + unsigned char mAnimDelay[16]; + unsigned char mAnimLen[16]; + int mAnimWidth[16]; + int mAnimWidth2[16]; +} MisFileData; + +typedef struct ChainStruct +{ + int idx; + int _mitype; + int _mirange; +} ChainStruct; + +typedef struct MissileStruct +{ + int _mitype; + int _mix; + int _miy; + int _mixoff; + int _miyoff; + int _mixvel; + int _miyvel; + int _misx; + int _misy; + int _mitxoff; + int _mityoff; + int _mimfnum; + int _mispllvl; + int _miDelFlag; + BYTE _miAnimType; + int _miAnimFlags; + unsigned char *_miAnimData; + int _miAnimDelay; + int _miAnimLen; + int _miAnimWidth; + int _miAnimWidth2; + int _miAnimCnt; + int _miAnimAdd; + int _miAnimFrame; + int _miDrawFlag; + int _miLightFlag; + int _miPreFlag; + int _miUniqTrans; + int _mirange; + int _misource; + int _micaster; + int _midam; + int _miHitFlag; + int _midist; + int _mlid; + int _mirnd; + int _miVar1; + int _miVar2; + int _miVar3; + int _miVar4; + int _miVar5; + int _miVar6; + int _miVar7; + int _miVar8; +} MissileStruct; + +////////////////////////////////////////////////// +// effects/sound +////////////////////////////////////////////////// + +typedef struct CKINFO { + DWORD dwSize; + DWORD dwOffset; +} CKINFO; + +typedef struct TSnd +{ + WAVEFORMATEX fmt; + CKINFO chunk; + char *sound_path; + IDirectSoundBuffer *DSB; + int start_tc; +} TSnd; + +#pragma pack(push, 1) +typedef struct TSFX +{ + unsigned char bFlags; + char *pszName; + TSnd *pSnd; +} TSFX; +#pragma pack(pop) + +////////////////////////////////////////////////// +// monster +////////////////////////////////////////////////// + +typedef struct AnimStruct // note: wrong names +{ + BYTE *CMem; // [unsigned] char * ?? + unsigned char *Frames[8]; // probably Data[8] + int Rate; + int Delay; +} AnimStruct; + +typedef struct MonsterData +{ + int flags; // width? + int mType; + char *GraphicType; + int has_special; + char *sndfile; + int snd_special; + int has_trans; + char *TransFile; + int Frames[6]; + int Rate[6]; + char *mName; + char mMinDLvl; + char mMaxDLvl; + char mLevel; + int mMinHP; + int mMaxHP; + char mAi; + int mFlags; + unsigned char mInt; + unsigned char mHit; + unsigned char mAFNum; + unsigned char mMinDamage; + unsigned char mMaxDamage; + unsigned char mHit2; + unsigned char mAFNum2; + unsigned char mMinDamage2; + unsigned char mMaxDamage2; + char mArmorClass; + char mMonstClass; + unsigned short mMagicRes; + unsigned short mMagicRes2; + unsigned short mTreasure; + char mSelFlag; + unsigned short mExp; +} MonsterData; + +typedef struct CMonster +{ + unsigned char mtype; + unsigned char mPlaceFlags; + AnimStruct Anims[6]; + TSnd *Snds[4][2]; + int flags_1; // width + int flags_2; // width 2 + unsigned char mMinHP; + unsigned char mMaxHP; + int has_special; + unsigned char mAFNum; + char mdeadval; + MonsterData *MData; + BYTE *trans_file; +} CMonster; + +typedef struct MonsterStruct // note: missing field _mAFNum +{ + int _mMTidx; + int _mmode; + char _mgoal; + int _mgoalvar1; + int _mgoalvar2; + int _mgoalvar3; + int field_18; // _mgoalvar4? + char _pathcount; + int _mx; + int _my; + int _mfutx; + int _mfuty; + int _moldx; + int _moldy; + int _mxoff; + int _myoff; + int _mxvel; + int _myvel; + int _mdir; + int _menemy; + unsigned char _menemyx; + unsigned char _menemyy; + short falign_52; + unsigned char *_mAnimData; + int _mAnimDelay; + int _mAnimCnt; + int _mAnimLen; + int _mAnimFrame; + int _meflag; + int _mDelFlag; + int _mVar1; + int _mVar2; + int _mVar3; + int _mVar4; + int _mVar5; + int _mVar6; + int _mVar7; + int _mVar8; + int _mmaxhp; + int _mhitpoints; + unsigned char _mAi; + unsigned char _mint; + short falign_9A; + int _mFlags; + BYTE _msquelch; + int falign_A4; + int _lastx; + int _lasty; + int _mRndSeed; + int _mAISeed; + int falign_B8; + unsigned char _uniqtype; + unsigned char _uniqtrans; + char _udeadval; + char mWhoHit; + char mLevel; + unsigned short mExp; + unsigned char mHit; + unsigned char mMinDamage; + unsigned char mMaxDamage; + unsigned char mHit2; + unsigned char mMinDamage2; + unsigned char mMaxDamage2; + char mArmorClass; + char falign_CB; + WORD mMagicRes; + int mtalkmsg; + unsigned char leader; + unsigned char leaderflag; + unsigned char packsize; + unsigned char mlid; + char *mName; + CMonster *MType; + MonsterData *MData; +} MonsterStruct; + +typedef struct UniqMonstStruct +{ + char mtype; + char *mName; + char *mTrnName; + unsigned char mlevel; + unsigned short mmaxhp; + unsigned char mAi; + unsigned char mint; + unsigned char mMinDamage; + unsigned char mMaxDamage; + unsigned short mMagicRes; + unsigned short mUnqAttr; + unsigned char mUnqVar1; + unsigned char mUnqVar2; + int mtalkmsg; +} UniqMonstStruct; + +////////////////////////////////////////////////// +// objects +////////////////////////////////////////////////// + +typedef struct ObjDataStruct +{ + char oload; + char ofindex; + char ominlvl; + char omaxlvl; + char olvltype; + char otheme; + char oquest; + int oAnimFlag; + int oAnimDelay; + int oAnimLen; + int oAnimWidth; + int oSolidFlag; + int oMissFlag; + int oLightFlag; + char oBreak; + char oSelFlag; + int oTrapFlag; +} ObjDataStruct; + +typedef struct ObjectStruct +{ + int _otype; + int _ox; + int _oy; + int _oLight; + int _oAnimFlag; + unsigned char *_oAnimData; + int _oAnimDelay; + int _oAnimCnt; + int _oAnimLen; + int _oAnimFrame; + int _oAnimWidth; + int _oAnimWidth2; + int _oDelFlag; + char _oBreak; // check + int _oSolidFlag; + int _oMissFlag; + char _oSelFlag; // check + int _oPreFlag; + int _oTrapFlag; + int _oDoorFlag; + int _olid; + int _oRndSeed; + int _oVar1; + int _oVar2; + int _oVar3; + int _oVar4; + int _oVar5; + int _oVar6; + int _oVar7; + int _oVar8; +} ObjectStruct; + +////////////////////////////////////////////////// +// portal +////////////////////////////////////////////////// + +typedef struct PortalStruct +{ + int open; + int x; + int y; + int level; + int ltype; + int setlvl; +} PortalStruct; + +////////////////////////////////////////////////// +// msg +////////////////////////////////////////////////// + +#pragma pack(push, 1) +typedef struct TCmd +{ + unsigned char bCmd; +} TCmd; + +typedef struct TCmdLoc +{ + unsigned char bCmd; + unsigned char x; + unsigned char y; +} TCmdLoc; + +typedef struct TCmdLocParam1 +{ + unsigned char bCmd; + unsigned char x; + unsigned char y; + unsigned short wParam1; +} TCmdLocParam1; + +typedef struct TCmdLocParam2 +{ + unsigned char bCmd; + unsigned char x; + unsigned char y; + unsigned short wParam1; + unsigned short wParam2; +} TCmdLocParam2; + +typedef struct TCmdLocParam3 +{ + unsigned char bCmd; + unsigned char x; + unsigned char y; + unsigned short wParam1; + unsigned short wParam2; + unsigned short wParam3; +} TCmdLocParam3; + +typedef struct TCmdParam1 +{ + unsigned char bCmd; + unsigned short wParam1; +} TCmdParam1; + +typedef struct TCmdParam2 +{ + unsigned char bCmd; + unsigned short wParam1; + unsigned short wParam2; +} TCmdParam2; + +typedef struct TCmdParam3 +{ + unsigned char bCmd; + unsigned short wParam1; + unsigned short wParam2; + unsigned short wParam3; +} TCmdParam3; + +typedef struct TCmdGolem +{ + unsigned char bCmd; + unsigned char _mx; + unsigned char _my; + unsigned char _mdir; + unsigned char _menemy; + int _mhitpoints; + unsigned char _currlevel; +} TCmdGolem; + +typedef struct TCmdQuest +{ + unsigned char bCmd; + unsigned char q; + unsigned char qstate; + unsigned char qlog; + unsigned char qvar1; +} TCmdQuest; + +typedef struct TCmdGItem +{ + unsigned char bCmd; + unsigned char bMaster; + unsigned char bPnum; + unsigned char bCursitem; + unsigned char bLevel; + unsigned char x; + unsigned char y; + unsigned short wIndx; + unsigned short wCI; + int dwSeed; + unsigned char bId; + unsigned char bDur; + unsigned char bMDur; + unsigned char bCh; + unsigned char bMCh; + unsigned short wValue; + int dwBuff; + int dwTime; +} TCmdGItem; + +typedef struct TCmdPItem +{ + char bCmd; /* unsigned */ + unsigned char x; + unsigned char y; + unsigned short wIndx; + unsigned short wCI; + int dwSeed; + unsigned char bId; + unsigned char bDur; + unsigned char bMDur; + unsigned char bCh; + unsigned char bMCh; + unsigned short wValue; + int dwBuff; +} TCmdPItem; + +typedef struct TCmdChItem +{ + unsigned char bCmd; + unsigned char bLoc; + unsigned short wIndx; + unsigned short wCI; + int dwSeed; + unsigned char bId; +} TCmdChItem; + +typedef struct TCmdDelItem +{ + unsigned char bCmd; + unsigned char bLoc; +} TCmdDelItem; + +typedef struct TCmdDamage +{ + unsigned char bCmd; + unsigned char bPlr; + int dwDam; +} TCmdDamage; + +typedef struct TCmdPlrInfoHdr +{ + unsigned char bCmd; + unsigned short wOffset; + unsigned short wBytes; +} TCmdPlrInfoHdr; + +typedef struct TCmdString +{ + unsigned char bCmd; + char str[80]; +} TCmdString; + +typedef struct TFakeCmdPlr +{ + unsigned char bCmd; + unsigned char bPlr; +} TFakeCmdPlr; + +typedef struct TFakeDropPlr +{ + unsigned char bCmd; + unsigned char bPlr; + int dwReason; +} TFakeDropPlr; + +typedef struct TSyncHeader +{ + unsigned char bCmd; + unsigned char bLevel; + unsigned short wLen; + unsigned char bObjId; + unsigned char bObjCmd; + unsigned char bItemI; + unsigned char bItemX; + unsigned char bItemY; + unsigned short wItemIndx; + unsigned short wItemCI; + int dwItemSeed; + unsigned char bItemId; + unsigned char bItemDur; + unsigned char bItemMDur; + unsigned char bItemCh; + unsigned char bItemMCh; + unsigned short wItemVal; + unsigned int dwItemBuff; + unsigned char bPInvLoc; + unsigned short wPInvIndx; + unsigned short wPInvCI; + int dwPInvSeed; + unsigned char bPInvId; +} TSyncHeader; + +typedef struct TSyncMonster +{ + unsigned char _mndx; + unsigned char _mx; + unsigned char _my; + unsigned char _menemy; + unsigned char _mdelta; +} TSyncMonster; + +typedef struct TPktHdr +{ + unsigned char px; + unsigned char py; + unsigned char targx; + unsigned char targy; + int php; + int pmhp; + unsigned char bstr; + unsigned char bmag; + unsigned char bdex; + unsigned short wCheck; + unsigned short wLen; +} TPktHdr; + +typedef struct TPkt +{ + TPktHdr hdr; + unsigned char body[493]; +} TPkt; + +typedef struct DMonsterStr +{ + unsigned char _mx; /* these might be unsigned */ + unsigned char _my; + unsigned char _mdir; + unsigned char _menemy; + unsigned char _mactive; + int _mhitpoints; +} DMonsterStr; + +typedef struct DObjectStr +{ + unsigned char bCmd; +} DObjectStr; + +typedef struct DLevel +{ + TCmdPItem item[MAXITEMS]; + DObjectStr object[MAXOBJECTS]; + DMonsterStr monster[MAXMONSTERS]; +} DLevel; + +typedef struct LocalLevel +{ + unsigned char automapsv[40][40]; +} LocalLevel; + +typedef struct DPortal +{ + unsigned char x; + unsigned char y; + unsigned char level; + unsigned char ltype; + unsigned char setlvl; +} DPortal; + +typedef struct MultiQuests +{ + unsigned char qstate; + unsigned char qlog; + unsigned char qvar1; +} MultiQuests; + +typedef struct DJunk +{ + DPortal portal[MAXPORTAL]; + MultiQuests quests[MAXMULTIQUESTS]; +} DJunk; +#pragma pack(pop) + +typedef struct TMegaPkt +{ + struct TMegaPkt *pNext; + int dwSpaceLeft; + unsigned char data[32000]; +} TMegaPkt; + +typedef struct TBuffer +{ + unsigned int dwNextWriteOffset; + unsigned char bData[4096]; +} TBuffer; + +////////////////////////////////////////////////// +// quests +////////////////////////////////////////////////// + +typedef struct QuestStruct +{ + unsigned char _qlevel; + unsigned char _qtype; + unsigned char _qactive; + unsigned char _qlvltype; + int _qtx; + int _qty; + unsigned char _qslvl; + unsigned char _qidx; + unsigned char _qmsg; + unsigned char _qvar1; + unsigned char _qvar2; + int _qlog; /* char */ +} QuestStruct; + +typedef struct QuestData +{ + unsigned char _qdlvl; + char _qdmultlvl; + unsigned char _qlvlt; + unsigned char _qdtype; + unsigned char _qdrnd; + unsigned char _qslvl; + int _qflags; /* unsigned char */ + int _qdmsg; + char *_qlstr; +} QuestData; + +////////////////////////////////////////////////// +// gamemenu/gmenu +////////////////////////////////////////////////// + +// TPDEF PTR FCN VOID TMenuFcn + +typedef struct TMenuItem +{ + unsigned int dwFlags; + char *pszStr; + void (* fnMenu)(BOOL); /* fix, should have one arg */ +} TMenuItem; + +// TPDEF PTR FCN VOID TMenuUpdateFcn + +////////////////////////////////////////////////// +// spells +////////////////////////////////////////////////// + +typedef struct SpellData +{ + unsigned char sName; + unsigned char sManaCost; + unsigned char sType; + char *sNameText; + char *sSkillText; + int sBookLvl; + int sStaffLvl; + int sTargeted; + BOOL sTownSpell; + int sMinInt; + unsigned char sSFX; + unsigned char sMissiles[3]; + unsigned char sManaAdj; + unsigned char sMinMana; + int sStaffMin; + int sStaffMax; + int sBookCost; + int sStaffCost; +} SpellData; + +////////////////////////////////////////////////// +// towners +////////////////////////////////////////////////// + +typedef struct TNQ +{ + unsigned char _qsttype; + unsigned char _qstmsg; + unsigned char _qstmsgact; +} TNQ; + +typedef struct TownerStruct +{ + int _tmode; + int _ttype; + int _tx; + int _ty; + int _txoff; + int _tyoff; + int _txvel; + int _tyvel; + int _tdir; + unsigned char *_tAnimData; + int _tAnimDelay; + int _tAnimCnt; + int _tAnimLen; + int _tAnimFrame; + int _tAnimFrameCnt; + char _tAnimOrder; + int _tAnimWidth; + int _tAnimWidth2; + int _tTenPer; + int _teflag; + int _tbtcnt; + int _tSelFlag; + int _tMsgSaid; + TNQ qsts[16]; + int _tSeed; + int _tVar1; + int _tVar2; + int _tVar3; + int _tVar4; + char _tName[32]; + unsigned char *_tNAnim[8]; + int _tNFrames; + unsigned char *_tNData; +} TownerStruct; + +typedef struct QuestTalkData +{ + int _qinfra; + int _qblkm; + int _qgarb; + int _qzhar; + int _qveil; + int _qmod; + int _qbutch; + int _qbol; + int _qblind; + int _qblood; + int _qanvil; + int _qwarlrd; + int _qking; + int _qpw; + int _qbone; + int _qvb; +} QuestTalkData; + +////////////////////////////////////////////////// +// gendung +////////////////////////////////////////////////// + +typedef struct ScrollStruct +{ + int _sxoff; + int _syoff; + int _sdx; + int _sdy; + int _sdir; +} ScrollStruct; + +typedef struct THEME_LOC +{ + int x; + int y; + int ttval; + int width; + int height; +} THEME_LOC; + +typedef struct MICROS +{ + WORD mt[16]; +} MICROS; + +////////////////////////////////////////////////// +// drlg +////////////////////////////////////////////////// + +typedef struct ShadowStruct +{ + unsigned char strig; + unsigned char s1; + unsigned char s2; + unsigned char s3; + unsigned char nv1; + unsigned char nv2; + unsigned char nv3; +} ShadowStruct; + +typedef struct HALLNODE +{ + int nHallx1; + int nHally1; + int nHallx2; + int nHally2; + int nHalldir; + struct HALLNODE *pNext; +} HALLNODE; + +typedef struct ROOMNODE +{ + int nRoomx1; + int nRoomy1; + int nRoomx2; + int nRoomy2; + int nRoomDest; +} ROOMNODE; + +////////////////////////////////////////////////// +// themes +////////////////////////////////////////////////// + +typedef struct ThemeStruct +{ + char ttype; /* aligned 4 */ + int ttval; +} ThemeStruct; + +////////////////////////////////////////////////// +// inv +////////////////////////////////////////////////// + +typedef struct InvXY +{ + int X; + int Y; +} InvXY; + +////////////////////////////////////////////////// +// lighting +////////////////////////////////////////////////// + +typedef struct LightListStruct +{ + int _lx; + int _ly; + int _lradius; + int _lid; + int _ldel; + int _lunflag; + int field_18; + int _lunx; + int _luny; + int _lunr; + int _xoff; + int _yoff; + int _lflags; +} LightListStruct; + +////////////////////////////////////////////////// +// dead +////////////////////////////////////////////////// + +typedef struct DeadStruct +{ + unsigned char *_deadData[8]; + int _deadFrame; + int _deadWidth; + int _deadWidth2; + char _deadtrans; +} DeadStruct; + +////////////////////////////////////////////////// +// storm +////////////////////////////////////////////////// + +// TPDEF PTR FCN VOID SEVTHANDLER + +// TPDEF PTR FCN UCHAR SMSGIDLEPROC +// TPDEF PTR FCN VOID SMSGHANDLER + +typedef struct _SNETCAPS +{ + DWORD size; + DWORD flags; + DWORD maxmessagesize; + DWORD maxqueuesize; + DWORD maxplayers; + DWORD bytessec; + DWORD latencyms; + DWORD defaultturnssec; + DWORD defaultturnsintransit; +} _SNETCAPS; + +typedef struct _SNETEVENT +{ + DWORD eventid; + DWORD playerid; + void *data; + DWORD databytes; +} _SNETEVENT; + +// TPDEF PTR FCN UCHAR SNETABORTPROC +// TPDEF PTR FCN UCHAR SNETCATEGORYPROC +// TPDEF PTR FCN UCHAR SNETCHECKAUTHPROC +// TPDEF PTR FCN UCHAR SNETCREATEPROC +// TPDEF PTR FCN UCHAR SNETDRAWDESCPROC +// TPDEF PTR FCN UCHAR SNETENUMDEVICESPROC +// TPDEF PTR FCN UCHAR SNETENUMGAMESPROC +// TPDEF PTR FCN UCHAR SNETENUMPROVIDERSPROC +// TPDEF PTR FCN VOID SNETEVENTPROC +// TPDEF PTR FCN UCHAR SNETGETARTPROC +// TPDEF PTR FCN UCHAR SNETGETDATAPROC +// TPDEF PTR FCN INT SNETMESSAGEBOXPROC +// TPDEF PTR FCN UCHAR SNETPLAYSOUNDPROC +// TPDEF PTR FCN UCHAR SNETSELECTEDPROC +// TPDEF PTR FCN UCHAR SNETSTATUSPROC + +typedef struct _SNETPLAYERDATA +{ + int size; + char *playername; + char *playerdescription; + int reserved; +} _SNETPLAYERDATA; + +typedef struct _SNETPROGRAMDATA +{ + int size; + char *programname; + char *programdescription; + int programid; + int versionid; + int reserved1; + int maxplayers; + void *initdata; + int initdatabytes; + void *reserved2; + int optcategorybits; + char *cdkey; + char *registereduser; + int spawned; + int lcid; +} _SNETPROGRAMDATA; + +typedef struct _SNETUIDATA +{ + int size; + int uiflags; + HWND parentwindow; + void (* artcallback)(); + void (* authcallback)(); + void (* createcallback)(); + void (* drawdesccallback)(); + void (* selectedcallback)(); + void (* messageboxcallback)(); + void (* soundcallback)(); + void (* statuscallback)(); + void (* getdatacallback)(); + void (* categorycallback)(); + void (* categorylistcallback)(); + void (* newaccountcallback)(); + void (* profilecallback)(); + int profilefields; + void (* profilebitmapcallback)(); + void (* selectnamecallback)(); + void (* changenamecallback)(); +} _SNETUIDATA; + +typedef struct _SNETVERSIONDATA +{ + int size; + char *versionstring; + char *executablefile; + char *originalarchivefile; + char *patcharchivefile; +} _SNETVERSIONDATA; + +// TPDEF PTR FCN UCHAR SNETSPIBIND +// TPDEF PTR FCN UCHAR SNETSPIQUERY + +////////////////////////////////////////////////// +// diabloui +////////////////////////////////////////////////// + +// TPDEF PTR FCN VOID PLAYSND + +typedef struct _gamedata +{ + DWORD dwSeed; + unsigned char bDiff; +} _gamedata; + +typedef struct _uidefaultstats +{ + unsigned short strength; + unsigned short magic; + unsigned short dexterity; + unsigned short vitality; +} _uidefaultstats; + +typedef struct _uiheroinfo +{ + struct _uiheroinfo *next; + char name[16]; + unsigned short level; + unsigned char heroclass; + unsigned char herorank; + unsigned short strength; + unsigned short magic; + unsigned short dexterity; + unsigned short vitality; + int gold; + int hassaved; + int spawned; +} _uiheroinfo; + +// TPDEF PTR FCN UCHAR ENUMHEROPROC +// TPDEF PTR FCN UCHAR ENUMHEROS +// TPDEF PTR FCN UCHAR CREATEHERO +// TPDEF PTR FCN UCHAR DELETEHERO +// TPDEF PTR FCN UCHAR GETDEFHERO + +// TPDEF PTR FCN INT PROGRESSFCN + +////////////////////////////////////////////////// +// pack +////////////////////////////////////////////////// + +#pragma pack(push, 1) +typedef struct PkItemStruct +{ + int iSeed; + short iCreateInfo; + short idx; + char bId; + char bDur; + char bMDur; + char bCh; + char bMCh; + short wValue; + int dwBuff; +} PkItemStruct; + +typedef struct PkPlayerStruct +{ + FILETIME archiveTime; + char destAction; + char destParam1; + char destParam2; + char plrlevel; + char px; + char py; + char targx; + char targy; + char pName[32]; + char pClass; + char pBaseStr; + char pBaseMag; + char pBaseDex; + char pBaseVit; + char pLevel; + char pStatPts; + int pExperience; + int pGold; + int pHPBase; + int pMaxHPBase; + int pManaBase; + int pMaxManaBase; + char pSplLvl[37]; + int pMemSpells; /* __int64 */ + int pMemSpells2; + PkItemStruct InvBody[7]; + PkItemStruct InvList[40]; + char InvGrid[40]; + char _pNumInv; + PkItemStruct SpdList[8]; + char pTownWarps; + char pDungMsgs; + char pLvlLoad; + char pBattleNet; + char pManaShield; + char bReserved[3]; + short wReserved[8]; + DWORD pDiabloKillLevel; + int dwReserved[7]; +} PkPlayerStruct; +#pragma pack(pop) + +////////////////////////////////////////////////// +// path +////////////////////////////////////////////////// + +typedef struct PATHNODE +{ + char f; + char h; + char g; + int x; + int y; + struct PATHNODE *Parent; + struct PATHNODE *Child[8]; + struct PATHNODE *NextNode; +} PATHNODE; + +// TPDEF PTR FCN UCHAR CHECKFUNC1 + +// TPDEF PTR FCN UCHAR CHECKFUNC + +////////////////////////////////////////////////// +// sha +////////////////////////////////////////////////// + +typedef struct SHA1Context +{ + int state[5]; + int count[2]; + char buffer[64]; +} SHA1Context; + +////////////////////////////////////////////////// +// tmsg +////////////////////////////////////////////////// + +#pragma pack(push, 1) +typedef struct TMsg TMsg; + +typedef struct TMsgHdr +{ + TMsg *pNext; + unsigned int dwTime; + unsigned char bLen; +} TMsgHdr; + +typedef struct TMsg +{ + TMsgHdr hdr; + unsigned char body[3]; +} TMsg; +#pragma pack(pop) + +////////////////////////////////////////////////// +// mpqapi +////////////////////////////////////////////////// + +typedef struct _FILEHEADER +{ + int signature; + int headersize; + int filesize; + short version; + short sectorsizeid; + int hashoffset; + int blockoffset; + int hashcount; + int blockcount; + char pad[72]; +} _FILEHEADER; + +typedef struct _HASHENTRY +{ + int hashcheck[2]; + int lcid; + int block; +} _HASHENTRY; + +typedef struct _BLOCKENTRY +{ + int offset; + int sizealloc; + int sizefile; + int flags; +} _BLOCKENTRY; + +// TPDEF PTR FCN UCHAR TGetNameFcn + +// TPDEF PTR FCN VOID TCrypt + +////////////////////////////////////////////////// +// trigs +////////////////////////////////////////////////// + +typedef struct TriggerStruct +{ + int _tx; + int _ty; + int _tmsg; + int _tlvl; +} TriggerStruct; + +////////////////////////////////////////////////// +// stores +////////////////////////////////////////////////// + +typedef struct STextStruct +{ + int _sx; + int _syoff; + char _sstr[128]; + int _sjust; + char _sclr; + int _sline; + BOOL _ssel; + int _sval; +} STextStruct; + +////////////////////////////////////////////////// +// wave +////////////////////////////////////////////////// + +typedef struct MEMFILE +{ + int end; + int offset; + int buf_len; + int dist; + int bytes_to_read; + char *buf; + int file; +} MEMFILE; + +////////////////////////////////////////////////// +// plrmsg +////////////////////////////////////////////////// + +typedef struct _plrmsg +{ + int time; + char player; + char str[144]; +} _plrmsg; + +////////////////////////////////////////////////// +// capture +////////////////////////////////////////////////// + +typedef struct _PcxHeader +{ + BYTE Manufacturer; + BYTE Version; + BYTE Encoding; + BYTE BitsPerPixel; + WORD Xmin; + WORD Ymin; + WORD Xmax; + WORD Ymax; + WORD HDpi; + WORD VDpi; + BYTE Colormap[48]; + BYTE Reserved; + BYTE NPlanes; + WORD BytesPerLine; + WORD PaletteInfo; + WORD HscreenSize; + WORD VscreenSize; + BYTE Filler[54]; +} PCXHEADER; + +////////////////////////////////////////////////// +// encrypt +////////////////////////////////////////////////// + +typedef struct TDataInfo +{ + unsigned char *pbInBuff; + unsigned char *pbInBuffEnd; + unsigned char *pbOutBuff; + unsigned char *pbOutBuffEnd; + unsigned char *pbSize; +} TDataInfo; + +////////////////////////////////////////////////// +// codec +////////////////////////////////////////////////// + +typedef struct CODECCHUNK { + DWORD checksum; + BYTE failed; + BYTE last_chunk_size; + WORD unused; +} CODECCHUNK; + +////////////////////////////////////////////////// +// dthread +////////////////////////////////////////////////// + +typedef struct TDeltaInfo { + TDeltaInfo *pNext; + int pnum; + BYTE cmd; + DWORD size; + BYTE data[4]; +} TDeltaInfo; diff --git a/2020_03_31/types.h b/2020_03_31/types.h new file mode 100644 index 00000000..9963ac28 --- /dev/null +++ b/2020_03_31/types.h @@ -0,0 +1,66 @@ +// temporary file + +#ifndef _TYPES_H +#define _TYPES_H + +#define WIN32_LEAN_AND_MEAN + +#include "resource.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef __GNUC__ +#include +#endif + +typedef unsigned char _bool; + +// tell Visual C++ to shut the hell up +#ifdef _MSC_VER +#pragma warning (disable : 4309) // truncation of constant value +#pragma warning (disable : 4305) // truncation of int +#pragma warning (disable : 4018) // signed/unsigned mismatch +#pragma warning (disable : 4700) // used without having been initialized +#pragma warning (disable : 4804) // unsafe use of type 'bool' in operation +#pragma warning (disable : 4805) // unsafe bool mix +#pragma warning (disable : 4244) // conversion loss +#pragma warning (disable : 4800) // bool perf +#pragma warning (disable : 4146) // negative unsigned +#endif + +#include "defs.h" +#include "enums.h" +#include "structs.h" + +#if (_MSC_VER >= 800) && (_MSC_VER <= 1200) +#define USE_ASM +#endif + +// If defined, use copy protection [Default -> Defined] +//#define COPYPROT + +// If defined, don't reload for debuggers [Default -> Undefined] +// Note that with patch 1.03 the command line was hosed, this is required to pass arguments to the game +#ifdef _DEBUG +#define DEBUGGER +#endif + +// If defined, don't fry the CPU [Default -> Undefined] +#ifdef _DEBUG +#define SLEEPFIX +#endif + +// If defined, fix palette glitch in Windows Vista+ [Default -> Undefined] +//#define COLORFIX + +#endif